Compare commits

...

354 Commits

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

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

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

* Help: fix `module-format` related issues

* Help: remove unnecessary code
2023-10-05 19:59:24 +08:00
李通洲 f78f97a726 Revert "DisplayServer (Linux): add debug log for #568"
This reverts commit 1a4eb25194.
2023-10-04 16:28:54 +08:00
Carter Li 9972c61bbe Sound (macOS): support non-controllable devices 2023-10-04 14:59:13 +08:00
Carter Li 8795d99f79 Brightness: add DDC/CI support for Intel
Doesn't work for me. Need more testing
2023-10-04 14:41:06 +08:00
Carter Li f8aafb7ce4 Monitor (macOS): better intel platform support 2023-10-04 00:30:35 +08:00
Carter Li 27581d92b5 Disk (macOS): detect physical type 2023-10-04 00:30:35 +08:00
Carter Li 4a89b92185 Disk: allow custiomize disk key with mountFrom 2023-10-04 00:30:35 +08:00
李通洲 1a4eb25194 DisplayServer (Linux): add debug log for #568 2023-10-04 00:30:35 +08:00
李通洲 3eb9acea2e Doc: update changelog 2023-10-03 17:04:08 +08:00
李通洲 be860064c5 Users (Windows): fix crashing caused by uninitialized strings 2023-10-03 17:01:57 +08:00
李通洲 1985552636 Disk (Windows): fix crashing on Windows 7 VM 2023-10-03 16:50:57 +08:00
李通洲 985264d485 Fastfetch: add Directx Headers to --list-features 2023-10-02 23:19:44 +08:00
Carter Li e3c69c4569 Merge pull request #571 from fastfetch-cli/dev
Release v2.1.0
2023-10-02 19:23:07 +08:00
李通洲 45f523adb8 Release v2.1.0 2023-10-02 18:03:10 +08:00
李通洲 f7cc4fb4b1 Doc: update changelog 2023-10-02 18:00:30 +08:00
Alxhr0 ddec13be29 Fix Slackware 2023-10-01 22:37:18 +08:00
李通洲 74ac023cb0 Logo (Builtin): support Oracle Linux Server
Fix #569
2023-10-01 20:52:05 +08:00
李通洲 7f75d42ec8 Logo (Builtin): tidy 2023-10-01 20:50:10 +08:00
李通洲 e53acf42ec Disk (Linux): detect physical type 2023-09-30 20:32:14 +08:00
李通洲 18233a27c5 Disk (Windows): detect disk physical type 2023-09-30 15:00:59 +08:00
李通洲 9857f48bb9 OS (Linux): actually display debian .x version
Also display code name on Linux
2023-09-28 23:40:03 +08:00
李通洲 289976372f Shell: improve nu version detection performance 2023-09-27 20:05:55 +08:00
李通洲 72d2ce4b43 Logo: add LainOS
Ref: https://github.com/dylanaraps/neofetch/pull/2382
2023-09-27 15:52:52 +08:00
李通洲 eb0faec74a NetIO (Android): fix building
Doesn't work because `/sys` is unaccessable on Android
2023-09-27 15:34:53 +08:00
李通洲 767f99cffa CPU (Linux): only try lscpu on Linux
Since `lscpu` is a program of `util-linux`
2023-09-27 15:11:05 +08:00
李通洲 7caa8d4618 CPU (Linux): try detecting CPU name using lscpu
Fix #567
2023-09-27 15:05:26 +08:00
李通洲 88c12486bf Processing (Linux): always set LANG to C before executing child process 2023-09-27 15:02:55 +08:00
李通洲 8b357c27b4 Logo (Builtin): add Amazon LInux
Fix #566
2023-09-27 11:06:09 +08:00
李通洲 a7a8f2f461 NetIO (BSD): fix compiling 2023-09-27 10:48:54 +08:00
李通洲 5e5c0b4a58 NetIO: improve performance 2023-09-27 10:31:35 +08:00
李通洲 154657b455 NetUsage: rename to NetIO 2023-09-27 00:06:11 +08:00
李通洲 3866f27448 NetUsage (BSD): fix compiling 2023-09-26 23:58:05 +08:00
李通洲 b4f29918ed NetUsage: finish docs 2023-09-26 23:18:19 +08:00
李通洲 b29b78b321 NetUsage: finish module 2023-09-26 23:00:31 +08:00
李通洲 917b049030 LocalIP: cache default route value 2023-09-26 21:49:01 +08:00
李通洲 4843dedb4d LocalIp: filter --localip-default-route-only inside detection code 2023-09-26 20:57:02 +08:00
李通洲 69373906ca Windows: pre-basic msvc support 2023-09-26 20:13:32 +08:00
李通洲 24a6efa227 NetUsage: finish first working version 2023-09-26 19:54:19 +08:00
李通洲 9004d9e05c NetUsage (BSD): add detection support 2023-09-26 12:04:19 +08:00
李通洲 fa4fccd426 NetUsage (Windows): add detection support 2023-09-26 11:20:26 +08:00
李通洲 57bd741d96 NetUsage (Linux): new module (WIP) 2023-09-26 11:20:26 +08:00
李通洲 50c8809d51 LocalIp (Linux): add ioCounter detection 2023-09-26 09:52:10 +08:00
李通洲 e4c1ec916b FFstrbuf: change ffStrbufToUInt16 to more general function ffStrbufToUInt 2023-09-26 09:52:10 +08:00
李通洲 a4bc07cba5 LocalIp (Windows): add ioCounter detection 2023-09-26 09:52:10 +08:00
李通洲 40e542852f CMake: disable ASan on macOS
Ref: https://stackoverflow.com/questions/64126942/malloc-nano-zone-abandoned-due-to-inability-to-preallocate-reserved-vm-space
2023-09-26 09:14:39 +08:00
李通洲 bde2d67f25 CMake: disable UBSan 2023-09-26 08:58:16 +08:00
李通洲 6d1bde17c8 Wifi (macOS): silence compiler warnings 2023-09-25 16:11:00 +08:00
李通洲 ad0c2aa2e9 Version: detect compiler and compile time 2023-09-24 23:07:03 +08:00
李通洲 ddbd198864 Doc: update changelog 2023-09-24 22:21:18 +08:00
李通洲 3e768ddfd4 OS (Linux): detect detailed debian version
Ref: https://github.com/dylanaraps/neofetch/issues/2381
2023-09-24 21:50:12 +08:00
李通洲 6ccf8856b9 Bluetooth (Windows): fix mac address detection 2023-09-24 21:16:54 +08:00
李通洲 1caaa69deb Platform: fix memleaks 2023-09-23 11:58:46 +08:00
李通洲 5aa2798e42 Kernel (Windows): detect service pack version 2023-09-23 11:51:37 +08:00
李通洲 597daddf2a Fastfetch: add -c as a shortcut of --load-config 2023-09-23 09:56:34 +08:00
李通洲 ff1c3d9888 Doc: update changelog 2023-09-23 09:56:34 +08:00
李通洲 cc6cdb96fb Networking: support timeout on Linux 2023-09-23 09:56:34 +08:00
李通洲 db5619541a Init (Windows): actually disable stdout buffer with --no-buffer 2023-09-22 15:06:02 +08:00
李通洲 d94fc32f45 Colors: support --colors-key 2023-09-22 15:05:27 +08:00
李通洲 34723bba89 Colors: don't parse --colors-* as --color * 2023-09-22 15:05:27 +08:00
李通洲 a0efbd20a1 Title: make this module formattable 2023-09-22 15:05:27 +08:00
李通洲 4d86c53e81 Custom: code cleanup 2023-09-22 14:57:04 +08:00
李通洲 560c2acb88 Global: add --module-key " " as a magic case for hiding keys 2023-09-21 16:17:23 +08:00
李通洲 592de4c8f2 CI: print dependencies 2023-09-21 16:11:04 +08:00
李通洲 8cbe3f6453 GPU (Linux): add full GPU detection support in WSL
With DX12 API ;)
2023-09-21 15:47:03 +08:00
李通洲 ec8ee1a509 TerminalFont: fix compiler warnings 2023-09-21 15:47:03 +08:00
李通洲 30ae8a2f96 Packages (Linux): fix dpkg package number detection 2023-09-20 16:17:02 +08:00
李通洲 5337e5cead Packages (Linux): fix snap package number detection on systems other than Ubuntu
Fixes 562
2023-09-20 16:03:35 +08:00
李通洲 576fcd7d3d Display: print display type 2023-09-20 16:03:35 +08:00
李通洲 64615e635f Doc: update changelog 2023-09-20 10:16:18 +08:00
李通洲 38c22bf771 Disk (FreeBSD): hide /boot like what linux does 2023-09-20 10:16:18 +08:00
李通洲 064f624eab macOS: fix compiler warnings on latest xcode 2023-09-19 14:43:55 +08:00
李通洲 26e5790a78 Brightness: report more detailed values 2023-09-19 13:25:50 +08:00
李通洲 48cecd0ad1 CPU: update JSON format structure 2023-09-19 10:50:52 +08:00
李通洲 69e57e52ab Disk (Android): fix detection on Android 2023-09-18 23:03:14 +08:00
李通洲 dbd6e45aba Disk (Android): fix build 2023-09-18 22:25:15 +08:00
李通洲 3714dfdca7 Presets: new example 2023-09-18 20:51:09 +08:00
李通洲 06b1051a7e Global: don't trim custom strings
It can be useful to align separators
2023-09-18 20:46:30 +08:00
李通洲 8edb7d3833 Logo: fix Windows 11_small 2023-09-18 20:45:23 +08:00
李通洲 8a14cbae0c JSON: don't print the non-standand NaN 2023-09-18 20:12:33 +08:00
李通洲 7f727086af Disk: move filesystem outside of files (JSON format) 2023-09-18 20:01:41 +08:00
李通洲 7cd79d34bb Presets: remove devinfo and verbose 2023-09-18 14:19:19 +08:00
李通洲 939165d4cf Platform: align logic of getting host name to neofetch
Fixes: #561
2023-09-18 13:56:32 +08:00
李通洲 b4f063e1da Disk (Linux): detect external disk more accurately 2023-09-18 10:06:14 +08:00
李通洲 bdc79a2995 Doc: update changelog 2023-09-18 00:15:15 +08:00
李通洲 2bb78af1a7 Disk (Linux): detect USB devices as external volumes only
Fixes #559
2023-09-18 00:14:05 +08:00
李通洲 d8e4575157 Disk (Linux): fix ZFS subvolume detection 2023-09-17 22:28:03 +08:00
李通洲 b54e182c0f Disk (Windows): detect volume name 2023-09-17 20:41:07 +08:00
李通洲 fe89e71200 Disk (Linux): try fixing zpool detection
Ref: #559
2023-09-17 20:08:46 +08:00
xbt573 fb69d56297 Arguments: handle --lib-pulse properly 2023-09-17 02:13:48 -04:00
李通洲 6c1b39ae60 Shell (FreeBSD): remove trailing \0 2023-09-16 20:46:49 +08:00
李通洲 2082e01555 Theme: support JSON format (2) 2023-09-16 20:36:28 +08:00
李通洲 24a9231ad0 Kernel (Windows): remove trailing \0 2023-09-15 20:58:57 +08:00
李通洲 3c7903cc14 JsonSchema: add processingTimeout 2023-09-15 19:06:32 +08:00
李通洲 b721f9020e Logo (Builtin): improve performance on Windows 2023-09-15 11:07:47 +08:00
李通洲 bd02e5c632 Logo: code refactor 2023-09-15 10:53:09 +08:00
李通洲 0d5cf52f08 FFstrbuf: add ffStrbufAppendNC 2023-09-15 10:35:12 +08:00
李通洲 f97cddf2da JSON: support --stat for flag based configurations 2023-09-14 15:53:44 +08:00
李通洲 49f42cd003 Doc: update changelog 2023-09-14 15:29:15 +08:00
李通洲 0d7dc2d692 Logo (Ubuntu): changed the edges of the Ubuntu logo to make it rounder
Ref: https://github.com/dylanaraps/neofetch/pull/2378
2023-09-14 15:28:33 +08:00
xbt573 2039bed70d Logo (Builtin): add Elbrus 2023-09-14 01:20:40 -04:00
李通洲 9535b6a8bf PublicIP: fix missing new line 2023-09-14 08:55:33 +08:00
李通洲 df945e824b Deps: upgrade yyjson 2023-09-14 08:38:59 +08:00
李通洲 237c6f1c9e Processes / LocalIP: try increasing stability 2023-09-13 23:41:26 +08:00
李通洲 61131073f2 Global: silence compiler warnings 2023-09-13 22:46:11 +08:00
李通洲 013abe2b3e Weather: support JSON format 2023-09-13 18:38:02 +08:00
李通洲 63c29b10fe Weather: code refactor 2023-09-13 18:31:22 +08:00
李通洲 f5ad07a87b PublicIP: support JSON format 2023-09-13 17:56:50 +08:00
李通洲 28d40d9037 Global: fix some memleaks 2023-09-13 17:42:22 +08:00
李通洲 b3bdf494ab PublicIP: code refactor 2023-09-13 17:41:48 +08:00
李通洲 8d914ace33 Doc: update changelog 2023-09-13 17:36:39 +08:00
李通洲 58f234638b Users: make --users-compact false by default 2023-09-13 17:36:39 +08:00
李通洲 7dfc0d8e60 Shell: don't detect user shell 2023-09-13 17:36:39 +08:00
李通洲 2963e3bd93 Terminal: don't print shell information in Terminal module 2023-09-13 17:36:39 +08:00
李通洲 3dfa99c232 WMTheme: support JSON format 2023-09-13 14:25:00 +08:00
李通洲 804463a470 WM: support JSON format 2023-09-13 14:22:04 +08:00
李通洲 77466ba6f5 GPU: tidy 2023-09-13 14:07:14 +08:00
李通洲 3a8819d42b Wifi: support JSON format 2023-09-13 14:01:15 +08:00
李通洲 9765885fe6 Wallpaper: support JSON format 2023-09-13 13:39:56 +08:00
李通洲 16b01a06e0 Vulkan: support JSON format 2023-09-13 09:53:25 +08:00
李通洲 c400261a11 Deps: update yyjson 2023-09-13 09:42:34 +08:00
李通洲 9b72971dc9 Uptime (FreeBSD): fix building 2023-09-13 08:49:10 +08:00
李通洲 4449173b3d Version: support JSON config 2023-09-12 20:36:00 +08:00
李通洲 10a249d3a8 Title: support JSON support 2023-09-12 20:31:19 +08:00
李通洲 e91d011c8c Theme: support JSON format 2023-09-12 20:23:58 +08:00
李通洲 4124c12bac TerminalSize: support JSON format 2023-09-12 16:17:17 +08:00
李通洲 a927f4a04d DateTime: code refactor using ffTimeGetNow 2023-09-12 16:15:57 +08:00
李通洲 f3ec60a061 Uptime: add ffTimeGetNow() and use it 2023-09-12 14:55:33 +08:00
李通洲 2251086c0f TerminalFont: support JSON format 2023-09-12 11:18:05 +08:00
李通洲 9447f1ca80 Terminal: support JSON format 2023-09-12 09:49:36 +08:00
李通洲 f13b771317 Sound: support JSON format 2023-09-12 09:37:24 +08:00
李通洲 257439477e CI: update deps 2023-09-12 09:12:28 +08:00
李通洲 c702865332 Presets: add a new example
Ref: https://github.com/fastfetch-cli/fastfetch/discussions/556
2023-09-11 23:03:03 +08:00
李通洲 e2abe31fc1 Monitor: fix memleaks 2023-09-10 18:39:45 +08:00
李通洲 82c300f7f6 Logo (Builtin): add Afterglow
https://github.com/hykilpikonna/hyfetch/pull/
2023-09-08 21:22:00 +08:00
李通洲 94eb3b89e8 Logo (Builtin): use first color as title color
As what neofetch does
2023-09-08 21:22:00 +08:00
李通洲 f662cc0aa2 Logo (Builtin): update AOSC OS
Ref: https://github.com/hykilpikonna/hyfetch/pull/185
2023-09-08 21:21:33 +08:00
李通洲 1526930e54 Logo (Builtin): update EvolutionOS
Ref: #555
2023-09-08 21:06:37 +08:00
李通洲 1cdc99f327 JSON format: fix some memleaks 2023-09-08 20:25:41 +08:00
李通洲 d97b16950c Shell: JSON format support 2023-09-08 20:02:59 +08:00
李通洲 aff4a57092 Processes: JSON format support 2023-09-08 15:47:37 +08:00
李通洲 826aa2e46d Packages: support JSON format 2023-09-08 15:44:44 +08:00
李通洲 2c59a05dff Users: JSON format support 2023-09-08 15:31:58 +08:00
李通洲 aafd773fe7 Uptime: JSON format support 2023-09-08 15:31:58 +08:00
李通洲 4356974c5b Image: fix separated image printing 2023-09-08 15:31:58 +08:00
李通洲 7f1e2d2f03 Packages (Windows): support winget packages count
Guarded behind `--allow-slow-operations`
2023-09-08 15:25:22 +08:00
李通洲 cde2ba2c18 Uptime: detect boot time 2023-09-08 14:17:34 +08:00
李通洲 a093ca2001 Users: add more detailed information 2023-09-08 10:11:57 +08:00
李通洲 fe9fcd603b CPU (Windows): fix possible memory errors 2023-09-08 10:11:57 +08:00
李通洲 d8b2151143 CPU (macOS): support Apple Silicon frequency detection 2023-09-08 10:11:56 +08:00
李通洲 904c9eb3c4 CPU (macOS): code refactor 2023-09-08 10:11:31 +08:00
李通洲 598dfd2b02 Disk (Apple): use getattrlist to detect volume name
No functional changes
2023-09-08 10:11:29 +08:00
李通洲 77d388ce1d Disk (BSD): use getfsstat instead of getmntinfo for thread safety 2023-09-07 15:47:49 +08:00
李通洲 9eb35d3967 OS: JSON format support 2023-09-07 09:36:04 +08:00
李通洲 34902db21c OpenGL: JSON format support 2023-09-07 09:28:04 +08:00
李通洲 cdaf5e9281 OpenCL: JSON format support 2023-09-07 09:20:52 +08:00
李通洲 98833b4d74 Monitor: add JSON support 2023-09-06 16:33:51 +08:00
李通洲 f995d8d806 PowerAdapter: rename PowerAdapterResult to FFPowerAdapterResult 2023-09-06 16:27:02 +08:00
李通洲 eb4636b947 PowerAdapter: JSON format support 2023-09-06 16:23:57 +08:00
李通洲 a7c6e1165c Swap: JSON format support 2023-09-06 16:01:10 +08:00
李通洲 8bb88d1806 Memory: JSON format support 2023-09-06 15:59:56 +08:00
李通洲 849ff95116 Player: JSON format support 2023-09-06 15:53:52 +08:00
李通洲 dc29271987 Media: add JSON format support 2023-09-06 15:48:39 +08:00
李通洲 623c5d8eb9 LocalIP: add JSON format support 2023-09-05 16:31:54 +08:00
李通洲 e0ce520e0a Locale: add JSON format support 2023-09-05 16:25:08 +08:00
李通洲 f9cd032a5f LM: add JSON format support 2023-09-05 16:22:37 +08:00
李通洲 39b21f95b7 Kernel: add JSON format support 2023-09-05 16:10:28 +08:00
李通洲 dfbfb88a45 Icons: add JSON formatting support 2023-09-05 16:10:28 +08:00
李通洲 971a69ad1b Host: add JSON formatting support 2023-09-05 15:57:18 +08:00
李通洲 fddf6ddf1e CPU: don't use NaN in JSON 2023-09-05 15:51:09 +08:00
李通洲 81c625e7c9 GPU: add JSON printing support 2023-09-05 15:49:22 +08:00
李通洲 97293ddee1 Gamepad: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 21f36b564f Font: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 34e2b0f89c Display: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 d5ca6aa462 Disk: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 639ad436a0 Global: code refactor 2023-09-05 15:29:46 +08:00
李通洲 76fce2c5a9 DE: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 632718e1d0 DateTime: support JSON printing 2023-09-05 15:29:46 +08:00
李通洲 a4fababb71 Cursor: add JSON format support 2023-09-05 15:29:46 +08:00
李通洲 ac8741d57d CPUUsage: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 28e412b79d CPU: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 01aa9b9516 Command: add JSON printing support 2023-09-05 15:29:46 +08:00
李通洲 acd353b8b3 Chassis: add Json printing support 2023-09-05 15:29:46 +08:00
李通洲 c5d8d976f6 Brightness: add Json printing support 2023-09-05 15:29:46 +08:00
李通洲 3d44514b24 Board: support Json printing 2023-09-05 15:29:46 +08:00
李通洲 fb3fb1bf99 Bluetooth: rename FFBluetoothDevice to FFBluetoothResult 2023-09-05 15:29:46 +08:00
李通洲 757e5f8174 Bluetooth: support Json printing 2023-09-05 15:29:46 +08:00
李通洲 3669f2aee4 Battery: rename BatteryResult to FFBatteryResult 2023-09-05 15:29:46 +08:00
李通洲 14f26879de Global: init --format json support (#527) 2023-09-05 15:29:46 +08:00
李通洲 2f46a77ff2 TerminalFont: better kitty font detection 2023-09-04 19:19:55 +08:00
李通洲 10853fdf35 Doc: add note for image protocol support of Android 2023-09-03 22:51:28 +08:00
李通洲 591fd558e1 Logo: fix --logo-padding for --logo-separate 2023-09-03 22:39:09 +08:00
李通洲 b863e65ea3 OpenGL: silence warnings 2023-09-03 22:21:53 +08:00
李通洲 fc61f64630 Logo: add --logo-separate true 2023-09-03 22:20:11 +08:00
李通洲 3483673ef7 Terminal (Android): fix termux detection 2023-09-03 20:57:23 +08:00
李通洲 9e839d3b8b Logo: simplify code 2023-09-03 19:55:57 +08:00
李通洲 33f121d7fb JsonSchema: fix the name of property defaultRouteOnly 2023-09-03 19:01:52 +08:00
李通洲 9500ca8f83 Logo: fix poll() timeout or failed error when image is very large
Fix #554
2023-09-03 17:50:20 +08:00
李通洲 4dfbc0f909 Logo: try fixing #553 2023-09-02 22:32:34 +08:00
李通洲 effb685fba Logo: try improving performance for image-raw 2023-09-02 10:08:08 -04:00
李通洲 3692e49e9b TerminalShell: correctly set PATH_MAX on Linux 2023-09-02 10:05:30 -04:00
李通洲 04d56d9b6a IO: fix short read when reading from pipe 2023-09-02 10:04:57 -04:00
李通洲 34417ae692 TerminalFont: support contour 2023-09-02 08:11:21 -04:00
李通洲 67d04a746e Terminal: support contour version detection 2023-09-02 07:40:23 -04:00
李通洲 552e0f84aa Doc: update changelog 2023-09-02 00:47:05 -04:00
李通洲 3e880fedf7 Logo: support kitty-direct / iterm without specifying logo width / height
Fixes #550
2023-09-02 00:46:39 -04:00
李通洲 e5c4a6ed2c Logo (Builtin): update EvolutionOS
Closes #551
2023-09-01 23:29:23 -04:00
李通洲 0bda7d80c2 Doc: update README for image logo on Windows 2023-08-30 22:21:29 +08:00
李通洲 7cb86df48d Logo: improve performance on Windows for iterm protocol 2023-08-30 22:17:51 +08:00
李通洲 21e5df2826 Global: replace cpu-usage to cpuusage 2023-08-29 17:47:20 +08:00
李通洲 a5ee51e156 Global: use FF_LIST_AUTO_DESTROY 2023-08-29 10:49:22 +08:00
李通洲 bddcb4772c DE (FreeBSD): add fast path for xfce4 version detection 2023-08-29 10:47:24 +08:00
Carter Li a3f13bdca9 Merge pull request #545 from fastfetch-cli/dev
Release v2.0.5
2023-08-26 20:31:27 +08:00
李通洲 55444b9c4e Release v2.0.5 2023-08-26 08:16:06 -04:00
李通洲 2f14d7742e Display (Linux): fix memleaks 2023-08-26 05:52:06 -04:00
李通洲 0534882f4e Cursor: Don't print 0px 2023-08-26 05:43:15 -04:00
李通洲 ce2f2f4416 Doc: update changelog 2023-08-26 05:31:00 -04:00
李通洲 5259aeb039 Display: fix segfault when using libxrandr
Fix #544
2023-08-26 05:28:21 -04:00
李通洲 e51999edd1 Doc: update changelog 2023-08-26 13:43:33 +08:00
李通洲 2f96c847b9 Disk: print Read-only 2023-08-26 13:43:33 +08:00
李通洲 32d6436027 Disk: add --disk-show-readonly 2023-08-26 13:43:33 +08:00
李通洲 7358326a13 Disk: add --disk-use-available
fix #543
2023-08-26 13:43:13 +08:00
李通洲 434a879538 Disk: rename FFDiskType to FFDiskVolumeType 2023-08-26 13:40:40 +08:00
Carter Li 745a8dda65 Merge pull request #540 from fastfetch-cli/dev
Release v2.0.4
2023-08-25 15:41:50 +08:00
李通洲 c40086615f Release v2.0.4 2023-08-25 15:05:39 +08:00
李通洲 fe3d38e542 Logo: trait - as an alias for /dev/stdin
which can be useful where `/dev/stdin` is not available, eg. on Windows
2023-08-25 11:03:37 +08:00
李通洲 f19a3b5549 Logo: fix --file-raw doesn't work
Fix #539
Ref https://github.com/hykilpikonna/hyfetch/issues/173
2023-08-25 11:01:48 +08:00
李通洲 eb308e1861 Memory (BSD): fix building on 32-bit FreeBSD
fix #538
2023-08-25 08:47:16 +08:00
Carter Li 9a4e7874d6 Merge pull request #536 from fastfetch-cli/dev
Release 2.0.3
2023-08-24 19:12:52 +08:00
李通洲 d78e528527 CI: generate 7z archive 2023-08-24 16:18:10 +08:00
李通洲 81f0e4d583 cI: really bundle presets 2023-08-24 15:13:25 +08:00
李通洲 1d9f462071 Release: 2.0.3 2023-08-24 14:43:19 +08:00
李通洲 047dca3849 CI: include presets (Windows) 2023-08-24 14:42:47 +08:00
李通洲 1f7c6ab70c Fastfetch: add --config 2023-08-24 14:36:32 +08:00
李通洲 1c49ae5324 Fastfetch: try $exePath/presets with --load-config 2023-08-24 14:29:35 +08:00
李通洲 2e82f8294f Doc: document --precent-ndigits 2023-08-24 14:21:08 +08:00
李通洲 b2ead8735b Platform (Unix): add exePath 2023-08-24 14:20:48 +08:00
李通洲 5e9166847d Platform (Windows): add exePath 2023-08-24 13:47:25 +08:00
李通洲 28c01599d5 Platform: add $EXE_PATH/../share to dataDir
Support loading presets when fastfetch is installed in a special path. eg. `/opt/homebrew/bin/`
2023-08-24 11:14:51 +08:00
李通洲 ce47a82fb5 Doc: update changelog 2023-08-24 10:46:38 +08:00
李通洲 f1b047c32b Display: use FFDisplayOptions 2023-08-24 09:55:40 +08:00
李通洲 bc6ed4f4a2 OpenGL: use FFOpenGLOptions in detection code 2023-08-24 09:55:00 +08:00
李通洲 b1ac31f590 Global: add option --percent-ndigits 2023-08-24 09:35:17 +08:00
李通洲 326d83f25b Global: fix percent formatting for --*-format
fix #535
2023-08-24 09:12:24 +08:00
李通洲 7218164088 Doc: add more badges in README 2023-08-24 08:36:53 +08:00
Ian Manske 6f970c36e3 Fix typo in config parsing for --color-title 2023-08-24 08:32:56 +08:00
Carter Li eea4150dbd Merge pull request #532 from fastfetch-cli/dev
Release v2.0.2
2023-08-22 05:26:33 -04:00
李通洲 afa736c37d Release v2.0.2 2023-08-22 16:17:05 +08:00
李通洲 643e632368 CMake: try fixing CI on FreeBSD 2023-08-22 16:14:24 +08:00
Carter Li ffe354ab07 Merge pull request #531 from fastfetch-cli/dev
Release v2.0.2
2023-08-22 03:57:27 -04:00
李通洲 f77090070c Image: code cleanup; no functional change 2023-08-22 15:32:19 +08:00
李通洲 fd5d2c84e8 Logo (Builtin): add Tuxedo OS 2023-08-21 22:46:50 +08:00
李通洲 ef6af84ea1 Fastfetch: fix presets not detected by file name (#529) 2023-08-21 22:14:44 +08:00
李通洲 f64bf73279 Windows: fix compiling for GCC 2023-08-21 20:28:27 +08:00
Carter Li 157be8443d Merge pull request #526 from fastfetch-cli/dev
Release v2.0.1 (stable)
2023-08-20 22:35:09 -04:00
李通洲 154e15e88f Release: v2.0.1 2023-08-21 10:05:41 +08:00
李通洲 159122eb98 Brightness (macOS): silence compiler warnings 2023-08-21 09:38:20 +08:00
李通洲 7b6e157a4d Doc: update bug_report.md 2023-08-21 09:26:07 +08:00
李通洲 c6eff111cc Fastfetch: refactor printVersion() 2023-08-21 09:22:03 +08:00
李通洲 f23384725f Version: add new module 2023-08-21 09:19:16 +08:00
李通洲 970863e7df Global: simplify code of module matching 2023-08-20 21:35:38 +08:00
李通洲 0b473e3bff Fastfetch: refactor the code of --list-modules 2023-08-20 20:51:55 +08:00
李通洲 5a43adb62b Doc: update changelog 2023-08-20 00:09:48 +08:00
李通洲 1a4a949dfe Logo (Builtin): add aerOS 2023-08-20 00:04:52 +08:00
李通洲 069c20be40 Brightness: don't make DDC/CI a slow operation 2023-08-19 02:16:04 -04:00
李通洲 c7f0172b25 CMake: Add option ENABLE_SYSTEM_YYJSON
Fix: #525
2023-08-19 11:11:50 +08:00
李通洲 125759dc75 Terminal: correctly detecting version and font on NixOS 2023-08-19 10:02:07 +08:00
李通洲 f0a10fcc6d Disk (BSD): improve disk type detection 2023-08-18 20:57:54 +08:00
李通洲 c70b9cb84e Revert "Disk (BSD): try detecting disk label"
Doesn't work

This reverts commit 55b9e274b6.
2023-08-18 21:21:34 +08:00
李通洲 5ebdd9a989 Logo (Builtin): add MOS
Ref: https://github.com/dylanaraps/neofetch/pull/2364
2023-08-18 13:44:48 +08:00
李通洲 77e0d9dba1 JsonConfig: prepare for module weather and public ip 2023-08-18 13:38:32 +08:00
李通洲 55b9e274b6 Disk (BSD): try detecting disk label 2023-08-18 09:52:21 +08:00
李通洲 67fe1e66b5 Windows: fix build 2023-08-17 17:15:30 +08:00
李通洲 ea2a26bd57 Battery (Linux): fix build 2023-08-17 16:13:54 +08:00
李通洲 55b279ab09 JsonConfig: remove useless checks 2023-08-17 16:10:05 +08:00
李通洲 e5e4c8bf88 Fastfetch: refactor command line option parsing code
1. improve performance
2. remove `-c`
3. rename `--recache` to `--logo-recache`, and remove `-r`
2023-08-17 16:10:05 +08:00
李通洲 c888254f70 Modules: major code refactor
Also fix some bugs found when refactoring
2023-08-17 16:10:02 +08:00
李通洲 75323d64f8 Chore: fix typo 2023-08-16 16:51:54 +08:00
李通洲 a0c4f2febd Global: support --bar-width 2023-08-16 16:51:41 +08:00
李通洲 4b714c7057 Doc: update changelog 2023-08-16 14:52:20 +08:00
李通洲 559bca4223 Global: add --bar-char-elapsed, --bar-char-total and --bar-border options 2023-08-16 14:41:56 +08:00
李通洲 8ed28673a9 Global: support --module-key-width per module 2023-08-16 13:21:15 +08:00
李通洲 ed9639c66b Disk (Linux): replace all \\x20 to real charactors in disk label 2023-08-15 21:11:52 +08:00
李通洲 98b9ef74cf Disk (Linux): fix label detection 2023-08-15 21:11:52 +08:00
李通洲 e6be90614a fastfetch: support --key-width 2023-08-15 21:11:52 +08:00
李通洲 20c2cdf7ba Monitor (Linux): fix EDID file reading
Its file length is always 0
2023-08-15 19:20:21 +08:00
李通洲 c70787bde9 Fastfetch: tidy 2023-08-15 16:52:35 +08:00
李通洲 8835f66b8c Fastfetch: unescape strings only when parsing .conf files
So that `NO_CONFIG=1 ./fastfetch --os-key \\\\ -s os -l none` prints `\\: *`
2023-08-15 16:41:04 +08:00
李通洲 2b2ebe0823 Logo (Builtin): update venom; add venom_small 2023-08-15 15:24:31 +08:00
李通洲 3ff3feb0e1 EdidHelper: silence compiler warnings 2023-08-14 20:48:37 +08:00
李通洲 ee4bc2302a Chore: move mk_wcwidch to 3rdparty folder 2023-08-14 20:48:37 +08:00
李通洲 cd4a512291 Chore: embed yyjson source code
Ref: https://github.com/fastfetch-cli/fastfetch/discussions/523
2023-08-14 20:48:37 +08:00
377 changed files with 27389 additions and 4570 deletions
+1 -6
View File
@@ -19,11 +19,6 @@ assignees: ''
# Often helpful information:
Output of `fastfetch --version`:
```
//paste here
```
The content of the configuration file you use (if any)
```
//paste here
@@ -34,7 +29,7 @@ Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --mu
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`.
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false && fastfetch --version`.
-->
```
+66 -26
View File
@@ -13,24 +13,29 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
compiler: [gcc, clang, "musl-gcc"]
compiler: [
{ cc: gcc, cxx: "g++" },
{ cc: clang, cxx: "clang++" },
{ cc: "musl-gcc", cxx: "musl-g++" }
]
enableFeatures: [ON, OFF]
exclude:
# The feature libraries are all build against glibc, so they can't be used with musl
- compiler: "musl-gcc"
- compiler: { cc: "musl-gcc", cxx: "musl-g++" }
enableFeatures: ON
runs-on: ${{ matrix.os }}
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
- name: configure project
env:
CC: ${{ matrix.compiler }}
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_JSONC=${{ matrix.enableFeatures }} .
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_JSONC=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} .
- name: build project
run: cmake --build .
@@ -39,10 +44,13 @@ jobs:
run: ctest
- name: run fastfetch
run: ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: ./flashfetch
run: time ./flashfetch
linux:
name: Linux
@@ -54,10 +62,10 @@ jobs:
ffversion: ${{ steps.ffversion.outputs.ffversion }}
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
@@ -77,11 +85,17 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
@@ -103,7 +117,7 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: install required packages
run: brew install vulkan-loader molten-vk imagemagick chafa
@@ -126,11 +140,17 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: otool -L fastfetch
- name: run tests
run: ctest
@@ -148,19 +168,21 @@ jobs:
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: run VM
uses: vmactions/freebsd-vm@v0
with:
prepare: |
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package
./fastfetch --list-features
time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
time ./fastfetch -c presets/ci
time ./fastfetch -c presets/ci --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
@@ -180,14 +202,14 @@ jobs:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: CLANG64
update: true
install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
- name: print msys version
run: uname -a
@@ -213,22 +235,31 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
- name: create zip archive
run: zip fastfetch-$(./fastfetch --version-raw)-Win64.zip *.dll fastfetch.exe flashfetch.exe
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.zip *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win64.7z *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v3
with:
name: fastfetch-win64
path: ./fastfetch-*-Win64.zip
path: ./fastfetch-*-Win64.*
win32:
name: Win32
@@ -241,14 +272,14 @@ jobs:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: CLANG32
update: true
install: git zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd
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-opencl-icd
- name: print msys version
run: uname -a
@@ -271,22 +302,31 @@ jobs:
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
- name: run fastfetch
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors --no-buffer --load-config presets/all
run: time ./fastfetch -c presets/ci
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
- name: create zip archive
run: zip fastfetch-$(./fastfetch --version-raw)-Win32.zip *.dll fastfetch.exe flashfetch.exe
run: 7z a -tzip -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.zip *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-$(./fastfetch --version-raw)-Win32.7z *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v3
with:
name: fastfetch-win32
path: ./fastfetch-*-Win32.zip
path: ./fastfetch-*-Win32.*
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
+142 -2
View File
@@ -1,4 +1,144 @@
# 2.0.0 (beta)
# 2.1.1
Features:
* Support opkg (Packages, Linux)
* Support GNOME Console terminal version and font detection (Terminal, Linux)
* Add `--cpu-freq-ndigits` to set number of digits for CPU frequency (CPU)
* New module to detect physical disk I/O usage (DiskIO)
* Add `--cpuusage-separate` to display CPU usage per CPU logical core
* Add `--brightness-ddcci-sleep` to set the sleep times (in ms) when sending DDC/CI requests (Brightness, #580)
Bugfixes:
* Fix possible crashes on Windows 7 (Disk, Windows)
* Fix possible crashes caused by uninitialized strings (Users, Windows)
* Improve support of `--help *-format` and several bugs are found and fixed
* Don't incorrectly print `No active sound devices found` when using a non-controllable sound device (Sound, macOS)
* Fix implementation processes counting (Processes, Linux)
* Work around a issue that SSID cannot be detected on macOS Sonoma (Wifi, macOS)
Logo:
* Add Chimera Linux
* Add EndeavourSmall
* Add Xenia
# 2.1.0
This release introduces a new output format: JSON result
Changes:
* Users module detects and prints user login time by default. Specifying `--users-compact` to disable it
* Fastfetch now requires yyjson 0.8.0 or later, which is embeded in fastfetch source tree. If you build fastfetch with `-DENABLE_SYSTEM_YYJSON` cmake option, you must upgrade your yyjson package
* Reduced information supported by `--terminal-format`, `--shell-format`
* Some config presets (`devinfo` and `verbose`) are obseleted and removed. They are barely maintained and can be replaced with `--format json` now.
* Custom strings in `--module-key` and `--module-format` are no longer trimmed.
* `/boot` is hidden by default (FreeBSD, Disk)
Features:
* Add `--format json`, which prints system information as JSON format
* Add fast path for xfce4 version detection (DE, FreeBSD)
* Support contour terminal version and font detection (Terminal / TerminalFont)
* Support `kitty-direct` / `iterm` without specifying logo width / height. Note: in this case, the entre screen will be cleared.
* Support new flag `--logo-separate`. If true, print modules at bottom of the logo
* Support Apple Silicon CPU frequency detection (CPU, macOS)
* Support user login time detection (Users)
* Support winget package manager detection, guarded behind `--allow-slow-operations` (Packages, Windows)
* Print monitor type (built-in or external) (Display)
* Support full GPU detection in WSL (Linux, GPU)
* Add `--module-key " "` as a special case for hiding keys
* Support `--title-format`. See `fastfetch --help title-format` for detail
* Support `--colors-key` (Colors)
* Add `-c` as a shortcut of `--load-config`. Note it was used as the shortcut of `--color` before 2.0.5
* Support Windows Service Pack version detection (Kernel, Windows)
* Support Debian point releases detection (OS, Linux)
* Add new module `NetIO` which prints network throughput (usage) of specified interface. Note this module costs about 1 second to finish.
* Use `lscpu` to detect CPU name for ARM CPUs (CPU, Linux)
Bugfixes:
* Fix fastfetch hanging in specific environment (#561)
* Fix short read when reading from stdin (Logo)
* Fix `poll() timeout or failed` error when image is very large (Logo)
* Fix Termux Monet terminal version detection (Terminal)
* Fix zpool volumes detection (Disk, Linux)
* Fix external volumes detection (Disk, Linux)
* Fix snap package number detection on systems other than Ubuntu (Packages, Linux)
* Fix dpkg / apt package number detection (Packages, Linux)
* Fix bluetooth mac address detection (Bluetooth, Windows)
Logo:
* Add Afterglow
* Add Elbrus
* Update EvolutionOS
* Update AOSC OS
* Update Ubuntu_old
* Update Windows 11_small
* Add Amazon Linux
* Add LainOS
* Fix colors of Slackware
# 2.0.5
Bugfixes:
* Fix segfault when using libxrandr (#544, Display, Linux)
* Don't print 0px (#544, Cursor)
Features:
* Add option `--disk-use-available` (#543)
* Add option `--disk-show-readonly`
# 2.0.4
Bugfixes:
* Fix building on 32-bit FreeBSD (Memory, FreeBSD)
* Fix `--file-raw` doesn't work (Logo)
Features:
* Trait `-` as an alias for `/dev/stdin`. Available for `--file`, `--file-raw` and `--raw` (Logo)
# 2.0.3
Bugfixes:
* Fix typo in config parsing for --color-title (#534)
* Fix percent formatting for `--*-format` (#535)
* Fix loading presets for homebrew (macOS)
Features:
* Add option `--percent-ndigits`
* Add command flag `--config` as an alias of `--load-config`
* Windows packages now include presets (Windows)
# 2.0.2
Bugfixes:
* Workarund [a compiler bug of GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282) (Windows)
* Fix presets not detected by file name (#529)
Logo:
* Add Tuxedo OS
# 2.0.1
First stable release of Fastfetch V2
Changes:
* Unescape strings only when parsing `.conf` files
* Previously: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\: *`. Note the backslashs are unescaped twice (once by shell and once by fastfetch).
* Now: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\\: *`
* Remove option shortcut `-c` (alias of `--color`), which is more commonly used as alias of `--config`
* Rename `--recache` to `--logo-recache` (which is used for regenerate image logo cache). Remove option shortcut `-r` (alias of `--recache`).
* Detecting brightness of external displays with DDC/CI is no longer guarded behind `--allow-slow-operations` (Brightness)
Features:
* Add `--key-width` for aligning the left edge of values, supported both for global `--key-width` and specific module `--module-key-width`
* Add `--bar-char-elapsed`, `--bar-char-total`, `--bar-width` and `--bar-border` options
* Add CMake option `ENABLE_SYSTEM_YYJSON`, which allow building fastfetch with system-provided yyjson (for package managers)
* Add new module `Version`, which prints fastfetch version (like `fastfetch --version`)
Bugfixes:
* Fix label detection. Use `--disk-key 'Disk ({2})'` to display it (Disk, Linux)
* Fix some module options were not inited
* Fix terminal version and font detection on NixOS (Terminal, Linux)
# 2.0.0-beta
Fastfetch v2 introduces a new configuration file format: JSON config. Please refer to <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration> for details.
@@ -32,7 +172,7 @@ Features:
* Support iTerm non-ascii font detection (Terminal, macOS)
* Add option `--title-color-user`, `--title-color-at` and `--title-color-host` (Title)
* Add Exherbo logo and package manager count (Packages, Linux, #503)
* Add module `Terminal Size` which prints the number of terminal width and height in charactors and pixels
* Add module `Terminal Size` which prints the number of terminal width and height in characters and pixels
* Add new option `--temperature-unit`
* Better CPU and Host detection for Android (Android)
* Support yakuake terminal version & font detection (Terminal, Linux)
+113 -32
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url & FetchContent
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.0.0
VERSION 2.1.1
LANGUAGES C
DESCRIPTION "Fast system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -36,24 +36,6 @@ endif()
include(CheckIncludeFile)
include(FetchContent)
function(ff_fetch_dep package repo tag)
FetchContent_Declare(
"${package}"
GIT_REPOSITORY "${repo}"
GIT_TAG "${tag}"
GIT_PROGRESS TRUE
)
FetchContent_GetProperties("${package}")
if(NOT ${package}_POPULATED)
message("-- Fetching dependency ${package}@${tag} from ${repo}")
FetchContent_Populate(${package})
add_subdirectory(${${package}_SOURCE_DIR} ${${package}_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
endfunction()
ff_fetch_dep(yyjson "https://github.com/ibireme/yyjson" "0.7.0")
#####################
# Configure options #
#####################
@@ -85,8 +67,10 @@ cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
cmake_dependent_option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
option(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
@@ -115,10 +99,13 @@ set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=retu
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
if(WIN32)
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -fno-exceptions -fno-rtti")
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")
endif()
@@ -129,8 +116,8 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
endif()
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
if(NOT WIN32)
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined")
if(NOT WIN32 AND NOT APPLE)
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address")
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
@@ -138,8 +125,8 @@ if(NOT WIN32)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -rdynamic")
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Enabling LTO")
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORTED)
if(IPO_SUPPORTED)
@@ -228,7 +215,6 @@ fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/config_system.txt DATATEXT_CONFIG_SYSTEM)
fastfetch_load_text(src/data/config_user.txt DATATEXT_CONFIG_USER)
fastfetch_load_text(src/data/config_user.jsonc DATATEXT_CONFIG_USER_JSONC)
fastfetch_load_text(src/data/modules.txt DATATEXT_MODULES)
fastfetch_load_text(src/data/help.txt DATATEXT_HELP)
fastfetch_load_text(src/data/help_color.txt DATATEXT_HELP_COLOR)
fastfetch_load_text(src/data/help_format.txt DATATEXT_HELP_FORMAT)
@@ -236,6 +222,9 @@ fastfetch_load_text(src/data/help_config.txt DATATEXT_HELP_CONFIG)
configure_file(src/fastfetch_config.h.in fastfetch_config.h @ONLY)
configure_file(src/fastfetch_datatext.h.in fastfetch_datatext.h @ONLY)
if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
endif()
####################
# Ascii image data #
@@ -270,11 +259,14 @@ file(GENERATE OUTPUT logo_builtin.h CONTENT "${LOGO_BUILTIN_H}")
set(LIBFASTFETCH_SRC
src/common/bar.c
src/common/commandoption.c
src/common/font.c
src/common/format.c
src/common/init.c
src/common/jsonconfig.c
src/common/library.c
src/common/modules.c
src/common/netif/netif.c
src/common/option.c
src/common/parsing.c
src/common/printing.c
@@ -283,19 +275,23 @@ set(LIBFASTFETCH_SRC
src/detection/chassis/chassis.c
src/detection/cpu/cpu.c
src/detection/cpuusage/cpuusage.c
src/detection/datetime/datetime.c
src/detection/disk/disk.c
src/detection/diskio/diskio.c
src/detection/displayserver/displayserver.c
src/detection/font/font.c
src/detection/gpu/gpu.c
src/detection/locale/locale.c
src/detection/media/media.c
src/detection/netio/netio.c
src/detection/opencl/opencl.c
src/detection/os/os.c
src/detection/packages/packages.c
src/detection/publicip/publicip.c
src/detection/terminalfont/terminalfont.c
src/detection/terminalshell/terminalshell.c
src/detection/version/version.c
src/detection/vulkan/vulkan.c
src/detection/weather/weather.c
src/logo/builtin.c
src/logo/image/im6.c
src/logo/image/im7.c
@@ -318,6 +314,7 @@ set(LIBFASTFETCH_SRC
src/modules/datetime/datetime.c
src/modules/de/de.c
src/modules/disk/disk.c
src/modules/diskio/diskio.c
src/modules/font/font.c
src/modules/gpu/gpu.c
src/modules/host/host.c
@@ -329,6 +326,7 @@ set(LIBFASTFETCH_SRC
src/modules/localip/localip.c
src/modules/memory/memory.c
src/modules/monitor/monitor.c
src/modules/netio/netio.c
src/modules/opencl/opencl.c
src/modules/opengl/opengl.c
src/modules/os/os.c
@@ -350,6 +348,7 @@ set(LIBFASTFETCH_SRC
src/modules/title/title.c
src/modules/uptime/uptime.c
src/modules/users/users.c
src/modules/version/version.c
src/modules/vulkan/vulkan.c
src/modules/wallpaper/wallpaper.c
src/modules/weather/weather.c
@@ -368,6 +367,7 @@ if(LINUX)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_linux.c
src/common/networking_linux.c
src/common/processing_linux.c
src/detection/battery/battery_linux.c
@@ -380,6 +380,7 @@ if(LINUX)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/wayland.c
src/detection/displayserver/linux/wmde.c
@@ -390,12 +391,14 @@ if(LINUX)
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
src/detection/libc/libc_linux.c
src/detection/lm/lm_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_linux.c
src/detection/media/media_linux.c
src/detection/memory/memory_linux.c
src/detection/monitor/monitor_linux.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
src/detection/packages/packages_linux.c
@@ -419,6 +422,7 @@ if(LINUX)
elseif(ANDROID)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
src/common/netif/netif_linux.c
src/common/networking_linux.c
src/common/processing_linux.c
src/detection/battery/battery_android.c
@@ -431,17 +435,20 @@ elseif(ANDROID)
src/detection/cursor/cursor_nosupport.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
src/detection/gpu/gpu_nosupport.c
src/detection/host/host_android.c
src/detection/icons/icons_nosupport.c
src/detection/libc/libc_android.c
src/detection/lm/lm_nosupport.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_linux.c
src/detection/monitor/monitor_nosupport.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_android.c
src/detection/packages/packages_linux.c
@@ -465,6 +472,7 @@ elseif(BSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
@@ -478,6 +486,7 @@ elseif(BSD)
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/wayland.c
src/detection/displayserver/linux/wmde.c
@@ -489,11 +498,13 @@ elseif(BSD)
src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/libc/libc_bsd.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_bsd.c
src/detection/media/media_linux.c
src/detection/memory/memory_bsd.c
src/detection/monitor/monitor_nosupport.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
src/detection/packages/packages_linux.c
@@ -517,6 +528,7 @@ elseif(BSD)
elseif(APPLE)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
src/common/netif/netif_bsd.c
src/common/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
@@ -529,19 +541,21 @@ elseif(APPLE)
src/detection/cpu/cpu_apple.c
src/detection/cpuusage/cpuusage_apple.c
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_apple.m
src/detection/disk/disk_bsd.c
src/detection/diskio/diskio_apple.c
src/detection/displayserver/displayserver_apple.c
src/detection/font/font_apple.m
src/detection/gpu/gpu_apple.c
src/detection/host/host_apple.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_nosupport.c
src/detection/libc/libc_apple.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_apple.c
src/detection/media/media_apple.m
src/detection/memory/memory_apple.c
src/detection/monitor/monitor_apple.m
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_apple.c
src/detection/os/os_apple.m
src/detection/packages/packages_apple.c
@@ -566,6 +580,7 @@ elseif(APPLE)
elseif(WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_windows.c
src/common/netif/netif_windows.c
src/common/networking_windows.c
src/common/processing_windows.c
src/detection/battery/battery_windows.c
@@ -578,17 +593,20 @@ elseif(WIN32)
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
src/detection/disk/disk_windows.c
src/detection/diskio/diskio_windows.c
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
src/detection/lm/lm_nosupport.c
src/detection/localip/localip_windows.c
src/detection/gamepad/gamepad_windows.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_windows.c
src/detection/monitor/monitor_windows.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
src/detection/os/os_windows.cpp
src/detection/packages/packages_windows.c
@@ -615,19 +633,66 @@ elseif(WIN32)
)
endif()
if(ENABLE_DIRECTX_HEADERS)
message(STATUS "Enabling DirectX headers for WSL")
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_wsl.cpp)
endif()
include(CheckFunctionExists)
check_function_exists(wcwidth HAVE_WCWIDTH)
if(NOT HAVE_WCWIDTH)
list(APPEND LIBFASTFETCH_SRC src/util/wcwidth.c)
list(APPEND LIBFASTFETCH_SRC src/3rdparty/mk_wcwidch/wcwidth.c)
endif()
if(ENABLE_SYSTEM_YYJSON)
find_package(yyjson)
if(yyjson_FOUND)
message(STATUS "System provided yyjson is used")
else()
message(FATAL_ERROR "ENABLE_SYSTEM_YYJSON is set but system provided yyjson is not found")
endif()
else()
list(APPEND LIBFASTFETCH_SRC
src/3rdparty/yyjson/yyjson.c
)
endif()
add_library(libfastfetch OBJECT
${LIBFASTFETCH_SRC}
)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE)
if(yyjson_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
target_link_libraries(libfastfetch PRIVATE yyjson)
endif()
if(LINUX AND EXISTS "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1")
execute_process(COMMAND "/lib/ld-musl-${CMAKE_HOST_SYSTEM_PROCESSOR}.so.1"
ERROR_VARIABLE LD_MUSL_RESULT)
if("${LD_MUSL_RESULT}" MATCHES "Version ([0-9]+\\.[0-9]+\\.[0-9]+)")
target_compile_definitions(libfastfetch PUBLIC FF_MUSL_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(APPLE AND EXISTS "/usr/bin/otool")
execute_process(COMMAND /usr/bin/otool -L /usr/bin/otool
OUTPUT_VARIABLE OTOOL_OTOOL_RESULT)
if("${OTOOL_OTOOL_RESULT}" MATCHES "libSystem\\.B\\.dylib \\(.*current version ([0-9]+\\.[0-9]+\\.[0-9]+)\\)")
target_compile_definitions(libfastfetch PUBLIC FF_LIBSYSTEM_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(BSD AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[^ )]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1)
if(WIN32)
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _DARWIN_C_SOURCE)
endif()
if(HAVE_WCWIDTH)
@@ -770,6 +835,10 @@ ff_lib_enable(DDCUTIL
"ddcutil"
"Ddcutil"
)
ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
@@ -822,7 +891,9 @@ elseif(WIN32)
)
elseif(BSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "usbhid"
PRIVATE "devstat"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
@@ -847,7 +918,6 @@ target_include_directories(libfastfetch
target_link_libraries(libfastfetch
PRIVATE ${CMAKE_DL_LIBS}
PRIVATE yyjson
)
######################
@@ -862,7 +932,6 @@ target_compile_definitions(fastfetch
)
target_link_libraries(fastfetch
PRIVATE libfastfetch
PRIVATE yyjson
)
add_executable(flashfetch
@@ -873,9 +942,14 @@ target_compile_definitions(flashfetch
)
target_link_libraries(flashfetch
PRIVATE libfastfetch
PRIVATE yyjson
)
# Prevent fastfetch from linking to libstdc++
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
if(WIN32)
set(TARGET_NAME fastfetch)
target_sources(fastfetch
@@ -886,6 +960,13 @@ if(WIN32)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
)
elseif(APPLE)
target_link_options(fastfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
target_link_options(flashfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
endif()
###################
+20 -8
View File
@@ -1,6 +1,15 @@
# Fastfetch
[![CI](https://github.com/fastfetch-cli/fastfetch/actions/workflows/ci.yml/badge.svg)](https://github.com/fastfetch-cli/fastfetch/actions/workflows/ci.yml)
![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/fastfetch-cli/fastfetch/ci.yml)
![GitHub license](https://img.shields.io/github/license/fastfetch-cli/fastfetch)
![GitHub contributors](https://img.shields.io/github/contributors/fastfetch-cli/fastfetch)
![GitHub top language](https://img.shields.io/github/languages/top/fastfetch-cli/fastfetch?logo=c&label=)
![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/fastfetch-cli/fastfetch)
![homebrew downloads](https://img.shields.io/homebrew/installs/dm/fastfetch?logo=homebrew)
![GitHub all releases](https://img.shields.io/github/downloads/fastfetch-cli/fastfetch/total?logo=github)
![GitHub release (with filter)](https://img.shields.io/github/v/release/fastfetch-cli/fastfetch?logo=github)
[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
@@ -62,6 +71,7 @@ The following libraries are used if present at runtime:
* [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection.
* [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection.
* [`libddcutil`](https://github.com/rockowitz/ddcutil): Used for brightness detection of external displays
* [`DirectX-Headers`](https://github.com/microsoft/DirectX-Headers): Used for GPU detection in WSL
### macOS
@@ -82,35 +92,37 @@ For the image logo, iTerm with iterm image protocol should work. Apple Terminal
Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, as fastfetch for Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library, [it must be installed manually](https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c) as UCRT is only pre-installed in Windows 10 and later.
For the image logo, only chafa is supported due to [a design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not included by default due to the massive dependencies of imagemagick. You must built it yourself.
For the image logo, WezTerm with iterm image protocol is known to work, surprisingly.
### Android
* [`freetype`](https://www.freetype.org/): Used for Termux font detection. [`freetype`](https://github.com/termux/termux-packages/tree/master/packages/freetype)
* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. [`vulkan-loader-android`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-loader-android) [`vulkan-headers`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-headers)
* [`termux-api`](https://github.com/termux/termux-api-package): Used for Wifi / Battery detection. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail or if you hang on these modules (IMPORTANT). [`termux-api`](https://github.com/termux/termux-packages/tree/master/packages/termux-api)
* [`termux-api`](https://github.com/termux/termux-api-package): Used for Wifi / Battery detection. Both the package [termux-api](https://github.com/termux/termux-packages/tree/master/packages/termux-api) and the Android app [Termux API](https://github.com/termux/termux-api) must be installed and the app `Termux API` must be configured to be able to self-running. In order to make Wifi detection actuall work, location privilege must be granted to the app `Termux API`. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail.
* [`libandroid-wordexp-static`](https://github.com/termux/termux-packages/tree/master/packages/libandroid-wordexp): `wordexp.h` support for Android.
For the image logo, [Termux Monet](https://github.com/HardcodedCat/termux-monet) supports iterm image protocol.
## Support status
All categories not listed here should work without needing a specific implementation.
##### Available Modules
```
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, OpenCL, OpenGL, Packages, Player, Power Adapter, Processes, PublicIP, Separator, OS, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Vulkan, Wallpaper, Wifi, WM, WMTheme
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, DiskIO, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, NetIO, OpenCL, OpenGL, OS, Packages, Player, Power Adapter, Processes, PublicIP, Separator, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Version, Vulkan, Wallpaper, Weather, Wifi, WM, WMTheme
```
##### Builtin logos
<!-- `Content of src/logo/builtin.c`.split('\n').map(x => x.trim()).filter(x => x.startsWith('// ')).map(x => x.slice(3)).sort((a,b)=>a.toUpperCase().localeCompare(b.toUpperCase())).join(', ') -->
<!-- `Content of src/logo/builtin.c`.split('\n').map(x => x.trim()).filter(x => x.startsWith('// ')).map(x => x.slice(3)).filter(x => x != 'LAST').sort((a, b)=>a.toUpperCase().localeCompare(b.toUpperCase())).join(', ') -->
```
AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, Endless, Enso, EuroLinux, EvolutionOS, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LangitKetujuh, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, LAST, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xferience, YiffOS, Zorin
AerOS, Afterglow, AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmazonLinux, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOS_old, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, Chimera Linux, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elbrus, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, EndeavourSmall, Endless, Enso, EuroLinux, EvolutionOS, EvolutionOS_old, EvolutionOSSmall, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, MOS, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, TuxedoOS, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, VenomSmall, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xenia, Xferience, YiffOS, Zorin
```
Run `fastfetch --print-logos` to print them
##### Package managers
```
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, opkg, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
```
##### WM themes
@@ -125,7 +137,7 @@ Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
##### Terminal fonts
```
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Console, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
```
## Building
+1 -1
View File
@@ -24,7 +24,7 @@ __fastfetch_complete_help()
"terminal-format"
"terminalfont-format"
"cpu-format"
"cpu-usage-format"
"cpuusage-format"
"gpu-format"
"memory-format"
"swap-format"
+384 -43
View File
@@ -17,6 +17,12 @@
"title": "Color of the module key. Left empty to use `display.color.keys`",
"$ref": "#/$defs/colors"
},
"keyWidth": {
"title": "Width of the module key. Use 0 to use `display.keyWidth`",
"type": "integer",
"minimum": 0,
"default": 0
},
"format": {
"title": "Output format of the module",
"type": "string"
@@ -155,6 +161,16 @@
"title": "Whether to preserve the aspect ratio of the logo. Supported by iTerm image protocol",
"default": false
},
"recache": {
"type": "boolean",
"title": "If true, regenerate image logo cache",
"default": false
},
"separate": {
"type": "boolean",
"title": "If true, print modules at bottom of the logo",
"default": false
},
"chafa": {
"type": "object",
"title": "Chafa configuration. See chafa document for details",
@@ -221,6 +237,11 @@
"title": "Use multiple threads to detect values",
"default": true
},
"thread": {
"type": "boolean",
"title": "Alias of multithreading",
"default": true
},
"stat": {
"type": "boolean",
"title": "Show time usage (in ms) for individual modules",
@@ -253,6 +274,11 @@
"type": "integer",
"title": "Set the timeout (ms) for WMI queries, `-1` for no timeout. Windows only",
"default": 5000
},
"processingTimeout": {
"type": "integer",
"title": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
"default": 1000
}
},
"additionalProperties": false
@@ -309,6 +335,12 @@
"type": "boolean",
"default": true
},
"keyWidth": {
"title": "Align the width of keys to number of characters, 0 to disable",
"type": "integer",
"minimum": 0,
"default": 0
},
"binaryPrefix": {
"type": "string",
"title": "Set the binary prefix to used when printing bytes",
@@ -321,6 +353,8 @@
"sizeNdigits": {
"type": "integer",
"title": "Set the number of digits to keep after the decimal point when formatting sizes",
"minimum": 0,
"maximum": 9,
"default": 2
},
"sizeMaxPrefix": {
@@ -335,13 +369,47 @@
"enum": ["CELSIUS", "C", "FAHRENHEIT", "F", "KELVIN", "K"],
"default": "C"
},
"bar": {
"type": "object",
"title": "Set the bar configuration",
"properties": {
"charElapsed": {
"type": "string",
"title": "Set the character to use in elapsed part",
"default": "■"
},
"charTotal": {
"type": "string",
"title": "Set the character to use in total part",
"default": "-"
},
"border": {
"type": "boolean",
"title": "Whether to show a border around the bar",
"default": true
},
"width": {
"type": "integer",
"title": "Set the width of the bar, in number of characters",
"minimum": 1,
"default": 10
}
}
},
"percentType": {
"type": "number",
"title": "Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number",
"minimum": 0,
"maximum": 9,
"maximum": 255,
"default": 1
},
"percentNdigits": {
"type": "number",
"title": "Set the number of digits to keep after the decimal point when formatting percentage numbers",
"minimum": 0,
"maximum": 9,
"default": 0
},
"noBuffer": {
"type": "boolean",
"title": "Whether to disable the stdout application buffer",
@@ -477,6 +545,7 @@
"datetime",
"display",
"disk",
"diskio",
"de",
"font",
"gamepad",
@@ -490,6 +559,7 @@
"media",
"memory",
"monitor",
"netio",
"opencl",
"opengl",
"os",
@@ -509,6 +579,7 @@
"theme",
"uptime",
"users",
"version",
"vulkan",
"wallpaper",
"weather",
@@ -525,7 +596,6 @@
],
"properties": {
"type": {
"title": "Module type",
"type": "string"
}
},
@@ -544,44 +614,151 @@
"title": "No additional properties",
"properties": {
"type": {
"enum": [
"bios",
"board",
"brightness",
"chassis",
"cpuusage",
"cursor",
"datetime",
"de",
"font",
"gamepad",
"host",
"icons",
"kernel",
"lm",
"locale",
"media",
"memory",
"monitor",
"opencl",
"os",
"packages",
"player",
"poweradapter",
"processes",
"shell",
"swap",
"terminal",
"terminalfont",
"terminalsize",
"theme",
"uptime",
"users",
"vulkan",
"wallpaper",
"wm",
"wifi",
"wmtheme"
"anyOf": [
{
"const": "bios",
"description": "Print BIOS name, version, release date, etc"
},
{
"const": "board",
"description": "Print mather board name and other info"
},
{
"const": "chassis",
"description": "Print chassis type (desktop, laptop, etc)"
},
{
"const": "cursor",
"description": "Print cursor style name"
},
{
"const": "datetime",
"description": "Print current date and time"
},
{
"const": "de",
"description": "Print desktop environment name"
},
{
"const": "font",
"description": "Print system font name"
},
{
"const": "gamepad",
"description": "List connected gamepads"
},
{
"const": "host",
"description": "Print product name of your computer"
},
{
"const": "icons",
"description": "Print icon style name"
},
{
"const": "kernel",
"description": "Print system kernel version"
},
{
"const": "lm",
"description": "Print login manager (desktop manager) name and version"
},
{
"const": "locale",
"description": "Print system locale name"
},
{
"const": "media",
"description": "Print playing song name"
},
{
"const": "memory",
"description": "Print system memory usage info"
},
{
"const": "monitor",
"description": "Print connected physical monitor information"
},
{
"const": "opencl",
"description": "Print highest OpenCL version supported by the GPU"
},
{
"const": "os",
"description": "Print operating system name and version"
},
{
"const": "packages",
"description": "List installed package managers and count of installed packages"
},
{
"const": "player",
"description": "Print music player name"
},
{
"const": "poweradapter",
"description": "Print power adapter name and charging watts"
},
{
"const": "processes",
"description": "Count running processes"
},
{
"const": "shell",
"description": "Print current shell name and version"
},
{
"const": "swap",
"description": "Print swap (paging file) space usage"
},
{
"const": "terminal",
"description": "Print current terminal name and version"
},
{
"const": "terminalfont",
"description": "Print font name and size used by current terminal"
},
{
"const": "terminalsize",
"description": "Print current terminal size"
},
{
"const": "theme",
"description": "Print current theme information"
},
{
"const": "uptime",
"description": "Print system uptime"
},
{
"const": "users",
"description": "List users currently logged in"
},
{
"const": "version",
"description": "Print Fastfetch version"
},
{
"const": "vulkan",
"description": "Print highest Vulkan version supported by the GPU"
},
{
"const": "wallpaper",
"description": "Print image file path of current wallpaper"
},
{
"const": "wm",
"description": "Print window manager name and version"
},
{
"const": "wifi",
"description": "Print connected Wi-Fi info (SSID, connection and security protocol)"
},
{
"const": "wmtheme",
"description": "Print current theme of window manager"
}
]
},
"key": {
@@ -590,6 +767,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -600,7 +780,8 @@
"title": "Battery",
"properties": {
"type": {
"const": "battery"
"const": "battery",
"description": "Print battery capacity, status, etc"
},
"dir": {
"title": "The directory where the battery folders are. Standard: `/sys/class/power_supply/`. Linux only",
@@ -617,6 +798,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -627,6 +811,7 @@
"title": "Bluetooth",
"properties": {
"type": {
"description": "List bluetooth devices",
"const": "bluetooth"
},
"showDisconnected": {
@@ -640,16 +825,36 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "Brightness",
"properties": {
"type": {
"const": "brightness",
"description": "Print current brightness / luminance of your monitors"
},
"ddcciSleep": {
"type": "integer",
"description": "Set the sleep times (in ms) when sending DDC/CI requests.\nSee <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail",
"minimum": 0,
"maximum": 400,
"default": 10
}
}
},
{
"title": "CPU",
"properties": {
"type": {
"description": "Print CPU name, frequency, etc",
"const": "cpu"
},
"temp": {
@@ -657,22 +862,47 @@
"type": "boolean",
"default": false
},
"freqNdigits": {
"title": "Set the number of digits to keep after the decimal point when printing CPU frequency",
"type": "integer",
"minimum": 0,
"maximum": 9,
"default": 2
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "CPU Usage",
"properties": {
"type": {
"const": "cpuusage",
"description": "Print CPU usage. Costs some time to collect data"
},
"separate": {
"type": "boolean",
"description": "Display CPU usage per CPU logical core, instead of an average result",
"default": false
}
}
},
{
"title": "Colors",
"properties": {
"type": {
"description": "Print some colored blocks",
"const": "colors"
},
"symbol": {
@@ -700,6 +930,7 @@
"title": "Command",
"properties": {
"type": {
"description": "Running custom shell scripts",
"const": "command"
},
"shell": {
@@ -716,6 +947,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -724,9 +958,9 @@
},
{
"title": "Custom",
"description": "Print a custom string, with or without key",
"properties": {
"type": {
"description": "Print a custom string, with or without key",
"const": "custom"
},
"key": {
@@ -736,6 +970,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"title": "Text to print",
"type": "string"
@@ -750,6 +987,7 @@
"title": "Display",
"properties": {
"type": {
"description": "Print resolutions, refresh rates, etc",
"const": "display"
},
"compactType": {
@@ -772,6 +1010,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -782,6 +1023,7 @@
"title": "Disk",
"properties": {
"type": {
"description": "Print partitions, space usage, disk type, etc",
"const": "disk"
},
"folders": {
@@ -803,17 +1045,56 @@
"title": "Set if subvolumes should be printed",
"default": false
},
"showReadOnly": {
"type": "boolean",
"title": "Set if read only volumes should be printed",
"default": false
},
"showUnknown": {
"type": "boolean",
"title": "Set if unknown (unable to detect sizes) volumes should be printed",
"default": false
},
"useAvailable": {
"type": "boolean",
"title": "Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "DiskIO",
"properties": {
"type": {
"description": "Print physical disk I/O throughput",
"const": "diskio"
},
"namePrefix": {
"title": "Show disks with given name prefix only",
"type": "string"
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -824,6 +1105,7 @@
"title": "GPU",
"properties": {
"type": {
"description": "Print GPU names, graphic memory size, type, etc",
"const": "gpu"
},
"temp": {
@@ -851,6 +1133,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -861,6 +1146,7 @@
"title": "Local IP",
"properties": {
"type": {
"description": "List local IP addresses (v4 or v6), MAC addresses, etc",
"const": "localip"
},
"showIpv4": {
@@ -892,7 +1178,7 @@
"title": "Show IPs with given name prefix only",
"type": "string"
},
"showDefaultRouteOnly": {
"defaultRouteOnly": {
"title": "Show ips that are used for default routing only",
"type": "boolean",
"default": false
@@ -903,6 +1189,40 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
},
"additionalProperties": false
},
{
"title": "NetIO",
"properties": {
"type": {
"description": "Print network I/O throughput",
"const": "netio"
},
"namePrefix": {
"title": "Show IPs with given name prefix only",
"type": "string"
},
"defaultRouteOnly": {
"title": "Show ips that are used for default routing only",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -913,6 +1233,7 @@
"title": "OpenGL",
"properties": {
"type": {
"description": "Print highest OpenGL version supported by the GPU",
"const": "opengl"
},
"library": {
@@ -931,6 +1252,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -941,6 +1265,7 @@
"title": "Public IP",
"properties": {
"type": {
"description": "Print your public IP address, etc",
"const": "publicip"
},
"url": {
@@ -961,6 +1286,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -971,6 +1299,7 @@
"title": "Separator",
"properties": {
"type": {
"description": "Print a separator line",
"const": "separator"
},
"string": {
@@ -985,6 +1314,7 @@
"title": "Sound",
"properties": {
"type": {
"description": "Print sound devices, volume, etc",
"const": "sound"
},
"soundType": {
@@ -1003,6 +1333,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1013,6 +1346,7 @@
"title": "Title",
"properties": {
"type": {
"description": "Print title, which contains your user name, hostname",
"const": "title"
},
"fqdn": {
@@ -1044,6 +1378,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1054,6 +1391,7 @@
"title": "Weather",
"properties": {
"type": {
"description": "Print weather information",
"const": "weather"
},
"location": {
@@ -1077,6 +1415,9 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
+1 -1
View File
@@ -1 +1 @@
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:Break:Colors
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
+3
View File
@@ -51,6 +51,9 @@
"sound",
"gamepad",
"weather",
"netio",
"diskio",
"version",
"break",
"colors"
]
+7
View File
@@ -0,0 +1,7 @@
-c all
--pipe
--show-errors
--no-buffer
--publicip-timeout 1000
--weather-timeout 1000
--stat
-3
View File
@@ -1,3 +0,0 @@
--disable-linewrap false
--multithreading false
--show-errors
-3
View File
@@ -1,3 +0,0 @@
--load-config devinfo
--load-config all
--load-config verbose
-49
View File
@@ -1,49 +0,0 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "builtin",
"source": "arch"
},
"display": {
"disableLinewrap": false,
"showErrors": true
},
"general": {
"multithreading": false
},
"modules": [
"title",
"separator",
{
"type": "os",
"format": "Arch Linux ({12})"
},
"host",
"kernel",
"uptime",
{
"type": "packages",
"format": "{} (pacman)"
},
"shell",
"display",
"de",
"wm",
"wmtheme",
"theme",
"icons",
"font",
"cursor",
"terminal",
"terminalfont",
"cpu",
"gpu",
"memory",
"disk",
"battery",
"poweradapter",
"locale",
"break",
"colors"
]
}
+150
View File
@@ -0,0 +1,150 @@
// Load with --load-config examples/2.jsonc
// Note that you must replace the image path to an existing image to display it.
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"padding": {
"top": 2
}
},
"display": {
"separator": " -> "
},
"modules": [
{
"type": "custom",
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
},
{
"type": "title",
"keyWidth": 10
},
{
"type": "custom",
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
},
{
"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"
},
{
"type": "custom",
"format": "\u001b[90m┌────────────────────────────────────────────────────────────┐"
},
{
"type": "os",
"key": " OS",
"keyColor": "yellow"
},
{
"type": "kernel",
"key": "│ ├",
"keyColor": "yellow"
},
{
"type": "packages",
"key": "│ ├󰏖",
"keyColor": "yellow"
},
{
"type": "shell",
"key": "│ └",
"keyColor": "yellow"
},
{
"type": "wm",
"key": " DE/WM",
"keyColor": "blue"
},
{
"type": "lm",
"key": "│ ├󰧨",
"keyColor": "blue"
},
{
"type": "wmtheme",
"key": "│ ├󰉼",
"keyColor": "blue"
},
{
"type": "icons",
"key": "│ ├󰀻",
"keyColor": "blue"
},
{
"type": "terminal",
"key": "│ ├",
"keyColor": "blue"
},
{
"type": "wallpaper",
"key": "│ └󰸉",
"keyColor": "blue"
},
{
"type": "host",
"key": " PC",
"keyColor": "green"
},
{
"type": "cpu",
"key": "│ ├",
"keyColor": "green"
},
{
"type": "gpu",
"key": "│ ├﬙",
"keyColor": "green"
},
{
"type": "disk",
"key": "│ ├",
"keyColor": "green"
},
{
"type": "memory",
"key": "│ ├󰑭",
"keyColor": "green"
},
{
"type": "swap",
"key": "│ ├󰓡",
"keyColor": "green"
},
{
"type": "uptime",
"key": "│ ├󰅐",
"keyColor": "green"
},
{
"type": "display",
"key": "│ └󰍹",
"keyColor": "green"
},
{
"type": "sound",
"key": " SND",
"keyColor": "cyan"
},
{
"type": "player",
"key": "│ ├󰥠",
"keyColor": "cyan"
},
{
"type": "media",
"key": "│ └󰝚",
"keyColor": "cyan"
},
{
"type": "custom",
"format": "\u001b[90m└────────────────────────────────────────────────────────────┘"
},
"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"
}
]
}
+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "file:///C:/msys64/home/zhang/fastfetch/doc/json_schema.json",
"logo": {
"type": "small"
},
"display": {
"percentType": 9,
"separator": "\u001b[31m-> "
},
"modules": [
{
"key": "Distro ",
"type": "os"
},
{
"key": "Shell ",
"type": "shell"
},
{
"key": "Terminal ",
"type": "terminal"
},
{
"key": "Display ",
"type": "display"
},
{
"key": "Backlight ",
"type": "brightness"
},
"break",
{
"type": "colors",
"paddingLeft": 6,
"symbol": "circle"
}
]
}
+28
View File
@@ -0,0 +1,28 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "small"
},
"display": {
"percentType": 6,
"keyWidth": 11,
"bar": {
"charElapsed": "=",
"charTotal": "-",
"width": 13
}
},
"modules": [
"title",
"separator",
"memory",
"swap",
"disk",
"battery",
{
"type": "colors",
"paddingLeft": 11,
"symbol": "circle"
}
]
}
-31
View File
@@ -1,31 +0,0 @@
--os-format System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}
--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; sys_vendor: {}
--kernel-format Sysname: {}; Release: {}; Version: {}
--uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {}
--processes-format Count: {}
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak-system: {}; flatpak-user: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}; pkgtool: {}; paludis {}
--shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}
--display-format Width: {}; Height: {}; Refresh rate: {}; ScaledWith: {}; ScaledHeight: {}
--de-format Process name: {}; Pretty name: {}; Version: {}
--wm-format Process name: {}; Pretty name: {}; Protocol: {}
--wmtheme-format Name: {}
--theme-format Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
--icons-format Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
--font-format Font1: {}; Font2: {}; Font3: {}; Font4: {}
--cursor-format Theme: {}; Size: {}
--terminal-format Process: {}; Path: {}; Exe: {}
--terminalfont-format Pretty: {}; Name: {}; Size: {}; Styles: {}
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
--cpu-usage-format Percentage: {}
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}; Type: {}
--memory-format Used: {}; Total: {}; Percentage: {}
--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; External: {}; Hidden: {}; Filesystem: {}; Name: {}
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {}
--player-format Pretty: {}; Name: {}; Bus: {}; Url: {}
--media-format Pretty: {}; Name: {}; Artist: {}; Album: {}
--datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}
--vulkan-format driver: {}; Api Version: {}; Conformance Version: {}
--opengl-format version: {}; renderer: {}; vendor: {}
--opencl-format version: {}; device: {}; vendor: {}
--bluetooth-format Name: {}; Address: {}; Type: {}; Battery: {}
+7
View File
@@ -0,0 +1,7 @@
{
"home": "https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c",
"license": "Embed in source",
"version": "2007-05-26 (Unicode 5.0)",
"author": "Markus Kuhn",
"modified": "CarterLi"
}
+6
View File
@@ -0,0 +1,6 @@
{
"home": "https://github.com/ibireme/yyjson",
"license": "MIT ( embed in source )",
"version": "0.8.0",
"author": "ibireme"
}
+9447
View File
File diff suppressed because it is too large Load Diff
+7910
View File
File diff suppressed because it is too large Load Diff
+45 -39
View File
@@ -1,51 +1,57 @@
#include "common/bar.h"
#include "common/color.h"
#include "util/textModifier.h"
#include "bar.h"
// green, yellow, red: print the color on nth (0~9) block
// set its value == 10 means the color will not be printed
void ffAppendPercentBar(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red)
void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, uint8_t red)
{
assert(green <= 10 && yellow <= 10 && red <= 10);
assert(green <= 100 && yellow <= 100 && red <= 100);
// [ 0%, 5%) prints 0 blocks
// [ 5%, 15%) prints 1 block;
// ...
// [85%, 95%) prints 9 blocks;
// [95%,100%] prints 10 blocks
percent = (uint8_t)(percent + 5) / 10;
assert(percent <= 10);
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksGreen = (uint32_t) (green / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * instance.config.barWidth + 0.5);
uint32_t blocksRed = (uint32_t) (red / 100.0 * instance.config.barWidth + 0.5);
assert(blocksPercent <= instance.config.barWidth);
if(!instance.config.pipe)
ffStrbufAppendS(buffer, "\033[97m[ ");
else
ffStrbufAppendS(buffer, "[ ");
if(instance.config.barBorder)
{
if(!instance.config.pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
else
ffStrbufAppendS(buffer, "[ ");
}
for (uint8_t i = 0; i < percent; ++i)
for (uint32_t i = 0; i < blocksPercent; ++i)
{
if(!instance.config.pipe)
{
if (i == green)
ffStrbufAppendS(buffer, "\033[32m");
else if (i == yellow)
ffStrbufAppendS(buffer, "\033[93m");
else if (i == red)
ffStrbufAppendS(buffer, "\033[91m");
if (i == blocksGreen)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
else if (i == blocksYellow)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
else if (i == blocksRed)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
}
ffStrbufAppendS(buffer, "");
ffStrbufAppend(buffer, &instance.config.barCharElapsed);
}
if (percent < 10)
if (blocksPercent < instance.config.barWidth)
{
if(!instance.config.pipe)
ffStrbufAppendS(buffer, "\033[97m");
for (uint8_t i = percent; i < 10; ++i)
ffStrbufAppendS(buffer, "-");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
for (uint32_t i = blocksPercent; i < instance.config.barWidth; ++i)
ffStrbufAppend(buffer, &instance.config.barCharTotal);
}
if(instance.config.barBorder)
{
if(!instance.config.pipe)
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
else
ffStrbufAppendS(buffer, " ]");
}
if(!instance.config.pipe)
ffStrbufAppendS(buffer, "\033[97m ]" FASTFETCH_TEXT_MODIFIER_RESET);
else
ffStrbufAppendS(buffer, " ]");
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
// if (green < yellow)
@@ -57,7 +63,7 @@ void ffAppendPercentBar(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_
// [green, 100]: print green
// [yellow, green): print yellow
// [0, yellow): PRINT RED
void ffAppendPercentNum(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses)
void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, bool parentheses)
{
assert(green <= 100 && yellow <= 100);
@@ -71,23 +77,23 @@ void ffAppendPercentNum(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_
if(green < yellow)
{
if (percent <= green)
ffStrbufAppendS(buffer, "\033[32m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
else if (percent <= yellow)
ffStrbufAppendS(buffer, "\033[93m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
else
ffStrbufAppendS(buffer, "\033[91m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
}
else
{
if (percent >= green)
ffStrbufAppendS(buffer, "\033[32m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
else if (percent >= yellow)
ffStrbufAppendS(buffer, "\033[93m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_YELLOW "m");
else
ffStrbufAppendS(buffer, "\033[91m");
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
}
}
ffStrbufAppendF(buffer, "%u%%", (unsigned) percent);
ffStrbufAppendF(buffer, "%.*f%%", instance.config.percentNdigits, percent);
if (colored && !instance.config.pipe)
{
+2 -2
View File
@@ -13,7 +13,7 @@ enum
FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3,
};
void ffAppendPercentBar(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red);
void ffAppendPercentNum(FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, bool parentheses);
void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, uint8_t red);
void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, bool parentheses);
#endif
+143
View File
@@ -0,0 +1,143 @@
#include "commandoption.h"
#include "common/printing.h"
#include "common/time.h"
#include "fastfetch_datatext.h"
#include "modules/modules.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <inttypes.h>
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
{
yyjson_mut_doc* doc = instance.state.resultDoc;
if (__builtin_expect(!doc, true)) return NULL;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJson)
baseInfo->generateJson(baseInfo, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
return module;
}
bool ffParseModuleCommand(const char* type)
{
if(!isalpha(type[0])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(type, baseInfo->name))
{
if (!genJson(baseInfo))
baseInfo->printModule(baseInfo);
return true;
}
}
return false;
}
bool ffParseModuleOptions(const char* key, const char* value)
{
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
{
FFModuleBaseInfo* baseInfo = *modules;
if (baseInfo->parseCommandOptions(baseInfo, key, value)) return true;
}
return false;
}
void ffPrepareCommandOption(FFdata* data)
{
//If we don't have a custom structure, use the default one
if(data->structure.length == 0)
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
if(ffStrbufContainIgnCaseS(&data->structure, FF_CPUUSAGE_MODULE_NAME))
ffPrepareCPUUsage();
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
ffPrepareDiskIO(&instance.config.diskIo);
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
ffPrepareNetIO(&instance.config.netIo);
if(instance.config.multithreading)
{
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
ffPreparePublicIp(&instance.config.publicIP);
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
ffPrepareWeather(&instance.config.weather);
}
}
static void parseStructureCommand(const char* line, FFlist* customValues)
{
// 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);
ffPrintCustom(&options);
return;
}
}
if(!ffParseModuleCommand(line))
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
}
void ffPrintCommandOption(FFdata* data)
{
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
//Parse the structure and call the modules
uint32_t startIndex = 0;
while (startIndex < data->structure.length)
{
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
data->structure.chars[colonIndex] = '\0';
uint64_t ms = 0;
if(instance.config.stat)
ms = ffTimeGetTick();
parseStructureCommand(data->structure.chars + startIndex, &data->customValues);
if(instance.config.stat)
{
ms = ffTimeGetTick() - ms;
if (resultDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
}
else
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
if(instance.config.pipe)
puts(str);
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
}
#if defined(_WIN32)
if (!instance.config.noBuffer) fflush(stdout);
#endif
startIndex = colonIndex + 1;
}
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#ifndef FF_INCLUDED_common_commandoption
#define FF_INCLUDED_common_commandoption
#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 loadUserConfig;
} FFdata;
bool ffParseModuleCommand(const char* type);
bool ffParseModuleOptions(const char* key, const char* value);
void ffPrepareCommandOption(FFdata* data);
void ffPrintCommandOption(FFdata* data);
#endif
+2 -2
View File
@@ -12,6 +12,8 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT64)
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
@@ -254,7 +256,5 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
}
ffStrbufTrimRight(buffer, ' ');
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
}
+1
View File
@@ -7,6 +7,7 @@ typedef enum FFformatargtype
{
FF_FORMAT_ARG_TYPE_NULL = 0,
FF_FORMAT_ARG_TYPE_UINT,
FF_FORMAT_ARG_TYPE_UINT64,
FF_FORMAT_ARG_TYPE_UINT16,
FF_FORMAT_ARG_TYPE_UINT8,
FF_FORMAT_ARG_TYPE_INT,
+110 -86
View File
@@ -27,6 +27,7 @@ static void initState(FFstate* state)
ffPlatformInit(&state->platform);
state->configDoc = NULL;
state->resultDoc = NULL;
}
static void defaultConfig(void)
@@ -48,7 +49,6 @@ static void defaultConfig(void)
#endif
instance.config.showErrors = false;
instance.config.recache = false;
instance.config.allowSlowOperations = false;
instance.config.pipe = !isatty(STDOUT_FILENO);
@@ -68,58 +68,72 @@ static void defaultConfig(void)
instance.config.multithreading = true;
instance.config.stat = false;
instance.config.noBuffer = false;
instance.config.keyWidth = 0;
ffInitTitleOptions(&instance.config.title);
ffInitOSOptions(&instance.config.os);
ffInitHostOptions(&instance.config.host);
ffStrbufInitStatic(&instance.config.barCharElapsed, "");
ffStrbufInitStatic(&instance.config.barCharTotal, "-");
instance.config.barWidth = 10;
instance.config.barBorder = true;
instance.config.percentType = 1;
instance.config.percentNdigits = 0;
ffInitBatteryOptions(&instance.config.battery);
ffInitBiosOptions(&instance.config.bios);
ffInitBluetoothOptions(&instance.config.bluetooth);
ffInitBoardOptions(&instance.config.board);
ffInitBreakOptions(&instance.config.break_);
ffInitBrightnessOptions(&instance.config.brightness);
ffInitChassisOptions(&instance.config.chassis);
ffInitCommandOptions(&instance.config.command);
ffInitCustomOptions(&instance.config.custom);
ffInitKernelOptions(&instance.config.kernel);
ffInitUptimeOptions(&instance.config.uptime);
ffInitProcessesOptions(&instance.config.processes);
ffInitPackagesOptions(&instance.config.packages);
ffInitShellOptions(&instance.config.shell);
ffInitDisplayOptions(&instance.config.display);
ffInitDEOptions(&instance.config.de);
ffInitWMOptions(&instance.config.wm);
ffInitWMThemeOptions(&instance.config.wmTheme);
ffInitThemeOptions(&instance.config.theme);
ffInitIconsOptions(&instance.config.icons);
ffInitFontOptions(&instance.config.font);
ffInitCursorOptions(&instance.config.cursor);
ffInitTerminalOptions(&instance.config.terminal);
ffInitTerminalFontOptions(&instance.config.terminalFont);
ffInitCPUOptions(&instance.config.cpu);
ffInitCPUUsageOptions(&instance.config.cpuUsage);
ffInitGPUOptions(&instance.config.gpu);
ffInitMemoryOptions(&instance.config.memory);
ffInitSwapOptions(&instance.config.swap);
ffInitChassisOptions(&instance.config.chassis);
ffInitColorsOptions(&instance.config.colors);
ffInitCommandOptions(&instance.config.command);
ffInitCursorOptions(&instance.config.cursor);
ffInitCustomOptions(&instance.config.custom);
ffInitDEOptions(&instance.config.de);
ffInitDateTimeOptions(&instance.config.dateTime);
ffInitDiskOptions(&instance.config.disk);
ffInitBatteryOptions(&instance.config.battery);
ffInitPowerAdapterOptions(&instance.config.powerAdapter);
ffInitDiskIOOptions(&instance.config.diskIo);
ffInitDisplayOptions(&instance.config.display);
ffInitFontOptions(&instance.config.font);
ffInitGPUOptions(&instance.config.gpu);
ffInitGamepadOptions(&instance.config.gamepad);
ffInitHostOptions(&instance.config.host);
ffInitIconsOptions(&instance.config.icons);
ffInitKernelOptions(&instance.config.kernel);
ffInitLMOptions(&instance.config.lm);
ffInitLocaleOptions(&instance.config.locale);
ffInitLocalIpOptions(&instance.config.localIP);
ffInitLocaleOptions(&instance.config.locale);
ffInitMediaOptions(&instance.config.media);
ffInitMemoryOptions(&instance.config.memory);
ffInitMonitorOptions(&instance.config.monitor);
ffInitNetIOOptions(&instance.config.netIo);
ffInitOSOptions(&instance.config.os);
ffInitOpenCLOptions(&instance.config.openCL);
ffInitOpenGLOptions(&instance.config.openGL);
ffInitPackagesOptions(&instance.config.packages);
ffInitPlayerOptions(&instance.config.player);
ffInitPowerAdapterOptions(&instance.config.powerAdapter);
ffInitProcessesOptions(&instance.config.processes);
ffInitPublicIpOptions(&instance.config.publicIP);
ffInitSeparatorOptions(&instance.config.separator);
ffInitShellOptions(&instance.config.shell);
ffInitSoundOptions(&instance.config.sound);
ffInitSwapOptions(&instance.config.swap);
ffInitTerminalFontOptions(&instance.config.terminalFont);
ffInitTerminalOptions(&instance.config.terminal);
ffInitTerminalSizeOptions(&instance.config.terminalSize);
ffInitThemeOptions(&instance.config.theme);
ffInitTitleOptions(&instance.config.title);
ffInitUptimeOptions(&instance.config.uptime);
ffInitUsersOptions(&instance.config.users);
ffInitVersionOptions(&instance.config.version);
ffInitVulkanOptions(&instance.config.vulkan);
ffInitWMOptions(&instance.config.wm);
ffInitWMThemeOptions(&instance.config.wmTheme);
ffInitWallpaperOptions(&instance.config.wallpaper);
ffInitWeatherOptions(&instance.config.weather);
ffInitWifiOptions(&instance.config.wifi);
ffInitPlayerOptions(&instance.config.player);
ffInitMediaOptions(&instance.config.media);
ffInitDateTimeOptions(&instance.config.dateTime);
ffInitVulkanOptions(&instance.config.vulkan);
ffInitWallpaperOptions(&instance.config.wallpaper);
ffInitOpenGLOptions(&instance.config.openGL);
ffInitOpenCLOptions(&instance.config.openCL);
ffInitUsersOptions(&instance.config.users);
ffInitBluetoothOptions(&instance.config.bluetooth);
ffInitSoundOptions(&instance.config.sound);
ffInitSeparatorOptions(&instance.config.separator);
ffInitGamepadOptions(&instance.config.gamepad);
ffInitColorsOptions(&instance.config.colors);
ffStrbufInit(&instance.config.libPCI);
ffStrbufInit(&instance.config.libVulkan);
@@ -145,8 +159,6 @@ static void defaultConfig(void)
ffStrbufInit(&instance.config.libPulse);
ffStrbufInit(&instance.config.libnm);
ffStrbufInit(&instance.config.libDdcutil);
instance.config.percentType = 1;
}
void ffInitInstance(void)
@@ -225,11 +237,11 @@ void ffStart(void)
startDetectionThreads();
#endif
ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe;
ffHideCursor = instance.config.hideCursor && !instance.config.pipe;
ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe && !instance.state.resultDoc;
ffHideCursor = instance.config.hideCursor && !instance.config.pipe && !instance.state.resultDoc;
#ifdef _WIN32
if (!instance.config.noBuffer) setvbuf(stdout, NULL, _IOFBF, 4096);
setvbuf(stdout, NULL, _IOFBF, instance.config.noBuffer ? 0 : 4096);
SetConsoleCtrlHandler(consoleHandler, TRUE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
@@ -245,7 +257,7 @@ void ffStart(void)
#endif
//reset everything to default before we start printing
if(!instance.config.pipe)
if(!instance.config.pipe && !instance.state.resultDoc)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if(ffHideCursor)
@@ -272,63 +284,71 @@ static void destroyConfig(void)
ffStrbufDestroy(&instance.config.colorKeys);
ffStrbufDestroy(&instance.config.colorTitle);
ffStrbufDestroy(&instance.config.keyValueSeparator);
ffStrbufDestroy(&instance.config.barCharElapsed);
ffStrbufDestroy(&instance.config.barCharTotal);
#if defined(__linux__) || defined(__FreeBSD__)
ffStrbufDestroy(&instance.config.playerName);
ffStrbufDestroy(&instance.config.osFile);
#endif
ffDestroyTitleOptions(&instance.config.title);
ffDestroyOSOptions(&instance.config.os);
ffDestroyHostOptions(&instance.config.host);
ffDestroyBatteryOptions(&instance.config.battery);
ffDestroyBiosOptions(&instance.config.bios);
ffDestroyBluetoothOptions(&instance.config.bluetooth);
ffDestroyBoardOptions(&instance.config.board);
ffDestroyBreakOptions(&instance.config.break_);
ffDestroyBrightnessOptions(&instance.config.brightness);
ffDestroyChassisOptions(&instance.config.chassis);
ffDestroyCommandOptions(&instance.config.command);
ffDestroyCustomOptions(&instance.config.custom);
ffDestroyKernelOptions(&instance.config.kernel);
ffDestroyUptimeOptions(&instance.config.uptime);
ffDestroyProcessesOptions(&instance.config.processes);
ffDestroyPackagesOptions(&instance.config.packages);
ffDestroyShellOptions(&instance.config.shell);
ffDestroyDisplayOptions(&instance.config.display);
ffDestroyDEOptions(&instance.config.de);
ffDestroyWMOptions(&instance.config.wm);
ffDestroyWMThemeOptions(&instance.config.wmTheme);
ffDestroyThemeOptions(&instance.config.theme);
ffDestroyIconsOptions(&instance.config.icons);
ffDestroyFontOptions(&instance.config.font);
ffDestroyCursorOptions(&instance.config.cursor);
ffDestroyTerminalOptions(&instance.config.terminal);
ffDestroyTerminalFontOptions(&instance.config.terminalFont);
ffDestroyCPUOptions(&instance.config.cpu);
ffDestroyCPUUsageOptions(&instance.config.cpuUsage);
ffDestroyGPUOptions(&instance.config.gpu);
ffDestroyMemoryOptions(&instance.config.memory);
ffDestroySwapOptions(&instance.config.swap);
ffDestroyChassisOptions(&instance.config.chassis);
ffDestroyColorsOptions(&instance.config.colors);
ffDestroyCommandOptions(&instance.config.command);
ffDestroyCursorOptions(&instance.config.cursor);
ffDestroyCustomOptions(&instance.config.custom);
ffDestroyDEOptions(&instance.config.de);
ffDestroyDateTimeOptions(&instance.config.dateTime);
ffDestroyDiskOptions(&instance.config.disk);
ffDestroyBatteryOptions(&instance.config.battery);
ffDestroyPowerAdapterOptions(&instance.config.powerAdapter);
ffDestroyDiskIOOptions(&instance.config.diskIo);
ffDestroyDisplayOptions(&instance.config.display);
ffDestroyFontOptions(&instance.config.font);
ffDestroyGPUOptions(&instance.config.gpu);
ffDestroyGamepadOptions(&instance.config.gamepad);
ffDestroyHostOptions(&instance.config.host);
ffDestroyIconsOptions(&instance.config.icons);
ffDestroyKernelOptions(&instance.config.kernel);
ffDestroyLMOptions(&instance.config.lm);
ffDestroyLocaleOptions(&instance.config.locale);
ffDestroyLocalIpOptions(&instance.config.localIP);
ffDestroyLocaleOptions(&instance.config.locale);
ffDestroyMediaOptions(&instance.config.media);
ffDestroyMemoryOptions(&instance.config.memory);
ffDestroyMonitorOptions(&instance.config.monitor);
ffDestroyNetIOOptions(&instance.config.netIo);
ffDestroyOSOptions(&instance.config.os);
ffDestroyOpenCLOptions(&instance.config.openCL);
ffDestroyOpenGLOptions(&instance.config.openGL);
ffDestroyPackagesOptions(&instance.config.packages);
ffDestroyPlayerOptions(&instance.config.player);
ffDestroyPowerAdapterOptions(&instance.config.powerAdapter);
ffDestroyProcessesOptions(&instance.config.processes);
ffDestroyPublicIpOptions(&instance.config.publicIP);
ffDestroySeparatorOptions(&instance.config.separator);
ffDestroyShellOptions(&instance.config.shell);
ffDestroySoundOptions(&instance.config.sound);
ffDestroySwapOptions(&instance.config.swap);
ffDestroyTerminalFontOptions(&instance.config.terminalFont);
ffDestroyTerminalOptions(&instance.config.terminal);
ffDestroyTerminalSizeOptions(&instance.config.terminalSize);
ffDestroyThemeOptions(&instance.config.theme);
ffDestroyTitleOptions(&instance.config.title);
ffDestroyUptimeOptions(&instance.config.uptime);
ffDestroyUsersOptions(&instance.config.users);
ffDestroyVersionOptions(&instance.config.version);
ffDestroyVulkanOptions(&instance.config.vulkan);
ffDestroyWMOptions(&instance.config.wm);
ffDestroyWMThemeOptions(&instance.config.wmTheme);
ffDestroyWallpaperOptions(&instance.config.wallpaper);
ffDestroyWeatherOptions(&instance.config.weather);
ffDestroyWifiOptions(&instance.config.wifi);
ffDestroyPlayerOptions(&instance.config.player);
ffDestroyMediaOptions(&instance.config.media);
ffDestroyDateTimeOptions(&instance.config.dateTime);
ffDestroyVulkanOptions(&instance.config.vulkan);
ffDestroyOpenGLOptions(&instance.config.openGL);
ffDestroyOpenCLOptions(&instance.config.openCL);
ffDestroyUsersOptions(&instance.config.users);
ffDestroyBluetoothOptions(&instance.config.bluetooth);
ffDestroySeparatorOptions(&instance.config.separator);
ffDestroySoundOptions(&instance.config.sound);
ffDestroyGamepadOptions(&instance.config.gamepad);
ffDestroyColorsOptions(&instance.config.colors);
ffStrbufDestroy(&instance.config.libPCI);
ffStrbufDestroy(&instance.config.libVulkan);
@@ -360,6 +380,7 @@ static void destroyState(void)
{
ffPlatformDestroy(&instance.state.platform);
yyjson_doc_free(instance.state.configDoc);
yyjson_mut_doc_free(instance.state.resultDoc);
}
void ffDestroyInstance(void)
@@ -450,6 +471,9 @@ void ffListFeatures(void)
#ifdef FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#ifdef FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
""
, stdout);
}
+24
View File
@@ -12,6 +12,7 @@
typedef HANDLE FFNativeFD;
#else
#include <unistd.h>
#include <dirent.h>
typedef int FFNativeFD;
#endif
@@ -84,6 +85,8 @@ typedef enum FFPathType
bool ffPathExists(const char* path, FFPathType pathType);
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
FF_C_SCANF(2, 3)
const char* ffGetTerminalResponse(const char* request, const char* format, ...);
@@ -130,4 +133,25 @@ static inline bool wrapFclose(FILE** pfile)
}
#define FF_AUTO_CLOSE_FILE __attribute__((__cleanup__(wrapFclose)))
#ifndef _WIN32
static inline bool wrapClosedir(DIR** pdir)
{
assert(pdir);
if (!*pdir)
return false;
closedir(*pdir);
return true;
}
#else
static inline bool wrapClosedir(HANDLE* pdir)
{
assert(pdir);
if (!*pdir)
return false;
FindClose(*pdir);
return true;
}
#endif
#define FF_AUTO_CLOSE_DIR __attribute__((__cleanup__(wrapClosedir)))
#endif // FF_INCLUDED_common_io_io
+5 -9
View File
@@ -54,24 +54,20 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
uint32_t free = ffStrbufGetFree(buffer);
while(
(readed = read(fd, buffer->chars + buffer->length, free)) > 0 &&
(uint32_t) readed == free
(readed = read(fd, buffer->chars + buffer->length, free)) > 0
) {
buffer->length += (uint32_t) readed;
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
if((uint32_t) readed == free)
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
free = ffStrbufGetFree(buffer);
}
// In case of failure, read returns -1. We don't want to substract the length of the buffer.
if(readed > 0)
buffer->length += (uint32_t) readed;
buffer->chars[buffer->length] = '\0';
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
return readed >= 0;
return buffer->length > 0;
}
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
@@ -150,7 +146,7 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
fflush(stdout);
//Give the terminal 35ms to respond
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, 35) <= 0)
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
{
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
return "poll() timeout or failed";
+4 -6
View File
@@ -44,16 +44,14 @@ bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
bool success;
while(
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &readed, NULL)) &&
(uint32_t) readed == free
readed > 0
) {
buffer->length += (uint32_t) readed;
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
if((uint32_t) readed == free)
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
free = ffStrbufGetFree(buffer);
}
if(readed > 0)
buffer->length += (uint32_t) readed;
buffer->chars[buffer->length] = '\0';
ffStrbufTrimRight(buffer, '\n');
@@ -173,7 +171,7 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
while (true)
{
if (WaitForSingleObjectEx(hInput, 35, TRUE) != WAIT_OBJECT_0)
if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0)
{
SetConsoleMode(hInput, prev_mode);
return "WaitForSingleObject() failed or timeout";
+122 -158
View File
@@ -17,14 +17,19 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
ffStrbufSetNS(&moduleArgs->key, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
return true;
}
else if(ffStrEqualsIgnCase(key, "format"))
{
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
return true;
}
else if(ffStrEqualsIgnCase(key, "keyColor"))
{
ffOptionParseColor(yyjson_get_str(val), &moduleArgs->keyColor);
return true;
}
else if(ffStrEqualsIgnCase(key, "format"))
else if(ffStrEqualsIgnCase(key, "keyWidth"))
{
ffStrbufSetNS(&moduleArgs->outputFormat, (uint32_t) yyjson_get_len(val), yyjson_get_str(val));
moduleArgs->keyWidth = (uint32_t) yyjson_get_uint(val);
return true;
}
return false;
@@ -65,165 +70,84 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
return "Invalid enum value type; must be a string or integer";
}
static inline bool tryModule(const char* type, yyjson_val* module, const char* moduleName, void (*const f)(yyjson_val *module))
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
{
if (ffStrEqualsIgnCase(type, moduleName))
yyjson_mut_doc* doc = instance.state.resultDoc;
if (__builtin_expect(!doc, true)) return NULL;
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
if (baseInfo->generateJson)
baseInfo->generateJson(baseInfo, doc, module);
else
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
return module;
}
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
{
if(!isalpha(type[0])) return false;
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
{
f(module);
return true;
FFModuleBaseInfo* baseInfo = *modules;
if (ffStrEqualsIgnCase(type, baseInfo->name))
{
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
if (!genJson(baseInfo))
baseInfo->printModule(baseInfo);
return true;
}
}
return false;
}
static bool parseModuleJsonObject(const char* type, yyjson_val* module)
static void prepareModuleJsonObject(const char* type, yyjson_val* module)
{
switch (toupper(type[0]))
FFconfig* cfg = &instance.config;
switch (type[0])
{
case 'B': {
return
tryModule(type, module, FF_BATTERY_MODULE_NAME, ffParseBatteryJsonObject) ||
tryModule(type, module, FF_BIOS_MODULE_NAME, ffParseBiosJsonObject) ||
tryModule(type, module, FF_BLUETOOTH_MODULE_NAME, ffParseBluetoothJsonObject) ||
tryModule(type, module, FF_BOARD_MODULE_NAME, ffParseBoardJsonObject) ||
tryModule(type, module, FF_BREAK_MODULE_NAME, ffParseBreakJsonObject) ||
tryModule(type, module, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessJsonObject) ||
false;
case 'b': case 'B': {
if (ffStrEqualsIgnCase(type, FF_CPUUSAGE_MODULE_NAME))
ffPrepareCPUUsage();
break;
}
case 'C': {
return
tryModule(type, module, FF_CHASSIS_MODULE_NAME, ffParseChassisJsonObject) ||
tryModule(type, module, FF_COMMAND_MODULE_NAME, ffParseCommandJsonObject) ||
tryModule(type, module, FF_COLORS_MODULE_NAME, ffParseColorsJsonObject) ||
tryModule(type, module, FF_CPU_MODULE_NAME, ffParseCPUJsonObject) ||
tryModule(type, module, FF_CPUUSAGE_MODULE_NAME, ffParseCPUUsageJsonObject) ||
tryModule(type, module, FF_CURSOR_MODULE_NAME, ffParseCursorJsonObject) ||
tryModule(type, module, FF_CUSTOM_MODULE_NAME, ffParseCustomJsonObject) ||
false;
case 'd': case 'D': {
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
{
if (module) ffParseDiskIOJsonObject(&cfg->diskIo, module);
ffPrepareDiskIO(&cfg->diskIo);
}
break;
}
case 'D': {
return
tryModule(type, module, FF_DATETIME_MODULE_NAME, ffParseDateTimeJsonObject) ||
tryModule(type, module, FF_DE_MODULE_NAME, ffParseDEJsonObject) ||
tryModule(type, module, FF_DISPLAY_MODULE_NAME, ffParseDisplayJsonObject) ||
tryModule(type, module, FF_DISK_MODULE_NAME, ffParseDiskJsonObject) ||
false;
case 'n': case 'N': {
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
{
if (module) ffParseNetIOJsonObject(&cfg->netIo, module);
ffPrepareNetIO(&cfg->netIo);
}
break;
}
case 'F': {
return
tryModule(type, module, FF_FONT_MODULE_NAME, ffParseFontJsonObject) ||
false;
case 'p': case 'P': {
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
{
if (module) ffParsePublicIpJsonObject(&cfg->publicIP, module);
ffPreparePublicIp(&cfg->publicIP);
}
break;
}
case 'G': {
return
tryModule(type, module, FF_GAMEPAD_MODULE_NAME, ffParseGamepadJsonObject) ||
tryModule(type, module, FF_GPU_MODULE_NAME, ffParseGPUJsonObject) ||
false;
case 'w': case 'W': {
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
{
if (module) ffParseWeatherJsonObject(&cfg->weather, module);
ffPrepareWeather(&cfg->weather);
}
break;
}
case 'H': {
return
tryModule(type, module, FF_HOST_MODULE_NAME, ffParseHostJsonObject) ||
false;
}
case 'I': {
return
tryModule(type, module, FF_ICONS_MODULE_NAME, ffParseIconsJsonObject) ||
false;
}
case 'K': {
return
tryModule(type, module, FF_KERNEL_MODULE_NAME, ffParseKernelJsonObject) ||
false;
}
case 'L': {
return
tryModule(type, module, FF_LM_MODULE_NAME, ffParseLMJsonObject) ||
tryModule(type, module, FF_LOCALE_MODULE_NAME, ffParseLocaleJsonObject) ||
tryModule(type, module, FF_LOCALIP_MODULE_NAME, ffParseLocalIpJsonObject) ||
false;
}
case 'M': {
return
tryModule(type, module, FF_MEDIA_MODULE_NAME, ffParseMediaJsonObject) ||
tryModule(type, module, FF_MEMORY_MODULE_NAME, ffParseMemoryJsonObject) ||
tryModule(type, module, FF_MONITOR_MODULE_NAME, ffParseMonitorJsonObject) ||
false;
}
case 'O': {
return
tryModule(type, module, FF_OPENCL_MODULE_NAME, ffParseOpenCLJsonObject) ||
tryModule(type, module, FF_OPENGL_MODULE_NAME, ffParseOpenGLJsonObject) ||
tryModule(type, module, FF_OS_MODULE_NAME, ffParseOSJsonObject) ||
false;
}
case 'P': {
return
tryModule(type, module, FF_PACKAGES_MODULE_NAME, ffParsePackagesJsonObject) ||
tryModule(type, module, FF_PLAYER_MODULE_NAME, ffParsePlayerJsonObject) ||
tryModule(type, module, FF_POWERADAPTER_MODULE_NAME, ffParsePowerAdapterJsonObject) ||
tryModule(type, module, FF_PROCESSES_MODULE_NAME, ffParseProcessesJsonObject) ||
tryModule(type, module, FF_PUBLICIP_MODULE_NAME, ffParsePublicIpJsonObject) ||
false;
}
case 'S': {
return
tryModule(type, module, FF_SEPARATOR_MODULE_NAME, ffParseSeparatorJsonObject) ||
tryModule(type, module, FF_SHELL_MODULE_NAME, ffParseShellJsonObject) ||
tryModule(type, module, FF_SOUND_MODULE_NAME, ffParseSoundJsonObject) ||
tryModule(type, module, FF_SWAP_MODULE_NAME, ffParseSwapJsonObject) ||
false;
}
case 'T': {
return
tryModule(type, module, FF_TERMINAL_MODULE_NAME, ffParseTerminalJsonObject) ||
tryModule(type, module, FF_TERMINALFONT_MODULE_NAME, ffParseTerminalFontJsonObject) ||
tryModule(type, module, FF_TERMINALSIZE_MODULE_NAME, ffParseTerminalSizeJsonObject) ||
tryModule(type, module, FF_TITLE_MODULE_NAME, ffParseTitleJsonObject) ||
tryModule(type, module, FF_THEME_MODULE_NAME, ffParseThemeJsonObject) ||
false;
}
case 'U': {
return
tryModule(type, module, FF_UPTIME_MODULE_NAME, ffParseUptimeJsonObject) ||
tryModule(type, module, FF_USERS_MODULE_NAME, ffParseUsersJsonObject) ||
false;
}
case 'V': {
return
tryModule(type, module, FF_VULKAN_MODULE_NAME, ffParseVulkanJsonObject) ||
false;
}
case 'W': {
return
tryModule(type, module, FF_WALLPAPER_MODULE_NAME, ffParseWallpaperJsonObject) ||
tryModule(type, module, FF_WEATHER_MODULE_NAME, ffParseWeatherJsonObject) ||
tryModule(type, module, FF_WM_MODULE_NAME, ffParseWMJsonObject) ||
tryModule(type, module, FF_WIFI_MODULE_NAME, ffParseWifiJsonObject) ||
tryModule(type, module, FF_WMTHEME_MODULE_NAME, ffParseWMThemeJsonObject) ||
false;
}
default:
return false;
}
}
static const char* printJsonConfig(void)
static const char* printJsonConfig(bool prepare)
{
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
assert(root);
@@ -235,12 +159,14 @@ static const char* printJsonConfig(void)
if (!modules) return NULL;
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
yyjson_val* item;
size_t idx, max;
yyjson_arr_foreach(modules, idx, max, item)
{
uint64_t ms = 0;
if(__builtin_expect(instance.config.stat, false))
if(!prepare && instance.config.stat)
ms = ffTimeGetTick();
yyjson_val* module = item;
@@ -257,21 +183,32 @@ static const char* printJsonConfig(void)
else
return "modules must be an array of strings or objects";
if(!parseModuleJsonObject(type, module))
if(prepare)
prepareModuleJsonObject(type, module);
else if(!parseModuleJsonObject(type, module))
return "Unknown module type";
if(__builtin_expect(instance.config.stat, false))
if(!prepare && instance.config.stat)
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ffTimeGetTick() - ms);
if(instance.config.pipe)
puts(str);
ms = ffTimeGetTick() - ms;
if (resultDoc)
{
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
}
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
if(instance.config.pipe)
puts(str);
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
}
#if defined(_WIN32)
if (!instance.config.noBuffer) fflush(stdout);
if (!instance.config.noBuffer && !resultDoc) fflush(stdout);
#endif
}
@@ -430,9 +367,36 @@ const char* ffParseDisplayJsonConfig(void)
config->temperatureUnit = (FFTemperatureUnit) value;
}
else if (ffStrEqualsIgnCase(key, "percentType"))
config->percentType = (uint32_t) yyjson_get_uint(val);
config->percentType = (uint8_t) yyjson_get_uint(val);
else if (ffStrEqualsIgnCase(key, "percentNdigits"))
config->percentNdigits = (uint8_t) yyjson_get_uint(val);
else if (ffStrEqualsIgnCase(key, "bar"))
{
if (yyjson_is_obj(val))
{
const char* charElapsed = yyjson_get_str(yyjson_obj_get(val, "charElapsed"));
if (charElapsed)
ffStrbufSetS(&config->barCharElapsed, charElapsed);
const char* charTotal = yyjson_get_str(yyjson_obj_get(val, "charTotal"));
if (charTotal)
ffStrbufSetS(&config->barCharTotal, charTotal);
yyjson_val* border = yyjson_obj_get(val, "border");
if (border)
config->barBorder = yyjson_get_bool(border);
yyjson_val* width = yyjson_obj_get(val, "width");
if (width)
config->barWidth = (uint8_t) yyjson_get_uint(width);
}
else
return "display.bar must be an object";
}
else if (ffStrEqualsIgnCase(key, "noBuffer"))
config->noBuffer = yyjson_get_bool(val);
else if (ffStrEqualsIgnCase(key, "keyWidth"))
config->keyWidth = (uint32_t) yyjson_get_uint(val);
else
return "Unknown display property";
}
@@ -515,9 +479,9 @@ const char* ffParseLibraryJsonConfig(void)
return NULL;
}
void ffPrintJsonConfig(void)
void ffPrintJsonConfig(bool prepare)
{
const char* error = printJsonConfig();
const char* error = printJsonConfig(prepare);
if (error)
ffPrintErrorString("JsonConfig", 0, NULL, NULL, "%s", error);
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
}
+17 -4
View File
@@ -4,7 +4,20 @@
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
void ffPrintJsonConfig();
const char* ffParseGeneralJsonConfig();
const char* ffParseDisplayJsonConfig();
const char* ffParseLibraryJsonConfig();
void ffPrintJsonConfig(bool prepare);
const char* ffParseGeneralJsonConfig(void);
const char* ffParseDisplayJsonConfig(void);
const char* ffParseLibraryJsonConfig(void);
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
const char *_key,
const FFstrbuf* buf) {
return yyjson_mut_obj_add_strncpy(doc, obj, _key, buf->chars, buf->length);
}
yyjson_api_inline bool yyjson_mut_arr_add_strbuf(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
const FFstrbuf* buf) {
return yyjson_mut_arr_add_strncpy(doc, obj, buf->chars, buf->length);
}
+166
View File
@@ -0,0 +1,166 @@
#include "fastfetch.h"
static FFModuleBaseInfo* A[] = {
NULL,
};
static FFModuleBaseInfo* B[] = {
(void*) &instance.config.battery,
(void*) &instance.config.bios,
(void*) &instance.config.bluetooth,
(void*) &instance.config.board,
(void*) &instance.config.break_,
(void*) &instance.config.brightness,
NULL,
};
static FFModuleBaseInfo* C[] = {
(void*) &instance.config.chassis,
(void*) &instance.config.command,
(void*) &instance.config.colors,
(void*) &instance.config.cpu,
(void*) &instance.config.cpuUsage,
(void*) &instance.config.cursor,
(void*) &instance.config.custom,
NULL,
};
static FFModuleBaseInfo* D[] = {
(void*) &instance.config.dateTime,
(void*) &instance.config.de,
(void*) &instance.config.display,
(void*) &instance.config.disk,
(void*) &instance.config.diskIo,
NULL,
};
static FFModuleBaseInfo* E[] = {
NULL,
};
static FFModuleBaseInfo* F[] = {
(void*) &instance.config.font,
NULL,
};
static FFModuleBaseInfo* G[] = {
(void*) &instance.config.gamepad,
(void*) &instance.config.gpu,
NULL,
};
static FFModuleBaseInfo* H[] = {
(void*) &instance.config.host,
NULL,
};
static FFModuleBaseInfo* I[] = {
(void*) &instance.config.icons,
NULL,
};
static FFModuleBaseInfo* J[] = {
NULL,
};
static FFModuleBaseInfo* K[] = {
(void*) &instance.config.kernel,
NULL,
};
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.lm,
(void*) &instance.config.locale,
(void*) &instance.config.localIP,
NULL,
};
static FFModuleBaseInfo* M[] = {
(void*) &instance.config.media,
(void*) &instance.config.memory,
(void*) &instance.config.monitor,
NULL,
};
static FFModuleBaseInfo* N[] = {
(void*) &instance.config.netIo,
NULL,
};
static FFModuleBaseInfo* O[] = {
(void*) &instance.config.openCL,
(void*) &instance.config.openGL,
(void*) &instance.config.os,
NULL,
};
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.packages,
(void*) &instance.config.player,
(void*) &instance.config.powerAdapter,
(void*) &instance.config.processes,
(void*) &instance.config.publicIP,
NULL,
};
static FFModuleBaseInfo* Q[] = {
NULL,
};
static FFModuleBaseInfo* R[] = {
NULL,
};
static FFModuleBaseInfo* S[] = {
(void*) &instance.config.separator,
(void*) &instance.config.shell,
(void*) &instance.config.sound,
(void*) &instance.config.swap,
NULL,
};
static FFModuleBaseInfo* T[] = {
(void*) &instance.config.terminal,
(void*) &instance.config.terminalFont,
(void*) &instance.config.terminalSize,
(void*) &instance.config.title,
(void*) &instance.config.theme,
NULL,
};
static FFModuleBaseInfo* U[] = {
(void*) &instance.config.uptime,
(void*) &instance.config.users,
NULL,
};
static FFModuleBaseInfo* V[] = {
(void*) &instance.config.version,
(void*) &instance.config.vulkan,
NULL,
};
static FFModuleBaseInfo* W[] = {
(void*) &instance.config.wallpaper,
(void*) &instance.config.weather,
(void*) &instance.config.wm,
(void*) &instance.config.wifi,
(void*) &instance.config.wmTheme,
NULL,
};
static FFModuleBaseInfo* X[] = {
NULL,
};
static FFModuleBaseInfo* Y[] = {
NULL,
};
static FFModuleBaseInfo* Z[] = {
NULL,
};
FFModuleBaseInfo** ffModuleInfos[] = {
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
};
+30
View File
@@ -0,0 +1,30 @@
#include "netif.h"
#ifndef _WIN32
#include <net/if.h>
#else
#define IF_NAMESIZE 16
#endif
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex);
enum { IF_INDEX_UNINITIALIZED = (uint32_t) -1, IF_INDEX_INVALID = (uint32_t) -2 };
static uint32_t ifIndex = IF_INDEX_UNINITIALIZED;
static char ifName[IF_NAMESIZE + 1];
static inline void init()
{
if (ifIndex == (uint32_t) IF_INDEX_UNINITIALIZED && !ffNetifGetDefaultRouteImpl(ifName, &ifIndex))
ifIndex = (uint32_t) IF_INDEX_INVALID;
}
const char* ffNetifGetDefaultRouteIfName()
{
init();
return ifName;
}
uint32_t ffNetifGetDefaultRouteIfIndex()
{
init();
return ifIndex;
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#ifndef _WIN32
const char* ffNetifGetDefaultRouteIfName();
#endif
uint32_t ffNetifGetDefaultRouteIfIndex();
+98
View File
@@ -0,0 +1,98 @@
#include "netif.h"
#include "common/io/io.h"
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define ROUNDUP2(a, n) ((a) > 0 ? (1 + (((a) - 1U) | ((n) - 1))) : (n))
#if defined(__APPLE__)
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
#elif defined(__NetBSD__)
# define ROUNDUP(a) ROUNDUP2((a), sizeof(uint64_t))
#elif defined(__FreeBSD__)
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
#elif defined(__OpenBSD__)
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
#else
# error unknown platform
#endif
static struct sockaddr *
get_rt_address(struct rt_msghdr *rtm, int desired)
{
struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
for (int i = 0; i < RTAX_MAX; i++)
{
if (rtm->rtm_addrs & (1 << i))
{
if ((1 <<i ) == desired)
return sa;
sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
}
}
return NULL;
}
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
{
//https://github.com/hashPirate/copenheimer-masscan-fork/blob/36f1ed9f7b751a7dccd5ed27874e2e703db7d481/src/rawsock-getif.c#L104
FF_AUTO_CLOSE_FD int pfRoute = socket(PF_ROUTE, SOCK_RAW, AF_INET);
if (pfRoute < 0)
return false;
{
struct timeval timeout = {1, 0};
setsockopt(pfRoute, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
setsockopt(pfRoute, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout));
}
int pid = getpid();
struct {
struct rt_msghdr hdr;
struct sockaddr_in dst;
uint8_t data[512];
} rtmsg = {
.hdr = {
.rtm_type = RTM_GET,
.rtm_flags = RTF_UP | RTF_GATEWAY,
.rtm_version = RTM_VERSION,
.rtm_addrs = RTA_DST | RTA_IFP,
.rtm_msglen = sizeof(rtmsg.hdr) + sizeof(rtmsg.dst),
.rtm_pid = pid,
.rtm_seq = 1,
},
.dst = {
.sin_family = AF_INET,
.sin_len = sizeof(rtmsg.dst),
},
};
if (write(pfRoute, &rtmsg, rtmsg.hdr.rtm_msglen) != rtmsg.hdr.rtm_msglen)
return false;
while (read(pfRoute, &rtmsg, sizeof(rtmsg)) > 0)
{
if (rtmsg.hdr.rtm_seq == 1 && rtmsg.hdr.rtm_pid == pid)
{
struct sockaddr_dl* sdl = (struct sockaddr_dl *)get_rt_address(&rtmsg.hdr, RTA_IFP);
if (sdl)
{
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
iface[sdl->sdl_nlen] = '\0';
*ifIndex = sdl->sdl_index;
return true;
}
return false;
}
}
return false;
}
+28
View File
@@ -0,0 +1,28 @@
#include "netif.h"
#include "common/io/io.h"
#include <net/if.h>
#include <stdio.h>
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
{
FILE* FF_AUTO_CLOSE_FILE netRoute = fopen("/proc/net/route", "r");
if (!netRoute) return false;
// skip first line
flockfile(netRoute);
while (getc_unlocked(netRoute) != '\n');
funlockfile(netRoute);
unsigned long long destination; //, gateway, flags, refCount, use, metric, mask, mtu,
while (fscanf(netRoute, "%" FF_STR(IF_NAMESIZE) "s%llx%*[^\n]", iface, &destination) == 2)
{
if (destination != 0) continue;
*ifIndex = if_nametoindex(iface);
return true;
}
return false;
}
+27
View File
@@ -0,0 +1,27 @@
#include "netif.h"
#include "util/mallocHelper.h"
#include <iphlpapi.h>
bool ffNetifGetDefaultRouteImpl(FF_MAYBE_UNUSED char* iface/* unsupported */, uint32_t* ifIndex)
{
ULONG size = 0;
if (GetIpForwardTable(NULL, &size, TRUE) != ERROR_INSUFFICIENT_BUFFER)
return false;
FF_AUTO_FREE MIB_IPFORWARDTABLE* pIpForwardTable = (MIB_IPFORWARDTABLE*) malloc(size);
if (GetIpForwardTable(pIpForwardTable, &size, TRUE) != ERROR_SUCCESS)
return false;
for (uint32_t i = 0; i < pIpForwardTable->dwNumEntries; ++i)
{
MIB_IPFORWARDROW* ipForwardRow = &pIpForwardTable->table[i];
if (ipForwardRow->dwForwardDest == 0 && ipForwardRow->dwForwardMask == 0)
{
*ifIndex = ipForwardRow->dwForwardIfIndex;
break;
}
}
return true;
}
+4 -3
View File
@@ -77,7 +77,8 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
{
#ifdef FF_HAVE_THREADS
ffThreadJoin(state->thread);
if (!ffThreadJoin(state->thread, timeout))
return false;
#endif
if(state->sockfd == -1)
return false;
@@ -85,8 +86,8 @@ bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, ui
if(timeout > 0)
{
struct timeval timev;
timev.tv_sec = 0;
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
timev.tv_sec = timeout / 1000;
timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
}
+8 -2
View File
@@ -34,6 +34,11 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
ffOptionParseString(argumentKey, value, &result->key);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "format"))
{
ffOptionParseString(argumentKey, value, &result->outputFormat);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "key-color"))
{
if(value == NULL)
@@ -44,9 +49,9 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
ffOptionParseColor(value, &result->keyColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "format"))
else if(ffStrEqualsIgnCase(subKey, "key-width"))
{
ffOptionParseString(argumentKey, value, &result->outputFormat);
result->keyWidth = ffOptionParseUInt32(argumentKey, value);
return true;
}
return false;
@@ -175,6 +180,7 @@ void ffOptionInitModuleArg(FFModuleArgs* args)
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInit(&args->outputFormat);
args->keyWidth = 0;
}
void ffOptionDestroyModuleArg(FFModuleArgs* args)
+38
View File
@@ -2,11 +2,49 @@
#include "util/FFstrbuf.h"
struct yyjson_val;
struct yyjson_mut_doc;
struct yyjson_mut_val;
// Must be the first field of FFModuleOptions
typedef struct FFModuleBaseInfo
{
const char* name;
// A dirty polymorphic implementation in C.
// This is UB, because `void*` is not compatible with `FF*Options*`.
// However we can't do it better unless we move to C++, so that `option` becomes a `this` pointer
// https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
void (*parseJsonObject)(void* options, struct yyjson_val *module);
void (*printModule)(void* options);
void (*generateJson)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
void (*printHelpFormat)(void);
} FFModuleBaseInfo;
static inline void ffOptionInitModuleBaseInfo(
FFModuleBaseInfo* baseInfo,
const char* name,
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
void* printModule, // void (*const printModule)(void* options)
void* generateJson, // void (*const generateJson)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void)
)
{
baseInfo->name = name;
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
baseInfo->generateJson = (__typeof__(baseInfo->generateJson)) generateJson;
baseInfo->printHelpFormat = printHelpFormat;
}
typedef struct FFModuleArgs
{
FFstrbuf key;
FFstrbuf keyColor;
FFstrbuf outputFormat;
uint32_t keyWidth;
} FFModuleArgs;
typedef struct FFKeyValuePair
+42 -51
View File
@@ -2,7 +2,7 @@
#include "common/printing.h"
#include "util/textModifier.h"
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor)
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
{
ffLogoPrintLine();
@@ -10,20 +10,24 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrb
if(moduleName == NULL)
return;
//This is used as a magic value for hiding keys
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
return;
if(!instance.config.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (instance.config.brightColor)
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
if(customKeyColor != NULL && customKeyColor->length > 0)
ffPrintColor(customKeyColor);
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
ffPrintColor(&moduleArgs->keyColor);
else
ffPrintColor(&instance.config.colorKeys);
}
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if(customKeyFormat == NULL || customKeyFormat->length == 0)
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
{
fputs(moduleName, stdout);
@@ -33,10 +37,10 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrb
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){
ffParseFormatString(&key, &moduleArgs->key, 1, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
});
ffPrintUserString(key.chars);
ffStrbufWriteTo(&key, stdout);
}
if(!instance.config.pipe)
@@ -46,32 +50,37 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrb
if(!instance.config.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
}
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateA(256);
ffParseFormatString(&buffer, format, numArgs, arguments);
if(buffer.length > 0)
if (!instance.config.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
{
ffPrintLogoAndKey(moduleName, moduleIndex, customKeyFormat, customKeyColor);
ffPrintUserString(buffer.chars);
putchar('\n');
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.keyWidth;
if (keyWidth > 0)
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
}
}
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments)
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments)
{
ffPrintFormatString(moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->keyColor, &moduleArgs->outputFormat, numArgs, arguments);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (moduleArgs)
ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
else
ffStrbufAppendS(&buffer, "unknown");
if(buffer.length > 0)
{
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
ffStrbufPutTo(&buffer, stdout);
}
}
static void printError(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, va_list arguments)
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
{
if(!instance.config.showErrors)
return;
ffPrintLogoAndKey(moduleName, moduleIndex, customKeyFormat, customKeyColor);
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
if(!instance.config.pipe)
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
@@ -84,11 +93,11 @@ static void printError(const char* moduleName, uint8_t moduleIndex, const FFstrb
putchar('\n');
}
void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, ...)
void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...)
{
va_list arguments;
va_start(arguments, message);
printError(moduleName, moduleIndex, customKeyFormat, customKeyColor, message, arguments);
printError(moduleName, moduleIndex, moduleArgs, printType, message, arguments);
va_end(arguments);
}
@@ -96,7 +105,7 @@ void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArg
{
va_list arguments;
va_start(arguments, message);
printError(moduleName, moduleIndex, &moduleArgs->key, &moduleArgs->keyColor, message, arguments);
printError(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, message, arguments);
va_end(arguments);
}
@@ -107,9 +116,7 @@ void ffPrintColor(const FFstrbuf* colorValue)
if(colorValue->length == 0)
return;
fputs("\033[", stdout);
ffStrbufWriteTo(colorValue, stdout);
fputc('m', stdout);
printf("\e[%sm", colorValue->chars);
}
void ffPrintCharTimes(char c, uint32_t times)
@@ -126,33 +133,17 @@ void ffPrintCharTimes(char c, uint32_t times)
fwrite(str, 1, remaining, stdout);
}
void ffPrintUserString(const char* value)
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
{
while(*value != '\0')
{
if(*value != '\\')
{
putchar(*value);
++value;
continue;
}
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
ffStrbufLowerCase(&buffer);
printf("--%s-format:\n", buffer.chars);
printf("Sets the format string for %s output.\n", name);
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
puts("The following values are passed:");
++value;
for(unsigned i = 0; i < numArgs; i++)
printf(" {%u}: %s\n", i + 1, args[i]);
if(*value == 'n')
putchar('\n');
else if(*value == 't')
putchar('\t');
else if(*value == 'e')
putchar('\e');
else if(*value == '\\')
putchar('\\');
else
{
putchar('\\');
putchar(*value);
}
++value;
}
printf("The default is something similar to \"%s\".\n", def);
}
+17 -5
View File
@@ -6,13 +6,25 @@
#include "fastfetch.h"
#include "common/format.h"
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor);
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments);
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments);
FF_C_PRINTF(5, 6) void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customKeyColor, const char* message, ...);
typedef enum FFPrintType {
FF_PRINT_TYPE_DEFAULT = 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
} FFPrintType;
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
static inline void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments)
{
ffPrintFormatString(moduleName, moduleIndex, moduleArgs, FF_PRINT_TYPE_DEFAULT, numArgs, arguments);
}
FF_C_PRINTF(5, 6) void ffPrintErrorString(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
FF_C_PRINTF(4, 5) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
void ffPrintUserString(const char* str);
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
#endif
+1
View File
@@ -38,6 +38,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
close(pipes[0]);
close(pipes[1]);
close(useStdErr ? STDOUT_FILENO : STDERR_FILENO);
setenv("LANG", "C", 1);
execvp(argv[0], argv);
exit(901);
}
+38 -2
View File
@@ -10,6 +10,7 @@
#include <handleapi.h>
#include <synchapi.h>
#include <process.h>
#include <processthreadsapi.h>
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
typedef SRWLOCK FFThreadMutex;
typedef HANDLE FFThreadType;
@@ -21,9 +22,23 @@
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static __stdcall unsigned fn ## ThreadMain () { fn(); return 0; }
static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); }
static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, 0xffffffff /*INFINITE*/); }
static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout)
{
if (WaitForSingleObject(thread, timeout == 0 ? (DWORD) -1 : timeout) != 0 /*WAIT_OBJECT_0*/)
{
TerminateThread(thread, (DWORD) -1);
CloseHandle(thread);
return false;
}
CloseHandle(thread);
return true;
}
#else
#include <pthread.h>
#include <signal.h>
#if __has_include(<pthread_np.h>)
#include <pthread_np.h>
#endif
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t FFThreadMutex;
typedef pthread_t FFThreadType;
@@ -37,7 +52,28 @@
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static void* fn ## ThreadMain () { fn(); return NULL; }
static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); }
static inline bool ffThreadJoin(FFThreadType thread, FF_MAYBE_UNUSED uint32_t timeout)
{
#if (defined(__linux__) && !defined(__ANDROID__)) || __has_include(<pthread_np.h>)
if (timeout > 0)
{
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
{
ts.tv_sec += ts.tv_sec / 1000;
ts.tv_nsec += (ts.tv_nsec % 1000) * 1000000;
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
{
pthread_kill(thread, SIGTERM);
return false;
}
return true;
}
}
#endif
pthread_join(thread, NULL);
return true;
}
#endif
#else //FF_HAVE_THREADS
#define FF_THREAD_MUTEX_INITIALIZER 0
+14
View File
@@ -7,6 +7,7 @@
#ifdef _WIN32
#include <synchapi.h>
#include <profileapi.h>
#include <sysinfoapi.h>
#else
#include <time.h>
#endif
@@ -26,6 +27,19 @@ static inline uint64_t ffTimeGetTick() //In msec
#endif
}
static inline uint64_t ffTimeGetNow()
{
#ifdef _WIN32
uint64_t timeNow;
GetSystemTimeAsFileTime((FILETIME*) &timeNow);
return (timeNow - 116444736000000000ull) / 10000ull;
#else
struct timespec timeNow;
clock_gettime(CLOCK_REALTIME, &timeNow);
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
#endif
}
static inline void ffTimeSleep(uint32_t msec)
{
#ifdef _WIN32
+11 -3
View File
@@ -360,7 +360,7 @@
#--terminal-key Terminal
#--terminalfont-key Terminal Font
#--cpu-key CPU
#--cpu-usage-key CPU Usage
#--cpuusage-key CPU Usage
#--gpu-key GPU {1}
#--memory-key Memory
#--swap-key Swap
@@ -370,12 +370,14 @@
#--lm-key LM
#--locale-key Locale
#--localip-key Local IP ({1})
#--netio-key Network IO ({1})
#--publicip-key Public IP
#--wifi-key Wifi
#--weather-key Weather
#--player-key Media Player
#--media-key Media
#--datetime-key Date Time
#--version-key Version
#--vulkan-key Vulkan
#--opengl-key OpenGL
#--opencl-key OpenCL
@@ -390,6 +392,7 @@
# For information on format strings, see "fastfetch --help format".
# To see the parameter they take and their default value, see "fastfetch --help *-format", e.g. "fastfetch --help os-format".
# An empty format string (As they are currently below) will behave as if it was not set.
#--title-format
#--os-format
#--host-format
#--chassis-format
@@ -410,7 +413,7 @@
#--terminal-format
#--terminalfont-format
#--cpu-format
#--cpu-usage-format
#--cpuusage-format
#--gpu-format
#--memory-format
#--swap-format
@@ -420,12 +423,14 @@
#--lm-format
#--locale-format
#--localip-format
#--netio-format
#--publicip-format
#--weather-format
#--monitor-format
#--player-format
#--media-format
#--datetime-format
#--version-format
#--vulkan-format
#--opengl-format
#--opencl-format
@@ -437,6 +442,7 @@
# Key color options:
# Overrides the global `--color-keys` for one specified module
#--title-key-color
#--os-key-color
#--host-key-color
#--chassis-key-color
@@ -457,7 +463,7 @@
#--terminal-key-color
#--terminalfont-key-color
#--cpu-key-color
#--cpu-usage-key-color
#--cpuusage-key-color
#--gpu-key-color
#--memory-key-color
#--swap-key-color
@@ -467,12 +473,14 @@
#--lm-key-color
#--locale-key-color
#--localip-key-color
#--netio-key-color
#--publicip-key-color
#--weather-key-color
#--monitor-key-color
#--player-key-color
#--media-key-color
#--datetime-key-color
#--version-key-color
#--vulkan-key-color
#--opengl-key-color
#--opencl-key-color
+24 -7
View File
@@ -19,6 +19,7 @@ Informative options:
General options:
--load-config <file>: Load a config file or preset (+)
--config <file>: Alias of --load-config (+)
--multithreading <?value>: Use multiple threads to detect values
--stat <?value>: Show time usage (in ms) for individual modules
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
@@ -40,6 +41,7 @@ Logo options:
--logo-padding-right <padding>: Set the padding on the right of the logo
--logo-padding-top <padding>: Set the padding on the top of the logo
--logo-print-remaining <?value>: Whether to print the remaining logo, if it has more lines than modules to display
--logo-recache <?value>: If true, regenerate image logo cache
--file <file>: Short for --logo-type file --logo <file>
--file-raw <file>: Short for --logo-type file-raw --logo <file>
--data <data>: Short for --logo-type data --logo <data>
@@ -58,8 +60,9 @@ Display options:
-s,--structure <structure>: Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
--color-keys <color>: Set the color of the keys
--color-title <color>: Set the color of the title
--color <color>: Set the color of both the keys and title
--key-width <num>: Align the width of keys to <num> characters
--bright-color <?value>: Set if the keys, title and ASCII logo should be printed in bright color. Default is true
-c,--color <color>: Set the color of both the keys and title
--separator <str>: Set the separator between key and value. Default is a colon with a space
--set <key=value>: Hard set the value of a key
--set-keyless <key=value>: Hard set the value of a key, but don't print the key or the separator
@@ -68,6 +71,11 @@ Display options:
--hide-cursor <?value>: Whether to hide the cursor during the run
--binary-prefix <value>: Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC
--percent-type <value>: Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number. Default is 1
--percent-ndigits <value>: Set the number of digits to keep after the decimal point when formatting percentage numbers. Default is 0
--bar-char-elapsed <str>: Set the character to use in elapsed part. Default is '■'
--bar-char-total <str>: Set the character to use in total part. Default is '-'
--bar-width <?num>: Set the width of the bar, in number of characters. Default is 10
--bar-border <?value>: Whether to show a border around the bar. Default is true
--no-buffer <?value>: Set if the stdout application buffer should be disabled. Default is false
--size-ndigits <value>: Set the number of digits to keep after the decimal point when formatting sizes
--size-max-prefix <value>: Set the largest binary prefix to use when formatting sizes. Default is YB
@@ -82,6 +90,7 @@ General module options:
For modules which print multiple lines, the string is parsed as a format string with the index as first character.
--<module>-key-color <format>: Override the global `--color-keys` option for each specific module.
--<module>-key-width <num>: Override the global `--key-width` option for each specific module.
Library options: Set the path of a library to load
--lib-PCI <path>
@@ -120,25 +129,33 @@ Module specific options:
--disk-show-external <?value>: Set if external volume should be printed. Default is true
--disk-show-hidden <?value>: Set if hidden volumes should be printed. Default is false
--disk-show-subvolumes <?value>: Set if subvolumes should be printed. Default is false
--disk-show-readonly <?value>: Set if read only volumes should be printed. Default is false
--disk-show-unknown <?value>: Set if unknown (unable to detect sizes) volumes should be printed. Default is false
--disk-use-available <?value>: Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes. Default is false
--diskio-name-prefix <str>: Show disks with given name prefix only. Default is empty
--bluetooth-show-disconnected: <?value>: Set if disconnected bluetooth devices should be printed. Default is false
--display-compact-type: <?string>: Set if all displays should be printed in one line. Default is none
--display-detect-name: <?value>: Set if display name should be detected and printed (if supported). Default is false
--display-precise-refresh-rate: <?value>:Set if decimal refresh rates should not be rounded into integers when printing. Default is true
--brightness-ddcci-sleep: <num> Set the sleep times (in ms) when sending DDC/CI requests. See <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail. Default is 10
--sound-type: <value>: Set what type of sound devices should be printed. Should be either main, active or all. Default is main
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
--gpu-force-vulkan <?value>: Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
--cpu-freq-ndigits <num>: Set the number of digits to keep after the decimal point when printing CPU frequency. Default is 2
--cpuusage-separate <?value>: Display CPU usage per CPU logical core, instead of an average result. Default is false
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
--gpu-force-vulkan <?value>: Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false
--gpu-hide-type <?value>: Specify the type of GPUs should not be printed. Must be `integrated`, `discrete` or `none`. Default is none
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
--localip-show-ipv4 <?value>: Show IPv4 addresses in local ip module. Default is true
--localip-show-ipv6 <?value>: Show IPv6 addresses in local ip module. Default is false
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
--localip-name-prefix <str>: Show IPs with given name prefix only. Default is empty
--localip-default-route-only <?value>: Show ips that are used for default routing only. Default is false
--localip-name-prefix <str>: Show interfaces with given interface name prefix only. Default is empty
--localip-default-route-only <?value>: Show the interface that is used for default routing only. Default is false
--localip-compact <?value>: Show all IPs in one line. Default is false
--netio-name-prefix <str>: Show interfaces with given name prefix only. Default is empty
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is false
--publicip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
--publicip-url: The URL of public IP detection server to be used.
--weather-location: Set the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`).
-45
View File
@@ -1,45 +0,0 @@
Battery
Bios
Bluetooth
Board
Break
Chassis
Colors
CPU
CPUUsage
Cursor
Date
Datetime
DE
Disk
Display
Font
GPU
Host
Icons
Kernel
Locale
LocalIP
Media
Memory
OpenGL
OS
Packages
Player
PowerAdapter
Processes
PublicIP
Separator
Shell
Swap
Terminal
TerminalFont
Theme
Time
Title
Uptime
Vulkan
Weather
Wifi
WM
WMTheme
+2 -2
View File
@@ -7,7 +7,7 @@
#define FF_BATTERY_TEMP_UNSET (0/0.0)
typedef struct BatteryResult
typedef struct FFBatteryResult
{
FFstrbuf manufacturer;
FFstrbuf modelName;
@@ -15,7 +15,7 @@ typedef struct BatteryResult
double capacity;
FFstrbuf status;
double temperature;
} BatteryResult;
} FFBatteryResult;
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results);
+3 -3
View File
@@ -33,7 +33,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
if (!yyjson_is_obj(root))
return "Battery info result is not a JSON object";
BatteryResult* battery = ffListAdd(results);
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
@@ -68,7 +68,7 @@ static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
return NULL;
ffStrbufClear(&temp);
BatteryResult* battery = ffListAdd(results);
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
@@ -78,7 +78,7 @@ static const char* parseDumpsys(FFBatteryOptions* options, FFlist* results)
if (ffParsePropLines(start, "AC powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
ffStrbufAppendS(&battery->status, "AC powered");
ffStrbufClear(&temp);
if (ffParsePropLines(start, "USB powered: ", &temp) && ffStrbufEqualS(&temp, "true"))
{
if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
+2 -6
View File
@@ -17,12 +17,8 @@ static double detectBatteryTemp(void)
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
{
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleSmartBattery\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleSmartBattery"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
@@ -38,7 +34,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
bool boolValue;
const char* error;
BatteryResult* battery = ffListAdd(results);
FFBatteryResult* battery = ffListAdd(results);
battery->capacity = 0.0/0.0;
int currentCapacity, maxCapacity;
+1 -1
View File
@@ -32,7 +32,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
if(ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) < 0 || (battio.battinfo.state == ACPI_BATT_STAT_NOT_PRESENT))
continue;
BatteryResult* battery = ffListAdd(results);
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
+1 -1
View File
@@ -27,7 +27,7 @@ static void parseBattery(FFstrbuf* dir, FFlist* results)
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0)
return;
BatteryResult* result = ffListAdd(results);
FFBatteryResult* result = ffListAdd(results);
//capacity must exist and be not empty
ffStrbufAppendS(dir, "/capacity");
+2 -2
View File
@@ -74,7 +74,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
continue;
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
ffStrbufInitS(&battery->technology, "Lead Acid");
@@ -143,7 +143,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
SYSTEM_BATTERY_STATE info;
if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
{
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->technology);
+3 -3
View File
@@ -5,15 +5,15 @@
#include "fastfetch.h"
typedef struct FFBluetoothDevice
typedef struct FFBluetoothResult
{
FFstrbuf name;
FFstrbuf address;
FFstrbuf type;
uint8_t battery; // 0-100%
bool connected;
} FFBluetoothDevice;
} FFBluetoothResult;
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */);
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */);
#endif
+2 -2
View File
@@ -2,7 +2,7 @@
#import <IOBluetooth/IOBluetooth.h>
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */)
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
{
NSArray<IOBluetoothDevice*>* ioDevices = IOBluetoothDevice.pairedDevices;
if(!ioDevices)
@@ -10,7 +10,7 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */)
for(IOBluetoothDevice* ioDevice in ioDevices)
{
FFBluetoothDevice* device = ffListAdd(devices);
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, ioDevice.name.UTF8String);
ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String);
ffStrbufInit(&device->type);
+4 -4
View File
@@ -44,7 +44,7 @@ array [ //root
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothDevice* device)
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
@@ -72,7 +72,7 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
ffDBusGetBool(dbus, &dictIter, &device->connected);
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothDevice* device)
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
@@ -130,7 +130,7 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
FFBluetoothDevice* device = ffListAdd(devices);
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInit(&device->type);
@@ -193,7 +193,7 @@ static const char* detectBluetooth(FFlist* devices)
#endif
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothDevice */)
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
@@ -1,6 +1,6 @@
#include "bluetooth.h"
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothDevice */)
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
return "Not supported on this platform";
}
+10 -5
View File
@@ -7,7 +7,7 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-sign"
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */)
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
{
BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = {
.fReturnConnected = TRUE,
@@ -25,7 +25,7 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */)
return "BluetoothFindFirstDevice() failed or no devices found";
do {
FFBluetoothDevice* device = ffListAdd(devices);
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInit(&device->type);
@@ -33,9 +33,14 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothDevice */)
device->connected = !!btdi.fConnected;
ffStrbufSetWS(&device->name, btdi.szName);
for (uint32_t i = 0; i < sizeof(btdi.Address.rgBytes) / sizeof(btdi.Address.rgBytes); ++i)
ffStrbufAppendF(&device->address, "%X:", btdi.Address.rgBytes[i]);
ffStrbufTrimRight(&device->name, ':');
ffStrbufAppendF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
btdi.Address.rgBytes[0],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[3],
btdi.Address.rgBytes[4],
btdi.Address.rgBytes[5]);
//https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Assigned%20Numbers.pdf
if(BitTest(&btdi.ulClassofDevice, 13))
+2 -2
View File
@@ -9,9 +9,9 @@
typedef struct FFBrightnessResult
{
FFstrbuf name;
float value;
double min, max, current;
} FFBrightnessResult;
const char* ffDetectBrightness(FFlist* result); // list of FFBrightnessResult
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult
#endif
+97 -13
View File
@@ -1,9 +1,27 @@
#include "brightness.h"
#include "detection/displayserver/displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/ddcci.h"
#include "util/edidHelper.h"
#include <CoreGraphics/CoreGraphics.h>
// DDC/CI
#ifdef __aarch64__
typedef CFTypeRef IOAVServiceRef;
extern IOAVServiceRef IOAVServiceCreate(CFAllocatorRef allocator) __attribute__((weak_import));
extern IOAVServiceRef IOAVServiceCreateWithService(CFAllocatorRef allocator, io_service_t service) __attribute__((weak_import));
extern IOReturn IOAVServiceCopyEDID(IOAVServiceRef service, CFDataRef* x2) __attribute__((weak_import));
extern IOReturn IOAVServiceReadI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t offset, void* outputBuffer, uint32_t outputBufferSize) __attribute__((weak_import));
extern IOReturn IOAVServiceWriteI2C(IOAVServiceRef service, uint32_t chipAddress, uint32_t dataAddress, void* inputBuffer, uint32_t inputBufferSize) __attribute__((weak_import));
#else
// DDC/CI (Intel)
#include <IOKit/IOKitLib.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <IOKit/i2c/IOI2CInterface.h>
extern void CGSServiceForDisplayNumber(CGDirectDisplayID display, io_service_t* service) __attribute__((weak_import));
#endif
// ACPI
extern int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness) __attribute__((weak_import));
// Works for internal display
@@ -20,7 +38,9 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
if(DisplayServicesGetBrightness((CGDirectDisplayID) display->id, &value) == kCGErrorSuccess)
{
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->value = value * 100;
brightness->current = value;
brightness->max = 1;
brightness->min = 0;
ffStrbufInitCopy(&brightness->name, &display->name);
}
}
@@ -29,19 +49,16 @@ static const char* detectWithDisplayServices(const FFDisplayServerResult* displa
return NULL;
}
#ifdef __aarch64__
// https://github.com/waydabber/m1ddc
// Works for Apple Silicon and USB-C adapter connection ( but not HTMI )
static const char* detectWithDdcci(FFlist* result)
static const char* detectWithDdcci(FF_MAYBE_UNUSED const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!IOAVServiceCreate || !IOAVServiceReadI2C)
return "IOAVService is not available";
CFMutableDictionaryRef matchDict = IOServiceMatching("DCPAVServiceProxy");
if (matchDict == NULL)
return "IOServiceMatching(\"DCPAVServiceProxy\") failed";
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("DCPAVServiceProxy"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate();
@@ -76,7 +93,7 @@ static const char* detectWithDdcci(FFlist* result)
for (uint32_t i = 0; i < 2; ++i)
{
IOAVServiceWriteI2C(service, 0x37, 0x51, i2cIn, sizeof(i2cIn));
usleep(10000);
usleep(options->ddcciSleep * 1000);
}
}
@@ -90,7 +107,9 @@ static const char* detectWithDdcci(FFlist* result)
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->value = (float) current * 100.f / max;
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInit(&brightness->name);
uint8_t edid[128] = {};
@@ -101,15 +120,80 @@ static const char* detectWithDdcci(FFlist* result)
return NULL;
}
#else
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFBrightnessOptions* options, FFlist* result)
{
if (!CGSServiceForDisplayNumber) return "CGSServiceForDisplayNumber is not available";
const char* ffDetectBrightness(FFlist* result)
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
{
if (display->type == FF_DISPLAY_TYPE_EXTERNAL)
{
io_service_t framebuffer = 0;
CGSServiceForDisplayNumber((CGDirectDisplayID)display->id, &framebuffer);
if (framebuffer == 0) continue;
IOItemCount count;
if (IOFBGetI2CInterfaceCount(framebuffer, &count) != KERN_SUCCESS || count == 0) continue;
io_service_t interface = 0;
if (IOFBCopyI2CInterfaceForBus(framebuffer, 0, &interface) != KERN_SUCCESS) continue;
uint8_t i2cOut[12] = {};
IOI2CConnectRef connect;
if (IOI2CInterfaceOpen(interface, kNilOptions, &connect) != KERN_SUCCESS)
{
IOObjectRelease(interface);
continue;
}
uint8_t i2cIn[] = { 0x51, 0x82, 0x01, 0x10 /* luminance */, 0 };
i2cIn[4] = 0x6E ^ i2cIn[0] ^ i2cIn[1] ^ i2cIn[2] ^ i2cIn[3];
IOI2CRequest request = {
.commFlags = kNilOptions,
.sendAddress = 0x6e,
.sendTransactionType = kIOI2CSimpleTransactionType,
.sendBuffer = (vm_address_t) i2cIn,
.sendBytes = sizeof(i2cIn) / sizeof(i2cIn[0]),
.minReplyDelay = options->ddcciSleep,
.replyAddress = 0x6F,
.replySubAddress = 0x51,
.replyTransactionType = kIOI2CDDCciReplyTransactionType,
.replyBytes = sizeof(i2cOut) / sizeof(i2cOut[0]),
.replyBuffer = (vm_address_t) i2cOut,
};
IOReturn ret = IOI2CSendRequest(connect, kNilOptions, &request);
IOI2CInterfaceClose(connect, kNilOptions);
IOObjectRelease(interface);
if (ret != KERN_SUCCESS || request.result != kIOReturnSuccess) continue;
if (i2cOut[2] != 0x02 || i2cOut[3] != 0x00) continue;
uint32_t current = ((uint32_t) i2cOut[8] << 8u) + (uint32_t) i2cOut[9];
uint32_t max = ((uint32_t) i2cOut[6] << 8u) + (uint32_t) i2cOut[7];
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitCopy(&brightness->name, &display->name);
}
}
return NULL;
}
#endif
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result)
{
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
detectWithDisplayServices(displayServer, result);
if (instance.config.allowSlowOperations && displayServer->displays.length > result->length)
detectWithDdcci(result);
if (displayServer->displays.length > result->length)
detectWithDdcci(displayServer, options, result);
return NULL;
}
+10 -7
View File
@@ -9,7 +9,7 @@
#include <sys/fcntl.h>
#include <unistd.h>
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
// https://man.freebsd.org/cgi/man.cgi?query=backlight&sektion=9
char path[] = "/dev/backlight/backlight0";
@@ -26,22 +26,25 @@ const char* ffDetectBrightness(FFlist* result)
if(ioctl(blfd, BACKLIGHTGETSTATUS, &status) < 0)
continue;
FFBrightnessResult* display = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInit(&display->name);
display->value = (float) status.brightness / BACKLIGHTMAXLEVELS;
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInit(&brightness->name);
brightness->max = BACKLIGHTMAXLEVELS;
brightness->min = 0;
brightness->current = status.brightness;
struct backlight_info info;
if(ioctl(blfd, BACKLIGHTGETINFO, &info) < 0)
ffStrbufAppendS(&display->name, info.name);
ffStrbufAppendS(&brightness->name, info.name);
}
return NULL;
}
#else
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FF_MAYBE_UNUSED FFlist* result)
{
return "Backlight is supported only on FreeBSD 13 and newer";
}
#endif
#endif
+15 -12
View File
@@ -72,8 +72,9 @@ static const char* detectWithBacklight(FFlist* result)
}
else
ffStrbufInitS(&brightness->name, entry->d_name);
double maxBrightness = ffStrbufToDouble(&buffer);
brightness->value = (float) (actualBrightness * 100 / maxBrightness);
brightness->max = ffStrbufToDouble(&buffer);
brightness->min = 0;
brightness->current = actualBrightness;
}
}
ffStrbufSubstrBefore(&backlightDir, backlightDirLength);
@@ -91,16 +92,19 @@ static const char* detectWithBacklight(FFlist* result)
#include <ddcutil_c_api.h>
static const char* detectWithDdcci(FFlist* result)
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_set_default_sleep_multiplier)
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
ffddca_set_default_sleep_multiplier(options->ddcciSleep / 40.0);
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
if (__builtin_expect(ffddca_get_display_info_list2(false, &infoList) < 0, 0))
return "ddca_get_display_info_list2(false, &infoList) failed";
@@ -123,7 +127,9 @@ static const char* detectWithDdcci(FFlist* result)
ffddca_free_any_vcp_value(vcpValue);
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->value = (float) current * 100.f / (float) max;
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitS(&brightness->name, display->model_name);
}
ffddca_close_display(handle);
@@ -134,17 +140,14 @@ static const char* detectWithDdcci(FFlist* result)
}
#endif
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
detectWithBacklight(result);
#ifdef FF_HAVE_DDCUTIL
if (instance.config.allowSlowOperations)
{
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
if (result->length < displayServer->displays.length)
detectWithDdcci(result);
}
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
if (result->length < displayServer->displays.length)
detectWithDdcci(options, result);
#endif
return NULL;
@@ -1,6 +1,6 @@
#include "brightness.h"
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FF_MAYBE_UNUSED FFlist* result)
{
return "Not supported on this platform";
}
@@ -20,7 +20,9 @@ static const char* detectWithWmi(FFlist* result)
if(FFWmiVariant vtValue = record.get(L"CurrentBrightness"))
{
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->value = vtValue.get<uint8_t>();
brightness->max = 100;
brightness->min = 0;
brightness->current = vtValue.get<uint8_t>();
ffStrbufInit(&brightness->name);
if (FFWmiVariant vtName = record.get(L"InstanceName"))
@@ -51,7 +53,9 @@ static char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist*
else
ffStrbufInitWS(&brightness->name, physicalMonitor.szPhysicalMonitorDescription);
brightness->value = (float) (curr - min) * 100.f / (float) (max - min);
brightness->max = max;
brightness->min = min;
brightness->current = curr;
}
}
}
@@ -69,14 +73,14 @@ static bool hasBuiltinDisplay(const FFDisplayServerResult* displayServer)
}
extern "C"
const char* ffDetectBrightness(FFlist* result)
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
if (hasBuiltinDisplay(displayServer))
detectWithWmi(result);
if (instance.config.allowSlowOperations && result->length < displayServer->displays.length)
if (result->length < displayServer->displays.length)
detectWithDdcci(displayServer, result);
return NULL;
}
+1 -1
View File
@@ -25,7 +25,7 @@ const char* ffDetectChassis(FFChassisResult* result)
if(result->type.length)
{
const char* typeStr = ffChassisTypeToString(ffStrbufToUInt16(&result->type, 9999));
const char* typeStr = ffChassisTypeToString((uint32_t) ffStrbufToUInt(&result->type, 9999));
if(typeStr)
ffStrbufSetS(&result->type, typeStr);
}
+71 -15
View File
@@ -2,17 +2,6 @@
#include "common/sysctl.h"
#include "detection/temps/temps_apple.h"
static double getFrequency(const char* propName)
{
double herz = (double) ffSysctlGetInt64(propName, 0);
if(herz <= 0.0)
return herz;
herz /= 1000.0; //to KHz
herz /= 1000.0; //to MHz
return herz / 1000.0; //to GHz
}
static double detectCpuTemp(const FFstrbuf* cpuName)
{
double result = 0;
@@ -31,11 +20,81 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
return result;
}
#ifdef __aarch64__
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
static const char* detectFrequency(FFCPUResult* cpu)
{
// https://github.com/giampaolo/psutil/pull/2222/files
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching("AppleARMIODevice"), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
CFMutableDictionaryRef properties;
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
{
IOObjectRelease(registryEntry);
continue;
}
io_name_t name;
if (IORegistryEntryGetName(registryEntry, name) != KERN_SUCCESS)
continue;
if (strcmp(name, "pmgr") != 0)
continue;
uint32_t pMin, eMin, aMax, pCoreLength;
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), 0, 4, (uint8_t*) &pMin, &pCoreLength); // pCore
ffCfDictGetData(properties, CFSTR("voltage-states1-sram"), 0, 4, (uint8_t*) &eMin, NULL); // eCore
cpu->frequencyMin = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000);
if (pCoreLength >= 8)
{
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL);
cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000);
}
else
cpu->frequencyMax = 0.0;
CFRelease(properties);
IOObjectRelease(registryEntry);
}
IOObjectRelease(iterator);
return NULL;
}
#else
static const char* detectFrequency(FFCPUResult* cpu)
{
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
{
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;
}
return NULL;
}
#endif
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("machdep.cpu.brand_string", &cpu->name) != NULL)
return "sysctlbyname(machdep.cpu.brand_string) failed";
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
if (cpu->vendor.length == 0 && ffStrbufStartsWithS(&cpu->name, "Apple "))
ffStrbufAppendS(&cpu->vendor, "Apple");
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
if(cpu->coresPhysical == 1)
@@ -49,10 +108,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if(cpu->coresOnline == 1)
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1);
cpu->frequencyMin = getFrequency("hw.cpufrequency_min");
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
if(cpu->frequencyMax == 0.0)
cpu->frequencyMax = getFrequency("hw.cpufrequency");
detectFrequency(cpu);
cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET;
+4 -1
View File
@@ -16,7 +16,10 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
ffDetectThermalTemp(&cpu->temperature);
{
if (!ffDetectCpuTemp(&cpu->temperature))
ffDetectThermalTemp(&cpu->temperature);
}
return NULL;
}
+14 -1
View File
@@ -1,5 +1,6 @@
#include "cpu.h"
#include "common/io/io.h"
#include "common/processing.h"
#include "common/properties.h"
#include "detection/temps/temps_linux.h"
#include "util/mallocHelper.h"
@@ -128,7 +129,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch);
if (error) return error;
cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1);
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 1);
cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresOnline = (uint16_t) get_nprocs();
@@ -163,5 +164,17 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectAndroid(cpu);
#endif
#ifdef __linux__
if (cpu->name.length == 0)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (!ffProcessAppendStdOut(&buffer, (char *const[]) { "lscpu", NULL }))
{
ffParsePropLines(buffer.chars, "Model name:", &cpu->name);
if (ffStrbufEqualS(&cpu->name, "-")) ffStrbufClear(&cpu->name);
}
}
#endif
return NULL;
}
+1 -1
View File
@@ -35,7 +35,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed";
}
FF_HKEY_AUTO_DESTROY hKey;
FF_HKEY_AUTO_DESTROY hKey = NULL;
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";
+35 -21
View File
@@ -4,40 +4,54 @@
#include <stdint.h>
// We need to use uint64_t because sizeof(long) == 4 on Windows
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll);
static uint64_t inUseAll1, totalAll1;
static FFlist cpuTimes1;
void ffPrepareCPUUsage(void)
{
ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
assert(cpuTimes1.elementSize == 0);
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
ffGetCpuUsageInfo(&cpuTimes1);
}
const char* ffGetCpuUsageResult(double* result)
const char* ffGetCpuUsageResult(FFlist* result)
{
const char* error = NULL;
if(inUseAll1 == 0 && totalAll1 == 0)
if(cpuTimes1.elementSize == 0)
{
error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
if(error)
return error;
ffListInit(&cpuTimes1, sizeof(FFCpuUsageInfo));
error = ffGetCpuUsageInfo(&cpuTimes1);
if(error) return error;
ffTimeSleep(200);
}
while(true)
{
uint64_t inUseAll2, totalAll2;
error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2);
if(error)
return error;
if(cpuTimes1.length == 0) return "No CPU cores found";
if(inUseAll2 != inUseAll1)
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
retry:
error = ffGetCpuUsageInfo(&cpuTimes2);
if(error) return error;
if(cpuTimes1.length != cpuTimes2.length) return "Unexpected CPU usage result";
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
if (cpuTime2->totalAll <= cpuTime1->totalAll)
{
*result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
return NULL;
}
else
ffListClear(&cpuTimes2);
ffTimeSleep(200);
goto retry;
}
}
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
*(double*) ffListAdd(result) = (double)(cpuTime2->inUseAll - cpuTime1->inUseAll) / (double)(cpuTime2->totalAll - cpuTime1->totalAll) * 100;
cpuTime1->inUseAll = cpuTime2->inUseAll;
cpuTime1->totalAll = cpuTime2->totalAll;
}
return NULL;
}
+9 -1
View File
@@ -3,6 +3,14 @@
#ifndef FF_INCLUDED_detection_cpuusage_cpuusage
#define FF_INCLUDED_detection_cpuusage_cpuusage
const char* ffGetCpuUsageResult(double* result);
#include "fastfetch.h"
typedef struct FFCpuUsageInfo {
uint64_t inUseAll;
uint64_t totalAll;
} FFCpuUsageInfo;
const char* ffGetCpuUsageInfo(FFlist* cpuTimes);
const char* ffGetCpuUsageResult(FFlist* result); // list of double
#endif
+20 -11
View File
@@ -4,20 +4,29 @@
#include <mach/processor_info.h>
#include <mach/mach_host.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
host_cpu_load_info_data_t cpustats;
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
natural_t numCPUs = 0U;
processor_info_array_t cpuInfo;
mach_msg_type_number_t numCpuInfo;
*inUseAll = *totalAll = 0;
if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUs, &cpuInfo, &numCpuInfo) != KERN_SUCCESS)
return "host_processor_info() failed";
if (numCPUs * CPU_STATE_MAX != numCpuInfo)
return "Unexpected host_processor_info() result";
if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)(&cpustats), &count) != KERN_SUCCESS)
return "host_statistics() failed";
*inUseAll = cpustats.cpu_ticks[CPU_STATE_USER]
+ cpustats.cpu_ticks[CPU_STATE_SYSTEM]
+ cpustats.cpu_ticks[CPU_STATE_NICE];
*totalAll = *inUseAll + cpustats.cpu_ticks[CPU_STATE_IDLE];
for (natural_t i = 0U; i < numCPUs; ++i)
{
integer_t inUse = cpuInfo[CPU_STATE_MAX * i + CPU_STATE_USER]
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM]
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE];
integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE];
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+26 -9
View File
@@ -1,19 +1,36 @@
#include "detection/cpuusage/cpuusage.h"
#include "util/mallocHelper.h"
#include <sys/types.h>
#include <sys/user.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
#include <stdlib.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
// interrupt processing, user processes, system processing, lock spinning, and idling
uint64_t cpTime[5];
size_t neededLength = sizeof(cpTime);
if(sysctlbyname("kern.cp_time", cpTime, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_time) failed";
size_t neededLength = 0;
if(sysctlbyname("kern.cp_times", NULL, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, NULL) failed";
*inUseAll = cpTime[0] + cpTime[1] + cpTime[2] + cpTime[3];
*totalAll = *inUseAll + cpTime[4];
uint32_t coreCount = neededLength / (CPUSTATES * (uint32_t) sizeof(uint64_t));
assert(coreCount > 0);
FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);
if(sysctlbyname("kern.cp_times", cpTimes, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, cpTime) failed";
for (uint32_t i = 0; i < coreCount; ++i)
{
uint64_t* cpTime = cpTimes[i];
uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS];
uint64_t total = cpTime[CP_INTR] + cpTime[CP_IDLE];
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+16 -11
View File
@@ -1,14 +1,13 @@
#include "fastfetch.h"
#include "detection/cpuusage/cpuusage.h"
#include "common/io/io.h"
#include <stdio.h>
#include <inttypes.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
FILE* procStat = fopen("/proc/stat", "r");
FF_AUTO_CLOSE_FILE FILE* procStat = fopen("/proc/stat", "r");
if(procStat == NULL)
{
#ifdef __ANDROID__
@@ -17,16 +16,22 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
return "fopen(\"""/proc/stat\", \"r\") == NULL";
#endif
}
// Skip first line
if (fscanf(procStat, "cpu%*[^\n]\n") < 0)
return "fscanf() first line failed";
if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0)
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
while (fscanf(procStat, "cpu%*d%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%*[^\n]\n", &user, &nice, &system, &idle, &iowait, &irq, &softirq) == 7)
{
fclose(procStat);
return "fscanf() failed";
}
*inUseAll = user + nice + system;
*totalAll = *inUseAll + idle + iowait + irq + softirq;
uint64_t inUse = user + nice + system;
uint64_t total = inUse + idle + iowait + irq + softirq;
fclose(procStat);
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
}
+9 -6
View File
@@ -6,7 +6,7 @@
#include <ntstatus.h>
#include <winternl.h>
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
ULONG size = 0;
if(NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
@@ -16,8 +16,6 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessorPerformanceInformation, pinfo, size, &size)))
return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, size) failed";
*inUseAll = *totalAll = 0;
for (uint32_t i = 0; i < size / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); ++i)
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* coreInfo = pinfo + i;
@@ -28,9 +26,14 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
coreInfo->KernelTime.QuadPart -= coreInfo->IdleTime.QuadPart;
coreInfo->KernelTime.QuadPart += dpcTime + interruptTime;
LONGLONG inUse = coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart;
*inUseAll += (uint64_t)inUse;
*totalAll += (uint64_t)(inUse + coreInfo->IdleTime.QuadPart);
uint64_t inUse = (uint64_t) (coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart);
uint64_t total = inUse + (uint64_t)coreInfo->IdleTime.QuadPart;
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
*info = (FFCpuUsageInfo) {
.inUseAll = (uint64_t)inUse,
.totalAll = (uint64_t)total,
};
}
return NULL;
-71
View File
@@ -1,71 +0,0 @@
#include "fastfetch.h"
#include "detection/datetime/datetime.h"
#include "common/thread.h"
#include <time.h>
const FFDateTimeResult* ffDetectDateTime(void)
{
static FFDateTimeResult result;
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
static bool init = false;
ffThreadMutexLock(&mutex);
if (init)
{
ffThreadMutexUnlock(&mutex);
return &result;
}
init = true;
const time_t t = time(NULL);
struct tm* tm = localtime(&t);
result.year = (uint16_t) (tm->tm_year + 1900);
result.yearShort = (uint8_t) (result.year % 100);
result.month = (uint8_t) (tm->tm_mon + 1);
ffStrbufInitA(&result.monthPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.monthPretty.length = (uint32_t) strftime(result.monthPretty.chars, ffStrbufGetFree(&result.monthPretty), "%m", tm);
ffStrbufInitA(&result.monthName, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.monthName.length = (uint32_t) strftime(result.monthName.chars, ffStrbufGetFree(&result.monthName), "%B", tm);
ffStrbufInitA(&result.monthNameShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.monthNameShort.length = (uint32_t) strftime(result.monthNameShort.chars, ffStrbufGetFree(&result.monthNameShort), "%b", tm);
result.week = (uint8_t) (tm->tm_yday / 7 + 1);
ffStrbufInitA(&result.weekday, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.weekday.length = (uint32_t) strftime(result.weekday.chars, ffStrbufGetFree(&result.weekday), "%A", tm);
ffStrbufInitA(&result.weekdayShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.weekdayShort.length = (uint32_t) strftime(result.weekdayShort.chars, ffStrbufGetFree(&result.weekdayShort), "%a", tm);
result.dayInYear = (uint8_t) (tm->tm_yday + 1);
result.dayInMonth = (uint8_t) tm->tm_mday;
result.dayInWeek = tm->tm_wday == 0 ? 7 : (uint8_t) tm->tm_wday;
result.hour = (uint8_t) tm->tm_hour;
ffStrbufInitA(&result.hourPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.hourPretty.length = (uint32_t) strftime(result.hourPretty.chars, ffStrbufGetFree(&result.hourPretty), "%H", tm);
result.hour12 = (uint8_t) (result.hour % 12);
ffStrbufInitA(&result.hour12Pretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.hour12Pretty.length = (uint32_t) strftime(result.hour12Pretty.chars, ffStrbufGetFree(&result.hour12Pretty), "%I", tm);
result.minute = (uint8_t) tm->tm_min;
ffStrbufInitA(&result.minutePretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.minutePretty.length = (uint32_t) strftime(result.minutePretty.chars, ffStrbufGetFree(&result.minutePretty), "%M", tm);
result.second = (uint8_t) tm->tm_sec;
ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm);
ffThreadMutexUnlock(&mutex);
return &result;
}
-35
View File
@@ -1,35 +0,0 @@
#pragma once
#ifndef FF_INCLUDED_detection_datetime_datetime
#define FF_INCLUDED_detection_datetime_datetime
#include "fastfetch.h"
typedef struct FFDateTimeResult
{
//Examples for 21.02.2022 - 15:18:37
uint16_t year; //2022
uint8_t yearShort; //22
uint8_t month; //2
FFstrbuf monthPretty; //02
FFstrbuf monthName; //February
FFstrbuf monthNameShort; //Feb
uint8_t week; //8
FFstrbuf weekday; //Monday
FFstrbuf weekdayShort; //Mon
uint16_t dayInYear; //52
uint8_t dayInMonth; //21
uint8_t dayInWeek; //1
uint8_t hour; //15
FFstrbuf hourPretty; //15
uint8_t hour12; //3
FFstrbuf hour12Pretty; //03
uint8_t minute; //18
FFstrbuf minutePretty; //18
uint8_t second; //37
FFstrbuf secondPretty; //37
} FFDateTimeResult;
const FFDateTimeResult* ffDetectDateTime();
#endif
+8 -2
View File
@@ -7,7 +7,7 @@ static int compareDisks(const void* disk1, const void* disk2)
return ffStrbufCompAlphabetically(&((const FFDisk*) disk1)->mountpoint, &((const FFDisk*) disk2)->mountpoint);
}
const char* ffDetectDisks(FFlist* disks)
const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks)
{
const char* error = ffDetectDisksImpl(disks);
@@ -22,7 +22,13 @@ const char* ffDetectDisks(FFlist* disks)
FF_LIST_FOR_EACH(FFDisk, disk, *disks)
{
if(disk->bytesTotal == 0)
disk->type |= FF_DISK_TYPE_UNKNOWN_BIT;
disk->type |= FF_DISK_VOLUME_TYPE_UNKNOWN_BIT;
else
{
disk->bytesUsed = disk->bytesTotal - (
options->calcType == FF_DISK_CALC_TYPE_FREE ? disk->bytesFree : disk->bytesAvailable
);
}
}
return NULL;
+5 -2
View File
@@ -7,12 +7,15 @@
typedef struct FFDisk
{
FFstrbuf mountFrom;
FFstrbuf mountpoint;
FFstrbuf filesystem;
FFstrbuf name;
FFDiskType type;
FFDiskVolumeType type;
uint64_t bytesUsed;
uint64_t bytesFree;
uint64_t bytesAvailable;
uint64_t bytesTotal;
uint32_t filesUsed;
@@ -23,6 +26,6 @@ typedef struct FFDisk
* Returns a List of FFDisk, sorted alphabetically by mountpoint.
* If error is not set, disks contains at least one disk.
*/
const char* ffDetectDisks(FFlist* result /* list of FFDisk */);
const char* ffDetectDisks(FFDiskOptions* options, FFlist* result /* list of FFDisk */);
#endif
-17
View File
@@ -1,17 +0,0 @@
#include "disk.h"
#include <sys/mount.h>
#import <Foundation/Foundation.h>
void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
// FreeBSD doesn't support these flags
if(fs->f_flags & MNT_DONTBROWSE)
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
else if(fs->f_flags & MNT_REMOVABLE)
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_TYPE_REGULAR_BIT;
ffStrbufInitS(&disk->name, [NSFileManager.defaultManager displayNameAtPath:@(fs->f_mntonname)].UTF8String);
}
+60 -22
View File
@@ -1,42 +1,70 @@
#include "disk.h"
#include "util/mallocHelper.h"
#include "util/stringUtils.h"
#include <sys/mount.h>
#ifdef __FreeBSD__
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
if(
ffStrbufStartsWithS(&disk->mountpoint, "/boot") ||
ffStrbufStartsWithS(&disk->mountpoint, "/dev") ||
ffStrbufStartsWithS(&disk->mountpoint, "/var") ||
ffStrbufStartsWithS(&disk->mountpoint, "/tmp") ||
ffStrbufStartsWithS(&disk->mountpoint, "/proc") ||
ffStrbufStartsWithS(&disk->mountpoint, "/zroot") ||
ffStrbufStartsWithS(&disk->mountpoint, "/compat/linux/")
)
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
if(ffStrbufEqualS(&disk->filesystem, "zfs"))
{
disk->type = !ffStrbufStartsWithS(&disk->mountFrom, "zroot/") || ffStrbufStartsWithS(&disk->mountFrom, "zroot/ROOT/")
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
: FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
}
else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi"))
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(!(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_TYPE_REGULAR_BIT;
ffStrbufInit(&disk->name);
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
#elif __APPLE__
#include "util/apple/cf_helpers.h"
#include <sys/attr.h>
#include <unistd.h>
struct VolAttrBuf {
uint32_t length;
attrreference_t volNameRef;
char volNameSpace[MAXPATHLEN];
} __attribute__((aligned(4), packed));
void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
if(fs->f_flags & MNT_DONTBROWSE)
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(fs->f_flags & MNT_REMOVABLE || !(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
struct VolAttrBuf attrBuf;
if (getattrlist(disk->mountpoint.chars, &(struct attrlist) {
.bitmapcount = ATTR_BIT_MAP_COUNT,
.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME,
}, &attrBuf, sizeof(attrBuf), 0) == 0)
ffStrbufInitNS(&disk->name, attrBuf.volNameRef.attr_length - 1 /* excluding '\0' */, attrBuf.volNameSpace);
}
#else
void detectFsInfo(struct statfs* fs, FFDisk* disk);
#endif
const char* ffDetectDisksImpl(FFlist* disks)
{
struct statfs* buf;
int size = getfsstat(NULL, 0, MNT_WAIT);
int size = getmntinfo(&buf, MNT_WAIT);
if(size <= 0)
return "getmntinfo(&buf, MNT_WAIT) failed";
return "getfsstat(NULL, 0, MNT_WAIT) failed";
FF_AUTO_FREE struct statfs* buf = malloc(sizeof(*buf) * (unsigned) size);
if(getfsstat(buf, (int) (sizeof(*buf) * (unsigned) size), MNT_NOWAIT) <= 0)
return "getfsstat(buf, size, MNT_NOWAIT) failed";
for(struct statfs* fs = buf; fs < buf + size; ++fs)
{
FFDisk* disk = ffListAdd(disks);
if(!ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs"))
continue;
#ifdef __FreeBSD__
// f_bavail and f_ffree are signed on FreeBSD...
@@ -44,15 +72,25 @@ const char* ffDetectDisksImpl(FFlist* disks)
if(fs->f_ffree < 0) fs->f_ffree = 0;
#endif
FFDisk* disk = ffListAdd(disks);
disk->bytesTotal = fs->f_blocks * fs->f_bsize;
disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bfree * fs->f_bsize);
disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize;
disk->bytesAvailable = (uint64_t)fs->f_bavail * fs->f_bsize;
disk->bytesUsed = 0; // To be filled in ./disk.c
disk->filesTotal = (uint32_t) fs->f_files;
disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree);
ffStrbufInitS(&disk->mountFrom, fs->f_mntfromname);
ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
ffStrbufInitS(&disk->filesystem, fs->f_fstypename);
ffStrbufInit(&disk->name);
disk->type = 0;
detectFsInfo(fs, disk);
if(fs->f_flags & MNT_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
return NULL;
+151 -111
View File
@@ -1,5 +1,6 @@
#include "disk.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <limits.h>
@@ -7,6 +8,8 @@
#include <dirent.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <mntent.h>
#include <sys/mount.h>
#ifdef __USE_LARGEFILE64
#define stat stat64
@@ -15,77 +18,60 @@
#define readdir readdir64
#endif
static bool isPhysicalDevice(FFstrbuf* device)
static bool isPhysicalDevice(const struct mntent* device)
{
#ifndef __ANDROID__ //On Android, `/dev` is not accessable, so that the following checks always fail
//https://askubuntu.com/a/1289123
if(ffStrbufEqualS(device, "/cow"))
//Always show the root path
if(ffStrEquals(device->mnt_dir, "/"))
return true;
//DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem.
if(ffStrbufEqualS(device, "drvfs"))
if(ffStrEquals(device->mnt_fsname, "drvfs"))
return true;
//ZFS root pool. The format is rpool/<POOL_NAME>/<VOLUME_NAME>/<SUBVOLUME_NAME>
if(ffStrbufStartsWithS(device, "rpool/"))
//ZFS pool
if(ffStrEquals(device->mnt_type, "zfs"))
return true;
//Pseudo filesystems don't have a device in /dev
if(!ffStrStartsWith(device->mnt_fsname, "/dev/"))
return false;
if(
ffStrStartsWith(device->mnt_fsname + 5, "loop") || //Ignore loop devices
ffStrStartsWith(device->mnt_fsname + 5, "ram") || //Ignore ram devices
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
) return false;
struct stat deviceStat;
if(stat(device->chars, &deviceStat) != 0)
if(stat(device->mnt_fsname, &deviceStat) != 0)
return false;
//Ignore all devices that are not block devices
if(!S_ISBLK(deviceStat.st_mode))
return false;
#else
//Pseudo filesystems don't have a device in /dev
if(!ffStrbufStartsWithS(device, "/dev/"))
if(!ffStrStartsWith(device->mnt_fsname, "/dev/"))
return false;
#endif // __ANDROID__
if(
ffStrbufStartsWithS(device, "/dev/loop") || //Ignore loop devices
ffStrbufStartsWithS(device, "/dev/ram") || //Ignore ram devices
ffStrbufStartsWithS(device, "/dev/fd") //Ignore fd devices
ffStrStartsWith(device->mnt_fsname + 5, "loop") || //Ignore loop devices
ffStrStartsWith(device->mnt_fsname + 5, "ram") || //Ignore ram devices
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
) return false;
#endif // __ANDROID__
return true;
}
static void appendNextEntry(FFstrbuf* buffer, char** source)
{
//Read the current entry into the buffer
while(**source != '\0' && !isspace(**source))
{
//After a backslash the next 3 characters are octal ascii codes
if(**source == '\\' && strnlen(*source, 4) == 4)
{
char octal[4] = {0};
strncpy(octal, *source + 1, 3);
long value = strtol(octal, NULL, 8); //Returns 0 on error, so no need to check endptr
if(value > 0 && value < CHAR_MAX)
{
ffStrbufAppendC(buffer, (char) value);
*source += 4;
continue;
}
}
ffStrbufAppendC(buffer, **source);
++*source;
}
//Skip whitespace
while(isspace(**source))
++*source;
}
static void detectNameFromPath(FFDisk* disk, const struct stat* deviceStat, FFstrbuf* basePath)
{
DIR* dir = opendir(basePath->chars);
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath->chars);
if(dir == NULL)
return;
@@ -110,82 +96,150 @@ static void detectNameFromPath(FFDisk* disk, const struct stat* deviceStat, FFst
ffStrbufAppendS(&disk->name, entry->d_name);
break;
}
closedir(dir);
}
static void detectName(FFDisk* disk, const FFstrbuf* device)
static void detectName(FFDisk* disk)
{
struct stat deviceStat;
if(stat(device->chars, &deviceStat) != 0)
if(stat(disk->mountFrom.chars, &deviceStat) != 0)
return;
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
//Try partlabel first
ffStrbufSetS(&basePath, "/dev/disk/by-partlabel/");
//Detect USB devices. Code is put here to reuse deviceStat
//https://stackoverflow.com/a/73302717
ffStrbufAppendS(&basePath, "/dev/disk/by-id/");
detectNameFromPath(disk, &deviceStat, &basePath);
if (ffStrbufStartsWithS(&disk->name, "usb-"))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
ffStrbufClear(&disk->name);
//Try label first
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
detectNameFromPath(disk, &deviceStat, &basePath);
//Try label second
if(disk->name.length == 0)
{
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
//Try partlabel second
ffStrbufSetS(&basePath, "/dev/disk/by-partlabel/");
detectNameFromPath(disk, &deviceStat, &basePath);
}
//Use the mountpoint as a last resort
if(disk->name.length == 0)
ffStrbufAppend(&disk->name, &disk->mountpoint);
if (disk->name.length == 0) return;
// Basic\x20data\x20partition
for (uint32_t i = ffStrbufFirstIndexS(&disk->name, "\\x");
i != disk->name.length;
i = ffStrbufNextIndexS(&disk->name, i + 1, "\\x"))
{
uint32_t len = (uint32_t) strlen("\\x20");
if (disk->name.length >= len)
{
char bak = disk->name.chars[i + len];
disk->name.chars[i + len] = '\0';
disk->name.chars[i] = (char) strtoul(&disk->name.chars[i + 2], NULL, 16);
ffStrbufRemoveSubstr(&disk->name, i + 1, i + len);
disk->name.chars[i + 1] = bak;
}
}
}
#ifdef __ANDROID__
static void detectType(FF_MAYBE_UNUSED const FFlist* devices, FFDisk* currentDisk, FF_MAYBE_UNUSED const char* options)
static void detectType(FF_MAYBE_UNUSED const FFlist* disks, FFDisk* currentDisk)
{
if(ffStrbufEqualS(&currentDisk->mountpoint, "/") || ffStrbufEqualS(&currentDisk->mountpoint, "/storage/emulated"))
currentDisk->type = FF_DISK_TYPE_REGULAR_BIT;
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
else if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/mnt/media_rw/"))
currentDisk->type = FF_DISK_TYPE_EXTERNAL_BIT;
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
currentDisk->type = FF_DISK_TYPE_HIDDEN_BIT;
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
}
#else
static bool isSubvolume(const FFlist* devices)
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
{
const FFstrbuf* current = ffListGet(devices, devices->length - 1);
if(ffStrbufEqualS(current, "drvfs")) // WSL Windows drives
if(ffStrbufEqualS(&currentDisk->mountFrom, "drvfs")) // WSL Windows drives
return false;
//Filter all disks which device was already found. This catches BTRFS subvolumes.
for(uint32_t i = 0; i < devices->length - 1; i++)
if(ffStrbufEqualS(&currentDisk->filesystem, "zfs"))
{
const FFstrbuf* otherDevice = ffListGet(devices, i);
//ZFS subvolumes
uint32_t index = ffStrbufFirstIndexC(&currentDisk->mountFrom, '/');
if (index == currentDisk->mountFrom.length)
return false;
if(ffStrbufEqual(current, otherDevice))
return true;
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
return true;
}
return false;
}
else
{
//Filter all disks which device was already found. This catches BTRFS subvolumes.
for(uint32_t i = 0; i < disks->length - 1; i++)
{
const FFDisk* otherDevice = ffListGet(disks, i);
//ZFS subvolumes: rpool/<POOL_NAME>/<VOLUME_NAME>/<SUBVOLUME_NAME>.
//Test if the third slash is present.
if(ffStrbufStartsWithS(current, "rpool/") && ffStrHasNChars(current->chars, '/', 3))
return true;
if(ffStrbufEqual(&currentDisk->mountFrom, &otherDevice->mountFrom))
return true;
}
}
return false;
}
static void detectType(const FFlist* devices, FFDisk* currentDisk, const char* options)
static bool isRemovable(FFDisk* currentDisk)
{
if(isSubvolume(devices))
currentDisk->type = FF_DISK_TYPE_SUBVOLUME_BIT;
else if(strstr(options, "nosuid") != NULL || strstr(options, "nodev") != NULL)
currentDisk->type = FF_DISK_TYPE_EXTERNAL_BIT;
// https://stackoverflow.com/a/73302025
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
// USB devices should be handled in detectName
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
if(dir == NULL)
return false;
uint32_t index = ffStrbufLastIndexC(&currentDisk->mountFrom, '/');
const char* partitionName = index == currentDisk->mountFrom.length ? NULL : currentDisk->mountFrom.chars + index + 1;
if (!partitionName || !*partitionName) return false;
struct dirent* entry;
while((entry = readdir(dir)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
// /sys/block/sdx/removable
ffStrbufAppendS(&basePath, entry->d_name);
ffStrbufAppendS(&basePath, "/removable");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
}
return false;
}
static void detectType(const FFlist* disks, FFDisk* currentDisk)
{
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
if(isRemovable(currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
else if(ffStrbufStartsWithS(&currentDisk->mountpoint, "/boot") || ffStrbufStartsWithS(&currentDisk->mountpoint, "/efi"))
currentDisk->type = FF_DISK_TYPE_HIDDEN_BIT;
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else
currentDisk->type = FF_DISK_TYPE_REGULAR_BIT;
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
#endif
@@ -197,69 +251,55 @@ static void detectStats(FFDisk* disk)
memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
disk->bytesUsed = disk->bytesTotal - (fs.f_bfree * fs.f_frsize);
disk->bytesFree = fs.f_bfree * fs.f_frsize;
disk->bytesAvailable = fs.f_bavail * fs.f_frsize;
disk->bytesUsed = 0; // To be filled in ./disk.c
disk->filesTotal = (uint32_t) fs.f_files;
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
if(fs.f_flag & ST_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
const char* ffDetectDisksImpl(FFlist* disks)
{
FILE* mountsFile = fopen("/proc/mounts", "r");
FILE* mountsFile = setmntent("/proc/mounts", "r");
if(mountsFile == NULL)
return "fopen(\"/proc/mounts\", \"r\") == NULL";
return "setmntent(\"/proc/mounts\", \"r\") == NULL";
FF_LIST_AUTO_DESTROY devices = ffListCreate(sizeof(FFstrbuf));
struct mntent* device;
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, mountsFile) != EOF)
while((device = getmntent(mountsFile)))
{
//Format of the file: "<device> <mountpoint> <filesystem> <options> ..." (Same as fstab)
char* currentPos = line;
//detect device
FFstrbuf* device = ffListAdd(&devices);
ffStrbufInit(device);
appendNextEntry(device, &currentPos);
if(!isPhysicalDevice(device))
{
ffStrbufDestroy(device);
devices.length--;
continue;
}
//We have a valid device, add it to the list
FFDisk* disk = ffListAdd(disks);
disk->type = FF_DISK_VOLUME_TYPE_NONE;
//detect mountFrom
ffStrbufInitS(&disk->mountFrom, device->mnt_fsname);
//detect mountpoint
ffStrbufInit(&disk->mountpoint);
appendNextEntry(&disk->mountpoint, &currentPos);
ffStrbufInitS(&disk->mountpoint, device->mnt_dir);
//detect filesystem
ffStrbufInit(&disk->filesystem);
appendNextEntry(&disk->filesystem, &currentPos);
ffStrbufInitS(&disk->filesystem, device->mnt_type);
//detect name
ffStrbufInit(&disk->name);
detectName(disk, device);
detectName(disk); // Also detects external devices
//detect type
detectType(&devices, disk, currentPos);
detectType(disks, disk);
//Detects stats
detectStats(disk);
}
if(line != NULL)
free(line);
FF_LIST_FOR_EACH(FFstrbuf, device, devices)
ffStrbufDestroy(device);
fclose(mountsFile);
endmntent(mountsFile);
return NULL;
}
+24 -8
View File
@@ -1,7 +1,9 @@
#include "disk.h"
#include "common/io/io.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <winioctl.h>
#include <assert.h>
const char* ffDetectDisksImpl(FFlist* disks)
@@ -25,20 +27,31 @@ const char* ffDetectDisksImpl(FFlist* disks)
FFDisk* disk = ffListAdd(disks);
ffStrbufInitWS(&disk->mountpoint, mountpoint);
uint64_t bytesFree;
if(!GetDiskFreeSpaceExW(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree))
wchar_t volumeName[64];
if(GetVolumeNameForVolumeMountPointW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
ffStrbufInitWS(&disk->mountFrom, volumeName);
else
ffStrbufInit(&disk->mountFrom);
if(!GetDiskFreeSpaceExW(
mountpoint,
(PULARGE_INTEGER)&disk->bytesAvailable,
(PULARGE_INTEGER)&disk->bytesTotal,
(PULARGE_INTEGER)&disk->bytesFree
))
{
disk->bytesTotal = 0;
bytesFree = 0;
disk->bytesFree = 0;
disk->bytesAvailable = 0;
}
disk->bytesUsed = disk->bytesTotal - bytesFree;
disk->bytesUsed = 0; // To be filled in ./disk.c
if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM)
disk->type = FF_DISK_TYPE_EXTERNAL_BIT;
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(driveType == DRIVE_FIXED)
disk->type = FF_DISK_TYPE_REGULAR_BIT;
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
else
disk->type = FF_DISK_TYPE_HIDDEN_BIT;
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
ffStrbufInit(&disk->filesystem);
ffStrbufInit(&disk->name);
@@ -47,11 +60,12 @@ const char* ffDetectDisksImpl(FFlist* disks)
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks
UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
DWORD diskFlags;
BOOL result = GetVolumeInformationW(mountpoint,
diskName, sizeof(diskName) / sizeof(*diskName), //Volume name
NULL, //Serial number
NULL, //Max component length
NULL, //File system flags
&diskFlags, //File system flags
diskFileSystem, sizeof(diskFileSystem) / sizeof(*diskFileSystem)
);
SetErrorMode(errorMode);
@@ -60,6 +74,8 @@ const char* ffDetectDisksImpl(FFlist* disks)
{
ffStrbufSetWS(&disk->filesystem, diskFileSystem);
ffStrbufSetWS(&disk->name, diskName);
if(diskFlags & FILE_READ_ONLY_VOLUME)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
//Unsupported
+67
View File
@@ -0,0 +1,67 @@
#include "diskio.h"
#include "common/time.h"
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options);
static FFlist ioCounters1;
static uint64_t time1;
void ffPrepareDiskIO(FFDiskIOOptions* options)
{
ffListInit(&ioCounters1, sizeof(FFDiskIOResult));
ffDiskIOGetIoCounters(&ioCounters1, options);
time1 = ffTimeGetNow();
}
const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
{
const char* error = NULL;
if (time1 == 0)
{
ffListInit(&ioCounters1, sizeof(FFDiskIOResult));
error = ffDiskIOGetIoCounters(&ioCounters1, options);
if (error)
return error;
time1 = ffTimeGetNow();
}
if (ioCounters1.length == 0)
return "No physical disk found";
uint64_t time2 = ffTimeGetNow();
while (time2 - time1 < 1000)
{
ffTimeSleep((uint32_t) (1000 - (time2 - time1)));
time2 = ffTimeGetNow();
}
error = ffDiskIOGetIoCounters(result, options);
if (error)
return error;
if (result->length != ioCounters1.length)
return "Different number of physical disks. Hardware change?";
for (uint32_t i = 0; i < result->length; ++i)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
return "Network interface name changed";
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
{
uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off);
uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off);
uint64_t temp = *currValue;
*currValue -= *prevValue;
*currValue /= (time2 - time1) / 1000 /* seconds */;
*prevValue = temp;
}
}
time1 = time2;
return NULL;
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "fastfetch.h"
typedef enum FFDiskIOPhysicalType
{
FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
FF_DISKIO_PHYSICAL_TYPE_HDD,
FF_DISKIO_PHYSICAL_TYPE_SSD,
} FFDiskIOPhysicalType;
typedef struct FFDiskIOResult
{
FFstrbuf name;
FFstrbuf interconnect;
FFDiskIOPhysicalType type;
FFstrbuf devPath;
uint64_t bytesRead;
uint64_t readCount;
uint64_t bytesWritten;
uint64_t writeCount;
} FFDiskIOResult;
const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options);
+89
View File
@@ -0,0 +1,89 @@
#include "diskio.h"
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOBlockStorageDriver.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
static inline void wrapIoObjectRelease(io_service_t* service)
{
assert(service);
if (*service)
IOObjectRelease(*service);
}
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
io_name_t deviceName;
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
continue;
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
continue;
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
continue;
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions);
if (!statistics)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount);
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
if (bsdName)
{
ffCfStrGetString(bsdName, &device->devPath);
ffStrbufPrependS(&device->devPath, "/dev/");
}
ffStrbufInit(&device->interconnect);
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
{
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics)
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (deviceCharacteristics)
{
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
if (mediumType)
{
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
}
}
}
}
return NULL;
}
+51
View File
@@ -0,0 +1,51 @@
#include "diskio.h"
#include <devstat.h>
#include <memory.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
if (devstat_checkversion(NULL) < 0)
return "devstat_checkversion() failed";
struct statinfo stats = {
.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)),
};
if (devstat_getdevs(NULL, &stats) < 0)
return "devstat_getdevs() failed";
for (int i = 0; i < stats.dinfo->numdevs; i++)
{
struct devstat* current = &stats.dinfo->devices[i];
if (current->device_type & DEVSTAT_TYPE_PASS)
continue;
char deviceName[128];
snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number);
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInitF(&device->devPath, "/dev/%s", deviceName);
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
ffStrbufInit(&device->interconnect);
switch (current->device_type & DEVSTAT_TYPE_IF_MASK)
{
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
}
device->bytesRead = current->bytes[DEVSTAT_READ];
device->readCount = current->operations[DEVSTAT_READ];
device->bytesWritten = current->bytes[DEVSTAT_WRITE];
device->writeCount = current->operations[DEVSTAT_WRITE];
}
if (stats.dinfo->mem_ptr)
free(stats.dinfo->mem_ptr);
free(stats.dinfo);
return NULL;
}
+108
View File
@@ -0,0 +1,108 @@
#include "diskio.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return "opendir(batteryDir) == NULL";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_name[0] == '.')
continue;
char* part = strstr(entry->d_name, "-part");
if (part && isdigit(part[strlen("-part")]))
continue;
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive indentifier
continue;
// Other exceptions?
ffStrbufAppendS(&baseDir, entry->d_name);
char pathDev[PATH_MAX];
ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
ffStrbufSubstrBefore(&baseDir, baseDirLength);
if (pathLen < 0) continue;
pathDev[pathLen] = '\0'; // ../../nvme0n1
char pathDev1[PATH_MAX];
const char* devName = basename(pathDev);
snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
// Avoid duplicated disks
bool flag = false;
FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
{
if (ffStrbufEqualS(&disk->devPath, pathDev1))
{
flag = true;
break;
}
}
if (flag) continue;
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
if (!sysBlockStat) continue;
// I/Os merges sectors ticks ...
uint64_t nRead, sectorRead, nWritten, sectorWritten;
if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, &sectorRead, &nWritten, &sectorWritten) == 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
char* slash = strchr(entry->d_name, '-');
if (slash)
{
char* slash2 = strchr(slash + 1, '-');
if (slash2)
ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
else
ffStrbufInitS(&device->name, slash + 1);
ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
}
else
{
ffStrbufInitS(&device->name, entry->d_name);
ffStrbufInit(&device->interconnect);
}
ffStrbufReplaceAllC(&device->name, '_', ' ');
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
ffStrbufInitS(&device->devPath, pathDev1);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffReadFileBuffer(pathSysBlock, &buffer))
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
}
return NULL;
}
+89
View File
@@ -0,0 +1,89 @@
#include "diskio.h"
#include "common/io/io.h"
#include "util/windows/registry.h"
#include "util/windows/unicode.h"
#include <winioctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
uint32_t nDevices;
if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
for (uint32_t idev = 0; idev <= nDevices; ++idev) {
_ultow(idev, pNum, 10);
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
continue;
DISK_PERFORMANCE diskPerformance;
DWORD ioctrlSize = sizeof(diskPerformance);
DWORD dwSize;
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
{
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInit(&device->name);
ffStrbufInit(&device->interconnect);
if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
{
// SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
if (index != device->name.length)
{
ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
ffStrbufSubstrAfter(&device->name, index);
}
ffStrbufSubstrBeforeLastC(&device->name, '\\');
ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
ffStrbufRemoveS(&device->name, "&Prod");
ffStrbufReplaceAllC(&device->name, '_', ' ');
ffStrbufTrim(&device->name, ' ');
}
else
ffStrbufSetWS(&device->name, szDevice);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
ffStrbufInitWS(&device->devPath, szDevice);
device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
device->readCount = (uint64_t) diskPerformance.ReadCount;
device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
device->writeCount = (uint64_t) diskPerformance.WriteCount;
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
DWORD retSize = 0;
if(DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
&retSize,
NULL
) && retSize == sizeof(dspd))
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
}
}
return NULL;
}
@@ -80,9 +80,9 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
ffStrbufContainC(&buffer, ','))
{
// 1440,3200,560 => width,height,ppi
uint32_t width = ffStrbufToUInt16(&buffer, 0);
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t height = ffStrbufToUInt16(&buffer, 0);
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
return ffdsAppendDisplay(ds,
width,
height,
+17
View File
@@ -233,6 +233,23 @@ static void getXFCE4(FFDisplayServerResult* result)
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", &result->deVersion);
#ifdef __FreeBSD__
if(result->deVersion.length == 0)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
if (dirp)
{
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
continue;
ffStrbufAppendS(&result->deVersion, &entry->d_name[5]);
}
}
}
#endif
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
{
//This is somewhat slow
+11 -4
View File
@@ -116,6 +116,7 @@ typedef struct XrandrData
{
FF_LIBRARY_SYMBOL(XInternAtom)
FF_LIBRARY_SYMBOL(XGetAtomName);
FF_LIBRARY_SYMBOL(XFree);
FF_LIBRARY_SYMBOL(XRRGetScreenInfo)
FF_LIBRARY_SYMBOL(XRRConfigCurrentConfiguration)
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
@@ -207,9 +208,11 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true);
if (atomEdid != None)
{
unsigned long nitems = 0;
int actual_format = 0;
unsigned long nitems = 0, bytes_after = 0;
Atom actual_type = None;
uint8_t* edidData = NULL;
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, 0, 0, AnyPropertyType, NULL, NULL, &nitems, NULL, &edidData) == Success)
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &edidData) == Success)
{
if (nitems >= 128)
{
@@ -217,6 +220,8 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
ffEdidGetName(edidData, name);
}
}
if (edidData)
data->ffXFree(edidData);
}
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary);
@@ -228,8 +233,9 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
{
bool foundOutput = false;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(data->ffXGetAtomName(data->display, monitorInfo->name));
char* xname = data->ffXGetAtomName(data->display, monitorInfo->name);
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(xname);
data->ffXFree(xname);
for(int i = 0; i < monitorInfo->noutput; i++)
{
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary))
@@ -341,6 +347,7 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenInfo,)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentConfiguration,);
+1 -1
View File
@@ -130,7 +130,7 @@ const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */)
if (hHidFile && HidD_GetProductString(hHidFile, displayName, sizeof(wchar_t) * 126))
ffStrbufSetWS(&device->name, displayName);
else
ffStrbufSetF(&device->name, "Unknown gamepad %4X-%4X", rdi.hid.dwVendorId, rdi.hid.dwProductId);
ffStrbufSetF(&device->name, "Unknown gamepad %4X-%4X", (unsigned) rdi.hid.dwVendorId, (unsigned) rdi.hid.dwProductId);
}
}
+1 -2
View File
@@ -30,9 +30,8 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAcceleratorClassName);
io_iterator_t iterator;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOAcceleratorClassName), &iterator) != kIOReturnSuccess)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
+6
View File
@@ -311,6 +311,12 @@ 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))
return NULL;
#endif
#ifdef FF_HAVE_LIBPCI
return pciDetectGPUs(options, gpus);
#else
+102
View File
@@ -0,0 +1,102 @@
#ifdef FF_HAVE_DIRECTX_HEADERS
#define INITGUID
extern "C" {
#include "common/library.h"
#include "detection/gpu/gpu.h"
}
#include <wsl/winadapter.h>
#include <directx/dxcore.h>
#include <directx/d3d12.h>
#include <dxguids/dxguids.h>
#include <utility>
#include <cinttypes>
template <typename Fn>
struct on_scope_exit {
on_scope_exit(Fn &&fn): _fn(std::move(fn)) {}
~on_scope_exit() { this->_fn(); }
private:
Fn _fn;
};
extern "C"
const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
{
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);
auto ffDXCoreCreateAdapterFactory = (DXCoreCreateAdapterFactory_t) dlsym(libdxcore, "DXCoreCreateAdapterFactory");
if(ffDXCoreCreateAdapterFactory == nullptr) return "dlsym DXCoreCreateAdapterFactory failed";
IDXCoreAdapterFactory *factory = nullptr;
if (FAILED(ffDXCoreCreateAdapterFactory(IID_PPV_ARGS(&factory))))
return "DXCoreCreateAdapterFactory(IID_PPV_ARGS(&factory)) failed";
on_scope_exit destroyFactory([&] { factory->Release(); });
IDXCoreAdapterList *list = NULL;
if (FAILED(factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D11_GRAPHICS, &list)))
return "factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D11_GRAPHICS, &list) failed";
on_scope_exit destroyList([&] { list->Release(); });
for (uint32_t i = 0, count = list->GetAdapterCount(); i < count; i++)
{
IDXCoreAdapter *adapter = nullptr;
if (FAILED(list->GetAdapter(i, &adapter)))
continue;
on_scope_exit destroyAdapter([&] { adapter->Release(); });
// https://learn.microsoft.com/en-us/windows/win32/api/dxcore_interface/ne-dxcore_interface-dxcoreadapterproperty
{
bool value = 0;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::IsHardware, sizeof(value), &value)) && !value)
continue;
}
char desc[256];
if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::DriverDescription, sizeof(desc), desc)))
continue;
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
ffStrbufInitS(&gpu->name, desc);
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
ffStrbufInit(&gpu->driver);
uint64_t value = 0;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::DriverVersion, sizeof(value), &value)))
{
ffStrbufSetF(&gpu->driver, "%" PRIu64 ".%" PRIu64 ".%" PRIu64 ".%" PRIu64,
(value >> 48) & 0xFFFF,
(value >> 32) & 0xFFFF,
(value >> 16) & 0xFFFF,
(value >> 0) & 0xFFFF);
}
gpu->dedicated.used = gpu->shared.used = gpu->dedicated.total = gpu->shared.total = FF_GPU_VMEM_SIZE_UNSET;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::DedicatedAdapterMemory, sizeof(value), &value)))
gpu->dedicated.total = value;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::SharedSystemMemory, sizeof(value), &value)))
gpu->shared.total = value;
gpu->type = FF_GPU_TYPE_UNKNOWN;
bool integrated;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::IsIntegrated, sizeof(integrated), &integrated)))
gpu->type = integrated ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
ffStrbufInit(&gpu->vendor);
DXCoreHardwareID hardwareId;
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, sizeof(hardwareId), &hardwareId)))
{
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
ffStrbufAppendS(&gpu->vendor, vendorStr);
}
}
return NULL;
}
#endif

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