Compare commits

...

349 Commits

Author SHA1 Message Date
Carter Li 4a1037d2b6 Merge pull request #1509 from fastfetch-cli/dev
Release: v2.34.1
2025-01-13 15:57:52 +08:00
Carter Li dbcd5b922a Sound: fix a memleak 2025-01-13 15:39:16 +08:00
Carter Li 8982b860f9 Chore: fix spelling 2025-01-13 15:15:28 +08:00
Carter Li 373b4353bb CPU (BSD): improve base freq detection 2025-01-13 15:06:18 +08:00
Carter Li ace336dfa9 Release: v2.34.1 2025-01-13 14:55:53 +08:00
CELESTIFYX Team 4060626382 fix(logo): Rename *_LOGO_SMARTOS to *_LOGO_SNIGDHAOS (#1502) 2025-01-13 13:48:02 +08:00
李通洲 9f9e3dd931 Logo (Builtin): add Oreon 2025-01-13 13:42:20 +08:00
李通洲 3ed5a250a4 Logo (Builtin): add HeliumOS 2025-01-13 13:39:07 +08:00
carterli fc969b01c7 Memory (NetBSD): change formula to be consistant with other systems 2025-01-13 10:47:25 +08:00
carterli 41e22ea866 Memory (OpenBSD): update formula to be consistant with other systems 2025-01-13 10:47:25 +08:00
李通洲 0b4a6055c6 Logo (Builtin): add netbsd_small 2025-01-13 10:41:11 +08:00
Carter Li b340d4e149 CI: fix build 2025-01-12 12:10:10 +08:00
Carter Li 878e516880 DisplayServer (Linux): upgrade wayland protocol kde-output-device-v2
Ref: #1504
2025-01-12 11:23:42 +08:00
Carter Li 4e3673a2bb DisplayServer (Linux): check HDR support with xx_color_manager_v4_interface (WIP) 2025-01-11 13:10:07 +08:00
李通洲 10c8c1b4bf Media (Linux): use file name as media name if song title is not available 2025-01-10 22:17:36 +08:00
李通洲 17e3853f38 CPU (FreeBSD): bind process to the first 2 cores 2025-01-10 21:14:51 +08:00
李通洲 1bc41dfa54 chore: remove unnecessary NULL checks
Fix #1494
2025-01-10 14:01:48 +08:00
李通洲 8c227ae4b8 TerminalFont (macOS): fix Ghostty termfont detection
`~/Library/Application Support/com.mitchellh.ghostty/config` is generated as an empty file if the settings dialog is opened

Fix #1495
2025-01-10 09:41:19 +08:00
李通洲 c5c2589f4d GPU: set GPU vendor string when using OpenGL backend 2025-01-10 08:48:29 +08:00
Carter Li b273693842 Packaging: update debian stuff [ci skip] 2025-01-09 09:06:41 +08:00
Carter Li 52de8df1f9 Merge pull request #1492 from fastfetch-cli/dev
Release: v2.34.0
2025-01-09 09:02:12 +08:00
李通洲 be99c4ca6e Media (Linux): remove unused variables 2025-01-09 08:50:56 +08:00
李通洲 8133c3365f Doc: update JSON schema [ci skip] 2025-01-08 22:29:49 +08:00
李通洲 6226ccc70e Processing (Windows): fix get current process 2025-01-08 20:37:35 +08:00
李通洲 88917cb14f OpenGL (EGL): try GLES 2.0+; then fallback to 1.1 if failed 2025-01-08 20:13:01 +08:00
Carter Li a93e2aafdb Release: v2.34.0 2025-01-08 16:26:06 +08:00
李通洲 5848b5fc24 OpenGL (Android): enable support 2025-01-08 16:09:41 +08:00
李通洲 934b6291e3 OpenGL (Android): request GLES 2+ 2025-01-08 15:38:55 +08:00
李通洲 90068ab474 Battery (NetBSD): fix battery percentage detection 2025-01-08 13:46:08 +08:00
Carter Li 5567e6cc5e Packages (Linux): rename am-user to appman 2025-01-08 10:56:55 +08:00
Carter Li 8b3017c0d9 Packages (Linux): remove possible final newlines in am config 2025-01-08 10:28:13 +08:00
Carter Li f9f15ba844 General: don't suppress the output of preRun
Fix #1489
2025-01-08 09:46:41 +08:00
Carter Li b282ac5d47 Packages (Linux): support am-user
Fix #771
2025-01-08 09:46:12 +08:00
Carter Li 6577884417 WMDE: detect Sway by env variables 2025-01-08 08:50:53 +08:00
李通洲 c4ee606955 CPU (Android): check for MTK D9X00 SOCs 2025-01-08 08:39:09 +08:00
Bahar KURT 59c80820f2 feat: Add Rhino Linux ASCII (#1487)
Cramp all additions into one commit because I like to do it that
way. xD

Co-authored-by: Bahar KURT <kurtbahartr@users.noreply.github.com>
2025-01-07 21:30:22 +08:00
李通洲 c11e14f7e1 CMake (Android): set rpath for system Android libs
So that Vulkan & OpenCL can find them
2025-01-07 15:38:47 +08:00
Carter Li ab6a770155 Sound: detect platform API
Ref: #1454
2025-01-07 15:38:38 +08:00
李通洲 0e99486efe Processing (Windows): early return if OpenProcess failed 2025-01-07 08:35:57 +08:00
Eshan Roy f82f3002e4 Logo (Builtin): add snigdhaos ascii (#1485)
* feat: add snigdhaos ascii

* feat: insert builtin data
2025-01-06 23:49:48 +08:00
Angel Gustavo Lopez 0bed182784 fixing fastfetch wrong colors for xray_os logo (#1486) 2025-01-06 19:54:38 +08:00
Carter Li d39be955b1 Doc: update changelog [ci skip] 2025-01-06 14:39:29 +08:00
CaKrome 3b2790cccc CI (Linux): add Linux ppc64le platform (#1484) 2025-01-06 13:55:13 +08:00
Carter Li 3ea0406b69 CPU (Linux): fix var content was unexpectedly modified 2025-01-06 10:57:29 +08:00
李通洲 6429c20466 OS: prefer pretty names
Hopefully we can end the controversy.

Fix #1483 #1038
2025-01-06 08:58:14 +08:00
李通洲 88ebeb21e2 CPU: fix core count output in multi-package platforms
Fix #1413
2025-01-05 19:38:16 +08:00
Carter Li f28f5e2874 CPU (Linux): detect TZ temp if CPU temp is not available 2025-01-05 17:28:01 +08:00
Carter Li 637c37e81c Packages (macOS): remove redundant tokens 2025-01-05 17:28:01 +08:00
Simon Quigley b2c779dea9 Logo (Builtin): add the Lubuntu logo (#1481)
* Add the Lubuntu logo

* Lubuntu uses LXQt, not LXDE
2025-01-05 11:08:27 +08:00
李通洲 89d636447b Doc: update README [ci skip] 2025-01-03 13:56:48 +08:00
Carter Li 3dc51d5f88 FFstrbuf: improve performance of copying static strings 2025-01-03 10:59:01 +08:00
Carter Li 60ff89c794 Terminal (Linux): fix detection of pk-command-not-found
Fix #1467
2025-01-03 10:32:16 +08:00
Carter Li f973572c5a TerminalShell (Linux): relax detection of terminals in NixOS
Fix #1479
2025-01-03 10:18:44 +08:00
Carter Li ea78665971 Doc: update README.md 2025-01-03 10:16:38 +08:00
Carter Li 80b48dd2d1 Logo (Image): mark ghostty supports kitty image protocol 2025-01-03 09:55:38 +08:00
Carter Li df6eed7a02 TerminalSize (Linux): enable fast path when stdout is redirected. 2025-01-03 09:50:59 +08:00
李通洲 c9ac09f9eb WM (Linux): detect WM version 2025-01-02 20:19:15 +08:00
Carter Li 67597e4566 WM (Linux): add sway version detection 2025-01-02 16:36:31 +08:00
李通洲 611de77980 Terminal (macOS): improve performance of kitty version 2025-01-02 16:35:53 +08:00
李通洲 0fde835629 WM (Windows): detect version of DWM 2025-01-02 16:35:53 +08:00
李通洲 f373e07847 WM (Linux): don't crash if no wm is detected 2025-01-02 16:35:53 +08:00
李通洲 89e4403cc8 WM (macOS): add WindowServer version detection 2025-01-02 16:35:53 +08:00
李通洲 c68d21e215 WM: report version field in custom and JSON output 2025-01-02 16:35:53 +08:00
Christopher Kaster f14cd2c6e8 WM: Add support for detecting window manager versions, add support for Hyprland version (#1472) 2025-01-02 10:13:28 +08:00
Carter Li d58d786c83 Logo (Image): add --kitty-icat; honor --logo-height if set 2024-12-31 15:43:01 +08:00
Carter Li 9f37557177 Logo (Image): support generate image data via kitten icat 2024-12-31 15:30:26 +08:00
李通洲 aa63c4f5f2 Revert "GPU: support detection by EGLext"
Works only for NVIDIA GPUs

This reverts commits 9ef8580d93 and 9342d74c93.
2024-12-31 13:57:06 +08:00
李通洲 a378d2ad62 Brightness (FreeBSD): fix backlight name detection 2024-12-30 11:12:06 +08:00
Carter Li 2ab2dd4d48 TerminalFont (macOS): fix ghostty font detection; default to JetBrains Mono
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1466#issuecomment-2564379883
2024-12-30 10:43:28 +08:00
Peter Zmanovsky 2a83b86ba4 Platform (Linux): fix exe path detection (#1468)
On error, -1 is returned from readlink()
2024-12-29 09:53:20 +08:00
李通洲 d967d05019 Bluetooth (DragonFly): disable module to fix build 2024-12-28 22:13:49 +08:00
李通洲 9ef8580d93 GPU (EGLext): fix build on old systems 2024-12-28 21:50:08 +08:00
Carter Li 813b80c5a8 TerminalFont: support Ghostty
Fix #1466
2024-12-28 15:34:41 +08:00
Carter Li ddce9b2357 GPU: rename ffGetGPUVendorString to ffGPUGetVendorString 2024-12-28 15:26:17 +08:00
Carter Li 9342d74c93 GPU: support detection by EGLext
Support multi-gpus
2024-12-28 15:25:22 +08:00
Carter Li d6028370e7 Bluetooth (FreeBSD): add support (not tested) 2024-12-27 14:49:15 +08:00
李通洲 e425d7df63 CI: update *BSD versions 2024-12-27 14:11:53 +08:00
李通洲 a4a2ae7d67 Host (macOS): fix thunderbolt version of new MBPs
Fix #1465
2024-12-27 14:07:17 +08:00
Carter Li 99aa0638cc Packaging: update debian stuff [ci skip] 2024-12-26 09:47:44 +08:00
Carter Li 1a9e637134 Merge pull request #1464 from fastfetch-cli/dev
Release: v2.33.0
2024-12-26 09:37:25 +08:00
李通洲 f322405c04 Release: v2.33.0 2024-12-26 09:08:33 +08:00
Carter Li e4202635af Doc: update changelog [ci skip] 2024-12-25 10:47:36 +08:00
Carter Li 2f13ee3814 Media (Linux): set player name manually for musikcube 2024-12-25 10:47:36 +08:00
Carter Li 2bfde87f84 Logo (Builtin): add GoralixOS
Fix #1462
2024-12-25 10:47:36 +08:00
Carter Li f38a51c9bc Media: make it able to print player info in custom format 2024-12-25 09:04:10 +08:00
Carter Li 28ec935c42 Media (Linux): report player name 2024-12-25 08:50:28 +08:00
李通洲 d939f95c69 Vulkan (Android): hard code path of libvulkan.so, so that users don't need to install vulkan-loader wrapper of termux 2024-12-24 21:20:03 +08:00
李通洲 e0fd5111fe Media (Linux): Fix #1461 (WIP) 2024-12-24 19:38:43 +08:00
李通洲 4736031538 Doc: update changelog [ci skip] 2024-12-22 22:19:02 +08:00
李通洲 66085c087e Logo (Builtin): add NurOS
Fix #1456
2024-12-22 21:48:18 +08:00
李通洲 e0253d71c0 Doc: add comments for running fastfetch in root 2024-12-22 20:45:51 +08:00
李通洲 dadd4bfab6 DiskIO (OpenBSD): remove debug output 2024-12-22 20:43:36 +08:00
李通洲 2f3861e732 PhysicalMemory: clean up garbage data 2024-12-22 20:27:27 +08:00
李通洲 851f271ed5 CPU (NetBSD): fix typo 2024-12-22 14:20:32 +08:00
Carter Li d3e40f625b Battery (OpenBSD): fix build 2024-12-22 09:30:42 +08:00
Carter Li 7c1991c2e3 Battery (NetBSD): add support 2024-12-21 23:54:30 +08:00
李通洲 b8048ee488 Bluetooth (BSD): disable
bluez is Linux specific
2024-12-21 23:54:30 +08:00
李通洲 b99f54b9f4 CPU (NetBSD): trim CPU vendor 2024-12-21 23:54:30 +08:00
Carter Li b38d7a4919 Brightness (NetBSD): don't error out if the screen idx isn't 0 2024-12-21 23:54:30 +08:00
李通洲 45f7e2c0b2 Version (NetBSD): report sysname 2024-12-21 23:54:30 +08:00
李通洲 5a8dda27ff CPU (NetBSD): support temp and frequency detection 2024-12-21 23:54:30 +08:00
李通洲 1ea3264b13 SMBIOS (NetBSD): add more data 2024-12-21 23:54:30 +08:00
Carter Li 852a729581 Battary (NetBSD): some basic investigation of acpi battery detection 2024-12-21 23:54:30 +08:00
Carter Li 0f454b7140 Battery (OpenBSD): add support 2024-12-21 23:54:30 +08:00
Carter Li 9c47a3a9e7 Brightness (OpenBSD): add support
Requires root permission. Not tested
2024-12-21 23:54:30 +08:00
李通洲 4adf7fda28 Brightness (NetBSD): add support for builtin display 2024-12-21 23:54:30 +08:00
李通洲 e2fc83fd48 Bluetooth (Windows): silence compiler warnings 2024-12-21 23:54:30 +08:00
Robin Candau dd41dfa000 CMake: Add a cmake option to make flashfetch target optional (#1455)
Introduces the `-DBUILD_FLASHFETCH='ON'/'OFF'` build option so one can skip the `flashfetch` target (both from executable and install targets, option at `ON` by default to preserve compatibility with the current default behavior).
This is useful when distributing pre-built downstream packages (e.g. for Linux distributions packaging `fastfetch`) as building and shipping the `flashfetch` binary in such pre-built packages serves little to no purpose.
2024-12-21 23:53:02 +08:00
Carter Li 14d6157901 PhysicalDisk (Linux): fix interconnect type detection
Regression of b5a9d64

Fix #1453
2024-12-20 16:38:30 +08:00
Carter Li 74586a9df1 Bluetooth (Linux): improve performance
1. ignore unpaired devices
2. ignore disconnected devices when `showDisconnected == false`
2024-12-20 15:57:17 +08:00
Carter Li c5d4b20729 TerminalShell (Android): ignore proot 2024-12-20 15:57:17 +08:00
李通洲 b152b383a2 Bluetooth (Windows): optimise
1. don't report disconnected devices if `showDisconnected == false`
2. don't report unknown devices
3. don't report errors when no devices found
2024-12-20 15:57:17 +08:00
李通洲 ae26692ef6 Bluetooth (macOS): don't report disconnected devices if showDisconnected == false 2024-12-20 15:57:17 +08:00
Carter Li 4f807f26a9 Bluetooth (Linux): improve performance when showDisconnected == false
If no connected devices found, no dbus calls will be emitted

Fix #1450
2024-12-20 15:57:02 +08:00
Carter Li 4bef801337 BluetoothRadio (Linux): improve performance by reducing size of dbus response 2024-12-20 15:56:48 +08:00
李通洲 41240e9460 FFlist: fix return value of ffListPop 2024-12-20 11:12:14 +08:00
JohnTheCoolingFan 3bb82423b3 OS (Linux): Refactor Armbian version detection and add support for ubuntu-based armbian detection (#1447)
* Add support for detection of Armbian as Ubuntu flavor

Ubuntu can be used to build Armbian, it is one of the official bases for
Armbian. This allows the detection of Armbian in case it is based on
Ubuntu.

* Refactor Armbian detection

* Armbian: set idLike to id before setting id to "armbian"

* Tidy up detectArmbianVersion
2024-12-19 16:18:42 +08:00
李通洲 b87df82d58 Shell (Windows): use $POWERSHELL_VERSION if available 2024-12-19 11:00:16 +08:00
Carter Li c145ce49a5 Merge pull request #1446 from fastfetch-cli/dev
Release: v2.32.1
2024-12-18 14:41:21 +08:00
李通洲 8c4fb5d6d4 Release: v2.32.1 2024-12-18 14:25:44 +08:00
李通洲 eae0fee032 Packages (OpenBSD): fix a typo that prevents package counting from working 2024-12-18 14:24:13 +08:00
Carter Li 4472a13f41 Packaging: update debian stuff 2024-12-18 14:22:56 +08:00
Carter Li 5b001d6bd6 Merge pull request #1445 from fastfetch-cli/dev
Release: v2.32.0
2024-12-18 10:38:44 +08:00
Carter Li 1b52029fce Release: v2.32.0 2024-12-18 09:58:46 +08:00
Carter Li 2176ea2937 Revert "Display (Linux): prefer detecting physical size from EDID"
Try fixing #1444

This reverts commit 5f3ce50022.
2024-12-18 09:28:42 +08:00
李通洲 ac2266c72f Wifi (FreeBSD): early break if the interface is not associated 2024-12-17 20:55:33 +08:00
Eva 0dc40a2632 WM (Linux): added ratpoison window manager (#1442) 2024-12-17 10:49:55 +08:00
李通洲 ca975f8e81 Version: fix format parameter name
Fix #1443
2024-12-17 10:24:18 +08:00
Kevin c4c6fe6668 Logo (Builtin): improved debian ascii logo (#1441) 2024-12-16 12:05:18 +08:00
Carter Li 0a00f5721e OpenGL (NetBSD): try fixing build 2024-12-14 22:22:35 +08:00
李通洲 69f180beea Display (FreeBSD): don't try to use /sys on FreeBSD 2024-12-14 22:22:35 +08:00
李通洲 0e9cdf75b5 WM (FreeBSD): improve WM detection for Wayland 2024-12-14 22:22:35 +08:00
Carter Li 7d7e219c0a OpenGL (NetBSD): fix build 2024-12-14 13:34:42 +08:00
Carter Li 4937ccfa81 OpenGL (EGL): prefer surfaceless display 2024-12-14 12:56:40 +08:00
JohnTheCoolingFan d0d29c163b Add Armbian-unofficial detection (#1436) 2024-12-14 12:56:13 +08:00
Carter Li 901e0eb177 Logo (Builtin): add Ultramarine Small
Fix #1438
2024-12-14 12:00:33 +08:00
Carter Li 87446e6eef WM (OpenBSD): fix process enumeration 2024-12-14 00:18:41 +08:00
Carter Li bfaa73a2c7 Display (Linux): clean up 2024-12-14 00:05:28 +08:00
Carter Li 373e288d03 WM: add support for fvwm (OpenBSD) and ctwm (NetBSD) 2024-12-14 00:05:02 +08:00
李通洲 82170ceab0 Scripts: fix typo 2024-12-13 16:05:37 +08:00
Carter Li 009a7888b5 OpenGL (Linux): suppress IO
Fix #1435
2024-12-13 15:40:36 +08:00
Carter Li ab1a11c9fa CPU (ARM): add more apple cores 2024-12-13 15:29:24 +08:00
Carter Li 68746275f8 CPU (Linux): detect Virtualized Apple Silicon 2024-12-13 15:28:59 +08:00
李通洲 491cfb94b6 Doc: update changelog [ci skip] 2024-12-12 16:01:56 +08:00
李通洲 79c8919431 Logo (Builtin): add Serpent OS
Ref: https://github.com/serpent-os/recipes/blob/main/f/fastfetch/pkg/0001-logo-Port-our-neofetch-Serpent-OS-logo-from-ermo.patch
2024-12-12 15:43:43 +08:00
李通洲 e98afa8315 JsonSchema: fix typo 2024-12-11 16:41:48 +08:00
李通洲 86783c033b OS (Linux): detect Linux Lite
Fix #1434
2024-12-11 16:40:02 +08:00
李通洲 f01944de41 JsonSchema: add documentation of format args 2024-12-11 16:12:55 +08:00
李通洲 ebfdeef25c Fastfetch: add -h format-json 2024-12-11 16:12:03 +08:00
李通洲 9a36d63d18 Global: refactor code of -h <module>-format 2024-12-11 10:47:02 +08:00
李通洲 e45ff546ed Host: silence compiler warnings 2024-12-10 09:35:52 +08:00
李通洲 2700390371 Host (Sun): fix build 2024-12-09 23:07:24 +08:00
Carter Li 5c01685d69 Host: detect mac model in FreeBSD & Windows 2024-12-09 21:44:31 +08:00
Carter Li d897472572 Edid: use screen size in DTD if make sense 2024-12-06 19:20:06 +08:00
Carter Li 8410a66277 Host (Linux): report mac product name 2024-12-06 18:31:33 +08:00
Carter Li 856d229b36 Wifi (Linux): fix bssid formatting 2024-12-06 09:14:30 +08:00
李通洲 b33692aa7d Logo: randomly select one if the logo source expands to multiple files
Fix #1426
2024-12-05 14:16:30 +08:00
李通洲 e90c5cb241 GPU (OpenBSD): fix pci.ids file location 2024-12-05 08:37:41 +08:00
Carter Li 03cd283755 Packaging: update debian stuff [ci skip] 2024-12-04 08:43:33 +08:00
Carter Li 58a1d965cb Merge pull request #1425 from fastfetch-cli/dev
Release: v2.31.0
2024-12-03 15:00:54 +08:00
Carter Li 6edf763f2b Display (Linux): detect bit depth when libdrm is used 2024-12-03 10:55:00 +08:00
Carter Li ab200d7e4a Terminal: Support sakura version & font detection
Fix #1424
2024-12-02 19:10:47 +08:00
Carter Li dfe36daf79 Release: v2.31.0 2024-12-02 16:36:12 +08:00
李通洲 e9ab67b380 Processing (Linux): interrupt poll & read syscalls when the child process is exited
Fix #1418
2024-12-02 16:02:04 +08:00
Carter Li f073f4882c Wifi (Linux): detect Wifi-7 2024-12-01 18:16:05 +08:00
李通洲 692ad502df Wifi (Windows): make unit of bitrates be consistant
Also fix a copy & paste bug
2024-11-30 23:50:06 +08:00
Raymond Kemboi 3004ce8565 Completion (Zsh): fix syntax error in completion file (#1421)
A syntax error in the file caused the following output when trying to trigger completions in `zsh` (pressing <TAB>):

```zsh
$ fastfetch    File "<stdin>", line 15
    command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
                                               ^^^^
SyntaxError: f-string: unmatched '['
```
This fix replaces single quotes with double quotes in the f-strings in lines 37 and 41.
2024-11-29 10:25:58 +08:00
Ryan ee8801b54d WM (Linux): fix wl-restart parsing (#1422)
Make the WM name in `wl-restart -n 5 Hyprland` parse as "Hyprland"
instead of "-n".
2024-11-29 08:34:40 +08:00
李通洲 bbe239647b Logo (Builtin): add Windows Server 2025
Fix #1420
2024-11-28 21:55:21 +08:00
Carter Li 77c06193d6 GPU (Linux): detect GPU NV type 2024-11-28 21:28:35 +08:00
李通洲 90bbefe11a CPU (Windows): code cleanup 2024-11-26 22:02:57 +08:00
Carter Li 69a7e64e48 CPU (Linux): support up to 128-socket boards 2024-11-26 21:49:28 +08:00
Carter Li ee564de461 CPU: change cpuCount to packages; support custom format
Fix #1413
2024-11-26 21:37:15 +08:00
Carter Li 9955e9da02 CPU: remove duplicate whitespaces in CPU name
Eg. `Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz`
2024-11-26 21:27:36 +08:00
Carter Li 8b41cbd508 CPU (Linux): refactor; fix cpu count detection 2024-11-26 16:05:01 +08:00
AzimovParviz 7535ce8a18 Support for dual CPU systems (#1417)
* [macOS] Added support for dual CPUs on Mac computers

Signed-off-by: Koneko <azimovp17@gmail.com>

* Change how number of cores is displayed when the system is dual CPU

* Support for dual CPU on Windows

* Dual CPU detection on Linux basic implementation

---------

Signed-off-by: Koneko <azimovp17@gmail.com>
2024-11-26 08:53:01 +08:00
李通洲 b76eb87510 CI: fix building on macOS 2024-11-25 22:46:57 +08:00
李通洲 0cd7aeac19 Display (macOS): don't crash with NULL pointer references
Fix #1393
2024-11-25 22:23:24 +08:00
Carter Li 04088b5b2c Logo (Builtin): update MidOS
Fix #1409
2024-11-25 14:31:07 +08:00
Carter Li e77c3119ca OS (Linux): check for lmde
Fix #1415
2024-11-25 14:20:52 +08:00
Carlos Henrique Lima Melara 3463fc331f Scripts: use datetime to get date and set timezone to UTC (#1410)
This will ensure the package is reproducible even in different
timezones.
2024-11-24 10:22:57 +08:00
李通洲 64287eed21 Display: change physical size detection to use basic display parameters
Some monitor report invalid data in DTD.
Ref: #1406
2024-11-24 01:02:06 +08:00
李通洲 1b835544b6 Users: fix invalid var name
Fix #1408
2024-11-23 22:44:45 +08:00
Carter Li 55352be0cc Wifi (FreeBSD): support channel & frequency detection 2024-11-23 12:21:48 +08:00
Carter Li c0be2637a8 Wifi (Android): silence compiler warnings 2024-11-22 15:37:01 +08:00
Carter Li 864fb918bc Chore: silence some warnings 2024-11-22 14:20:50 +08:00
Carter Li 2197cfb06d Wifi (Android): report more props 2024-11-22 13:53:04 +08:00
Carter Li 94f8ff938b Wifi: print channel band 2024-11-22 11:01:54 +08:00
Carter Li 7000317841 Wifi (Linux): detect frequency & channel number 2024-11-22 10:31:12 +08:00
李通洲 06055cc6c3 Wifi (macOS): fix build on old OS version 2024-11-21 22:03:25 +08:00
李通洲 601b9706b5 Display: report ppi to 0 if screen size is not available 2024-11-21 21:44:05 +08:00
李通洲 d48c76b597 Wifi: detect channel and frequency 2024-11-21 21:37:30 +08:00
李通洲 9a1d18556d Display: don't report screen size when display is mirrored
Fix #1406
2024-11-21 15:29:14 +08:00
李通洲 71b073e1bf CMake: fix possible linking errors in BINARY_LINK_TYPE=dynamic mode 2024-11-20 22:13:10 +08:00
Carter Li a567268ca1 Display (Linux): fix preferred resolution detection for wayland 2024-11-20 21:38:18 +08:00
李通洲 8b62ad72f7 Display (FreeBSD): fix build 2024-11-20 16:39:01 +08:00
李通洲 cee880cb83 Display: print preferred resolution & refresh rate in custom format
Fix #1406
2024-11-20 16:39:01 +08:00
李通洲 925c3471c2 Display: add scale factor in custom format 2024-11-20 16:39:01 +08:00
李通洲 7948e627b0 Display (Android): fix build 2024-11-20 16:39:01 +08:00
李通洲 4cca63a299 Display (Windows): detect preferred resolution & refresh rate 2024-11-20 16:39:01 +08:00
李通洲 21a35769a7 Display (macOS): detect maximum resolution & refresh rate 2024-11-20 16:39:01 +08:00
Carter Li fa9290088d Display (Linux): detect preferred resolution and refresh rate 2024-11-20 16:38:53 +08:00
Carter Li 3d5133eaba DisplayServer (Linux): remove support of xcb & xlib
They don't support multi-monitors. Prefer libdrm.
2024-11-20 09:37:32 +08:00
Carter Li 4cbcd0f107 Wifi (Linux): improve performance 2024-11-20 08:43:41 +08:00
Carter Li fdc9bee4b3 DBus: use general.processingTimeout as its timeout instead hard coding 2024-11-20 08:43:41 +08:00
Carter Li 16b7a4a1be Media (Linux): improve performance of dbus communication 2024-11-20 08:43:41 +08:00
R0CKSTAR 465170428f mtgpu: header file cleanup for forward compatibility (#1405)
Signed-off-by: Xiaodong Ye <yeahdongcn@gmail.com>
2024-11-19 19:36:12 +08:00
Carter Li e953ed9d88 Packaging: update debian stuff [ci skip] 2024-11-18 15:47:48 +08:00
Carter Li 6d45fe61b5 Merge pull request #1404 from fastfetch-cli/dev
Release: v2.30.1
2024-11-18 14:57:05 +08:00
李通洲 efc8504607 CMake: check return code of python scripts 2024-11-18 14:08:53 +08:00
李通洲 a9a08d8a80 Release: v2.30.1 2024-11-18 13:40:08 +08:00
李通洲 7f63ec1315 CMake: fix the destination where fastfetch_pciids.c.inc is generated 2024-11-18 13:36:31 +08:00
Masato TOYOSHIMA 6cbbe334b5 CMake: Fixed the destination where fastfetch.1 is generated. (#1403)
* Fixed the destination where fastfetch.1 is generated.

* Update CMakeLists.txt

Reappend trailing new line

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-18 13:32:49 +08:00
Carter Li 4bde8d3fb3 Packaging: update debian stuff [ci skip] 2024-11-18 09:36:46 +08:00
Carter Li 62dcd1257e Merge pull request #1401 from fastfetch-cli/dev
Release: v2.30.0
2024-11-18 09:21:24 +08:00
Carter Li dbb6a4b265 Release: v2.30.0 2024-11-18 09:04:17 +08:00
Carter Li a73a3089af Doc: remove guix package installer as it's outdated [ci skip] 2024-11-18 08:40:45 +08:00
李通洲 dcdf2b570e Display: concat flags 2024-11-15 20:01:56 +08:00
李通洲 ba7d3ed27b GPU (Windows): fix a bad assignment 2024-11-15 19:47:24 +08:00
Carter Li b7a9fe58b4 Terminal (Linux): support tilix version detection 2024-11-15 16:18:43 +08:00
李通洲 e5451b6826 NetIO (BSD): remove unnecessary checks
Seems...
2024-11-15 15:13:09 +08:00
李通洲 9f314a208b NetIO (BSD): add txDrops detection if supported 2024-11-15 15:13:09 +08:00
李通洲 56eb8b80c6 NetIO (macOS): fix 32bit trancation 2024-11-15 15:11:55 +08:00
Dariqq 563ed58b4f Scripts: gen-man.py honors SOURCE_DATE_EPOCH. (#1400) 2024-11-15 08:50:47 +08:00
李通洲 b8ec07092a Logo (Builtin): update openSUSE Tumbleweed
Fix #1398
2024-11-15 08:41:14 +08:00
李通洲 e77a4e8262 Doc: update changelog [ci skip] 2024-11-14 16:40:45 +08:00
李通洲 782af250ff Percent: in custom format, only set num and bar string if enabled in percent config
Also fix `percentage-bar` printing in Brightness module
2024-11-14 15:45:25 +08:00
李通洲 6801fe3d9c Doc: update schema for percent type config 2024-11-14 14:26:18 +08:00
李通洲 1c41c6ccb1 Percent: allow use enum to set type value in JSON config 2024-11-14 14:21:55 +08:00
李通洲 c9e3f8d95c Global: support percent type config in module level 2024-11-14 13:52:02 +08:00
李通洲 97e1b987dd Global: pack all enums and make flag enums unsigned 2024-11-14 11:00:44 +08:00
Carter Li e821a99873 CPU (Linux): add more Apple SOC code names 2024-11-13 16:44:24 +08:00
李通洲 bad85a557a Host (Android): detect marketing name of vivo smartphone 2024-11-13 15:53:14 +08:00
李通洲 1d92bf864a IO (macOS): fix logo fails to load from symlinked files
Fix #1395
2024-11-13 15:15:50 +08:00
李通洲 2cfc8ec0db Processing (macOS): fix exe path detection 2024-11-13 10:46:30 +08:00
李通洲 5efb87997b Util (macOS): cleanup cf_helpers.c 2024-11-13 10:38:40 +08:00
李通洲 d7fa0417ed CMake: use gen-man.py to generate man file 2024-11-13 10:24:57 +08:00
李通洲 fe57b28581 Scripts: clean up gen-man.py 2024-11-13 10:18:11 +08:00
李通洲 5a1be2535b Scripts: make gen-pciids.py executable 2024-11-13 10:17:06 +08:00
Tibo bccf241816 Scripts: Add python script to generate man page (#1392)
*  Add man generating script

*  Add arguments and description

* 🐛 Add shebang

* 📝 Add documentation & text for sections

* 🐛 Fix italic text (italic is not supported for man pages)

* 🗑️ Remove .1 generated file

* ✏️ Fix type "abbreviation" gen-man.py:24

* 🐛 Fix invalid escape sequence

*  Add version finder

*  Example & config sections

* 🗑️ Delete generated .1 file

---------

Co-authored-by: tgallone <thibaut.gallone@etu.unistra.fr>
2024-11-13 09:13:13 +08:00
李通洲 c70c37c50c GPU (macOS): apply the same logic as CPU just in case 2024-11-12 22:58:22 +08:00
李通洲 644458bc74 CPU (macOS): try fixing CPU freq detection on Apple M4
Fix #1394
2024-11-12 22:34:57 +08:00
李通洲 e618303343 Media (macOS): try fixing error CFStringGetCString() failed 2024-11-12 21:52:12 +08:00
李通洲 748b7df0d7 Smbios: clean up more garbage values
Ref: #1391
2024-11-12 10:45:09 +08:00
李通洲 7c8250c68c StringUtil: rename ffStrCopy and correctly reflect its usage 2024-11-11 18:02:23 +08:00
Carter Li c368908b7d Shell (macOS): try fixing segfault in old macOS
Ref: #1388
2024-11-11 17:49:49 +08:00
李通洲 830c71ddc4 DisplayServer (NetBSD): detect WM / DE by process name 2024-11-11 17:37:01 +08:00
李通洲 5e7d9ed45e Packages (Linux): add qi support 2024-11-11 17:37:01 +08:00
Carter Li 4799f9277e Revert "IO: optimize createSubfolders (#1382)" (#1390)
This reverts commit 0284e4ccc4.
2024-11-11 17:33:22 +08:00
apocelipes 0a61031463 tests: add FFstrbuf smallest allocation test & minor fix (#1387) 2024-11-11 07:58:24 +08:00
Tibo G 07d0743a18 Logo (Builtin): add cosmicDE logo (#1386)
* add cosmicDE logo

* Update cosmic.txt

* Update builtin.c

---------

Co-authored-by: tgallone <thibaut.gallone@etu.unistra.fr>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-11 00:43:43 +08:00
Emily Astranova f989a1a982 Doc: fix typo in README (#1385) [ci skip]
Changed "deserved" to "derived"
2024-11-10 23:37:29 +08:00
李通洲 f9713d5ee2 OS (Android): display android icon 2024-11-10 13:57:57 +08:00
李通洲 4f9645e7ff Logo (Builtin): add Unifi 2024-11-10 13:35:22 +08:00
Carter Li 08a92a4324 CPU (OpenBSD): support CPU temp detection 2024-11-10 13:28:48 +08:00
李通洲 d10c14721a Disk: be able to print disk indices 2024-11-10 13:07:30 +08:00
李通洲 4534f18525 Battery: don't print index in multi-battery device 2024-11-10 13:07:12 +08:00
Carter Li f98e6c9d4e Sound (BSD): trim device names 2024-11-10 12:47:26 +08:00
Carter Li 59c666515a Version (MidnightBSD): support libc version detection 2024-11-10 12:47:26 +08:00
李通洲 7fab6f27ee Packages (BSD): support mport 2024-11-10 12:47:26 +08:00
李通洲 7d406bbae1 Logo (Builtin): add MidnightBSD 2024-11-10 12:47:26 +08:00
apocelipes 7b81ffc8e4 FFstrbuf: fix small FFstrbuf allocations in ffStrbufEnsureFree (#1383) 2024-11-10 08:27:57 +08:00
apocelipes 0284e4ccc4 IO: optimize createSubfolders (#1382) 2024-11-10 08:27:34 +08:00
Carter Li 837903e845 DisplayServer: fix deprecation warnings 2024-11-09 21:36:48 +08:00
xiaoran007 3fa0d1ab19 Host (macOS): add HwModel support for new Mac (2024) (#1381)
* host(macOS): add HwModel support for new Mac (iMac, Mac mini and Macbook Pro 2024)

* Update host_apple.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-09 20:32:35 +08:00
李通洲 07f2a71b3c Bluetooth (Windows): detect battery level 2024-11-09 20:23:25 +08:00
李通洲 acb38fa3ee Bluetooth (Windows): detect battery (WIP) 2024-11-06 08:25:54 +08:00
李通洲 7396208809 Logo (Builtin): fix Lilidog
Fix #1373
2024-11-06 08:25:48 +08:00
李通洲 2389d7b580 FFstrbuf: correct definition of StrStrIA 2024-11-06 08:25:06 +08:00
李通洲 8f750da559 Bluetooth (Windows): fix mac address detection 2024-11-06 08:25:06 +08:00
Lucas Holt f69a9dab33 CMake: Add initial support for MidnightBSD (#1377)
* Add initial support for MidnightBSD

* Cleanup some issues identified through code review.

Add libzfs check as MidnightBSD does have zfs.

* Add MidnightBSD check to the version.c detection

* Remove `OR MidnightBSD` tests

* Clean up

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-11-06 00:17:23 +08:00
李通洲 9a34cb98dc Bluetooth (macOS): normalize mac address strings 2024-11-05 16:39:04 +08:00
李通洲 ef974ef8c0 Bluetooth (macOS): support battery level detection 2024-11-05 11:06:54 +08:00
李通洲 40671c78f1 Monitor: don't display () if display name is not available 2024-11-05 10:01:43 +08:00
李通洲 211fd4b197 Display: add hdr-compatible
Fix #1376
2024-11-05 09:59:25 +08:00
Carter Li 722063401c Packaging: update debian stuff [ci skip] 2024-11-04 15:06:33 +08:00
Carter Li 9be70a73d3 Merge pull request #1374 from fastfetch-cli/dev
Release: v2.29.0
2024-11-04 15:02:18 +08:00
李通洲 55909c480e CMake (OpenBSD): enable bluetooth detection
I don't think it work, though
2024-11-04 14:47:38 +08:00
李通洲 7ceabcc03e CMake (NetBSD): add /usr/pkg/lib to rpath 2024-11-04 14:28:16 +08:00
Carter Li e4b98b3494 GPU: fix build if libpciaccess is not available 2024-11-04 21:59:41 +08:00
Carter Li 991ebfbc4a Camera (OpenBSD): add support (?) 2024-11-04 13:30:50 +08:00
Carter Li 02e133bf35 OpenGL (NetBSD): use correct so file 2024-11-04 13:30:50 +08:00
李通洲 3c6214d90f Release: 2.29.0 2024-11-04 10:48:38 +08:00
李通洲 7f56928cf0 OS (BSD): don't check for debian and ubuntu variants 2024-11-04 10:47:52 +08:00
李通洲 1487c91f3f OS (Linux): fix build
oops
2024-11-04 10:42:51 +08:00
李通洲 47b9d0a3a4 Library (Windows): load dlls at current exe path 2024-11-04 10:32:17 +08:00
李通洲 17d6153353 Vulkan: drop windows-i686 support 2024-11-04 09:30:13 +08:00
李通洲 b5545c926f Logo (Builtin): add Lilidog
Fix #1373
2024-11-04 09:20:38 +08:00
李通洲 a7f881522b OS (Linux): detect Lilidog 2024-11-04 09:19:53 +08:00
李通洲 91fdc8114f CI: remove windows-i686 2024-11-04 09:08:10 +08:00
Carter Li 8f2d51c698 Doc: update changelog 2024-11-03 18:09:18 +08:00
Carter Li 534aa09d86 CI (DragonFly): build with chafa & libelf 2024-11-03 18:09:08 +08:00
Carter Li d216391278 Libc (BSD): always initialize variables 2024-11-03 18:00:45 +08:00
李通洲 743babda10 Libc (DragonFly): add support 2024-11-03 11:58:23 +08:00
李通洲 9610912c1f CI: build on DragonFly 2024-11-03 11:15:24 +08:00
李通洲 282ed9b40b Netif (SunOS): fix compiling 2024-11-03 11:01:27 +08:00
Carter Li d1ef454ae8 Sound (DragonFly): add support 2024-11-03 18:40:59 +08:00
Carter Li 5c21931a09 DiskIO (DragonFly): add support 2024-11-03 18:10:36 +08:00
李通洲 3c04b0ae65 Doc: update changelog 2024-11-03 09:54:04 +08:00
李通洲 dab02f176f OS (Linux): improve performance of proxmox version detection
Fix #1370
2024-11-03 09:53:54 +08:00
Carter Li f7288fec01 Global: support DragonFly BSD 2024-11-03 08:35:11 +08:00
李通洲 540239fe03 Brightness (NetBSD): disable 2024-11-01 22:33:28 +08:00
李通洲 fe8595a054 Doc: update changelog 2024-11-01 22:18:59 +08:00
李通洲 efe0676831 Logo (Builtin): update OpenSUSE Leap 2024-11-01 22:16:29 +08:00
李通洲 565afa1e51 CI (NetBSD): release NetBSD 2024-11-01 22:05:36 +08:00
李通洲 7ffffda504 CI: remove libv4l
We need libv4l2 instead of libv4l(1)
2024-11-01 22:00:21 +08:00
Carter Li 0110584e39 NetIO (*BSD): support OpenBSD & NetBSD 2024-11-01 18:51:59 +08:00
Carter Li 254f1216ec Users (OpenBSD): add support 2024-11-01 18:44:34 +08:00
Carter Li 090b6d741c DiskIO (SunOS): remove dev path 2024-11-01 15:31:54 +08:00
Carter Li b05023fb8b DiskIO (OpenBSD): add support 2024-11-01 15:21:47 +08:00
Carter Li 0f3ce426e9 DiskIO (NetBSD): add support 2024-11-01 15:21:17 +08:00
李通洲 7d46b2ada5 Logo (Builtin): make aperture colorable
Fix #1368
2024-11-01 08:47:26 +08:00
李通洲 e0acce9646 CI (OpenBSD / NetBSD): embed pci.ids 2024-11-01 00:21:19 +08:00
Carter Li b410710903 Processes (NetBSD): add support 2024-11-01 00:20:51 +08:00
Carter Li cb403be8e5 GPU: use pciaccess to enumerate PCI devices 2024-10-31 23:51:58 +08:00
Carter Li 2bc66d7f27 CMake (NetBSD): set rpath 2024-10-31 22:39:25 +08:00
李通洲 d4c7b53ded CPU (Android): add QS8E 2024-10-31 09:33:23 +08:00
Carter Li c693e5ab5f Bios (NetBSD): try detecting boot method 2024-10-31 00:40:29 +08:00
Carter Li cae8286621 Shell / Terminal: fix proc path detection 2024-10-31 00:25:40 +08:00
Carter Li c3d04d067d Platform (NetBSD): fix exe path detection 2024-10-31 00:13:34 +08:00
Carter Li 49902d8c2f Disk (NetBSD): fix disk size detection 2024-10-30 23:46:40 +08:00
Carter Li 229d5f899c CPU (NetBSD): add support 2024-10-30 23:29:05 +08:00
Carter Li 3f41306c91 Packages (NetBSD): add support 2024-10-30 22:42:46 +08:00
李通洲 6ccc6124d0 Keyboard (Linux): silence compiler warnings 2024-10-30 09:28:18 +08:00
Carter Li c6c6803403 CMake (*BSD): detect videodev2 2024-10-29 09:22:09 +08:00
Carter Li e22b58b26e CI (NetBSD): try fixing build 2024-10-29 09:13:59 +08:00
Carter Li 0406f5c2b2 CI (NetBSD): add more dependencies 2024-10-29 09:08:32 +08:00
Carter Li 5443334156 DisplayServer (Linux): silense compiler warnings 2024-10-29 09:08:28 +08:00
Carter Li a3a042f02b Global: remove stb_printf
Doesn't gain any performance boost
2024-10-29 08:51:17 +08:00
Carter Li bc550a5ea7 Disk (OpenBSD): fix build 2024-10-28 16:27:29 +08:00
Carter Li 82fc27f259 CMake (NetBSD): detect X11 and other packages 2024-10-28 16:12:23 +08:00
Carter Li 081e8ea39f Disk: support NetBSD, improve hidden partition detection 2024-10-28 16:11:37 +08:00
Carter Li e7630aef34 NetBSD: support CPUUsage / Memory / Swap 2024-10-28 16:10:20 +08:00
Carter Li e19ed4c8f6 CMake: allow to replace native *printf to stb_*printf 2024-10-28 14:47:08 +08:00
Carter Li 332ddfc6ed CI: fix a copy-paste error 2024-10-27 14:05:18 +08:00
李通洲 32939eabab Uptime (NetBSD): fix invalid result 2024-10-27 12:19:48 +08:00
李通洲 bdd87a6ce7 CI: try adding netbsd 2024-10-27 12:09:27 +08:00
李通洲 4665fdd145 Global: make it compile on NetBSD
Doesn't work yet.
2024-10-27 11:43:36 +08:00
ferrreo 2fe6e60d98 Logo (Builtin): update PikaOS (#1361) 2024-10-27 09:40:49 +08:00
李通洲 26920d49f5 Logo (Builtin): add SummitOS
Fix #1352
2024-10-26 22:45:32 +08:00
李通洲 2dc8ac6a51 Logo (Builtin): add XCP-ng
Fix #1359
2024-10-26 22:27:09 +08:00
李通洲 20f9ff9bae Logo (Builtin): update OpenSuse Tumbleweed
Fix #1357
2024-10-26 11:42:08 +08:00
李通洲 fd26373c8f Global: overall optimization 2024-10-26 11:42:07 +08:00
李通洲 6dc6fd8b24 3rdparty: add stb_sprintf 2024-10-26 11:42:07 +08:00
apocelipes 53e0861b03 Editor: fix the Vim version detection (#1356) 2024-10-26 11:08:18 +08:00
李通洲 19902fa18c CMake: define NOMINMAX on Windows 2024-10-24 15:21:40 +08:00
李通洲 f3f8601a60 CMake: use 64bit time_t on Linux 2024-10-24 15:21:40 +08:00
apocelipes 0bdb097592 Editor: optimize editor version parsing (#1355) 2024-10-24 09:43:23 +08:00
Carter Li b57766522d Packaging: update debian stuff [ci skip] 2024-10-23 14:36:12 +08:00
329 changed files with 8912 additions and 4056 deletions
+115 -77
View File
@@ -232,6 +232,41 @@ jobs:
name: fastfetch-linux-riscv64
path: ./fastfetch-*.*
linux-ppc64le:
name: Linux-ppc64le
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: uraimo/run-on-arch-action@v2
id: runcmd
with:
arch: ppc64le
distro: ubuntu20.04
githubToken: ${{ github.token }}
run: |
uname -a
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-linux-ppc64le
path: ./fastfetch-*.*
musl-amd64:
name: Musl-amd64
runs-on: ubuntu-latest
@@ -274,7 +309,7 @@ jobs:
macos-universal:
name: macOS-universal
runs-on: macos-12
runs-on: macos-latest
permissions:
security-events: write
contents: read
@@ -377,11 +412,11 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '14.1'
version: '14.2'
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm libelf glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests chafa
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
@@ -397,6 +432,41 @@ jobs:
name: fastfetch-freebsd-amd64
path: ./fastfetch-*.*
dragonfly-amd64:
name: DragonFly-amd64
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: vmactions/dragonflybsd-vm@v1
with:
usesh: yes
prepare: |
uname -a
pkg update
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py39-requests chafa libelf
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-dragonfly-amd64
path: ./fastfetch-*.*
openbsd-amd64:
name: OpenBSD-amd64
runs-on: ubuntu-latest
@@ -414,11 +484,11 @@ jobs:
architecture: x86-64
cpu_count: 4
shell: bash
version: '7.5'
version: '7.6'
run: |
uname -a
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa pulseaudio hwdata py3-requests
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
@@ -433,6 +503,42 @@ jobs:
name: fastfetch-openbsd-amd64
path: ./fastfetch-*.*
netbsd-amd64:
name: NetBSD-amd64
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: run VM
uses: cross-platform-actions/action@master
with:
operating_system: netbsd
architecture: x86-64
cpu_count: 4
shell: bash
version: '10.0'
run: |
uname -a
sudo pkgin -y install cmake git pkgconf wayland vulkan-headers dconf dbus sqlite3 ImageMagick pulseaudio opencl-headers ocl-icd py312-requests
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=ON .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-netbsd-amd64
path: ./fastfetch-*.*
windows-amd64:
name: Windows-amd64
runs-on: windows-latest
@@ -498,76 +604,6 @@ jobs:
name: fastfetch-windows-amd64
path: ./fastfetch-windows-amd64.*
windows-i686:
name: Windows-i686
runs-on: windows-latest
permissions:
security-events: write
contents: read
defaults:
run:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW32
update: true
install: git p7zip mingw-w64-i686-cmake mingw-w64-i686-clang mingw-w64-i686-vulkan-loader mingw-w64-i686-vulkan-headers mingw-w64-i686-opencl-icd mingw-w64-i686-opencl-headers
- name: print msys version
run: uname -a
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: c, cpp
- name: configure project
run: env PKG_CONFIG_PATH=/mingw32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project
run: cmake --build . --verbose -j4
- name: perform CodeQL analysis
uses: github/codeql-action/analyze@v3
- name: copy necessary dlls
run: cp /mingw32/bin/{OpenCL,vulkan-1}.dll .
- name: download amd_ags
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-windows-i686
path: ./fastfetch-windows-i686.*
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
@@ -577,13 +613,15 @@ jobs:
- linux-aarch64
- linux-armv7
- linux-riscv64
- linux-ppc64le
- musl-amd64
- macos-universal
- freebsd-amd64
- openbsd-amd64
- netbsd-amd64
- dragonfly-amd64
- sunos-amd64
- windows-amd64
- windows-i686
permissions:
contents: write
steps:
+1
View File
@@ -9,3 +9,4 @@ tags
fastfetch.kdev4
*.user
*.user.*
*.swp
+239
View File
@@ -1,3 +1,242 @@
# 2.34.1
An early release to fix KDE Plasma 6.3 compatibility. Hopefully it can be accepted by package managers before KDE 6.3 is officially released.
To package managers: if you find fastfetch bugs, it's highly appreciated if you can report them to the upstream, so that all users can benefit from the fix, instead of maintaining out-of-tree patches. Thanks!
Features:
* Report vendor name when detecting GPUs by OpenGL
* Note: the vendor name is actually the creator of the OpenGL driver (such as `Mesa`) and may not be the same as the GPU vendor.
Bugfixes:
* Fix Ghostty termfont detection (#1495, TerminalFont, macOS)
* Fix compatibility with KDE Plasma 6.3 (#1504, Display, Linux)
* Make memory usage detection logic consistent with other systems (Memory, OpenBSD / NetBSD)
* Report media file name if media title is not available (Media)
* Fix max frequency detection for CPUs with both performance and efficiency cores (CPU, FreeBSD)
Logo:
* Add HeliumOS
* Add Oreon
* Update SnigdhaOS
# 2.34.0
Changes:
* We now print distro pretty name if available (OS)
* This is a long requested feature. However, it may break some distros. File a bug with the content of `/etc/os-release` if it breaks your distro.
Bugfixes:
* Fix thunderbolt version of new MBPs (#1465, Host, macOS)
* Fix backlight name detection on FreeBSD (Brightness, FreeBSD)
* Fix Terminal detection when running fastfetch in `pk-command-not-found` (#1467, Terminal, Linux)
* Relax detection of terminals in NixOS (#1479, Terminal, Linux)
* Should fix konsole, ghostty and maybe others
* Fix core count output in multi-package platforms (CPU)
* Don't suppress the output of `preRun` (#1489)
* Fix battery percentage detection (Battery, NetBSD)
Features:
* Support ghostty terminal font detection (TerminalFont, Linux / macOS)
* Support `kitty-icat` image protocol, which uses `kitten icat` to generate image data
* Pros: support tmux; support gif animations; good performance
* Cons: due to the limitation of `kitten icat`, we need to clear the screen before displaying the image logo
* Support WM version detection (WM)
* In Linux, Hyprland & sway are supported currently
* Improve performance when stdout is redirected (TerminalSize)
* Report thermal zone temp if CPU temp is not available (CPU, Linux)
* Report sound server (Pipewire or PulseAudio) if available (#1454, Sound, Linux)
* Enable OpenGL & OpenCL detection on Android (OpenGL / OpenCL, Android)
* Detect & report MediaTek Dimensity 9000+ SOC name (CPU, Android)
* Support appman (am-user) package manager detection (Packages, Linux)
Logo:
* Add Lubuntu
* Update Xray_os
* Add SnigdhaOS
* Add Rhino Linux
# 2.33.0
Changes:
* Introduce a new CMake flag `-DBUILD_FLASHFETCH=OFF` to disable building flashfetch binaries
* Package managers are encouraged to enable it. See <https://github.com/fastfetch-cli/fastfetch/discussions/627> for detail
Bugfixes:
* Fix interconnect type detection (#1453, PhysicalDisk, Linux)
* Regression of v2.28
* Don't report `proot` as terminal (Terminal, Android)
* Remove a debug output (DiskIO, OpenBSD)
* Fix media detection for some players (#1461, Media, Linux)
* Regression of v2.32
Features:
* Use `$POWERSHELL_VERSION` as PowerShell version if available (Shell, Windows)
* Fetching Windows PowerShell version can be very slow. Add `$env:POWERSHELL_VERSION = $PSVersionTable.PSVersion.ToString()` in `$PROFILE` before running `fastfetch` to improve the performance of `Shell` module
* Add support for ubuntu-based armbian detection (#1447, OS, Linux)
* Improve performance of Bluetooth detection (Bluetooth)
* We no longer report disconnected bluetooth devices in `--format json` when `--bluetooth-show-disconnected` isn't specified
* Support brightness level detection for builtin displays (Brightness, OpenBSD / NetBSD)
* Requires root permission on OpenBSD
* Support battery level detection (Battery, OpenBSD / NetBSD)
* Support CPU temperature detection in NetBSD (CPU, NetBSD)
* Hard code path of `libvulkan.so` for Android
* So that users don't need to install the vulkan-loader wrapper of termux
Logo:
* Add NurOS
* Add GoralixOS
# 2.32.1
A hotfix for OpenBSD. No changes to other platforms.
Bugfixes:
* Fix package count detection on OpenBSD (Packages, OpenBSD)
# 2.32.0
Bugfixes:
* Fix `pci.ids` file location on OpenBSD (GPU, OpenBSD)
* It's normally unused because enumerating PCI devices on OpenBSD requires root privileges
* Fix bssid formatting (Wifi, Linux)
* Fix Linux Lite distro detection (#1434, OS, Linux)
* Suppress XE driver warnings from Mesa (#1435, OpenGL, Linux)
* Fix format parameter name (#1443, Version)
* Don't report useless information when Wifi is disabled (Wifi, FreeBSD)
* Currently there are issues when the SSID contains whitespaces. More fixes are expected in the future.
* Always use physical size reported by X11 server to avoid inconsistent results (#1444, Display, Linux)
Features:
* Randomly select one if the logo source expands to multiple files (#1426, Logo)
* Report mac product name when running Linux in MacBook (Host, Linux / FreeBSD)
* Use screen size reported in DTD if make sense (Display)
* Detect Virtualized Apple Silicon CPUs (CPU, Linux)
* Add detection support for fvwm and ctwm (WM, OpenBSD / NetBSD)
* Add Armbian-unofficial detection (OS, Linux)
* Prefer surfaceless display when connect EGL (OpenGL)
* Improve accuracy of WM detection on FreeBSD (WM, FreeBSD)
* Add ratpoison window manager (WM, Linux)
Logo:
* Update Linux Lite
* Add Serpent OS
* Add Ultramarine Small
* Update Debian
# 2.31.0
Bugfixes:
* Improve performance of media detection; fix musikcube detection (Media, Linux)
* After the change, `general.processingTimeout` will also control the timeout of dbus remote calls
* Fix invalid variable names (#1408, Users)
* Change physical size detection to use basic display parameters (#1406)
* Fix possible sigfaults when detecting displays (#1393)
* Fix Nvidia card type detection
* Fix wl-restart parsing (#1422, WM, Linux)
* Fix syntax error in completion file (#1421)
* Fix hunging when using `ssh-agent` as command text (#1418, Command, macOS)
Features:
* Remove support of xcb & xlib and xrandr extension is always required (Display)
* Support preferred resolution & refresh rate detection
* On macOS there is no preferred resolution reported and maximum available resolution is reported instead.
* `--display-format {preferred-width}x{preferred-height}@{preferred-refresh-rate}`
* Report scale factor in custom format (Display)
* `--display-format {scale-factor}`
* Detect current Wi-Fi channel and maximum frequency (Wifi)
* Report processor package count (#1413, CPU)
* Remove duplicate whitespaces in CPU name
* Support sakura terminal version & font detection (Terminal / TerminalFont, Linux)
Logo:
* Fix LMDE
* Update MidOS
* Add Windows Server 2025
# 2.30.1
Bugfixes:
* Fix the destination where `fastfetch.1` is generated (#1403)
# 2.30.0
Changes:
* Percent: bar type must be enabled in `percent.type` before using percent bar in custom format
Features:
* Port to MidnightBSD; add mport package manager support
* Support bluetooth battery detection for macOS and Windows (Bluetooth, macOS / Windows)
* Support M4 model detection (Host, macOS)
* Support CPU temperature detection on OpenBSD (CPU, OpenBSD)
* Display Android icon in Android devices (OS, Android)
* Support qi package manager detection (Packages, Linux)
* Detect WM / DE by enumerating running processes (WM / DE, NetBSD)
* Generate manual pages from `help.json` (Doc)
* Detect marketing name of vivo smartphone (Host, Android)
* Add txDrops detection if supported (NetIO, *BSD)
* Support tilix version detection (Terminal, Linux)
* Support percent type config in module level. Example:
```json
{
"type": "memory",
"percent": {
"green": 20, // [0%, 20%) will be displayed in green
"yellow": 40, // [20, 40) will be displayed in yellow and [40, 100] will be displayed in red
"type": [ // Display percent value in monochrome bar, same as 10
"bar",
"bar-monochrome"
]
}
}
```
Bugfixes:
* Don't display `()` in key if display name is not available (Display)
* Fix & normalize bluetooth mac address detection (Bluetooth, macOS / Windows)
* Don't print index in multi-battery devices (Battery)
* Fix segfault in macOS (#1388, macOS)
* Fix `CFStringGetCString() failed` errors (#1394, Media, macOS)
* Fix CPU frequency detection on Apple M4 (#1394, CPU, macOS)
* Fix exe path detection on macOS (Shell / Terminal, macOS)
* Fix logo fails to load from symlinked files on macOS (#1395, Logo, macOS)
* Fix 32-bit truncation (NetIO, macOS)
Logos:
* Fix Lilidog
* Add MidnightBSD
* Add Unifi
* Add Cosmic DE
* Update openSUSE Tumbleweed
# 2.29.0
Changes:
* Due to [the upstream removal of MSYS2 CLANG32 environment](https://www.msys2.org/news/#2024-09-23-starting-to-drop-the-clang32-environment), we dropped fastfetch-windows-i686 support. v2.27.1 was the last version supporting it.
* Note: fastfetch built with MSVCRT has known bug that DateTime module doesn't work because of its bad support of [strftime](https://en.cppreference.com/w/c/chrono/strftime). Don't use it.
Features:
* Port to NetBSD and DragonFly BSD
* Fastfetch now supports all major BSD variants
* Support DiskIO, NetIO, GPU and Users module on OpenBSD
* Report SD8E SOC name (CPU, Android)
* On Windows, try loading dlls from current exe path (Windows)
* Fix Media module when installed with winget
Bugfixes:
* Fix the VIM version detection on Ubuntu (Editor, Linux)
* Improve performance of OS version detection on Proxmox (#1370, OS, Linux)
Logo:
* Update OpenSuse Tumbleweed
* Add XCP-ng
* Add SummitOS
* Add Lilidog
* Update PikaOS
* Update OpenSUSE Leap
* Update aperture
# 2.28.0
Features:
+274 -80
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.28.0
VERSION 2.34.1
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -20,6 +20,14 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
set(OpenBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "MidnightBSD")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
set(MidnightBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "NetBSD")
set(NetBSD TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
set(FreeBSD TRUE CACHE BOOL "..." FORCE)
set(DragonFly TRUE CACHE BOOL "..." FORCE)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
set(SunOS TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
@@ -46,39 +54,39 @@ include(CheckIncludeFile)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR APPLE OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR APPLE OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS" OFF)
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD OR NetBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD OR SunOS" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
option(BUILD_FLASHFETCH "Build flashfetch" ON) # Also build the flashfetch binary
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
@@ -247,6 +255,7 @@ endfunction(fastfetch_load_text)
find_package(Python)
if(Python_FOUND)
message(STATUS "Minifying 'help.json'")
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
@@ -254,20 +263,39 @@ if(Python_FOUND)
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
endif()
else()
message(STATUS "Python3 is not found, 'help.json' will not be minified")
message(WARNING "Python3 is not found, 'help.json' will not be minified")
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
endif()
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "fastfetch_pciids.c.inc")
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc")
if(Python_FOUND)
message(STATUS "Generating 'fastfetch_pciids.c.inc'")
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py"
OUTPUT_FILE "fastfetch_pciids.c.inc")
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch_pciids.c.inc"
RESULT_VARIABLE PYTHON_PCIIDS_RETCODE)
if(NOT PYTHON_PCIIDS_RETCODE EQUAL 0)
message(FATAL_ERROR "Failed to generate 'fastfetch_pciids.c.inc'")
endif()
else()
message(STATUS "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
message(WARNING "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
set(ENABLE_EMBEDDED_PCIIDS OFF)
endif()
endif()
if(Python_FOUND)
message(STATUS "Generating 'fastfetch.1'")
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-man.py"
OUTPUT_FILE "${PROJECT_BINARY_DIR}/fastfetch.1"
RESULT_VARIABLE PYTHON_MANPAGE_RETCODE)
if(NOT PYTHON_MANPAGE_RETCODE EQUAL 0)
message(FATAL_ERROR "Failed to generate 'fastfetch.1'")
endif()
else()
message(WARNING "Python3 is not found, use basic 'fastfetch.1.in' instead")
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/help_footer.txt DATATEXT_HELP_FOOTER)
@@ -280,9 +308,6 @@ if(APPLE)
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
endif()
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
####################
# Ascii image data #
####################
@@ -478,6 +503,7 @@ if(LINUX)
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/host/host_mac.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_linux.c
@@ -508,7 +534,7 @@ if(LINUX)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_linux.c
src/detection/wm/wm_nosupport.c
src/detection/wm/wm_linux.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
@@ -591,8 +617,7 @@ elseif(FreeBSD)
src/common/sysctl.c
src/detection/battery/battery_bsd.c
src/detection/bios/bios_bsd.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/bluetoothradio/bluetoothradio_linux.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_bsd.c
src/detection/bootmgr/bootmgr_bsd.c
src/detection/brightness/brightness_bsd.c
@@ -625,6 +650,7 @@ elseif(FreeBSD)
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c
src/detection/host/host_mac.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
@@ -663,7 +689,16 @@ elseif(FreeBSD)
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(OpenBSD)
if(DragonFly)
list(APPEND LIBFASTFETCH_SRC
src/detection/bluetooth/bluetooth_nosupport.c
)
else()
list(APPEND LIBFASTFETCH_SRC
src/detection/bluetooth/bluetooth_bsd.c
)
endif()
elseif(NetBSD)
list(APPEND LIBFASTFETCH_SRC
src/common/dbus.c
src/common/io/io_unix.c
@@ -671,16 +706,16 @@ elseif(OpenBSD)
src/common/networking_linux.c
src/common/processing_linux.c
src/common/sysctl.c
src/detection/battery/battery_nosupport.c
src/detection/bios/bios_nosupport.c
src/detection/battery/battery_nbsd.c
src/detection/bios/bios_nbsd.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_nosupport.c
src/detection/board/board_nbsd.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_nosupport.c
src/detection/brightness/brightness_nbsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_obsd.c
src/detection/chassis/chassis_nbsd.c
src/detection/cpu/cpu_nbsd.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
@@ -688,7 +723,7 @@ elseif(OpenBSD)
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_nosupport.c
src/detection/diskio/diskio_nbsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
@@ -703,7 +738,90 @@ elseif(OpenBSD)
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_nosupport.c
src/detection/gpu/gpu_general.c
src/detection/gpu/gpu_pci.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_nbsd.c
src/detection/lm/lm_linux.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_nosupport.c
src/detection/libc/libc_nosupport.c
src/detection/loadavg/loadavg_bsd.c
src/detection/locale/locale_linux.c
src/detection/localip/localip_linux.c
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_nbsd.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_nbsd.c
src/detection/packages/packages_obsd.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_nbsd.c
src/detection/gtk_qt/qt.c
src/detection/sound/sound_linux.c
src/detection/swap/swap_obsd.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(OpenBSD)
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
src/detection/battery/battery_obsd.c
src/detection/bios/bios_nosupport.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_nosupport.c
src/detection/bootmgr/bootmgr_nosupport.c
src/detection/brightness/brightness_obsd.c
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_nosupport.c
src/detection/cpu/cpu_obsd.c
src/detection/cpucache/cpucache_nosupport.c
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/dns/dns_linux.c
src/detection/physicaldisk/physicaldisk_nosupport.c
src/detection/physicalmemory/physicalmemory_nosupport.c
src/detection/diskio/diskio_obsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
src/detection/displayserver/linux/wayland/wayland.c
src/detection/displayserver/linux/wayland/global-output.c
src/detection/displayserver/linux/wayland/zwlr-output.c
src/detection/displayserver/linux/wayland/kde-output.c
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
src/detection/displayserver/linux/wmde.c
src/detection/displayserver/linux/xcb.c
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_pci.c
src/detection/gpu/gpu_general.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_obsd.c
src/detection/lm/lm_nosupport.c
@@ -718,7 +836,7 @@ elseif(OpenBSD)
src/detection/media/media_linux.c
src/detection/memory/memory_obsd.c
src/detection/mouse/mouse_nosupport.c
src/detection/netio/netio_nosupport.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_obsd.c
src/detection/packages/packages_obsd.c
@@ -733,13 +851,13 @@ elseif(OpenBSD)
src/detection/theme/theme_linux.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_nosupport.c
src/detection/users/users_obsd.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
@@ -774,6 +892,7 @@ elseif(APPLE)
src/detection/gpu/gpu_apple.c
src/detection/gpu/gpu_apple.m
src/detection/host/host_apple.c
src/detection/host/host_mac.c
src/detection/icons/icons_nosupport.c
src/detection/initsystem/initsystem_linux.c
src/detection/keyboard/keyboard_apple.c
@@ -786,7 +905,7 @@ elseif(APPLE)
src/detection/media/media_apple.m
src/detection/memory/memory_apple.c
src/detection/mouse/mouse_apple.c
src/detection/netio/netio_bsd.c
src/detection/netio/netio_apple.c
src/detection/opengl/opengl_apple.c
src/detection/os/os_apple.m
src/detection/packages/packages_apple.c
@@ -803,7 +922,7 @@ elseif(APPLE)
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.m
src/detection/wifi/wifi_apple.m
src/detection/wm/wm_apple.c
src/detection/wm/wm_apple.m
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
@@ -823,6 +942,7 @@ elseif(WIN32)
src/detection/battery/battery_windows.c
src/detection/bios/bios_windows.c
src/detection/bluetooth/bluetooth_windows.c
src/detection/bluetooth/bluetooth_windows.cpp
src/detection/bluetoothradio/bluetoothradio_windows.c
src/detection/board/board_windows.c
src/detection/bootmgr/bootmgr_windows.c
@@ -841,6 +961,7 @@ elseif(WIN32)
src/detection/dns/dns_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/host/host_mac.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/initsystem/initsystem_nosupport.c
@@ -882,6 +1003,7 @@ elseif(WIN32)
src/util/windows/registry.c
src/util/windows/unicode.c
src/util/windows/wmi.cpp
src/util/windows/version.c
src/util/platform/FFPlatform_windows.c
src/util/binary_windows.c
)
@@ -1020,6 +1142,14 @@ else()
endif()
endif()
if(ANDROID)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib64 -Wl,-rpath,/system/lib64")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/vendor/lib -Wl,-rpath,/system/lib")
endif()
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)
@@ -1034,26 +1164,58 @@ if(APPLE AND EXISTS "/usr/bin/otool")
target_compile_definitions(libfastfetch PUBLIC FF_LIBSYSTEM_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(FreeBSD 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"
if(MidnightBSD AND EXISTS "/usr/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
message(STATUS "Found FBSD ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
elseif(FreeBSD AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'FBSD_[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "FBSD_([0-9]+\\.[0-9]+)")
message(STATUS "Found FBSD ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_FBSD_VERSION="${CMAKE_MATCH_1}")
endif()
elseif(DragonFly AND EXISTS "/usr/local/bin/objdump")
execute_process(COMMAND /bin/sh -c "/usr/local/bin/objdump -T /lib/libc.so.* | grep 'DF[0-9][0-9]*\\.[0-9][0-9]*' -o | sort -Vru | head -1"
OUTPUT_VARIABLE OBJDUMP_T_RESULT)
if("${OBJDUMP_T_RESULT}" MATCHES "DF([0-9]+\\.[0-9]+)")
message(STATUS "Found DF ${CMAKE_MATCH_1}")
target_compile_definitions(libfastfetch PUBLIC FF_DF_VERSION="${CMAKE_MATCH_1}")
endif()
endif()
if(LINUX)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _ATFILE_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _ATFILE_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _TIME_BITS=64) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
elseif(ANDROID)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE _FILE_OFFSET_BITS=64 "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY>" "$<$<CONFIG:DEBUG>:__BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED>")
elseif(WIN32)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN=1 _WIN32_WINNT=0x0A00) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 NOMINMAX UNICODE) # "$<$<CONFIG:Release>:_FORTIFY_SOURCE=3>"
elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 _DARWIN_C_SOURCE)
elseif(OpenBSD)
target_compile_definitions(libfastfetch PUBLIC _XOPEN_SOURCE=700 _FILE_OFFSET_BITS=64 _BSD_SOURCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R6/lib") # detect x11 lib path automatically
elseif(DragonFly)
target_compile_definitions(libfastfetch PUBLIC __FreeBSD__)
elseif(SunOS)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
elseif(NetBSD)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-char-subscripts")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,/usr/X11R7/lib -Wl,-rpath,/usr/pkg/lib") # ditto
endif()
if(FreeBSD OR OpenBSD OR NetBSD)
include(CheckStructHasMember)
set(CMAKE_REQUIRED_DEFINITIONS "-D_IFI_OQDROPS=1")
CHECK_STRUCT_HAS_MEMBER("struct if_data" ifi_oqdrops net/if.h HAVE_IFI_OQDROPS LANGUAGE C)
if(HAVE_IFI_OQDROPS)
target_compile_definitions(libfastfetch PUBLIC _IFI_OQDROPS FF_HAVE_IFI_OQDROPS)
endif()
unset(CMAKE_REQUIRED_DEFINITIONS)
endif()
if(HAVE_STATX)
@@ -1080,6 +1242,9 @@ endif()
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
message(STATUS "Enabling custom link type: ${BINARY_LINK_TYPE}")
target_compile_definitions(libfastfetch PRIVATE FF_DISABLE_DLOPEN=1)
if(NOT WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--copy-dt-needed-entries")
endif()
endif()
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
@@ -1135,18 +1300,10 @@ ff_lib_enable(XCB_RANDR
"xcb-randr"
"XcbRandr"
)
ff_lib_enable(XCB
"xcb"
"Xcb"
)
ff_lib_enable(XRANDR
"xrandr"
"XRandr"
)
ff_lib_enable(X11
"x11"
"X11"
)
ff_lib_enable(DRM
"libdrm"
"Libdrm"
@@ -1199,7 +1356,7 @@ ff_lib_enable(EGL
"egl"
"EGL"
)
if(NOT OpenBSD)
if(NOT OpenBSD AND NOT NetBSD)
ff_lib_enable(GLX
"glx"
"GLX"
@@ -1238,6 +1395,10 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
ff_lib_enable(PCIACCESS
"pciaccess"
"pciaccess"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
@@ -1318,18 +1479,33 @@ elseif(WIN32)
PRIVATE "imagehlp"
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
)
elseif(FreeBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "usbhid"
PRIVATE "geom"
PRIVATE "bluetooth"
)
if(NOT DragonFly)
target_link_libraries(libfastfetch
PRIVATE "geom"
)
else()
target_link_libraries(libfastfetch
PRIVATE "devstat"
)
endif()
elseif(OpenBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "kvm"
)
elseif(NetBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "prop"
)
elseif(SunOS)
target_link_libraries(libfastfetch
PRIVATE "m"
@@ -1382,9 +1558,9 @@ if(WIN32)
set(CMAKE_CXX_STANDARD 17)
endif()
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
if(LINUX OR FreeBSD)
if(LINUX OR FreeBSD OR OpenBSD OR NetBSD)
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
if(HAVE_LINUX_VIDEODEV2)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
@@ -1455,41 +1631,52 @@ target_link_libraries(fastfetch
PRIVATE libfastfetch
)
add_executable(flashfetch
src/flashfetch.c
)
target_compile_definitions(flashfetch
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
)
target_link_libraries(flashfetch
PRIVATE libfastfetch
)
# 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)
target_sources(fastfetch
PRIVATE src/util/windows/version.rc
)
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()
if(BINARY_LINK_TYPE STREQUAL "static")
target_link_options(fastfetch PRIVATE "-static")
target_link_options(flashfetch PRIVATE "-static")
endif()
# Apply all above parameters to flashfetch if it is built
if (BUILD_FLASHFETCH)
add_executable(flashfetch
src/flashfetch.c
)
target_compile_definitions(flashfetch
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
)
target_link_libraries(flashfetch
PRIVATE libfastfetch
)
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
if(WIN32)
target_sources(flashfetch
PRIVATE src/util/windows/version.rc
)
elseif(APPLE)
target_link_options(flashfetch
PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,Info.plist
)
endif()
if(BINARY_LINK_TYPE STREQUAL "static")
target_link_options(flashfetch PRIVATE "-static")
endif()
endif()
###################
@@ -1531,10 +1718,17 @@ endif()
include(GNUInstallDirs)
install(
TARGETS fastfetch flashfetch
TARGETS fastfetch
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
if (TARGET flashfetch)
install(
TARGETS flashfetch
DESTINATION "${CMAKE_INSTALL_BINDIR}"
)
endif()
if (TARGET ffwinrt)
install(
TARGETS ffwinrt
+34 -2
View File
@@ -40,7 +40,6 @@ Some distros package an outdated fastfetch version. Older versions receive no su
* openSUSE: `zypper install fastfetch`
* ALT Linux: `apt-get install fastfetch`
* Exherbo: `cave resolve --execute app-misc/fastfetch`
* GNU Guix: `guix install fastfetch`
* Solus: `eopkg install fastfetch`
* Slackware: `sbopkg -i fastfetch`
* Void Linux: `xbps-install fastfetch`
@@ -194,16 +193,49 @@ See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
Neofetch incorrectly counts `rc` packages ( the package has been removed, but that the configuration files remain ). Bug https://github.com/dylanaraps/neofetch/issues/2278
### Q: I use Debian / Ubuntu / Debian deserved distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug?
### Q: I use Debian / Ubuntu / Debian derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug?
Try upgrading `pci.ids`: Download <https://pci-ids.ucw.cz/v2.2/pci.ids> and overwrite file `/usr/share/hwdata/pci.ids`. For AMD GPUs, you should also upgrade `amdgpu.ids`: Download <https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids> and overwrite file `/usr/share/libdrm/amdgpu.ids`
Alternatively, you may try to use `fastfetch --gpu-driver-specific`, so that `fastfetch` will try to ask the driver for GPU name if supported.
### Q: I get error `Authorization required, but no authorization protocol specified` when running fastfetch in root
Try `export XAUTHORITY=$HOME/.Xauthority`
### Q: Fastfetch cannot detect my awesome 3rd-party macOS window manager!
Try `fastfetch --wm-detect-plugin`. See also [#984](https://github.com/fastfetch-cli/fastfetch/issues/984)
### Q: How can I change the colors of my ASCII logo?
Try `fastfetch --logo-color-[1-9] <color>`. `[1-9]` is the index of color placeholders.
For example: `fastfetch --logo-color-1 red --logo-color-2 green`.
In JSONC, you can use:
```jsonc
{
"logo": {
"color": {
"1": "red",
"2": "green"
}
}
}
```
### Q: How to hide a key?
Set the key to a white space.
```jsonc
{
"key": " "
}
```
### Q: I want feature A / B / C. Will fastfetch support it?
Fastfetch is a system information tool. We only accept hardware or system level software feature requests. For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
+3 -3
View File
@@ -26,7 +26,7 @@ def main():
for flag in data[key]:
if flag["long"] == "logo-color-[1-9]":
for i in range(1, 10):
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
command_prefix = f"--logo-color-{i}[{flag['desc']} ({i})]"
print_command(command_prefix, flag)
continue
@@ -34,11 +34,11 @@ def main():
continue
if "short" in flag:
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
command_prefix = f"-{flag['short']}[{flag['desc']}]"
print_command(command_prefix, flag)
if "long" in flag:
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
command_prefix = f"--{flag['long']}[{flag['desc']}]"
print_command(command_prefix, flag)
+48
View File
@@ -1,3 +1,51 @@
fastfetch (2.34.0) jammy; urgency=medium
* Update to 2.34.0
-- Carter Li <zhangsongcui@live.cn> Thu, 09 Jan 2025 09:03:17 +0800
fastfetch (2.33.0) jammy; urgency=medium
* Update to 2.33.0
-- Carter Li <zhangsongcui@live.cn> Thu, 26 Dec 2024 09:42:27 +0800
fastfetch (2.32.0) jammy; urgency=medium
* Update to 2.32.0
-- Carter Li <zhangsongcui@live.cn> Wed, 18 Dec 2024 10:39:06 +0800
fastfetch (2.31.0) jammy; urgency=medium
* Update to 2.31.0
-- Carter Li <zhangsongcui@live.cn> Wed, 04 Dec 2024 08:41:40 +0800
fastfetch (2.30.1) jammy; urgency=medium
* Update to 2.30.1
-- Carter Li <zhangsongcui@live.cn> Mon, 18 Nov 2024 15:40:48 +0800
fastfetch (2.30.0) jammy; urgency=medium
* Update to 2.30.0
-- Carter Li <zhangsongcui@live.cn> Mon, 18 Nov 2024 09:30:58 +0800
fastfetch (2.29.0) jammy; urgency=medium
* Update to 2.29.0
-- Carter Li <zhangsongcui@live.cn> Mon, 04 Nov 2024 15:05:02 +0800
fastfetch (2.28.0) jammy; urgency=medium
* Update to 2.28.0
-- Carter Li <zhangsongcui@live.cn> Wed, 23 Oct 2024 10:18:59 +0800
fastfetch (2.27.1) jammy; urgency=medium
* Update to 2.27.1
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.27.1_source.buildinfo universe/utils optional
fastfetch_2.34.0_source.buildinfo universe/utils optional
+1444 -248
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -87,8 +87,8 @@
"opengl",
"opencl",
"users",
"bluetooth",
"bluetoothradio",
// "bluetooth", // doesn't work on macOS because it requires bluetooth permissions
// "bluetoothradio",
"sound",
"camera",
"gamepad",
+258
View File
@@ -0,0 +1,258 @@
#!/usr/bin/env python3
"""
Python script to generate a man page for the command `fastfetch`.
The man content will be printed to stdout so you will need to
pipe it to a file if you want to save it.
The command options will be generated using a JSON file.
For the format of the JSON file, see https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json
"""
from json import load
from datetime import datetime, timezone
from time import time
from re import search
from os import environ, path
###### Text Decorations Tags ######
startUnderline = r"\fI" # start underline text tag
endUnderline = r"\fR" # end underline text tag
startBold = r"\fB" # start bold text tag
endBold = r"\fR" # end bold text tag
###### Parameters ######
# path to the current directory
pathToCurrentDir = path.dirname(__file__)
# path to the JSON option file
pathToHelpFile = path.join(pathToCurrentDir, "../src/data/help.json")
# man page section
manSection = 1
# title (center header)
titlePage = "Fastfetch man page"
# date (center footer)
# format : "Month (abbreviation) Day Year"
todayDate = datetime.fromtimestamp(
int(environ.get("SOURCE_DATE_EPOCH", time())),
tz=timezone.utc,
).strftime("%b %d %Y")
# file to fastfetch version (left footer)
pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt")
###### Sections Text ######
# text displayed in the "NAME" section
nameSection = r"fastfetch \- A maintained, feature\-rich and performance oriented, neofetch like system information tool"
# text displayed at the beginning of the "OPTIONS" section
optionSection = r"""
Parsing is not case sensitive. E.g. \fB--logo-type\fR is
equal to \fB--LOGO-TYPE\fR.
If a value is between square brackets, it is optional.
An optional boolean value defaults to true if not specified.
More detailed help messages for each options can be printed
with \fB-h <option_without_dash_prefix>\fR.
All options can be made permanent with command
\fBfastfetch <options> --gen-config\fR.
"""
# text displayed in the "CONFIGURATION"
configurationSection = f"""
.SS Fetch Structure
The structure of a fetch describes the modules that should
be included in the output. It consists of a string of modules,
separated by a colon (:). To list all available modules,
use --list-modules.
.SS Config Files
Fastfetch uses JSONC based format for configuration.
Fastfetch doesn't generate config file automatically;
it should be generated manually by {startBold}--gen-config{endBold}.
The config file will be saved in
{startBold}~/.config/fastfetch/config.jsonc{endBold} by default.
A JSONC config file is a JSON file that also supports comments
with (// and /* */). Those files must have the extension '.jsonc'.
The specified configuration/preset files are searched in the following order:
{startBold}1.{endBold} relative to the current working directory
{startBold}2.{endBold} relative to ~/.local/share/fastfetch/presets/
{startBold}3.{endBold} relative to /usr/share/fastfetch/presets/
Fastfetch provides some default presets. List them with --list-presets.
"""
# text displayed in the "EXAMPLE" section
exampleSection = """
.SS Config files:
.nf
// ~/.config/fastfetch/config.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
"title",
"separator",
"module1",
{
"type": "module2",
"module2-option": "value"
}
]
}
.fi
"""
# text displayed in the "BUGS" section
bugSection = "Please report bugs to : \
https://github.com/fastfetch-cli/fastfetch/issues"
# text displayed in the "WIKI" section
wikiSection = "Fastfetch github wiki : https://github.com/fastfetch-cli/fastfetch/wiki/Configuration"
###### Argument decoration ######
### optional arguments tags ###
# if an optional argument is displayed as [?optArg] (with "optArg" underlined)
# this value should be f"[?{startUnderline}"
startOptionalArgument = f"[{startUnderline}?"
# if an optional argument is displayed as [?optArg] (with "optArg underlined")
# this value should be f"{endUnderline}]"
endOptionalArgument = f"{endUnderline}]"
### mandatory arguments tags ###
startMandatoryArgument = f"{startUnderline}"
endMandatoryArgument = f"{endUnderline}"
def main():
# importing the JSON file
with open(pathToHelpFile, 'r') as jsonFile:
helpFileData = load(jsonFile) # json.load
######## Start printing the generated .1 file ########
###### header, footer & config #####
print(f".TH FASTFETCH {manSection} ", end=" ")
print(f"\"{todayDate}\"", end=" ")
# version number
with open(pathToVersionFile, 'r') as versionFile:
# research version number in file with regex
for line in versionFile:
researchVersion = search(r"^\s*VERSION (\d+\.\d+\.\d+)$", line)
if (researchVersion):
print(f"\"{researchVersion.group(1)}\"", end=" ")
break
print(f"\"{titlePage}\"")
###### Name ######
print(".SH NAME")
print(nameSection)
##### Synopsis ######
print(".SH SYNOPSIS")
print(".B fastfetch")
print(f"[{startUnderline}OPTIONS{endUnderline}]")\
###### Wiki ######
print(".SH WIKI")
print(wikiSection)
###### Configuration ######
print(".SH CONFIGURATION")
print(configurationSection)
###### Options ######
print(".SH OPTIONS")
print(optionSection)
print()
# loop through every options sections
for key, value in helpFileData.items():
# print new subsection
print(f".SS {key}:")
# loop through every option in a section
for option in value:
# list of existing keys for this option
keyList = option.keys()
# start a new "option" entry
print(".TP")
print(startBold, end="")
# short option (-opt)
if "short" in keyList:
print(fr"\-{ option['short'] }", end="")
# if also have a long option, print a comma
if "long" in keyList:
print(", ", end="")
# long option (--option)
if "long" in keyList:
print(fr"\-\-{ option['long'] }", end="")
print(endBold, end=" ")
# arguments
if "arg" in keyList:
# if argument is optional, print "[arg]"
if "optional" in option["arg"].keys() and option["arg"]["optional"]:
print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="")
# if argument is mandatory, print "arg"
else:
print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="")
# description
print(f"\n {option['desc']} \n")
###### Examples ######
print(".SH EXAMPLES")
print(exampleSection)
###### Bugs ######
print(".SH BUGS")
print(bugSection)
if __name__ == "__main__":
main()
Regular → Executable
+2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python3
from requests import get as http_get
class PciDeviceModel:
+2 -2
View File
@@ -171,7 +171,7 @@ DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const c
if (arg)
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
dbus->lib->ffdbus_message_unref(message);
@@ -189,7 +189,7 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
DBUS_TYPE_STRING, &property,
DBUS_TYPE_INVALID);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, FF_DBUS_TIMEOUT_MILLISECONDS, NULL);
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
dbus->lib->ffdbus_message_unref(message);
+5 -2
View File
@@ -6,8 +6,6 @@
#include "util/FFstrbuf.h"
#include "common/library.h"
#define FF_DBUS_TIMEOUT_MILLISECONDS 100
typedef struct FFDBusLibrary
{
FF_LIBRARY_SYMBOL(dbus_bus_get)
@@ -38,4 +36,9 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface)
{
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface);
}
#endif // FF_HAVE_DBUS
+5 -5
View File
@@ -51,7 +51,7 @@ static void fontInitPretty(FFfont* font)
for(uint32_t i = 0; i < font->styles.length; i++)
{
ffStrbufAppend(&font->pretty, ffListGet(&font->styles, i));
ffStrbufAppend(&font->pretty, FF_LIST_GET(FFstrbuf, font->styles, i));
if(i < font->styles.length - 1)
ffStrbufAppendS(&font->pretty, ", ");
@@ -86,7 +86,7 @@ void ffFontInitQt(FFfont* font, const char* data)
{
do
{
FFstrbuf* style = ffListAdd(&font->styles);
FFstrbuf* style = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) data++;
@@ -142,7 +142,7 @@ static void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* altern
) {
if(alternativeBuffer == NULL)
{
alternativeBuffer = ffListAdd(&font->styles);
alternativeBuffer = (FFstrbuf*) ffListAdd(&font->styles);
ffStrbufInit(alternativeBuffer);
}
@@ -215,7 +215,7 @@ void ffFontDestroy(FFfont* font)
ffStrbufDestroy(&font->name);
ffStrbufDestroy(&font->size);
for(uint32_t i = 0; i < font->styles.length; i++)
ffStrbufDestroy(ffListGet(&font->styles, i));
FF_LIST_FOR_EACH(FFstrbuf, str, font->styles)
ffStrbufDestroy(str);
ffListDestroy(&font->styles);
}
+3 -3
View File
@@ -42,10 +42,10 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
break;
case FF_FORMAT_ARG_TYPE_LIST:
{
const FFlist* list = formatarg->value;
const FFlist* list = (const FFlist*) formatarg->value;
for(uint32_t i = 0; i < list->length; i++)
{
ffStrbufAppend(buffer, ffListGet(list, i));
ffStrbufAppend(buffer, FF_LIST_GET(FFstrbuf, *list, i));
if(i < list->length - 1)
ffStrbufAppendS(buffer, ", ");
}
@@ -110,7 +110,7 @@ static inline bool formatArgSet(const FFformatarg* arg)
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) || //Also is false for NaN
(arg->type == FF_FORMAT_ARG_TYPE_INT && *(int*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) ||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet((char*)arg->value)) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
+3 -5
View File
@@ -2,7 +2,7 @@
#include "util/FFstrbuf.h"
typedef enum FFformatArgType
typedef enum __attribute__((__packed__)) FFformatArgType
{
FF_FORMAT_ARG_TYPE_NULL = 0,
FF_FORMAT_ARG_TYPE_UINT,
@@ -42,7 +42,5 @@ typedef struct FFformatarg
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*arguments) == (numArgs), "Invalid number of format arguments");\
ffParseFormatString((buffer), (formatstr), (numArgs), (arguments));\
} while (0)
#define FF_PARSE_FORMAT_STRING_CHECKED(buffer, formatstr, arguments) \
ffParseFormatString((buffer), (formatstr), sizeof(arguments) / sizeof(*arguments), (arguments));
+8 -11
View File
@@ -76,19 +76,21 @@ static void resetConsole(void)
}
#ifdef _WIN32
BOOL WINAPI consoleHandler(DWORD signal)
BOOL WINAPI consoleHandler(FF_MAYBE_UNUSED DWORD signal)
{
FF_UNUSED(signal);
resetConsole();
exit(0);
}
#else
static void exitSignalHandler(int signal)
static void exitSignalHandler(FF_MAYBE_UNUSED int signal)
{
FF_UNUSED(signal);
resetConsole();
exit(0);
}
static void chldSignalHandler(FF_MAYBE_UNUSED int signal)
{
// empty; used to interrupt the poll and read syscalls
}
#endif
void ffStart(void)
@@ -118,6 +120,7 @@ void ffStart(void)
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
sigaction(SIGQUIT, &action, NULL);
sigaction(SIGCHLD, &(struct sigaction) { .sa_handler = chldSignalHandler }, NULL);
#endif
//reset everything to default before we start printing
@@ -179,15 +182,9 @@ void ffListFeatures(void)
#if FF_HAVE_XCB_RANDR
"xcb-randr\n"
#endif
#if FF_HAVE_XCB
"xcb\n"
#endif
#if FF_HAVE_XRANDR
"xrandr\n"
#endif
#if FF_HAVE_X11
"x11\n"
#endif
#if FF_HAVE_DRM
"drm\n"
#endif
@@ -245,7 +242,7 @@ void ffListFeatures(void)
#if FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#if FF_HAVE_ELF || __sun || __FreeBSD__ || __OpenBSD__
#if FF_HAVE_ELF || __sun || (__FreeBSD__ && !__DragonFly__) || __OpenBSD__ || __NetBSD__
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
+16 -1
View File
@@ -87,11 +87,12 @@ static inline bool ffReadFileBufferRelative(FFNativeFD dfd, const char* fileName
}
//Bit flags, combine with |
typedef enum FFPathType
typedef enum __attribute__((__packed__)) FFPathType
{
FF_PATHTYPE_FILE = 1 << 0,
FF_PATHTYPE_DIRECTORY = 1 << 1,
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
FF_PATHTYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFPathType;
static inline bool ffPathExists(const char* path, FFPathType pathType)
@@ -118,6 +119,19 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
}
else
{
#if __APPLE__ // #1395
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
unsigned int mode = fileStat.st_mode & S_IFMT;
if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
return true;
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
#else
size_t len = strlen(path);
assert(len < PATH_MAX);
if (len == 0) return false;
@@ -134,6 +148,7 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
else
ret = access(path, F_OK);
return pathType == FF_PATHTYPE_DIRECTORY ? ret == 0 : ret == -1 && errno == ENOTDIR;
#endif
}
#endif
+5 -4
View File
@@ -1,6 +1,7 @@
#include "io.h"
#include "fastfetch.h"
#include "util/stringUtils.h"
#include "common/time.h"
#include <fcntl.h>
#include <termios.h>
@@ -145,10 +146,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
if (wordexp(in, &exp, 0) != 0)
return false;
if (exp.we_wordc == 1)
if (exp.we_wordc >= 1)
{
result = true;
ffStrbufSetS(out, exp.we_wordv[0]);
ffStrbufSetS(out, exp.we_wordv[exp.we_wordc > 1 ? ffTimeGetNow() % exp.we_wordc : 0]);
}
wordfree(&exp);
@@ -159,10 +160,10 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
return false;
if (gb.gl_matchc == 1)
if (gb.gl_matchc >= 1)
{
result = true;
ffStrbufSetS(out, gb.gl_pathv[0]);
ffStrbufSetS(out, gb.gl_pathv[gb.gl_matchc > 1 ? ffTimeGetNow() % gb.gl_matchc : 0]);
}
globfree(&gb);
+11
View File
@@ -29,6 +29,17 @@ static void* libraryLoad(const char* path, int maxVersion)
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
FF_UNUSED(maxVersion)
if(result != NULL)
return result;
uint32_t pathLen = ffStrbufLastIndexC(&instance.state.platform.exePath, '/');
if (pathLen == instance.state.platform.exePath.length)
return result;
char absPath[MAX_PATH + 1];
strcpy(mempcpy(absPath, instance.state.platform.exePath.chars, pathLen + 1), path);
return dlopen(absPath, FF_DLOPEN_FLAGS);
#else
if(result != NULL || maxVersion < 0)
-20
View File
@@ -43,11 +43,6 @@ static inline void ffLibraryUnload(void** handle)
if(symbolMapping == NULL) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = dlsym(library, #symbolName); \
if(symbolMapping == NULL && !(symbolMapping = (__typeof__(&symbolName)) dlsym(library, #alternateName))) \
return returnValue;
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
@@ -57,18 +52,12 @@ static inline void ffLibraryUnload(void** handle)
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
@@ -87,9 +76,6 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, symbolMapping, symbolName, alternateName, returnValue) \
symbolMapping = (__typeof__(&symbolName)) &symbolName
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
@@ -99,18 +85,12 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE2(library, symbolName, alternateName) \
FF_MAYBE_UNUSED __typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, returnValue);
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName).ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE2(library, varName, symbolName, alternateName) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS2(library, (varName).ff ## symbolName, symbolName, alternateName, "dlsym " #symbolName " failed");
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
+73 -73
View File
@@ -5,65 +5,65 @@ static FFModuleBaseInfo* A[] = {
};
static FFModuleBaseInfo* B[] = {
(void*) &instance.config.modules.battery,
(void*) &instance.config.modules.bios,
(void*) &instance.config.modules.bluetooth,
(void*) &instance.config.modules.bluetoothRadio,
(void*) &instance.config.modules.board,
(void*) &instance.config.modules.bootmgr,
(void*) &instance.config.modules.break_,
(void*) &instance.config.modules.brightness,
(void*) &instance.config.modules.btrfs,
(FFModuleBaseInfo*) &instance.config.modules.battery,
(FFModuleBaseInfo*) &instance.config.modules.bios,
(FFModuleBaseInfo*) &instance.config.modules.bluetooth,
(FFModuleBaseInfo*) &instance.config.modules.bluetoothRadio,
(FFModuleBaseInfo*) &instance.config.modules.board,
(FFModuleBaseInfo*) &instance.config.modules.bootmgr,
(FFModuleBaseInfo*) &instance.config.modules.break_,
(FFModuleBaseInfo*) &instance.config.modules.brightness,
(FFModuleBaseInfo*) &instance.config.modules.btrfs,
NULL,
};
static FFModuleBaseInfo* C[] = {
(void*) &instance.config.modules.camera,
(void*) &instance.config.modules.chassis,
(void*) &instance.config.modules.command,
(void*) &instance.config.modules.colors,
(void*) &instance.config.modules.cpu,
(void*) &instance.config.modules.cpuCache,
(void*) &instance.config.modules.cpuUsage,
(void*) &instance.config.modules.cursor,
(void*) &instance.config.modules.custom,
(FFModuleBaseInfo*) &instance.config.modules.camera,
(FFModuleBaseInfo*) &instance.config.modules.chassis,
(FFModuleBaseInfo*) &instance.config.modules.command,
(FFModuleBaseInfo*) &instance.config.modules.colors,
(FFModuleBaseInfo*) &instance.config.modules.cpu,
(FFModuleBaseInfo*) &instance.config.modules.cpuCache,
(FFModuleBaseInfo*) &instance.config.modules.cpuUsage,
(FFModuleBaseInfo*) &instance.config.modules.cursor,
(FFModuleBaseInfo*) &instance.config.modules.custom,
NULL,
};
static FFModuleBaseInfo* D[] = {
(void*) &instance.config.modules.dateTime,
(void*) &instance.config.modules.de,
(void*) &instance.config.modules.display,
(void*) &instance.config.modules.disk,
(void*) &instance.config.modules.diskIo,
(void*) &instance.config.modules.dns,
(FFModuleBaseInfo*) &instance.config.modules.dateTime,
(FFModuleBaseInfo*) &instance.config.modules.de,
(FFModuleBaseInfo*) &instance.config.modules.display,
(FFModuleBaseInfo*) &instance.config.modules.disk,
(FFModuleBaseInfo*) &instance.config.modules.diskIo,
(FFModuleBaseInfo*) &instance.config.modules.dns,
NULL,
};
static FFModuleBaseInfo* E[] = {
(void*) &instance.config.modules.editor,
(FFModuleBaseInfo*) &instance.config.modules.editor,
NULL,
};
static FFModuleBaseInfo* F[] = {
(void*) &instance.config.modules.font,
(FFModuleBaseInfo*) &instance.config.modules.font,
NULL,
};
static FFModuleBaseInfo* G[] = {
(void*) &instance.config.modules.gamepad,
(void*) &instance.config.modules.gpu,
(FFModuleBaseInfo*) &instance.config.modules.gamepad,
(FFModuleBaseInfo*) &instance.config.modules.gpu,
NULL,
};
static FFModuleBaseInfo* H[] = {
(void*) &instance.config.modules.host,
(FFModuleBaseInfo*) &instance.config.modules.host,
NULL,
};
static FFModuleBaseInfo* I[] = {
(void*) &instance.config.modules.icons,
(void*) &instance.config.modules.initSystem,
(FFModuleBaseInfo*) &instance.config.modules.icons,
(FFModuleBaseInfo*) &instance.config.modules.initSystem,
NULL,
};
@@ -72,47 +72,47 @@ static FFModuleBaseInfo* J[] = {
};
static FFModuleBaseInfo* K[] = {
(void*) &instance.config.modules.kernel,
(void*) &instance.config.modules.keyboard,
(FFModuleBaseInfo*) &instance.config.modules.kernel,
(FFModuleBaseInfo*) &instance.config.modules.keyboard,
NULL,
};
static FFModuleBaseInfo* L[] = {
(void*) &instance.config.modules.lm,
(void*) &instance.config.modules.loadavg,
(void*) &instance.config.modules.locale,
(void*) &instance.config.modules.localIP,
(FFModuleBaseInfo*) &instance.config.modules.lm,
(FFModuleBaseInfo*) &instance.config.modules.loadavg,
(FFModuleBaseInfo*) &instance.config.modules.locale,
(FFModuleBaseInfo*) &instance.config.modules.localIP,
NULL,
};
static FFModuleBaseInfo* M[] = {
(void*) &instance.config.modules.media,
(void*) &instance.config.modules.memory,
(void*) &instance.config.modules.monitor,
(void*) &instance.config.modules.mouse,
(FFModuleBaseInfo*) &instance.config.modules.media,
(FFModuleBaseInfo*) &instance.config.modules.memory,
(FFModuleBaseInfo*) &instance.config.modules.monitor,
(FFModuleBaseInfo*) &instance.config.modules.mouse,
NULL,
};
static FFModuleBaseInfo* N[] = {
(void*) &instance.config.modules.netIo,
(FFModuleBaseInfo*) &instance.config.modules.netIo,
NULL,
};
static FFModuleBaseInfo* O[] = {
(void*) &instance.config.modules.openCL,
(void*) &instance.config.modules.openGL,
(void*) &instance.config.modules.os,
(FFModuleBaseInfo*) &instance.config.modules.openCL,
(FFModuleBaseInfo*) &instance.config.modules.openGL,
(FFModuleBaseInfo*) &instance.config.modules.os,
NULL,
};
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.physicalMemory,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
(void*) &instance.config.modules.publicIP,
(FFModuleBaseInfo*) &instance.config.modules.packages,
(FFModuleBaseInfo*) &instance.config.modules.physicalDisk,
(FFModuleBaseInfo*) &instance.config.modules.physicalMemory,
(FFModuleBaseInfo*) &instance.config.modules.player,
(FFModuleBaseInfo*) &instance.config.modules.powerAdapter,
(FFModuleBaseInfo*) &instance.config.modules.processes,
(FFModuleBaseInfo*) &instance.config.modules.publicIP,
NULL,
};
@@ -125,42 +125,42 @@ static FFModuleBaseInfo* R[] = {
};
static FFModuleBaseInfo* S[] = {
(void*) &instance.config.modules.separator,
(void*) &instance.config.modules.shell,
(void*) &instance.config.modules.sound,
(void*) &instance.config.modules.swap,
(FFModuleBaseInfo*) &instance.config.modules.separator,
(FFModuleBaseInfo*) &instance.config.modules.shell,
(FFModuleBaseInfo*) &instance.config.modules.sound,
(FFModuleBaseInfo*) &instance.config.modules.swap,
NULL,
};
static FFModuleBaseInfo* T[] = {
(void*) &instance.config.modules.terminal,
(void*) &instance.config.modules.terminalFont,
(void*) &instance.config.modules.terminalSize,
(void*) &instance.config.modules.terminalTheme,
(void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme,
(void*) &instance.config.modules.tpm,
(FFModuleBaseInfo*) &instance.config.modules.terminal,
(FFModuleBaseInfo*) &instance.config.modules.terminalFont,
(FFModuleBaseInfo*) &instance.config.modules.terminalSize,
(FFModuleBaseInfo*) &instance.config.modules.terminalTheme,
(FFModuleBaseInfo*) &instance.config.modules.title,
(FFModuleBaseInfo*) &instance.config.modules.theme,
(FFModuleBaseInfo*) &instance.config.modules.tpm,
NULL,
};
static FFModuleBaseInfo* U[] = {
(void*) &instance.config.modules.uptime,
(void*) &instance.config.modules.users,
(FFModuleBaseInfo*) &instance.config.modules.uptime,
(FFModuleBaseInfo*) &instance.config.modules.users,
NULL,
};
static FFModuleBaseInfo* V[] = {
(void*) &instance.config.modules.version,
(void*) &instance.config.modules.vulkan,
(FFModuleBaseInfo*) &instance.config.modules.version,
(FFModuleBaseInfo*) &instance.config.modules.vulkan,
NULL,
};
static FFModuleBaseInfo* W[] = {
(void*) &instance.config.modules.wallpaper,
(void*) &instance.config.modules.weather,
(void*) &instance.config.modules.wm,
(void*) &instance.config.modules.wifi,
(void*) &instance.config.modules.wmTheme,
(FFModuleBaseInfo*) &instance.config.modules.wallpaper,
(FFModuleBaseInfo*) &instance.config.modules.weather,
(FFModuleBaseInfo*) &instance.config.modules.wm,
(FFModuleBaseInfo*) &instance.config.modules.wifi,
(FFModuleBaseInfo*) &instance.config.modules.wmTheme,
NULL,
};
@@ -173,7 +173,7 @@ static FFModuleBaseInfo* Y[] = {
};
static FFModuleBaseInfo* Z[] = {
(void*) &instance.config.modules.zpool,
(FFModuleBaseInfo*) &instance.config.modules.zpool,
NULL,
};
+5 -1
View File
@@ -91,7 +91,11 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
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)
if (sdl
#ifndef __sun
&& sdl->sdl_len
#endif
)
{
assert(sdl->sdl_nlen <= IF_NAMESIZE);
memcpy(iface, sdl->sdl_data, sdl->sdl_nlen);
+17 -24
View File
@@ -6,6 +6,20 @@ struct yyjson_val;
struct yyjson_mut_doc;
struct yyjson_mut_val;
typedef struct FFModuleFormatArg
{
const char* desc;
const char* name;
} FFModuleFormatArg;
typedef struct FFModuleFormatArgList
{
FFModuleFormatArg* args;
uint32_t count;
} FFModuleFormatArgList;
#define FF_FORMAT_ARG_LIST(list) { .args = list, .count = sizeof(list) / sizeof(FFModuleFormatArg) }
// Must be the first field of FFModuleOptions
typedef struct FFModuleBaseInfo
{
@@ -19,38 +33,17 @@ typedef struct FFModuleBaseInfo
void (*parseJsonObject)(void* options, struct yyjson_val *module);
void (*printModule)(void* options);
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
void (*printHelpFormat)(void);
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
FFModuleFormatArgList formatArgs;
} FFModuleBaseInfo;
static inline void ffOptionInitModuleBaseInfo(
FFModuleBaseInfo* baseInfo,
const char* name,
const char* description,
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* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
void (*printHelpFormat)(void),
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
)
{
baseInfo->name = name;
baseInfo->description = description;
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
baseInfo->printHelpFormat = printHelpFormat;
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
}
typedef enum FFModuleKeyType
typedef enum __attribute__((__packed__)) FFModuleKeyType
{
FF_MODULE_KEY_TYPE_NONE = 0,
FF_MODULE_KEY_TYPE_STRING = 1 << 0,
FF_MODULE_KEY_TYPE_ICON = 1 << 1,
FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
FF_MODULE_KEY_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFModuleKeyType;
typedef struct FFModuleArgs
+1 -1
View File
@@ -72,7 +72,7 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
}
if(counter == 0)
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
ffStrbufAppendF(result, "%" PRIu64 " %s", bytes, prefixes[0]);
else
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
}
+72 -10
View File
@@ -14,7 +14,46 @@ static void appendOutputColor(FFstrbuf* buffer, const FFModuleArgs* module)
ffStrbufAppendF(buffer, "\e[%sm", instance.config.display.colorOutput.chars);
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module)
const char* ffPercentParseTypeJsonConfig(yyjson_val* jsonVal, FFPercentageTypeFlags* result)
{
if (yyjson_is_uint(jsonVal))
{
*result = (FFPercentageTypeFlags) yyjson_get_uint(jsonVal);
return NULL;
}
if (yyjson_is_arr(jsonVal))
{
FFPercentageTypeFlags flags = 0;
yyjson_val* item;
size_t idx, max;
yyjson_arr_foreach(jsonVal, idx, max, item)
{
const char* flag = yyjson_get_str(item);
if (!flag)
return "Error: percent.type: invalid flag string";
if (ffStrEqualsIgnCase(flag, "num"))
flags |= FF_PERCENTAGE_TYPE_NUM_BIT;
else if (ffStrEqualsIgnCase(flag, "bar"))
flags |= FF_PERCENTAGE_TYPE_BAR_BIT;
else if (ffStrEqualsIgnCase(flag, "hide-others"))
flags |= FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT;
else if (ffStrEqualsIgnCase(flag, "num-color"))
flags |= FF_PERCENTAGE_TYPE_NUM_COLOR_BIT;
else if (ffStrEqualsIgnCase(flag, "bar-monochrome"))
flags |= FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT;
else
return "Error: percent.type: unknown flag string";
}
*result = flags;
return NULL;
}
return "Error: usage: percent.type must be a number or an array of strings";
}
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
@@ -41,15 +80,18 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
}
else
{
const char* colorGreen = instance.config.display.percentColorGreen.chars;
const char* colorYellow = instance.config.display.percentColorYellow.chars;
const char* colorRed = instance.config.display.percentColorRed.chars;
const char* colorGreen = options->percentColorGreen.chars;
const char* colorYellow = options->percentColorYellow.chars;
const char* colorRed = options->percentColorRed.chars;
FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type;
bool monochrome = !!(percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT);
for (uint32_t i = 0; i < blocksPercent; ++i)
{
if(!options->pipe)
{
if (options->percentType & FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT)
if (monochrome)
{
const char* color = NULL;
if (green <= yellow)
@@ -104,14 +146,15 @@ void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig con
}
}
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module)
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module)
{
uint8_t green = config.green, yellow = config.yellow;
assert(green <= 100 && yellow <= 100);
const FFOptionsDisplay* options = &instance.config.display;
FFPercentageTypeFlags percentType = config.type == 0 ? options->percentType : config.type;
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
bool colored = !!(percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
if (parentheses)
ffStrbufAppendC(buffer, '(');
@@ -156,7 +199,7 @@ void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig con
ffStrbufAppendC(buffer, ')');
}
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config)
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config)
{
if (!ffStrStartsWithIgnCase(subkey, "percent-"))
return false;
@@ -187,10 +230,16 @@ bool ffPercentParseCommandOptions(const char* key, const char* subkey, const cha
return true;
}
if (ffStrEqualsIgnCase(subkey, "type"))
{
config->type = (FFPercentageTypeFlags) ffOptionParseUInt32(key, value);
return true;
}
return false;
}
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config)
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config)
{
if (!ffStrEqualsIgnCase(key, "percent"))
return false;
@@ -225,10 +274,21 @@ bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeCo
config->yellow = (uint8_t) num;
}
yyjson_val* typeVal = yyjson_obj_get(value, "type");
if (typeVal)
{
const char* error = ffPercentParseTypeJsonConfig(typeVal, &config->type);
if (error)
{
fputs(error, stderr);
exit(480);
}
}
return true;
}
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config)
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config)
{
if (config.green == defaultConfig.green && config.yellow == defaultConfig.yellow)
return;
@@ -238,4 +298,6 @@ void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FF
yyjson_mut_obj_add_uint(doc, percent, "green", config.green);
if (config.yellow != defaultConfig.yellow)
yyjson_mut_obj_add_uint(doc, percent, "yellow", config.yellow);
if (config.type != defaultConfig.type)
yyjson_mut_obj_add_uint(doc, percent, "type", config.type);
}
+18 -7
View File
@@ -4,14 +4,24 @@
#include "common/parsing.h"
#include "common/option.h"
enum FFPercentageTypeFlags
typedef enum __attribute__((__packed__)) FFPercentageTypeFlags
{
FF_PERCENTAGE_TYPE_NONE = 0,
FF_PERCENTAGE_TYPE_NUM_BIT = 1 << 0,
FF_PERCENTAGE_TYPE_BAR_BIT = 1 << 1,
FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT = 1 << 2,
FF_PERCENTAGE_TYPE_NUM_COLOR_BIT = 1 << 3,
FF_PERCENTAGE_TYPE_BAR_MONOCHROME_BIT = FF_PERCENTAGE_TYPE_NUM_COLOR_BIT,
};
FF_PERCENTAGE_TYPE_FORCE_UNSIGNED_ = UINT8_MAX,
} FFPercentageTypeFlags;
static_assert(sizeof(FFPercentageTypeFlags) == 1, "");
typedef struct FFPercentageModuleConfig
{
uint8_t green;
uint8_t yellow;
FFPercentageTypeFlags type;
} FFPercentageModuleConfig;
// if (green <= yellow)
// [0, green]: print green
@@ -23,12 +33,13 @@ enum FFPercentageTypeFlags
// [yellow, green): print yellow
// [0, yellow): print red
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFColorRangeConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFColorRangeConfig config, bool parentheses, const FFModuleArgs* module);
void ffPercentAppendBar(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, const FFModuleArgs* module);
void ffPercentAppendNum(FFstrbuf* buffer, double percent, FFPercentageModuleConfig config, bool parentheses, const FFModuleArgs* module);
typedef struct yyjson_val yyjson_val;
typedef struct yyjson_mut_doc yyjson_mut_doc;
typedef struct yyjson_mut_val yyjson_mut_val;
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFColorRangeConfig* config);
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFColorRangeConfig* config);
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFColorRangeConfig defaultConfig, FFColorRangeConfig config);
bool ffPercentParseCommandOptions(const char* key, const char* subkey, const char* value, FFPercentageModuleConfig* config);
bool ffPercentParseJsonObject(const char* key, yyjson_val* value, FFPercentageModuleConfig* config);
void ffPercentGenerateJsonConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFPercentageModuleConfig defaultConfig, FFPercentageModuleConfig config);
const char* ffPercentParseTypeJsonConfig(yyjson_val* value, FFPercentageTypeFlags* result);
+1 -16
View File
@@ -50,7 +50,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, ((FFformatarg[]) {
FF_FORMAT_ARG(moduleIndex, "index"),
FF_FORMAT_ARG(moduleArgs->keyIcon, "icon"),
}));
@@ -148,18 +148,3 @@ void ffPrintCharTimes(char c, uint32_t times)
if(remaining > 0)
fwrite(str, 1, remaining, stdout);
}
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[])
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreateS(name);
ffStrbufLowerCase(&buffer);
printf("--%s-format:\n", buffer.chars);
printf("Sets the format string for %s output.\n", name);
puts("To see how a format string is constructed, take a look at \"fastfetch --help format\".");
puts("The following values are passed:");
for(unsigned i = 0; i < numArgs; i++)
printf(" {%u}: %s\n", i + 1, args[i]);
printf("The default is something similar to \"%s\".\n", def);
}
+4 -11
View File
@@ -3,26 +3,19 @@
#include "fastfetch.h"
#include "common/format.h"
typedef enum FFPrintType {
typedef enum __attribute__((__packed__)) FFPrintType {
FF_PRINT_TYPE_DEFAULT = 0,
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
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
FF_PRINT_TYPE_FORCE_UNSIGNED = UINT8_MAX,
} FFPrintType;
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType);
void ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments);
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, numArgs, arguments) do {\
static_assert(sizeof(arguments) / sizeof(*arguments) == (numArgs), "Invalid number of format arguments");\
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (numArgs), (arguments));\
} while (0)
#define FF_PRINT_FORMAT_CHECKED(moduleName, moduleIndex, moduleArgs, printType, arguments) \
ffPrintFormat((moduleName), (moduleIndex), (moduleArgs), (printType), (sizeof(arguments) / sizeof(*arguments)), (arguments));
FF_C_PRINTF(5, 6) void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...);
void ffPrintColor(const FFstrbuf* colorValue);
void ffPrintCharTimes(char c, uint32_t times);
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
#define FF_PRINT_MODULE_FORMAT_HELP_CHECKED(moduleName, def, numArgs, args) do {\
static_assert(sizeof(args) / sizeof(*args) == (numArgs), "Invalid number of format arguments");\
ffPrintModuleFormatHelp((moduleName), (def), (numArgs), (args));\
} while (0)
+80 -17
View File
@@ -1,7 +1,6 @@
#include "fastfetch.h"
#include "common/processing.h"
#include "common/io/io.h"
#include "common/time.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
@@ -23,9 +22,12 @@
#elif defined(__sun)
#include <procfs.h>
#elif defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#elif defined(__NetBSD__)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
enum { FF_PIPE_BUFSIZ = 8192 };
@@ -87,6 +89,16 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
waitpid(childPid, NULL, 0);
return "poll(&pollfd, 1, timeout) timeout (try increasing --processing-timeout)";
}
else if (errno == EINTR)
{
// The child process has been terminated. See `chldSignalHandler` in `common/init.c`
if (waitpid(childPid, NULL, WNOHANG) == childPid)
{
// Read remaining data from the pipe
fcntl(childPipeFd, F_SETFL, O_CLOEXEC | O_NONBLOCK);
childPid = -1;
}
}
else if (pollfd.revents & POLLERR)
{
kill(childPid, SIGTERM);
@@ -101,7 +113,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
else if (nRead == 0)
{
int stat_loc = 0;
if (waitpid(childPid, &stat_loc, 0) == childPid)
if (childPid > 0 && waitpid(childPid, &stat_loc, 0) == childPid)
{
if (!WIFEXITED(stat_loc))
return "child process exited abnormally";
@@ -110,10 +122,15 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
// We only handle 127 as an error. See `getTerminalVersionUrxvt` in `terminalshell.c`
return NULL;
}
return "waitpid() failed";
return NULL;
}
else if (nRead < 0)
break;
{
if (errno == EAGAIN)
return NULL;
else
break;
}
};
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
@@ -144,7 +161,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
if (length > 0) // doesn't contain trailing NUL
{
buf[length] = '\0';
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length + 1); // +1 for the NUL
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
}
}
@@ -155,10 +172,8 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid };
if (sysctl(mibs, ARRAY_SIZE(mibs), NULL, &len, NULL, 0) == 0)
{// try get arg0
#ifndef MAC_OS_X_VERSION_10_15
//don't know why if don't let len longer, proArgs2 and len will change during the following sysctl() in old MacOS version.
len++;
#endif
FF_AUTO_FREE char* const procArgs2 = malloc(len);
if (sysctl(mibs, ARRAY_SIZE(mibs), procArgs2, &len, NULL, 0) == 0)
{
@@ -192,17 +207,18 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
}
else
{
ffStrbufEnsureFixedLengthFree(exe, PATH_MAX);
int length = proc_pidpath(pid, exe->chars, exe->allocated);
char buf[PROC_PIDPATHINFO_MAXSIZE];
int length = proc_pidpath(pid, buf, ARRAY_SIZE(buf));
if (length > 0)
{
exe->length = (uint32_t) length;
ffStrbufEnsureFixedLengthFree(exe, (uint32_t) length);
ffStrbufAppendNS(exe, (uint32_t) length, buf);
if (exePath)
ffStrbufSet(exePath, exe);
}
}
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || defined(__NetBSD__)
size_t size = ARG_MAX;
FF_AUTO_FREE char* args = malloc(size);
@@ -210,7 +226,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
static_assert(ARG_MAX > PATH_MAX, "");
if(exePath && sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid}, 4,
(int[]){CTL_KERN,
#if __FreeBSD__
KERN_PROC, KERN_PROC_PATHNAME, pid
#else
KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME
#endif
}, 4,
args, &size,
NULL, 0
) == 0)
@@ -218,7 +240,13 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
size = ARG_MAX;
if(sysctl(
(int[]){CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}, 4,
(int[]){CTL_KERN,
#if __FreeBSD__
KERN_PROC, KERN_PROC_ARGS, pid
#else
KERN_PROC_ARGS, pid, KERN_PROC_ARGV,
#endif
}, 4,
args, &size,
NULL, 0
) == 0)
@@ -260,7 +288,7 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
if (length > 0) // doesn't contain trailing NUL
{
buf[length] = '\0';
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length + 1); // +1 for the NUL
ffStrbufEnsureFixedLengthFree(exePath, (uint32_t)length);
ffStrbufAppendNS(exePath, (uint32_t)length, buf);
}
}
@@ -352,6 +380,13 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
#elif defined(__FreeBSD__)
#ifdef __DragonFly__
#define ki_comm kp_comm
#define ki_ppid kp_ppid
#define ki_tdev kp_tdev
#define ki_flag kp_flags
#endif
struct kinfo_proc proc;
size_t size = sizeof(proc);
if(sysctl(
@@ -378,6 +413,34 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
*tty = -1;
}
#elif defined(__NetBSD__)
struct kinfo_proc2 proc;
size_t size = sizeof(proc);
if(sysctl(
(int[]){CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(proc), 1}, 6,
&proc, &size,
NULL, 0
) != 0)
return "sysctl(KERN_PROC_PID) failed";
ffStrbufSetS(name, proc.p_comm);
if (ppid)
*ppid = (pid_t)proc.p_ppid;
if (tty)
{
if (proc.p_flag & P_CONTROLT)
{
const char* ttyName = devname(proc.p_tdev, S_IFCHR);
if (ffStrStartsWith(ttyName, "pts/"))
*tty = (int32_t) strtol(ttyName + strlen("pts/"), NULL, 10);
else
*tty = -1;
}
else
*tty = -1;
}
#elif defined(__sun)
char path[128];
snprintf(path, sizeof(path), "/proc/%d/psinfo", (int) pid);
+3
View File
@@ -169,6 +169,9 @@ bool ffProcessGetInfoWindows(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFst
? GetCurrentProcess()
: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess == NULL)
return false;
if (gui)
*gui = GetGuiResources(hProcess, GR_GDIOBJECTS) > 0;
+1 -1
View File
@@ -2,7 +2,7 @@
#include "fastfetch.h"
typedef enum FFvarianttype
typedef enum __attribute__((__packed__)) FFvarianttype
{
FF_VARIANT_TYPE_STRING,
FF_VARIANT_TYPE_BOOL,
+28 -1
View File
@@ -186,7 +186,8 @@
"data-raw": "Text data, printed as is",
"sixel": "Image file, printed as sixel codes",
"kitty": "Image file, printed as kitty graphics protocol",
"kitty_direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
"kitty-direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
"kitty-icat": "Image file, use `kitten icat` to display the image. Requires binary `kitten` to be installed",
"iterm": "Image file, printed as iterm graphics protocol",
"chafa": "Image file, printed as ascii art using libchafa",
"raw": "Image file, printed as raw binary string",
@@ -351,6 +352,14 @@
"type": "path"
}
},
{
"long": "kitty-icat",
"desc": "Short for --logo-type kitty-icat --logo <path>",
"remark": "See \"--help logo-type\" for more info",
"arg": {
"type": "path"
}
},
{
"long": "iterm",
"desc": "Short for --logo-type iterm --logo <path>",
@@ -1602,6 +1611,24 @@
},
"pseudo": true
},
{
"long": "<module>-percent-type",
"desc": "Set the percentage output type",
"remark": [
"0 for use global `--percent-type` value",
"1 for percentage number",
"2 for multi-color bar",
"3 for both",
"6 for bar only",
"9 for colored number",
"10 for monochrome bar"
],
"arg": {
"type": "num",
"default": 0
},
"pseudo": true
},
{
"long": "<module>-temp-green",
"desc": [
+12
View File
@@ -70,14 +70,26 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
ffStrbufTrimRight(&battery->status, ',');
}
#ifdef ACPIIO_BATT_GET_BIX
battio.unit = i;
if (ioctl(acpifd, ACPIIO_BATT_GET_BIX, &battio) >= 0)
{
ffStrbufAppendS(&battery->manufacturer, battio.bix.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bix.model);
ffStrbufAppendS(&battery->technology, battio.bix.type);
ffStrbufAppendS(&battery->serial, battio.bix.serial);
battery->cycleCount = battio.bix.cycles;
}
#elif defined(ACPIIO_BATT_GET_BIF)
battio.unit = i;
if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) >= 0)
{
ffStrbufAppendS(&battery->manufacturer, battio.bif.oeminfo);
ffStrbufAppendS(&battery->modelName, battio.bif.model);
ffStrbufAppendS(&battery->technology, battio.bif.type);
ffStrbufAppendS(&battery->serial, battio.bif.serial);
}
#endif
}
return NULL;
}
+107
View File
@@ -0,0 +1,107 @@
#include "battery.h"
#include "common/io/io.h"
#include "util/FFstrbuf.h"
#include "util/stringUtils.h"
#include <prop/prop_array.h>
#include <prop/prop_bool.h>
#include <prop/prop_dictionary.h>
#include <prop/prop_object.h>
#include <sys/envsys.h>
#include <prop/proplib.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
{
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
bool acConnected = false;
{
prop_array_t acad = prop_dictionary_get(root, "acpiacad0");
if (acad)
{
prop_dictionary_t dict = prop_array_get(acad, 0);
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &acConnected);
}
}
prop_object_iterator_t itKey = prop_dictionary_iterator(root);
for (prop_dictionary_keysym_t key; (key = prop_object_iterator_next(itKey)) != NULL; )
{
if (!ffStrStartsWith(prop_dictionary_keysym_value(key), "acpibat")) continue;
prop_array_t bat = prop_dictionary_get_keysym(root, key);
uint32_t max = 0, curr = 0, dischargeRate = 0;
bool charging = false, critical = false;
prop_object_iterator_t iter = prop_array_iterator(bat);
for (prop_dictionary_t dict; (dict = prop_object_iterator_next(iter)) != NULL;)
{
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
continue;
const char* desc = NULL;
if (!prop_dictionary_get_string(dict, "description", &desc))
continue;
if (ffStrEquals(desc, "present"))
{
int value = 0;
if (prop_dictionary_get_int(dict, "cur-value", &value) && value == 0)
continue;
}
else if (ffStrEquals(desc, "charging"))
{
prop_dictionary_get_uint8(dict, "cur-value", (uint8_t*) &charging);
}
else if (ffStrEquals(desc, "charge"))
{
prop_dictionary_get_uint32(dict, "max-value", &max);
prop_dictionary_get_uint32(dict, "cur-value", &curr);
const char* state = NULL;
if (prop_dictionary_get_string(dict, "state", &state) && ffStrEquals(state, "critical"))
critical = true;
}
else if (ffStrEquals(desc, "discharge rate"))
{
prop_dictionary_get_uint(dict, "cur-value", &dischargeRate);
}
}
if (max > 0)
{
FFBatteryResult* battery = ffListAdd(results);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
battery->timeRemaining = -1;
battery->capacity = (double) curr / (double) max * 100.;
if (charging)
ffStrbufAppendS(&battery->status, "Charging, ");
else if (dischargeRate)
ffStrbufAppendS(&battery->status, "Discharging, ");
if (critical)
ffStrbufAppendS(&battery->status, "Critical, ");
if (acConnected)
ffStrbufAppendS(&battery->status, "AC Connected");
ffStrbufTrimRight(&battery->status, ' ');
ffStrbufTrimRight(&battery->status, ',');
}
}
prop_object_iterator_release(itKey);
return NULL;
}
+52
View File
@@ -0,0 +1,52 @@
#include "battery.h"
#include "common/io/io.h"
#include <machine/apmvar.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* result)
{
FF_AUTO_CLOSE_FD int devfd = open("/dev/apm", O_RDONLY);
if (devfd < 0) return "open(dev/apm, O_RDONLY) failed";
struct apm_power_info info = {};
if (ioctl(devfd, APM_IOC_GETPOWER, &info) < 0)
return "ioctl(APM_IOC_GETPOWER) failed";
if (info.battery_state == APM_BATTERY_ABSENT)
return NULL;
FFBatteryResult* battery = (FFBatteryResult*) ffListAdd(result);
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->cycleCount = 0;
battery->timeRemaining = -1;
battery->capacity = info.battery_life;
ffStrbufInit(&battery->manufacturer);
ffStrbufInit(&battery->modelName);
ffStrbufInit(&battery->status);
ffStrbufInit(&battery->technology);
ffStrbufInit(&battery->serial);
ffStrbufInit(&battery->manufactureDate);
if (info.ac_state == APM_AC_ON)
ffStrbufAppendS(&battery->status, "AC Connected");
else if (info.ac_state == APM_AC_BACKUP)
ffStrbufAppendS(&battery->status, "Backup In Use");
else if (info.ac_state == APM_AC_OFF)
{
battery->timeRemaining = (int) info.minutes_left * 60;
ffStrbufAppendS(&battery->status, "Discharging");
}
if (info.battery_state == APM_BATT_CRITICAL || info.battery_state == APM_BATT_CHARGING)
{
if (battery->status.length) ffStrbufAppendS(&battery->status, ", ");
ffStrbufAppendS(&battery->status, info.battery_state == APM_BATT_CRITICAL ? "Critical" : "Charging");
}
return NULL;
}
+15
View File
@@ -0,0 +1,15 @@
#include "bios.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectBios(FFBiosResult* bios)
{
if (ffSysctlGetString("machdep.dmi.bios-date", &bios->date) == NULL)
ffCleanUpSmbiosValue(&bios->date);
if (ffSysctlGetString("machdep.dmi.bios-version", &bios->version) == NULL)
ffCleanUpSmbiosValue(&bios->version);
if (ffSysctlGetString("machdep.dmi.bios-vendor", &bios->vendor) == NULL)
ffCleanUpSmbiosValue(&bios->vendor);
ffSysctlGetString("machdep.bootmethod", &bios->type);
return NULL;
}
+1 -1
View File
@@ -11,4 +11,4 @@ typedef struct FFBluetoothResult
bool connected;
} FFBluetoothResult;
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */);
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */);
+22 -2
View File
@@ -2,7 +2,15 @@
#import <IOBluetooth/IOBluetooth.h>
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
@interface IOBluetoothDevice()
@property (nonatomic) uint8_t batteryPercentCase;
@property (nonatomic) uint8_t batteryPercentCombined;
@property (nonatomic) uint8_t batteryPercentLeft;
@property (nonatomic) uint8_t batteryPercentRight;
@property (nonatomic) uint8_t batteryPercentSingle;
@end
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
{
NSArray<IOBluetoothDevice*>* ioDevices = IOBluetoothDevice.pairedDevices;
if(!ioDevices)
@@ -10,11 +18,23 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
for(IOBluetoothDevice* ioDevice in ioDevices)
{
if (!options->showDisconnected && !ioDevice.isConnected)
continue;
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, ioDevice.name.UTF8String);
ffStrbufInitS(&device->address, ioDevice.addressString.UTF8String);
ffStrbufReplaceAllC(&device->address, '-', ':');
ffStrbufUpperCase(&device->address);
ffStrbufInit(&device->type);
device->battery = 0;
if (ioDevice.batteryPercentSingle)
device->battery = ioDevice.batteryPercentSingle;
else if (ioDevice.batteryPercentCombined)
device->battery = ioDevice.batteryPercentCombined;
else if (ioDevice.batteryPercentCase)
device->battery = ioDevice.batteryPercentCase;
device->connected = !!ioDevice.isConnected;
if(ioDevice.serviceClassMajor & kBluetoothServiceClassMajorLimitedDiscoverableMode)
ffStrbufAppendS(&device->type, "Limited Discoverable Mode, ");
+25
View File
@@ -0,0 +1,25 @@
#include "bluetooth.h"
#define L2CAP_SOCKET_CHECKED
#include <bluetooth.h>
static int enumDev(FF_MAYBE_UNUSED int sockfd, struct bt_devinfo const* dev, FFlist* devices)
{
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, bt_devremote_name_gen(dev->devname, &dev->bdaddr));
ffStrbufInitS(&device->address, bt_ntoa(&dev->bdaddr, NULL));
ffStrbufUpperCase(&device->address);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = true;
return 0;
}
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
// struct hostent* ent = bt_gethostent();
if (bt_devenum((void*) enumDev, devices) < 0)
return "bt_devenum() failed";
return 0;
}
+68 -22
View File
@@ -3,6 +3,7 @@
#ifdef FF_HAVE_DBUS
#include "common/dbus.h"
#include "common/io/io.h"
/* Example dbus reply, striped to only the relevant parts:
array [ //root
@@ -44,16 +45,16 @@ array [ //root
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
static bool detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return true;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
return true;
const char* deviceProperty;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
@@ -74,6 +75,13 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
}
else if(ffStrEquals(deviceProperty, "Connected"))
ffDBusGetBool(dbus, &dictIter, &device->connected);
else if(ffStrEquals(deviceProperty, "Paired"))
{
bool paired = true;
ffDBusGetBool(dbus, &dictIter, &paired);
if (!paired) return false;
}
return true;
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothResult* device)
@@ -103,32 +111,37 @@ static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFB
do
{
detectBluetoothValue(dbus, &arrayIter, device);
bool shouldContinue = detectBluetoothValue(dbus, &arrayIter, device);
if (!shouldContinue)
{
ffStrbufClear(&device->name);
break;
}
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
static FFBluetoothResult* detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return NULL;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
return;
return NULL;
const char* objectPath;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
// We don't want adapter objects
if(!ffStrContains(objectPath, "/dev_"))
return;
return NULL;
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
return NULL;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
@@ -145,16 +158,10 @@ static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessage
detectBluetoothProperty(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
if(device->name.length == 0)
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
ffStrbufDestroy(&device->type);
--devices->length;
}
return device;
}
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter, int32_t connectedCount)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return;
@@ -164,11 +171,25 @@ static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIt
do
{
detectBluetoothObject(devices, dbus, &arrayIter);
FFBluetoothResult* device = detectBluetoothObject(devices, dbus, &arrayIter);
if (device)
{
if(device->name.length == 0 || (connectedCount > 0 && !device->connected))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
ffStrbufDestroy(&device->type);
--devices->length;
}
if (device->connected && --connectedCount == 0)
break;
}
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static const char* detectBluetooth(FFlist* devices)
static const char* detectBluetooth(FFlist* devices, int32_t connectedCount)
{
FFDBusData dbus;
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
@@ -186,18 +207,43 @@ static const char* detectBluetooth(FFlist* devices)
return "Failed to get root iterator of GetManagedObjects";
}
detectBluetoothRoot(devices, &dbus, &rootIter);
detectBluetoothRoot(devices, &dbus, &rootIter, connectedCount);
dbus.lib->ffdbus_message_unref(managedObjects);
return NULL;
}
static uint32_t connectedDevices(void)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
if(dirp == NULL)
return 0;
uint32_t result = 0;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (strchr(entry->d_name, ':') != NULL)
++result;
}
return result;
}
#endif
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
int32_t connectedCount = -1;
if (!options->showDisconnected)
{
connectedCount = (int32_t) connectedDevices();
if (connectedCount == 0)
return NULL;
}
return detectBluetooth(devices, connectedCount);
#else
return "Fastfetch was compiled without DBus support";
#endif
@@ -1,6 +1,6 @@
#include "bluetooth.h"
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FF_MAYBE_UNUSED FFBluetoothOptions* options, FF_MAYBE_UNUSED FFlist* devices /* FFBluetoothResult */)
{
return "Not supported on this platform";
}
+14 -10
View File
@@ -7,7 +7,7 @@
#pragma GCC diagnostic ignored "-Wpointer-sign"
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
const char* ffDetectBluetooth(FFBluetoothOptions* options, FFlist* devices /* FFBluetoothResult */)
{
// Actually bluetoothapis.dll, but it's missing on Windows 7
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
@@ -20,26 +20,27 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
};
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstDevice(&(BLUETOOTH_DEVICE_SEARCH_PARAMS) {
.fReturnConnected = TRUE,
.fReturnRemembered = TRUE,
.fReturnAuthenticated = TRUE,
.fReturnUnknown = TRUE,
.fReturnRemembered = options->showDisconnected,
.fReturnAuthenticated = options->showDisconnected,
.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)
}, &btdi);
if(!hFind)
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
return NULL;
return "BluetoothFindFirstDevice() failed";
}
do {
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitWS(&device->name, btdi.szName);
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
btdi.Address.rgBytes[0],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[3],
ffStrbufInitF(&device->address, "%02X:%02X:%02X:%02X:%02X:%02X",
btdi.Address.rgBytes[5],
btdi.Address.rgBytes[4],
btdi.Address.rgBytes[5]);
btdi.Address.rgBytes[3],
btdi.Address.rgBytes[2],
btdi.Address.rgBytes[1],
btdi.Address.rgBytes[0]);
ffStrbufInit(&device->type);
device->battery = 0;
device->connected = !!btdi.fConnected;
@@ -121,5 +122,8 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
ffBluetoothFindDeviceClose(hFind);
const char* ffBluetoothDetectBattery(FFlist* result);
ffBluetoothDetectBattery(devices);
return NULL;
}
@@ -0,0 +1,122 @@
extern "C"
{
#include "bluetooth.h"
}
#include "util/windows/wmi.hpp"
#include "util/windows/unicode.hpp"
STDAPI InitVariantFromStringArray(_In_reads_(cElems) PCWSTR *prgsz, _In_ ULONG cElems, _Out_ VARIANT *pvar);
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* ffBluetoothDetectBattery(FFlist* devices)
{
FFWmiQuery query(L"SELECT __PATH FROM Win32_PnPEntity WHERE Service = 'BthHFEnum'", nullptr, FFWmiNamespace::CIMV2);
if(!query)
return "Query WMI service failed";
IWbemClassObject* pInParams = nullptr;
on_scope_exit releaseInParams([&] { pInParams && pInParams->Release(); });
{
IWbemClassObject* pnpEntityClass = nullptr;
if (FAILED(query.pService->GetObjectW(bstr_t(L"Win32_PnPEntity"), 0, nullptr, &pnpEntityClass, nullptr)))
return "Failed to get PnP entity class";
on_scope_exit releasePnpEntityClass([&] { pnpEntityClass && pnpEntityClass->Release(); });
if (FAILED(pnpEntityClass->GetMethod(bstr_t(L"GetDeviceProperties"), 0, &pInParams, NULL)))
return "Failed to get GetDeviceProperties method";
VARIANT devicePropertyKeys;
PCWSTR props[] = { L"{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2", L"DEVPKEY_Bluetooth_DeviceAddress" };
if (FAILED(InitVariantFromStringArray(props, ARRAY_SIZE(props), &devicePropertyKeys)))
return "Failed to init variant from string array";
on_scope_exit releaseDevicePropertyKeys([&] { VariantClear(&devicePropertyKeys); });
if (FAILED(pInParams->Put(L"devicePropertyKeys", 0, &devicePropertyKeys, CIM_FLAG_ARRAY | CIM_STRING)))
return "Failed to put devicePropertyKeys";
}
while (FFWmiRecord record = query.next())
{
IWbemCallResult* pCallResult = nullptr;
if (FAILED(query.pService->ExecMethod(record.get(L"__PATH").bstrVal, bstr_t(L"GetDeviceProperties"), 0, nullptr, pInParams, nullptr, &pCallResult)))
continue;
on_scope_exit releaseCallResult([&] { pCallResult && pCallResult->Release(); });
IWbemClassObject* pResultObject = nullptr;
if (FAILED(pCallResult->GetResultObject((LONG) WBEM_INFINITE, &pResultObject)))
continue;
on_scope_exit releaseResultObject([&] { pResultObject && pResultObject->Release(); });
VARIANT propArray;
if (FAILED(pResultObject->Get(L"deviceProperties", 0, &propArray, nullptr, nullptr)))
continue;
on_scope_exit releasePropArray([&] { VariantClear(&propArray); });
if (propArray.vt != (VT_ARRAY | VT_UNKNOWN) ||
(propArray.parray->fFeatures & FADF_UNKNOWN) == 0 ||
propArray.parray->cDims != 1 ||
propArray.parray->rgsabound[0].cElements != 2
)
continue;
uint8_t batt = 0;
for (LONG i = 0; i < 2; i++)
{
IWbemClassObject* object = nullptr;
if (FAILED(SafeArrayGetElement(propArray.parray, &i, &object)))
continue;
FFWmiRecord rec(object);
auto data = rec.get(L"Data");
if (data.vt == VT_EMPTY)
break;
if (i == 0)
batt = data.get<uint8_t>();
else
{
FF_STRBUF_AUTO_DESTROY addr; // MAC address without colon
ffStrbufInitWSV(&addr, data.get<std::wstring_view>());
if (__builtin_expect(addr.length != 12, 0))
continue;
FF_LIST_FOR_EACH(FFBluetoothResult, bt, *devices)
{
if (bt->address.length != 12 + 5)
continue;
if (addr.chars[0] == bt->address.chars[0] &&
addr.chars[1] == bt->address.chars[1] &&
addr.chars[2] == bt->address.chars[3] &&
addr.chars[3] == bt->address.chars[4] &&
addr.chars[4] == bt->address.chars[6] &&
addr.chars[5] == bt->address.chars[7] &&
addr.chars[6] == bt->address.chars[9] &&
addr.chars[7] == bt->address.chars[10] &&
addr.chars[8] == bt->address.chars[12] &&
addr.chars[9] == bt->address.chars[13] &&
addr.chars[10] == bt->address.chars[15] &&
addr.chars[11] == bt->address.chars[16])
{
bt->battery = batt;
break;
}
}
}
}
}
return NULL;
}
@@ -3,56 +3,47 @@
#ifdef FF_HAVE_DBUS
#include "common/dbus.h"
#include "common/io/io.h"
/* Example dbus reply, striped to only the relevant parts:
array [ //root
/* Example dbus reply:
array [
dict entry(
object path "/org/bluez/hci0"
array [
dict entry(
string "org.bluez.Adapter1"
array [
dict entry(
string "Address"
variant string "XX:XX:XX:XX:XX:XX"
)
dict entry(
string "Name"
variant string "xxxxxxxx"
)
dict entry(
string "Powered"
variant boolean true
)
dict entry(
string "PowerState"
variant string "on"
)
dict entry(
string "Manufacturer"
variant uint16 2
)
dict entry(
string "Version"
variant byte 12
)
]
)
]
string "Address"
variant string "XX:XX:XX:XX:XX:XX"
)
dict entry(
string "Name"
variant string "xxxxxxxx"
)
dict entry(
string "Powered"
variant boolean true
)
dict entry(
string "PowerState"
variant string "on"
)
dict entry(
string "Manufacturer"
variant uint16 2
)
dict entry(
string "Version"
variant byte 12
)
]
*/
static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
static const char* detectBluetoothProperty(FFBluetoothRadioResult* device, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
return "Expected dict entry";
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
return "Expected dict entry key to be a string";
const char* deviceProperty;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &deviceProperty);
@@ -77,121 +68,73 @@ static void detectBluetoothValue(FFDBusData* dbus, DBusMessageIter* iter, FFBlue
ffDBusGetBool(dbus, &dictIter, &device->discoverable);
else if(ffStrEquals(deviceProperty, "Pairable"))
ffDBusGetBool(dbus, &dictIter, &device->connectable);
return NULL;
}
static void detectBluetoothProperty(FFDBusData* dbus, DBusMessageIter* iter, FFBluetoothRadioResult* device)
static const char* detectBluetoothRoot(FFBluetoothRadioResult* device, const char* hciName, FFDBusData* dbus)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
char objPath[300];
snprintf(objPath, sizeof(objPath), "/org/bluez/%s", hciName);
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
DBusMessage* properties = ffDBusGetMethodReply(dbus, "org.bluez", objPath, "org.freedesktop.DBus.Properties", "GetAll", "org.bluez.Adapter1");
if(!properties)
return "Failed to call org.freedesktop.DBus.Properties.GetAll";
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_STRING)
return;
const char* propertyType;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &propertyType);
if(!ffStrContains(propertyType, ".Adapter"))
return; //We don't care about other properties
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
do
DBusMessageIter rootIter;
if(!dbus->lib->ffdbus_message_iter_init(properties, &rootIter))
{
detectBluetoothValue(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
}
static void detectBluetoothObject(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY)
return;
DBusMessageIter dictIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_OBJECT_PATH)
return;
const char* objectPath;
dbus->lib->ffdbus_message_iter_get_basic(&dictIter, &objectPath);
//We want adapter objects
if(!ffStrStartsWith(objectPath, "/org/bluez/hci") || ffStrContains(objectPath, "/dev_"))
return;
dbus->lib->ffdbus_message_iter_next(&dictIter);
if(dbus->lib->ffdbus_message_iter_get_arg_type(&dictIter) != DBUS_TYPE_ARRAY)
return;
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(&dictIter, &arrayIter);
FFBluetoothRadioResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInitStatic(&device->vendor, "Unknown");
device->lmpVersion = INT_MIN;
device->lmpSubversion = INT_MIN;
device->enabled = false;
do
{
detectBluetoothProperty(dbus, &arrayIter, device);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
if(device->name.length == 0)
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->address);
--devices->length;
dbus->lib->ffdbus_message_unref(properties);
return "Failed to get root iterator of org.freedesktop.DBus.Properties.GetAll";
}
}
static void detectBluetoothRoot(FFlist* devices, FFDBusData* dbus, DBusMessageIter* iter)
{
if(dbus->lib->ffdbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return;
if(dbus->lib->ffdbus_message_iter_get_arg_type(&rootIter) != DBUS_TYPE_ARRAY)
{
dbus->lib->ffdbus_message_unref(properties);
return "Expected array";
}
DBusMessageIter arrayIter;
dbus->lib->ffdbus_message_iter_recurse(iter, &arrayIter);
dbus->lib->ffdbus_message_iter_recurse(&rootIter, &arrayIter);
do
{
detectBluetoothObject(devices, dbus, &arrayIter);
detectBluetoothProperty(device, dbus, &arrayIter);
} while (dbus->lib->ffdbus_message_iter_next(&arrayIter));
dbus->lib->ffdbus_message_unref(properties);
return NULL;
}
static const char* detectBluetooth(FFlist* devices)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/bluetooth");
if(dirp == NULL)
return "Failed to open /sys/class/bluetooth";
FFDBusData dbus;
const char* error = ffDBusLoadData(DBUS_BUS_SYSTEM, &dbus);
if(error)
return error;
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL);
if(!managedObjects)
return "Failed to call GetManagedObjects";
DBusMessageIter rootIter;
if(!dbus.lib->ffdbus_message_iter_init(managedObjects, &rootIter))
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
dbus.lib->ffdbus_message_unref(managedObjects);
return "Failed to get root iterator of GetManagedObjects";
if (entry->d_name[0] == '.')
continue;
if (strchr(entry->d_name, ':') != NULL) // ignore connected devices
continue;
FFBluetoothRadioResult* device = ffListAdd(devices);
ffStrbufInit(&device->name);
ffStrbufInit(&device->address);
ffStrbufInitStatic(&device->vendor, "Unknown");
device->lmpVersion = INT_MIN;
device->lmpSubversion = INT_MIN;
device->enabled = false;
detectBluetoothRoot(device, entry->d_name, &dbus);
}
detectBluetoothRoot(devices, &dbus, &rootIter);
dbus.lib->ffdbus_message_unref(managedObjects);
return NULL;
}
@@ -202,7 +145,7 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
#ifdef FF_HAVE_DBUS
return detectBluetooth(devices);
#else
FF_UNUSED(devices)
FF_UNUSED(devices)
return "Fastfetch was compiled without DBus support";
#endif
}
@@ -84,12 +84,12 @@ const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
BLUETOOTH_ADDRESS_STRUCT addr = { .ullLong = blri.localInfo.address };
ffStrbufInitF(&device->address, "%02x:%02x:%02x:%02x:%02x:%02x",
addr.rgBytes[0],
addr.rgBytes[1],
addr.rgBytes[2],
addr.rgBytes[3],
addr.rgBytes[5],
addr.rgBytes[4],
addr.rgBytes[5]);
addr.rgBytes[3],
addr.rgBytes[2],
addr.rgBytes[1],
addr.rgBytes[0]);
device->lmpVersion = blri.radioInfo.lmpVersion;
device->lmpSubversion = blri.radioInfo.lmpSubversion;
+17
View File
@@ -0,0 +1,17 @@
#include "board.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectBoard(FFBoardResult* board)
{
if (ffSysctlGetString("machdep.dmi.board-product", &board->name) == NULL)
ffCleanUpSmbiosValue(&board->name);
if (ffSysctlGetString("machdep.dmi.board-version", &board->version) == NULL)
ffCleanUpSmbiosValue(&board->version);
if (ffSysctlGetString("machdep.dmi.board-vendor", &board->vendor) == NULL)
ffCleanUpSmbiosValue(&board->vendor);
if (ffSysctlGetString("machdep.dmi.board-serial", &board->serial) == NULL)
ffCleanUpSmbiosValue(&board->serial);
return NULL;
}
+2 -2
View File
@@ -34,9 +34,9 @@ bool ffEfiFillLoadOption(const FFEfiLoadOption* efiOption, FFBootmgrResult* resu
ffEfiUcs2ToUtf8(efiOption->Description, &result->name);
for (
ffEfiDevicePathProtocol* filePathList = (void*) &efiOption->Description[descLen + 1];
ffEfiDevicePathProtocol* filePathList = (ffEfiDevicePathProtocol*) &efiOption->Description[descLen + 1];
filePathList->Type != 0x7F; // End of Hardware Device Path
filePathList = (void*) ((uint8_t*) filePathList + filePathList->Length))
filePathList = (ffEfiDevicePathProtocol*) ((uint8_t*) filePathList + filePathList->Length))
{
if (filePathList->Type == 4 && filePathList->SubType == 4)
{
+1 -1
View File
@@ -34,7 +34,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
brightness->current = status.brightness;
struct backlight_info info;
if(ioctl(blfd, BACKLIGHTGETINFO, &info) < 0)
if(ioctl(blfd, BACKLIGHTGETINFO, &info) == 0)
ffStrbufAppendS(&brightness->name, info.name);
else
ffStrbufAppendS(&brightness->name, path + strlen("/dev/backlight/"));
+1 -1
View File
@@ -99,7 +99,7 @@ double ddca_set_default_sleep_multiplier(double multiplier); // ddcutil 1.4
DDCA_Status ddca_init(const char *libopts, int syslog_level, int opts);
#endif
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
static const char* detectWithDdcci(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
@@ -0,0 +1,25 @@
#include "brightness.h"
#include "common/sysctl.h"
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
// https://man.netbsd.org/NetBSD-10.1/acpiout.4#DESCRIPTION
char key[] = "hw.acpi.acpiout0.brightness";
char* pn = key + strlen("hw.acpi.acpiout");
for (uint32_t i = 0; i <= 9; ++i)
{
*pn = (char) ('0' + i);
int value = ffSysctlGetInt(key, -1);
if (value == -1) continue;
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInitF(&brightness->name, "acpiout%d", i);
brightness->max = 100;
brightness->min = 0;
brightness->current = value;
}
return NULL;
}
@@ -0,0 +1,30 @@
#include "brightness.h"
#include "common/io/io.h"
#include <dev/wscons/wsconsio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFlist* result)
{
FF_AUTO_CLOSE_FD int devfd = open("/dev/ttyC0", O_RDONLY);
if (devfd < 0) return "open(dev/ttyC0, O_RDONLY) failed";
struct wsdisplay_param param = {
.param = WSDISPLAYIO_PARAM_BRIGHTNESS,
};
if (ioctl(devfd, WSDISPLAYIO_GETPARAM, &param) < 0)
return "ioctl(WSDISPLAYIO_GETPARAM) failed";
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
ffStrbufInitStatic(&brightness->name, "wsdisplay");
brightness->max = param.max;
brightness->min = param.min;
brightness->current = param.curval;
return NULL;
}
+17
View File
@@ -0,0 +1,17 @@
#include "chassis.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectChassis(FFChassisResult* chassis)
{
if (ffSysctlGetString("machdep.dmi.chassis-type", &chassis->type) == NULL)
ffCleanUpSmbiosValue(&chassis->type);
if (ffSysctlGetString("machdep.dmi.chassis-version", &chassis->version) == NULL)
ffCleanUpSmbiosValue(&chassis->version);
if (ffSysctlGetString("machdep.dmi.chassis-vendor", &chassis->vendor) == NULL)
ffCleanUpSmbiosValue(&chassis->vendor);
if (ffSysctlGetString("machdep.dmi.chassis-serial", &chassis->serial) == NULL)
ffCleanUpSmbiosValue(&chassis->serial);
return NULL;
}
+3
View File
@@ -16,6 +16,7 @@ const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu)
ffStrbufRemoveStrings(&cpu->name, ARRAY_SIZE(removeStrings), removeStrings);
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
ffStrbufRemoveDupWhitespaces(&cpu->name);
return NULL;
}
@@ -37,6 +38,8 @@ const char* ffCPUAppleCodeToName(uint32_t code)
case 6031:
case 6034: return "Apple M3 Max";
case 8132: return "Apple M4";
case 6040: return "Apple M4 Pro";
case 6041: return "Apple M4 Max";
default: return NULL;
}
}
+1
View File
@@ -15,6 +15,7 @@ typedef struct FFCPUResult
FFstrbuf name;
FFstrbuf vendor;
uint16_t packages;
uint16_t coresPhysical;
uint16_t coresLogical;
uint16_t coresOnline;
+7 -1
View File
@@ -59,7 +59,12 @@ static const char* detectFrequency(FFCPUResult* cpu)
pMax = pMax > pStart[i] ? pMax : pStart[i];
if (pMax > 0)
cpu->frequencyMax = pMax / 1000 / 1000;
{
if (pMax > 100000000) // Assume that pMax is in Hz, M1~M3
cpu->frequencyMax = pMax / 1000 / 1000;
else // Assume that pMax is in kHz, M4 and later (#1394)
cpu->frequencyMax = pMax / 1000;
}
return NULL;
}
@@ -104,6 +109,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
return "sysctlbyname(machdep.cpu.brand_string) failed";
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
cpu->packages = (uint16_t) ffSysctlGetInt("hw.packages", 1);
if (cpu->vendor.length == 0 && ffStrbufStartsWithS(&cpu->name, "Apple "))
ffStrbufAppendS(&cpu->vendor, "Apple");
+5 -1
View File
@@ -168,7 +168,8 @@ static const char* qcomPartId2name(uint32_t partId)
{
switch (partId)
{
case 0x001: return "Oryon";
case 0x001: return "Oryon 1";
case 0x002: return "Oryon 2";
case 0x00f: return "Scorpion";
case 0x02d: return "Scorpion";
case 0x04d: return "Krait";
@@ -262,6 +263,9 @@ static const char* applePartId2name(uint32_t partId)
case 0x037: return "Everest-A16";
case 0x038: return "Blizzard-M2-Max";
case 0x039: return "Avalanche-M2-Max";
case 0x046: return "Sawtooth-M11";
case 0x048: return "Sawtooth-M3-Max";
case 0x049: return "Everest-M3-Max";
default: return NULL;
}
}
+18 -2
View File
@@ -1,6 +1,12 @@
#include "cpu.h"
#include "common/sysctl.h"
#include <sys/param.h>
#if __has_include(<sys/cpuset.h>)
#include <sys/cpuset.h>
#define FF_HAVE_CPUSET 1
#endif
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
@@ -25,7 +31,7 @@ static const char* detectThermalTemp(double* current)
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("hw.model", &cpu->name))
if (ffSysctlGetString("hw.model", &cpu->name) != NULL)
return "sysctlbyname(hw.model) failed";
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
@@ -60,9 +66,19 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
}
}
#if FF_HAVE_CPUSET && (__x86_64__ || __i386__)
// Bind current process to the first two cores, which is *usually* a performance core
cpuset_t currentCPU;
CPU_ZERO(&currentCPU);
CPU_SET(1, &currentCPU);
CPU_SET(2, &currentCPU);
cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &currentCPU);
#endif
ffCPUDetectSpeedByCpuid(cpu);
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
+112 -36
View File
@@ -44,12 +44,20 @@ static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
if(
ffStrbufContainS(buffer, "cpu") ||
ffStrbufEqualS(buffer, "k10temp") || // AMD
ffStrbufEqualS(buffer, "fam15h_power") || // AMD
ffStrbufEqualS(buffer, "coretemp") // Intel
) return value / 1000.;
return 0.0/0.0;
}
static double detectTZTemp(FFstrbuf* buffer)
{
if (ffReadFileBuffer("/sys/class/thermal/thermal_zone0/temp", buffer))
return ffStrbufToDouble(buffer) / 1000.;
return 0.0/0.0;
}
static double detectCPUTemp(void)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
@@ -79,7 +87,7 @@ static double detectCPUTemp(void)
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return 0.0/0.0;
return detectTZTemp(&buffer);
}
#ifdef __ANDROID__
@@ -89,7 +97,9 @@ static void detectQualcomm(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
if (ffStrbufEqualS(&cpu->name, "SM8635"))
if (ffStrbufEqualS(&cpu->name, "SM8750"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Elite [SM8750]");
else if (ffStrbufEqualS(&cpu->name, "SM8635"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
else if (ffStrbufEqualS(&cpu->name, "SM8650-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 3 for Galaxy [SM8650-AC]");
@@ -134,6 +144,36 @@ static void detectQualcomm(FFCPUResult* cpu)
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 4 Gen 1 [SM4375]");
}
static void detectMediaTek(FFCPUResult* cpu)
{
// https://en.wikipedia.org/wiki/List_of_MediaTek_systems_on_chips
if (ffStrbufEqualS(&cpu->name, "MT6991"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991]");
else if (ffStrbufEqualS(&cpu->name, "MT6991Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9400 [MT6991Z]");
else if (ffStrbufEqualS(&cpu->name, "MT6989Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT6989Z]");
else if (ffStrbufEqualS(&cpu->name, "MT8796Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300+ [MT8796Z]");
else if (ffStrbufEqualS(&cpu->name, "MT6989"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT6989]");
else if (ffStrbufEqualS(&cpu->name, "MT8796"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9300 [MT8796]");
else if (ffStrbufEqualS(&cpu->name, "MT6985W"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200+ [MT6985W]");
else if (ffStrbufEqualS(&cpu->name, "MT6985"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9200 [MT6985]");
else if (ffStrbufEqualS(&cpu->name, "MT6983W"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT6983W]");
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/T"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000+ [MT8798Z/T]");
else if (ffStrbufEqualS(&cpu->name, "MT6983Z"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT6983Z]");
else if (ffStrbufEqualS(&cpu->name, "MT8798Z/C"))
ffStrbufSetStatic(&cpu->name, "MediaTek Dimensity 9000 [MT8798Z/C]");
}
static void detectAndroid(FFCPUResult* cpu)
{
if (cpu->name.length == 0)
@@ -151,46 +191,53 @@ static void detectAndroid(FFCPUResult* cpu)
if (ffStrbufEqualS(&cpu->vendor, "QTI") && ffStrbufStartsWithS(&cpu->name, "SM"))
detectQualcomm(cpu);
else if (ffStrbufEqualS(&cpu->vendor, "MTK") && ffStrbufStartsWithS(&cpu->name, "MT"))
detectMediaTek(cpu);
}
#endif
#if __arm__ || __aarch64__
#include "cpu_arm.h"
static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
static void detectArmName(FFstrbuf* cpuinfo, FFCPUResult* cpu, uint32_t implId)
{
FF_AUTO_FREE char* line = NULL;
rewind(cpuinfo);
char* line = NULL;
size_t len = 0;
uint32_t lastPartId = UINT32_MAX;
uint32_t num = 0;
while(getline(&line, &len, cpuinfo) != -1)
while(ffStrbufGetline(&line, &len, cpuinfo))
{
if (!ffStrStartsWith(line, "CPU part\t: ")) continue;
uint32_t partId = (uint32_t) strtoul(line + strlen("CPU part\t: "), NULL, 16);
const char* name = NULL;
if (partId > 0) // Linux reports 0 for unknown CPUs
switch (implId)
{
switch (implId)
{
case 0x41: name = armPartId2name(partId); break;
case 0x42: name = brcmPartId2name(partId); break;
case 0x43: name = caviumPartId2name(partId); break;
case 0x44: name = decPartId2name(partId); break;
case 0x46: name = fujitsuPartId2name(partId); break;
case 0x48: name = hisiPartId2name(partId); break;
case 0x4e: name = nvidiaPartId2name(partId); break;
case 0x50: name = apmPartId2name(partId); break;
case 0x51: name = qcomPartId2name(partId); break;
case 0x53: name = samsungPartId2name(partId); break;
case 0x56: name = marvellPartId2name(partId); break;
case 0x61: name = applePartId2name(partId); break;
case 0x66: name = faradayPartId2name(partId); break;
case 0x69: name = intelPartId2name(partId); break;
case 0x6d: name = msPartId2name(partId); break;
case 0x70: name = ftPartId2name(partId); break;
case 0xc0: name = amperePartId2name(partId); break;
}
case 0x41: name = armPartId2name(partId); break;
case 0x42: name = brcmPartId2name(partId); break;
case 0x43: name = caviumPartId2name(partId); break;
case 0x44: name = decPartId2name(partId); break;
case 0x46: name = fujitsuPartId2name(partId); break;
case 0x48: name = hisiPartId2name(partId); break;
case 0x4e: name = nvidiaPartId2name(partId); break;
case 0x50: name = apmPartId2name(partId); break;
case 0x51: name = qcomPartId2name(partId); break;
case 0x53: name = samsungPartId2name(partId); break;
case 0x56: name = marvellPartId2name(partId); break;
case 0x61:
if (partId == 0)
{
// https://github.com/Dr-Noob/cpufetch/issues/213#issuecomment-1927782105
ffStrbufSetStatic(&cpu->name, "Virtualized Apple Silicon");
ffStrbufGetlineRestore(&line, &len, cpuinfo);
return;
}
name = applePartId2name(partId);
break;
case 0x66: name = faradayPartId2name(partId); break;
case 0x69: name = intelPartId2name(partId); break;
case 0x6d: name = msPartId2name(partId); break;
case 0x70: name = ftPartId2name(partId); break;
case 0xc0: name = amperePartId2name(partId); break;
}
if (lastPartId != partId)
{
@@ -218,18 +265,18 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
#endif
static const char* parseCpuInfo(
FF_MAYBE_UNUSED FILE* cpuinfo,
FF_MAYBE_UNUSED FFCPUResult* cpu,
FFstrbuf* cpuinfo,
FFCPUResult* cpu,
FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer,
FF_MAYBE_UNUSED FFstrbuf* cpuMHz,
FF_MAYBE_UNUSED FFstrbuf* cpuIsa,
FF_MAYBE_UNUSED FFstrbuf* cpuUarch,
FF_MAYBE_UNUSED FFstrbuf* cpuImplementer)
{
FF_AUTO_FREE char* line = NULL;
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, cpuinfo) != -1)
while(ffStrbufGetline(&line, &len, cpuinfo))
{
//Stop after reasonable information is acquired
if((*line == '\0' || *line == '\n')
@@ -237,7 +284,10 @@ static const char* parseCpuInfo(
&& cpu->name.length > 0 // #1202 #1204
#endif
)
{
ffStrbufGetlineRestore(&line, &len, cpuinfo);
break;
}
(void)(
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
@@ -463,11 +513,32 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
}
}
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
{
const char* p = cpuinfo->chars;
uint64_t low = 0, high = 0;
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
{
if (!p) break;
p += strlen("\nphysical id\t:");
char* pend;
unsigned long id = strtoul(p, &pend, 10);
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
high |= 1 << (id - 64);
else
low |= 1 << id;
p = pend;
}
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
if(cpuinfo == NULL)
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
@@ -477,12 +548,17 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
const char* error = parseCpuInfo(cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
if (error) return error;
cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
#if __x86_64__ || __i386__
cpu->packages = getPackageCount(&cpuinfo);
if (cpu->packages > 1)
cpu->coresPhysical *= cpu->packages;
#endif
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
ffCPUDetectSpeedByCpuid(cpu);
@@ -517,7 +593,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
#endif
if (cpu->name.length == 0)
detectArmName(cpuinfo, cpu, cpuImplementer);
detectArmName(&cpuinfo, cpu, cpuImplementer);
#endif
return NULL;
+68
View File
@@ -0,0 +1,68 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "common/io/io.h"
#include <sys/envsys.h>
#include <prop/proplib.h>
#include <paths.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
static const char* detectCpuTemp(double* current)
{
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY);
if (fd < 0) return "open(_PATH_SYSMON, O_RDONLY) failed";
prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0)
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
prop_array_t array = prop_dictionary_get(root, "coretemp0");
if (!array) array = prop_dictionary_get(root, "amdzentemp0");
if (!array) array = prop_dictionary_get(root, "viac7temp0");
if (!array) array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
if (!array) return "No temp data found in root dictionary";
if (prop_array_count(array) != 2)
return "Unexpected `xtemp0` data";
prop_dictionary_t dict = prop_array_get(array, 0);
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY)
return "Unexpected `xtemp0[0]`";
int temp = 0; // in µK
if (!prop_dictionary_get_int(dict, "cur-value", &temp))
return "Failed to get temperature";
*current = temp / 1e6 - 273.15;
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL)
{
if (ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL)
return "sysctlbyname(machdep.cpu_brand) failed";
}
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL)
ffStrbufTrimRightSpace(&cpu->vendor);
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
ffCPUDetectSpeedByCpuid(cpu);
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
if (freq > cpu->frequencyBase) cpu->frequencyBase = freq;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp) detectCpuTemp(&cpu->temperature);
return NULL;
}
+14 -2
View File
@@ -1,6 +1,9 @@
#include "cpu.h"
#include "common/sysctl.h"
#include <sys/time.h>
#include <sys/sensors.h>
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString(CTL_HW, HW_MODEL, &cpu->name))
@@ -12,8 +15,17 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
ffCPUDetectSpeedByCpuid(cpu);
cpu->frequencyBase = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
cpu->temperature = FF_CPU_TEMP_UNSET; // HW_SENSORS?
uint32_t cpuspeed = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
if (cpuspeed > cpu->frequencyBase) cpu->frequencyBase = cpuspeed;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
{
struct sensor sensors;
size_t size = sizeof(sensors);
if (sysctl((int[]) {CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0}, 5, &sensors, &size, NULL, 0) == 0)
cpu->temperature = (double) (sensors.value - 273150000) / 1E6;
}
return NULL;
}
+5 -3
View File
@@ -100,9 +100,7 @@ static const char* detectNCores(FFCPUResult* cpu)
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
)
{
if (ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if (ptr->Relationship == RelationGroup)
if (ptr->Relationship == RelationGroup)
{
for (uint32_t index = 0; index < ptr->Group.ActiveGroupCount; ++index)
{
@@ -110,6 +108,10 @@ static const char* detectNCores(FFCPUResult* cpu)
cpu->coresLogical += ptr->Group.GroupInfo[index].MaximumProcessorCount;
}
}
else if (ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if (ptr->Relationship == RelationProcessorPackage)
cpu->packages++;
}
return NULL;
+1 -1
View File
@@ -2,7 +2,7 @@
#include "fastfetch.h"
typedef enum FFCPUCacheType
typedef enum __attribute__((__packed__)) FFCPUCacheType
{
FF_CPU_CACHE_TYPE_UNIFIED = 0,
FF_CPU_CACHE_TYPE_INSTRUCTION = 1,
+7 -7
View File
@@ -20,35 +20,35 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
{
*pNum = (char) ('0' + i);
ffStrCopyN(pSubkey, "physicalcpu", lenLeft);
ffStrCopy(pSubkey, "physicalcpu", lenLeft);
uint32_t ncpu = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (ncpu <= 0) continue;
ffStrCopyN(pSubkey, "l1icachesize", lenLeft);
ffStrCopy(pSubkey, "l1icachesize", lenLeft);
uint32_t size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_INSTRUCTION)->num = ncpu;
ffStrCopyN(pSubkey, "l1dcachesize", lenLeft);
ffStrCopy(pSubkey, "l1dcachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_DATA)->num = ncpu;
ffStrCopyN(pSubkey, "l2cachesize", lenLeft);
ffStrCopy(pSubkey, "l2cachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
{
ffStrCopyN(pSubkey, "cpusperl2", lenLeft);
ffStrCopy(pSubkey, "cpusperl2", lenLeft);
uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (cpuSper)
ffCPUCacheAddItem(result, 2, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
}
ffStrCopyN(pSubkey, "l3cachesize", lenLeft);
ffStrCopy(pSubkey, "l3cachesize", lenLeft);
size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (size)
{
ffStrCopyN(pSubkey, "cpusperl3", lenLeft);
ffStrCopy(pSubkey, "cpusperl3", lenLeft);
uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
if (cpuSper)
ffCPUCacheAddItem(result, 3, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
+4 -4
View File
@@ -36,8 +36,8 @@ retry:
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
if (cpuTime2->totalAll <= cpuTime1->totalAll)
{
if (++retryCount <= 3)
@@ -51,8 +51,8 @@ retry:
for (uint32_t i = 0; i < cpuTimes1.length; ++i)
{
FFCpuUsageInfo* cpuTime1 = ffListGet(&cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
*(double*) ffListAdd(result) = (double)(cpuTime2->inUseAll - cpuTime1->inUseAll) / (double)(cpuTime2->totalAll - cpuTime1->totalAll) * 100;
cpuTime1->inUseAll = cpuTime2->inUseAll;
cpuTime1->totalAll = cpuTime2->totalAll;
+8 -4
View File
@@ -6,15 +6,19 @@
#include <sys/resource.h>
#include <stdlib.h>
#ifdef __OpenBSD__
#if __OpenBSD__ || __NetBSD__
#include <sys/sched.h>
#endif
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
size_t neededLength = 0;
#ifdef __OpenBSD__
int ctls[] = {CTL_KERN, KERN_CPTIME};
#if __OpenBSD__|| __NetBSD__
#ifdef KERN_CPTIME
int ctls[] = {CTL_KERN, KERN_CPTIME};
#else
int ctls[] = {CTL_KERN, KERN_CP_TIME};
#endif
if (sysctl(ctls, 2, NULL, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
@@ -27,7 +31,7 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);
#ifdef __OpenBSD__
#if __OpenBSD__ || __NetBSD__
if (sysctl(ctls, 2, cpTimes, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
+29 -4
View File
@@ -5,7 +5,17 @@
#include <sys/mount.h>
#include <sys/stat.h>
#ifdef __NetBSD__
#include <sys/types.h>
#include <sys/statvfs.h>
#define getfsstat(...) getvfsstat(__VA_ARGS__)
#define statfs statvfs
#define f_flags f_flag
#define f_bsize f_frsize
#endif
#ifdef __FreeBSD__
#if __has_include(<libgeom.h>)
#include <libgeom.h>
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
@@ -42,6 +52,12 @@ static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
return NULL;
}
#else
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
{
return "Fastfetch was compiled without libgeom support";
}
#endif
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
@@ -51,7 +67,7 @@ static void detectFsInfo(struct statfs* fs, FFDisk* disk)
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
: FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
}
else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi"))
else if(fs->f_flags & MNT_IGNORE)
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else if(!(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
@@ -95,7 +111,15 @@ void detectFsInfo(struct statfs* fs, FFDisk* disk)
#else
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
FF_UNUSED(fs, disk);
#ifdef MNT_IGNORE
if(fs->f_flags & MNT_IGNORE)
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else
#endif
if(!(fs->f_flags & MNT_LOCAL))
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
#endif
@@ -117,7 +141,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
if(!ffDiskMatchMountpoint(options, fs->f_mntonname))
continue;
}
else if(!ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs"))
else if(!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs"))
continue;
#ifdef __FreeBSD__
@@ -151,10 +175,11 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
#ifdef __OpenBSD__
#define st_birthtimespec __st_birthtim
#endif
#ifndef __DragonFly__
struct stat st;
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
#endif
}
return NULL;
+2 -2
View File
@@ -176,7 +176,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
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);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
return true;
}
@@ -188,7 +188,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
//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);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqual(&currentDisk->mountFrom, &otherDevice->mountFrom))
return true;
+2 -2
View File
@@ -48,7 +48,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
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);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
return true;
}
@@ -60,7 +60,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
//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);
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
if(ffStrbufEqual(&currentDisk->mountFrom, &otherDevice->mountFrom))
return true;
+2 -2
View File
@@ -56,8 +56,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
for (uint32_t i = 0; i < result->length; ++i)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
FFDiskIOResult* icPrev = FF_LIST_GET(FFDiskIOResult, ioCounters1, i);
FFDiskIOResult* icCurr = FF_LIST_GET(FFDiskIOResult, *result, i);
if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
return "Physical disk device path changed";
+48
View File
@@ -1,4 +1,7 @@
#include "diskio.h"
#if __has_include(<libgeom.h>)
#include "util/stringUtils.h"
#include <devstat.h>
@@ -58,3 +61,48 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
return NULL;
}
#else
#include <devstat.h>
#include <memory.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
if (checkversion() < 0)
return "checkversion() failed";
struct statinfo stats = {
.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)),
};
if (getdevs(&stats) < 0)
return "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->bytesRead = current->bytes_read;
device->readCount = current->num_reads;
device->bytesWritten = current->bytes_written;
device->writeCount = current->num_writes;
}
free(stats.dinfo->mem_ptr);
free(stats.dinfo);
return NULL;
}
#endif
+38
View File
@@ -0,0 +1,38 @@
#include "diskio.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <sys/iostat.h>
#include <sys/sysctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
int mib[] = {CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl)};
size_t len;
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
return "sysctl({HW_IOSTATS}, NULL) failed";
uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl));
struct io_sysctl* stats = malloc(len);
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
return "sysctl({HW_IOSTATS}, stats) failed";
for (uint32_t i = 0; i < nDrive; ++i)
{
struct io_sysctl* st = &stats[i];
if (options->namePrefix.length && strncmp(st->name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", st->name);
ffStrbufInitS(&device->name, st->name);
device->bytesRead = st->rbytes;
device->readCount = st->rxfer;
device->bytesWritten = st->wbytes;
device->writeCount = st->wxfer;
}
return NULL;
}
+38
View File
@@ -0,0 +1,38 @@
#include "diskio.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <sys/disk.h>
#include <sys/sysctl.h>
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
int mib[] = {CTL_HW, HW_DISKSTATS};
size_t len;
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0)
return "sysctl({HW_DISKSTATS}, NULL) failed";
uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats));
struct diskstats* stats = malloc(len);
if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0)
return "sysctl({HW_DISKSTATS}, stats) failed";
for (uint32_t i = 0; i < nDrive; ++i)
{
struct diskstats* st = &stats[i];
if (options->namePrefix.length && strncmp(st->ds_name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", st->ds_name);
ffStrbufInitS(&device->name, st->ds_name);
device->bytesRead = st->ds_rbytes;
device->readCount = st->ds_rxfer;
device->bytesWritten = st->ds_wbytes;
device->writeCount = st->ds_wxfer;
}
return NULL;
}
+2 -2
View File
@@ -27,12 +27,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->devPath, ks->ks_name);
ffStrbufInit(&device->devPath);
ffStrbufInitS(&device->name, ks->ks_name);
device->bytesRead = kio.nread;
device->readCount = kio.reads;
device->bytesWritten = kio.nwritten;
device->writeCount = kio.writes;
ffStrbufInitS(&device->name, ks->ks_name);
}
return NULL;
+7 -1
View File
@@ -7,6 +7,9 @@ FFDisplayResult* ffdsAppendDisplay(
double refreshRate,
uint32_t scaledWidth,
uint32_t scaledHeight,
uint32_t preferredWidth,
uint32_t preferredHeight,
double preferredRefreshRate,
uint32_t rotation,
FFstrbuf* name,
FFDisplayType type,
@@ -19,12 +22,15 @@ FFDisplayResult* ffdsAppendDisplay(
if(width == 0 || height == 0)
return NULL;
FFDisplayResult* display = ffListAdd(&result->displays);
FFDisplayResult* display = (FFDisplayResult*) ffListAdd(&result->displays);
display->width = width;
display->height = height;
display->refreshRate = refreshRate;
display->scaledWidth = scaledWidth;
display->scaledHeight = scaledHeight;
display->preferredWidth = preferredWidth;
display->preferredHeight = preferredHeight;
display->preferredRefreshRate = preferredRefreshRate;
display->rotation = rotation;
ffStrbufInitMove(&display->name, name);
display->type = type;
+18 -10
View File
@@ -36,19 +36,21 @@
#define FF_WM_PRETTY_ICEWM "IceWM"
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
#define FF_WM_PRETTY_DTWM "dtwm"
#define FF_WM_PRETTY_FVWM "fvwm"
#define FF_WM_PRETTY_CTWM "ctwm"
#define FF_WM_PRETTY_RATPOISON "ratpoison"
#define FF_WM_PROTOCOL_TTY "TTY"
#define FF_WM_PROTOCOL_X11 "X11"
#define FF_WM_PROTOCOL_WAYLAND "Wayland"
typedef enum FFDisplayType {
typedef enum __attribute__((__packed__)) FFDisplayType {
FF_DISPLAY_TYPE_UNKNOWN,
FF_DISPLAY_TYPE_BUILTIN,
FF_DISPLAY_TYPE_EXTERNAL,
} FFDisplayType;
typedef enum FFDisplayHdrStatus
typedef enum __attribute__((__packed__)) FFDisplayHdrStatus
{
FF_DISPLAY_HDR_STATUS_UNKNOWN,
FF_DISPLAY_HDR_STATUS_UNSUPPORTED,
@@ -58,17 +60,20 @@ typedef enum FFDisplayHdrStatus
typedef struct FFDisplayResult
{
uint32_t width;
uint32_t height;
double refreshRate;
uint32_t scaledWidth;
uint32_t scaledHeight;
uint32_t width; // in px
uint32_t height; // in px
double refreshRate; // in Hz
uint32_t scaledWidth; // in px
uint32_t scaledHeight; // in px
uint32_t preferredWidth; // in px
uint32_t preferredHeight; // in px
double preferredRefreshRate; // in Hz
FFstrbuf name;
FFDisplayType type;
uint32_t rotation;
uint64_t id; // platform dependent
uint32_t physicalWidth;
uint32_t physicalHeight;
uint32_t physicalWidth; // in mm
uint32_t physicalHeight; // in mm
bool primary;
const char* platformApi;
uint8_t bitDepth;
@@ -97,6 +102,9 @@ FFDisplayResult* ffdsAppendDisplay(
double refreshRate,
uint32_t scaledWidth,
uint32_t scaledHeight,
uint32_t preferredWidth,
uint32_t preferredHeight,
double preferredRefreshRate,
uint32_t rotation,
FFstrbuf* name,
FFDisplayType type,
@@ -61,6 +61,9 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
0,
0,
0,
0,
0,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
false,
@@ -97,6 +100,9 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
(uint32_t) (height / scaleFactor + .5),
0,
0,
0,
0,
NULL,
FF_DISPLAY_TYPE_BUILTIN,
false,
0,
@@ -36,6 +36,8 @@ static void detectDisplays(FFDisplayServerResult* ds)
if (refreshRate == 0)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
CVDisplayLinkRef link;
if(CVDisplayLinkCreateWithCGDisplay(screen, &link) == kCVReturnSuccess)
{
@@ -44,6 +46,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
refreshRate = time.timeScale / (double) time.timeValue; //59.97...
CVDisplayLinkRelease(link);
}
#pragma clang diagnostic pop
}
ffStrbufClear(&buffer);
@@ -57,7 +60,11 @@ static void detectDisplays(FFDisplayServerResult* ds)
displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
}
#endif
uint32_t physicalWidth = 0, physicalHeight = 0;
uint32_t preferredWidth = 0, preferredHeight = 0;
double preferredRefreshRate = 0;
if(displayInfo)
{
CFDictionaryRef productNames;
@@ -73,9 +80,35 @@ static void detectDisplays(FFDisplayServerResult* ds)
if (edidLength >= 128)
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
}
if (!physicalWidth || !physicalHeight)
{
if (ffCfDictGetInt(displayInfo, CFSTR(kDisplayHorizontalImageSize), (int*) &physicalWidth) == NULL)
ffCfDictGetInt(displayInfo, CFSTR(kDisplayVerticalImageSize), (int*) &physicalHeight);
}
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), (int*) &preferredWidth);
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), (int*) &preferredHeight);
if (preferredWidth && preferredHeight)
{
FF_CFTYPE_AUTO_RELEASE CFArrayRef allModes = CGDisplayCopyAllDisplayModes(screen, NULL);
if (allModes)
{
for (CFIndex i = 0, count = CFArrayGetCount(allModes); i < count; i++)
{
CGDisplayModeRef modeInfo = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, i);
if (CGDisplayModeGetPixelWidth(modeInfo) == preferredWidth && CGDisplayModeGetPixelHeight(modeInfo) == preferredHeight)
{
double rr = CGDisplayModeGetRefreshRate(modeInfo);
if (rr > preferredRefreshRate) preferredRefreshRate = rr;
break;
}
}
}
}
}
if (!physicalWidth || !physicalHeight)
if ((!physicalWidth || !physicalHeight) && CGDisplayPrimaryDisplay(screen) == screen) // #1406
{
CGSize size = CGDisplayScreenSize(screen);
physicalWidth = (uint32_t) (size.width + 0.5);
@@ -88,6 +121,9 @@ static void detectDisplays(FFDisplayServerResult* ds)
refreshRate,
(uint32_t)CGDisplayModeGetWidth(mode),
(uint32_t)CGDisplayModeGetHeight(mode),
preferredWidth,
preferredHeight,
preferredRefreshRate,
(uint32_t)CGDisplayRotation(screen),
&buffer,
CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
@@ -99,6 +135,10 @@ static void detectDisplays(FFDisplayServerResult* ds)
);
if (display)
{
#ifndef MAC_OS_X_VERSION_10_11
FF_CFTYPE_AUTO_RELEASE CFStringRef pe = CGDisplayModeCopyPixelEncoding(mode);
if (pe) display->bitDepth = (uint8_t) (CFStringGetLength(pe) - CFStringFind(pe, CFSTR("B"), 0).location);
#else
// https://stackoverflow.com/a/33519316/9976392
// Also shitty, but better than parsing `CFCopyDescription(mode)`
CFDictionaryRef dict = (CFDictionaryRef) *((int64_t *)mode + 2);
@@ -108,8 +148,9 @@ static void detectDisplays(FFDisplayServerResult* ds)
ffCfDictGetInt(dict, kCGDisplayBitsPerSample, &bitDepth);
display->bitDepth = (uint8_t) bitDepth;
}
#endif
if (display->type == FF_DISPLAY_TYPE_BUILTIN)
if (display->type == FF_DISPLAY_TYPE_BUILTIN && displayInfo)
display->hdrStatus = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance"))
? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
#ifdef MAC_OS_X_VERSION_10_15
@@ -127,11 +168,15 @@ static void detectDisplays(FFDisplayServerResult* ds)
#endif
display->serial = CGDisplaySerialNumber(screen);
int value;
if (ffCfDictGetInt(displayInfo, CFSTR(kDisplayYearOfManufacture), &value) == NULL)
display->manufactureYear = (uint16_t) value;
if (ffCfDictGetInt(displayInfo, CFSTR(kDisplayWeekOfManufacture), &value) == NULL)
display->manufactureWeek = (uint16_t) value;
if (displayInfo)
{
int value;
if (ffCfDictGetInt(displayInfo, CFSTR(kDisplayYearOfManufacture), &value) == NULL)
display->manufactureYear = (uint16_t) value;
if (ffCfDictGetInt(displayInfo, CFSTR(kDisplayWeekOfManufacture), &value) == NULL)
display->manufactureWeek = (uint16_t) value;
}
}
CGDisplayModeRelease(mode);
}
@@ -149,12 +149,30 @@ static void detectDisplays(FFDisplayServerResult* ds)
default: rotation = 0; break;
}
DISPLAYCONFIG_TARGET_PREFERRED_MODE preferredMode = {
.header = {
.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE,
.size = sizeof(preferredMode),
.adapterId = path->targetInfo.adapterId,
.id = path->targetInfo.id,
}
};
double preferredRefreshRate = 0;
if (DisplayConfigGetDeviceInfo(&preferredMode.header) == ERROR_SUCCESS)
{
DISPLAYCONFIG_RATIONAL freq = preferredMode.targetMode.targetVideoSignalInfo.vSyncFreq;
preferredRefreshRate = freq.Numerator / (double) freq.Denominator;
}
FFDisplayResult* display = ffdsAppendDisplay(ds,
width,
height,
path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator,
(uint32_t) (monitorInfo->info.rcMonitor.right - monitorInfo->info.rcMonitor.left),
(uint32_t) (monitorInfo->info.rcMonitor.bottom - monitorInfo->info.rcMonitor.top),
preferredMode.width,
preferredMode.height,
preferredRefreshRate,
rotation,
&name,
path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER ? FF_DISPLAY_TYPE_UNKNOWN :
@@ -218,19 +236,24 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067
const FFOSResult* os = ffDetectOS();
if(
ffStrbufEqualS(&os->version, "11") ||
ffStrbufEqualS(&os->version, "10") ||
ffStrbufEqualS(&os->version, "2022") ||
ffStrbufEqualS(&os->version, "2019") ||
ffStrbufEqualS(&os->version, "2016")
) ffStrbufSetStatic(&ds->dePrettyName, "Fluent");
else if(
ffStrbufEqualS(&os->version, "8") ||
ffStrbufEqualS(&os->version, "8.1") ||
ffStrbufEqualS(&os->version, "2012 R2") ||
ffStrbufEqualS(&os->version, "2012")
) ffStrbufSetStatic(&ds->dePrettyName, "Metro");
uint32_t ver = (uint32_t) ffStrbufToUInt(&os->version, 0);
if (ver > 1000)
{
// Windows Server
if (ver >= 2016)
ffStrbufSetStatic(&ds->dePrettyName, "Fluent");
else if (ver >= 2012)
ffStrbufSetStatic(&ds->dePrettyName, "Metro");
else
ffStrbufSetStatic(&ds->dePrettyName, "Aero");
}
else
ffStrbufSetStatic(&ds->dePrettyName, "Aero");
{
if (ver >= 10)
ffStrbufSetStatic(&ds->dePrettyName, "Fluent");
else if (ver >= 8)
ffStrbufSetStatic(&ds->dePrettyName, "Metro");
else
ffStrbufSetStatic(&ds->dePrettyName, "Aero");
}
}
@@ -54,18 +54,11 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
//Try the x11 libs, from most feature rich to least.
//We use the display list to detect if a connection is needed.
//They respect wmProtocolName, and only detect display if it is set.
if(ds->displays.length == 0)
ffdsConnectXcbRandr(ds);
if(ds->displays.length == 0)
ffdsConnectXrandr(ds);
if(ds->displays.length == 0)
ffdsConnectXcb(ds);
if(ds->displays.length == 0)
ffdsConnectXlib(ds);
}
//This display detection method is display server independent.
@@ -86,7 +79,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
if (ffSettingsGetFreeBSDKenv("screen.height", &buf))
{
uint32_t height = (uint32_t) ffStrbufToUInt(&buf, 0);
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0, "kenv");
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0, "kenv");
}
}
}
@@ -5,11 +5,7 @@
const char* ffdsConnectWayland(FFDisplayServerResult* result);
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result);
const char* ffdsConnectXcb(FFDisplayServerResult* result);
const char* ffdsConnectXrandr(FFDisplayServerResult* result);
const char* ffdsConnectXlib(FFDisplayServerResult* result);
const char* ffdsConnectDrm(FFDisplayServerResult* result);
void ffdsDetectWMDE(FFDisplayServerResult* result);
+47 -24
View File
@@ -84,6 +84,8 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
width, height,
refreshRate,
0, 0,
0, 0,
0,
0,
&name,
ffdsGetDisplayType(plainName),
@@ -218,12 +220,14 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetCrtc)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetFB)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeResources)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeFB)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeProperty)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreePropertyBlob)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmFreeDevices)
@@ -252,28 +256,29 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
continue;
#endif
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
FF_AUTO_CLOSE_FD int primaryFd = open(path, O_RDWR | O_CLOEXEC);
if (primaryFd < 0)
continue;
drmModeRes* res = ffdrmModeGetResources(fd);
drmModeRes* res = ffdrmModeGetResources(primaryFd);
if (!res)
continue;
for (int iConn = 0; iConn < res->count_connectors; ++iConn)
{
drmModeConnector* conn = ffdrmModeGetConnectorCurrent(fd, res->connectors[iConn]);
drmModeConnector* conn = ffdrmModeGetConnectorCurrent(primaryFd, res->connectors[iConn]);
if (!conn)
continue;
if (conn->connection != DRM_MODE_DISCONNECTED)
{
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
drmModeEncoder* encoder = ffdrmModeGetEncoder(primaryFd, conn->encoder_id);
uint32_t width = 0, height = 0, refreshRate = 0;
uint8_t bitDepth = 0;
if (encoder)
{
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
drmModeCrtc* crtc = ffdrmModeGetCrtc(primaryFd, encoder->crtc_id);
if (crtc)
{
width = crtc->mode.hdisplay;
@@ -292,28 +297,42 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
}
}
}
drmModeFBPtr fb = ffdrmModeGetFB(primaryFd, crtc->buffer_id);
if (fb)
{
bitDepth = (uint8_t) (fb->depth / 3);
ffdrmModeFreeFB(fb);
}
ffdrmModeFreeCrtc(crtc);
}
ffdrmModeFreeEncoder(encoder);
}
uint32_t preferredWidth = 0, preferredHeight = 0, preferredRefreshRate = 0;
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
{
drmModeModeInfo* mode = &conn->modes[iMode];
if (mode->type & DRM_MODE_TYPE_PREFERRED)
{
preferredWidth = mode->hdisplay;
preferredHeight = mode->vdisplay;
preferredRefreshRate = mode->vrefresh;
break;
}
}
// NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
// Assume preferred resolution is used as what we do in drmParseSys
if (width == 0 || height == 0)
{
// NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
// Assume preferred resolution is used as what we do in drmParseSys
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
{
drmModeModeInfo* mode = &conn->modes[iMode];
if (mode->type & DRM_MODE_TYPE_PREFERRED)
{
width = mode->hdisplay;
height = mode->vdisplay;
refreshRate = mode->vrefresh;
break;
}
}
width = preferredWidth;
height = preferredHeight;
refreshRate = preferredRefreshRate;
}
@@ -324,7 +343,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
for (int iProp = 0; iProp < conn->count_props; ++iProp)
{
drmModePropertyRes *prop = ffdrmModeGetProperty(fd, conn->props[iProp]);
drmModePropertyRes *prop = ffdrmModeGetProperty(primaryFd, conn->props[iProp]);
if (!prop)
continue;
@@ -334,9 +353,9 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
drmModePropertyBlobPtr blob = NULL;
if (prop->count_blobs > 0 && prop->blob_ids != NULL)
blob = ffdrmModeGetPropertyBlob(fd, prop->blob_ids[0]);
blob = ffdrmModeGetPropertyBlob(primaryFd, prop->blob_ids[0]);
else
blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
blob = ffdrmModeGetPropertyBlob(primaryFd, (uint32_t) conn->prop_values[iProp]);
if (blob)
{
@@ -382,6 +401,9 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
refreshRate,
0,
0,
preferredWidth,
preferredHeight,
preferredRefreshRate,
0,
&name,
conn->connector_type == DRM_MODE_CONNECTOR_eDP || conn->connector_type == DRM_MODE_CONNECTOR_LVDS
@@ -401,6 +423,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
item->serial = serial;
item->manufactureYear = myear;
item->manufactureWeek = mweak;
item->bitDepth = bitDepth;
}
}
@@ -6,13 +6,20 @@
static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
{
if(!(flags & WL_OUTPUT_MODE_CURRENT))
return;
WaylandDisplay* display = data;
display->width = width;
display->height = height;
display->refreshRate = refreshRate;
if (flags & WL_OUTPUT_MODE_CURRENT)
{
display->width = width;
display->height = height;
display->refreshRate = refreshRate;
}
if (flags & WL_OUTPUT_MODE_PREFERRED)
{
display->preferredWidth = width;
display->preferredHeight = height;
display->preferredRefreshRate = refreshRate;
}
}
static void waylandOutputScaleListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, int32_t scale)
@@ -79,9 +86,6 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
WaylandDisplay display = {
.parent = wldata,
.width = 0,
.height = 0,
.refreshRate = 0,
.scale = 1,
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
.type = FF_DISPLAY_TYPE_UNKNOWN,
@@ -118,6 +122,9 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
display.refreshRate / 1000.0,
(uint32_t) (display.width / display.scale),
(uint32_t) (display.height / display.scale),
(uint32_t) display.preferredWidth,
(uint32_t) display.preferredHeight,
display.preferredRefreshRate / 1000.0,
rotation,
display.edidName.length
? &display.edidName
@@ -1,4 +1,4 @@
/* Generated by wayland-scanner 1.22.0 */
/* Generated by wayland-scanner 1.23.1 */
#ifndef KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
#define KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
@@ -53,6 +53,11 @@ struct kde_output_device_v2;
* This object is published as global during start up for every available
* display devices, or when one later becomes available, for example by
* being hotplugged via a physical connector.
*
* Warning! The protocol described in this file is a desktop environment
* implementation detail. Regular clients must not use this protocol.
* Backward incompatible changes may be added without bumping the major
* version of the extension.
* @section page_iface_kde_output_device_v2_api API
* See @ref iface_kde_output_device_v2.
*/
@@ -75,6 +80,11 @@ struct kde_output_device_v2;
* This object is published as global during start up for every available
* display devices, or when one later becomes available, for example by
* being hotplugged via a physical connector.
*
* Warning! The protocol described in this file is a desktop environment
* implementation detail. Regular clients must not use this protocol.
* Backward incompatible changes may be added without bumping the major
* version of the extension.
*/
extern const struct wl_interface kde_output_device_v2_interface;
#endif
@@ -199,6 +209,11 @@ enum kde_output_device_v2_capability {
* @since 5
*/
KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE = 0x40,
/**
* if this outputdevice supports the brightness setting
* @since 9
*/
KDE_OUTPUT_DEVICE_V2_CAPABILITY_BRIGHTNESS = 0x80,
};
/**
* @ingroup iface_kde_output_device_v2
@@ -216,6 +231,10 @@ enum kde_output_device_v2_capability {
* @ingroup iface_kde_output_device_v2
*/
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE_SINCE_VERSION 5
/**
* @ingroup iface_kde_output_device_v2
*/
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_BRIGHTNESS_SINCE_VERSION 9
#endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */
#ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM
@@ -274,6 +293,29 @@ enum kde_output_device_v2_color_profile_source {
};
#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM */
#ifndef KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM
#define KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM
/**
* @ingroup iface_kde_output_device_v2
* tradeoff between power and accuracy
*
* The compositor can do a lot of things that trade between
* performance, power and color accuracy. This setting describes
* a high level preference from the user about in which direction
* that tradeoff should be made.
*/
enum kde_output_device_v2_color_power_tradeoff {
/**
* prefer efficiency and performance
*/
KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_EFFICIENCY = 0,
/**
* prefer accuracy
*/
KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ACCURACY = 1,
};
#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_ENUM */
/**
* @ingroup iface_kde_output_device_v2
* @struct kde_output_device_v2_listener
@@ -593,6 +635,29 @@ struct kde_output_device_v2_listener {
void (*brightness)(void *data,
struct kde_output_device_v2 *kde_output_device_v2,
uint32_t brightness);
/**
* the preferred color/power tradeoff
*
*
* @since 10
*/
void (*color_power_tradeoff)(void *data,
struct kde_output_device_v2 *kde_output_device_v2,
uint32_t preference);
/**
* dimming multiplier
*
* This is the dimming multiplier of the output. This is similar
* to the brightness setting, except it's meant to be a temporary
* setting only, not persistent and may be implemented differently
* depending on the display. 0 is the minimum dimming factor (not
* completely dark) and 10000 means the output is not dimmed.
* @param multiplier multiplier in 0-10000
* @since 11
*/
void (*dimming)(void *data,
struct kde_output_device_v2 *kde_output_device_v2,
uint32_t multiplier);
};
/**
@@ -706,34 +771,42 @@ kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device
* @ingroup iface_kde_output_device_v2
*/
#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_SINCE_VERSION 8
/**
* @ingroup iface_kde_output_device_v2
*/
#define KDE_OUTPUT_DEVICE_V2_COLOR_POWER_TRADEOFF_SINCE_VERSION 10
/**
* @ingroup iface_kde_output_device_v2
*/
#define KDE_OUTPUT_DEVICE_V2_DIMMING_SINCE_VERSION 11
// /** @ingroup iface_kde_output_device_v2 */
// static inline void
// kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data)
// {
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data);
// }
/** @ingroup iface_kde_output_device_v2 */
static inline void
kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data);
}
// /** @ingroup iface_kde_output_device_v2 */
// static inline void *
// kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2)
// {
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2);
// }
/** @ingroup iface_kde_output_device_v2 */
static inline void *
kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2);
}
// static inline uint32_t
// kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2)
// {
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2);
// }
static inline uint32_t
kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2)
{
return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2);
}
// /** @ingroup iface_kde_output_device_v2 */
// static inline void
// kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
// {
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
// }
/** @ingroup iface_kde_output_device_v2 */
static inline void
kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
{
wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
}
/**
* @ingroup iface_kde_output_device_mode_v2
@@ -811,32 +884,32 @@ kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_out
#define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1
// /** @ingroup iface_kde_output_device_mode_v2 */
// static inline void
// kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data)
// {
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data);
// }
/** @ingroup iface_kde_output_device_mode_v2 */
static inline void
kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data);
}
// /** @ingroup iface_kde_output_device_mode_v2 */
// static inline void *
// kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
// {
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2);
// }
/** @ingroup iface_kde_output_device_mode_v2 */
static inline void *
kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2);
}
// static inline uint32_t
// kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
// {
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2);
// }
static inline uint32_t
kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
{
return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2);
}
// /** @ingroup iface_kde_output_device_mode_v2 */
// static inline void
// kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
// {
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2);
// }
/** @ingroup iface_kde_output_device_mode_v2 */
static inline void
kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
{
wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2);
}
#ifdef __cplusplus
}
@@ -1,6 +1,6 @@
#ifdef FF_HAVE_WAYLAND
/* Generated by wayland-scanner 1.22.0 */
/* Generated by wayland-scanner 1.23.1 */
/*
* SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
@@ -12,6 +12,7 @@
* SPDX-License-Identifier: MIT-CMU
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <wayland-util.h>
@@ -57,12 +58,14 @@ static const struct wl_message kde_output_device_v2_events[] = {
{ "sdr_gamut_wideness", "6u", kde_output_device_v2_types + 0 },
{ "color_profile_source", "7u", kde_output_device_v2_types + 0 },
{ "brightness", "8u", kde_output_device_v2_types + 0 },
{ "color_power_tradeoff", "10u", kde_output_device_v2_types + 0 },
{ "dimming", "11u", kde_output_device_v2_types + 0 },
};
WL_EXPORT const struct wl_interface kde_output_device_v2_interface = {
"kde_output_device_v2", 8,
"kde_output_device_v2", 11,
0, NULL,
25, kde_output_device_v2_events,
27, kde_output_device_v2_events,
};
static const struct wl_message kde_output_device_mode_v2_events[] = {
@@ -11,26 +11,33 @@ typedef struct WaylandKdeMode
int32_t width;
int32_t height;
int32_t refreshRate;
bool preferred;
struct kde_output_device_mode_v2* pMode;
} WaylandKdeMode;
static void waylandKdeSizeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t width, int32_t height)
static void waylandKdeModeSizeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t width, int32_t height)
{
WaylandKdeMode* mode = (WaylandKdeMode*) data;
mode->width = width;
mode->height = height;
}
static void waylandKdeRefreshListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t rate)
static void waylandKdeModeRefreshListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t rate)
{
WaylandKdeMode* mode = (WaylandKdeMode*) data;
mode->refreshRate = rate;
}
static void waylandKdeModePreferredListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_)
{
WaylandKdeMode* mode = (WaylandKdeMode*) data;
mode->preferred = true;
}
static const struct kde_output_device_mode_v2_listener modeListener = {
.size = waylandKdeSizeListener,
.refresh = waylandKdeRefreshListener,
.preferred = (void*) stubListener,
.size = waylandKdeModeSizeListener,
.refresh = waylandKdeModeRefreshListener,
.preferred = waylandKdeModePreferredListener,
.removed = (void*) stubListener,
};
@@ -40,7 +47,7 @@ static void waylandKdeModeListener(void* data, FF_MAYBE_UNUSED struct kde_output
if (!wldata->internal) return;
WaylandKdeMode* newMode = ffListAdd((FFlist*) wldata->internal);
newMode->pMode = mode;
*newMode = (WaylandKdeMode) { .pMode = mode };
// Strangely, the listener is called only in this function, but not in `waylandKdeCurrentModeListener`
wldata->parent->ffwl_proxy_add_listener((struct wl_proxy *) mode, (void (**)(void)) &modeListener, newMode);
@@ -52,18 +59,24 @@ static void waylandKdeCurrentModeListener(void* data, FF_MAYBE_UNUSED struct kde
WaylandDisplay* wldata = (WaylandDisplay*) data;
if (!wldata->internal) return;
WaylandKdeMode* current = NULL;
int set = 0;
FF_LIST_FOR_EACH(WaylandKdeMode, m, *(FFlist*) wldata->internal)
{
if (m->pMode == mode)
{
current = m;
break;
wldata->width = m->width;
wldata->height = m->height;
wldata->refreshRate = m->refreshRate;
if (++set == 2) break;
}
if (m->preferred)
{
wldata->preferredWidth = m->width;
wldata->preferredHeight = m->height;
wldata->preferredRefreshRate = m->refreshRate;
if (++set == 2) break;
}
}
wldata->width = current->width;
wldata->height = current->height;
wldata->refreshRate = current->refreshRate;
}
static void waylandKdeScaleListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, wl_fixed_t scale)
@@ -114,6 +127,7 @@ static void waylandKdeNameListener(void* data, FF_MAYBE_UNUSED struct kde_output
display->type = ffdsGetDisplayType(name);
// As display->id is used as an internal identifier, we don't need it to be NUL terminated
strncpy((char*) &display->id, name, sizeof(display->id));
ffStrbufAppendS(&display->name, name);
}
@@ -149,6 +163,8 @@ static struct kde_output_device_v2_listener outputListener = {
.sdr_gamut_wideness = (void*) stubListener,
.color_profile_source = (void*) stubListener,
.brightness = (void*) stubListener,
.color_power_tradeoff = (void*) stubListener,
.dimming = (void*) stubListener,
};
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
@@ -160,9 +176,6 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode));
WaylandDisplay display = {
.parent = wldata,
.width = 0,
.height = 0,
.refreshRate = 0,
.scale = 1,
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
.type = FF_DISPLAY_TYPE_UNKNOWN,
@@ -187,6 +200,9 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
display.refreshRate / 1000.0,
(uint32_t) (display.width / display.scale),
(uint32_t) (display.height / display.scale),
(uint32_t) display.preferredWidth,
(uint32_t) display.preferredHeight,
display.preferredRefreshRate / 1000.0,
rotation,
display.edidName.length
? &display.edidName
@@ -18,10 +18,18 @@
#include "kde-output-order-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#ifdef __linux__
#if __FreeBSD__
#include <sys/un.h>
#include <sys/ucred.h>
#include <sys/sysctl.h>
#endif
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
{
struct ucred ucred;
#if __linux__ || (__FreeBSD__ && !__DragonFly__)
#if __linux
struct ucred ucred = {};
socklen_t len = sizeof(ucred);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1 || ucred.pid <= 0)
return false;
@@ -30,6 +38,19 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed.
if (!ffReadFileBuffer(procPath.chars, &result->wmProcessName))
return false;
#else
struct xucred ucred = {};
socklen_t len = sizeof(ucred);
if (getsockopt(fd, AF_UNSPEC, LOCAL_PEERCRED, &ucred, &len) == -1 || ucred.cr_pid <= 0)
return false;
size_t size = 4096;
ffStrbufEnsureFixedLengthFree(&result->wmProcessName, (uint32_t) size);
if(sysctl((int[]){CTL_KERN, KERN_PROC, KERN_PROC_ARGS, ucred.cr_pid}, 4, result->wmProcessName.chars, &size, NULL, 0 ) != 0)
return false;
result->wmProcessName.length = (uint32_t) size - 1;
#endif
// #1135: wl-restart is a special case
const char* filename = strrchr(result->wmProcessName.chars, '/');
@@ -39,20 +60,18 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
filename = result->wmProcessName.chars;
if (ffStrEquals(filename, "wl-restart"))
ffStrbufSubstrAfterFirstC(&result->wmProcessName, '\0');
ffStrbufSubstrAfterLastC(&result->wmProcessName, '\0');
ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
return true;
}
#else
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
{
FF_UNUSED(fd, result);
return false;
}
#endif
}
static void waylandGlobalAddListener(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
{
@@ -83,7 +102,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
}
}
static bool matchDrmConnector(const char* connName, WaylandDisplay* wldata)
static FF_MAYBE_UNUSED bool matchDrmConnector(const char* connName, WaylandDisplay* wldata)
{
// https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output-event-name
// The doc says that "do not assume that the name is a reflection of an underlying DRM connector, X11 connection, etc."
@@ -129,8 +148,10 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
if (display->id) return;
display->type = ffdsGetDisplayType(name);
#if __linux__
if (!display->edidName.length)
matchDrmConnector(name, display);
#endif
display->id = ffWaylandGenerateIdFromName(name);
ffStrbufAppendS(&display->name, name);
}
@@ -9,7 +9,7 @@
#include "../displayserver_linux.h"
typedef enum WaylandProtocolType
typedef enum __attribute__((__packed__)) WaylandProtocolType
{
FF_WAYLAND_PROTOCOL_TYPE_NONE,
FF_WAYLAND_PROTOCOL_TYPE_GLOBAL,
@@ -36,9 +36,12 @@ typedef struct WaylandDisplay
WaylandData* parent;
int32_t width;
int32_t height;
int32_t refreshRate;
int32_t preferredWidth;
int32_t preferredHeight;
int32_t preferredRefreshRate;
int32_t physicalWidth;
int32_t physicalHeight;
int32_t refreshRate;
double scale;
enum wl_output_transform transform;
FFDisplayType type;
@@ -20,34 +20,43 @@ typedef struct WaylandZwlrMode
int32_t width;
int32_t height;
int32_t refreshRate;
bool preferred;
struct zwlr_output_mode_v1* pMode;
} WaylandZwlrMode;
static void waylandZwlrSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_mode_v1 *zwlr_output_mode_v1, int32_t width, int32_t height)
static void waylandZwlrModeSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_mode_v1 *zwlr_output_mode_v1, int32_t width, int32_t height)
{
WaylandZwlrMode* mode = (WaylandZwlrMode*) data;
mode->width = width;
mode->height = height;
}
static void waylandZwlrRefreshListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_mode_v1 *zwlr_output_mode_v1, int32_t rate)
static void waylandZwlrModeRefreshListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_mode_v1 *zwlr_output_mode_v1, int32_t rate)
{
WaylandZwlrMode* mode = (WaylandZwlrMode*) data;
mode->refreshRate = rate;
}
static void waylandZwlrModePreferredListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_mode_v1 *zwlr_output_mode_v1)
{
WaylandZwlrMode* mode = (WaylandZwlrMode*) data;
mode->preferred = true;
}
static const struct zwlr_output_mode_v1_listener modeListener = {
.size = waylandZwlrSizeListener,
.refresh = waylandZwlrRefreshListener,
.preferred = (void*) stubListener,
.size = waylandZwlrModeSizeListener,
.refresh = waylandZwlrModeRefreshListener,
.preferred = waylandZwlrModePreferredListener,
.finished = (void*) stubListener,
};
static void waylandZwlrModeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, struct zwlr_output_mode_v1 *mode)
{
WaylandDisplay* wldata = (WaylandDisplay*) data;
if (!wldata->internal) return;
WaylandZwlrMode* newMode = ffListAdd((FFlist*) wldata->internal);
newMode->pMode = mode;
*newMode = (WaylandZwlrMode) { .pMode = mode };
// Strangely, the listener is called only in this function, but not in `waylandZwlrCurrentModeListener`
wldata->parent->ffwl_proxy_add_listener((struct wl_proxy *) mode, (void (**)(void)) &modeListener, newMode);
@@ -57,18 +66,26 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw
{
// waylandZwlrModeListener is always run before this
WaylandDisplay* wldata = (WaylandDisplay*) data;
WaylandZwlrMode* current = NULL;
if (!wldata->internal) return;
int set = 0;
FF_LIST_FOR_EACH(WaylandZwlrMode, m, *(FFlist*) wldata->internal)
{
if (m->pMode == mode)
{
current = m;
break;
wldata->width = m->width;
wldata->height = m->height;
wldata->refreshRate = m->refreshRate;
if (++set == 2) break;
}
if (m->preferred)
{
wldata->preferredWidth = m->width;
wldata->preferredHeight = m->height;
wldata->preferredRefreshRate = m->refreshRate;
if (++set == 2) break;
}
}
wldata->width = current->width;
wldata->height = current->height;
wldata->refreshRate = current->refreshRate;
}
static void waylandZwlrPhysicalSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, int32_t width, int32_t height)
@@ -78,12 +95,18 @@ static void waylandZwlrPhysicalSizeListener(void* data, FF_MAYBE_UNUSED struct z
wldata->physicalHeight = height;
}
static void waylandZwlrEnabledListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, bool enabled)
{
WaylandDisplay* wldata = (WaylandDisplay*) data;
if (!enabled) wldata->internal = NULL;
}
static const struct zwlr_output_head_v1_listener headListener = {
.name = (void*) ffWaylandOutputNameListener,
.description = (void*) ffWaylandOutputDescriptionListener,
.physical_size = waylandZwlrPhysicalSizeListener,
.mode = waylandZwlrModeListener,
.enabled = (void*) stubListener,
.enabled = (void*) waylandZwlrEnabledListener,
.current_mode = waylandZwlrCurrentModeListener,
.position = (void*) stubListener,
.transform = waylandZwlrTransformListener,
@@ -102,9 +125,6 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandZwlrMode));
WaylandDisplay display = {
.parent = wldata,
.width = 0,
.height = 0,
.refreshRate = 0,
.scale = 1,
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
.type = FF_DISPLAY_TYPE_UNKNOWN,
@@ -117,7 +137,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
wldata->ffwl_proxy_add_listener((struct wl_proxy*) head, (void(**)(void)) &headListener, &display);
wldata->ffwl_display_roundtrip(wldata->display);
if(display.width <= 0 || display.height <= 0)
if(display.width <= 0 || display.height <= 0 || !display.internal)
return;
uint32_t rotation = ffWaylandHandleRotation(&display);
@@ -128,6 +148,9 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
display.refreshRate / 1000.0,
(uint32_t) (display.width / display.scale + 0.5),
(uint32_t) (display.height / display.scale + 0.5),
(uint32_t) display.preferredWidth,
(uint32_t) display.preferredHeight,
display.preferredRefreshRate / 1000.0,
rotation,
display.edidName.length
? &display.edidName
+44 -5
View File
@@ -8,16 +8,19 @@
#include <string.h>
#include <unistd.h>
#ifdef __FreeBSD__
#if __FreeBSD__
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/user.h>
#elif defined(__OpenBSD__)
#elif __OpenBSD__
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#elif defined(__sun)
#elif __sun
#include <procfs.h>
#elif __NetBSD__
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
static const char* parseEnv(void)
@@ -59,6 +62,9 @@ static const char* parseEnv(void)
if(getenv("HYPRLAND_CMD") != NULL)
return "Hyprland";
if(getenv("SWAYSOCK") != NULL)
return "Sway";
#ifdef __linux__
if(
getenv("WAYLAND_DISPLAY") != NULL &&
@@ -123,8 +129,14 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
else if(ffStrEqualsIgnCase(name, "dtwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
else if(ffStrEqualsIgnCase(name, "fvwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_FVWM);
else if(ffStrEqualsIgnCase(name, "ctwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_CTWM);
else if(ffStrEqualsIgnCase(name, "hyprland"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HYPRLAND);
else if(ffStrEqualsIgnCase(name, "ratpoison"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_RATPOISON);
}
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
@@ -257,6 +269,10 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
uint32_t userId = getuid();
#if __FreeBSD__
#ifdef __DragonFly__
#define ki_comm kp_comm
#endif
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
size_t length = 0;
@@ -289,10 +305,10 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
for (int i = 0; i < count; ++i)
{
if(result->dePrettyName.length == 0)
applyPrettyNameIfDE(result, proc->p_comm);
applyPrettyNameIfDE(result, proc[i].p_comm);
if(result->wmPrettyName.length == 0)
applyNameIfWM(result, proc->p_comm);
applyNameIfWM(result, proc[i].p_comm);
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
@@ -384,6 +400,29 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
if(result->wmPrettyName.length == 0)
applyNameIfWM(result, processName.chars);
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
#elif __NetBSD__
int request[] = {CTL_KERN, KERN_PROC2, KERN_PROC_UID, (int) userId, sizeof(struct kinfo_proc2), INT_MAX};
size_t size = 0;
if(sysctl(request, ARRAY_SIZE(request), NULL, &size, NULL, 0) != 0)
return "sysctl(KERN_PROC_UID, NULL) failed";
FF_AUTO_FREE struct kinfo_proc2* procs = malloc(size);
if(sysctl(request, ARRAY_SIZE(request), procs, &size, NULL, 0) != 0)
return "sysctl(KERN_PROC_UID, procs) failed";
for(struct kinfo_proc2* proc = procs; proc < procs + (size / sizeof(struct kinfo_proc2)); proc++)
{
if(result->dePrettyName.length == 0)
applyPrettyNameIfDE(result, proc->p_comm);
if(result->wmPrettyName.length == 0)
applyNameIfWM(result, proc->p_comm);
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
+35 -93
View File
@@ -1,11 +1,15 @@
#include "displayserver_linux.h"
#include "util/mallocHelper.h"
#include "common/time.h"
#ifdef FF_HAVE_XCB
#ifdef FF_HAVE_XCB_RANDR
#include "common/library.h"
#include "common/time.h"
#include "util/edidHelper.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <string.h>
#include <xcb/randr.h>
#include <xcb/xcb.h>
typedef struct XcbPropertyData
@@ -82,72 +86,6 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
ffStrbufSetS(&result->wmProcessName, wmName);
}
const char* ffdsConnectXcb(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(xcb, "dlopen lbxcb failed", "libxcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_connect)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_get_setup)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_setup_roots_iterator)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_screen_next)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_disconnect)
XcbPropertyData propertyData;
bool propertyDataInitialized = xcbInitPropertyData(xcb, &propertyData);
xcb_connection_t* connection = ffxcb_connect(NULL, NULL);
if(connection == NULL)
return "xcb_connect failed";
xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(connection));
if(iterator.rem > 0 && propertyDataInitialized)
xcbDetectWMfromEWMH(&propertyData, connection, iterator.data->root, result);
while(iterator.rem > 0)
{
xcb_screen_t* screen = iterator.data;
ffdsAppendDisplay(result,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
0,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0,
(uint32_t) screen->width_in_millimeters,
(uint32_t) screen->height_in_millimeters,
"xcb"
);
ffxcb_screen_next(&iterator);
}
ffxcb_disconnect(connection);
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
const char* ffdsConnectXcb(FFDisplayServerResult* result)
{
//Do nothing. There are other implementations coming
FF_UNUSED(result)
return "Fastfetch was compiled without XCB support";
}
#endif
#ifdef FF_HAVE_XCB_RANDR
#include "util/edidHelper.h"
#include <xcb/randr.h>
typedef struct XcbRandrData
{
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current)
@@ -181,28 +119,6 @@ typedef struct XcbRandrData
xcb_randr_get_screen_resources_current_reply_t* screenResources;
} XcbRandrData;
static double xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode)
{
//We do the check here, because we want the best fallback display if this call failed
if(data->screenResources == NULL)
return 0;
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(data->screenResources);
while(modesIterator.rem > 0)
{
if(modesIterator.data->id == mode)
{
xcb_randr_mode_info_t* modeInfo = modesIterator.data;
return (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
}
data->ffxcb_randr_mode_info_next(&modesIterator);
}
return 0;
}
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength)
{
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME);
@@ -227,13 +143,38 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
break;
}
xcb_randr_mode_info_t* currentMode = NULL;
xcb_randr_mode_info_t* preferredMode = NULL;
if(data->screenResources)
{
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(data->screenResources);
if (output->num_preferred > 0)
preferredMode = modesIterator.data;
while (modesIterator.rem > 0)
{
if (modesIterator.data->id == crtcInfoReply->mode)
{
currentMode = modesIterator.data;
break;
}
data->ffxcb_randr_mode_info_next(&modesIterator);
}
}
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
xcbRandrHandleMode(data, crtcInfoReply->mode),
currentMode ? (double) currentMode->dot_clock / (double) ((uint32_t) currentMode->htotal * currentMode->vtotal) : 0,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
preferredMode ? (uint32_t) preferredMode->width : 0,
preferredMode ? (uint32_t) preferredMode->height : 0,
preferredMode ? (double) preferredMode->dot_clock / (double) ((uint32_t) preferredMode->htotal * preferredMode->vtotal) : 0,
rotation,
name,
displayType,
@@ -247,7 +188,6 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
{
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetPhysicalSize(edidData, &item->physicalWidth, &item->physicalHeight);
}
return !!item;
@@ -323,6 +263,7 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
0,
(uint32_t) monitor->width,
(uint32_t) monitor->height,
0, 0, 0,
0,
&name,
displayType,
@@ -378,6 +319,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
0,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
0, 0, 0,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
+26 -76
View File
@@ -1,9 +1,13 @@
#include "displayserver_linux.h"
#ifdef FF_HAVE_X11
#ifdef FF_HAVE_XRANDR
#include "common/library.h"
#include "common/parsing.h"
#include "util/edidHelper.h"
#include "util/stringUtils.h"
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
typedef struct X11PropertyData
@@ -58,66 +62,6 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
data->ffXFree(wmWindow);
}
const char* ffdsConnectXlib(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(x11, "dlopen libX11 failed", "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XCloseDisplay)
X11PropertyData propertyData;
bool propertyDataInitialized = x11InitPropertyData(x11, &propertyData);
Display* display = ffXOpenDisplay(x11);
if(display == NULL)
return "XOpenDisplay failed";
if(propertyDataInitialized && ScreenCount(display) > 0)
x11DetectWMFromEWMH(&propertyData, display, result);
for(int i = 0; i < ScreenCount(display); i++)
{
Screen* screen = ScreenOfDisplay(display, i);
ffdsAppendDisplay(result,
(uint32_t) WidthOfScreen(screen),
(uint32_t) HeightOfScreen(screen),
0,
(uint32_t) WidthOfScreen(screen),
(uint32_t) HeightOfScreen(screen),
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0,
(uint32_t) WidthMMOfScreen(screen),
(uint32_t) HeightMMOfScreen(screen),
"xlib"
);
}
ffXCloseDisplay(display);
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
if(result->wmProtocolName.length == 0)
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
return NULL;
}
#else
const char* ffdsConnectXlib(FFDisplayServerResult* result)
{
//Do nothing. WM / DE detection will use environment vars to detect as much as possible.
FF_UNUSED(result);
return "Fastfetch was compiled without libX11 support";
}
#endif //FF_HAVE_X11
#ifdef FF_HAVE_XRANDR
#include "util/edidHelper.h"
#include <X11/extensions/Xrandr.h>
typedef struct XrandrData
{
FF_LIBRARY_SYMBOL(XInternAtom)
@@ -141,19 +85,6 @@ typedef struct XrandrData
XRRScreenResources* screenResources;
} XrandrData;
static double xrandrHandleMode(XrandrData* data, RRMode mode)
{
for(int i = 0; i < data->screenResources->nmode; i++)
{
if(data->screenResources->modes[i].id == mode)
{
XRRModeInfo* modeInfo = &data->screenResources->modes[i];
return (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
}
}
return 0;
}
static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength)
{
//We do the check here, because we want the best fallback display if this call failed
@@ -181,13 +112,31 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
break;
}
XRRModeInfo* currentMode = NULL;
if (data->screenResources)
{
for(int i = 0; i < data->screenResources->nmode; i++)
{
if(data->screenResources->modes[i].id == crtcInfo->mode)
{
currentMode = &data->screenResources->modes[i];
break;
}
}
}
XRRModeInfo* preferredMode = data->screenResources && output->npreferred > 0 ? &data->screenResources->modes[0] : NULL;
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfo->width,
(uint32_t) crtcInfo->height,
xrandrHandleMode(data, crtcInfo->mode),
currentMode ? (double) currentMode->dotClock / (double) ((uint32_t) currentMode->hTotal * currentMode->vTotal) : 0,
(uint32_t) crtcInfo->width,
(uint32_t) crtcInfo->height,
preferredMode ? (uint32_t) preferredMode->width : 0,
preferredMode ? (uint32_t) preferredMode->height : 0,
preferredMode ? (double) preferredMode->dotClock / (double) ((uint32_t) preferredMode->hTotal * preferredMode->vTotal) : 0,
rotation,
name,
displayType,
@@ -202,7 +151,6 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
{
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
ffEdidGetPhysicalSize(edidData, &item->physicalWidth, &item->physicalHeight);
}
data->ffXRRFreeCrtcInfo(crtcInfo);
@@ -264,6 +212,7 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
0,
(uint32_t) monitorInfo->width,
(uint32_t) monitorInfo->height,
0, 0, 0,
0,
&name,
displayType,
@@ -315,6 +264,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
0,
(uint32_t) WidthOfScreen(screen),
(uint32_t) HeightOfScreen(screen),
0, 0, 0,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
+10 -19
View File
@@ -95,7 +95,7 @@ const char* ffDetectEditor(FFEditorResult* result)
if (ffStrbufEqualS(&result->exe, "nvim"))
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
else if (ffStrbufEqualS(&result->exe, "vim"))
else if (ffStrbufEqualS(&result->exe, "vim") || ffStrbufStartsWithS(&result->exe, "vim."))
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
else if (ffStrbufEqualS(&result->exe, "nano"))
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
@@ -106,6 +106,7 @@ const char* ffDetectEditor(FFEditorResult* result)
if (
ffStrbufEqualS(&result->exe, "nano") ||
ffStrbufEqualS(&result->exe, "vim") ||
ffStrbufStartsWithS(&result->exe, "vim.") || // vim.basic/vim.tiny
ffStrbufEqualS(&result->exe, "nvim") ||
ffStrbufEqualS(&result->exe, "micro") ||
ffStrbufEqualS(&result->exe, "emacs") ||
@@ -134,24 +135,14 @@ const char* ffDetectEditor(FFEditorResult* result)
return NULL;
ffStrbufSubstrBeforeFirstC(&result->version, '\n');
for (uint32_t iStart = 0; iStart < result->version.length; ++iStart)
{
char c = result->version.chars[iStart];
if (ffCharIsDigit(c))
{
for (uint32_t iEnd = iStart + 1; iEnd < result->version.length; ++iEnd)
{
char c = result->version.chars[iEnd];
if (isspace(c))
{
ffStrbufSubstrBefore(&result->version, iEnd);
break;
}
}
if (iStart > 0)
ffStrbufSubstrAfter(&result->version, iStart - 1);
break;
}
const char* versionStart = strpbrk(result->version.chars, "0123456789");
if (versionStart != NULL) {
const char* versionEnd = strpbrk(versionStart, " \t\v\f\r");
if (versionEnd != NULL)
ffStrbufSubstrBefore(&result->version, (uint32_t)(versionEnd - result->version.chars));
if (versionStart != result->version.chars)
ffStrbufSubstrAfter(&result->version, (uint32_t)(versionStart - result->version.chars - 1));
}
return NULL;
+6 -1
View File
@@ -4,7 +4,12 @@
#include <stdio.h>
#include <fcntl.h>
#include <usbhid.h>
#include <dev/usb/usb_ioctl.h>
#if __has_include(<dev/usb/usb_ioctl.h>)
#include <dev/usb/usb_ioctl.h> // FreeBSD
#else
#include <bus/u4b/usb_ioctl.h> // DragonFly
#endif
#define MAX_UHID_JOYS 64
+3 -3
View File
@@ -16,7 +16,7 @@ const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
const char* ffGetGPUVendorString(unsigned vendorId)
const char* ffGPUGetVendorString(unsigned vendorId)
{
// https://devicehunt.com/all-pci-vendors
switch (vendorId)
@@ -51,9 +51,9 @@ const char* detectByOpenGL(FFlist* gpus)
{
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
gpu->type = FF_GPU_TYPE_UNKNOWN;
ffStrbufInit(&gpu->vendor);
ffStrbufInitMove(&gpu->vendor, &result.vendor);
ffStrbufInitMove(&gpu->name, &result.renderer);
ffStrbufInitMove(&gpu->driver, &result.vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
+2 -2
View File
@@ -46,8 +46,8 @@ typedef struct FFGPUResult
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
const char* ffGetGPUVendorString(unsigned vendorId);
const char* ffGPUGetVendorString(unsigned vendorId);
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__NetBSD__) || defined(__OpenBSD__)
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
#endif
+1 -1
View File
@@ -66,7 +66,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
if (result.index)
*result.type = (uint32_t) device->adlAdapterIndex;
*result.index = (uint32_t) device->adlAdapterIndex;
if (result.name)
ffStrbufSetS(result.name, device->adapterString);
+8 -2
View File
@@ -68,7 +68,13 @@ static const char* detectFrequency(FFGPUResult* gpu)
pMax = pMax > pStart[i] ? pMax : pStart[i];
if (pMax > 0)
gpu->frequency = pMax / 1000 / 1000;
{
// While this is not necessary for now (seems), we add this logic just in case. See cpu_apple.c
if (pMax > 100000000) // Assume that pMax is in Hz
gpu->frequency = pMax / 1000 / 1000;
else // Assume that pMax is in kHz
gpu->frequency = pMax / 1000;
}
return NULL;
}
@@ -155,7 +161,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
int vendorId;
if(ffCfDictGetInt(properties, CFSTR("vendor-id"), &vendorId) == NULL)
{
const char* vendorStr = ffGetGPUVendorString((unsigned) vendorId);
const char* vendorStr = ffGPUGetVendorString((unsigned) vendorId);
ffStrbufAppendS(&gpu->vendor, vendorStr);
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE || vendorStr == FF_GPU_VENDOR_NAME_INTEL)
gpu->type = FF_GPU_TYPE_INTEGRATED;
+6 -4
View File
@@ -2,12 +2,14 @@
#include "common/io/io.h"
#include "common/properties.h"
#include "util/mallocHelper.h"
#include "util/stringUtils.h"
#include <dev/pci/pcireg.h>
#include <sys/pciio.h>
#include <fcntl.h>
#if __has_include(<dev/pci/pcireg.h>)
#include <dev/pci/pcireg.h> // FreeBSD
#else
#include <bus/pci/pcireg.h> // DragonFly
#endif
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
@@ -36,7 +38,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
struct pci_conf* pc = &confs[i];
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(pc->pc_vendor));
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(pc->pc_vendor));
ffStrbufInit(&gpu->name);
ffStrbufInitS(&gpu->driver, pc->pd_name);
ffStrbufInit(&gpu->platformApi);

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