mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:06:11 +02:00
Compare commits
230 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4059bca941 | |||
| bb94ac7832 | |||
| d5d935a658 | |||
| 44ccc69834 | |||
| 6bcfc3a61e | |||
| 2d356aa644 | |||
| 9ea887e841 | |||
| 5f3ce50022 | |||
| acfab74d4b | |||
| 24c3f0d6b9 | |||
| c2ec1e9606 | |||
| 951a15b61b | |||
| f30501f365 | |||
| bde6c3b829 | |||
| 7fac54e7b8 | |||
| d4c8a4c9fd | |||
| b34283eaf0 | |||
| 67964363e8 | |||
| 41a1b3a9d5 | |||
| 320283a538 | |||
| 40ab735e6b | |||
| 716bfe7cc1 | |||
| 84fc5b4503 | |||
| 729085e054 | |||
| a32d9d788c | |||
| d06f9a1509 | |||
| c2b60a2ebf | |||
| 937b2e41ed | |||
| aa734e2220 | |||
| a4fe933625 | |||
| 53a373c9cf | |||
| 46c8bc1f99 | |||
| 8a11aa0f8f | |||
| 89d3924659 | |||
| b49c509a6c | |||
| 99626149f6 | |||
| 3381262930 | |||
| 6dd6266a2a | |||
| 18be6c8fd1 | |||
| 5bdae7afc3 | |||
| 316849e5df | |||
| d5c395fb85 | |||
| 46eb0e4b1c | |||
| fb0a18dc82 | |||
| ca442b3da4 | |||
| a32361fdc5 | |||
| d77f0fe3d9 | |||
| 1df129083b | |||
| 2cd6cb3ca1 | |||
| eeb2d1c746 | |||
| d97999ddc9 | |||
| 70e8398f05 | |||
| 0b32abd5a7 | |||
| 73e61c2b89 | |||
| 1901b9308f | |||
| a7c7493733 | |||
| 73f98f9509 | |||
| 3d82d55e5d | |||
| 6485d34700 | |||
| 17c9179b7d | |||
| 88097463af | |||
| 5381395c54 | |||
| 51796de69a | |||
| 140b9834cc | |||
| a424839d2f | |||
| acd5d4a258 | |||
| f8fa3f8ea6 | |||
| 38f07ade44 | |||
| 7ae7ff8cef | |||
| 842ba9fd4e | |||
| 5058a93428 | |||
| d6eff93c12 | |||
| 03565384e6 | |||
| a3a4f0a64a | |||
| af067c7c3f | |||
| 8bbc985d98 | |||
| 254876b9e6 | |||
| 78fc5a2b5d | |||
| 745c041b44 | |||
| 4283d96c53 | |||
| e07fcc4d49 | |||
| d095f39418 | |||
| af63e6e98b | |||
| fc05d728f3 | |||
| e3cb52583d | |||
| 01735d6fde | |||
| b37b495aee | |||
| 28c9b67414 | |||
| 4d7d367e72 | |||
| 8295f66320 | |||
| 87f2e69162 | |||
| f496e6d965 | |||
| 96d885e93a | |||
| ae6817e106 | |||
| 582b0fa087 | |||
| 0414128a55 | |||
| 5dbd6b9ab8 | |||
| 0c90941a32 | |||
| 29ae56e76a | |||
| 81b0ddb2da | |||
| 4ea5d6f4fe | |||
| 9b4053e9dc | |||
| b4325ff205 | |||
| 87d32466f6 | |||
| 3b9d20ddf2 | |||
| 32b6af2686 | |||
| a3c0617f22 | |||
| 30ffa4bdd2 | |||
| 86a96da9ab | |||
| b3b6e5fec1 | |||
| e0296b75f6 | |||
| bd2b002d14 | |||
| c936d170b2 | |||
| a77d972834 | |||
| 10868ed951 | |||
| fc947468a9 | |||
| 005d660d77 | |||
| 866c7303e6 | |||
| 85a31c7c69 | |||
| 1dba6d155b | |||
| db669c00a1 | |||
| 006c00ab2c | |||
| 0bcbae90e9 | |||
| 503a8d51ab | |||
| 9332f42889 | |||
| 9d0797c308 | |||
| f80423607d | |||
| c49c857db2 | |||
| 174359dc3e | |||
| 43d6f81b01 | |||
| 0025c78cce | |||
| 5a9a2ca0fd | |||
| 6c8b4b25d2 | |||
| 6acc33cd16 | |||
| 756865855b | |||
| c64720c6da | |||
| 0eecdd16ea | |||
| acdd1fc69c | |||
| 1b9345267f | |||
| c24328e26e | |||
| c58f4c24c4 | |||
| 3381062ab9 | |||
| 553b0fe8cc | |||
| 74fcd8b1c3 | |||
| a1f0570a96 | |||
| cd11a9dff4 | |||
| ed2dd8f2ec | |||
| 9faa38296a | |||
| 3d1a6b67c5 | |||
| b1eceb6be2 | |||
| af450ae788 | |||
| 03c901b260 | |||
| 7bbaca2fab | |||
| ce90689ba3 | |||
| 0c4edf7d0e | |||
| 119de2e91a | |||
| e9bb761a2d | |||
| fd432e3635 | |||
| 174dde131c | |||
| 99668771c7 | |||
| dc541ac781 | |||
| 68ab41f748 | |||
| e8f711830e | |||
| a052033dc6 | |||
| fed2c87f67 | |||
| b7fcd7fc0c | |||
| b2810bc030 | |||
| 8f1f1607da | |||
| 611d5f949b | |||
| 536e2fb42d | |||
| 1e4601485a | |||
| f8c58a9178 | |||
| d8fb8d439e | |||
| de59ffb31f | |||
| c24d378cf1 | |||
| de8efb39c8 | |||
| 13452da076 | |||
| 7db8d7c3ce | |||
| f4424b4204 | |||
| 8371920c6b | |||
| c9d539090d | |||
| d43c6ffe27 | |||
| cf7c5d3cfa | |||
| 3f67fac4fa | |||
| 879d5594da | |||
| 32bf85742c | |||
| 37cc2c9c1b | |||
| c39df1ae7b | |||
| 4622604ee1 | |||
| 617661b546 | |||
| 9aae274cc7 | |||
| 90b2bf0ad6 | |||
| aec27c3e50 | |||
| d79bf0a460 | |||
| 352ed51504 | |||
| d824045973 | |||
| bbe4988054 | |||
| 636126c57d | |||
| 2e475d590f | |||
| 0cf45c1dcd | |||
| 435516373d | |||
| 64735245e7 | |||
| 85d89395a9 | |||
| 093940e504 | |||
| e427a5112b | |||
| 1ab86a8ab9 | |||
| 99e0dc9aaa | |||
| 73e9db5b6e | |||
| adc03bd792 | |||
| 10fdc8e4a7 | |||
| d75803794e | |||
| d25ac86283 | |||
| de8bbc9a5c | |||
| 66977de5c7 | |||
| f828d3a9b9 | |||
| f0bc08e006 | |||
| e0f8e39a47 | |||
| 8b9f787095 | |||
| d946cf27fe | |||
| 5842ad1d56 | |||
| 201047251d | |||
| 5c8e771939 | |||
| b22e28b548 | |||
| 8c51836a47 | |||
| df729938c5 | |||
| 67d0dfcef0 | |||
| 03c95e5cad | |||
| c0a07002f2 | |||
| 5a9c3154fa | |||
| e35aed761b |
+1
-1
@@ -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 +0,0 @@
|
||||
github: [CarterLi, LinusDierheimer]
|
||||
+49
-12
@@ -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}
|
||||
|
||||
@@ -388,8 +388,8 @@ jobs:
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
@@ -422,12 +422,12 @@ 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
|
||||
time ./fastfetch --format json
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
@@ -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
|
||||
@@ -456,7 +492,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt mingw-w64-clang-x86_64-imagemagick
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -586,6 +622,7 @@ jobs:
|
||||
- musl-aarch64
|
||||
- macos-universal
|
||||
- freebsd-amd64
|
||||
- openbsd-amd64
|
||||
- sunos-amd64
|
||||
- windows-amd64
|
||||
- windows-i686
|
||||
|
||||
+156
@@ -1,3 +1,159 @@
|
||||
# 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:
|
||||
* Moore Threads GPU add support to query number of cores (#1259, GPU)
|
||||
* Cache detection result based on last modification time (Packages)
|
||||
* Add cmake options to disable certain package managers at compile time
|
||||
* Package managers are encouraged to disable some package managers by passing `-DPACKAGES_DISABLE_` when running `cmake`. For example, when building for Arch Linux, `-DPACKAGES_DISABLE_APK=ON -DPACKAGES_DISABLE_DPKG=ON -DPACKAGES_DISABLE_RPM=ON ...` should be specified.
|
||||
* See all available options by [running `cmake -L | grep PACKAGES_DISABLE_`](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L91)
|
||||
* This option does NOT remove the detection code. It just disables the detection at runtime. One can still use `--packages-disabled ""` to enable all package managers.
|
||||
* Add new option `--show-localip-{speed,mtu}` (LocalIP)
|
||||
* Add new module `Btrfs`, which prints all mounted Btrfs volumes, like `Zpool` module (#1262, Linux)
|
||||
* Improve Wifi module support for macOS Sequoia (Wifi, macOS)
|
||||
* Currently it uses `system_profiler` which costs about 2 seconds on my MBP. I suggest disabling it for now until a better solution is found.
|
||||
|
||||
Bugfixes:
|
||||
* Fix invalid CPU temperature detection on FreeBSD (#1260, CPU, FreeBSD)
|
||||
* Remove `showPeCoreCount` support on FreeBSD (#1260, CPU, FreeBSD)
|
||||
* Don't use Wifi speed as Ethernet speed (LocalIP, FreeBSD)
|
||||
* Fix compiling with old linux headers (Camera, Linux)
|
||||
* Fix detecting public ipv6 address (PublicIP, Windows)
|
||||
|
||||
Logo:
|
||||
* Fix parrot logo detection
|
||||
* Rename TorizonCore to Torizon OS
|
||||
|
||||
# 2.24.0
|
||||
|
||||
Changes:
|
||||
* Support of `--lib-XXX` is removed
|
||||
* If fastfetch fails to load some `.so` `.dylib` libraries, `LD_LIBRARY_PATH` should be used.
|
||||
|
||||
Features:
|
||||
* Support sixel image protocol on Windows (Logo, Windows)
|
||||
* Requires imagemagick7 to be installed. MSYS2 is recommended.
|
||||
* Improve terminal query on Windows (Windows)
|
||||
* TerminalSize, TerminalTheme
|
||||
* Detect more ARM microarchitectures and SOC names (CPU, Linux)
|
||||
* Detect the number of online cores (CPU, FreeBSD)
|
||||
* Support board name detection for Asahi Linux (Board, Linux)
|
||||
* Add new option `--command-param` to customize the parameters when running shell
|
||||
* Support syntax of sub string in `--<module>-format`: `{variable~startIndex,endIndex}`
|
||||
* See `fastfetch -h format` for detail
|
||||
|
||||
Bugfixes:
|
||||
* Fix tests building when system yyjson is used (#1244)
|
||||
* Fix dinit detection; support dinit version detection (#1245, InitSystem, Linux)
|
||||
* Fix signal quality, refresh rate and maybe others in custom format (#1241)
|
||||
* Fix boot time calculation (#1249, Uptime, Linux)
|
||||
* Fix custom format for boolean values
|
||||
* `{?false-value}This should not print{?}{?true-value}This should print{?}` will print `This should print`
|
||||
* Fix possible hanging when running fastfetch in screen 5.0 (TerminalTheme, macOS)
|
||||
|
||||
Logos:
|
||||
* Add Lliurex
|
||||
|
||||
# 2.23.0
|
||||
|
||||
Features:
|
||||
* Support unity version detection (DE, Linux)
|
||||
* Print model name in Battery keys if available (Battery)
|
||||
* Add module `Zpool`
|
||||
* Improve performance (Shell / Terminal, Linux)
|
||||
* Support syntax of padded strings in `--<module>-format`. `{variable<padlength}` and `{variable>padlength}` are supported.
|
||||
* If pad length is greater than the length of the variable, the variable will be padded with spaces.
|
||||
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1<20})'` prints `Command: output(12345 )`
|
||||
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1>20})'` prints `Command: output( 12345)`
|
||||
* If pad length is less than the length of the variable, the variable will be truncated.
|
||||
|
||||
Bugfixes:
|
||||
* Fix broken `--list-presets`
|
||||
* Update zsh completion script
|
||||
* Don't print `*` if `defaultRouteOnly` is set (NetIO)
|
||||
* Fix Camera module incorrectly disabled on FreeBSD (Camera, FreeBSD)
|
||||
* Fix hanging on screen 5.0 (Terminal)
|
||||
* Improve image logo support on Windows (Logo, Windows)
|
||||
|
||||
Logos:
|
||||
* Update AmogOS
|
||||
* Add Magix
|
||||
* Make ubuntu logo colorable
|
||||
* Add Steam Deck Logo
|
||||
* add Huawei Cloud EulerOS
|
||||
|
||||
# 2.22.0
|
||||
|
||||
Features:
|
||||
|
||||
+247
-56
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.22.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,33 +46,35 @@ 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 FreeBSD OR ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
@@ -79,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")
|
||||
@@ -87,6 +92,15 @@ 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 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)
|
||||
else()
|
||||
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" OFF)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (LINUX)
|
||||
set(CUSTOM_PCI_IDS_PATH "" CACHE STRING "Custom path to file pci.ids, defaults to `/usr/share/hwdata/pci.ids`")
|
||||
set(CUSTOM_AMDGPU_IDS_PATH "" CACHE STRING "Custom path to file amdgpu.ids, defaults to `/usr/share/libdrm/amdgpu.ids`")
|
||||
@@ -244,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)
|
||||
@@ -332,6 +356,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/bootmgr/bootmgr.c
|
||||
src/modules/brightness/brightness.c
|
||||
src/modules/break/break.c
|
||||
src/modules/btrfs/btrfs.c
|
||||
src/modules/camera/camera.c
|
||||
src/modules/chassis/chassis.c
|
||||
src/modules/colors/colors.c
|
||||
@@ -383,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
|
||||
@@ -392,15 +418,16 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/wifi/wifi.c
|
||||
src/modules/wm/wm.c
|
||||
src/modules/wmtheme/wmtheme.c
|
||||
src/modules/zpool/zpool.c
|
||||
src/options/display.c
|
||||
src/options/modules.c
|
||||
src/options/logo.c
|
||||
src/options/general.c
|
||||
src/options/library.c
|
||||
src/util/edidHelper.c
|
||||
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
|
||||
@@ -418,6 +445,7 @@ if(LINUX)
|
||||
src/detection/board/board_linux.c
|
||||
src/detection/bootmgr/bootmgr_linux.c
|
||||
src/detection/brightness/brightness_linux.c
|
||||
src/detection/btrfs/btrfs_linux.c
|
||||
src/detection/chassis/chassis_linux.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cpucache/cpucache_linux.c
|
||||
@@ -458,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
|
||||
@@ -468,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
|
||||
@@ -481,6 +508,7 @@ if(LINUX)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
@@ -497,6 +525,7 @@ elseif(ANDROID)
|
||||
src/detection/board/board_android.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_linux.c
|
||||
src/detection/cpucache/cpucache_linux.c
|
||||
@@ -521,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
|
||||
@@ -530,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
|
||||
@@ -543,6 +571,7 @@ elseif(ANDROID)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/camera/camera_android.c
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
@@ -561,6 +590,7 @@ elseif(FreeBSD)
|
||||
src/detection/board/board_bsd.c
|
||||
src/detection/bootmgr/bootmgr_bsd.c
|
||||
src/detection/brightness/brightness_bsd.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_bsd.c
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
@@ -599,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
|
||||
@@ -609,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
|
||||
@@ -622,6 +651,86 @@ elseif(FreeBSD)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(OpenBSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/dbus.c
|
||||
src/common/io/io_unix.c
|
||||
src/common/netif/netif_bsd.c
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_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
|
||||
)
|
||||
@@ -639,6 +748,7 @@ elseif(APPLE)
|
||||
src/detection/board/board_apple.c
|
||||
src/detection/bootmgr/bootmgr_apple.c
|
||||
src/detection/brightness/brightness_apple.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/cpucache/cpucache_apple.c
|
||||
@@ -664,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
|
||||
@@ -673,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
|
||||
@@ -686,8 +795,10 @@ elseif(APPLE)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/camera/camera_apple.m
|
||||
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
|
||||
)
|
||||
@@ -704,8 +815,10 @@ elseif(WIN32)
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/bootmgr/bootmgr_windows.c
|
||||
src/detection/brightness/brightness_windows.cpp
|
||||
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
|
||||
@@ -728,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
|
||||
@@ -740,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
|
||||
@@ -750,6 +862,7 @@ elseif(WIN32)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/detection/camera/camera_windows.cpp
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/com.cpp
|
||||
src/util/windows/registry.c
|
||||
@@ -770,6 +883,7 @@ elseif(SunOS)
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/btrfs/btrfs_nosupport.c
|
||||
src/detection/chassis/chassis_windows.c
|
||||
src/detection/cpu/cpu_sunos.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
@@ -810,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
|
||||
@@ -824,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
|
||||
@@ -832,6 +946,7 @@ elseif(SunOS)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_nosupport.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
@@ -878,8 +993,8 @@ add_library(libfastfetch OBJECT
|
||||
)
|
||||
|
||||
if(yyjson_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(libfastfetch PRIVATE yyjson::yyjson)
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(libfastfetch PUBLIC yyjson::yyjson)
|
||||
# `target_link_libraries(yyjson::yyjson)` sets rpath implicitly
|
||||
else()
|
||||
# Used for dlopen finding dylibs installed by homebrew
|
||||
@@ -911,21 +1026,24 @@ 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)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_STATX)
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_STATX)
|
||||
endif()
|
||||
|
||||
if(HAVE_WCWIDTH)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WCWIDTH)
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH)
|
||||
endif()
|
||||
|
||||
if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "")
|
||||
@@ -1015,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"
|
||||
@@ -1059,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"
|
||||
@@ -1091,18 +1220,48 @@ ff_lib_enable(DIRECTX_HEADERS
|
||||
"DirectX-Headers"
|
||||
"DirectX-Headers"
|
||||
)
|
||||
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
|
||||
if(ENABLE_LIBZFS)
|
||||
if(BINARY_LINK_TYPE STREQUAL "dlopen")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
|
||||
check_function_exists("libzfs_init" LIBZFS_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
|
||||
if(NOT LIBZFS_FOUND)
|
||||
message(STATUS "Library: missing: LIBZFS")
|
||||
else()
|
||||
message(STATUS "Library: found LIBZFS")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
|
||||
target_link_libraries(libfastfetch PRIVATE zfs)
|
||||
endif()
|
||||
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"
|
||||
@@ -1126,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"
|
||||
@@ -1147,12 +1305,19 @@ elseif(FreeBSD)
|
||||
PRIVATE "usbhid"
|
||||
PRIVATE "geom"
|
||||
)
|
||||
elseif(OpenBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "kvm"
|
||||
)
|
||||
elseif(SunOS)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "socket"
|
||||
PRIVATE "kstat"
|
||||
PRIVATE "proc"
|
||||
PRIVATE "zfs"
|
||||
PRIVATE "nvpair"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
@@ -1196,11 +1361,16 @@ if(WIN32)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
if(LINUX)
|
||||
if(FreeBSD)
|
||||
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
|
||||
endif()
|
||||
if(LINUX OR FreeBSD)
|
||||
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
|
||||
if(HAVE_LINUX_VIDEODEV2)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
|
||||
endif()
|
||||
endif()
|
||||
if(LINUX)
|
||||
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
|
||||
if(HAVE_LINUX_WIRELESS)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
|
||||
@@ -1215,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)
|
||||
@@ -1231,6 +1405,22 @@ if(NOT WIN32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(PACKAGES_DISABLE_LIST "")
|
||||
foreach(package_manager ${PACKAGE_MANAGERS})
|
||||
if(PACKAGES_DISABLE_${package_manager})
|
||||
list(APPEND PACKAGES_DISABLE_LIST "${package_manager}")
|
||||
endif()
|
||||
endforeach()
|
||||
if("${PACKAGES_DISABLE_LIST}" STREQUAL "")
|
||||
set(PACKAGES_DISABLE_LIST "FF_PACKAGES_FLAG_NONE")
|
||||
else()
|
||||
message(STATUS "Disabled package managers: ${PACKAGES_DISABLE_LIST}")
|
||||
list(TRANSFORM PACKAGES_DISABLE_LIST PREPEND "FF_PACKAGES_FLAG_")
|
||||
list(TRANSFORM PACKAGES_DISABLE_LIST APPEND "_BIT")
|
||||
list(JOIN PACKAGES_DISABLE_LIST " | " PACKAGES_DISABLE_LIST)
|
||||
endif()
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_PACKAGES_DISABLE_LIST=${PACKAGES_DISABLE_LIST})
|
||||
|
||||
######################
|
||||
# Executable targets #
|
||||
######################
|
||||
@@ -1261,13 +1451,6 @@ set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||
set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(yyjson_FOUND)
|
||||
target_compile_definitions(fastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(fastfetch PRIVATE yyjson::yyjson)
|
||||
target_compile_definitions(flashfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(flashfetch PRIVATE yyjson::yyjson)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_sources(fastfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
@@ -1308,9 +1491,17 @@ if (BUILD_TESTS)
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
add_executable(fastfetch-test-format
|
||||
tests/format.c
|
||||
)
|
||||
target_link_libraries(fastfetch-test-format
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
|
||||
add_test(NAME test-list COMMAND fastfetch-test-list)
|
||||
add_test(NAME test-format COMMAND fastfetch-test-format)
|
||||
endif()
|
||||
|
||||
##################
|
||||
|
||||
@@ -27,7 +27,7 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
||||
|
||||
### Linux
|
||||
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
Some distros package an outdated fastfetch version. Older versions receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
||||
@@ -81,7 +81,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
## Usage
|
||||
|
||||
* Run it with default configuration: `fastfetch`
|
||||
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what you interest: `fastfetch -c all.jsonc`
|
||||
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what interests you: `fastfetch -c all.jsonc`
|
||||
* Find all data that fastfetch detects: `fastfetch -s <module> --format json`
|
||||
* Display help messages: `fastfetch --help`
|
||||
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --gen-config`
|
||||
@@ -90,7 +90,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. Those files can serve as examples of the configuration syntax.
|
||||
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
|
||||
## Packaging
|
||||
@@ -112,7 +112,7 @@ Logos can be heavily customized too; see the [logo documentation](https://github
|
||||
2. Fastfetch is faster. As the name suggests.
|
||||
3. Fastfetch has a greater number of features, though by default fastfetch only has a few modules enabled; use `fastfetch -c all` to find what you want.
|
||||
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>.
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555 MiB` in the Memory module and `23 G` in the Disk module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
|
||||
|
||||
### Q: Fastfetch shows my local IP address. It leaks my privacy!
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
### 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!
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
+39
-23
@@ -1,11 +1,17 @@
|
||||
#compdef fastfetch
|
||||
|
||||
function _fastfetch() {
|
||||
|
||||
whence python3 &> /dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
local state
|
||||
|
||||
local -a opts
|
||||
opts=(${(f)"$(
|
||||
python <<EOF
|
||||
local -a opts=("${(f)$(
|
||||
python3 <<EOF
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -18,15 +24,21 @@ def main():
|
||||
|
||||
for key in data:
|
||||
for flag in data[key]:
|
||||
if flag["long"] == "logo-color-[1-9]":
|
||||
for i in range(1, 10):
|
||||
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
|
||||
print_command(command_prefix, flag)
|
||||
continue
|
||||
|
||||
if flag.get("pseudo", False):
|
||||
continue
|
||||
|
||||
if "short" in flag:
|
||||
command_prefix = f"""-{flag["short"]}[{flag["desc"]}]"""
|
||||
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
if "long" in flag:
|
||||
command_prefix = f"""--{flag["long"]}[{flag["desc"]}]"""
|
||||
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
|
||||
@@ -34,22 +46,22 @@ def print_command(command_prefix: str, flag: dict):
|
||||
if "arg" in flag:
|
||||
type: str = flag["arg"]["type"]
|
||||
if type == "bool":
|
||||
print(f"{command_prefix}:bool:(true false)")
|
||||
print(f"{command_prefix}::bool:(true false)")
|
||||
elif type == "color":
|
||||
print(f"{command_prefix}:color:(black red green yellow blue magenta cyan white default)")
|
||||
print(f"{command_prefix}:color:->colors")
|
||||
elif type == "command":
|
||||
print(f"{command_prefix}:module:->modules")
|
||||
print(f"{command_prefix}::module:->modules")
|
||||
elif type == "config":
|
||||
print(f"{command_prefix}:presets:->presets")
|
||||
print(f"{command_prefix}:preset:->presets")
|
||||
elif type == "enum":
|
||||
temp: str = " ".join(flag["arg"]["enum"])
|
||||
print(f'{command_prefix}:type:( {temp} )')
|
||||
print(f'{command_prefix}:type:({temp})')
|
||||
elif type == "logo":
|
||||
print(f"{command_prefix}:logo:->logo")
|
||||
print(f"{command_prefix}:logo:->logos")
|
||||
elif type == "structure":
|
||||
print(f"{command_prefix}:structure:->structure")
|
||||
print(f"{command_prefix}:structure:->structures")
|
||||
elif type == "path":
|
||||
print(f"{command_prefix}:path:_files -/")
|
||||
print(f"{command_prefix}::path:_files")
|
||||
else:
|
||||
print(f"{command_prefix}:")
|
||||
else:
|
||||
@@ -62,30 +74,34 @@ if __name__ == "__main__":
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
EOF
|
||||
)"})
|
||||
)}")
|
||||
|
||||
_arguments -C "$opts[@]"
|
||||
_arguments "$opts[@]"
|
||||
|
||||
case $state in
|
||||
colors)
|
||||
local -a colors=(black red green yellow blue magenta cyan white default)
|
||||
_describe 'color' colors
|
||||
;;
|
||||
modules)
|
||||
local -a modules=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
|
||||
modules=( ${(L)^modules%%:*}-format format color )
|
||||
local -a modules=("${(f)$(fastfetch --list-modules autocompletion)}")
|
||||
modules=(${(L)^modules[@]%%:*}-format format color)
|
||||
_describe 'module' modules
|
||||
;;
|
||||
presets)
|
||||
local -a presets=(
|
||||
${$(fastfetch --list-presets autocompletion):#.*}
|
||||
"${(f)$(fastfetch --list-presets autocompletion)}"
|
||||
"none:Disable loading config file"
|
||||
)
|
||||
_describe 'preset' presets
|
||||
_describe 'preset' presets || _files
|
||||
;;
|
||||
structure)
|
||||
local -a structures=( ${(f)"$(fastfetch --list-modules autocompletion)"} )
|
||||
structures)
|
||||
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
|
||||
_describe 'structure' structures
|
||||
;;
|
||||
logo)
|
||||
logos)
|
||||
local -a logos=(
|
||||
$(fastfetch --list-logos autocompletion)
|
||||
"${(f)$(fastfetch --list-logos autocompletion)}"
|
||||
"none:Don't print logo"
|
||||
"small:Print small ascii logo if available"
|
||||
)
|
||||
|
||||
Vendored
+42
@@ -1,3 +1,45 @@
|
||||
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
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 11 Sep 2024 13:50:02 +0800
|
||||
|
||||
fastfetch (2.23.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.23.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Tue, 03 Sep 2024 18:44:11 +0800
|
||||
|
||||
fastfetch (2.22.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.22.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 26 Aug 2024 18:53:35 +0800
|
||||
|
||||
fastfetch (2.21.3) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.3
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.21.3_source.buildinfo universe/utils optional
|
||||
fastfetch_2.26.1ubuntu1_source.buildinfo universe/utils optional
|
||||
|
||||
+99
-111
@@ -337,14 +337,14 @@
|
||||
"processingTimeout": {
|
||||
"type": "integer",
|
||||
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
|
||||
"default": 1000
|
||||
"default": 5000
|
||||
},
|
||||
"preRun": {
|
||||
"type": "string",
|
||||
"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
|
||||
@@ -638,113 +638,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"library": {
|
||||
"description": "Set the path of a library to load",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"vulkan": {
|
||||
"type": "string",
|
||||
"description": "Vulkan module & fallback for GPU output"
|
||||
},
|
||||
"freetype": {
|
||||
"type": "string",
|
||||
"description": "Used for Termux font detection (Android)"
|
||||
},
|
||||
"wayland": {
|
||||
"type": "string",
|
||||
"description": "Better display performance and output in wayland sessions.\nSupports different refresh rates per monitor.\n(Linux, FreeBSD)"
|
||||
},
|
||||
"xcbRandr": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xcb": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xrandr": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"x11": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"drm": {
|
||||
"type": "string",
|
||||
"description": "Used for fast resolution and refresh rate detection (Linux, FreeBSD)"
|
||||
},
|
||||
"gio": {
|
||||
"type": "string",
|
||||
"description": "Needed for values that are only stored GSettings (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"dconf": {
|
||||
"type": "string",
|
||||
"description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"dbus": {
|
||||
"type": "string",
|
||||
"description": "Bluetooth, Player & Media detection (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xfconf": {
|
||||
"type": "string",
|
||||
"description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"sqlite3": {
|
||||
"type": "string",
|
||||
"description": "Needed for pkg & rpm package count (Linux, FreeBSD)"
|
||||
},
|
||||
"rpm": {
|
||||
"type": "string",
|
||||
"description": "Slower fallback for rpm package count. Needed on openSUSE & old CentOS / Redhat. (Linux)"
|
||||
},
|
||||
"imagemagick": {
|
||||
"type": "string",
|
||||
"description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)"
|
||||
},
|
||||
"z": {
|
||||
"description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)",
|
||||
"type": "string"
|
||||
},
|
||||
"chafa": {
|
||||
"type": "string",
|
||||
"description": "Image output as ascii art (Linux, FreeBSD, SunOS, macOS)"
|
||||
},
|
||||
"egl": {
|
||||
"type": "string",
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS, Windows)"
|
||||
},
|
||||
"glx": {
|
||||
"type": "string",
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"osmesa": {
|
||||
"type": "string",
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"opencl": {
|
||||
"type": "string",
|
||||
"description": "OpenCL module (Linux, FreeBSD, SunOS, Windows)"
|
||||
},
|
||||
"pulse": {
|
||||
"description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD, SunOS)",
|
||||
"type": "string"
|
||||
},
|
||||
"nm": {
|
||||
"description": "NetworkManager. Used for Wifi detection (Linux)",
|
||||
"type": "string"
|
||||
},
|
||||
"ddcutil": {
|
||||
"description": "Used for brightness detection of external displays (Linux)",
|
||||
"type": "string"
|
||||
},
|
||||
"elf": {
|
||||
"description": "Used for st terminal font detection and systemd version detection (Linux)",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"description": "Fastfetch modules to run",
|
||||
"type": "array",
|
||||
@@ -762,6 +655,7 @@
|
||||
"bootmgr",
|
||||
"break",
|
||||
"brightness",
|
||||
"btrfs",
|
||||
"camera",
|
||||
"chassis",
|
||||
"cpu",
|
||||
@@ -812,6 +706,7 @@
|
||||
"terminaltheme",
|
||||
"title",
|
||||
"theme",
|
||||
"tpm",
|
||||
"uptime",
|
||||
"users",
|
||||
"version",
|
||||
@@ -820,7 +715,8 @@
|
||||
"weather",
|
||||
"wm",
|
||||
"wifi",
|
||||
"wmtheme"
|
||||
"wmtheme",
|
||||
"zpool"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -920,7 +816,7 @@
|
||||
},
|
||||
{
|
||||
"const": "monitor",
|
||||
"description": "Print connected physical monitor information"
|
||||
"description": "Alias of Display module"
|
||||
},
|
||||
{
|
||||
"const": "opencl",
|
||||
@@ -970,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"
|
||||
@@ -1141,6 +1041,43 @@
|
||||
"maximum": 400,
|
||||
"default": 10
|
||||
},
|
||||
"compact": {
|
||||
"description": "Set if multiple results should be printed in one line",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"keyIcon": {
|
||||
"$ref": "#/$defs/keyIcon"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "BTRFS",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "btrfs",
|
||||
"description": "Print Btrfs volumes"
|
||||
},
|
||||
"percent": {
|
||||
"$ref": "#/$defs/percent"
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
@@ -1338,6 +1275,10 @@
|
||||
"description": "Set the shell program to execute the command text\nDefault: cmd for Windows, /bin/sh for *nix",
|
||||
"type": "string"
|
||||
},
|
||||
"param": {
|
||||
"description": "Set the parameter used when starting the shell\nDefault: /c for Windows, -c for *nix",
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"description": "Set the command text to be executed",
|
||||
"type": "string"
|
||||
@@ -1732,6 +1673,16 @@
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"showSpeed": {
|
||||
"description": "Show ethernet rx speed",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"showMtu": {
|
||||
"description": "Show MTU",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"showMac": {
|
||||
"description": "Show MAC addresses",
|
||||
"type": "boolean",
|
||||
@@ -1752,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",
|
||||
@@ -2359,6 +2315,38 @@
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Zpool",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "zpool",
|
||||
"description": "Print ZFS storage pools"
|
||||
},
|
||||
"percent": {
|
||||
"$ref": "#/$defs/percent"
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"keyIcon": {
|
||||
"$ref": "#/$defs/keyIcon"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+12
-2
@@ -54,7 +54,12 @@
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
"btrfs",
|
||||
"zpool",
|
||||
{
|
||||
"type": "battery",
|
||||
"temp": true
|
||||
},
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
@@ -65,7 +70,11 @@
|
||||
{
|
||||
"type": "localip",
|
||||
"showIpv6": true,
|
||||
"showMac": true
|
||||
"showMac": true,
|
||||
"showSpeed": true,
|
||||
"showMtu": true,
|
||||
"showLoop": true,
|
||||
"showFlags": true
|
||||
},
|
||||
"dns",
|
||||
"wifi",
|
||||
@@ -90,6 +99,7 @@
|
||||
"type": "physicaldisk",
|
||||
"temp": true
|
||||
},
|
||||
"tpm",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
|
||||
+106
-96
@@ -1,99 +1,109 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"display": {
|
||||
"stat": true,
|
||||
"pipe": true,
|
||||
"showErrors": true,
|
||||
"noBuffer": true
|
||||
},
|
||||
"logo": null,
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
"host",
|
||||
"bios",
|
||||
"bootmgr",
|
||||
"board",
|
||||
"chassis",
|
||||
"kernel",
|
||||
"initsystem",
|
||||
"uptime",
|
||||
"loadavg",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
"editor",
|
||||
"display",
|
||||
"brightness",
|
||||
"monitor",
|
||||
"lm",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"wallpaper",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"terminalsize",
|
||||
"terminaltheme",
|
||||
{
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"display": {
|
||||
"stat": true,
|
||||
"pipe": true,
|
||||
"showErrors": true,
|
||||
"noBuffer": true
|
||||
},
|
||||
"cpucache",
|
||||
"cpuusage",
|
||||
{
|
||||
"type": "gpu",
|
||||
"driverSpecific": true,
|
||||
"temp": true
|
||||
},
|
||||
"memory",
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
{
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"showIpv6": true,
|
||||
"showMac": true
|
||||
},
|
||||
"dns",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"users",
|
||||
"bluetooth",
|
||||
"bluetoothradio",
|
||||
"sound",
|
||||
"camera",
|
||||
"gamepad",
|
||||
{
|
||||
"type": "weather",
|
||||
"timeout": 1000
|
||||
},
|
||||
"netio",
|
||||
"diskio",
|
||||
{
|
||||
"type": "physicaldisk",
|
||||
"temp": true
|
||||
},
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
"logo": null,
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
"host",
|
||||
"bios",
|
||||
"bootmgr",
|
||||
"board",
|
||||
"chassis",
|
||||
"kernel",
|
||||
"initsystem",
|
||||
"uptime",
|
||||
"loadavg",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
"editor",
|
||||
"display",
|
||||
"brightness",
|
||||
"monitor",
|
||||
"lm",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"wallpaper",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"terminalsize",
|
||||
"terminaltheme",
|
||||
{
|
||||
"type": "cpu",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true
|
||||
},
|
||||
"cpucache",
|
||||
"cpuusage",
|
||||
{
|
||||
"type": "gpu",
|
||||
"driverSpecific": true,
|
||||
"temp": true
|
||||
},
|
||||
"memory",
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"btrfs",
|
||||
"zpool",
|
||||
{
|
||||
"type": "battery",
|
||||
"temp": true
|
||||
},
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
{
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"showIpv6": true,
|
||||
"showMac": true,
|
||||
"showSpeed": true,
|
||||
"showMtu": true,
|
||||
"showLoop": true,
|
||||
"showFlags": true
|
||||
},
|
||||
"dns",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"users",
|
||||
"bluetooth",
|
||||
"bluetoothradio",
|
||||
"sound",
|
||||
"camera",
|
||||
"gamepad",
|
||||
{
|
||||
"type": "weather",
|
||||
"timeout": 1000
|
||||
},
|
||||
"netio",
|
||||
"diskio",
|
||||
{
|
||||
"type": "physicaldisk",
|
||||
"temp": true
|
||||
},
|
||||
"tpm",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -111,8 +111,7 @@
|
||||
{
|
||||
"type": "loadavg",
|
||||
"compact": false,
|
||||
// {duration} is not fixed length, hack it
|
||||
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
|
||||
"key": "│ LOAD {duration>2}m │{$1}" // pad duration to 2 chars
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
// By jan-rex
|
||||
// Modified from: https://github.com/fastfetch-cli/fastfetch/discussions/1269
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"padding": {
|
||||
"top": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": "",
|
||||
"constants": [
|
||||
// CONSTANT {$1} - COLOR BACKGROUND FOR KEY
|
||||
"\u001b[48;2;43;43;69m",
|
||||
// CONSTANT {$2} - COLOR BACKGROUND FOR OUTPUT
|
||||
"\u001b[48;2;56;59;78m",
|
||||
// CONSTANT {$3} - VERTICAL BARS AT START AND 75th CHARACTERS FORWARD AND BACKWARD
|
||||
"\u001b[90m│ │\u001b[60D\u001b[39m",
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
// CUSTOM - Top UI bar
|
||||
{
|
||||
"type": "custom",
|
||||
"key": "{#90}{$1}╭─────────────╮",
|
||||
"format": "{#90}{$2}╭────────────────────────────────────────────────────────────╮",
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}{$1}│ {#92}User {#90}│",
|
||||
"format": "{$2}{$3}{user-name} {#2}[{home-dir}]"
|
||||
},
|
||||
{
|
||||
"type": "users",
|
||||
"key": "{#90}{$1}│ {#92}Users {#90}│",
|
||||
"myselfOnly": false,
|
||||
"format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} {#2}[Login time: {login-time}]",
|
||||
},
|
||||
{
|
||||
"type": "datetime",
|
||||
"key": "{#90}{$1}│ {#92}Datetime {#90}│",
|
||||
"format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}{weekday} {#2}[W{week}] {#2}[UTC{offset-from-utc}]"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "{#90}{$1}│ {#93}Host: {#90}│",
|
||||
"format": "{$2}{$3}{#1}{#36}{host-name}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "{#90}{$1}│ {#93}Machine {#90}│",
|
||||
"format": "{$2}{$3}{name} {#2}{version}"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "{#90}{$1}│ {#93}OS {#90}│",
|
||||
"format": "{$2}{$3}{pretty-name} {codename} {#2}[v{version}] {#2}[{arch}]"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "{#90}{$1}│ {#93}Kernel {#90}│",
|
||||
"format": "{$2}{$3}{sysname} {#2}[v{release}]"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "{#90}{$1}│ {#93}Uptime {#90}│",
|
||||
"format": "{$2}{$3}{?days}{days} Days + {?}{hours}:{minutes}:{seconds}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "{#90}{$1}│ {#91}CPU {#90}│",
|
||||
"showPeCoreCount": true,
|
||||
"temp": true,
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-types}] {#2}[{freq-max}]"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "{#90}{$1}│ {#91}GPU {#90}│",
|
||||
"detectionMethod": "auto",
|
||||
"driverSpecific": true,
|
||||
"format": "{$2}{$3}{name} {#2}[C:{core-count}] {#2}[{type}]"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "{#90}{$1}│ {#91}Memory {#90}│",
|
||||
"format": "{$2}{$3}{used} / {total} ({percentage}{$2})"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "{#90}{$1}│ {#91}Disk {#90}│",
|
||||
"format": "{$2}{$3}{size-used} / {size-total} ({size-percentage}{$2})"
|
||||
},
|
||||
{
|
||||
"type": "poweradapter",
|
||||
"key": "{#90}{$1}│ {#91}Power {#90}│",
|
||||
"format": "{$2}{$3}{name}"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": "{#90}{$1}│ {#95}Terminal {#90}│",
|
||||
"format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": "{#90}{$1}│ {#95}Font {#90}│",
|
||||
"format": "{$2}{$3}{name} {#2}[{size}]"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": "{#90}{$1}│ {#95}Shell {#90}│",
|
||||
"format": "{$2}{$3}{pretty-name} {#2}[v{version}] [PID:{pid}]"
|
||||
},
|
||||
{
|
||||
// localip IPv4
|
||||
"type": "localip",
|
||||
"key": "{#90}{$1}│ {#94}Local IPv4 {#90}│",
|
||||
"showPrefixLen": true,
|
||||
"showIpv4": true,
|
||||
"showIpv6": false,
|
||||
"showMtu": true,
|
||||
"format": "{$2}{$3}{ifname}: {ipv4} {#2}[MTU:{mtu}]"
|
||||
},
|
||||
{
|
||||
// localip IPv6
|
||||
"type": "localip",
|
||||
"key": "{#90}{$1}│ {#94}Local IPv6 {#90}│",
|
||||
"showPrefixLen": true,
|
||||
"showIpv4": false,
|
||||
"showIpv6": true,
|
||||
"showMtu": true,
|
||||
"format": "{$2}{$3}{ifname}: {ipv6} {#2}[MTU:{mtu}]"
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "{#90}{$1}│ {#94}Public IPv4 {#90}│",
|
||||
"ipv6": false,
|
||||
"format": "{$2}{$3}{ip} {#2}[{location}]"
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "{#90}{$1}│ {#94}Public IPv6 {#90}│",
|
||||
"ipv6": true,
|
||||
"format": "{$2}{$3}{ip} {#2}[{location}]"
|
||||
},
|
||||
// CUSTOM - Button UI bar
|
||||
{
|
||||
"type": "custom",
|
||||
"key": "{#90}{$1}╰─────────────╯",
|
||||
"format": "{#90}{$2}╰────────────────────────────────────────────────────────────╯",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -25,7 +25,10 @@
|
||||
"type": "disk",
|
||||
"folders": "/"
|
||||
},
|
||||
"battery",
|
||||
{
|
||||
"type": "battery",
|
||||
"key": "Battery"
|
||||
},
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 10,
|
||||
|
||||
@@ -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
|
||||
})
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
|
||||
static bool loadLibSymbols(FFDBusLibrary* lib)
|
||||
{
|
||||
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD(dbus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_append_args, false)
|
||||
|
||||
+143
-55
@@ -8,39 +8,53 @@
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
{
|
||||
if(formatarg->type == FF_FORMAT_ARG_TYPE_INT)
|
||||
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
|
||||
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT64)
|
||||
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
|
||||
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
|
||||
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING)
|
||||
ffStrbufAppendS(buffer, (const char*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF)
|
||||
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_FLOAT)
|
||||
ffStrbufAppendF(buffer, "%f", *(float*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE)
|
||||
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL)
|
||||
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST)
|
||||
switch(formatarg->type)
|
||||
{
|
||||
const FFlist* list = formatarg->value;
|
||||
for(uint32_t i = 0; i < list->length; i++)
|
||||
case FF_FORMAT_ARG_TYPE_INT:
|
||||
ffStrbufAppendF(buffer, "%" PRIi32, *(int32_t*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_UINT:
|
||||
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_UINT64:
|
||||
ffStrbufAppendF(buffer, "%" PRIu64, *(uint64_t*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_UINT16:
|
||||
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_UINT8:
|
||||
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_STRING:
|
||||
ffStrbufAppendS(buffer, (const char*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_STRBUF:
|
||||
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_FLOAT:
|
||||
ffStrbufAppendF(buffer, "%f", *(float*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_DOUBLE:
|
||||
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_BOOL:
|
||||
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_LIST:
|
||||
{
|
||||
ffStrbufAppend(buffer, ffListGet(list, i));
|
||||
if(i < list->length - 1)
|
||||
ffStrbufAppendS(buffer, ", ");
|
||||
const FFlist* list = formatarg->value;
|
||||
for(uint32_t i = 0; i < list->length; i++)
|
||||
{
|
||||
ffStrbufAppend(buffer, ffListGet(list, i));
|
||||
if(i < list->length - 1)
|
||||
ffStrbufAppendS(buffer, ", ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(formatarg->type != FF_FORMAT_ARG_TYPE_NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
|
||||
default:
|
||||
if(formatarg->type != FF_FORMAT_ARG_TYPE_NULL)
|
||||
fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +114,8 @@ static inline bool formatArgSet(const FFformatarg* arg)
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && arg->value != NULL)
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && *(bool*)arg->value) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_LIST && ((FFlist*)arg->value)->length > 0)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -265,18 +280,18 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t truncLength = INT32_MAX;
|
||||
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pColon != NULL)
|
||||
char* pSep = placeholderValue.chars;
|
||||
char cSep = '\0';
|
||||
while (*pSep && *pSep != ':' && *pSep != '<' && *pSep != '>' && *pSep != '~')
|
||||
++pSep;
|
||||
if (*pSep)
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
|
||||
if (*pEnd != '\0')
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
*pColon = '\0';
|
||||
cSep = *pSep;
|
||||
*pSep = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
pSep = NULL;
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
@@ -287,26 +302,99 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
|
||||
if (index > numArgs)
|
||||
{
|
||||
if (pColon) *pColon = ':';
|
||||
if (pSep) *pSep = cSep;
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ellipsis = false;
|
||||
if (truncLength < 0)
|
||||
if (!cSep)
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
else if (cSep == '~')
|
||||
{
|
||||
ellipsis = true;
|
||||
truncLength = -truncLength;
|
||||
}
|
||||
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
|
||||
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
|
||||
|
||||
uint32_t oldLength = buffer->length;
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
if (buffer->length - oldLength > (uint32_t) truncLength)
|
||||
char* pEnd = NULL;
|
||||
int32_t start = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
||||
if (start < 0)
|
||||
start = (int32_t) tempString.length + start;
|
||||
if (start >= 0 && (uint32_t) start < tempString.length)
|
||||
{
|
||||
if (*pEnd == '\0')
|
||||
ffStrbufAppendNS(buffer, tempString.length - (uint32_t) start, &tempString.chars[start]);
|
||||
else if (*pEnd == ',')
|
||||
{
|
||||
int32_t end = (int32_t) strtol(pEnd + 1, &pEnd, 10);
|
||||
if (!*pEnd)
|
||||
{
|
||||
if (end < 0)
|
||||
end = (int32_t) tempString.length + end;
|
||||
if ((uint32_t) end > tempString.length)
|
||||
end = (int32_t) tempString.length;
|
||||
if (end > start)
|
||||
ffStrbufAppendNS(buffer, (uint32_t) (end - start), &tempString.chars[start]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*pEnd)
|
||||
{
|
||||
*pSep = cSep;
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
char* pEnd = NULL;
|
||||
int32_t truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
||||
if (*pEnd != '\0')
|
||||
{
|
||||
*pSep = cSep;
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ellipsis = false;
|
||||
if (truncLength < 0)
|
||||
{
|
||||
ellipsis = true;
|
||||
truncLength = -truncLength;
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY tempString = ffStrbufCreate();
|
||||
ffFormatAppendFormatArg(&tempString, &arguments[index - 1]);
|
||||
if (tempString.length == (uint32_t) truncLength)
|
||||
ffStrbufAppend(buffer, &tempString);
|
||||
else if (tempString.length > (uint32_t) truncLength)
|
||||
{
|
||||
if (cSep == ':')
|
||||
{
|
||||
ffStrbufSubstrBefore(&tempString, (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(&tempString);
|
||||
}
|
||||
else
|
||||
ffStrbufSubstrBefore(&tempString, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
|
||||
ffStrbufAppend(buffer, &tempString);
|
||||
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
}
|
||||
else if (cSep == ':')
|
||||
ffStrbufAppend(buffer, &tempString);
|
||||
else
|
||||
{
|
||||
if (cSep == '<')
|
||||
{
|
||||
ffStrbufAppend(buffer, &tempString);
|
||||
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendNC(buffer, (uint32_t) truncLength - tempString.length, ' ');
|
||||
ffStrbufAppend(buffer, &tempString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
typedef enum FFformatargtype
|
||||
typedef enum FFformatArgType
|
||||
{
|
||||
FF_FORMAT_ARG_TYPE_NULL = 0,
|
||||
FF_FORMAT_ARG_TYPE_UINT,
|
||||
@@ -16,11 +16,26 @@ typedef enum FFformatargtype
|
||||
FF_FORMAT_ARG_TYPE_DOUBLE,
|
||||
FF_FORMAT_ARG_TYPE_LIST,
|
||||
FF_FORMAT_ARG_TYPE_BOOL
|
||||
} FFformatargtype;
|
||||
} FFformatArgType;
|
||||
|
||||
#define FF_FORMAT_ARG(variable, var_name) { _Generic((variable), \
|
||||
uint32_t: FF_FORMAT_ARG_TYPE_UINT, \
|
||||
uint64_t: FF_FORMAT_ARG_TYPE_UINT64, \
|
||||
uint16_t: FF_FORMAT_ARG_TYPE_UINT16, \
|
||||
uint8_t: FF_FORMAT_ARG_TYPE_UINT8, \
|
||||
int32_t: FF_FORMAT_ARG_TYPE_INT, \
|
||||
char*: FF_FORMAT_ARG_TYPE_STRING, \
|
||||
const char*: FF_FORMAT_ARG_TYPE_STRING, \
|
||||
FFstrbuf: FF_FORMAT_ARG_TYPE_STRBUF, \
|
||||
float: FF_FORMAT_ARG_TYPE_FLOAT, \
|
||||
double: FF_FORMAT_ARG_TYPE_DOUBLE, \
|
||||
FFlist: FF_FORMAT_ARG_TYPE_LIST, \
|
||||
bool: FF_FORMAT_ARG_TYPE_BOOL \
|
||||
), _Generic((variable), char*: (variable), const char*: (variable), default: &(variable) ), (var_name) }
|
||||
|
||||
typedef struct FFformatarg
|
||||
{
|
||||
FFformatargtype type;
|
||||
FFformatArgType type;
|
||||
const void* value;
|
||||
const char* name; // argument name, must start with an alphabet
|
||||
} FFformatarg;
|
||||
|
||||
+10
-3
@@ -43,7 +43,6 @@ static void defaultConfig(void)
|
||||
ffOptionsInitGeneral(&instance.config.general);
|
||||
ffOptionsInitModules(&instance.config.modules);
|
||||
ffOptionsInitDisplay(&instance.config.display);
|
||||
ffOptionsInitLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
void ffInitInstance(void)
|
||||
@@ -148,7 +147,6 @@ static void destroyConfig(void)
|
||||
ffOptionsDestroyGeneral(&instance.config.general);
|
||||
ffOptionsDestroyModules(&instance.config.modules);
|
||||
ffOptionsDestroyDisplay(&instance.config.display);
|
||||
ffOptionsDestroyLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
static void destroyState(void)
|
||||
@@ -193,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
|
||||
@@ -244,9 +245,12 @@ void ffListFeatures(void)
|
||||
#if FF_HAVE_DDCUTIL
|
||||
"libddcutil\n"
|
||||
#endif
|
||||
#if FF_HAVE_ELF
|
||||
#if FF_HAVE_ELF || __sun || __FreeBSD__ || __OpenBSD__
|
||||
"libelf\n"
|
||||
#endif
|
||||
#if FF_HAVE_LIBZFS
|
||||
"libzfs\n"
|
||||
#endif
|
||||
#if FF_HAVE_DIRECTX_HEADERS
|
||||
"Directx Headers\n"
|
||||
#endif
|
||||
@@ -259,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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -130,8 +130,8 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out);
|
||||
|
||||
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
|
||||
|
||||
FF_C_SCANF(2, 3)
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
FF_C_SCANF(3, 4)
|
||||
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...);
|
||||
|
||||
// Not thread safe!
|
||||
bool ffSuppressIO(bool suppress);
|
||||
|
||||
+73
-19
@@ -4,14 +4,21 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#ifndef __APPLE__
|
||||
#include <poll.h>
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#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)
|
||||
@@ -117,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)
|
||||
@@ -128,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;
|
||||
@@ -140,7 +161,7 @@ void restoreTerm(void)
|
||||
tcsetattr(ftty, TCSAFLUSH, &oldTerm);
|
||||
}
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
|
||||
{
|
||||
if (ftty < 0)
|
||||
{
|
||||
@@ -161,20 +182,54 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
ffWriteFDData(ftty, strlen(request), request);
|
||||
|
||||
//Give the terminal some time to respond
|
||||
#ifndef __APPLE__
|
||||
if(poll(&(struct pollfd) { .fd = ftty, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
return "poll() timeout or failed";
|
||||
return "poll(/dev/tty) timeout or failed";
|
||||
#else
|
||||
{
|
||||
// On macOS, poll(/dev/tty) always returns immediately
|
||||
// See also https://nathancraddock.com/blog/macos-dev-tty-polling/
|
||||
fd_set rd;
|
||||
FD_ZERO(&rd);
|
||||
FD_SET(ftty, &rd);
|
||||
if(select(ftty + 1, &rd, NULL, NULL, &(struct timeval) { .tv_sec = FF_IO_TERM_RESP_WAIT_MS / 1000, .tv_usec = (FF_IO_TERM_RESP_WAIT_MS % 1000) * 1000 }) <= 0)
|
||||
return "select(/dev/tty) timeout or failed";
|
||||
}
|
||||
#endif
|
||||
|
||||
char buffer[512];
|
||||
ssize_t bytesRead = read(ftty, buffer, sizeof(buffer) - 1);
|
||||
|
||||
if(bytesRead <= 0)
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
|
||||
buffer[bytesRead] = '\0';
|
||||
char buffer[1024];
|
||||
size_t bytesRead = 0;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
|
||||
while (true)
|
||||
{
|
||||
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';
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
return NULL;
|
||||
@@ -232,12 +287,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(entry->d_name[0] == '.') // skip hidden files
|
||||
continue;
|
||||
|
||||
bool isDir = false;
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
#ifndef __sun
|
||||
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
|
||||
isDir = entry->d_type == DT_DIR;
|
||||
else
|
||||
#else
|
||||
#endif
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
|
||||
@@ -245,12 +303,8 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
else
|
||||
isDir = S_ISDIR(stbuf.st_mode);
|
||||
}
|
||||
#endif
|
||||
if (isDir)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(folder, entry->d_name);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
|
||||
|
||||
+32
-12
@@ -205,7 +205,7 @@ void ffListFilesRecursively(const char* path, bool pretty)
|
||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
||||
}
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
const char* ffGetTerminalResponse(const char* request, int nParams, const char* format, ...)
|
||||
{
|
||||
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
|
||||
@@ -256,20 +256,40 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
ReadConsoleInputW(hInput, &record, 1, &len);
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
DWORD bytes = 0;
|
||||
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
char buffer[1024];
|
||||
uint32_t bytesRead = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
SetConsoleMode(hInput, inputMode);
|
||||
|
||||
if(bytes <= 0)
|
||||
return "ReadFile() failed";
|
||||
|
||||
buffer[bytes] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
return NULL;
|
||||
|
||||
+16
-16
@@ -55,28 +55,28 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
return result;
|
||||
}
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...)
|
||||
void* ffLibraryLoad(const char* path, int maxVersion, ...)
|
||||
{
|
||||
if(userProvidedName != NULL && userProvidedName->length > 0)
|
||||
return dlopen(userProvidedName->chars, FF_DLOPEN_FLAGS);
|
||||
void* result = libraryLoad(path, maxVersion);
|
||||
|
||||
va_list defaultNames;
|
||||
va_start(defaultNames, userProvidedName);
|
||||
|
||||
void* result = NULL;
|
||||
|
||||
while(result == NULL)
|
||||
if (!result)
|
||||
{
|
||||
const char* path = va_arg(defaultNames, const char*);
|
||||
if(path == NULL)
|
||||
break;
|
||||
va_list defaultNames;
|
||||
va_start(defaultNames, maxVersion);
|
||||
|
||||
int maxVersion = va_arg(defaultNames, int);
|
||||
result = libraryLoad(path, maxVersion);
|
||||
do
|
||||
{
|
||||
const char* pathRest = va_arg(defaultNames, const char*);
|
||||
if(pathRest == NULL)
|
||||
break;
|
||||
|
||||
int maxVersionRest = va_arg(defaultNames, int);
|
||||
result = libraryLoad(pathRest, maxVersionRest);
|
||||
} while (!result);
|
||||
|
||||
va_end(defaultNames);
|
||||
}
|
||||
|
||||
va_end(defaultNames);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ static inline void ffLibraryUnload(void** handle)
|
||||
#define FF_LIBRARY_SYMBOL(symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName;
|
||||
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
|
||||
void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
|
||||
void* __attribute__((__cleanup__(ffLibraryUnload))) libraryObjectName = ffLibraryLoad(__VA_ARGS__, NULL);\
|
||||
if(libraryObjectName == NULL) \
|
||||
return returnValue;
|
||||
|
||||
@@ -72,7 +72,7 @@ static inline void ffLibraryUnload(void** handle)
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
|
||||
void* ffLibraryLoad(const char* path, int maxVersion, ...);
|
||||
|
||||
#else
|
||||
|
||||
@@ -81,7 +81,7 @@ void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
|
||||
#define FF_LIBRARY_SYMBOL(symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName;
|
||||
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, returnValue, ...) \
|
||||
FF_MAYBE_UNUSED void* libraryObjectName = NULL; // Placeholder
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
||||
|
||||
@@ -13,6 +13,7 @@ static FFModuleBaseInfo* B[] = {
|
||||
(void*) &instance.config.modules.bootmgr,
|
||||
(void*) &instance.config.modules.break_,
|
||||
(void*) &instance.config.modules.brightness,
|
||||
(void*) &instance.config.modules.btrfs,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -136,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,
|
||||
};
|
||||
|
||||
@@ -169,6 +171,7 @@ static FFModuleBaseInfo* Y[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Z[] = {
|
||||
(void*) &instance.config.modules.zpool,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -132,5 +132,6 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
||||
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
|
||||
|
||||
close(state->sockfd);
|
||||
if (buffer->length == 0) return "Empty server response received";
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
|
||||
}
|
||||
|
||||
@@ -63,19 +63,21 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
||||
return "socket() failed";
|
||||
}
|
||||
|
||||
{
|
||||
//ConnectEx requires the socket to be initially bound
|
||||
if(bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
|
||||
//ConnectEx requires the socket to be initially bound
|
||||
if((state->ipv6
|
||||
? bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in6) {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_addr = in6addr_any,
|
||||
}, sizeof(struct sockaddr_in6))
|
||||
: bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
.sin_port = 0,
|
||||
}, sizeof(struct sockaddr_in)) != 0)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
state->sockfd = INVALID_SOCKET;
|
||||
return "bind() failed";
|
||||
}
|
||||
}, sizeof(struct sockaddr_in))) != 0)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
state->sockfd = INVALID_SOCKET;
|
||||
return "bind() failed";
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64);
|
||||
@@ -93,7 +95,6 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
|
||||
if(!result && WSAGetLastError() != WSA_IO_PENDING)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
state->sockfd = INVALID_SOCKET;
|
||||
return "ConnectEx() failed";
|
||||
}
|
||||
@@ -140,5 +141,6 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
|
||||
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
|
||||
|
||||
closesocket(state->sockfd);
|
||||
if (buffer->length == 0) return "Empty server response received";
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex, "index"},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &moduleArgs->keyIcon, "icon"},
|
||||
FF_FORMAT_ARG(moduleIndex, "index"),
|
||||
FF_FORMAT_ARG(moduleArgs->keyIcon, "icon"),
|
||||
}));
|
||||
ffStrbufWriteTo(&key, stdout);
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -60,7 +60,7 @@ static const GSettingsData* getGSettingsData(void)
|
||||
if (!data.inited)
|
||||
{
|
||||
data.inited = true;
|
||||
FF_LIBRARY_LOAD(libgsettings, &instance.config.library.libGIO, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_LOAD(libgsettings, NULL, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_source_lookup, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_schema_has_key, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libgsettings, data, g_settings_new_full, NULL)
|
||||
@@ -141,7 +141,7 @@ static const DConfData* getDConfData(void)
|
||||
{
|
||||
data.inited = true;
|
||||
|
||||
FF_LIBRARY_LOAD(libdconf, &instance.config.library.libDConf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
FF_LIBRARY_LOAD(libdconf, NULL, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_read_full, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data, dconf_client_new, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libdconf, data.variantGetters, g_variant_dup_string, NULL)
|
||||
@@ -218,7 +218,7 @@ static const XFConfData* getXFConfData(void)
|
||||
if (!data.inited)
|
||||
{
|
||||
data.inited = true;
|
||||
FF_LIBRARY_LOAD(libxfconf, &instance.config.library.libXFConf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD(libxfconf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_has_property, NULL)
|
||||
@@ -292,7 +292,7 @@ static const SQLiteData* getSQLiteData(void)
|
||||
if (!data.inited)
|
||||
{
|
||||
data.inited = true;
|
||||
FF_LIBRARY_LOAD(libsqlite, &instance.config.library.libSQLite3, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_LOAD(libsqlite, NULL, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_open_v2, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_prepare_v2, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libsqlite, data, sqlite3_step, NULL)
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
+45
-179
@@ -128,7 +128,7 @@
|
||||
"desc": "Set the timeout (ms) when waiting for child processes",
|
||||
"arg": {
|
||||
"type": "num",
|
||||
"default": 1000
|
||||
"default": 5000
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -766,184 +766,6 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"Library path": [
|
||||
{
|
||||
"long": "lib-vulkan",
|
||||
"desc": "Vulkan module & fallback for GPU output",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-wayland",
|
||||
"desc": "Better display performance and output in wayland sessions",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-xcb-randr",
|
||||
"desc": "X11 sessions for better display detection and faster WM detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-xcb",
|
||||
"desc": "X11 sessions for better display detection and faster WM detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-xrandr",
|
||||
"desc": "X11 sessions for better display detection and faster WM detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-x11",
|
||||
"desc": "X11 sessions for better display detection and faster WM detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-drm",
|
||||
"desc": "Used for fast resolution and refresh rate detection",
|
||||
"remark": "Linux only",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-gio",
|
||||
"desc": "Needed for values that are only stored GSettings",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-dconf",
|
||||
"desc": "Needed for values that are only stored in DConf + Fallback for GSettings",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-dbus",
|
||||
"desc": "Bluetooth, Player & Media detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-xfconf",
|
||||
"desc": "Needed for XFWM theme and XFCE Terminal font",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-sqlite3",
|
||||
"desc": "Needed for pkg & rpm package count",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-rpm",
|
||||
"desc": "Slower fallback for rpm package count",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-imagemagick",
|
||||
"desc": "Images in terminal using sixel or kitty graphics protocol",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-z",
|
||||
"desc": "Libz. Faster image output when using kitty graphics protocol",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-chafa",
|
||||
"desc": "Image output as ascii art",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-egl",
|
||||
"desc": "Needed by the OpenGL module for gl context creation",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-glx",
|
||||
"desc": "Needed by the OpenGL module for gl context creation",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-osmesa",
|
||||
"desc": "Needed by the OpenGL module for gl context creation",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-opencl",
|
||||
"desc": "OpenCL module",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-pulse",
|
||||
"desc": "Pulseaudio. Used for Sound detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-nm",
|
||||
"desc": "NetworkManager. Used for Wifi detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-freetype",
|
||||
"desc": "Used for Termux font detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-ddcutil",
|
||||
"desc": "Used for brightness detection of external displays",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-elf",
|
||||
"desc": "Used for st terminal font detection and systemd version detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Module specific": [
|
||||
{
|
||||
"long": "title-fqdn",
|
||||
@@ -1178,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",
|
||||
@@ -1366,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",
|
||||
@@ -1401,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",
|
||||
@@ -1554,6 +1411,15 @@
|
||||
"default": "\"cmd\" for Windows; \"/bin/sh\" for *nix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "command-param",
|
||||
"desc": "Set the parameter used when starting the shell",
|
||||
"remark": "If set to empty string, it will be ignored",
|
||||
"arg": {
|
||||
"type": "str",
|
||||
"default": "\"/c\" for Windows; \"-c\" for *nix"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "command-key",
|
||||
"desc": "Set the module key to display",
|
||||
|
||||
@@ -13,6 +13,14 @@ For example: "--title-format '{user-name:5}'" will truncate user name into 5-len
|
||||
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
|
||||
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
|
||||
|
||||
In 2.23.0 or newer, `<` or `>` can be specified instead of `:` to set a left or right padding.
|
||||
For example: "--title-format '{user-name<20}'" will generate `<user-name> `;
|
||||
"--title-format '{user-name>20}'" will generate ` <user-name>`
|
||||
|
||||
In 2.24.0 or newer, `{~startIndex,endIndex}` can be specified to slice a string. Negative index counts back from the end of the string.
|
||||
If an index is omitted, 0 is used. For example, both `{~,0}` `{~0,}` and `{~,}` are same as `{~0,0}` and will always generate a empty string.
|
||||
If `,endIndex` is omitted or greater than the length of the string, the length of string is used.
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
|
||||
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
|
||||
|
||||
@@ -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,6 +1,5 @@
|
||||
#include "battery.h"
|
||||
#include "common/io/io.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
// Actually bluetoothapis.dll, but it's missing on Windows 7
|
||||
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstDevice)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextDevice)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindDeviceClose)
|
||||
|
||||
@@ -54,7 +54,7 @@ static_assert(sizeof(BTH_LOCAL_RADIO_INFO) == 292, "BTH_LOCAL_RADIO_INFO should
|
||||
const char* ffDetectBluetoothRadio(FFlist* devices /* FFBluetoothRadioResult */)
|
||||
{
|
||||
// Actually bluetoothapis.dll, but it's missing on Windows 7
|
||||
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
FF_LIBRARY_LOAD(bluetoothapis, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstRadio)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextRadio)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindRadioClose)
|
||||
|
||||
@@ -6,9 +6,25 @@
|
||||
|
||||
const char* ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->name);
|
||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_serial", "/sys/class/dmi/id/board_serial", &board->serial);
|
||||
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);
|
||||
if (ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->name))
|
||||
{
|
||||
ffGetSmbiosValue("/sys/devices/virtual/dmi/id/board_serial", "/sys/class/dmi/id/board_serial", &board->serial);
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -101,7 +101,7 @@ DDCA_Status ddca_init(const char *libopts, int syslog_level, int opts);
|
||||
|
||||
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libddcutil, &instance.config.library.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
||||
FF_LIBRARY_LOAD(libddcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
|
||||
|
||||
@@ -39,7 +39,7 @@ static const char* detectWithWmi(FFlist* result)
|
||||
|
||||
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(dxva2, NULL, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD(dxva2, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBtrfsDiskUsage
|
||||
{
|
||||
uint64_t total;
|
||||
uint64_t used;
|
||||
const char* type;
|
||||
bool dup;
|
||||
} FFBtrfsDiskUsage;
|
||||
|
||||
typedef struct FFBtrfsResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf uuid;
|
||||
FFstrbuf devices;
|
||||
FFstrbuf features;
|
||||
uint32_t generation;
|
||||
uint32_t nodeSize;
|
||||
uint32_t sectorSize;
|
||||
uint64_t totalSize;
|
||||
uint64_t globalReservationUsed;
|
||||
uint64_t globalReservationTotal;
|
||||
FFBtrfsDiskUsage allocation[3];
|
||||
} FFBtrfsResult;
|
||||
|
||||
const char* ffDetectBtrfs(FFlist* result /* list of FFBtrfsResult */);
|
||||
@@ -0,0 +1,166 @@
|
||||
#include "btrfs.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
|
||||
enum { uuidLen = (uint32_t) __builtin_strlen("00000000-0000-0000-0000-000000000000") };
|
||||
|
||||
static const char* enumerateDevices(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufAppendS(path, "devices/");
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars);
|
||||
if(dirp == NULL)
|
||||
return "opendir(\"/sys/fs/btrfs/UUID/devices\") == NULL";
|
||||
const uint32_t devicesPathLen = path->length;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if (item->devices.length)
|
||||
ffStrbufAppendC(&item->devices, ',');
|
||||
ffStrbufAppendS(&item->devices, entry->d_name);
|
||||
ffStrbufAppendS(path, entry->d_name);
|
||||
ffStrbufAppendS(path, "/size");
|
||||
|
||||
if (ffReadFileBuffer(path->chars, buffer))
|
||||
item->totalSize += ffStrbufToUInt(buffer, 0) * 512;
|
||||
|
||||
ffStrbufSubstrBefore(path, devicesPathLen);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* enumerateFeatures(FFBtrfsResult* item, FFstrbuf* path)
|
||||
{
|
||||
ffStrbufAppendS(path, "features/");
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars);
|
||||
if(dirp == NULL)
|
||||
return "opendir(\"/sys/fs/btrfs/UUID/features\") == NULL";
|
||||
const uint32_t featuresPathLen = path->length;
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
if (item->features.length)
|
||||
ffStrbufAppendC(&item->features, ',');
|
||||
ffStrbufAppendS(&item->features, entry->d_name);
|
||||
|
||||
ffStrbufSubstrBefore(path, featuresPathLen);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectAllocation(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufAppendS(path, "allocation/");
|
||||
const uint32_t AllocationPathLen = path->length;
|
||||
|
||||
ffStrbufAppendS(path, "global_rsv_size");
|
||||
if (ffReadFileBuffer(path->chars, buffer))
|
||||
item->globalReservationTotal = ffStrbufToUInt(buffer, 0);
|
||||
else
|
||||
return "ffReadFileBuffer(\"/sys/fs/btrfs/UUID/allocation/global_rsv_size\") == NULL";
|
||||
ffStrbufSubstrBefore(path, AllocationPathLen);
|
||||
|
||||
ffStrbufAppendS(path, "global_rsv_reserved");
|
||||
if (ffReadFileBuffer(path->chars, buffer))
|
||||
item->globalReservationUsed = ffStrbufToUInt(buffer, 0);
|
||||
ffStrbufSubstrBefore(path, AllocationPathLen);
|
||||
item->globalReservationUsed = item->globalReservationTotal - item->globalReservationUsed;
|
||||
|
||||
#define FF_BTRFS_DETECT_TYPE(index, _type) \
|
||||
ffStrbufAppendS(path, #_type "/total_bytes"); \
|
||||
if (ffReadFileBuffer(path->chars, buffer)) \
|
||||
item->allocation[index].total = ffStrbufToUInt(buffer, 0); \
|
||||
ffStrbufSubstrBefore(path, AllocationPathLen); \
|
||||
\
|
||||
ffStrbufAppendS(path, #_type "/bytes_used"); \
|
||||
if (ffReadFileBuffer(path->chars, buffer)) \
|
||||
item->allocation[index].used = ffStrbufToUInt(buffer, 0); \
|
||||
ffStrbufSubstrBefore(path, AllocationPathLen); \
|
||||
\
|
||||
ffStrbufAppendS(path, #_type "/dup"); \
|
||||
item->allocation[index].dup = ffPathExists(path->chars, FF_PATHTYPE_DIRECTORY); \
|
||||
ffStrbufSubstrBefore(path, AllocationPathLen); \
|
||||
\
|
||||
item->allocation[index].type = #_type;
|
||||
|
||||
FF_BTRFS_DETECT_TYPE(0, data);
|
||||
FF_BTRFS_DETECT_TYPE(1, metadata);
|
||||
FF_BTRFS_DETECT_TYPE(2, system);
|
||||
|
||||
#undef FF_BTRFS_DETECT_TYPE
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectBtrfs(FFlist* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/fs/btrfs/");
|
||||
const uint32_t basePathLen = path.length;
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path.chars);
|
||||
if(dirp == NULL)
|
||||
return "opendir(\"/sys/fs/btrfs\") == NULL";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
if (strlen(entry->d_name) != uuidLen)
|
||||
continue;
|
||||
|
||||
FFBtrfsResult* item = ffListAdd(result);
|
||||
(*item) = (FFBtrfsResult){};
|
||||
ffStrbufInitNS(&item->uuid, uuidLen, entry->d_name);
|
||||
ffStrbufInit(&item->name);
|
||||
ffStrbufInit(&item->devices);
|
||||
ffStrbufInit(&item->features);
|
||||
|
||||
ffStrbufAppendNS(&path, uuidLen, entry->d_name);
|
||||
ffStrbufAppendC(&path, '/');
|
||||
const uint32_t itemPathLen = path.length;
|
||||
|
||||
ffStrbufAppendS(&path, "label");
|
||||
if (ffAppendFileBuffer(path.chars, &item->name))
|
||||
ffStrbufTrimRightSpace(&item->name);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
enumerateDevices(item, &path, &buffer);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
enumerateFeatures(item, &path);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
ffStrbufAppendS(&path, "generation");
|
||||
if (ffReadFileBuffer(path.chars, &buffer))
|
||||
item->generation = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
ffStrbufAppendS(&path, "nodesize");
|
||||
if (ffReadFileBuffer(path.chars, &buffer))
|
||||
item->nodeSize = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
ffStrbufAppendS(&path, "sectorsize");
|
||||
if (ffReadFileBuffer(path.chars, &buffer))
|
||||
item->sectorSize = (uint32_t) ffStrbufToUInt(&buffer, 0);
|
||||
ffStrbufSubstrBefore(&path, itemPathLen);
|
||||
|
||||
detectAllocation(item, &path, &buffer);
|
||||
|
||||
// finally
|
||||
ffStrbufSubstrBefore(&path, basePathLen);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "btrfs.h"
|
||||
|
||||
const char* ffDetectBtrfs(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -43,10 +43,10 @@ const char* ffDetectCamera(FFlist* result)
|
||||
case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break;
|
||||
case V4L2_COLORSPACE_REC709:
|
||||
case V4L2_COLORSPACE_SRGB: ffStrbufInitStatic(&camera->colorspace, "sRGB"); break;
|
||||
case V4L2_COLORSPACE_OPRGB: ffStrbufInitStatic(&camera->colorspace, "Adobe RGB"); break;
|
||||
case V4L2_COLORSPACE_BT2020: ffStrbufInitStatic(&camera->colorspace, "BT.2020"); break;
|
||||
case V4L2_COLORSPACE_RAW: ffStrbufInitStatic(&camera->colorspace, "RAW"); break;
|
||||
case V4L2_COLORSPACE_DCI_P3: ffStrbufInitStatic(&camera->colorspace, "DCI-P3"); break;
|
||||
case 9 /* V4L2_COLORSPACE_OPRGB */: ffStrbufInitStatic(&camera->colorspace, "Adobe RGB"); break;
|
||||
case 10 /* V4L2_COLORSPACE_BT2020 */: ffStrbufInitStatic(&camera->colorspace, "BT.2020"); break;
|
||||
case 11 /* V4L2_COLORSPACE_RAW */: ffStrbufInitStatic(&camera->colorspace, "RAW"); break;
|
||||
case 12 /* V4L2_COLORSPACE_DCI_P3 */: ffStrbufInitStatic(&camera->colorspace, "DCI-P3"); break;
|
||||
default: ffStrbufInit(&camera->colorspace); break;
|
||||
}
|
||||
camera->width = fmt.fmt.pix.width;
|
||||
|
||||
@@ -21,9 +21,9 @@ private:
|
||||
extern "C"
|
||||
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(mfplat, NULL, "dlopen mfplat" FF_LIBRARY_EXTENSION " failed", "mfplat" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD(mfplat, "dlopen mfplat" FF_LIBRARY_EXTENSION " failed", "mfplat" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mfplat, MFCreateAttributes)
|
||||
FF_LIBRARY_LOAD(mf, NULL, "dlopen mf" FF_LIBRARY_EXTENSION " failed", "mf" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD(mf, "dlopen mf" FF_LIBRARY_EXTENSION " failed", "mf" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(mf, MFEnumDeviceSources)
|
||||
|
||||
const char* error = ffInitCom();
|
||||
|
||||
+14
-1
@@ -37,6 +37,19 @@ const char* ffCPUAppleCodeToName(uint32_t code)
|
||||
case 6031:
|
||||
case 6034: return "Apple M3 Max";
|
||||
case 8132: return "Apple M4";
|
||||
default: return "Apple Silicon";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffCPUQualcommCodeToName(uint32_t code)
|
||||
{
|
||||
// https://github.com/AsahiLinux/docs/wiki/Codenames
|
||||
switch (code)
|
||||
{
|
||||
case 7180: return "Qualcomm Snapdragon 7c";
|
||||
case 7280: return "Qualcomm Snapdragon 7c+ Gen 3";
|
||||
case 8180: return "Qualcomm Snapdragon 8cx Gen 2 5G";
|
||||
case 8280: return "Qualcomm Snapdragon 8cx Gen 3";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -30,7 +29,7 @@ typedef struct FFCPUResult
|
||||
|
||||
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
|
||||
const char* ffCPUAppleCodeToName(uint32_t code);
|
||||
|
||||
const char* ffCPUQualcommCodeToName(uint32_t code);
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -106,6 +106,9 @@ static const char* armPartId2name(uint32_t partId)
|
||||
case 0xd80: return "Cortex-A520";
|
||||
case 0xd81: return "Cortex-A720";
|
||||
case 0xd82: return "Cortex-X4";
|
||||
case 0xd84: return "Neoverse-V3";
|
||||
case 0xd85: return "Cortex-X925";
|
||||
case 0xd87: return "Cortex-A725";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-31
@@ -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)
|
||||
{
|
||||
@@ -9,7 +30,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
cpu->coresLogical = cpu->coresPhysical;
|
||||
cpu->coresOnline = cpu->coresPhysical;
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
|
||||
@@ -41,40 +62,13 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
|
||||
{
|
||||
ffStrbufClear(&buffer);
|
||||
char key[32];
|
||||
snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i);
|
||||
if (ffSysctlGetString(key, &buffer) == NULL)
|
||||
{
|
||||
if (buffer.length == 0) continue;
|
||||
|
||||
// MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000
|
||||
uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10);
|
||||
if (cpu->frequencyMax < fmax) cpu->frequencyMax = fmax;
|
||||
|
||||
if (options->showPeCoreCount)
|
||||
{
|
||||
uint32_t ifreq = 0;
|
||||
while (cpu->coreTypes[ifreq].freq != fmax && cpu->coreTypes[ifreq].freq > 0)
|
||||
++ifreq;
|
||||
if (cpu->coreTypes[ifreq].freq == 0)
|
||||
cpu->coreTypes[ifreq].freq = fmax;
|
||||
cpu->coreTypes[ifreq].count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if (options->temp)
|
||||
{
|
||||
if (!ffDetectCpuTemp(&cpu->temperature))
|
||||
ffDetectThermalTemp(&cpu->temperature);
|
||||
if (detectCpuTemp(&cpu->temperature) != NULL)
|
||||
detectThermalTemp(&cpu->temperature);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
+171
-42
@@ -2,19 +2,93 @@
|
||||
#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"
|
||||
|
||||
static void detectQualcomm(FFCPUResult* cpu)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/List_of_Qualcomm_Snapdragon_systems_on_chips
|
||||
|
||||
if (ffStrbufEqualS(&cpu->name, "SM8635"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM8650-AC"))
|
||||
@@ -32,6 +106,8 @@ static void detectQualcomm(FFCPUResult* cpu)
|
||||
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM7675"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7+ Gen 3 [SM7675]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM7635"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7s Gen 3 [SM7635]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM7550"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7 Gen 3 [SM7550]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM7475"))
|
||||
@@ -43,6 +119,10 @@ static void detectQualcomm(FFCPUResult* cpu)
|
||||
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM6375-AC"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6s Gen 3 [SM6375-AC]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM6475"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6 Gen 3 [SM6475]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM6115"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6s Gen 1 [SM6115]");
|
||||
else if (ffStrbufEqualS(&cpu->name, "SM6450"))
|
||||
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6 Gen 1 [SM6450]");
|
||||
|
||||
@@ -245,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
|
||||
@@ -273,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
|
||||
@@ -311,26 +382,84 @@ FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu)
|
||||
FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
|
||||
{
|
||||
// In Asahi Linux, reading /proc/device-tree/compatible gives
|
||||
// information on the device model. It consists of 3 NUL terminated
|
||||
// strings, the second of which gives the actual SoC model. But it
|
||||
// is not the marketing name, i.e. for M2 there is "apple,t8112" in
|
||||
// the compatible string.
|
||||
if (cpu->name.length == 0 && ffStrbufEqualS(&cpu->vendor, "Apple"))
|
||||
{
|
||||
char content[32];
|
||||
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
|
||||
if (length <= 0) return;
|
||||
if (cpu->name.length > 0)
|
||||
return;
|
||||
|
||||
// get the second NUL terminated string
|
||||
char* modelName = memchr(content, '\0', (size_t) length) + 1;
|
||||
if (modelName - content < length && ffStrStartsWith(modelName, "apple,t"))
|
||||
// device-vendor,device-model\0soc-vendor,soc-model\0
|
||||
char content[256];
|
||||
ssize_t length = ffReadFileData("/proc/device-tree/compatible", sizeof(content), content);
|
||||
if (length <= 2) 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;
|
||||
|
||||
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/source/arch/arm64/boot/dts/apple
|
||||
if (model[0] == 't')
|
||||
{
|
||||
uint32_t deviceId = (uint32_t) strtoul(modelName + strlen("apple,t"), NULL, 10);
|
||||
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");
|
||||
}
|
||||
#endif
|
||||
else if (ffStrEquals(vendor, "qcom"))
|
||||
{
|
||||
// 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 = model + 1; *p; ++p)
|
||||
ffStrbufAppendC(&cpu->name, (char) toupper(*p));
|
||||
}
|
||||
else if (ffStrStartsWith(model, "sc"))
|
||||
{
|
||||
const char* code = model + 2;
|
||||
uint32_t deviceId = (uint32_t) strtoul(code, NULL, 10);
|
||||
ffStrbufSetStatic(&cpu->name, ffCPUQualcommCodeToName(deviceId));
|
||||
if (!cpu->name.length)
|
||||
{
|
||||
ffStrbufAppendS(&cpu->name, "Qualcomm Snapdragon SC");
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,8 +512,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#elif __aarch64__
|
||||
detectAsahi(cpu);
|
||||
#else
|
||||
detectArmSoc(cpu);
|
||||
#endif
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -121,7 +121,7 @@ static const char* getXfce4ByLib(FFstrbuf* result)
|
||||
{
|
||||
#ifndef FF_DISABLE_DLOPEN
|
||||
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
|
||||
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
|
||||
FF_LIBRARY_LOAD(xfce4util, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
|
||||
ffStrbufSetS(result, ffxfce_version_string());
|
||||
return NULL;
|
||||
@@ -178,6 +178,12 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
|
||||
}
|
||||
|
||||
static void getUnity(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
if (ffParsePropFile("/usr/bin/unity", "parser = OptionParser(version= \"%prog ", result))
|
||||
ffStrbufSubstrBeforeFirstC(result, '"');
|
||||
}
|
||||
|
||||
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
if (!instance.config.general.detectVersion) return "Disabled by config";
|
||||
@@ -196,6 +202,8 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
|
||||
getLXQt(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
|
||||
getBudgie(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_UNITY))
|
||||
getUnity(result, options);
|
||||
else
|
||||
return "Unsupported DE";
|
||||
return NULL;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
static unsigned __stdcall testRemoteVolumeAccessable(void* mountpoint)
|
||||
static unsigned __stdcall testRemoteVolumeAccessible(void* mountpoint)
|
||||
{
|
||||
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(
|
||||
(wchar_t*) mountpoint,
|
||||
@@ -84,7 +84,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
#ifdef FF_HAVE_THREADS
|
||||
if (driveType == DRIVE_REMOTE)
|
||||
{
|
||||
FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessable, mountpoint);
|
||||
FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessible, mountpoint);
|
||||
if (!ffThreadJoin(thread, 500))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,17 +5,15 @@
|
||||
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName);
|
||||
|
||||
const char* ffdsConnectWayland(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsConnectXcbRandr(FFDisplayServerResult* result);
|
||||
void ffdsConnectXcb(FFDisplayServerResult* result);
|
||||
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result);
|
||||
const char* ffdsConnectXcb(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsConnectXrandr(FFDisplayServerResult* result);
|
||||
void ffdsConnectXlib(FFDisplayServerResult* result);
|
||||
const char* ffdsConnectXrandr(FFDisplayServerResult* result);
|
||||
const char* ffdsConnectXlib(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsConnectDrm(FFDisplayServerResult* result);
|
||||
const char* ffdsConnectDrm(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsDetectWMDE(FFDisplayServerResult* result);
|
||||
|
||||
|
||||
@@ -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,30 +190,28 @@ 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";
|
||||
}
|
||||
|
||||
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD(libdrm, "dlopen libdrm" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmGetDevices)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetResources)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)
|
||||
@@ -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);
|
||||
@@ -376,17 +415,19 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
|
||||
#endif
|
||||
|
||||
void ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
{
|
||||
#ifdef FF_HAVE_DRM
|
||||
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
|
||||
{
|
||||
if (drmConnectLibdrm(result) == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
drmParseSysfs(result);
|
||||
return drmParseSysfs(result);
|
||||
#endif
|
||||
|
||||
return "fastfetch was compiled without drm support";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -150,7 +191,7 @@ const char* ffdsConnectWayland(FFDisplayServerResult* result)
|
||||
if (getenv("XDG_RUNTIME_DIR") == NULL)
|
||||
return "Wayland requires $XDG_RUNTIME_DIR being set";
|
||||
|
||||
FF_LIBRARY_LOAD(wayland, &instance.config.library.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD(wayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wayland, wl_display_connect)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wayland, wl_display_get_fd)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -238,6 +242,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
ffStrbufSetS(&result->deProcessName, "ukui-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UKUI);
|
||||
}
|
||||
|
||||
else if(
|
||||
ffStrStartsWithIgnCase(name, "Unity:Unity")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "unity-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UNITY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,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;
|
||||
|
||||
@@ -269,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";
|
||||
@@ -305,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";
|
||||
|
||||
@@ -82,21 +82,21 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
|
||||
ffStrbufSetS(&result->wmProcessName, wmName);
|
||||
}
|
||||
|
||||
void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcb, &instance.config.library.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_screen_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_disconnect,)
|
||||
FF_LIBRARY_LOAD(xcb, "dlopen lbxcb failed", "libxcb" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_connect)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_get_setup)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_setup_roots_iterator)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_screen_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcb, xcb_disconnect)
|
||||
|
||||
XcbPropertyData propertyData;
|
||||
bool propertyDataInitialized = xcbInitPropertyData(xcb, &propertyData);
|
||||
|
||||
xcb_connection_t* connection = ffxcb_connect(NULL, NULL);
|
||||
if(connection == NULL)
|
||||
return;
|
||||
return "xcb_connect failed";
|
||||
|
||||
xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(connection));
|
||||
|
||||
@@ -128,14 +128,17 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
|
||||
if(result->wmProtocolName.length == 0)
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
{
|
||||
//Do nothing. There are other implementations coming
|
||||
FF_UNUSED(result)
|
||||
return "Fastfetch was compiled without XCB support";
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -177,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);
|
||||
@@ -240,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,
|
||||
@@ -256,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)
|
||||
@@ -269,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;
|
||||
}
|
||||
@@ -388,45 +385,45 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
);
|
||||
}
|
||||
|
||||
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcbRandr, &instance.config.library.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_screen_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_disconnect,)
|
||||
FF_LIBRARY_LOAD(xcbRandr, "dlopen lbxcb-randr failed", "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_connect)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_get_setup)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_setup_roots_iterator)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_screen_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xcbRandr, xcb_disconnect)
|
||||
|
||||
XcbRandrData data;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_mode_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_monitors_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs_length,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_output_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_property_data_length,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_intern_atom)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_intern_atom_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_mode_info_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_monitors_monitors_iterator)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_outputs_length)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_monitor_info_outputs)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_output_next)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_info)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_info_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_reply)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_data)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_output_property_data_length)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_crtc_info)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xcbRandr, data, xcb_randr_get_crtc_info_reply)
|
||||
|
||||
bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &data.propData);
|
||||
|
||||
|
||||
data.connection = ffxcb_connect(NULL, NULL);
|
||||
if(data.connection == NULL)
|
||||
return;
|
||||
return "xcb_connect failed";
|
||||
|
||||
|
||||
data.result = result;
|
||||
@@ -450,14 +447,17 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
|
||||
if(result->wmProtocolName.length == 0)
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
{
|
||||
//Do nothing. There are other implementations coming
|
||||
FF_UNUSED(result)
|
||||
return "Fastfetch was compiled without libxcb-randr support";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -58,18 +58,18 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
|
||||
data->ffXFree(wmWindow);
|
||||
}
|
||||
|
||||
void ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(x11, &instance.config.library.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
|
||||
FF_LIBRARY_LOAD(x11, "dlopen libX11 failed", "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XOpenDisplay)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(x11, XCloseDisplay)
|
||||
|
||||
X11PropertyData propertyData;
|
||||
bool propertyDataInitialized = x11InitPropertyData(x11, &propertyData);
|
||||
|
||||
Display* display = ffXOpenDisplay(x11);
|
||||
if(display == NULL)
|
||||
return;
|
||||
return "XOpenDisplay failed";
|
||||
|
||||
if(propertyDataInitialized && ScreenCount(display) > 0)
|
||||
x11DetectWMFromEWMH(&propertyData, display, result);
|
||||
@@ -98,14 +98,17 @@ void ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
|
||||
if(result->wmProtocolName.length == 0)
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXlib(FFDisplayServerResult* result)
|
||||
{
|
||||
//Do nothing. WM / DE detection will use environment vars to detect as much as possible.
|
||||
FF_UNUSED(result);
|
||||
return "Fastfetch was compiled without libX11 support";
|
||||
}
|
||||
|
||||
#endif //FF_HAVE_X11
|
||||
@@ -150,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;
|
||||
|
||||
@@ -177,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,
|
||||
@@ -193,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)
|
||||
@@ -203,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;
|
||||
@@ -308,34 +322,34 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
);
|
||||
}
|
||||
|
||||
void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
||||
FF_LIBRARY_LOAD(xrandr, "dlopen libXrandr failed", "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XOpenDisplay)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xrandr, XCloseDisplay)
|
||||
|
||||
XrandrData data;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputProperty,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetCrtcInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeCrtcInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeOutputInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenResources,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeMonitors,);
|
||||
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, XRRGetScreenResourcesCurrent);
|
||||
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, XRRGetCrtcInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeCrtcInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeOutputInfo);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeScreenResources);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(xrandr, data, XRRFreeMonitors);
|
||||
|
||||
X11PropertyData propertyData;
|
||||
bool propertyDataInitialized = x11InitPropertyData(xrandr, &propertyData);
|
||||
|
||||
data.display = ffXOpenDisplay(NULL);
|
||||
if(data.display == NULL)
|
||||
return;
|
||||
return "XOpenDisplay() failed";
|
||||
|
||||
if(propertyDataInitialized && ScreenCount(data.display) > 0)
|
||||
x11DetectWMFromEWMH(&propertyData, data.display, result);
|
||||
@@ -350,14 +364,17 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
|
||||
if(result->wmProtocolName.length == 0)
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
const char* ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
{
|
||||
//Do nothing here. There are more x11 implementations to come.
|
||||
FF_UNUSED(result);
|
||||
return "Fastfetch was compiled without libXrandr support";
|
||||
}
|
||||
|
||||
#endif // FF_HAVE_XRANDR
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -14,26 +14,23 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool extractNvimVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("NVIM v0.0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "NVIM v")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractVimVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("VIM - Vi IMproved 0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
|
||||
ffStrbufSubstrBeforeFirstC(userdata, ' ');
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractNanoVersionFromBinary(const char* str, uint32_t len, void* userdata)
|
||||
static bool extractNanoVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (len < strlen("GNU nano 0.0")) return true;
|
||||
if (!ffStrStartsWith(str, "GNU nano ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
|
||||
return false;
|
||||
@@ -97,11 +94,11 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
if (ffStrbufEqualS(&result->exe, "nvim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version);
|
||||
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
|
||||
else if (ffStrbufEqualS(&result->exe, "vim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version);
|
||||
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
|
||||
else if (ffStrbufEqualS(&result->exe, "nano"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version);
|
||||
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
|
||||
|
||||
if (result->version.length > 0) return NULL;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
if (!inited)
|
||||
{
|
||||
inited = true;
|
||||
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
|
||||
FF_LIBRARY_LOAD(libags, "dlopen amd_ags failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
|
||||
|
||||
struct AGSContext* apiHandle;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -34,7 +34,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
if (!igclData.inited)
|
||||
{
|
||||
igclData.inited = true;
|
||||
FF_LIBRARY_LOAD(libigcl, NULL, "dlopen igcl (ControlLib) failed", soName , 1);
|
||||
FF_LIBRARY_LOAD(libigcl, "dlopen igcl (ControlLib) failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libigcl, ctlInit)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlClose)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libigcl, igclData, ctlEnumerateDevices)
|
||||
@@ -195,5 +195,8 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
|
||||
}
|
||||
}
|
||||
|
||||
if (result.name)
|
||||
ffStrbufSetS(result.name, properties.name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+417
-192
@@ -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,21 +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) ¶msGlobal,
|
||||
.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));
|
||||
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;
|
||||
@@ -417,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) ¶msGlobal,
|
||||
.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)
|
||||
{
|
||||
@@ -476,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);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
struct FFMtmlData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(mtmlDeviceCountGpuCores)
|
||||
FF_LIBRARY_SYMBOL(mtmlDeviceGetBrand)
|
||||
FF_LIBRARY_SYMBOL(mtmlDeviceGetIndex)
|
||||
FF_LIBRARY_SYMBOL(mtmlDeviceGetName)
|
||||
@@ -29,7 +30,7 @@ struct FFMtmlData
|
||||
MtmlSystem *sys;
|
||||
} mtmlData;
|
||||
|
||||
static void shutdownMtml()
|
||||
FF_MAYBE_UNUSED static void shutdownMtml(void)
|
||||
{
|
||||
mtmlData.ffmtmlLibraryShutDown(mtmlData.lib);
|
||||
}
|
||||
@@ -41,8 +42,9 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive
|
||||
if (!mtmlData.inited)
|
||||
{
|
||||
mtmlData.inited = true;
|
||||
FF_LIBRARY_LOAD(libmtml, NULL, "dlopen mtml failed", soName, 1);
|
||||
FF_LIBRARY_LOAD(libmtml, "dlopen mtml failed", soName, 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceCountGpuCores)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName)
|
||||
@@ -132,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;
|
||||
@@ -158,6 +167,9 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive
|
||||
}
|
||||
}
|
||||
|
||||
if (result.coreCount)
|
||||
mtmlData.ffmtmlDeviceCountGpuCores(device, result.coreCount);
|
||||
|
||||
if (result.frequency)
|
||||
{
|
||||
MtmlGpu *gpu = NULL;
|
||||
|
||||
@@ -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;
|
||||
@@ -26,7 +27,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
|
||||
if (!nvmlData.inited)
|
||||
{
|
||||
nvmlData.inited = true;
|
||||
FF_LIBRARY_LOAD(libnvml, NULL, "dlopen nvml failed", soName , 1);
|
||||
FF_LIBRARY_LOAD(libnvml, "dlopen nvml failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetCount_v2)
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
extern "C"
|
||||
const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libdxcore, nullptr, "dlopen libdxcore.so failed", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
|
||||
FF_LIBRARY_LOAD(libdxcore, "dlopen libdxcore.so failed", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
|
||||
// DXCoreCreateAdapterFactory is a reloaded function, so we can't use FF_LIBRARY_LOAD_SYMBOL_MESSAGE here
|
||||
typedef HRESULT (*DXCoreCreateAdapterFactory_t)(REFIID riid, void** ppvFactory);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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[];
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user