Compare commits

...

125 Commits

Author SHA1 Message Date
Carter Li 4059bca941 Merge pull request #1323 from fastfetch-cli/dev
Release: v2.27.1
2024-10-06 12:35:51 +08:00
Carter Li bb94ac7832 Release: v2.27.1 2024-10-06 12:31:47 +08:00
Carter Li d5d935a658 DisplayServer (Linux): fix invalid display name detection 2024-10-06 12:27:49 +08:00
Carter Li 44ccc69834 Merge pull request #1320 from fastfetch-cli/dev
Release:v 2.27.0
2024-10-06 11:15:18 +08:00
Carter Li 6bcfc3a61e Doc: update README.md [ci skip] 2024-10-06 10:25:50 +08:00
李通洲 2d356aa644 IO: don't reuse va_list
Fix #1321
2024-10-06 09:29:54 +08:00
李通洲 9ea887e841 TerminalFont: fix possible buffer overflow 2024-10-06 09:27:55 +08:00
Carter Li 5f3ce50022 Display (Linux): prefer detecting physical size from EDID 2024-10-05 23:56:16 +08:00
apocelipes acfab74d4b LocalIP: document show-mtu and show-speed command line options (#1318)
Also add these options to shell completions.
2024-10-05 21:49:29 +08:00
李通洲 24c3f0d6b9 Version (Android): correctly report sysName 2024-10-05 18:47:00 +08:00
李通洲 c2ec1e9606 CMake: fix building on Android 2024-10-05 18:42:47 +08:00
李通洲 951a15b61b LocalIP: only print properties if detected in JSON results 2024-10-05 17:45:45 +08:00
Carter Li f30501f365 Display (macOS): fix invalid physical size on old Intel Mac 2024-10-05 17:22:32 +08:00
李通洲 bde6c3b829 Logo (Builtin): add ValhallaOS
Fix #1316
2024-10-05 15:46:20 +08:00
李通洲 7fac54e7b8 Doc: update changelog 2024-10-05 11:52:59 +08:00
XeroArch d4c8a4c9fd Logo (Builtin): add XeroArch Ascii logo (#1312)
* putting xeroarch logo in askii

* updating logo

* updating

* updating

* uploading xeroarch ascii logo

* upgrading fetch ascii logo

* fixing a very small issue

* removing unecessary line

* removing trailing lines
2024-10-05 11:42:27 +08:00
李通洲 b34283eaf0 Chore: fix a warning of warning 2024-10-05 11:33:57 +08:00
李通洲 67964363e8 Doc: update changelog [ci skip] 2024-10-05 10:41:42 +08:00
李通洲 41a1b3a9d5 CI: test showFlags 2024-10-05 10:33:14 +08:00
Carter Li 320283a538 LocalIP: fix bug that flags are appended multiple times 2024-10-05 10:28:43 +08:00
apocelipes 40ab735e6b LocalIp: support get interface flags (#1315) 2024-10-05 09:49:27 +08:00
Carter Li 716bfe7cc1 Global: use glob(3) if wordexp(3) is not available 2024-10-04 20:00:28 +08:00
李通洲 84fc5b4503 TPM (Windows): corrently report TPM device is not found
Fix #1314
2024-10-04 19:58:55 +08:00
李通洲 729085e054 CI: add OpenBSD 2024-10-04 18:01:02 +08:00
Carter Li a32d9d788c OpenBSD: init platform support 2024-10-04 17:49:18 +08:00
李通洲 d06f9a1509 Chore (Windows): silence some warnings 2024-10-04 17:49:18 +08:00
李通洲 c2b60a2ebf Logo (Builtin): remove some paddings 2024-10-03 21:58:38 +08:00
李通洲 937b2e41ed Terminal (Linux): remove invalid info when fail to detect terminal by process tracing 2024-10-03 21:58:37 +08:00
李通洲 aa734e2220 Doc: fix Json schema [ci skip] 2024-10-03 21:58:37 +08:00
Carter Li a4fe933625 Doc: update changelog for 2.27.0 2024-10-03 21:05:36 +08:00
Carter Li 53a373c9cf Monitor: don't deprecate this module 2024-10-03 20:58:14 +08:00
Carter Li 46c8bc1f99 Board (Linux): trim strings 2024-10-03 20:47:31 +08:00
Andrew Davis 8a11aa0f8f Completions (zsh, fish): check for python3 (#1310)
Both the zsh and fish completions depend on python3.
When the completitions kick in with those shells where no python3 is
found it throws errors.

Check python3 is installed, otherwise return no completitions to avoid
throwing errors

Co-authored-by: Andrew Davis <adavis@adavis.net>
2024-10-02 21:30:19 +08:00
kralverde 89d3924659 CPU (Linux): fix temperature detection (#1308)
Return proper NaN instead of false -> 0.0 coercion
2024-10-02 07:43:58 +08:00
Carter Li b49c509a6c DateTime: add day-pretty
Fix #1305
2024-10-01 17:44:23 +08:00
Carter Li 99626149f6 Display (FreeBSD): add guards between linux specific code 2024-10-01 17:26:29 +08:00
李通洲 3381262930 Monitor: make it an alias of Display module 2024-10-01 12:10:15 +08:00
李通洲 6dd6266a2a GPU (Linux): fix possible buffer overflow 2024-10-01 09:30:39 +08:00
李通洲 18be6c8fd1 Display: don't use non-ascii charactors
Which cannot be displayed in Linux console
2024-09-30 23:42:08 +08:00
李通洲 5bdae7afc3 Display: display ppi in integer 2024-09-30 23:40:47 +08:00
李通洲 316849e5df Monitor: remove module 2024-09-30 23:35:34 +08:00
李通洲 d5c395fb85 Display (Windows): merge features of Monitor module 2024-09-30 23:25:08 +08:00
李通洲 46eb0e4b1c Display (Linux): merge features of Monitor module 2024-09-30 22:43:29 +08:00
李通洲 fb0a18dc82 Display (macOS): merge monitor module features 2024-09-30 20:16:24 +08:00
李通洲 ca442b3da4 Monitor (macOS): improve performance 2024-09-30 19:53:10 +08:00
李通洲 a32361fdc5 Brightness: add new option --brightness-compact 2024-09-30 15:45:06 +08:00
Carter Li d77f0fe3d9 CPU (Linux): detect SOC name if available 2024-09-30 15:09:06 +08:00
Carter Li 1df129083b GPU (Linux): add a special case for brcm 2024-09-30 15:02:49 +08:00
Carter Li 2cd6cb3ca1 Board (Linux): use /proc/device-tree/board if available 2024-09-30 15:00:55 +08:00
李通洲 eeb2d1c746 Doc: update README.md [ci skip] 2024-09-30 10:26:44 +08:00
李通洲 d97999ddc9 GPU (Linux): trim trailing new line
Fix #1303
2024-09-29 23:08:41 +08:00
Carter Li 70e8398f05 Packaging: update debian stuff [ci skip] 2024-09-29 16:22:54 +08:00
Carter Li 0b32abd5a7 Merge pull request #1302 from fastfetch-cli/dev
Release: v2.26.1
2024-09-29 15:50:33 +08:00
李通洲 73e61c2b89 Release: v2.26.1 2024-09-29 15:42:31 +08:00
李通洲 1901b9308f GPU: use adapterLuid as deviceID for non-pci devices 2024-09-29 15:42:31 +08:00
李通洲 a7c7493733 GPU (Windows): fix uninitialized variables 2024-09-29 15:34:57 +08:00
李通洲 73f98f9509 CMake: allow to disable pacstall 2024-09-29 14:18:23 +08:00
Carter Li 3d82d55e5d Packaging: update debian stuff [ci skip] 2024-09-29 13:34:25 +08:00
Carter Li 6485d34700 Merge pull request #1298 from fastfetch-cli/dev
Release: v2.26.0
2024-09-29 10:50:59 +08:00
李通洲 17c9179b7d Doc: update changelog 2024-09-29 10:29:11 +08:00
Carter Li 88097463af Display (Linux): report displays of unknown connection state too
Ref: #1301
2024-09-29 10:25:46 +08:00
李通洲 5381395c54 GPU (macOS): update how integrated GPUs are detected 2024-09-29 10:24:15 +08:00
Ziyao 51796de69a Display (Linux): detect all enabled or connected connectors (#1301)
DRM connectors have two properties, "enabled" and "status", standing for
"enabled by userspace" and "a display has been connected". Connector
status cannot be reliably detected sometimes, in this case status will
be set to unknown and it is still okay to enable it. Some drivers are
also able to enable disconnected connectors.

So it is both meaningful to detect connectors in two states,

- An enabled connector, where it must have been operating in some
  configuration required by userspace
- A connected connector, where driver is sure a display has been
  connected to the port, this is the obvious case.

In the original implementation, only information of connected connectors
are detected and an enabled connector without hotplug detection
capability, like a Composite video connector, will be silently ignored.
Switch to the new strategy to detect these connectors correctly.

References: https://github.com/torvalds/linux/blob/3efc57369a0ce8f76bf0804f7e673982384e4ac9/include/drm/drm_connector.h#L58-L89

Signed-off-by: Yao Zi <ziyao@disroot.org>
2024-09-29 10:23:20 +08:00
李通洲 140b9834cc Logo (Builtin): add GXDE OS
Fix #1300
2024-09-28 23:58:50 +08:00
Carter Li a424839d2f CPU (Linux): remove bios_limit detection 2024-09-28 17:10:22 +08:00
李通洲 acd5d4a258 Release: v2.26.0 2024-09-28 10:40:21 +08:00
李通洲 f8fa3f8ea6 Scripts: add SPDX-License-Identifier 2024-09-28 10:39:32 +08:00
Carter Li 38f07ade44 GPU (Linux): fix building with old kernel headers 2024-09-28 08:13:54 +08:00
Carter Li 7ae7ff8cef GPU (Linux): detect EU count & vmem size of Intel GPUs 2024-09-27 23:36:08 +08:00
Carter Li 842ba9fd4e GPU: use driver reported adapter name if available 2024-09-27 15:02:32 +08:00
Carter Li 5058a93428 GPU (Linux): use renderDN instead of cardN when detecting AMD cards
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1284#issuecomment-2377437210
2024-09-27 10:47:57 +08:00
Carter Li d6eff93c12 GPU: fix usage of bsearch 2024-09-27 09:54:22 +08:00
李通洲 03565384e6 Chore (macOS): use simplified syntax 2024-09-27 09:16:54 +08:00
李通洲 a3a4f0a64a Kmod: support macOS 2024-09-27 09:02:00 +08:00
李通洲 af067c7c3f Util: rename KernelMod to Kmod 2024-09-27 08:39:21 +08:00
李通洲 8bbc985d98 CMake: fix more linking errors in dynamic mode 2024-09-27 00:20:47 +08:00
李通洲 254876b9e6 GPU (Linux): try fixing linking errors when dyamic linking is used
Fix #1295
2024-09-27 00:19:31 +08:00
李通洲 78fc5a2b5d GPU: fix compiling error when -DCUSTOM_PCI_IDS_PATH is used 2024-09-27 00:00:04 +08:00
李通洲 745c041b44 GPU (Linux): fix some obvious bugs found in #1284 2024-09-26 23:53:13 +08:00
Carter Li 4283d96c53 CI: fix build 2024-09-26 20:12:12 +08:00
Carter Li e07fcc4d49 Scripts: fix old python version compatibility 2024-09-26 19:37:24 +08:00
Carter Li d095f39418 TPM (FreeBSD): fix silly bug... 2024-09-26 19:23:21 +08:00
李通洲 af63e6e98b GPU (macOS): detect GPU driver version 2024-09-26 16:43:54 +08:00
Carter Li fc05d728f3 Util: add function ffKernelModLoaded and use it 2024-09-26 16:05:34 +08:00
李通洲 e3cb52583d CI: try building with -DENABLE_EMBEDDED_PCIIDS=ON 2024-09-26 15:08:59 +08:00
李通洲 01735d6fde Presets: add tpm to all & ci 2024-09-26 15:02:43 +08:00
Carter Li b37b495aee TPM (FreeBSD): report clearer error if tpm module is not loaded 2024-09-26 14:58:26 +08:00
李通洲 28c9b67414 Processing (Windows): correctly escaping arguments 2024-09-26 14:41:06 +08:00
李通洲 4d7d367e72 FFstrbuf: add new methods ffStrbufPrependC and ffStrbufInsertNC 2024-09-26 14:34:51 +08:00
Carter Li 8295f66320 TPM (FreeBSD): add support 2024-09-26 11:03:54 +08:00
李通洲 87f2e69162 TPM: update description 2024-09-26 11:03:54 +08:00
李通洲 f496e6d965 TPM: add new module 2024-09-26 00:01:31 +08:00
李通洲 96d885e93a GPU: embed pci.ids into fastfetch 2024-09-25 20:27:03 +08:00
李通洲 ae6817e106 GPU: simplify logic of pci.ids file loading 2024-09-25 16:42:15 +08:00
Carter Li 582b0fa087 Monitor (Linux): prefer DRM 2024-09-25 09:36:20 +08:00
Carter Li 0414128a55 GPU (Linux): refactor code to support non-apple SOCs 2024-09-24 20:55:36 +08:00
李通洲 5dbd6b9ab8 Chore: remove temps_windows 2024-09-24 13:30:42 +08:00
李通洲 0c90941a32 Chore: remove temps_bsd 2024-09-24 11:00:49 +08:00
李通洲 29ae56e76a TerminalFont: fix hanging when font name is long (kitty) 2024-09-24 10:42:43 +08:00
李通洲 81b0ddb2da Chore: rename temps_apple 2024-09-24 10:37:54 +08:00
李通洲 4ea5d6f4fe Wifi (macOS): fix protocol detection on Sequoia 2024-09-24 09:56:02 +08:00
李通洲 9b4053e9dc Chore: remove temps_linux 2024-09-24 01:51:45 +00:00
李通洲 b4325ff205 Temps (Linux): simplify 2024-09-24 01:42:00 +00:00
李通洲 87d32466f6 GPU (SunOS): fix compiling 2024-09-23 22:44:17 +08:00
李通洲 3b9d20ddf2 Presets: fix examples/24
Fix #24
2024-09-23 22:34:49 +08:00
李通洲 32b6af2686 GPU (Windows): better Intel GPU type detection 2024-09-23 22:31:44 +08:00
Carter Li a3c0617f22 GPU: simplify integrated GPU detection 2024-09-23 20:40:36 +08:00
Carter Li 30ffa4bdd2 Temps (Linux): simplify 2024-09-23 16:42:34 +08:00
Carter Li 86a96da9ab PhysicalDisk (Linux): cleanup temp detection code 2024-09-23 16:42:34 +08:00
Carter Li b3b6e5fec1 GPU (Linux): refactor; add amdgpu DRM connector 2024-09-23 16:42:34 +08:00
李通洲 e0296b75f6 Doc: add donation info 2024-09-22 19:15:03 +08:00
Carter Li bd2b002d14 Display: always print inches in integer 2024-09-22 18:13:10 +08:00
李通洲 c936d170b2 Packages (Linux): support pacstall 2024-09-22 12:30:37 +08:00
李通洲 a77d972834 Packages (Linux): count flatpak runtime packages
Fix #1085
2024-09-22 12:21:56 +08:00
李通洲 10868ed951 Doc: update README [ci skip] 2024-09-22 10:45:18 +08:00
李通洲 fc947468a9 Terminal: ignore sudo and su
Fix #1283
2024-09-22 10:32:22 +08:00
李通洲 005d660d77 Logo (Builtin): add FoxOS
Fix #1281
2024-09-21 23:04:45 +08:00
李通洲 866c7303e6 Chore (Windows): use standard libc api 2024-09-20 20:25:59 +08:00
Carter Li 85a31c7c69 TerminalShell (Linux): improve perf of yakuake version detection 2024-09-20 16:30:00 +08:00
Carter Li 1dba6d155b TerminalShell (Linux): improve performance of foot version detection 2024-09-20 15:33:30 +08:00
Carter Li db669c00a1 TerminalFont (Linux): fix font size detection of foot when fall back font is used
Fix #1276
2024-09-20 15:33:04 +08:00
Carter Li 006c00ab2c Packaging: update debian stuff [ci skip] 2024-09-20 14:14:17 +08:00
李通洲 0bcbae90e9 GPU: clean up GPU index detection code 2024-09-19 15:38:43 +08:00
李通洲 503a8d51ab Merge remote-tracking branch 'origin/master' into dev 2024-09-19 15:24:17 +08:00
michela feng 9332f42889 GPU: detect GPU index (#1267) 2024-09-19 15:22:09 +08:00
158 changed files with 3251 additions and 1462 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
check-filenames =
builtin = clear,rare,usage,informal
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,sur,doas,conexant
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,slave,sur,doas,conexant
-1
View File
@@ -1 +0,0 @@
github: [CarterLi, LinusDierheimer]
+44 -7
View File
@@ -35,7 +35,7 @@ jobs:
run: uname -a
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -74,7 +74,7 @@ jobs:
run: uname -a
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y 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 libelf-dev directx-headers-dev
run: sudo apt-get update && sudo apt-get install -y 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 libelf-dev directx-headers-dev python3-requests
- name: install linuxbrew packages
run: |
@@ -87,7 +87,7 @@ jobs:
languages: c
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -247,12 +247,12 @@ jobs:
run: |
cat /etc/alpine-release
uname -a
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev py3-requests gcc g++
shell: alpine.sh --root {0}
- name: build
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -GNinja .
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -GNinja .
cmake --build . --target package --verbose -j4
shell: alpine.sh {0}
@@ -422,8 +422,8 @@ jobs:
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
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
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
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
@@ -438,6 +438,42 @@ jobs:
name: fastfetch-freebsd-amd64
path: ./fastfetch-*.*
openbsd-amd64:
name: OpenBSD-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: openbsd
architecture: x86-64
cpu_count: 4
shell: bash
version: '7.5'
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 .
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-openbsd-amd64
path: ./fastfetch-*.*
windows-amd64:
name: Windows-amd64
runs-on: windows-latest
@@ -586,6 +622,7 @@ jobs:
- musl-aarch64
- macos-universal
- freebsd-amd64
- openbsd-amd64
- sunos-amd64
- windows-amd64
- windows-i686
+73
View File
@@ -1,3 +1,76 @@
# 2.27.1
Bugfixes:
* Fix invalid display name detection on GNOME, wayland (Display, Linux)
# 2.27.0
Changes:
* We now print `"` instead of `″` when displaying diagonal length in inches, so that the character can be correctly displayed in Linux console (Display)
* All detection code of `monitor` module is merged into `display` module. Now `monitor` just prints the same information as `display` with different format. Notably:
* The resolution reported by `monitor` module is now current resolution instead of native / maximum resolution. PPI is calcuated based on current resolution too.
* The refresh rate reported by `monitor` module is the current refresh rate.
Features:
* Add basic, highly experimental support of OpenBSD (OpenBSD)
* Improve support for Raspberry pi (CPU / GPU, Linux)
* Detect SOC name, instead of displaying components used in the SOC, if available (CPU, Linux)
* Add option `--brightness-compact` to display multiple brightness values in one line (Brightness)
* Add `day-pretty` (#1305, DateTime)
* Support network interface adapter flag detection (#1315, LocalIP)
* Enable it with `--localip-show-flags`
Bugfixes:
* Remove trailing newline in GPU name for Raspberry pi (#1303, GPU, Linux)
* Fix a possible buffer overflow (GPU, Linux)
* Fix CPU temp incorrectly reported as 0 celsius (#1308, CPU, Linux)
* Corrently report `TPM device is not found` error (#1314, TPM, Windows)
* Fix errors when triggering shell completion with python3 uninstalled (#1310)
* To package managers: as shell completion scripts of fastfetch use python3, it should be added as an optional dependency of fastfetch
* Fix possible crashes when detecting term font of kitty (#1321, TerminalFont, Linux)
Logos:
* Add XeroArch
* Add ValhallaOS
# 2.26.1
Features:
* Allow to disable pacstall packager detection in CMake
Bugfixes:
* Fix uninitialized variables (GPU, Windows)
# 2.26.0
Changes:
* To be consistent to other platforms, CPU frequency detection on Linux no longer checks `bios_limit`
Features:
* Detect GPU index (#1267, GPU)
* Count Flatpak runtime packages (#1085, Packages, Linux)
* Support pacstall package manager (Packages, Linux)
* Support CU core count, max frequency, VMEM usage detection for AMD cards on Linux (GPU, Linux)
* Requires `--gpu-driver-specific`
* Support EU core count, VMEM size detection Intel cards on Linux (GPU, Linux)
* Requires `--gpu-driver-specific`. VMEM usage detection requires root permissions.
* Add new module `TPM` to print TPM (Trusted Platform Module) version if available (TPM)
* Support GPU driver version detection (GPU, macOS)
* Add new CMake option `-DENABLE_EMBEDDED_PCIIDS=ON`.
* If enabled, fastfetch will download the newest [`pci.ids`](https://pci-ids.ucw.cz/) file, [transform it into C code](https://github.com/fastfetch-cli/fastfetch/blob/dev/scripts/gen-pciids.py) and compile it into fastfetch binaries.
Bugfixes:
* Fix font size detecton of foot terminal (#1276, TerminalFont, Linux)
* Ignore `su` and `sudo` when detecting terminal (#1283, Terminal, Linux)
* Always print inches in integer (Display)
* Fix Wifi connection protocol detection on macOS Sequoia (Wifi, macOS)
* Fix hanging when font name is long when detecting kitty term font (#1289, TerminalFont)
* Detect all enabled or connected connectors (#1301, Display, Linux)
Logos:
* Add FoxOS
* Add GXDE OS
# 2.25.0
Features:
+169 -44
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.25.0
VERSION 2.27.1
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -18,6 +18,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
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 "SunOS")
set(SunOS TRUE CACHE BOOL "..." FORCE)
elseif(NOT APPLE AND NOT WIN32)
@@ -44,29 +46,30 @@ include(CheckIncludeFile)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR WIN32 OR ANDROID OR SunOS" OFF)
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD" OFF)
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR SunOS" OFF)
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_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_RPM "Enable rpm" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR APPLE OR WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR APPLE OR SunOS" 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_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 WIN32 OR SunOS" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR FreeBSD OR SunOS" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR WIN32 OR ANDROID OR SunOS" 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_FREETYPE "Enable freetype" ON "ANDROID" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR OpenBSD 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)
@@ -80,6 +83,7 @@ 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
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
@@ -88,7 +92,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PALUDIS PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
foreach(package_manager ${PACKAGE_MANAGERS})
if(package_manager STREQUAL "WINGET")
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
@@ -254,6 +258,16 @@ else()
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
endif()
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "fastfetch_pciids.c.inc")
if(Python_FOUND)
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py"
OUTPUT_FILE "fastfetch_pciids.c.inc")
else()
message(STATUS "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
set(ENABLE_EMBEDDED_PCIIDS OFF)
endif()
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)
@@ -394,6 +408,7 @@ set(LIBFASTFETCH_SRC
src/modules/terminalsize/terminalsize.c
src/modules/theme/theme.c
src/modules/title/title.c
src/modules/tpm/tpm.c
src/modules/uptime/uptime.c
src/modules/users/users.c
src/modules/version/version.c
@@ -412,6 +427,7 @@ set(LIBFASTFETCH_SRC
src/util/base64.c
src/util/FFlist.c
src/util/FFstrbuf.c
src/util/kmod.c
src/util/path.c
src/util/platform/FFPlatform.c
src/util/smbiosHelper.c
@@ -470,7 +486,6 @@ if(LINUX)
src/detection/gamepad/gamepad_linux.c
src/detection/media/media_linux.c
src/detection/memory/memory_linux.c
src/detection/monitor/monitor_linux.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
@@ -480,11 +495,11 @@ if(LINUX)
src/detection/gtk_qt/qt.c
src/detection/sound/sound_linux.c
src/detection/swap/swap_linux.c
src/detection/temps/temps_linux.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_linux.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
@@ -535,7 +550,6 @@ elseif(ANDROID)
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_nosupport.c
src/detection/memory/memory_linux.c
src/detection/monitor/monitor_nosupport.c
src/detection/netio/netio_linux.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_android.c
@@ -544,11 +558,11 @@ elseif(ANDROID)
src/detection/processes/processes_linux.c
src/detection/sound/sound_nosupport.c
src/detection/swap/swap_linux.c
src/detection/temps/temps_linux.c
src/detection/terminalfont/terminalfont_android.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
@@ -615,7 +629,6 @@ elseif(FreeBSD)
src/detection/gamepad/gamepad_bsd.c
src/detection/media/media_linux.c
src/detection/memory/memory_bsd.c
src/detection/monitor/monitor_linux.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
@@ -625,11 +638,11 @@ elseif(FreeBSD)
src/detection/gtk_qt/qt.c
src/detection/sound/sound_bsd.c
src/detection/swap/swap_bsd.c
src/detection/temps/temps_bsd.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_bsd.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
@@ -642,6 +655,85 @@ elseif(FreeBSD)
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_nosupport.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_nosupport.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_nosupport.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_nosupport.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_obsd.c
src/detection/lm/lm_nosupport.c
src/detection/icons/icons_linux.c
src/detection/initsystem/initsystem_linux.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_obsd.c
src/detection/netio/netio_nosupport.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_obsd.c
src/detection/packages/packages_obsd.c
src/detection/poweradapter/poweradapter_nosupport.c
src/detection/processes/processes_obsd.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_nosupport.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/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(APPLE)
list(APPEND LIBFASTFETCH_SRC
src/common/io/io_unix.c
@@ -682,7 +774,6 @@ elseif(APPLE)
src/detection/gamepad/gamepad_apple.c
src/detection/media/media_apple.m
src/detection/memory/memory_apple.c
src/detection/monitor/monitor_apple.m
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_apple.c
src/detection/os/os_apple.m
@@ -691,11 +782,11 @@ elseif(APPLE)
src/detection/processes/processes_bsd.c
src/detection/sound/sound_apple.c
src/detection/swap/swap_apple.c
src/detection/temps/temps_apple.c
src/detection/terminalfont/terminalfont_apple.m
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.m
@@ -707,6 +798,7 @@ elseif(APPLE)
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/apple/smc_temps.c
src/util/platform/FFPlatform_unix.c
src/util/binary_apple.c
)
@@ -726,6 +818,7 @@ elseif(WIN32)
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_windows.c
src/detection/cpu/cpu_windows.cpp
src/detection/cpucache/cpucache_windows.c
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
@@ -748,7 +841,6 @@ elseif(WIN32)
src/detection/media/media_windows.c
src/detection/memory/memory_windows.c
src/detection/physicalmemory/physicalmemory_linux.c
src/detection/monitor/monitor_windows.c
src/detection/netio/netio_windows.c
src/detection/opengl/opengl_windows.c
src/detection/os/os_windows.cpp
@@ -760,8 +852,8 @@ elseif(WIN32)
src/detection/terminalfont/terminalfont_windows.c
src/detection/terminalshell/terminalshell_windows.c
src/detection/terminalsize/terminalsize_windows.c
src/detection/temps/temps_windows.cpp
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_windows.c
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
src/detection/wallpaper/wallpaper_windows.c
@@ -832,7 +924,6 @@ elseif(SunOS)
src/detection/gamepad/gamepad_nosupport.c
src/detection/media/media_linux.c
src/detection/memory/memory_sunos.c
src/detection/monitor/monitor_linux.c
src/detection/netio/netio_sunos.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_sunos.c
@@ -846,6 +937,7 @@ elseif(SunOS)
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_sunos.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
@@ -934,13 +1026,16 @@ if(FreeBSD AND EXISTS "/usr/local/bin/objdump")
endif()
endif()
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
if(WIN32)
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
if(LINUX OR ANDROID)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__=1 _FILE_OFFSET_BITS=64)
elseif(WIN32)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE WIN32_LEAN_AND_MEAN=1 _WIN32_WINNT=0x0A00)
elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _DARWIN_C_SOURCE)
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)
elseif(SunOS)
target_compile_definitions(libfastfetch PUBLIC __EXTENSIONS__ _POSIX_C_SOURCE=1)
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE _XOPEN_SOURCE __STDC_WANT_LIB_EXT1__ _FILE_OFFSET_BITS=64 __EXTENSIONS__ _POSIX_C_SOURCE)
endif()
if(HAVE_STATX)
@@ -1038,6 +1133,10 @@ ff_lib_enable(DRM
"libdrm"
"Libdrm"
)
ff_lib_enable(DRM_AMDGPU
"libdrm_amdgpu"
"Libdrm_Amdgpu"
)
ff_lib_enable(GIO
"gio-2.0"
"GIO"
@@ -1082,10 +1181,17 @@ ff_lib_enable(EGL
"egl"
"EGL"
)
ff_lib_enable(GLX
"glx"
"GLX"
)
if(NOT OpenBSD)
ff_lib_enable(GLX
"glx"
"GLX"
)
else()
ff_lib_enable(GLX
"gl"
"GL"
)
endif()
ff_lib_enable(OSMESA
"osmesa"
"OSMesa"
@@ -1133,18 +1239,29 @@ if(ENABLE_LIBZFS)
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS=1)
if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
endif()
endif()
if(ENABLE_EMBEDDED_PCIIDS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_PCIIDS=1)
endif()
if(LINUX)
target_link_libraries(libfastfetch
PRIVATE "m"
)
if(ENABLE_DIRECTX_HEADERS)
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
target_link_libraries(libfastfetch
PRIVATE "/usr/lib/wsl/lib/libdxcore.so"
)
endif()
endif()
elseif(APPLE)
target_link_libraries(libfastfetch
PRIVATE "-framework AVFoundation"
@@ -1168,7 +1285,6 @@ elseif(APPLE)
PRIVATE "-weak_framework Apple80211"
)
elseif(WIN32)
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
target_link_libraries(libfastfetch
PRIVATE "dwmapi"
PRIVATE "gdi32"
@@ -1189,6 +1305,11 @@ elseif(FreeBSD)
PRIVATE "usbhid"
PRIVATE "geom"
)
elseif(OpenBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
PRIVATE "kvm"
)
elseif(SunOS)
target_link_libraries(libfastfetch
PRIVATE "m"
@@ -1264,6 +1385,10 @@ if(NOT WIN32)
if(HAVE_WORDEXP)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
endif()
CHECK_INCLUDE_FILE("glob.h" HAVE_GLOB)
if(HAVE_GLOB)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GLOB=1)
endif()
if(ENABLE_THREADS AND CMAKE_USE_PTHREADS_INIT)
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
if(HAVE_PTHREAD_NP)
+27 -2
View File
@@ -152,13 +152,13 @@ Fastfetch uses `format` to generate output. For example, to make the `GPU` modul
"modules": [
{
"type": "gpu",
"format": "{2}" // See `fastfetch -h gpu-format` for detail
"format": "{name}" // See `fastfetch -h gpu-format` for detail
}
]
}
```
. . which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
. . which is equivalent to `fastfetch -s gpu --gpu-format '{name}'`
See `fastfetch -h format` for information on basic usage. For module specific formattion, see `fastfetch -h <module>-format`
@@ -175,6 +175,10 @@ pyfiglet -s -f small_slant $(fastfetch -s os --format json | jq -r '.[0].result.
![image](https://github.com/fastfetch-cli/fastfetch/assets/6134068/6466524e-ab8c-484f-848d-eec7ddeb7df2)
### Q: My image logo behaves weird. How can I fix it?
See troubleshooting section: <https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options#troubleshooting>
### Q: Fastfetch runs in white and black on shell startup. Why?
This issue usually happens when using fastfetch with `p10k`. There are known incompatibility between fastfetch and p10k instant prompt.
@@ -186,6 +190,20 @@ You can always use `fastfetch --pipe false` to force fastfetch running in colorf
See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
### Q: Fastfetch shows less dpkg packages than neofetch, is it a bug?
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?
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: 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: 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:
@@ -210,6 +228,13 @@ Otherwise, open a feature request in [GitHub Issues](https://github.com/fastfetc
* For usage questions, please start a discussion in [GitHub Discussions](https://github.com/fastfetch-cli/fastfetch/discussions).
* For possible bugs, please open an issue in [GitHub Issues](https://github.com/fastfetch-cli/fastfetch/issues). Be sure to fill the bug-report template carefully for developers to investigate.
## Donate
If you find Fastfetch to be useful, please consider donating.
* Current maintainer: [@CarterLi](https://paypal.me/zhangsongcui)
* Original author: [@LinusDierheimer](https://github.com/sponsors/LinusDierheimer)
## Star History
Give it a star to support us!
+3
View File
@@ -183,7 +183,10 @@ __fastfetch_completion()
"--display-precise-refresh-rate"
"--localip-show-ipv4"
"--localip-show-ipv6"
"--localip-show-flags"
"--localip-show-loop"
"--localip-show-mtu"
"--localip-show-speed"
"--localip-name-prefix"
"--localip-compact-type"
"--escape-bedrock"
+5
View File
@@ -2,6 +2,11 @@ if not type -q fastfetch
exit
end
command -q python3
if test $status -ne 0
exit
end
complete -c fastfetch -f
function __fastfetch_complete_bool
+7
View File
@@ -1,6 +1,13 @@
#compdef fastfetch
function _fastfetch() {
whence python3 &> /dev/null
if [ $? -ne 0 ]
then
return
fi
local state
local -a opts=("${(f)$(
+24
View File
@@ -1,3 +1,27 @@
fastfetch (2.26.1ubuntu1) jammy; urgency=medium
* Update correct code
-- Carter Li <zhangsongcui@live.cn> Mon, 30 Sep 2024 00:21:20 +0800
fastfetch (2.26.1) jammy; urgency=medium
* Update to 2.26.1
-- Carter Li <zhangsongcui@live.cn> Sun, 29 Sep 2024 16:15:31 +0800
fastfetch (2.26.0) jammy; urgency=medium
* Update to 2.26.0
-- Carter Li <zhangsongcui@live.cn> Sun, 29 Sep 2024 13:31:25 +0800
fastfetch (2.25.0) jammy; urgency=medium
* Update to 2.25.0
-- Carter Li <zhangsongcui@live.cn> Thu, 19 Sep 2024 10:28:38 +0800
fastfetch (2.24.0) jammy; urgency=medium
* Update to 2.24.0
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.24.0_source.buildinfo universe/utils optional
fastfetch_2.26.1ubuntu1_source.buildinfo universe/utils optional
+17 -2
View File
@@ -344,7 +344,7 @@
"description": "Set the command to be executed before printing logos",
"default": ""
},
"showVersion": {
"detectVersion": {
"type": "boolean",
"description": "Whether to detect and display component versions. Mainly for benchmarking",
"default": true
@@ -706,6 +706,7 @@
"terminaltheme",
"title",
"theme",
"tpm",
"uptime",
"users",
"version",
@@ -815,7 +816,7 @@
},
{
"const": "monitor",
"description": "Print connected physical monitor information"
"description": "Alias of Display module"
},
{
"const": "opencl",
@@ -865,6 +866,10 @@
"const": "theme",
"description": "Print current theme of desktop environment"
},
{
"const": "tpm",
"description": "Print info of Trusted Platform Module (TPM) Security Device"
},
{
"const": "uptime",
"description": "Print how long system has been running"
@@ -1036,6 +1041,11 @@
"maximum": 400,
"default": 10
},
"compact": {
"description": "Set if multiple results should be printed in one line",
"type": "boolean",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
@@ -1693,6 +1703,11 @@
"type": "boolean",
"default": false
},
"showFlags": {
"description": "Show the interface's flags",
"type": "boolean",
"default": false
},
"compact": {
"description": "Show all IPs in one line",
"type": "boolean",
+4 -1
View File
@@ -72,7 +72,9 @@
"showIpv6": true,
"showMac": true,
"showSpeed": true,
"showMtu": true
"showMtu": true,
"showLoop": true,
"showFlags": true
},
"dns",
"wifi",
@@ -97,6 +99,7 @@
"type": "physicaldisk",
"temp": true
},
"tpm",
"version",
"break",
"colors"
+4 -1
View File
@@ -74,7 +74,9 @@
"showIpv6": true,
"showMac": true,
"showSpeed": true,
"showMtu": true
"showMtu": true,
"showLoop": true,
"showFlags": true
},
"dns",
"wifi",
@@ -99,6 +101,7 @@
"type": "physicaldisk",
"temp": true
},
"tpm",
"version",
"break",
"colors"
+3 -2
View File
@@ -119,9 +119,10 @@
"keyColor": "blue"
},
{
"type": "monitor",
"type": "display",
"key": "MONITOR ({name})",
"keyColor": "blue"
"keyColor": "blue",
"format": "{width}x{height} @ {refresh-rate} Hz - {physical-width}x{physical-height} mm ({inch} inches, {ppi} ppi)"
},
{
"type": "custom", // DesignInfo
+1 -1
View File
@@ -88,7 +88,7 @@
{
"type": "disk",
"key": "{#90}{$1}│ {#91}Disk {#90}│",
"format": "{$2}{$3}{size-used} / {size-used} ({size-percentage}{$2})"
"format": "{$2}{$3}{size-used} / {size-total} ({size-percentage}{$2})"
},
{
"type": "poweradapter",
+95
View File
@@ -0,0 +1,95 @@
from requests import get as http_get
class PciDeviceModel:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
class PciVendorModel:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
self.devices = []
def main(keep_vendor_list: set):
vendors = []
try:
with open('pci.ids', 'r') as f:
full_text = f.read()
except FileNotFoundError:
response = http_get('https://pci-ids.ucw.cz/v2.2/pci.ids')
full_text = response.text
dev_list_text = full_text[:full_text.rfind('\n\n\n')] # remove known classes
for line in dev_list_text.split('\n'):
if not line or line[0] == '#':
continue
if line[0] != '\t':
id, name = line.split(' ', maxsplit=1)
vendors.append(PciVendorModel(int(id, 16), name))
elif line[1] != '\t':
id, name = line[1:].split(' ', maxsplit=1)
vendors[-1].devices.append(PciDeviceModel(int(id, 16), name))
code = """\
// SPDX-License-Identifier: BSD-3-Clause
// https://opensource.org/license/BSD-3-Clause
// Generated from https://pci-ids.ucw.cz/v2.2/pci.ids
#include <stdint.h>
#include <stddef.h>
typedef struct FFPciDevice
{
const uint32_t id;
const char* name;
} FFPciDevice;
typedef struct FFPciVendor
{
const uint32_t id;
const char* name;
const FFPciDevice* devices;
const uint32_t nDevices;
} FFPciVendor;
"""
if keep_vendor_list:
vendors = [vendor for vendor in vendors if vendor.id in keep_vendor_list]
for vendor in vendors:
if vendor.devices:
piece = ',\n '.join('{{ 0x{:04X}, "{}" }}'.format(device.id, device.name.replace('"', '\\"')) for device in vendor.devices)
code += f"""
// {vendor.name}
static const FFPciDevice pciDevices_{vendor.id:04X}[] = {{
{piece},
{{}},
}};
"""
piece = ',\n '.join('{{ 0x{:04X}, "{}", {}, {} }}'.format(vendor.id, vendor.name.replace('"', '\\"'), vendor.devices and f"pciDevices_{vendor.id:04X}" or "NULL", len(vendor.devices)) for vendor in vendors)
code += f"""
const FFPciVendor ffPciVendors[] = {{
{piece},
{{}},
}};"""
print(code)
if __name__ == '__main__':
# From <src/detection/gpu/gpu.c>
main({
0x106b, # Apple
0x1002, 0x1022, # AMD
0x8086, 0x8087, 0x03e7, # Intel
0x0955, 0x10de, 0x12d2, # Nvidia
0x1ed5, # MThreads
0x5143, # Qualcomm
0x14c3, # MTK
0x15ad, # VMware
0x1af4, # RedHat
0x1ab8, # Parallel
0x1414, # Microsoft
0x108e, # Oracle
})
+7 -1
View File
@@ -191,6 +191,9 @@ void ffListFeatures(void)
#if FF_HAVE_DRM
"drm\n"
#endif
#if FF_HAVE_DRM_AMDGPU
"drm_amdgpu\n"
#endif
#if FF_HAVE_GIO
"gio\n"
#endif
@@ -242,7 +245,7 @@ void ffListFeatures(void)
#if FF_HAVE_DDCUTIL
"libddcutil\n"
#endif
#if FF_HAVE_ELF || __sun || __FreeBSD__
#if FF_HAVE_ELF || __sun || __FreeBSD__ || __OpenBSD__
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
@@ -260,6 +263,9 @@ void ffListFeatures(void)
#if FF_HAVE_LINUX_WIRELESS
"linux/wireless\n"
#endif
#if FF_HAVE_EMBEDDED_PCIIDS
"Embedded pciids\n"
#endif
""
, stdout);
}
+30 -3
View File
@@ -14,8 +14,11 @@
#if FF_HAVE_WORDEXP
#include <wordexp.h>
#elif FF_HAVE_GLOB
#warning "<wordexp.h> is not available, use <glob.h> instead"
#include <glob.h>
#else
#warning "<wordexp.h> not available"
#warning "Neither <wordexp.h> nor <glob.h> is available"
#endif
static void createSubfolders(const char* fileName)
@@ -121,7 +124,7 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
#if FF_HAVE_WORDEXP // https://github.com/termux/termux-packages/pull/7056
wordexp_t exp;
if(wordexp(in, &exp, 0) != 0)
if (wordexp(in, &exp, 0) != 0)
return false;
if (exp.we_wordc == 1)
@@ -132,6 +135,20 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
wordfree(&exp);
#elif FF_HAVE_GLOB
glob_t gb;
if (glob(in, GLOB_NOSORT | GLOB_TILDE, NULL, &gb) != 0)
return false;
if (gb.gl_matchc == 1)
{
result = true;
ffStrbufSetS(out, gb.gl_pathv[0]);
}
globfree(&gb);
#endif
return result;
@@ -191,14 +208,24 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
ssize_t nRead = read(ftty, buffer + bytesRead, sizeof(buffer) - bytesRead - 1);
if (nRead <= 0)
{
va_end(args);
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
}
bytesRead += (size_t) nRead;
buffer[bytesRead] = '\0';
int ret = vsscanf(buffer, format, args);
va_list cargs;
va_copy(cargs, args);
int ret = vsscanf(buffer, format, cargs);
va_end(cargs);
if (ret <= 0)
{
va_end(args);
return "vsscanf(buffer, format, args) failed";
}
if (ret >= nParams)
break;
}
+10
View File
@@ -266,14 +266,24 @@ const char* ffGetTerminalResponse(const char* request, int nParams, const char*
{
DWORD bytes = 0;
if (!ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL) || bytes == 0)
{
va_end(args);
return "ReadFile() failed";
}
bytesRead += bytes;
buffer[bytesRead] = '\0';
va_list cargs;
va_copy(cargs, args);
int ret = vsscanf(buffer, format, args);
va_end(cargs);
if (ret <= 0)
{
va_end(args);
return "vsscanf(buffer, format, args) failed";
}
if (ret >= nParams)
break;
}
+1
View File
@@ -137,6 +137,7 @@ static FFModuleBaseInfo* T[] = {
(void*) &instance.config.modules.terminalTheme,
(void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme,
(void*) &instance.config.modules.tpm,
NULL,
};
+33
View File
@@ -22,6 +22,10 @@
#include <libproc.h>
#elif defined(__sun)
#include <procfs.h>
#elif defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#endif
enum { FF_PIPE_BUFSIZ = 8192 };
@@ -259,6 +263,18 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
}
}
#elif defined(__OpenBSD__)
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
int count = 0;
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
if (proc)
{
char** argv = kvm_getargv(kd, proc, 0);
if (argv) ffStrbufSetS(exe, argv[0]);
}
kvm_close(kd);
#endif
if(exe->length == 0)
@@ -373,6 +389,23 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
if (tty)
*tty = (int) proc.pr_ttydev;
#elif defined(__OpenBSD__)
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
int count = 0;
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &count);
if (proc)
{
ffStrbufSetS(name, proc->p_comm);
if (ppid)
*ppid = proc->p_ppid;
if (tty)
*tty = (int) proc->p_tdev;
}
kvm_close(kd);
if (!proc)
return "kvm_getprocs() failed";
#else
return "Unsupported platform";
+39 -6
View File
@@ -8,6 +8,43 @@
enum { FF_PIPE_BUFSIZ = 8192 };
static void argvToCmdline(char* const argv[], FFstrbuf* result)
{
// From https://gist.github.com/jin-x/cdd641d98887524b091fb1f82a68717d
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
for (int i = 0; argv[i] != NULL; i++)
{
ffStrbufSetS(&temp, argv[i]);
// Add slash (\) before double quotes (") and duplicate slashes before it
for (
uint32_t pos = ffStrbufFirstIndexC(&temp, '"'), cnt;
pos != temp.length;
pos = ffStrbufNextIndexC(&temp, pos + cnt * 2, '"')
) {
cnt = 1;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
ffStrbufInsertNC(&temp, pos, cnt, '\\');
}
// Add quotes around string if whitespace chars are present (with slash duplicating at the end of string)
if (ffStrbufFirstIndexS(&temp, " \t") != temp.length)
{
uint32_t pos = temp.length;
uint32_t cnt = 0;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
if (cnt > 0) ffStrbufAppendNC(&temp, cnt, '\\');
ffStrbufPrependC(&temp, '"');
ffStrbufAppendC(&temp, '"');
}
// Add space delimiter
if (i > 0) ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, &temp);
ffStrbufClear(&temp);
}
}
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
{
int timeout = instance.config.general.processingTimeout;
@@ -55,12 +92,8 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
else
siStartInfo.hStdOutput = hChildPipeWrite;
FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]);
for(char* const* parg = &argv[1]; *parg; ++parg)
{
ffStrbufAppendC(&cmdline, ' ');
ffStrbufAppendS(&cmdline, *parg);
}
FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreate();
argvToCmdline(argv, &cmdline);
success = CreateProcessA(
NULL, // application name
+36
View File
@@ -2,6 +2,41 @@
#include <stdlib.h>
#ifdef __OpenBSD__
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result)
{
size_t neededLength;
if (sysctl((int[]) {mib1, mib2}, 2, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
return "sysctlbyname() failed";
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
if (sysctl((int[]) {mib1, mib2}, 2, result->chars + result->length, &neededLength, NULL, 0) == 0)
result->length += (uint32_t) neededLength - 1;
result->chars[result->length] = '\0';
return NULL;
}
int ffSysctlGetInt(int mib1, int mib2, int defaultValue)
{
int result;
size_t neededLength = sizeof(result);
if (sysctl((int[]) {mib1, mib2}, 2, &result, &neededLength, NULL, 0) != 0)
return defaultValue;
return result;
}
int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue)
{
int64_t result;
size_t neededLength = sizeof(result);
if(sysctl((int[]) {mib1, mib2}, 2, &result, &neededLength, NULL, 0) != 0)
return defaultValue;
return result;
}
#else
const char* ffSysctlGetString(const char* propName, FFstrbuf* result)
{
size_t neededLength;
@@ -35,6 +70,7 @@ int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue)
return defaultValue;
return result;
}
#endif // OpenBSD
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength)
{
+6
View File
@@ -6,7 +6,13 @@
#include <sys/types.h>
#include <sys/sysctl.h>
#ifdef __OpenBSD__
const char* ffSysctlGetString(int mib1, int mib2, FFstrbuf* result);
FF_C_NODISCARD int ffSysctlGetInt(int mib1, int mib2, int defaultValue);
FF_C_NODISCARD int64_t ffSysctlGetInt64(int mib1, int mib2, int64_t defaultValue);
#else
const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
#endif
FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
+36 -1
View File
@@ -1000,6 +1000,14 @@
"default": 10
}
},
{
"long": "brightness-compact",
"desc": "Set if multiple results should be printed in one line",
"arg": {
"type": "bool",
"default": false
}
},
{
"long": "sound-type",
"desc": "Set what type of sound devices should be printed",
@@ -1188,6 +1196,24 @@
"default": false
}
},
{
"long": "localip-show-mtu",
"desc": "Show net interface's MTU (Maximum Transmission Unit) size in bytes",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-show-speed",
"desc": "Show net interface's link speed with human-readable format (or an 1Mb units integer in JSON format)",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-show-prefix-len",
"desc": "Show network prefix length (/N) in local ip module",
@@ -1223,6 +1249,15 @@
"default": false
}
},
{
"long": "localip-show-flags",
"desc": "Show net interface flags in local ip module",
"arg": {
"type": "bool",
"optional": true,
"default": false
}
},
{
"long": "localip-compact",
"desc": "Show all IPs in one line",
@@ -1379,7 +1414,7 @@
{
"long": "command-param",
"desc": "Set the parameter used when starting the shell",
"remark": "Due to the difference of how OSes handle command line parameters, Windows will parse whitespaces as param separators, while *nix will not",
"remark": "If set to empty string, it will be ignored",
"arg": {
"type": "str",
"default": "\"/c\" for Windows; \"-c\" for *nix"
+1 -1
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "battery.h"
#include "util/apple/cf_helpers.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/smc_temps.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/pwr_mgt/IOPM.h>
-1
View File
@@ -1,6 +1,5 @@
#include "battery.h"
#include "common/io/io.h"
#include "detection/temps/temps_linux.h"
#include "util/stringUtils.h"
#include <dirent.h>
+5 -1
View File
@@ -12,13 +12,17 @@ const char* ffDetectBoard(FFBoardResult* board)
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->vendor);
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->version);
}
else if (ffReadFileBuffer("/proc/device-tree/board", &board->name))
{
ffStrbufTrimRightSpace(&board->name);
}
else if (ffReadFileBuffer("/proc/device-tree/compatible", &board->vendor))
{
// use model name as board name
uint32_t comma = ffStrbufFirstIndexC(&board->vendor, ',');
if (comma < board->vendor.length)
{
ffStrbufSetS(&board->name, board->vendor.chars + comma + 1);
ffStrbufTrimRightSpace(&board->name);
ffStrbufSubstrBefore(&board->vendor, comma);
}
}
+1 -1
View File
@@ -38,7 +38,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
uint8_t buffer[2048];
wchar_t key[16];
wsprintfW(key, L"Boot%04X", value);
swprintf(key, sizeof(key) / sizeof(*key), L"Boot%04X", value);
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
if (size < sizeof(FFEfiLoadOption) || size == sizeof(buffer))
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
-1
View File
@@ -21,7 +21,6 @@ typedef struct FFCPUResult
uint32_t frequencyBase; // GHz
uint32_t frequencyMax; // GHz
uint32_t frequencyBiosLimit; // GHz
FFCPUCore coreTypes[16]; // number of P cores, E cores, etc.
+1 -1
View File
@@ -1,6 +1,6 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/smc_temps.h"
#include "util/stringUtils.h"
static double detectCpuTemp(const FFstrbuf* cpuName)
+24 -3
View File
@@ -1,6 +1,27 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "detection/temps/temps_bsd.h"
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
static const char* detectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
@@ -46,8 +67,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if (options->temp)
{
if (ffDetectCpuTemp(&cpu->temperature) != NULL)
ffDetectThermalTemp(&cpu->temperature);
if (detectCpuTemp(&cpu->temperature) != NULL)
detectThermalTemp(&cpu->temperature);
}
return NULL;
+139 -44
View File
@@ -2,13 +2,85 @@
#include "common/io/io.h"
#include "common/processing.h"
#include "common/properties.h"
#include "detection/temps/temps_linux.h"
#include "util/mallocHelper.h"
#include "util/stringUtils.h"
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
{
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
uint32_t dirLength = dir->length;
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, buffer))
{
// Some badly implemented system put temp file in /hwmonN/device
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/");
dirLength = dir->length;
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, buffer))
return 0.0/0.0;
}
ffStrbufSubstrBefore(dir, dirLength);
double value = ffStrbufToDouble(buffer);// millidegree Celsius
if(value != value)
return 0.0/0.0;
ffStrbufAppendS(dir, "name");
if (!ffReadFileBuffer(dir->chars, buffer))
return 0.0/0.0;
ffStrbufTrimRightSpace(buffer);
if(
ffStrbufContainS(buffer, "cpu") ||
ffStrbufEqualS(buffer, "k10temp") || // AMD
ffStrbufEqualS(buffer, "coretemp") // Intel
) return value / 1000.;
return 0.0/0.0;
}
static double detectCPUTemp(void)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return 0.0/0.0;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&baseDir, entry->d_name);
ffStrbufAppendC(&baseDir, '/');
double result = parseHwmonDir(&baseDir, &buffer);
if (result == result)
return result;
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return 0.0/0.0;
}
#ifdef __ANDROID__
#include "common/settings.h"
@@ -253,18 +325,25 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
if (ffStrStartsWith(entry->d_name, "policy") && ffCharIsDigit(entry->d_name[strlen("policy")]))
{
ffStrbufAppendS(&path, entry->d_name);
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax == 0) continue;
if (cpu->frequencyMax >= fmax)
{
if (!options->showPeCoreCount)
{
ffStrbufSubstrBefore(&path, baseLen);
continue;
}
}
else
cpu->frequencyMax = fmax;
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase > 0)
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
uint32_t fbioslimit = getFrequency(&path, "/bios_limit", NULL, &buffer);
if (fbioslimit > 0)
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax > 0)
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
if (options->showPeCoreCount)
{
uint32_t freq = fbase == 0 ? fmax : fbase; // seems base frequencies are more stable
@@ -281,22 +360,6 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
return true;
}
static double detectCPUTemp(void)
{
const FFlist* tempsResult = ffDetectTemps();
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
{
if(
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
ffStrbufEqualS(&value->name, "k10temp") ||
ffStrbufEqualS(&value->name, "coretemp")
) return value->value;
}
return FF_CPU_TEMP_UNSET;
}
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
{
// Always use the last part of the ISA string. Ref: #590 #1204
@@ -325,38 +388,53 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
return;
// device-vendor,device-model\0soc-vendor,soc-model\0
char content[64];
char content[256];
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
if (length <= 2) return;
// get the second NUL terminated string
char* modelName = memchr(content, '\0', (size_t) length) + 1;
if (!modelName || modelName - content >= length) return;
// get the second NUL terminated string if it exists
char* vendor = memchr(content, '\0', (size_t) length) + 1;
if (!vendor || vendor - content >= length) vendor = content;
if (ffStrStartsWith(modelName, "apple,t"))
char* model = strchr(vendor, ',');
if (!model) return;
*model = '\0';
++model;
if (false) {}
#if __aarch64__
else if (ffStrEquals(vendor, "apple"))
{
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/apple
const char* code = modelName + strlen("apple,t");
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
if (!cpu->name.length)
// https://elixir.bootlin.com/linux/v6.11/source/arch/arm64/boot/dts/apple
if (model[0] == 't')
{
ffStrbufAppendS(&cpu->name, "Apple Silicon T");
ffStrbufAppendS(&cpu->name, code);
uint32_t deviceId = (uint32_t) strtoul(model + 1, NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUAppleCodeToName(deviceId));
if (!cpu->name.length)
{
ffStrbufSetS(&cpu->name, "Apple Silicon ");
ffStrbufAppendS(&cpu->name, model);
}
}
else
ffStrbufSetS(&cpu->name, model);
ffStrbufSetStatic(&cpu->vendor, "Apple");
}
else if (ffStrStartsWith(modelName, "qcom,"))
#endif
else if (ffStrEquals(vendor, "qcom"))
{
// https://elixir.bootlin.com/linux/v6.11-rc7/source/arch/arm64/boot/dts/qcom
if (ffStrStartsWith(modelName + strlen("qcom,"), "x"))
// https://elixir.bootlin.com/linux/v6.11/source/arch/arm64/boot/dts/qcom
if (ffStrStartsWith(model, "x"))
{
ffStrbufSetS(&cpu->name, "Qualcomm Snapdragon X Elite ");
for (const char* p = modelName + strlen("qcom,"); *p; ++p)
for (const char* p = model + 1; *p; ++p)
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
}
else if (ffStrStartsWith(modelName + strlen("qcom,"), "sc"))
else if (ffStrStartsWith(model, "sc"))
{
const char* code = modelName + strlen("qcom,sc");
const char* code = model + 2;
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId));
if (!cpu->name.length)
@@ -365,6 +443,23 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
ffStrbufAppendS(&cpu->name, code);
}
}
else
ffStrbufSetS(&cpu->name, model);
ffStrbufSetStatic(&cpu->vendor, "Qualcomm");
}
else if (ffStrEquals(vendor, "brcm"))
{
// Raspberry Pi
ffStrbufSetStatic(&cpu->vendor, "Broadcom");
for (const char* p = model; *p; ++p)
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
}
else
{
ffStrbufSetS(&cpu->name, model);
ffStrbufSetS(&cpu->vendor, vendor);
cpu->vendor.chars[0] = (char) toupper(vendor[0]);
}
}
@@ -417,7 +512,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
#if __ANDROID__
detectAndroid(cpu);
#elif __aarch64__
#else
detectArmSoc(cpu);
#endif
+19
View File
@@ -0,0 +1,19 @@
#include "cpu.h"
#include "common/sysctl.h"
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
if (ffSysctlGetString(CTL_HW, HW_MODEL, &cpu->name))
return "sysctl(hw.model) failed";
cpu->coresPhysical = (uint16_t) ffSysctlGetInt(CTL_HW, HW_NCPU, 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = (uint16_t) ffSysctlGetInt(CTL_HW, HW_NCPUONLINE, cpu->coresLogical);
ffCPUDetectSpeedByCpuid(cpu);
cpu->frequencyBase = (uint32_t) ffSysctlGetInt(CTL_HW, HW_CPUSPEED, 0);
cpu->temperature = FF_CPU_TEMP_UNSET; // HW_SENSORS?
return NULL;
}
+3 -2
View File
@@ -1,5 +1,4 @@
#include "cpu.h"
#include "detection/temps/temps_windows.h"
#include "util/windows/registry.h"
#include "util/windows/nt.h"
#include "util/mallocHelper.h"
@@ -160,6 +159,8 @@ static const char* detectCoreTypes(FFCPUResult* cpu)
return NULL;
}
const char* detectThermalTemp(double* current, double* critical);
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
detectNCores(cpu);
@@ -175,7 +176,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectMaxSpeedBySmbios(cpu);
if(options->temp)
ffDetectSmbiosTemp(&cpu->temperature, NULL);
detectThermalTemp(&cpu->temperature, NULL);
return NULL;
}
@@ -1,11 +1,7 @@
extern "C"
{
#include "temps_windows.h"
}
#include "util/windows/wmi.hpp"
extern "C"
const char* ffDetectSmbiosTemp(double* current, double* critical)
const char* detectThermalTemp(double* current, double* critical)
{
// Requires Administrator privileges
// https://wutils.com/wmi/root/wmi/msacpi_thermalzonetemperature/#properties
+16
View File
@@ -6,18 +6,34 @@
#include <sys/resource.h>
#include <stdlib.h>
#ifdef __OpenBSD__
#include <sys/sched.h>
#endif
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
{
size_t neededLength = 0;
#ifdef __OpenBSD__
int ctls[] = {CTL_KERN, KERN_CPTIME};
if (sysctl(ctls, 2, NULL, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
if(sysctlbyname("kern.cp_times", NULL, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, NULL) failed";
#endif
uint32_t coreCount = (uint32_t) (neededLength / (CPUSTATES * sizeof(uint64_t)));
assert(coreCount > 0);
FF_AUTO_FREE uint64_t (*cpTimes)[CPUSTATES] = malloc(neededLength);
#ifdef __OpenBSD__
if (sysctl(ctls, 2, cpTimes, &neededLength, NULL, 0) != 0)
return "sysctl({CTL_KERN, KERN_CPTIME}, 2, NULL) failed";
#else
if(sysctlbyname("kern.cp_times", cpTimes, &neededLength, NULL, 0) != 0)
return "sysctlbyname(kern.cp_times, cpTime) failed";
#endif
for (uint32_t i = 0; i < coreCount; ++i)
{
+7 -7
View File
@@ -4,10 +4,10 @@
static void appendColor(FFstrbuf* str, NSDictionary* color)
{
int r = (int) (((NSNumber*) [color valueForKey:@"red"]).doubleValue * 255);
int g = (int) (((NSNumber*) [color valueForKey:@"green"]).doubleValue * 255);
int b = (int) (((NSNumber*) [color valueForKey:@"blue"]).doubleValue * 255);
int a = (int) (((NSNumber*) [color valueForKey:@"alpha"]).doubleValue * 255);
int r = (int) (((NSNumber*) color[@"red"]).doubleValue * 255);
int g = (int) (((NSNumber*) color[@"green"]).doubleValue * 255);
int b = (int) (((NSNumber*) color[@"blue"]).doubleValue * 255);
int a = (int) (((NSNumber*) color[@"alpha"]).doubleValue * 255);
if (r == 255 && g == 255 && b == 255 && a == 255)
ffStrbufAppendS(str, "White");
@@ -32,19 +32,19 @@ void ffDetectCursor(FFCursorResult* result)
NSDictionary* color;
ffStrbufAppendS(&result->theme, "Fill - ");
if ((color = [dict valueForKey:@"cursorFill"]))
if ((color = dict[@"cursorFill"]))
appendColor(&result->theme, color);
else
ffStrbufAppendS(&result->theme, "Black");
ffStrbufAppendS(&result->theme, ", Outline - ");
if ((color = [dict valueForKey:@"cursorOutline"]))
if ((color = dict[@"cursorOutline"]))
appendColor(&result->theme, color);
else
ffStrbufAppendS(&result->theme, "White");
NSNumber* mouseDriverCursorSize = [dict valueForKey:@"mouseDriverCursorSize"];
NSNumber* mouseDriverCursorSize = dict[@"mouseDriverCursorSize"];
if (mouseDriverCursorSize)
ffStrbufAppendF(&result->size, "%d", (int) (mouseDriverCursorSize.doubleValue * 32));
else
+9
View File
@@ -92,6 +92,11 @@ void detectFsInfo(struct statfs* fs, FFDisk* disk)
}, &attrBuf, sizeof(attrBuf), 0) == 0)
ffStrbufInitNS(&disk->name, attrBuf.nameRef.attr_length - 1 /* excluding '\0' */, attrBuf.nameSpace);
}
#else
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
FF_UNUSED(fs, disk);
}
#endif
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
@@ -143,6 +148,10 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
if(fs->f_flags & MNT_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
#ifdef __OpenBSD__
#define st_birthtimespec __st_birthtim
#endif
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));
+4 -1
View File
@@ -33,7 +33,10 @@ FFDisplayResult* ffdsAppendDisplay(
display->primary = primary;
display->bitDepth = 0;
display->hdrEnabled = false;
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
display->manufactureYear = 0;
display->manufactureWeek = 0;
display->serial = 0;
return display;
}
+12 -1
View File
@@ -48,6 +48,14 @@ typedef enum FFDisplayType {
FF_DISPLAY_TYPE_EXTERNAL,
} FFDisplayType;
typedef enum FFDisplayHdrStatus
{
FF_DISPLAY_HDR_STATUS_UNKNOWN,
FF_DISPLAY_HDR_STATUS_UNSUPPORTED,
FF_DISPLAY_HDR_STATUS_SUPPORTED,
FF_DISPLAY_HDR_STATUS_ENABLED,
} FFDisplayHdrStatus;
typedef struct FFDisplayResult
{
uint32_t width;
@@ -63,7 +71,10 @@ typedef struct FFDisplayResult
uint32_t physicalHeight;
bool primary;
uint8_t bitDepth;
bool hdrEnabled;
FFDisplayHdrStatus hdrStatus;
uint16_t manufactureYear;
uint16_t manufactureWeek;
uint32_t serial;
} FFDisplayResult;
typedef struct FFDisplayServerResult
@@ -1,6 +1,7 @@
#include "displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/stringUtils.h"
#include "util/edidHelper.h"
#include <stdlib.h>
#include <string.h>
@@ -8,9 +9,10 @@
#include <CoreGraphics/CGDirectDisplay.h>
#include <CoreVideo/CVDisplayLink.h>
extern Boolean CoreDisplay_Display_SupportsHDRMode(CGDirectDisplayID display) __attribute__((weak_import));
extern Boolean CoreDisplay_Display_IsHDRModeEnabled(CGDirectDisplayID display) __attribute__((weak_import));
#ifdef MAC_OS_X_VERSION_10_15
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
extern Boolean CoreDisplay_Display_IsHDRModeEnabled(CGDirectDisplayID display) __attribute__((weak_import));
#else
#include <IOKit/graphics/IOGraphicsLib.h>
#endif
@@ -22,6 +24,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
if(CGGetOnlineDisplayList(sizeof(screens) / sizeof(screens[0]), screens, &screenCount) != kCGErrorSuccess)
return;
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
for(uint32_t i = 0; i < screenCount; i++)
{
CGDirectDisplayID screen = screens[i];
@@ -43,7 +46,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
ffStrbufClear(&buffer);
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = NULL;
#ifdef MAC_OS_X_VERSION_10_15
if(CoreDisplay_DisplayCreateInfoDictionary)
@@ -54,14 +57,30 @@ static void detectDisplays(FFDisplayServerResult* ds)
displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
}
#endif
uint32_t physicalWidth = 0, physicalHeight = 0;
if(displayInfo)
{
CFDictionaryRef productNames;
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
ffCfDictGetString(productNames, CFSTR("en_US"), &buffer);
// CGDisplayScreenSize reports invalid result for external displays on old Intel MacBook Pro
CFDataRef edidRef = (CFDataRef) CFDictionaryGetValue(displayInfo, CFSTR(kIODisplayEDIDKey));
if (edidRef && CFGetTypeID(edidRef) == CFDataGetTypeID())
{
const uint8_t* edidData = CFDataGetBytePtr(edidRef);
uint32_t edidLength = (uint32_t) CFDataGetLength(edidRef);
if (edidLength >= 128)
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
}
}
CGSize size = CGDisplayScreenSize(screen);
if (!physicalWidth || !physicalHeight)
{
CGSize size = CGDisplayScreenSize(screen);
physicalWidth = (uint32_t) (size.width + 0.5);
physicalHeight = (uint32_t) (size.height + 0.5);
}
FFDisplayResult* display = ffdsAppendDisplay(ds,
(uint32_t)CGDisplayModeGetPixelWidth(mode),
@@ -70,12 +89,12 @@ static void detectDisplays(FFDisplayServerResult* ds)
(uint32_t)CGDisplayModeGetWidth(mode),
(uint32_t)CGDisplayModeGetHeight(mode),
(uint32_t)CGDisplayRotation(screen),
&name,
&buffer,
CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
CGDisplayIsMain(screen),
(uint64_t)screen,
(uint32_t) (size.width + 0.5),
(uint32_t) (size.height + 0.5)
physicalWidth,
physicalHeight
);
if (display)
{
@@ -89,12 +108,27 @@ static void detectDisplays(FFDisplayServerResult* ds)
display->bitDepth = (uint8_t) bitDepth;
}
#ifdef MAC_OS_X_VERSION_10_15
if (CoreDisplay_Display_IsHDRModeEnabled)
if (display->type == FF_DISPLAY_TYPE_BUILTIN)
display->hdrStatus = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance"))
? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
else if (CoreDisplay_Display_SupportsHDRMode)
{
display->hdrEnabled = CoreDisplay_Display_IsHDRModeEnabled(screen);
if (CoreDisplay_Display_SupportsHDRMode(screen))
{
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
if (CoreDisplay_Display_IsHDRModeEnabled && CoreDisplay_Display_IsHDRModeEnabled(screen))
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
}
else
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
}
#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;
}
CGDisplayModeRelease(mode);
}
@@ -86,6 +86,9 @@ static void detectDisplays(FFDisplayServerResult* ds)
.id = path->targetInfo.id,
},
};
uint8_t edidData[1024];
DWORD edidLength = 0;
if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS)
{
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
@@ -103,8 +106,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
wcscpy(pRegPath, L"Device Parameters");
uint8_t edidData[1024];
DWORD edidLength = sizeof(edidData);
edidLength = sizeof(edidData);
if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS &&
edidLength > 0 && edidLength % 128 == 0)
{
@@ -113,6 +115,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
else
{
edidLength = 0;
if (targetName.flags.friendlyNameFromEdid)
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
else
@@ -177,9 +180,18 @@ static void detectDisplays(FFDisplayServerResult* ds)
};
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
{
display->hdrEnabled = !!advColorInfo.advancedColorEnabled;
if (advColorInfo.advancedColorEnabled)
display->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
else if (advColorInfo.advancedColorSupported)
display->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
else
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
}
else
display->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
if (edidLength > 0)
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
}
}
}
@@ -1,6 +1,5 @@
#include "displayserver_linux.h"
#include "common/io/io.h"
#include "util/edidHelper.h"
#include "util/stringUtils.h"
#ifdef __FreeBSD__
@@ -104,44 +103,6 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
}
}
bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName)
{
// 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."
// However I can't find a better method to get the edid data
const char* drmDirPath = "/sys/class/drm/";
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return false;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
const char* plainName = entry->d_name;
if (ffStrStartsWith(plainName, "card"))
{
const char* tmp = strchr(plainName + strlen("card"), '-');
if (tmp) plainName = tmp + 1;
}
if (ffStrEquals(plainName, connName))
{
ffStrbufAppendF(edidName, "%s%s/edid", drmDirPath, entry->d_name);
uint8_t edidData[128];
if(ffReadFileData(edidName->chars, sizeof(edidData), edidData) == sizeof(edidData))
{
ffStrbufClear(edidName);
ffEdidGetName(edidData, edidName);
return true;
}
break;
}
}
ffStrbufClear(edidName);
return false;
}
FFDisplayType ffdsGetDisplayType(const char* name)
{
if(ffStrStartsWith(name, "eDP-") || ffStrStartsWith(name, "LVDS-"))
@@ -5,8 +5,6 @@
#include "detection/displayserver/displayserver.h"
bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName);
const char* ffdsConnectWayland(FFDisplayServerResult* result);
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result);
+70 -31
View File
@@ -28,13 +28,19 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
ffStrbufAppendS(&drmDir, "/status");
char status = 'd'; // disconnected
ffReadFileData(drmDir.chars, sizeof(status), &status);
if (status != 'c') // connected
{
char buf;
ffStrbufAppendS(&drmDir, "/enabled");
if (!ffReadFileData(drmDir.chars, sizeof(buf), &buf) || buf != 'e') {
/* read failed or enabled != "enabled" */
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufAppendS(&drmDir, "/status");
buf = 'd';
ffReadFileData(drmDir.chars, sizeof(buf), &buf);
if (buf != 'c') {
/* read failed or status != "connected" */
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
}
unsigned width = 0, height = 0, physicalWidth = 0, physicalHeight = 0;
@@ -44,15 +50,18 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufAppendS(&drmDir, "/edid");
uint8_t edidData[128];
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
const char* plainName = entry->d_name;
if (ffStrStartsWith(plainName, "card"))
{
ffEdidGetName(edidData, &name);
ffEdidGetPreferredResolutionAndRefreshRate(edidData, &width, &height, &refreshRate);
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
const char* tmp = strchr(plainName + strlen("card"), '-');
if (tmp) plainName = tmp + 1;
}
else
uint8_t edidData[512];
ssize_t edidLength = ffReadFileData(drmDir.chars, sizeof(edidData), edidData);
if(edidLength <= 0 || edidLength % 128 != 0)
{
edidLength = 0;
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufAppendS(&drmDir, "/modes");
@@ -60,29 +69,34 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
if (ffReadFileData(drmDir.chars, sizeof(modes), modes) >= 3)
{
sscanf(modes, "%ux%u", &width, &height);
const char* plainName = entry->d_name;
if (ffStrStartsWith(plainName, "card"))
{
const char* tmp = strchr(plainName + strlen("card"), '-');
if (tmp) plainName = tmp + 1;
}
ffStrbufAppendS(&name, plainName);
}
}
else
{
ffEdidGetName(edidData, &name);
ffEdidGetPreferredResolutionAndRefreshRate(edidData, &width, &height, &refreshRate);
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
}
ffdsAppendDisplay(
FFDisplayResult* item = ffdsAppendDisplay(
result,
width, height,
refreshRate,
0, 0,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
ffdsGetDisplayType(plainName),
false,
0,
physicalWidth,
physicalHeight
);
if (item && edidLength)
{
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);
}
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
@@ -154,7 +168,7 @@ static inline const char* drmType2Name(uint32_t connector_type)
}
}
static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
FF_MAYBE_UNUSED static const char* drmGetEdidByConnId(uint32_t connId, uint8_t* edidData, ssize_t* edidLength)
{
const char* drmDirPath = "/sys/class/drm/";
@@ -176,24 +190,22 @@ static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
char connectorId[16] = {};
ffStrbufAppendS(&drmDir, "/connector_id");
ffReadFileBuffer(drmDir.chars, name);
if (ffStrbufToUInt(name, 0) != connId)
ffReadFileData(drmDir.chars, sizeof(connectorId), connectorId);
if (strtoul(connectorId, NULL, 10) != connId)
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufClear(name);
ffStrbufAppendS(&drmDir, "/edid");
uint8_t edidData[128];
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
ffEdidGetName(edidData, name);
*edidLength = ffReadFileData(drmDir.chars, (uint32_t) *edidLength, edidData);
return NULL;
}
ffStrbufClear(name);
return "Failed to match connector ID";
}
@@ -217,7 +229,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
drmDevice* devices[64];
int nDevices = ffdrmGetDevices(devices, sizeof(devices) / sizeof(devices[0]));
if (nDevices < 0)
if (nDevices <= 0)
return "drmGetDevices() failed";
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
@@ -231,11 +243,13 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
const char* path = dev->nodes[DRM_NODE_PRIMARY];
#if __linux__
ffStrbufSetF(&name, "/sys/class/drm/%s/device/power/runtime_status", strrchr(path, '/') + 1);
char buffer[8] = "";
if (ffReadFileData(name.chars, strlen("suspend"), buffer) > 0 && ffStrStartsWith(buffer, "suspend"))
continue;
#endif
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
@@ -251,7 +265,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
if (!conn)
continue;
if (conn->connection == DRM_MODE_CONNECTED)
if (conn->connection != DRM_MODE_DISCONNECTED)
{
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
uint32_t width = 0, height = 0, refreshRate = 0;
@@ -303,6 +317,9 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
ffStrbufClear(&name);
uint16_t myear = 0, mweak = 0;
uint32_t serial = 0;
FFDisplayHdrStatus hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
for (int iProp = 0; iProp < conn->count_props; ++iProp)
{
@@ -323,7 +340,11 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
if (blob)
{
if (blob->length >= 128)
{
ffEdidGetName(blob->data, &name);
hdrStatus = ffEdidGetHdrCompatible(blob->data, blob->length) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(blob->data, &serial, &myear, &mweak);
}
ffdrmModeFreePropertyBlob(blob);
}
break;
@@ -331,10 +352,20 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
ffdrmModeFreeProperty(prop);
}
#if __linux__
if (name.length == 0)
{
drmGetNameByConnId(conn->connector_id, &name);
uint8_t edidData[512];
ssize_t edidLength = 0;
drmGetEdidByConnId(conn->connector_id, edidData, &edidLength);
if (edidLength > 0 && edidLength % 128 == 0)
{
ffEdidGetName(edidData, &name);
hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
ffEdidGetSerialAndManufactureDate(edidData, &serial, &myear, &mweak);
}
}
#endif
if (name.length == 0)
{
@@ -344,7 +375,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn + 1);
}
ffdsAppendDisplay(result,
FFDisplayResult* item = ffdsAppendDisplay(result,
width,
height,
refreshRate,
@@ -361,6 +392,14 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
conn->mmWidth,
conn->mmHeight
);
if (item)
{
item->hdrStatus = hdrStatus;
item->serial = serial;
item->manufactureYear = myear;
item->manufactureWeek = mweak;
}
}
ffdrmModeFreeConnector(conn);
@@ -112,7 +112,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
uint32_t rotation = ffWaylandHandleRotation(&display);
ffdsAppendDisplay(wldata->result,
FFDisplayResult* item = ffdsAppendDisplay(wldata->result,
(uint32_t) display.width,
(uint32_t) display.height,
display.refreshRate / 1000.0,
@@ -131,6 +131,19 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
(uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight
);
if (item)
{
if (display.hdrSupported)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
else if (display.hdrInfoAvailable)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
else
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
item->manufactureYear = display.myear;
item->manufactureWeek = display.mweek;
item->serial = display.serial;
}
ffStrbufDestroy(&display.description);
ffStrbufDestroy(&display.name);
@@ -80,6 +80,9 @@ static void waylandKdeEdidListener(void* data, FF_MAYBE_UNUSED struct kde_output
FF_STRBUF_AUTO_DESTROY edid = ffBase64DecodeStrbuf(&b64);
if (edid.length < 128) return;
ffEdidGetName((const uint8_t*) edid.chars, &wldata->edidName);
wldata->hdrSupported = ffEdidGetHdrCompatible((const uint8_t*) edid.chars, edid.length);
ffEdidGetSerialAndManufactureDate((const uint8_t*) edid.chars, &wldata->serial, &wldata->myear, &wldata->mweek);
wldata->hdrInfoAvailable = true;
}
static void waylandKdeEnabledListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, int32_t enabled)
@@ -195,7 +198,18 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
);
if (item)
{
item->hdrEnabled = display.hdrEnabled;
if (display.hdrEnabled)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_ENABLED;
else if (display.hdrSupported)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
else if (display.hdrInfoAvailable)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
else
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
item->manufactureYear = display.myear;
item->manufactureWeek = display.mweek;
item->serial = display.serial;
}
ffStrbufDestroy(&display.description);
@@ -1,5 +1,6 @@
#include "../displayserver_linux.h"
#include "common/io/io.h"
#include "util/edidHelper.h"
#include "util/stringUtils.h"
#include <stdlib.h>
@@ -82,6 +83,46 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
}
}
static 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."
// However I can't find a better method to get the edid data
const char* drmDirPath = "/sys/class/drm/";
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return false;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
const char* plainName = entry->d_name;
if (ffStrStartsWith(plainName, "card"))
{
const char* tmp = strchr(plainName + strlen("card"), '-');
if (tmp) plainName = tmp + 1;
}
if (ffStrEquals(plainName, connName))
{
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s%s/edid", drmDirPath, entry->d_name);
uint8_t edidData[512];
ssize_t edidLength = ffReadFileData(path.chars, sizeof(edidData), edidData);
if (edidLength > 0 && edidLength % 128 == 0)
{
ffEdidGetName(edidData, &wldata->edidName);
ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
ffEdidGetSerialAndManufactureDate(edidData, &wldata->serial, &wldata->myear, &wldata->mweek);
wldata->hdrInfoAvailable = true;
return true;
}
break;
}
}
return false;
}
void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name)
{
WaylandDisplay* display = data;
@@ -89,7 +130,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const
display->type = ffdsGetDisplayType(name);
if (!display->edidName.length)
ffdsMatchDrmConnector(name, &display->edidName);
matchDrmConnector(name, display);
display->id = ffWaylandGenerateIdFromName(name);
ffStrbufAppendS(&display->name, name);
}
@@ -46,7 +46,12 @@ typedef struct WaylandDisplay
FFstrbuf description;
FFstrbuf edidName;
uint64_t id;
bool hdrInfoAvailable;
bool hdrSupported;
bool hdrEnabled;
uint16_t myear;
uint16_t mweek;
uint32_t serial;
void* internal;
} WaylandDisplay;
@@ -122,7 +122,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
uint32_t rotation = ffWaylandHandleRotation(&display);
ffdsAppendDisplay(wldata->result,
FFDisplayResult* item = ffdsAppendDisplay(wldata->result,
(uint32_t) display.width,
(uint32_t) display.height,
display.refreshRate / 1000.0,
@@ -140,6 +140,19 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
(uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight
);
if (item)
{
if (display.hdrSupported)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_SUPPORTED;
else if (display.hdrInfoAvailable)
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
else
item->hdrStatus = FF_DISPLAY_HDR_STATUS_UNKNOWN;
item->manufactureYear = display.myear;
item->manufactureWeek = display.mweek;
item->serial = display.serial;
}
ffStrbufDestroy(&display.description);
ffStrbufDestroy(&display.name);
+26 -3
View File
@@ -12,6 +12,10 @@
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/user.h>
#elif defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
#elif defined(__sun)
#include <procfs.h>
#endif
@@ -252,7 +256,7 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
{
uint32_t userId = getuid();
#ifdef __FreeBSD__
#if __FreeBSD__
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
size_t length = 0;
@@ -276,7 +280,26 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
#elif defined(__sun)
#elif __OpenBSD__
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
int count = 0;
const struct kinfo_proc* proc = kvm_getprocs(kd, KERN_PROC_UID, userId, sizeof(struct kinfo_proc), &count);
if (proc)
{
for (int i = 0; i < count; ++i)
{
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;
}
}
kvm_close(kd);
#elif __sun
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
if(procdir == NULL)
return "opendir(\"/proc\") failed";
@@ -312,7 +335,7 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
break;
}
}
#else
#elif __linux__
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
if(procdir == NULL)
return "opendir(\"/proc\") failed";
+28 -34
View File
@@ -180,47 +180,29 @@ typedef struct XcbRandrData
xcb_randr_get_screen_resources_current_reply_t* screenResources;
} XcbRandrData;
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
{
double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
return ffdsAppendDisplay(
data->result,
(uint32_t) modeInfo->width,
(uint32_t) modeInfo->height,
refreshRate,
(uint32_t) modeInfo->width,
(uint32_t) modeInfo->height,
rotation,
name,
displayType,
primary,
0,
(uint32_t) output->mm_width,
(uint32_t) output->mm_height
);
}
static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
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 false;
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)
return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary, output, displayType);
{
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 false;
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)
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);
FF_AUTO_FREE xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
@@ -243,12 +225,12 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
rotation = 0;
break;
}
bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary, output, displayType);
res = res ? true : !!ffdsAppendDisplay(
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
0,
xcbRandrHandleMode(data, crtcInfoReply->mode),
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
rotation,
@@ -259,8 +241,14 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
(uint32_t) output->mm_width,
(uint32_t) output->mm_height
);
if (item && edidLength)
{
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 res;
return !!item;
}
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType)
@@ -272,21 +260,27 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(data->connection, true, (uint16_t) strlen("EDID"), "EDID");
FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(data->connection, requestAtomCookie, NULL);
FF_AUTO_FREE xcb_randr_get_output_property_reply_t* outputPropertyReply = NULL;
uint8_t* edidData = NULL;
uint32_t edidLength = 0;
if(requestAtomReply)
{
xcb_randr_get_output_property_cookie_t outputPropertyCookie = data->ffxcb_randr_get_output_property(data->connection, output, requestAtomReply->atom, XCB_GET_PROPERTY_TYPE_ANY, 0, 100, false, false);
FF_AUTO_FREE xcb_randr_get_output_property_reply_t* outputPropertyReply = data->ffxcb_randr_get_output_property_reply(data->connection, outputPropertyCookie, NULL);
outputPropertyReply = data->ffxcb_randr_get_output_property_reply(data->connection, outputPropertyCookie, NULL);
if(outputPropertyReply)
{
if(data->ffxcb_randr_get_output_property_data_length(outputPropertyReply) >= 128)
int len = data->ffxcb_randr_get_output_property_data_length(outputPropertyReply);
if(len >= 128)
{
ffStrbufClear(name);
ffEdidGetName(data->ffxcb_randr_get_output_property_data(outputPropertyReply), name);
edidData = data->ffxcb_randr_get_output_property_data(outputPropertyReply);
ffEdidGetName(edidData, name);
edidLength = (uint32_t) len;
}
}
}
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply, displayType);
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply, displayType, edidData, edidLength);
return res;
}
+22 -11
View File
@@ -153,13 +153,13 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode)
return 0;
}
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary, XRROutputInfo* output, FFDisplayType displayType)
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
if(data->screenResources == NULL)
return false;
XRRCrtcInfo* crtcInfo = data->ffXRRGetCrtcInfo(data->display, data->screenResources, crtc);
XRRCrtcInfo* crtcInfo = data->ffXRRGetCrtcInfo(data->display, data->screenResources, output->crtc);
if(crtcInfo == NULL)
return false;
@@ -180,7 +180,7 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool
break;
}
bool res = ffdsAppendDisplay(
FFDisplayResult* item = ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfo->width,
(uint32_t) crtcInfo->height,
@@ -196,8 +196,15 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool
(uint32_t) output->mm_height
);
if (edidLength)
{
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);
return res;
return !!item;
}
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType)
@@ -206,26 +213,30 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
if(outputInfo == NULL)
return false;
uint8_t* edidData = NULL;
unsigned long edidLength = 0;
Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true);
if (atomEdid != None)
{
int actual_format = 0;
unsigned long nitems = 0, bytes_after = 0;
unsigned long bytes_after = 0;
Atom actual_type = None;
uint8_t* edidData = NULL;
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &edidData) == Success)
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &edidLength, &bytes_after, &edidData) == Success)
{
if (nitems >= 128)
if (edidLength >= 128)
{
ffStrbufClear(name);
ffEdidGetName(edidData, name);
}
else
edidLength = 0;
}
if (edidData)
data->ffXFree(edidData);
}
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary, outputInfo, displayType);
bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, (uint32_t) edidLength);
if (edidData)
data->ffXFree(edidData);
data->ffXRRFreeOutputInfo(outputInfo);
return res;
+4 -1
View File
@@ -17,11 +17,14 @@ const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
{
if (ffStrStartsWith(line, "nameserver"))
{
const char* nameserver = line + strlen("nameserver");
char* nameserver = line + strlen("nameserver");
while (*nameserver == ' ' || *nameserver == '\t')
nameserver++;
if (*nameserver == '\0') continue;
char* comment = strchr(nameserver, '#');
if (comment) *comment = '\0';
if ((ffStrContainsC(nameserver, ':') && !(options->showType & FF_DNS_TYPE_IPV6_BIT)) ||
(ffStrContainsC(nameserver, '.') && !(options->showType & FF_DNS_TYPE_IPV4_BIT)))
continue;
+1
View File
@@ -55,6 +55,7 @@ const char* detectByOpenGL(FFlist* gpus)
ffStrbufInitMove(&gpu->name, &result.renderer);
ffStrbufInitMove(&gpu->driver, &result.vendor);
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
+4 -2
View File
@@ -7,6 +7,7 @@
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t)-1)
#define FF_GPU_FREQUENCY_UNSET 0
#define FF_GPU_CORE_USAGE_UNSET (0/0.0)
#define FF_GPU_INDEX_UNSET ((uint32_t)-1)
extern const char* FF_GPU_VENDOR_NAME_APPLE;
extern const char* FF_GPU_VENDOR_NAME_AMD;
@@ -27,6 +28,7 @@ typedef struct FFGPUMemory
typedef struct FFGPUResult
{
uint32_t index;
FFGPUType type;
FFstrbuf vendor;
FFstrbuf name;
@@ -38,7 +40,7 @@ typedef struct FFGPUResult
uint32_t frequency; // Maximum time clock frequency in MHz
FFGPUMemory dedicated;
FFGPUMemory shared;
uint64_t deviceId; // Used internally, may be uninitialized
uint64_t deviceId;
} FFGPUResult;
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
@@ -47,5 +49,5 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
const char* ffGetGPUVendorString(unsigned vendorId);
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName);
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
#endif
+6
View File
@@ -65,5 +65,11 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
if (result.type)
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
if (result.index)
*result.type = (uint32_t) device->adlAdapterIndex;
if (result.name)
ffStrbufSetS(result.name, device->adapterString);
return NULL;
}
+4 -1
View File
@@ -1,12 +1,13 @@
#include "gpu.h"
#include "common/library.h"
#include "detection/cpu/cpu.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/smc_temps.h"
#include <IOKit/graphics/IOGraphicsLib.h>
const char* ffGpuDetectMetal(FFlist* gpus);
const char* ffGpuDetectDriverVersion(FFlist* gpus);
static double detectGpuTemp(const FFstrbuf* gpuName)
{
@@ -185,5 +186,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
}
ffGpuDetectMetal(gpus);
if (instance.config.general.detectVersion)
ffGpuDetectDriverVersion(gpus);
return NULL;
}
+25 -1
View File
@@ -1,6 +1,7 @@
#include "gpu.h"
#import <Metal/MTLDevice.h>
#import <IOKit/kext/KextManager.h>
#ifndef MAC_OS_VERSION_13_0
#define MTLGPUFamilyMetal3 ((MTLGPUFamily) 5001)
@@ -10,6 +11,28 @@
#define MTLFeatureSet_macOS_GPUFamily2_v1 ((MTLFeatureSet) 10005)
#endif
const char* ffGpuDetectDriverVersion(FFlist* gpus)
{
if (@available(macOS 10.7, *))
{
NSMutableArray* arr = NSMutableArray.new;
FF_LIST_FOR_EACH(FFGPUResult, x, *gpus)
[arr addObject:@(x->driver.chars)];
NSDictionary* dict = CFBridgingRelease(KextManagerCopyLoadedKextInfo((__bridge CFArrayRef)arr, (__bridge CFArrayRef)@[@"CFBundleVersion"]));
FF_LIST_FOR_EACH(FFGPUResult, x, *gpus)
{
NSString* version = dict[@(x->driver.chars)][@"CFBundleVersion"];
if (version)
{
ffStrbufAppendC(&x->driver, ' ');
ffStrbufAppendS(&x->driver, version.UTF8String);
}
}
}
return "Unsupported macOS version";
}
const char* ffGpuDetectMetal(FFlist* gpus)
{
if (@available(macOS 10.13, *))
@@ -42,7 +65,8 @@ const char* ffGpuDetectMetal(FFlist* gpus)
else if ([device supportsFamily:MTLGPUFamilyCommon1])
ffStrbufSetStatic(&gpu->platformApi, "Metal Common 1");
gpu->type = device.hasUnifiedMemory ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
gpu->type = device.location == MTLDeviceLocationBuiltIn ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
gpu->index = (uint32_t) device.locationNumber;
#endif
}
return NULL;
+91
View File
@@ -0,0 +1,91 @@
#if __aarch64__ && FF_HAVE_DRM
#include <drm.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#if __has_include(<drm/asahi_drm.h>)
#include <drm/asahi_drm.h>
#else
// https://github.com/AsahiLinux/linux/blob/asahi/include/uapi/drm/asahi_drm.h
/* SPDX-License-Identifier: MIT */
/* Copyright (C) The Asahi Linux Contributors */
#define DRM_ASAHI_UNSTABLE_UABI_VERSION 10011
#define DRM_ASAHI_GET_PARAMS 0x00
#define DRM_ASAHI_MAX_CLUSTERS 32
struct drm_asahi_params_global
{
__u32 unstable_uabi_version;
__u32 pad0;
__u64 feat_compat;
__u64 feat_incompat;
__u32 gpu_generation;
__u32 gpu_variant;
__u32 gpu_revision;
__u32 chip_id;
__u32 num_dies;
__u32 num_clusters_total;
__u32 num_cores_per_cluster;
__u32 num_frags_per_cluster;
__u32 num_gps_per_cluster;
__u32 num_cores_total_active;
__u64 core_masks[DRM_ASAHI_MAX_CLUSTERS];
__u32 vm_page_size;
__u32 pad1;
__u64 vm_user_start;
__u64 vm_user_end;
__u64 vm_usc_start;
__u64 vm_usc_end;
__u64 vm_kernel_min_size;
__u32 max_syncs_per_submission;
__u32 max_commands_per_submission;
__u32 max_commands_in_flight;
__u32 max_attachments;
__u32 timer_frequency_hz;
__u32 min_frequency_khz;
__u32 max_frequency_khz;
__u32 max_power_mw;
__u32 result_render_size;
__u32 result_compute_size;
__u32 firmware_version[4];
};
struct drm_asahi_get_params
{
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
/** @param: Parameter group to fetch (MBZ) */
__u32 param_group;
/** @pad: MBZ */
__u32 pad;
/** @value: User pointer to write parameter struct */
__u64 pointer;
/** @value: Size of user buffer, max size supported on return */
__u64 size;
};
enum
{
DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
};
#endif // __has_include
#endif // FF_HAVE_DRM
+18 -39
View File
@@ -8,20 +8,6 @@
#include <dev/pci/pcireg.h>
#include <sys/pciio.h>
#include <fcntl.h>
#include <paths.h>
static bool loadPciIds(FFstrbuf* pciids)
{
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
return false;
}
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
@@ -45,8 +31,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
if (pcio.status == PCI_GETCONF_ERROR)
return "ioctl(fd, PCIOCGETCONF, &pc) returned error";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
for (uint32_t i = 0; i < pcio.num_matches; ++i)
{
struct pci_conf* pc = &confs[i];
@@ -56,29 +40,15 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
ffStrbufInit(&gpu->name);
ffStrbufInitS(&gpu->driver, pc->pd_name);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pc->pc_sel.pc_domain << 6) | ((uint64_t) pc->pc_sel.pc_bus << 4) | ((uint64_t) pc->pc_sel.pc_dev << 2) | pc->pc_sel.pc_func;
gpu->deviceId = (pc->pc_sel.pc_domain * 100000ull) + (pc->pc_sel.pc_bus * 1000ull) + (pc->pc_sel.pc_dev * 10ull) + pc->pc_sel.pc_func;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) pc->pc_device, (unsigned) pc->pc_revid);
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
}
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
if (gpu->name.length == 0)
{
if (pciids.length == 0)
loadPciIds(&pciids);
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu, &coreName);
}
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
{
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
@@ -90,16 +60,29 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
.func = pc->pc_sel.pc_func,
},
}, (FFGpuDriverResult) {
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
.coreUsage = &gpu->coreUsage,
.name = options->driverSpecific ? &gpu->name : NULL,
.name = &gpu->name,
}, "libnvidia-ml.so");
}
if (gpu->name.length == 0)
{
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) pc->pc_device, (unsigned) pc->pc_revid);
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
}
if (gpu->name.length == 0)
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
}
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
{
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
@@ -116,12 +99,8 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
if ((coreName.chars[0] == 'D' || coreName.chars[0] == 'S') &&
coreName.chars[1] == 'G' &&
ffCharIsDigit(coreName.chars[2]))
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
else
gpu->type = FF_GPU_TYPE_INTEGRATED;
// 0000:00:02.0 is reserved for Intel integrated graphics
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
}
}
}
+1
View File
@@ -37,6 +37,7 @@ typedef struct FFGpuDriverCondition
// detect x if not NULL
typedef struct FFGpuDriverResult
{
uint32_t* index;
double* temp;
FFGPUMemory* memory;
uint32_t* coreCount;
+3
View File
@@ -195,5 +195,8 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
}
if (result.name)
ffStrbufSetS(result.name, properties.name);
return NULL;
}
+417 -194
View File
@@ -1,100 +1,33 @@
#include "detection/gpu/gpu.h"
#include "detection/vulkan/vulkan.h"
#include "detection/temps/temps_linux.h"
#include "detection/cpu/cpu.h"
#include "detection/gpu/gpu_driver_specific.h"
#include "common/io/io.h"
#include "common/library.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <inttypes.h>
#if __aarch64__ && FF_HAVE_DRM
#include <drm.h>
#ifdef FF_HAVE_DRM_AMDGPU
#include <amdgpu.h>
#include <amdgpu_drm.h>
#include <fcntl.h>
#endif
#ifdef FF_HAVE_DRM
#include "intel_drm.h"
#include <fcntl.h>
#include <sys/ioctl.h>
// https://github.com/AsahiLinux/linux/blob/asahi/include/uapi/drm/asahi_drm.h
/* SPDX-License-Identifier: MIT */
/* Copyright (C) The Asahi Linux Contributors */
#define DRM_ASAHI_UNSTABLE_UABI_VERSION 10011
#define DRM_ASAHI_GET_PARAMS 0x00
#define DRM_ASAHI_MAX_CLUSTERS 32
struct drm_asahi_params_global
{
__u32 unstable_uabi_version;
__u32 pad0;
__u64 feat_compat;
__u64 feat_incompat;
__u32 gpu_generation;
__u32 gpu_variant;
__u32 gpu_revision;
__u32 chip_id;
__u32 num_dies;
__u32 num_clusters_total;
__u32 num_cores_per_cluster;
__u32 num_frags_per_cluster;
__u32 num_gps_per_cluster;
__u32 num_cores_total_active;
__u64 core_masks[DRM_ASAHI_MAX_CLUSTERS];
__u32 vm_page_size;
__u32 pad1;
__u64 vm_user_start;
__u64 vm_user_end;
__u64 vm_usc_start;
__u64 vm_usc_end;
__u64 vm_kernel_min_size;
__u32 max_syncs_per_submission;
__u32 max_commands_per_submission;
__u32 max_commands_in_flight;
__u32 max_attachments;
__u32 timer_frequency_hz;
__u32 min_frequency_khz;
__u32 max_frequency_khz;
__u32 max_power_mw;
__u32 result_render_size;
__u32 result_compute_size;
__u32 firmware_version[4];
};
struct drm_asahi_get_params
{
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
/** @param: Parameter group to fetch (MBZ) */
__u32 param_group;
/** @pad: MBZ */
__u32 pad;
/** @value: User pointer to write parameter struct */
__u64 pointer;
/** @value: Size of user buffer, max size supported on return */
__u64 size;
};
enum
{
DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
};
#endif
#include "gpu_asahi.h"
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
static bool pciDetectDriver(FFstrbuf* result, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
{
uint32_t pciDirLength = pciDir->length;
ffStrbufAppendS(pciDir, "/driver");
@@ -106,17 +39,17 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
if (slash)
{
slash++;
ffStrbufSetNS(&gpu->driver, (uint32_t) (resultLength - (slash - pathBuf)), slash);
ffStrbufSetNS(result, (uint32_t) (resultLength - (slash - pathBuf)), slash);
}
if (ffStrbufEqualS(&gpu->driver, "nvidia"))
if (ffStrbufEqualS(result, "nvidia"))
{
if (ffReadFileBuffer("/proc/driver/nvidia/version", buffer))
{
if (ffStrbufContainS(buffer, " Open "))
ffStrbufAppendS(&gpu->driver, " (open source)");
ffStrbufAppendS(result, " (open source)");
else
ffStrbufAppendS(&gpu->driver, " (proprietary)");
ffStrbufAppendS(result, " (proprietary)");
}
}
@@ -126,18 +59,18 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
if (ffReadFileBuffer(pciDir->chars, buffer))
{
ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppend(&gpu->driver, buffer);
ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, buffer);
}
else if (ffStrbufEqualS(&gpu->driver, "zx"))
else if (ffStrbufEqualS(result, "zx"))
{
ffStrbufSubstrBefore(pciDir, pciDirLength);
ffStrbufAppendS(pciDir, "/zx_info/driver_version");
if (ffReadFileBuffer(pciDir->chars, buffer))
{
ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppend(&gpu->driver, buffer);
ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, buffer);
}
}
}
@@ -145,6 +78,98 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
return true;
}
static const char* drmFindRenderFromCard(const char* drmCardKey, FFstrbuf* result)
{
char path[PATH_MAX];
sprintf(path, "/sys/class/drm/%s/device/drm", drmCardKey);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path);
if (!dirp) return "Failed to open `/sys/class/drm/{drmCardKey}/device/drm`";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "render"))
{
ffStrbufSetS(result, "/dev/dri/");
ffStrbufAppendS(result, entry->d_name);
return NULL;
}
}
return "Failed to find render device";
}
static const char* drmDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, const char* drmKey, FFstrbuf* buffer)
{
#if FF_HAVE_DRM_AMDGPU
FF_LIBRARY_LOAD(libdrm, "dlopen libdrm_amdgpu" FF_LIBRARY_EXTENSION " failed", "libdrm_amdgpu" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_device_initialize)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_get_marketing_name)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_gpu_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_sensor_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_heap_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_device_deinitialize)
{
const char* error = drmFindRenderFromCard(drmKey, buffer);
if (error) return error;
}
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd < 0) return "Failed to open DRM device";
amdgpu_device_handle handle;
uint32_t majorVersion, minorVersion;
if (ffamdgpu_device_initialize(fd, &majorVersion, &minorVersion, &handle) < 0)
return "Failed to initialize AMDGPU device";
ffStrbufAppendF(&gpu->driver, " %u.%u", (unsigned) majorVersion, (unsigned) minorVersion);
uint32_t value;
if (options->temp)
{
if (ffamdgpu_query_sensor_info(handle, AMDGPU_INFO_SENSOR_GPU_TEMP, sizeof(value), &value) >= 0)
gpu->temperature = value / 1000.;
}
ffStrbufSetS(&gpu->name, ffamdgpu_get_marketing_name(handle));
struct amdgpu_gpu_info gpuInfo;
if (ffamdgpu_query_gpu_info(handle, &gpuInfo) >= 0)
{
gpu->coreCount = (int32_t) gpuInfo.cu_active_number;
gpu->frequency = (uint32_t) (gpuInfo.max_engine_clk / 1000u);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->type = gpuInfo.ids_flags & AMDGPU_IDS_FLAGS_FUSION ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
struct amdgpu_heap_info heapInfo;
if (ffamdgpu_query_heap_info(handle, AMDGPU_GEM_DOMAIN_VRAM, 0, &heapInfo) >= 0)
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
{
gpu->dedicated.total = heapInfo.heap_size;
gpu->dedicated.used = heapInfo.heap_usage;
}
else
{
gpu->shared.total = heapInfo.heap_size;
gpu->shared.used = heapInfo.heap_usage;
}
}
}
if (ffamdgpu_query_sensor_info(handle, AMDGPU_INFO_SENSOR_GPU_LOAD, sizeof(value), &value) >= 0)
gpu->coreUsage = value;
ffamdgpu_device_deinitialize(handle);
return NULL;
#else
FF_UNUSED(options, gpu, drmKey, buffer);
return "Fastfetch is compiled without libdrm support";
#endif
}
static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
{
// https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#mem-info-vis-vram-total
@@ -186,6 +211,11 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_total");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
gpu->dedicated.total = value;
else
gpu->shared.total = value;
ffStrbufSubstrBefore(pciDir, pciDir->length - (uint32_t) strlen("/mem_info_vis_vram_total"));
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_used");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
@@ -199,61 +229,174 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
}
}
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const FFstrbuf* coreName)
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey)
{
// Works for Intel GPUs
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
if ((coreName->chars[0] == 'D' || coreName->chars[0] == 'S') &&
coreName->chars[1] == 'G' &&
ffCharIsDigit(coreName->chars[2]))
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
else
gpu->type = FF_GPU_TYPE_INTEGRATED;
// 0000:00:02.0 is reserved for Intel integrated graphics
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
if (!drmKey) return;
if (ffStrbufEqualS(&gpu->driver, "xe"))
{
ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq");
}
else
{
ffStrbufAppendS(pciDir, "/drm/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "card")) break;
}
if (!entry) return;
ffStrbufAppendS(pciDir, entry->d_name);
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
}
ffStrbufAppendF(pciDir, "/drm/%s/gt_max_freq_mhz", drmKey);
if (ffReadFileBuffer(pciDir->chars, buffer))
gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0);
}
static bool loadPciIds(FFstrbuf* pciids)
static inline int popcountBytes(uint8_t* bytes, uint32_t length)
{
#ifdef FF_CUSTOM_PCI_IDS_PATH
int count = 0;
while (length >= 8)
{
count += __builtin_popcountll(*(uint64_t*) bytes);
bytes += 8;
length -= 8;
}
if (length >= 4)
{
count += __builtin_popcountl(*(uint32_t*) bytes);
bytes += 4;
length -= 4;
}
if (length >= 2)
{
count += __builtin_popcountl(*(uint16_t*) bytes);
bytes += 2;
length -= 2;
}
if (length)
{
count += __builtin_popcountl(*(uint8_t*) bytes);
}
return count;
}
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), pciids);
if (pciids->length > 0) return true;
static const char* drmDetectIntelSpecific(FFGPUResult* gpu, const char* drmKey, FFstrbuf* buffer)
{
#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd < 0) return "Failed to open drm device";
if (ffStrbufEqualS(&gpu->driver, "xe"))
{
{
struct drm_xe_device_query query = {
.extensions = 0,
.query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY,
.size = 0,
.data = 0,
};
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
FF_AUTO_FREE uint8_t* buffer = malloc(query.size);
query.data = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
int dssCount = 0, euPerDssCount = 0;
for (struct drm_xe_query_topology_mask* topo = (void*) buffer;
(uint8_t*) topo < buffer + query.size;
topo = (void*) (topo->mask + topo->num_bytes)
) {
switch (topo->type)
{
case DRM_XE_TOPO_DSS_COMPUTE:
case DRM_XE_TOPO_DSS_GEOMETRY:
dssCount += popcountBytes(topo->mask, topo->num_bytes);
break;
case DRM_XE_TOPO_EU_PER_DSS:
euPerDssCount += popcountBytes(topo->mask, topo->num_bytes);
break;
}
}
gpu->coreCount = dssCount * euPerDssCount;
}
}
}
{
struct drm_xe_device_query query = {
.query = DRM_XE_DEVICE_QUERY_MEM_REGIONS,
};
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
FF_AUTO_FREE uint8_t* buffer = malloc(query.size);
query.data = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
gpu->dedicated.total = gpu->shared.total = gpu->dedicated.used = gpu->shared.used = 0;
struct drm_xe_query_mem_regions* regionInfo = (void*) buffer;
for (uint32_t i = 0; i < regionInfo->num_mem_regions; i++)
{
struct drm_xe_mem_region* region = regionInfo->mem_regions + i;
switch (region->mem_class)
{
case DRM_XE_MEM_REGION_CLASS_SYSMEM:
gpu->shared.total += region->total_size;
gpu->shared.used += region->used;
break;
case DRM_XE_MEM_REGION_CLASS_VRAM:
gpu->dedicated.total += region->total_size;
gpu->dedicated.used += region->used;
break;
}
}
}
}
}
}
else if (ffStrbufEqualS(&gpu->driver, "i915"))
{
{
int value;
drm_i915_getparam_t getparam = { .param = I915_PARAM_EU_TOTAL, .value = &value };
if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &getparam) >= 0)
gpu->coreCount = value;
}
{
struct drm_i915_query_item queryItem = {
.query_id = DRM_I915_QUERY_MEMORY_REGIONS,
};
struct drm_i915_query query = {
.items_ptr = (uintptr_t) &queryItem,
.num_items = 1,
};
if (ioctl(fd, DRM_IOCTL_I915_QUERY, &query) >= 0 )
{
FF_AUTO_FREE uint8_t* buffer = calloc(1, (size_t) queryItem.length);
queryItem.data_ptr = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_I915_QUERY, &query) >= 0)
{
gpu->dedicated.total = gpu->shared.total = gpu->dedicated.used = gpu->shared.used = 0;
struct drm_i915_query_memory_regions* regionInfo = (void*) buffer;
for (uint32_t i = 0; i < regionInfo->num_regions; i++)
{
struct drm_i915_memory_region_info* region = regionInfo->regions + i;
switch (region->region.memory_class)
{
case I915_MEMORY_CLASS_SYSTEM:
gpu->shared.total += region->probed_size;
gpu->shared.used += region->probed_size - region->unallocated_size;
break;
case I915_MEMORY_CLASS_DEVICE:
gpu->dedicated.total += region->probed_size;
gpu->dedicated.used += region->probed_size - region->unallocated_size;
break;
}
}
}
}
}
}
return NULL;
#else
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", pciids); // debian?
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
return "Fastfetch is not compiled with drm support";
#endif
return false;
}
static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf* buffer, FFstrbuf* deviceDir, const char* drmKey)
@@ -262,7 +405,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
uint32_t vendorId, deviceId, subVendorId, subDeviceId;
uint8_t classId, subclassId;
if (sscanf(buffer->chars + strlen("pci:"), "v%8" SCNx32 "d%8" SCNx32 "sv%8" SCNx32 "sd%8" SCNx32 "bc%2" SCNx8 "sc%2" SCNx8, &vendorId, &deviceId, &subVendorId, &subDeviceId, &classId, &subclassId) != 6)
return "Invalid modalias string";
return "Failed to parse pci modalias";
if (classId != 0x03 /*PCI_BASE_CLASS_DISPLAY*/)
return "Not a GPU device";
@@ -295,61 +438,78 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pciDomain << 6) | ((uint64_t) pciBus << 4) | (deviceId << 2) | pciFunc;
gpu->deviceId = (pciDomain * 100000ull) + (pciBus * 1000ull) + (pciDevice * 10ull) + pciFunc;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (drmKey) ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
char drmKeyBuffer[8];
if (!drmKey)
{
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer))
ffStrbufAppendS(deviceDir, "/drm");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(deviceDir->chars);
if (dirp)
{
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars)
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
#else
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
#endif
if (ffStrStartsWith(entry->d_name, "card"))
{
strncpy(drmKeyBuffer, entry->d_name, sizeof(drmKeyBuffer) - 1);
drmKeyBuffer[sizeof(drmKeyBuffer) - 1] = '\0';
drmKey = drmKeyBuffer;
break;
}
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
if (gpu->name.length == 0)
{
static FFstrbuf pciids;
if (pciids.chars == NULL)
{
ffStrbufInit(&pciids);
loadPciIds(&pciids);
}
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu, &coreName);
}
if (drmKey) ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
pciDetectDriver(gpu, deviceDir, buffer, drmKey);
pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
bool ok = false;
if (drmKey && options->driverSpecific)
ok = drmDetectAmdSpecific(options, gpu, drmKey, buffer) == NULL;
if (!ok)
{
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer))
{
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
#else
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
#endif
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
pciDetectIntelSpecific(gpu, deviceDir, buffer, &coreName);
pciDetectIntelSpecific(gpu, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (options->driverSpecific && drmKey)
drmDetectIntelSpecific(gpu, drmKey, buffer);
}
else
{
@@ -366,13 +526,14 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
.func = pciFunc,
},
}, (FFGpuDriverResult) {
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
.name = options->driverSpecific ? &gpu->name : NULL,
.name = &gpu->name,
}, soName);
}
@@ -393,23 +554,92 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
}
}
if (gpu->name.length == 0)
ffGPUFillVendorAndName(subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
return NULL;
}
#if __aarch64__
FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
FF_MAYBE_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FFstrbuf* buffer, const char* drmKey)
{
uint32_t index = ffStrbufFirstIndexS(buffer, "apple,agx-t");
if (index == buffer->length) return "display-subsystem?";
index += (uint32_t) strlen("apple,agx-t");
if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1)
ffStrbufSetStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd >= 0)
{
struct drm_asahi_params_global paramsGlobal = {};
if (ioctl(fd, DRM_IOCTL_ASAHI_GET_PARAMS, &(struct drm_asahi_get_params) {
.param_group = DRM_ASAHI_GET_PARAMS,
.pointer = (uint64_t) &paramsGlobal,
.size = sizeof(paramsGlobal),
}) >= 0)
{
ffStrbufAppendF(&gpu->driver, " %u", paramsGlobal.unstable_uabi_version);
// FIXME: They will introduce ABI breaking changes. Always check the latest version
// https://www.reddit.com/r/AsahiLinux/comments/1ei2qiv/comment/lgm0v5s/
if (paramsGlobal.unstable_uabi_version == DRM_ASAHI_UNSTABLE_UABI_VERSION)
{
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
gpu->deviceId = paramsGlobal.chip_id;
if (!gpu->name.length)
{
const char* variant = " Unknown";
switch (paramsGlobal.gpu_variant) {
case 'G':
variant = "";
break;
case 'S':
variant = " Pro";
break;
case 'C':
variant = " Max";
break;
case 'D':
variant = " Ultra";
break;
}
ffStrbufSetF(&gpu->name, "Apple M%d%s (G%d%c %02X)",
paramsGlobal.gpu_generation - 12, variant,
paramsGlobal.gpu_generation, paramsGlobal.gpu_variant,
paramsGlobal.gpu_revision + 0xA0);
}
}
}
}
#endif
return NULL;
}
#endif
static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
{
char compatible[256]; // vendor,model-name
if (sscanf(buffer->chars + strlen("of:"), "NgpuT%*[^C]C%255[^C]", compatible) != 1)
return "Failed to parse of modalias or not a GPU device";
char* name = strchr(compatible, ',');
if (name)
{
*name = '\0';
++name;
}
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
ffStrbufInitStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
if (!gpu->name.length)
ffStrbufAppendF(&gpu->name, "Apple Silicon T%u", (uint32_t) gpu->deviceId);
ffStrbufInitStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->deviceId = 0;
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
gpu->temperature = FF_GPU_TEMP_UNSET;
@@ -419,36 +649,31 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
pciDetectDriver(gpu, drmDir, buffer, drmKey);
pciDetectDriver(&gpu->driver, drmDir, buffer, drmKey);
#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd >= 0)
#ifdef __aarch64__
if (ffStrbufEqualS(&gpu->driver, "asahi"))
drmDetectAsahiSpecific(gpu, name, buffer, drmKey);
#endif
if (!gpu->name.length)
{
struct drm_asahi_params_global paramsGlobal = {};
if (ioctl(fd, DRM_IOCTL_ASAHI_GET_PARAMS, &(struct drm_asahi_get_params){
.param_group = DRM_ASAHI_GET_PARAMS,
.pointer = (uint64_t) &paramsGlobal,
.size = sizeof(paramsGlobal),
}) >= 0)
ffStrbufSetS(&gpu->name, name ? name : compatible);
ffStrbufTrimRightSpace(&gpu->name);
}
if (!gpu->vendor.length && name)
{
if (ffStrEquals(compatible, "brcm"))
ffStrbufSetStatic(&gpu->vendor, "Broadcom"); // Raspberry Pi
else
{
// FIXME: They will introduce ABI breaking changes. Always check the latest version
// https://www.reddit.com/r/AsahiLinux/comments/1ei2qiv/comment/lgm0v5s/
if (paramsGlobal.unstable_uabi_version == DRM_ASAHI_UNSTABLE_UABI_VERSION)
{
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
gpu->deviceId = paramsGlobal.chip_id;
}
ffStrbufSetS(&gpu->vendor, compatible);
gpu->vendor.chars[0] = (char) toupper(compatible[0]);
}
}
#endif
return NULL;
}
#endif
static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{
@@ -478,10 +703,8 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
if (ffStrbufStartsWithS(&buffer, "pci:"))
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
#ifdef __aarch64__
else if (ffStrbufStartsWithS(&buffer, "of:"))
detectAsahi(gpus, &buffer, &drmDir, entry->d_name);
#endif
detectOf(gpus, &buffer, &drmDir, entry->d_name);
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
+8 -1
View File
@@ -30,7 +30,7 @@ struct FFMtmlData
MtmlSystem *sys;
} mtmlData;
static void shutdownMtml()
FF_MAYBE_UNUSED static void shutdownMtml(void)
{
mtmlData.ffmtmlLibraryShutDown(mtmlData.lib);
}
@@ -134,6 +134,13 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive
}
}
if (result.index)
{
unsigned int value;
if (mtmlData.ffmtmlDeviceGetIndex(device, &value) == MTML_SUCCESS)
*result.index = value;
}
if (result.temp)
{
MtmlGpu *gpu = NULL;
+10
View File
@@ -14,6 +14,7 @@ struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo)
FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates)
FF_LIBRARY_SYMBOL(nvmlDeviceGetBrand)
FF_LIBRARY_SYMBOL(nvmlDeviceGetIndex)
FF_LIBRARY_SYMBOL(nvmlDeviceGetName)
bool inited;
@@ -39,6 +40,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetBrand)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetIndex)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetName)
if (ffnvmlInit_v2() != NVML_SUCCESS)
@@ -105,6 +107,14 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
}
}
if (result.index)
{
unsigned int value;
if (nvmlData.ffnvmlDeviceGetIndex(device, &value) == NVML_SUCCESS)
*result.index = value;
}
if (result.temp)
{
uint32_t value;
+112 -6
View File
@@ -1,6 +1,54 @@
#include "gpu.h"
#include "common/io/io.h"
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName)
#include <stdlib.h>
#ifdef __FreeBSD__
#include <paths.h>
#endif
#if FF_HAVE_EMBEDDED_PCIIDS
#include "fastfetch_pciids.c.inc"
#endif
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
static const FFstrbuf* loadPciIds()
{
static FFstrbuf pciids;
if (pciids.chars) return &pciids;
ffStrbufInit(&pciids);
#ifdef FF_CUSTOM_PCI_IDS_PATH
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), &pciids);
#else // FF_CUSTOM_PCI_IDS_PATH
#if __linux__
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", &pciids);
if (pciids.length == 0)
{
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", &pciids); // debian?
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids);
}
#elif __FreeBSD__
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids);
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/pciids/pci.ids", &pciids);
#elif __sun
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
#endif
#endif // FF_CUSTOM_PCI_IDS_PATH
return &pciids;
}
static void parsePciIdsFile(const FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
if (content->length)
{
@@ -52,11 +100,6 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
{
openingBracket++;
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
if (coreName)
{
ffStrbufSetNS(coreName, (uint32_t) (openingBracket - start) - 1, start);
ffStrbufTrimRight(coreName, ' ');
}
}
}
if (!gpu->name.length)
@@ -79,3 +122,66 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr);
}
}
#if FF_HAVE_EMBEDDED_PCIIDS
static inline int pciDeviceCmp(const uint16_t* key, const FFPciDevice* element)
{
return (int) *key - (int) element->id;
}
static bool loadPciidsInc(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
for (const FFPciVendor* pvendor = ffPciVendors; pvendor->name; pvendor++)
{
if (pvendor->id != vendor) continue;
if (!gpu->vendor.length)
ffStrbufSetS(&gpu->vendor, pvendor->name);
const FFPciDevice* pdevice = (const FFPciDevice*) bsearch(&device, pvendor->devices, pvendor->nDevices, sizeof(FFPciDevice), (void*) pciDeviceCmp);
if (pdevice)
{
uint32_t nameLen = (uint32_t) strlen(pdevice->name);
const char* closingBracket = pdevice->name + nameLen - 1;
if (*closingBracket == ']')
{
const char* openingBracket = memrchr(pdevice->name, '[', nameLen - 1);
if (openingBracket)
{
openingBracket++;
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
}
}
if (!gpu->name.length)
ffStrbufSetNS(&gpu->name, nameLen, pdevice->name);
return true;
}
if (!gpu->name.length)
{
const char* subclassStr;
switch (subclass)
{
case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break;
case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break;
case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break;
default: subclassStr = ""; break;
}
ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr);
}
return true;
}
return false;
}
#endif
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
#if FF_HAVE_EMBEDDED_PCIIDS
bool ok = loadPciidsInc(subclass, vendor, device, gpu);
if (ok) return;
#endif
return parsePciIdsFile(loadPciIds(), subclass, vendor, device, gpu);
}
+2 -5
View File
@@ -20,8 +20,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (!ffStrbufStartsWithS(&buffer, "\npci "))
return "Invalid scanpci result";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
// Device unknown
// CardVendor 0x0000 card 0x0000 (Card unknown)
@@ -57,6 +55,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
@@ -74,9 +73,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (gpu->name.length == 0)
{
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu, NULL);
ffGPUFillVendorAndName((uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
}
}
+63 -44
View File
@@ -38,6 +38,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInitStatic(&gpu->platformApi, "SetupAPI");
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
@@ -46,9 +47,18 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->deviceId = 0;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
uint32_t pciBus = 0, pciAddr = UINT32_MAX, pciDev = 0, pciFunc = 0;
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
{
pciDev = (pciAddr >> 16) & 0xFFFF;
pciFunc = pciAddr & 0xFFFF;
gpu->deviceId = (pciBus * 1000ull) + (pciDev * 10ull) + pciFunc;
}
wchar_t buffer[256];
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
ffStrbufSetWS(&gpu->name, buffer);
uint64_t adapterLuid = 0;
FF_HKEY_AUTO_DESTROY hVideoIdKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
if (!hVideoIdKey) continue;
@@ -60,9 +70,19 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
{
uint32_t vendorId = 0;
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
uint64_t dedicatedVideoMemory = 0;
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
{
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
uint64_t dedicatedSystemMemory, sharedSystemMemory;
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
@@ -72,7 +92,10 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->shared.total = sharedSystemMemory;
}
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
if (ffRegReadUint64(hDirectxKey, L"AdapterLuid", &adapterLuid, NULL))
{
if (!gpu->deviceId) gpu->deviceId = adapterLuid;
}
uint32_t featureLevel = 0;
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
@@ -90,10 +113,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
(unsigned) (driverVersion >> 0) & 0xFFFF
);
}
uint32_t vendorId = 0;
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
}
}
@@ -131,43 +150,43 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
}
uint32_t pciBus, pciAddr;
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
{
uint32_t pciDev = (pciAddr >> 16) & 0xFFFF;
uint32_t pciFunc = pciAddr & 0xFFFF;
detectFn(
&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
| (adapterLuid > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
| (pciAddr > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
.pciDeviceId = {
.deviceId = deviceId,
.vendorId = vendorId,
.subSystemId = subSystemId,
.revId = revId,
},
.pciBusId = {
.domain = 0,
.bus = pciBus,
.device = pciDev,
.func = pciFunc,
},
.luid = adapterLuid,
},
(FFGpuDriverResult){
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.name = &gpu->name,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
},
dllName
);
}
detectFn(
&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
| (gpu->deviceId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
| (vendorId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
.pciDeviceId = {
.deviceId = deviceId,
.vendorId = vendorId,
.subSystemId = subSystemId,
.revId = revId,
},
.pciBusId = {
.domain = 0,
.bus = pciBus,
.device = pciDev,
.func = pciFunc,
},
.luid = gpu->deviceId,
},
(FFGpuDriverResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
},
dllName
);
}
if (!gpu->name.length)
{
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
ffStrbufSetWS(&gpu->name, buffer);
}
}
+3 -1
View File
@@ -70,6 +70,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
ffStrbufInitS(&gpu->name, desc);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
@@ -117,7 +118,8 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
.revId = hardwareId.revision,
},
};
ffDetectNvidiaGpuInfo(&cond, (FFGpuDriverResult) {
ffDetectNvidiaGpuInfo(&cond, (FFGpuDriverResult){
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
+125
View File
@@ -0,0 +1,125 @@
#pragma once
/* SPDX-License-Identifier: MIT */
#include <drm.h>
// xe_drm.h
/*
* Copyright © 2023 Intel Corporation
*/
#define DRM_XE_DEVICE_QUERY 0x00
#define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query)
enum drm_xe_memory_class {
DRM_XE_MEM_REGION_CLASS_SYSMEM = 0,
DRM_XE_MEM_REGION_CLASS_VRAM
};
struct drm_xe_mem_region {
__u16 mem_class;
__u16 instance;
__u32 min_page_size;
__u64 total_size;
__u64 used;
__u64 cpu_visible_size;
__u64 cpu_visible_used;
__u64 reserved[6];
};
struct drm_xe_query_mem_regions {
__u32 num_mem_regions;
__u32 pad;
struct drm_xe_mem_region mem_regions[];
};
struct drm_xe_query_topology_mask {
__u16 gt_id;
#define DRM_XE_TOPO_DSS_GEOMETRY 1
#define DRM_XE_TOPO_DSS_COMPUTE 2
#define DRM_XE_TOPO_EU_PER_DSS 4
__u16 type;
__u32 num_bytes;
__u8 mask[];
};
struct drm_xe_device_query {
__u64 extensions;
#define DRM_XE_DEVICE_QUERY_MEM_REGIONS 1
#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
__u32 query;
__u32 size;
__u64 data;
__u64 reserved[2];
};
// i915_drm.h
/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*/
#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
struct drm_i915_getparam {
__s32 param;
int *value;
};
typedef struct drm_i915_getparam drm_i915_getparam_t;
#define DRM_I915_GETPARAM 0x06
#define DRM_I915_QUERY 0x39
#define DRM_I915_QUERY_MEMORY_REGIONS 4
#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
#define I915_PARAM_EU_TOTAL 34
struct drm_i915_query_item {
__u64 query_id;
#define DRM_I915_QUERY_MEMORY_REGIONS 4
__s32 length;
__u32 flags;
__u64 data_ptr;
};
struct drm_i915_query {
__u32 num_items;
__u32 flags;
__u64 items_ptr;
};
enum drm_i915_gem_memory_class {
I915_MEMORY_CLASS_SYSTEM = 0,
I915_MEMORY_CLASS_DEVICE,
};
struct drm_i915_gem_memory_class_instance {
__u16 memory_class;
__u16 memory_instance;
};
struct drm_i915_memory_region_info {
struct drm_i915_gem_memory_class_instance region;
__u32 rsvd0;
__u64 probed_size;
__u64 unallocated_size;
union {
__u64 rsvd1[8];
struct {
__u64 probed_cpu_visible_size;
__u64 unallocated_cpu_visible_size;
};
};
};
struct drm_i915_query_memory_regions {
__u32 num_regions;
__u32 rsvd[3];
struct drm_i915_memory_region_info regions[];
};
+2
View File
@@ -132,5 +132,7 @@ extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType
extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type);
// Retrieves the current utilization rates for the device
extern nvmlReturn_t nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *utilization);
// Retrieves the globally unique immutable UUID associated with this device, as a 5 part hexadecimal string, that augments the immutable, board serial identifier.
extern nvmlReturn_t nvmlDeviceGetIndex(nvmlDevice_t device, unsigned int *index);
// Retrieves the name of this device.
extern nvmlReturn_t nvmlDeviceGetName(nvmlDevice_t device, char *name, unsigned int length);
+19
View File
@@ -0,0 +1,19 @@
#include "host.h"
#include "common/sysctl.h"
#include "util/smbiosHelper.h"
const char* ffDetectHost(FFHostResult* host)
{
const char* error = NULL;
if ((error = ffSysctlGetString(CTL_HW, HW_PRODUCT, &host->name)))
return error;
ffCleanUpSmbiosValue(&host->name);
if (ffSysctlGetString(CTL_HW, HW_VENDOR, &host->vendor) == NULL)
ffCleanUpSmbiosValue(&host->vendor);
if (ffSysctlGetString(CTL_HW, HW_VERSION, &host->version) == NULL)
ffCleanUpSmbiosValue(&host->version);
if (ffSysctlGetString(CTL_HW, HW_SERIALNO, &host->serial) == NULL)
ffCleanUpSmbiosValue(&host->serial);
return NULL;
}
+4 -2
View File
@@ -2,10 +2,12 @@
#include <sys/sysctl.h>
#ifdef __FreeBSD__
#if __FreeBSD__ || __OpenBSD__
#include <sys/types.h>
#include <sys/resource.h>
#include <vm/vm_param.h>
#if __FreeBSD__
#include <vm/vm_param.h>
#endif
#endif
const char* ffDetectLoadavg(double result[3])
+21
View File
@@ -8,9 +8,30 @@ typedef struct FFLocalIpResult
FFstrbuf ipv4;
FFstrbuf ipv6;
FFstrbuf mac;
FFstrbuf flags;
int32_t mtu;
int32_t speed;
bool defaultRoute;
} FFLocalIpResult;
typedef struct FFLocalIpNIFlag
{
uint32_t flag;
const char *name;
} FFLocalIpNIFlag;
static inline void ffLocalIpFillNIFlags(FFstrbuf *buf, uint32_t flag, const FFLocalIpNIFlag names[])
{
for (const FFLocalIpNIFlag *nf = names; flag && nf->name; ++nf)
{
if (flag & nf->flag)
{
if (buf->length > 0)
ffStrbufAppendC(buf, ',');
ffStrbufAppendS(buf, nf->name);
flag &= ~nf->flag;
}
}
}
const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results);
+55 -8
View File
@@ -15,9 +15,10 @@
#ifdef __linux__
#include <linux/ethtool.h>
#include <linux/sockios.h>
#include <linux/if.h>
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
#include <net/if_media.h>
#include <net/if_dl.h>
#else
@@ -27,7 +28,48 @@
#include <sys/sockio.h>
#endif
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
static const FFLocalIpNIFlag niFlagOptions[] = {
{ IFF_UP, "UP" },
{ IFF_BROADCAST, "BROADCAST" },
{ IFF_DEBUG, "DEBUG" },
{ IFF_LOOPBACK, "LOOPBACK" },
{ IFF_POINTOPOINT, "POINTOPOINT" },
{ IFF_RUNNING, "RUNNING" },
{ IFF_NOARP, "NOARP" },
{ IFF_PROMISC, "PROMISC" },
{ IFF_ALLMULTI, "ALLMULTI" },
{ IFF_MULTICAST, "MULTICAST" },
#if defined(__linux__) || defined(__APPLE__) || defined(__sun)
{ IFF_NOTRAILERS, "NOTRAILERS" },
#endif
#ifdef __linux__
{ IFF_MASTER, "MASTER" },
{ IFF_SLAVE, "SLAVE" },
{ IFF_PORTSEL, "PORTSEL" },
{ IFF_AUTOMEDIA, "AUTOMEDIA" },
{ IFF_DYNAMIC, "DYNAMIC" },
{ IFF_LOWER_UP, "LOWER_UP" },
{ IFF_DORMANT, "DORMANT" },
{ IFF_ECHO, "ECHO" },
#endif
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__)
{ IFF_OACTIVE, "OACTIVE" },
{ IFF_SIMPLEX, "SIMPLEX" },
{ IFF_LINK0, "LINK0" },
{ IFF_LINK1, "LINK1" },
{ IFF_LINK2, "LINK2" },
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
{ IFF_ALTPHYS, "ALTPHYS" },
#endif
#ifdef __FreeBSD__
{ IFF_CANTCONFIG, "CANTCONFIG" },
#endif
// sentinel
{},
};
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, uint32_t flags, bool firstOnly)
{
FFLocalIpResult* ip = NULL;
@@ -44,9 +86,12 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
ffStrbufInit(&ip->flags);
ip->defaultRoute = defaultRoute;
ip->mtu = -1;
ip->speed = -1;
ffLocalIpFillNIFlags(&ip->flags, flags, niFlagOptions);
}
switch (type)
@@ -96,6 +141,8 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (options->namePrefix.length && strncmp(ifa->ifa_name, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
uint32_t flags = options->showType & FF_LOCALIP_TYPE_FLAGS_BIT ? ifa->ifa_flags : 0;
if (ifa->ifa_addr->sa_family == AF_INET)
{
if (!(options->showType & FF_LOCALIP_TYPE_IPV4_BIT))
@@ -116,7 +163,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
}
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
@@ -141,9 +188,9 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute, flags, !(options->showType & FF_LOCALIP_TYPE_ALL_IPS_BIT));
}
#if defined(__FreeBSD__) || defined(__APPLE__)
#if __FreeBSD__ || __OpenBSD__ || __APPLE__
else if (ifa->ifa_addr->sa_family == AF_LINK)
{
if (!(options->showType & FF_LOCALIP_TYPE_MAC_BIT))
@@ -153,7 +200,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
uint8_t* ptr = (uint8_t*) LLADDR((struct sockaddr_dl *)ifa->ifa_addr);
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, flags, false);
}
#else
else if (ifa->ifa_addr->sa_family == AF_PACKET)
@@ -165,7 +212,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
uint8_t* ptr = ((struct sockaddr_ll *)ifa->ifa_addr)->sll_addr;
snprintf(addressBuffer, sizeof(addressBuffer), "%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, false);
addNewIp(results, ifa->ifa_name, addressBuffer, -1, isDefaultRoute, flags, false);
}
#endif
}
@@ -199,7 +246,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
ifr.ifr_data = (void*) &edata;
if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0)
iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android
#elif __FreeBSD__ || __APPLE__
#elif __FreeBSD__ || __APPLE__ || __OpenBSD__
struct ifmediareq ifmr = {};
strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0 && (IFM_TYPE(ifmr.ifm_active) & IFM_ETHER))
+22 -4
View File
@@ -6,6 +6,21 @@
#include "util/windows/unicode.h"
#include "localip.h"
static const FFLocalIpNIFlag niFlagOptions[] = {
{ IP_ADAPTER_DDNS_ENABLED, "DDNS_ENABLED" },
{ IP_ADAPTER_REGISTER_ADAPTER_SUFFIX, "REGISTER_ADAPTER_SUFFIX" },
{ IP_ADAPTER_DHCP_ENABLED, "DHCP_ENABLED" },
{ IP_ADAPTER_RECEIVE_ONLY, "RECEIVE_ONLY" },
{ IP_ADAPTER_NO_MULTICAST, "NO_MULTICAST" },
{ IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG, "IPV6_OTHER_STATEFUL_CONFIG" },
{ IP_ADAPTER_NETBIOS_OVER_TCPIP_ENABLED, "NETBIOS_OVER_TCPIP_ENABLED" },
{ IP_ADAPTER_IPV4_ENABLED, "IPV4_ENABLED" },
{ IP_ADAPTER_IPV6_ENABLED, "IPV6_ENABLED" },
{ IP_ADAPTER_IPV6_MANAGE_ADDRESS_CONFIG, "IPV6_MANAGE_ADDRESS_CONFIG" },
// sentinel
{},
};
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool newIp, bool defaultRoute)
{
FFLocalIpResult* ip = NULL;
@@ -17,6 +32,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
ffStrbufInit(&ip->ipv4);
ffStrbufInit(&ip->ipv6);
ffStrbufInit(&ip->mac);
ffStrbufInit(&ip->flags);
ip->defaultRoute = defaultRoute;
ip->speed = -1;
ip->mtu = -1;
@@ -113,13 +129,13 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
char addressBuffer[INET_ADDRSTRLEN + 4];
char addressBuffer[INET_ADDRSTRLEN + 6];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
if ((options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT) && ifa->OnLinkPrefixLength)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%u", (unsigned) ifa->OnLinkPrefixLength);
snprintf(addressBuffer + len, 6, "/%u", (unsigned) ifa->OnLinkPrefixLength);
}
addNewIp(results, name, addressBuffer, AF_INET, newIp, isDefaultRoute);
@@ -133,13 +149,13 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (!(typesToAdd & (FF_LOCALIP_TYPE_IPV6_BIT | FF_LOCALIP_TYPE_ALL_IPS_BIT))) continue;
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
char addressBuffer[INET6_ADDRSTRLEN + 4];
char addressBuffer[INET6_ADDRSTRLEN + 6];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
if ((options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT) && ifa->OnLinkPrefixLength)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%u", (unsigned) ifa->OnLinkPrefixLength);
snprintf(addressBuffer + len, 6, "/%u", (unsigned) ifa->OnLinkPrefixLength);
}
addNewIp(results, name, addressBuffer, AF_INET6, newIp, isDefaultRoute);
@@ -157,6 +173,8 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
if (options->showType & FF_LOCALIP_TYPE_MTU_BIT)
result->mtu = (int32_t) adapter->Mtu;
if (options->showType & FF_LOCALIP_TYPE_FLAGS_BIT)
ffLocalIpFillNIFlags(&result->flags, adapter->Flags, niFlagOptions);
}
}
+20
View File
@@ -0,0 +1,20 @@
#include "memory.h"
#include "common/sysctl.h"
#include <sys/vmmeter.h>
const char* ffDetectMemory(FFMemoryResult* ram)
{
size_t length = sizeof(ram->bytesTotal);
if (sysctl((int[]){ CTL_HW, HW_PHYSMEM }, 2, &ram->bytesTotal, &length, NULL, 0) < 0)
return "Failed to read hw.physmem";
struct vmtotal vmtotal;
length = sizeof(vmtotal);
if (sysctl((int[]) {CTL_VM, VM_METER}, 2, &vmtotal, &length, NULL, 0) < 0)
return "sysctl(VM_METER) failed";
ram->bytesUsed = ram->bytesTotal - vmtotal.t_free * instance.state.platform.sysinfo.pageSize;
return NULL;
}
-17
View File
@@ -1,17 +0,0 @@
#include "fastfetch.h"
typedef struct FFMonitorResult
{
FFstrbuf name;
uint32_t width; // native / maximum resolution, in pixels
uint32_t height; // native / maximum resolution, in pixels
double refreshRate;// maximum refresh rate in native resolution, in Hz
uint32_t physicalWidth; // in mm
uint32_t physicalHeight; // in mm
bool hdrCompatible;
uint16_t manufactureYear;
uint16_t manufactureWeek;
uint32_t serial;
} FFMonitorResult;
const char* ffDetectMonitor(FFlist* results);
-125
View File
@@ -1,125 +0,0 @@
#include "monitor.h"
#include "detection/displayserver/displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/edidHelper.h"
#import <AppKit/NSScreen.h>
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#ifdef MAC_OS_X_VERSION_10_15
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
#else
#include <IOKit/graphics/IOGraphicsLib.h>
#endif
static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
{
NSScreen* mainScreen = NSScreen.mainScreen;
if (display->primary)
{
#ifdef MAC_OS_X_VERSION_10_15
return mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
#else
return mainScreen.maximumExtendedDynamicRangeColorComponentValue > 1;
#endif
}
else
{
for (NSScreen* screen in NSScreen.screens)
{
if (screen == mainScreen) continue;
NSNumber* screenNumber = [screen.deviceDescription valueForKey:@"NSScreenNumber"];
if (screenNumber && screenNumber.longValue == (long) display->id)
{
#ifdef MAC_OS_X_VERSION_10_15
return screen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1;
#else
return screen.maximumExtendedDynamicRangeColorComponentValue > 1;
#endif
}
}
}
return false;
}
const char* ffDetectMonitor(FFlist* results)
{
#ifdef MAC_OS_X_VERSION_10_15
if(!CoreDisplay_DisplayCreateInfoDictionary) return "CoreDisplay_DisplayCreateInfoDictionary is not available";
#endif
const FFDisplayServerResult* displayServer = ffConnectDisplayServer();
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
{
#ifdef MAC_OS_X_VERSION_10_15
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
#else
io_service_t servicePort = CGDisplayIOServicePort((CGDirectDisplayID) display->id);
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
#endif
if(!displayInfo) continue;
bool isVirtual = false;
if (ffCfDictGetBool(displayInfo, CFSTR("kCGDisplayIsVirtualDevice"), &isVirtual) == NULL && isVirtual)
continue;
uint8_t edidData[128] = {};
uint32_t edidLength = 0;
if (ffCfDictGetData(displayInfo, CFSTR(kIODisplayEDIDKey), 0, sizeof(edidData), edidData, &edidLength) == NULL)
{
uint32_t width, height;
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width > 0 && height > 0)
{
FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results);
ffStrbufInitCopy(&monitor->name, &display->name);
monitor->width = width;
monitor->height = height;
ffEdidGetPhysicalSize(edidData, &monitor->physicalWidth, &monitor->physicalHeight);
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
detectHdrSupportWithNSScreen(display);
continue;
}
}
int width, height;
if (ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelWidth"), &width) || // Default resolution (limited by connectors, GPUs, etc.)
ffCfDictGetInt(displayInfo, CFSTR("kCGDisplayPixelHeight"), &height) ||
width <= 0 || height <= 0)
continue;
FFMonitorResult* monitor = (FFMonitorResult*) ffListAdd(results);
monitor->width = (uint32_t) width;
monitor->height = (uint32_t) height;
ffStrbufInitCopy(&monitor->name, &display->name);
CGSize size = CGDisplayScreenSize((CGDirectDisplayID) display->id);
monitor->physicalWidth = (uint32_t) (size.width + 0.5);
monitor->physicalHeight = (uint32_t) (size.height + 0.5);
monitor->hdrCompatible = CFDictionaryContainsKey(displayInfo, CFSTR("ReferencePeakHDRLuminance")) ||
detectHdrSupportWithNSScreen(display);
monitor->serial = CGDisplaySerialNumber((CGDirectDisplayID) display->id);
FF_CFTYPE_AUTO_RELEASE CFArrayRef modes = CGDisplayCopyAllDisplayModes((CGDirectDisplayID) display->id, NULL);
double maxRefreshRate = 0;
for (uint32_t j = 0; j < CFArrayGetCount(modes); ++j)
{
CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, j);
if (CGDisplayModeGetWidth(mode) == (uint32_t) width && CGDisplayModeGetHeight(mode) == (uint32_t) height)
{
double refreshRate = CGDisplayModeGetRefreshRate(mode);
if (refreshRate > maxRefreshRate) maxRefreshRate = refreshRate;
}
}
monitor->refreshRate = maxRefreshRate;
int64_t year, week;
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayYearManufacture"), &year) == NULL)
monitor->manufactureYear = (uint16_t) year;
if (ffCfDictGetInt64(displayInfo, CFSTR("DisplayWeekManufacture"), &week) == NULL)
monitor->manufactureWeek = (uint16_t) week;
}
return NULL;
}
-254
View File
@@ -1,254 +0,0 @@
#include "monitor.h"
#include "common/io/io.h"
#include "common/library.h"
#include "util/edidHelper.h"
#include "util/stringUtils.h"
#ifdef FF_HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#include <X11/Xlib.h>
typedef struct XrandrData
{
FF_LIBRARY_SYMBOL(XInternAtom)
FF_LIBRARY_SYMBOL(XGetAtomName);
FF_LIBRARY_SYMBOL(XFree);
FF_LIBRARY_SYMBOL(XRRGetMonitors)
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
FF_LIBRARY_SYMBOL(XRRGetOutputProperty)
FF_LIBRARY_SYMBOL(XRRFreeOutputInfo)
FF_LIBRARY_SYMBOL(XRRFreeMonitors)
//Init once
Display* display;
//Init per screen
XRRScreenResources* screenResources;
} XrandrData;
static const char* xrandrHandleMonitors(XrandrData* data, Screen* screen, FFlist* results)
{
int numberOfMonitors;
XRRMonitorInfo* monitorInfos = data->ffXRRGetMonitors(data->display, RootWindowOfScreen(screen), True, &numberOfMonitors);
if(monitorInfos == NULL)
return "XRRGetMonitors() failed";
for(int i = 0; i < numberOfMonitors; i++)
{
XRRMonitorInfo* monitorInfo = &monitorInfos[i];
for(int i = 0; i < monitorInfo->noutput; i++)
{
RROutput output = monitorInfo->outputs[i];
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output);
if(outputInfo == NULL)
continue;
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
ffStrbufInit(&display->name);
display->width = 0;
display->height = 0;
display->manufactureYear = 0;
display->manufactureWeek = 0;
display->serial = 0;
display->hdrCompatible = false;
display->refreshRate = 0;
bool edidOk = false;
Atom atomEdid = data->ffXInternAtom(data->display, "EDID", true);
if (atomEdid != None)
{
int actual_format = 0;
unsigned long nitems = 0, bytes_after = 0;
Atom actual_type = None;
uint8_t* edidData = NULL;
if (data->ffXRRGetOutputProperty(data->display, output, atomEdid, 0, 100, false, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &edidData) == Success)
{
if (nitems > 0 && nitems % 128 == 0)
{
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalResolution(edidData, &display->width, &display->height);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) nitems);
edidOk = true;
}
}
if (edidData)
data->ffXFree(edidData);
}
if (!edidOk)
{
ffStrbufSetS(&display->name, data->ffXGetAtomName(data->display, monitorInfo->name));
display->physicalWidth = (uint32_t) monitorInfo->mwidth;
display->physicalHeight = (uint32_t) monitorInfo->mheight;
display->width = (uint32_t) monitorInfo->width;
display->height = (uint32_t) monitorInfo->height;
}
for(int i = 0; i < data->screenResources->nmode; i++)
{
bool found = false;
for (int j = 0; j < outputInfo->nmode; ++j)
{
if (data->screenResources->modes[i].id == outputInfo->modes[j])
{
found = true;
break;
}
}
if(found)
{
XRRModeInfo* modeInfo = &data->screenResources->modes[i];
double refreshRate = (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
if (edidOk)
{
if (display->width != modeInfo->width || display->height != modeInfo->height)
continue;
}
else
{
if (display->width < modeInfo->width || display->height < modeInfo->height)
{
display->width = (uint32_t) modeInfo->width;
display->height = (uint32_t) modeInfo->height;
display->refreshRate = refreshRate;
continue;
}
else if (display->width != modeInfo->width || display->height != modeInfo->height)
continue;
}
if (display->refreshRate < refreshRate)
display->refreshRate = refreshRate;
}
}
data->ffXRRFreeOutputInfo(outputInfo);
}
}
data->ffXRRFreeMonitors(monitorInfos);
return NULL;
}
static const char* detectByXrandr(FFlist* results)
{
FF_LIBRARY_LOAD(xrandr, "dlopen libXrandr" FF_LIBRARY_EXTENSION " failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XOpenDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XCloseDisplay)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XRRGetScreenResourcesCurrent);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XRRFreeScreenResources);
XrandrData data;
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XInternAtom);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XGetAtomName);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XFree);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetMonitors);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRGetOutputProperty);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeOutputInfo);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeMonitors);
data.display = ffXOpenDisplay(NULL);
if(data.display == NULL)
return "XOpenDisplay() failed";
for(int i = 0; i < ScreenCount(data.display); i++)
{
Screen* screen = ScreenOfDisplay(data.display, i);
data.screenResources = ffXRRGetScreenResourcesCurrent(data.display, RootWindowOfScreen(screen));
xrandrHandleMonitors(&data, screen, results);
ffXRRFreeScreenResources(data.screenResources);
}
ffXCloseDisplay(data.display);
return NULL;
}
#endif // FF_HAVE_XRANDR
#ifdef __linux__
FF_MAYBE_UNUSED static const char* detectByDrm(FFlist* results)
{
const char* drmDirPath = "/sys/class/drm/";
DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return "opendir(drmDirPath) == NULL";
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
ffStrbufAppendS(&drmDir, drmDirPath);
uint32_t drmDirLength = drmDir.length;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
continue;
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
ffStrbufAppendS(&drmDir, "/status");
char status = 'd'; // disconnected
ffReadFileData(drmDir.chars, sizeof(status), &status);
if (status != 'c') // connected
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufAppendS(&drmDir, "/edid");
uint8_t edidData[512];
ssize_t edidLength = ffReadFileData(drmDir.chars, sizeof(edidData), edidData);
if(edidLength <= 0 || edidLength % 128 != 0)
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
uint32_t width, height;
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width != 0 && height != 0)
{
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
display->width = width;
display->height = height;
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
display->refreshRate = 0;
}
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
closedir(dirp);
return NULL;
}
#endif // __linux__
const char* ffDetectMonitor(FFlist* results)
{
const char* error = "Fastfetch was compiled without xrandr support";
#ifdef FF_HAVE_XRANDR
error = detectByXrandr(results);
if (!error) return NULL;
#endif
#if defined(__linux__)
error = detectByDrm(results);
#endif
return error;
}
@@ -1,6 +0,0 @@
#include "monitor.h"
const char* ffDetectMonitor(FF_MAYBE_UNUSED FFlist* results)
{
return "Not supported on this platform";
}
-116
View File
@@ -1,116 +0,0 @@
#include "monitor.h"
#include "util/edidHelper.h"
#include "util/windows/registry.h"
#include <windows.h>
const char* ffDetectMonitor(FFlist* results)
{
DISPLAYCONFIG_PATH_INFO paths[128];
uint32_t pathCount = sizeof(paths) / sizeof(paths[0]);
DISPLAYCONFIG_MODE_INFO modes[256];
uint32_t modeCount = sizeof(modes) / sizeof(modes[0]);
if (QueryDisplayConfig(
QDC_ONLY_ACTIVE_PATHS,
&pathCount,
paths,
&modeCount,
modes,
NULL) != ERROR_SUCCESS)
return "QueryDisplayConfig() failed";
if (pathCount == 0)
return "QueryDisplayConfig() returns 0 paths";
for (uint32_t i = 0; i < pathCount; ++i)
{
DISPLAYCONFIG_PATH_INFO* path = &paths[i];
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
.header = {
.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME,
.size = sizeof(targetName),
.adapterId = path->targetInfo.adapterId,
.id = path->targetInfo.id,
},
};
if (DisplayConfigGetDeviceInfo(&targetName.header) != ERROR_SUCCESS)
continue;
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum");
wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?");
while (*pDevPath && *pDevPath != L'{')
{
if (*pDevPath == L'#')
*pRegPath = L'\\';
else
*pRegPath = *pDevPath;
++pRegPath;
++pDevPath;
assert(pRegPath < regPath + sizeof(regPath) / sizeof(wchar_t) + strlen("Device Parameters"));
}
wcscpy(pRegPath, L"Device Parameters");
uint8_t edidData[1024];
DWORD edidLength = sizeof(edidData);
if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS &&
edidLength > 0 && edidLength % 128 == 0)
{
uint32_t width, height;
ffEdidGetPhysicalResolution(edidData, &width, &height);
if (width == 0 || height == 0) continue;
FFMonitorResult* display = (FFMonitorResult*) ffListAdd(results);
display->width = width;
display->height = height;
ffEdidGetSerialAndManufactureDate(edidData, &display->serial, &display->manufactureYear, &display->manufactureWeek);
ffStrbufInit(&display->name);
ffEdidGetName(edidData, &display->name);
ffEdidGetPhysicalSize(edidData, &display->physicalWidth, &display->physicalHeight);
display->refreshRate = 0;
display->hdrCompatible = false;
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
.header = {
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
.size = sizeof(advColorInfo),
.adapterId = path->targetInfo.adapterId,
.id = path->targetInfo.id,
}
};
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
display->hdrCompatible = !!advColorInfo.advancedColorSupported;
else
display->hdrCompatible = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength);
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,
}
};
if (DisplayConfigGetDeviceInfo(&preferredMode.header) == ERROR_SUCCESS)
{
if (preferredMode.width == width && preferredMode.height == height)
{
DISPLAYCONFIG_RATIONAL freq = preferredMode.targetMode.targetVideoSignalInfo.vSyncFreq;
display->refreshRate = freq.Numerator / (double) freq.Denominator;
}
}
DISPLAYCONFIG_VIDEO_SIGNAL_INFO current = modes[path->targetInfo.modeInfoIdx].targetMode.targetVideoSignalInfo;
if (current.activeSize.cx == width && current.activeSize.cy == height)
{
double refreshRate = current.vSyncFreq.Numerator / (double) current.vSyncFreq.Denominator;
if (refreshRate > display->refreshRate) display->refreshRate = refreshRate;
}
}
}
return NULL;
}
+1
View File
@@ -75,6 +75,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
+8 -3
View File
@@ -14,7 +14,6 @@ void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglG
#endif // FF_HAVE_GL
#ifdef FF_HAVE_GLX
#include <GL/glx.h>
@@ -25,7 +24,7 @@ typedef struct GLXData
FF_LIBRARY_SYMBOL(glXQueryVersion)
FF_LIBRARY_SYMBOL(XOpenDisplay)
FF_LIBRARY_SYMBOL(glXChooseVisual)
FF_LIBRARY_SYMBOL(XCreatePixmap);
FF_LIBRARY_SYMBOL(XCreatePixmap)
FF_LIBRARY_SYMBOL(glXCreateGLXPixmap)
FF_LIBRARY_SYMBOL(glXCreateContext)
FF_LIBRARY_SYMBOL(glXMakeCurrent)
@@ -120,7 +119,13 @@ static const char* detectByGlx(FFOpenGLResult* result)
{
GLXData data;
FF_LIBRARY_LOAD(glx, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD(glx, "dlopen glx failed",
#if !__OpenBSD__
"libGLX"
#else
"libGL"
#endif
FF_LIBRARY_EXTENSION, 1);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXQueryVersion);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay);
+3 -3
View File
@@ -19,11 +19,11 @@ static void parseSystemVersion(FFOSResult* os)
NSString* value;
if((value = [dict valueForKey:@"ProductName"]))
if((value = dict[@"ProductName"]))
ffStrbufInitS(&os->name, value.UTF8String);
if((value = [dict valueForKey:@"ProductUserVisibleVersion"]))
if((value = dict[@"ProductUserVisibleVersion"]))
ffStrbufInitS(&os->version, value.UTF8String);
if((value = [dict valueForKey:@"ProductBuildVersion"]))
if((value = dict[@"ProductBuildVersion"]))
ffStrbufInitS(&os->buildID, value.UTF8String);
}
+7
View File
@@ -0,0 +1,7 @@
#include "os.h"
void ffDetectOSImpl(FFOSResult* os)
{
ffStrbufSetStatic(&os->name, "OpenBSD");
ffStrbufSet(&os->version, &instance.state.platform.sysinfo.release);
}
+1
View File
@@ -35,6 +35,7 @@ typedef struct FFPackagesResult
uint32_t sorcery;
uint32_t winget;
uint32_t xbps;
uint32_t pacstall;
uint32_t all; //Make sure this goes last
+1 -1
View File
@@ -18,7 +18,7 @@ static uint32_t getSQLite3Int(const char* dbPath, const char* query, const char*
return num_elements;
}
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT))
{
+75 -2
View File
@@ -467,6 +467,78 @@ static uint32_t getGuixPackages(FFstrbuf* baseDir, const char* dirname)
return num_elements;
}
static inline uint32_t getFlatpakRuntimePackagesArch(FFstrbuf* baseDir)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
if (dirp == NULL)
return 0;
uint32_t num_elements = 0;
struct dirent *entry;
while ((entry = readdir(dirp)) != NULL)
{
if(entry->d_type == DT_DIR && entry->d_name[0] != '.')
{
num_elements += getNumElements(baseDir, entry->d_name, DT_DIR);
}
}
return num_elements;
}
static inline uint32_t getFlatpakRuntimePackages(FFstrbuf* baseDir)
{
ffStrbufAppendS(baseDir, "runtime/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
if (dirp == NULL)
return 0;
uint32_t runtimeDirLength = baseDir->length;
uint32_t num_elements = 0;
struct dirent *entry;
while ((entry = readdir(dirp)) != NULL)
{
if(entry->d_type == DT_DIR && entry->d_name[0] != '.')
{
// `flatpak list` ignores `.Locale` and `.Debug` packages, and maybe others
const char* dot = strrchr(entry->d_name, '.');
if (__builtin_expect(!dot, false)) continue;
dot++;
if (ffStrEquals(dot, "Locale") || ffStrEquals(dot, "Debug"))
continue;
ffStrbufAppendS(baseDir, entry->d_name);
ffStrbufAppendC(baseDir, '/');
num_elements += getFlatpakRuntimePackagesArch(baseDir);
ffStrbufSubstrBefore(baseDir, runtimeDirLength);
}
}
return num_elements;
}
static uint32_t getFlatpakPackages(FFstrbuf* baseDir, const char* dirname)
{
uint32_t num_elements = 0;
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, dirname);
ffStrbufAppendS(baseDir, "/flatpak/");
uint32_t flatpakDirLength = baseDir->length;
ffStrbufAppendS(baseDir, "app");
num_elements += getNumElementsImpl(baseDir->chars, DT_DIR);
ffStrbufSubstrBefore(baseDir, flatpakDirLength);
num_elements += getFlatpakRuntimePackages(baseDir);
ffStrbufSubstrBefore(baseDir, baseDirLength);
return num_elements;
}
static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q", "apk");
@@ -474,7 +546,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n", "lpkg");
if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getFlatpakPackages(baseDir, "/var/lib");
if (!(options->disabled & FF_PACKAGES_FLAG_NIX_BIT))
{
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
@@ -500,6 +572,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
}
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_PACSTALL_BIT)) packageCounts->pacstall += getNumElements(baseDir, "/var/lib/pacstall/metadata", DT_REG);
}
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
@@ -603,5 +676,5 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
}
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT))
result->flatpakUser = getNumElements(&baseDir, "/.local/share/flatpak/app", DT_DIR);
result->flatpakUser = getFlatpakPackages(&baseDir, "/.local/share");
}
+31
View File
@@ -0,0 +1,31 @@
#include "packages.h"
#include "common/io/io.h"
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
if(dirp == NULL)
return 0;
uint32_t num_elements = 0;
struct dirent *entry;
while((entry = readdir(dirp)) != NULL) {
if(entry->d_type == type)
++num_elements;
}
if(type == DT_DIR && num_elements >= 2)
num_elements -= 2; // accounting for . and ..
return num_elements;
}
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT))
{
result->pkg = getNumElementsImpl(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg", DT_DIR);
}
}
+26 -14
View File
@@ -1,12 +1,34 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "detection/temps/temps_linux.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
static double detectNvmeTemp(const char* devName)
{
char pathSysBlock[PATH_MAX];
int index = snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/hwmon$/temp1_input", devName);
if (index <= 0) return FF_PHYSICALDISK_TEMP_UNSET;
index -= (int) sizeof("/temp1_input");
for (char c = '0'; c <= '9'; c++) // hopefully there's only one digit
{
pathSysBlock[index] = c;
char buffer[64];
ssize_t size = ffReadFileData(pathSysBlock, sizeof(buffer), buffer);
if (size > 0)
{
buffer[size] = '\0';
double temp = strtod(buffer, NULL);
return temp > 0 ? temp / 1000 : FF_PHYSICALDISK_TEMP_UNSET;
}
}
return FF_PHYSICALDISK_TEMP_UNSET;
}
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
@@ -157,20 +179,10 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
}
}
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
if (options->temp)
{
const FFlist* tempsResult = ffDetectTemps();
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
{
if (ffStrStartsWith(devName, value->deviceName.chars)) // nvme0 - nvme0n1
{
device->temperature = value->value;
break;
}
}
}
device->temperature = detectNvmeTemp(devName);
else
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
}
return NULL;
+14
View File
@@ -0,0 +1,14 @@
#include "processes.h"
#include <sys/param.h>
#include <sys/sysctl.h>
#include <kvm.h>
const char* ffDetectProcesses(uint32_t* result)
{
kvm_t* kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
const void* ret = kvm_getprocs(kd, KERN_PROC_ALL, 0, 1, result);
kvm_close(kd);
if (!ret) return "kvm_getprocs() failed";
return NULL;
}
+30
View File
@@ -0,0 +1,30 @@
#include "swap.h"
#include "util/mallocHelper.h"
#include <sys/types.h>
#include <sys/swap.h>
#include <sys/param.h>
#include <unistd.h>
const char* ffDetectSwap(FFSwapResult* swap)
{
int nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap < 0) return "swapctl(SWAP_NSWAP) failed";
if (nswap == 0) NULL;
struct swapent* swdev = malloc((uint32_t) nswap * sizeof(*swdev));
if (swapctl(SWAP_STATS, swdev, nswap) < 0)
return "swapctl(SWAP_STATS) failed";
for (int i = 0; i < nswap; i++)
{
if (swdev[i].se_flags & SWF_ENABLE)
{
swap->bytesUsed += (uint64_t) swdev[i].se_inuse * DEV_BSIZE;
swap->bytesTotal += (uint64_t) swdev[i].se_nblks * DEV_BSIZE;
}
}
return NULL;
}
-24
View File
@@ -1,24 +0,0 @@
#include "temps_bsd.h"
#include "common/sysctl.h"
const char* ffDetectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
const char* ffDetectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
-4
View File
@@ -1,4 +0,0 @@
#pragma once
const char* ffDetectCpuTemp(double* current);
const char* ffDetectThermalTemp(double* current);
-101
View File
@@ -1,101 +0,0 @@
#include "fastfetch.h"
#include "common/io/io.h"
#include "common/thread.h"
#include "temps_linux.h"
#include <string.h>
#include <dirent.h>
static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
{
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
uint32_t dirLength = dir->length;
FF_STRBUF_AUTO_DESTROY valueBuffer = ffStrbufCreate();
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, &valueBuffer))
return false;
ffStrbufSubstrBefore(dir, dirLength);
value->value = ffStrbufToDouble(&valueBuffer) / 1000; // valueBuffer is millidegree Celsius
if(value->value != value->value)
return false;
ffStrbufAppendS(dir, "name");
ffReadFileBuffer(dir->chars, &value->name);
ffStrbufTrimRightSpace(&value->name);
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/class");
if(!ffReadFileBuffer(dir->chars, &valueBuffer))
{
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/device/class");
ffReadFileBuffer(dir->chars, &valueBuffer);
}
ffStrbufTrimRightSpace(&valueBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if(valueBuffer.length)
value->deviceClass = (uint32_t) strtoul(valueBuffer.chars, NULL, 16);
ffStrbufClear(&valueBuffer);
ffStrbufEnsureFree(&valueBuffer, 64);
ffStrbufAppendS(dir, "device");
ssize_t linkLen = readlink(dir->chars, valueBuffer.chars, valueBuffer.allocated - 1);
if (linkLen > 0)
{
valueBuffer.length = (uint32_t) linkLen;
valueBuffer.chars[linkLen] = 0;
ffStrbufSubstrAfterLastC(&valueBuffer, '/');
ffStrbufInitMove(&value->deviceName, &valueBuffer);
}
else
ffStrbufInit(&value->deviceName);
return value->name.length > 0 || value->deviceClass > 0;
}
const FFlist* ffDetectTemps(void)
{
static FFlist result;
if(result.elementSize > 0)
return &result;
ffListInitA(&result, sizeof(FFTempValue), 16);
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return &result;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&baseDir, entry->d_name);
ffStrbufAppendC(&baseDir, '/');
FFTempValue* temp = ffListAdd(&result);
ffStrbufInit(&temp->name);
temp->deviceClass = 0;
if(!parseHwmonDir(&baseDir, temp))
{
ffStrbufDestroy(&temp->name);
--result.length;
}
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return &result;
}
-13
View File
@@ -1,13 +0,0 @@
#pragma once
#include "fastfetch.h"
typedef struct FFTempValue
{
FFstrbuf name;
FFstrbuf deviceName;
uint32_t deviceClass;
double value;
} FFTempValue;
const FFlist* /* List of FFTempValue */ ffDetectTemps();

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