Compare commits

...

73 Commits

Author SHA1 Message Date
Carter Li 0b32abd5a7 Merge pull request #1302 from fastfetch-cli/dev
Release: v2.26.1
2024-09-29 15:50:33 +08:00
李通洲 73e61c2b89 Release: v2.26.1 2024-09-29 15:42:31 +08:00
李通洲 1901b9308f GPU: use adapterLuid as deviceID for non-pci devices 2024-09-29 15:42:31 +08:00
李通洲 a7c7493733 GPU (Windows): fix uninitialized variables 2024-09-29 15:34:57 +08:00
李通洲 73f98f9509 CMake: allow to disable pacstall 2024-09-29 14:18:23 +08:00
Carter Li 3d82d55e5d Packaging: update debian stuff [ci skip] 2024-09-29 13:34:25 +08:00
Carter Li 6485d34700 Merge pull request #1298 from fastfetch-cli/dev
Release: v2.26.0
2024-09-29 10:50:59 +08:00
李通洲 17c9179b7d Doc: update changelog 2024-09-29 10:29:11 +08:00
Carter Li 88097463af Display (Linux): report displays of unknown connection state too
Ref: #1301
2024-09-29 10:25:46 +08:00
李通洲 5381395c54 GPU (macOS): update how integrated GPUs are detected 2024-09-29 10:24:15 +08:00
Ziyao 51796de69a Display (Linux): detect all enabled or connected connectors (#1301)
DRM connectors have two properties, "enabled" and "status", standing for
"enabled by userspace" and "a display has been connected". Connector
status cannot be reliably detected sometimes, in this case status will
be set to unknown and it is still okay to enable it. Some drivers are
also able to enable disconnected connectors.

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

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

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

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

Signed-off-by: Yao Zi <ziyao@disroot.org>
2024-09-29 10:23:20 +08:00
李通洲 140b9834cc Logo (Builtin): add GXDE OS
Fix #1300
2024-09-28 23:58:50 +08:00
Carter Li a424839d2f CPU (Linux): remove bios_limit detection 2024-09-28 17:10:22 +08:00
李通洲 acd5d4a258 Release: v2.26.0 2024-09-28 10:40:21 +08:00
李通洲 f8fa3f8ea6 Scripts: add SPDX-License-Identifier 2024-09-28 10:39:32 +08:00
Carter Li 38f07ade44 GPU (Linux): fix building with old kernel headers 2024-09-28 08:13:54 +08:00
Carter Li 7ae7ff8cef GPU (Linux): detect EU count & vmem size of Intel GPUs 2024-09-27 23:36:08 +08:00
Carter Li 842ba9fd4e GPU: use driver reported adapter name if available 2024-09-27 15:02:32 +08:00
Carter Li 5058a93428 GPU (Linux): use renderDN instead of cardN when detecting AMD cards
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1284#issuecomment-2377437210
2024-09-27 10:47:57 +08:00
Carter Li d6eff93c12 GPU: fix usage of bsearch 2024-09-27 09:54:22 +08:00
李通洲 03565384e6 Chore (macOS): use simplified syntax 2024-09-27 09:16:54 +08:00
李通洲 a3a4f0a64a Kmod: support macOS 2024-09-27 09:02:00 +08:00
李通洲 af067c7c3f Util: rename KernelMod to Kmod 2024-09-27 08:39:21 +08:00
李通洲 8bbc985d98 CMake: fix more linking errors in dynamic mode 2024-09-27 00:20:47 +08:00
李通洲 254876b9e6 GPU (Linux): try fixing linking errors when dyamic linking is used
Fix #1295
2024-09-27 00:19:31 +08:00
李通洲 78fc5a2b5d GPU: fix compiling error when -DCUSTOM_PCI_IDS_PATH is used 2024-09-27 00:00:04 +08:00
李通洲 745c041b44 GPU (Linux): fix some obvious bugs found in #1284 2024-09-26 23:53:13 +08:00
Carter Li 4283d96c53 CI: fix build 2024-09-26 20:12:12 +08:00
Carter Li e07fcc4d49 Scripts: fix old python version compatibility 2024-09-26 19:37:24 +08:00
Carter Li d095f39418 TPM (FreeBSD): fix silly bug... 2024-09-26 19:23:21 +08:00
李通洲 af63e6e98b GPU (macOS): detect GPU driver version 2024-09-26 16:43:54 +08:00
Carter Li fc05d728f3 Util: add function ffKernelModLoaded and use it 2024-09-26 16:05:34 +08:00
李通洲 e3cb52583d CI: try building with -DENABLE_EMBEDDED_PCIIDS=ON 2024-09-26 15:08:59 +08:00
李通洲 01735d6fde Presets: add tpm to all & ci 2024-09-26 15:02:43 +08:00
Carter Li b37b495aee TPM (FreeBSD): report clearer error if tpm module is not loaded 2024-09-26 14:58:26 +08:00
李通洲 28c9b67414 Processing (Windows): correctly escaping arguments 2024-09-26 14:41:06 +08:00
李通洲 4d7d367e72 FFstrbuf: add new methods ffStrbufPrependC and ffStrbufInsertNC 2024-09-26 14:34:51 +08:00
Carter Li 8295f66320 TPM (FreeBSD): add support 2024-09-26 11:03:54 +08:00
李通洲 87f2e69162 TPM: update description 2024-09-26 11:03:54 +08:00
李通洲 f496e6d965 TPM: add new module 2024-09-26 00:01:31 +08:00
李通洲 96d885e93a GPU: embed pci.ids into fastfetch 2024-09-25 20:27:03 +08:00
李通洲 ae6817e106 GPU: simplify logic of pci.ids file loading 2024-09-25 16:42:15 +08:00
Carter Li 582b0fa087 Monitor (Linux): prefer DRM 2024-09-25 09:36:20 +08:00
Carter Li 0414128a55 GPU (Linux): refactor code to support non-apple SOCs 2024-09-24 20:55:36 +08:00
李通洲 5dbd6b9ab8 Chore: remove temps_windows 2024-09-24 13:30:42 +08:00
李通洲 0c90941a32 Chore: remove temps_bsd 2024-09-24 11:00:49 +08:00
李通洲 29ae56e76a TerminalFont: fix hanging when font name is long (kitty) 2024-09-24 10:42:43 +08:00
李通洲 81b0ddb2da Chore: rename temps_apple 2024-09-24 10:37:54 +08:00
李通洲 4ea5d6f4fe Wifi (macOS): fix protocol detection on Sequoia 2024-09-24 09:56:02 +08:00
李通洲 9b4053e9dc Chore: remove temps_linux 2024-09-24 01:51:45 +00:00
李通洲 b4325ff205 Temps (Linux): simplify 2024-09-24 01:42:00 +00:00
李通洲 87d32466f6 GPU (SunOS): fix compiling 2024-09-23 22:44:17 +08:00
李通洲 3b9d20ddf2 Presets: fix examples/24
Fix #24
2024-09-23 22:34:49 +08:00
李通洲 32b6af2686 GPU (Windows): better Intel GPU type detection 2024-09-23 22:31:44 +08:00
Carter Li a3c0617f22 GPU: simplify integrated GPU detection 2024-09-23 20:40:36 +08:00
Carter Li 30ffa4bdd2 Temps (Linux): simplify 2024-09-23 16:42:34 +08:00
Carter Li 86a96da9ab PhysicalDisk (Linux): cleanup temp detection code 2024-09-23 16:42:34 +08:00
Carter Li b3b6e5fec1 GPU (Linux): refactor; add amdgpu DRM connector 2024-09-23 16:42:34 +08:00
李通洲 e0296b75f6 Doc: add donation info 2024-09-22 19:15:03 +08:00
Carter Li bd2b002d14 Display: always print inches in integer 2024-09-22 18:13:10 +08:00
李通洲 c936d170b2 Packages (Linux): support pacstall 2024-09-22 12:30:37 +08:00
李通洲 a77d972834 Packages (Linux): count flatpak runtime packages
Fix #1085
2024-09-22 12:21:56 +08:00
李通洲 10868ed951 Doc: update README [ci skip] 2024-09-22 10:45:18 +08:00
李通洲 fc947468a9 Terminal: ignore sudo and su
Fix #1283
2024-09-22 10:32:22 +08:00
李通洲 005d660d77 Logo (Builtin): add FoxOS
Fix #1281
2024-09-21 23:04:45 +08:00
李通洲 866c7303e6 Chore (Windows): use standard libc api 2024-09-20 20:25:59 +08:00
Carter Li 85a31c7c69 TerminalShell (Linux): improve perf of yakuake version detection 2024-09-20 16:30:00 +08:00
Carter Li 1dba6d155b TerminalShell (Linux): improve performance of foot version detection 2024-09-20 15:33:30 +08:00
Carter Li db669c00a1 TerminalFont (Linux): fix font size detection of foot when fall back font is used
Fix #1276
2024-09-20 15:33:04 +08:00
Carter Li 006c00ab2c Packaging: update debian stuff [ci skip] 2024-09-20 14:14:17 +08:00
李通洲 0bcbae90e9 GPU: clean up GPU index detection code 2024-09-19 15:38:43 +08:00
李通洲 503a8d51ab Merge remote-tracking branch 'origin/master' into dev 2024-09-19 15:24:17 +08:00
michela feng 9332f42889 GPU: detect GPU index (#1267) 2024-09-19 15:22:09 +08:00
95 changed files with 1901 additions and 593 deletions
-1
View File
@@ -1 +0,0 @@
github: [CarterLi, LinusDierheimer]
+7 -7
View File
@@ -35,7 +35,7 @@ jobs:
run: uname -a
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -74,7 +74,7 @@ jobs:
run: uname -a
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev python3-requests
- name: install linuxbrew packages
run: |
@@ -87,7 +87,7 @@ jobs:
languages: c
- name: configure project
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -247,12 +247,12 @@ jobs:
run: |
cat /etc/alpine-release
uname -a
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev py3-requests gcc g++
shell: alpine.sh --root {0}
- name: build
run: |
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -GNinja .
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr -DIS_MUSL=ON -DENABLE_EMBEDDED_PCIIDS=On -GNinja .
cmake --build . --target package --verbose -j4
shell: alpine.sh {0}
@@ -422,8 +422,8 @@ jobs:
run: |
uname -a
sudo pkg update
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm libelf glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm libelf glib dconf dbus sqlite3-tcl xfce4-conf egl libosmesa opencl ocl-icd v4l_compat py311-requests
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc --stat false
+38
View File
@@ -1,3 +1,41 @@
# 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:
+42 -10
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.25.0
VERSION 2.26.1
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -51,6 +51,7 @@ cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR FreeBSD OR SunOS" OF
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_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX" 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)
@@ -80,6 +81,7 @@ option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
option(INSTALL_LICENSE "Install license into /usr/share/licenses" ON)
option(ENABLE_EMBEDDED_PCIIDS "Embed pci.ids into fastfetch, requires `python`" OFF)
set(BINARY_LINK_TYPE_OPTIONS dlopen dynamic static)
set(BINARY_LINK_TYPE dlopen CACHE STRING "How to link fastfetch")
@@ -88,7 +90,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PALUDIS PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
foreach(package_manager ${PACKAGE_MANAGERS})
if(package_manager STREQUAL "WINGET")
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
@@ -254,6 +256,16 @@ else()
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
endif()
if(ENABLE_EMBEDDED_PCIIDS AND NOT EXISTS "fastfetch_pciids.c.inc")
if(Python_FOUND)
execute_process(COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen-pciids.py"
OUTPUT_FILE "fastfetch_pciids.c.inc")
else()
message(STATUS "Python3 is not found, 'fastfetch_pciids.c.inc' will not be generated")
set(ENABLE_EMBEDDED_PCIIDS OFF)
endif()
endif()
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
fastfetch_load_text(src/data/help_footer.txt DATATEXT_HELP_FOOTER)
@@ -394,6 +406,7 @@ set(LIBFASTFETCH_SRC
src/modules/terminalsize/terminalsize.c
src/modules/theme/theme.c
src/modules/title/title.c
src/modules/tpm/tpm.c
src/modules/uptime/uptime.c
src/modules/users/users.c
src/modules/version/version.c
@@ -412,6 +425,7 @@ set(LIBFASTFETCH_SRC
src/util/base64.c
src/util/FFlist.c
src/util/FFstrbuf.c
src/util/kmod.c
src/util/path.c
src/util/platform/FFPlatform.c
src/util/smbiosHelper.c
@@ -480,11 +494,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
@@ -544,11 +558,11 @@ elseif(ANDROID)
src/detection/processes/processes_linux.c
src/detection/sound/sound_nosupport.c
src/detection/swap/swap_linux.c
src/detection/temps/temps_linux.c
src/detection/terminalfont/terminalfont_android.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_linux.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_nosupport.c
@@ -625,11 +639,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
@@ -691,11 +705,11 @@ elseif(APPLE)
src/detection/processes/processes_bsd.c
src/detection/sound/sound_apple.c
src/detection/swap/swap_apple.c
src/detection/temps/temps_apple.c
src/detection/terminalfont/terminalfont_apple.m
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
src/detection/theme/theme_nosupport.c
src/detection/tpm/tpm_nosupport.c
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_apple.m
@@ -707,6 +721,7 @@ elseif(APPLE)
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/apple/smc_temps.c
src/util/platform/FFPlatform_unix.c
src/util/binary_apple.c
)
@@ -726,6 +741,7 @@ elseif(WIN32)
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_windows.c
src/detection/cpu/cpu_windows.cpp
src/detection/cpucache/cpucache_windows.c
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
@@ -760,8 +776,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
@@ -846,6 +862,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
@@ -1038,6 +1055,10 @@ ff_lib_enable(DRM
"libdrm"
"Libdrm"
)
ff_lib_enable(DRM_AMDGPU
"libdrm_amdgpu"
"Libdrm_Amdgpu"
)
ff_lib_enable(GIO
"gio-2.0"
"GIO"
@@ -1133,18 +1154,29 @@ if(ENABLE_LIBZFS)
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS=1)
if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
endif()
endif()
if(ENABLE_EMBEDDED_PCIIDS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EMBEDDED_PCIIDS=1)
endif()
if(LINUX)
target_link_libraries(libfastfetch
PRIVATE "m"
)
if(ENABLE_DIRECTX_HEADERS)
if(NOT BINARY_LINK_TYPE STREQUAL "dlopen")
target_link_libraries(libfastfetch
PRIVATE "/usr/lib/wsl/lib/libdxcore.so"
)
endif()
endif()
elseif(APPLE)
target_link_libraries(libfastfetch
PRIVATE "-framework AVFoundation"
@@ -1168,7 +1200,7 @@ elseif(APPLE)
PRIVATE "-weak_framework Apple80211"
)
elseif(WIN32)
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0A00)
target_link_libraries(libfastfetch
PRIVATE "dwmapi"
PRIVATE "gdi32"
+13 -2
View File
@@ -152,13 +152,13 @@ Fastfetch uses `format` to generate output. For example, to make the `GPU` modul
"modules": [
{
"type": "gpu",
"format": "{2}" // See `fastfetch -h gpu-format` for detail
"format": "{name}" // See `fastfetch -h gpu-format` for detail
}
]
}
```
. . which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
. . which is equivalent to `fastfetch -s gpu --gpu-format '{name}'`
See `fastfetch -h format` for information on basic usage. For module specific formattion, see `fastfetch -h <module>-format`
@@ -186,6 +186,10 @@ You can always use `fastfetch --pipe false` to force fastfetch running in colorf
See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
### Q: I use Debian / Ubuntu / Debian deserved distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is it a bug?
See [#1282](https://github.com/fastfetch-cli/fastfetch/issues/1282)
### 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 +214,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!
+12
View File
@@ -1,3 +1,15 @@
fastfetch (2.26.0) jammy; urgency=medium
* Update to 2.26.0
-- Carter Li <zhangsongcui@live.cn> Sun, 29 Sep 2024 13:31:25 +0800
fastfetch (2.25.0) jammy; urgency=medium
* Update to 2.25.0
-- Carter Li <zhangsongcui@live.cn> Thu, 19 Sep 2024 10:28:38 +0800
fastfetch (2.24.0) jammy; urgency=medium
* Update to 2.24.0
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.24.0_source.buildinfo universe/utils optional
fastfetch_2.26.0_source.buildinfo universe/utils optional
+5
View File
@@ -706,6 +706,7 @@
"terminaltheme",
"title",
"theme",
"tpm",
"uptime",
"users",
"version",
@@ -865,6 +866,10 @@
"const": "theme",
"description": "Print current theme of desktop environment"
},
{
"const": "tpm",
"description": "Print info of Trusted Platform Module (TPM) Security Device"
},
{
"const": "uptime",
"description": "Print how long system has been running"
+1
View File
@@ -97,6 +97,7 @@
"type": "physicaldisk",
"temp": true
},
"tpm",
"version",
"break",
"colors"
+1
View File
@@ -99,6 +99,7 @@
"type": "physicaldisk",
"temp": true
},
"tpm",
"version",
"break",
"colors"
+1 -1
View File
@@ -88,7 +88,7 @@
{
"type": "disk",
"key": "{#90}{$1}│ {#91}Disk {#90}│",
"format": "{$2}{$3}{size-used} / {size-used} ({size-percentage}{$2})"
"format": "{$2}{$3}{size-used} / {size-total} ({size-percentage}{$2})"
},
{
"type": "poweradapter",
+95
View File
@@ -0,0 +1,95 @@
from requests import get as http_get
class PciDeviceModel:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
class PciVendorModel:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
self.devices = []
def main(keep_vendor_list: set):
vendors = []
try:
with open('pci.ids', 'r') as f:
full_text = f.read()
except FileNotFoundError:
response = http_get('https://pci-ids.ucw.cz/v2.2/pci.ids')
full_text = response.text
dev_list_text = full_text[:full_text.rfind('\n\n\n')] # remove known classes
for line in dev_list_text.split('\n'):
if not line or line[0] == '#':
continue
if line[0] != '\t':
id, name = line.split(' ', maxsplit=1)
vendors.append(PciVendorModel(int(id, 16), name))
elif line[1] != '\t':
id, name = line[1:].split(' ', maxsplit=1)
vendors[-1].devices.append(PciDeviceModel(int(id, 16), name))
code = """\
// SPDX-License-Identifier: BSD-3-Clause
// https://opensource.org/license/BSD-3-Clause
// Generated from https://pci-ids.ucw.cz/v2.2/pci.ids
#include <stdint.h>
#include <stddef.h>
typedef struct FFPciDevice
{
const uint32_t id;
const char* name;
} FFPciDevice;
typedef struct FFPciVendor
{
const uint32_t id;
const char* name;
const FFPciDevice* devices;
const uint32_t nDevices;
} FFPciVendor;
"""
if keep_vendor_list:
vendors = [vendor for vendor in vendors if vendor.id in keep_vendor_list]
for vendor in vendors:
if vendor.devices:
piece = ',\n '.join('{{ 0x{:04X}, "{}" }}'.format(device.id, device.name.replace('"', '\\"')) for device in vendor.devices)
code += f"""
// {vendor.name}
static const FFPciDevice pciDevices_{vendor.id:04X}[] = {{
{piece},
{{}},
}};
"""
piece = ',\n '.join('{{ 0x{:04X}, "{}", {}, {} }}'.format(vendor.id, vendor.name.replace('"', '\\"'), vendor.devices and f"pciDevices_{vendor.id:04X}" or "NULL", len(vendor.devices)) for vendor in vendors)
code += f"""
const FFPciVendor ffPciVendors[] = {{
{piece},
{{}},
}};"""
print(code)
if __name__ == '__main__':
# From <src/detection/gpu/gpu.c>
main({
0x106b, # Apple
0x1002, 0x1022, # AMD
0x8086, 0x8087, 0x03e7, # Intel
0x0955, 0x10de, 0x12d2, # Nvidia
0x1ed5, # MThreads
0x5143, # Qualcomm
0x14c3, # MTK
0x15ad, # VMware
0x1af4, # RedHat
0x1ab8, # Parallel
0x1414, # Microsoft
0x108e, # Oracle
})
+6
View File
@@ -191,6 +191,9 @@ void ffListFeatures(void)
#if FF_HAVE_DRM
"drm\n"
#endif
#if FF_HAVE_DRM_AMDGPU
"drm_amdgpu\n"
#endif
#if FF_HAVE_GIO
"gio\n"
#endif
@@ -260,6 +263,9 @@ void ffListFeatures(void)
#if FF_HAVE_LINUX_WIRELESS
"linux/wireless\n"
#endif
#if FF_HAVE_EMBEDDED_PCIIDS
"Embedded pciids\n"
#endif
""
, stdout);
}
+1
View File
@@ -137,6 +137,7 @@ static FFModuleBaseInfo* T[] = {
(void*) &instance.config.modules.terminalTheme,
(void*) &instance.config.modules.title,
(void*) &instance.config.modules.theme,
(void*) &instance.config.modules.tpm,
NULL,
};
+39 -6
View File
@@ -8,6 +8,43 @@
enum { FF_PIPE_BUFSIZ = 8192 };
static void argvToCmdline(char* const argv[], FFstrbuf* result)
{
// From https://gist.github.com/jin-x/cdd641d98887524b091fb1f82a68717d
FF_STRBUF_AUTO_DESTROY temp = ffStrbufCreate();
for (int i = 0; argv[i] != NULL; i++)
{
ffStrbufSetS(&temp, argv[i]);
// Add slash (\) before double quotes (") and duplicate slashes before it
for (
uint32_t pos = ffStrbufFirstIndexC(&temp, '"'), cnt;
pos != temp.length;
pos = ffStrbufNextIndexC(&temp, pos + cnt * 2, '"')
) {
cnt = 1;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
ffStrbufInsertNC(&temp, pos, cnt, '\\');
}
// Add quotes around string if whitespace chars are present (with slash duplicating at the end of string)
if (ffStrbufFirstIndexS(&temp, " \t") != temp.length)
{
uint32_t pos = temp.length;
uint32_t cnt = 0;
while (pos > 0 && temp.chars[pos - 1] == '\\') { ++cnt, --pos; }
if (cnt > 0) ffStrbufAppendNC(&temp, cnt, '\\');
ffStrbufPrependC(&temp, '"');
ffStrbufAppendC(&temp, '"');
}
// Add space delimiter
if (i > 0) ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, &temp);
ffStrbufClear(&temp);
}
}
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
{
int timeout = instance.config.general.processingTimeout;
@@ -55,12 +92,8 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
else
siStartInfo.hStdOutput = hChildPipeWrite;
FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]);
for(char* const* parg = &argv[1]; *parg; ++parg)
{
ffStrbufAppendC(&cmdline, ' ');
ffStrbufAppendS(&cmdline, *parg);
}
FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreate();
argvToCmdline(argv, &cmdline);
success = CreateProcessA(
NULL, // application name
+1 -1
View File
@@ -1379,7 +1379,7 @@
{
"long": "command-param",
"desc": "Set the parameter used when starting the shell",
"remark": "Due to the difference of how OSes handle command line parameters, Windows will parse whitespaces as param separators, while *nix will not",
"remark": "If set to empty string, it will be ignored",
"arg": {
"type": "str",
"default": "\"/c\" for Windows; \"-c\" for *nix"
+1 -1
View File
@@ -1,7 +1,7 @@
#include "fastfetch.h"
#include "battery.h"
#include "util/apple/cf_helpers.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/smc_temps.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/pwr_mgt/IOPM.h>
-1
View File
@@ -1,6 +1,5 @@
#include "battery.h"
#include "common/io/io.h"
#include "detection/temps/temps_linux.h"
#include "util/stringUtils.h"
#include <dirent.h>
+1 -1
View File
@@ -38,7 +38,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
uint8_t buffer[2048];
wchar_t key[16];
wsprintfW(key, L"Boot%04X", value);
swprintf(key, sizeof(key) / sizeof(*key), L"Boot%04X", value);
uint32_t size = GetFirmwareEnvironmentVariableW(key, L"{" FF_EFI_GLOBAL_GUID L"}", buffer, sizeof(buffer));
if (size < sizeof(FFEfiLoadOption) || size == sizeof(buffer))
return "GetFirmwareEnvironmentVariableW(Boot####) failed";
-1
View File
@@ -21,7 +21,6 @@ typedef struct FFCPUResult
uint32_t frequencyBase; // GHz
uint32_t frequencyMax; // GHz
uint32_t frequencyBiosLimit; // GHz
FFCPUCore coreTypes[16]; // number of P cores, E cores, etc.
+1 -1
View File
@@ -1,6 +1,6 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/smc_temps.h"
#include "util/stringUtils.h"
static double detectCpuTemp(const FFstrbuf* cpuName)
+24 -3
View File
@@ -1,6 +1,27 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "detection/temps/temps_bsd.h"
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
static const char* detectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
@@ -46,8 +67,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if (options->temp)
{
if (ffDetectCpuTemp(&cpu->temperature) != NULL)
ffDetectThermalTemp(&cpu->temperature);
if (detectCpuTemp(&cpu->temperature) != NULL)
detectThermalTemp(&cpu->temperature);
}
return NULL;
+88 -25
View File
@@ -2,13 +2,85 @@
#include "common/io/io.h"
#include "common/processing.h"
#include "common/properties.h"
#include "detection/temps/temps_linux.h"
#include "util/mallocHelper.h"
#include "util/stringUtils.h"
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
{
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
uint32_t dirLength = dir->length;
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, buffer))
{
// Some badly implemented system put temp file in /hwmonN/device
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/");
dirLength = dir->length;
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, buffer))
return 0.0/0.0;
}
ffStrbufSubstrBefore(dir, dirLength);
double value = ffStrbufToDouble(buffer);// millidegree Celsius
if(value != value)
return 0.0/0.0;
ffStrbufAppendS(dir, "name");
if (!ffReadFileBuffer(dir->chars, buffer))
return 0.0/0.0;
ffStrbufTrimRightSpace(buffer);
if(
ffStrbufContainS(buffer, "cpu") ||
ffStrbufEqualS(buffer, "k10temp") || // AMD
ffStrbufEqualS(buffer, "coretemp") // Intel
) return value / 1000.;
return false;
}
static double detectCPUTemp(void)
{
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return 0.0/0.0;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&baseDir, entry->d_name);
ffStrbufAppendC(&baseDir, '/');
double result = parseHwmonDir(&baseDir, &buffer);
if (result == result)
return result;
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return 0.0/0.0;
}
#ifdef __ANDROID__
#include "common/settings.h"
@@ -253,18 +325,25 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
if (ffStrStartsWith(entry->d_name, "policy") && ffCharIsDigit(entry->d_name[strlen("policy")]))
{
ffStrbufAppendS(&path, entry->d_name);
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax == 0) continue;
if (cpu->frequencyMax >= fmax)
{
if (!options->showPeCoreCount)
{
ffStrbufSubstrBefore(&path, baseLen);
continue;
}
}
else
cpu->frequencyMax = fmax;
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase > 0)
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
uint32_t fbioslimit = getFrequency(&path, "/bios_limit", NULL, &buffer);
if (fbioslimit > 0)
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax > 0)
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
if (options->showPeCoreCount)
{
uint32_t freq = fbase == 0 ? fmax : fbase; // seems base frequencies are more stable
@@ -281,22 +360,6 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
return true;
}
static double detectCPUTemp(void)
{
const FFlist* tempsResult = ffDetectTemps();
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
{
if(
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
ffStrbufEqualS(&value->name, "k10temp") ||
ffStrbufEqualS(&value->name, "coretemp")
) return value->value;
}
return FF_CPU_TEMP_UNSET;
}
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
{
// Always use the last part of the ISA string. Ref: #590 #1204
+3 -2
View File
@@ -1,5 +1,4 @@
#include "cpu.h"
#include "detection/temps/temps_windows.h"
#include "util/windows/registry.h"
#include "util/windows/nt.h"
#include "util/mallocHelper.h"
@@ -160,6 +159,8 @@ static const char* detectCoreTypes(FFCPUResult* cpu)
return NULL;
}
const char* detectThermalTemp(double* current, double* critical);
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
detectNCores(cpu);
@@ -175,7 +176,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectMaxSpeedBySmbios(cpu);
if(options->temp)
ffDetectSmbiosTemp(&cpu->temperature, NULL);
detectThermalTemp(&cpu->temperature, NULL);
return NULL;
}
@@ -1,11 +1,7 @@
extern "C"
{
#include "temps_windows.h"
}
#include "util/windows/wmi.hpp"
extern "C"
const char* ffDetectSmbiosTemp(double* current, double* critical)
const char* detectThermalTemp(double* current, double* critical)
{
// Requires Administrator privileges
// https://wutils.com/wmi/root/wmi/msacpi_thermalzonetemperature/#properties
+7 -7
View File
@@ -4,10 +4,10 @@
static void appendColor(FFstrbuf* str, NSDictionary* color)
{
int r = (int) (((NSNumber*) [color valueForKey:@"red"]).doubleValue * 255);
int g = (int) (((NSNumber*) [color valueForKey:@"green"]).doubleValue * 255);
int b = (int) (((NSNumber*) [color valueForKey:@"blue"]).doubleValue * 255);
int a = (int) (((NSNumber*) [color valueForKey:@"alpha"]).doubleValue * 255);
int r = (int) (((NSNumber*) color[@"red"]).doubleValue * 255);
int g = (int) (((NSNumber*) color[@"green"]).doubleValue * 255);
int b = (int) (((NSNumber*) color[@"blue"]).doubleValue * 255);
int a = (int) (((NSNumber*) color[@"alpha"]).doubleValue * 255);
if (r == 255 && g == 255 && b == 255 && a == 255)
ffStrbufAppendS(str, "White");
@@ -32,19 +32,19 @@ void ffDetectCursor(FFCursorResult* result)
NSDictionary* color;
ffStrbufAppendS(&result->theme, "Fill - ");
if ((color = [dict valueForKey:@"cursorFill"]))
if ((color = dict[@"cursorFill"]))
appendColor(&result->theme, color);
else
ffStrbufAppendS(&result->theme, "Black");
ffStrbufAppendS(&result->theme, ", Outline - ");
if ((color = [dict valueForKey:@"cursorOutline"]))
if ((color = dict[@"cursorOutline"]))
appendColor(&result->theme, color);
else
ffStrbufAppendS(&result->theme, "White");
NSNumber* mouseDriverCursorSize = [dict valueForKey:@"mouseDriverCursorSize"];
NSNumber* mouseDriverCursorSize = dict[@"mouseDriverCursorSize"];
if (mouseDriverCursorSize)
ffStrbufAppendF(&result->size, "%d", (int) (mouseDriverCursorSize.doubleValue * 32));
else
+12 -6
View File
@@ -28,13 +28,19 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
ffStrbufAppendS(&drmDir, "/status");
char status = 'd'; // disconnected
ffReadFileData(drmDir.chars, sizeof(status), &status);
if (status != 'c') // connected
{
char buf;
ffStrbufAppendS(&drmDir, "/enabled");
if (!ffReadFileData(drmDir.chars, sizeof(buf), &buf) || buf != 'e') {
/* read failed or enabled != "enabled" */
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
ffStrbufAppendS(&drmDir, "/status");
buf = 'd';
ffReadFileData(drmDir.chars, sizeof(buf), &buf);
if (buf != 'c') {
/* read failed or status != "connected" */
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
}
}
unsigned width = 0, height = 0, physicalWidth = 0, physicalHeight = 0;
@@ -251,7 +257,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;
+1
View File
@@ -55,6 +55,7 @@ const char* detectByOpenGL(FFlist* gpus)
ffStrbufInitMove(&gpu->name, &result.renderer);
ffStrbufInitMove(&gpu->driver, &result.vendor);
ffStrbufInitF(&gpu->platformApi, "OpenGL %s", result.version.chars);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
+4 -2
View File
@@ -7,6 +7,7 @@
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t)-1)
#define FF_GPU_FREQUENCY_UNSET 0
#define FF_GPU_CORE_USAGE_UNSET (0/0.0)
#define FF_GPU_INDEX_UNSET ((uint32_t)-1)
extern const char* FF_GPU_VENDOR_NAME_APPLE;
extern const char* FF_GPU_VENDOR_NAME_AMD;
@@ -27,6 +28,7 @@ typedef struct FFGPUMemory
typedef struct FFGPUResult
{
uint32_t index;
FFGPUType type;
FFstrbuf vendor;
FFstrbuf name;
@@ -38,7 +40,7 @@ typedef struct FFGPUResult
uint32_t frequency; // Maximum time clock frequency in MHz
FFGPUMemory dedicated;
FFGPUMemory shared;
uint64_t deviceId; // Used internally, may be uninitialized
uint64_t deviceId;
} FFGPUResult;
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
@@ -47,5 +49,5 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
const char* ffGetGPUVendorString(unsigned vendorId);
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName);
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
#endif
+6
View File
@@ -65,5 +65,11 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
if (result.type)
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
if (result.index)
*result.type = (uint32_t) device->adlAdapterIndex;
if (result.name)
ffStrbufSetS(result.name, device->adapterString);
return NULL;
}
+4 -1
View File
@@ -1,12 +1,13 @@
#include "gpu.h"
#include "common/library.h"
#include "detection/cpu/cpu.h"
#include "detection/temps/temps_apple.h"
#include "util/apple/cf_helpers.h"
#include "util/apple/smc_temps.h"
#include <IOKit/graphics/IOGraphicsLib.h>
const char* ffGpuDetectMetal(FFlist* gpus);
const char* ffGpuDetectDriverVersion(FFlist* gpus);
static double detectGpuTemp(const FFstrbuf* gpuName)
{
@@ -185,5 +186,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
}
ffGpuDetectMetal(gpus);
if (instance.config.general.detectVersion)
ffGpuDetectDriverVersion(gpus);
return NULL;
}
+25 -1
View File
@@ -1,6 +1,7 @@
#include "gpu.h"
#import <Metal/MTLDevice.h>
#import <IOKit/kext/KextManager.h>
#ifndef MAC_OS_VERSION_13_0
#define MTLGPUFamilyMetal3 ((MTLGPUFamily) 5001)
@@ -10,6 +11,28 @@
#define MTLFeatureSet_macOS_GPUFamily2_v1 ((MTLFeatureSet) 10005)
#endif
const char* ffGpuDetectDriverVersion(FFlist* gpus)
{
if (@available(macOS 10.7, *))
{
NSMutableArray* arr = NSMutableArray.new;
FF_LIST_FOR_EACH(FFGPUResult, x, *gpus)
[arr addObject:@(x->driver.chars)];
NSDictionary* dict = CFBridgingRelease(KextManagerCopyLoadedKextInfo((__bridge CFArrayRef)arr, (__bridge CFArrayRef)@[@"CFBundleVersion"]));
FF_LIST_FOR_EACH(FFGPUResult, x, *gpus)
{
NSString* version = dict[@(x->driver.chars)][@"CFBundleVersion"];
if (version)
{
ffStrbufAppendC(&x->driver, ' ');
ffStrbufAppendS(&x->driver, version.UTF8String);
}
}
}
return "Unsupported macOS version";
}
const char* ffGpuDetectMetal(FFlist* gpus)
{
if (@available(macOS 10.13, *))
@@ -42,7 +65,8 @@ const char* ffGpuDetectMetal(FFlist* gpus)
else if ([device supportsFamily:MTLGPUFamilyCommon1])
ffStrbufSetStatic(&gpu->platformApi, "Metal Common 1");
gpu->type = device.hasUnifiedMemory ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
gpu->type = device.location == MTLDeviceLocationBuiltIn ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
gpu->index = (uint32_t) device.locationNumber;
#endif
}
return NULL;
+91
View File
@@ -0,0 +1,91 @@
#if __aarch64__ && FF_HAVE_DRM
#include <drm.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#if __has_include(<drm/asahi_drm.h>)
#include <drm/asahi_drm.h>
#else
// https://github.com/AsahiLinux/linux/blob/asahi/include/uapi/drm/asahi_drm.h
/* SPDX-License-Identifier: MIT */
/* Copyright (C) The Asahi Linux Contributors */
#define DRM_ASAHI_UNSTABLE_UABI_VERSION 10011
#define DRM_ASAHI_GET_PARAMS 0x00
#define DRM_ASAHI_MAX_CLUSTERS 32
struct drm_asahi_params_global
{
__u32 unstable_uabi_version;
__u32 pad0;
__u64 feat_compat;
__u64 feat_incompat;
__u32 gpu_generation;
__u32 gpu_variant;
__u32 gpu_revision;
__u32 chip_id;
__u32 num_dies;
__u32 num_clusters_total;
__u32 num_cores_per_cluster;
__u32 num_frags_per_cluster;
__u32 num_gps_per_cluster;
__u32 num_cores_total_active;
__u64 core_masks[DRM_ASAHI_MAX_CLUSTERS];
__u32 vm_page_size;
__u32 pad1;
__u64 vm_user_start;
__u64 vm_user_end;
__u64 vm_usc_start;
__u64 vm_usc_end;
__u64 vm_kernel_min_size;
__u32 max_syncs_per_submission;
__u32 max_commands_per_submission;
__u32 max_commands_in_flight;
__u32 max_attachments;
__u32 timer_frequency_hz;
__u32 min_frequency_khz;
__u32 max_frequency_khz;
__u32 max_power_mw;
__u32 result_render_size;
__u32 result_compute_size;
__u32 firmware_version[4];
};
struct drm_asahi_get_params
{
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
/** @param: Parameter group to fetch (MBZ) */
__u32 param_group;
/** @pad: MBZ */
__u32 pad;
/** @value: User pointer to write parameter struct */
__u64 pointer;
/** @value: Size of user buffer, max size supported on return */
__u64 size;
};
enum
{
DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
};
#endif // __has_include
#endif // FF_HAVE_DRM
+18 -39
View File
@@ -8,20 +8,6 @@
#include <dev/pci/pcireg.h>
#include <sys/pciio.h>
#include <fcntl.h>
#include <paths.h>
static bool loadPciIds(FFstrbuf* pciids)
{
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/pciids/pci.ids", pciids);
if (pciids->length > 0) return true;
return false;
}
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
@@ -45,8 +31,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
if (pcio.status == PCI_GETCONF_ERROR)
return "ioctl(fd, PCIOCGETCONF, &pc) returned error";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
for (uint32_t i = 0; i < pcio.num_matches; ++i)
{
struct pci_conf* pc = &confs[i];
@@ -56,29 +40,15 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
ffStrbufInit(&gpu->name);
ffStrbufInitS(&gpu->driver, pc->pd_name);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pc->pc_sel.pc_domain << 6) | ((uint64_t) pc->pc_sel.pc_bus << 4) | ((uint64_t) pc->pc_sel.pc_dev << 2) | pc->pc_sel.pc_func;
gpu->deviceId = (pc->pc_sel.pc_domain * 100000ull) + (pc->pc_sel.pc_bus * 1000ull) + (pc->pc_sel.pc_dev * 10ull) + pc->pc_sel.pc_func;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) pc->pc_device, (unsigned) pc->pc_revid);
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
}
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
if (gpu->name.length == 0)
{
if (pciids.length == 0)
loadPciIds(&pciids);
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu, &coreName);
}
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
{
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
@@ -90,16 +60,29 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
.func = pc->pc_sel.pc_func,
},
}, (FFGpuDriverResult) {
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
.coreUsage = &gpu->coreUsage,
.name = options->driverSpecific ? &gpu->name : NULL,
.name = &gpu->name,
}, "libnvidia-ml.so");
}
if (gpu->name.length == 0)
{
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) pc->pc_device, (unsigned) pc->pc_revid);
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
}
if (gpu->name.length == 0)
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
}
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
{
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
@@ -116,12 +99,8 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
if ((coreName.chars[0] == 'D' || coreName.chars[0] == 'S') &&
coreName.chars[1] == 'G' &&
ffCharIsDigit(coreName.chars[2]))
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
else
gpu->type = FF_GPU_TYPE_INTEGRATED;
// 0000:00:02.0 is reserved for Intel integrated graphics
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
}
}
}
+1
View File
@@ -37,6 +37,7 @@ typedef struct FFGpuDriverCondition
// detect x if not NULL
typedef struct FFGpuDriverResult
{
uint32_t* index;
double* temp;
FFGPUMemory* memory;
uint32_t* coreCount;
+3
View File
@@ -195,5 +195,8 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
}
if (result.name)
ffStrbufSetS(result.name, properties.name);
return NULL;
}
+412 -197
View File
@@ -1,100 +1,33 @@
#include "detection/gpu/gpu.h"
#include "detection/vulkan/vulkan.h"
#include "detection/temps/temps_linux.h"
#include "detection/cpu/cpu.h"
#include "detection/gpu/gpu_driver_specific.h"
#include "common/io/io.h"
#include "common/library.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <inttypes.h>
#if __aarch64__ && FF_HAVE_DRM
#include <drm.h>
#ifdef FF_HAVE_DRM_AMDGPU
#include <amdgpu.h>
#include <amdgpu_drm.h>
#include <fcntl.h>
#endif
#ifdef FF_HAVE_DRM
#include "intel_drm.h"
#include <fcntl.h>
#include <sys/ioctl.h>
// https://github.com/AsahiLinux/linux/blob/asahi/include/uapi/drm/asahi_drm.h
/* SPDX-License-Identifier: MIT */
/* Copyright (C) The Asahi Linux Contributors */
#define DRM_ASAHI_UNSTABLE_UABI_VERSION 10011
#define DRM_ASAHI_GET_PARAMS 0x00
#define DRM_ASAHI_MAX_CLUSTERS 32
struct drm_asahi_params_global
{
__u32 unstable_uabi_version;
__u32 pad0;
__u64 feat_compat;
__u64 feat_incompat;
__u32 gpu_generation;
__u32 gpu_variant;
__u32 gpu_revision;
__u32 chip_id;
__u32 num_dies;
__u32 num_clusters_total;
__u32 num_cores_per_cluster;
__u32 num_frags_per_cluster;
__u32 num_gps_per_cluster;
__u32 num_cores_total_active;
__u64 core_masks[DRM_ASAHI_MAX_CLUSTERS];
__u32 vm_page_size;
__u32 pad1;
__u64 vm_user_start;
__u64 vm_user_end;
__u64 vm_usc_start;
__u64 vm_usc_end;
__u64 vm_kernel_min_size;
__u32 max_syncs_per_submission;
__u32 max_commands_per_submission;
__u32 max_commands_in_flight;
__u32 max_attachments;
__u32 timer_frequency_hz;
__u32 min_frequency_khz;
__u32 max_frequency_khz;
__u32 max_power_mw;
__u32 result_render_size;
__u32 result_compute_size;
__u32 firmware_version[4];
};
struct drm_asahi_get_params
{
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;
/** @param: Parameter group to fetch (MBZ) */
__u32 param_group;
/** @pad: MBZ */
__u32 pad;
/** @value: User pointer to write parameter struct */
__u64 pointer;
/** @value: Size of user buffer, max size supported on return */
__u64 size;
};
enum
{
DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
};
#endif
#include "gpu_asahi.h"
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
static bool pciDetectDriver(FFstrbuf* result, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
{
uint32_t pciDirLength = pciDir->length;
ffStrbufAppendS(pciDir, "/driver");
@@ -106,17 +39,17 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
if (slash)
{
slash++;
ffStrbufSetNS(&gpu->driver, (uint32_t) (resultLength - (slash - pathBuf)), slash);
ffStrbufSetNS(result, (uint32_t) (resultLength - (slash - pathBuf)), slash);
}
if (ffStrbufEqualS(&gpu->driver, "nvidia"))
if (ffStrbufEqualS(result, "nvidia"))
{
if (ffReadFileBuffer("/proc/driver/nvidia/version", buffer))
{
if (ffStrbufContainS(buffer, " Open "))
ffStrbufAppendS(&gpu->driver, " (open source)");
ffStrbufAppendS(result, " (open source)");
else
ffStrbufAppendS(&gpu->driver, " (proprietary)");
ffStrbufAppendS(result, " (proprietary)");
}
}
@@ -126,18 +59,18 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
if (ffReadFileBuffer(pciDir->chars, buffer))
{
ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppend(&gpu->driver, buffer);
ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, buffer);
}
else if (ffStrbufEqualS(&gpu->driver, "zx"))
else if (ffStrbufEqualS(result, "zx"))
{
ffStrbufSubstrBefore(pciDir, pciDirLength);
ffStrbufAppendS(pciDir, "/zx_info/driver_version");
if (ffReadFileBuffer(pciDir->chars, buffer))
{
ffStrbufTrimRightSpace(buffer);
ffStrbufAppendC(&gpu->driver, ' ');
ffStrbufAppend(&gpu->driver, buffer);
ffStrbufAppendC(result, ' ');
ffStrbufAppend(result, buffer);
}
}
}
@@ -145,6 +78,98 @@ static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer
return true;
}
static const char* drmFindRenderFromCard(const char* drmCardKey, FFstrbuf* result)
{
char path[PATH_MAX];
sprintf(path, "/sys/class/drm/%s/device/drm", drmCardKey);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path);
if (!dirp) return "Failed to open `/sys/class/drm/{drmCardKey}/device/drm`";
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "render"))
{
ffStrbufSetS(result, "/dev/dri/");
ffStrbufAppendS(result, entry->d_name);
return NULL;
}
}
return "Failed to find render device";
}
static const char* drmDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, const char* drmKey, FFstrbuf* buffer)
{
#if FF_HAVE_DRM_AMDGPU
FF_LIBRARY_LOAD(libdrm, "dlopen libdrm_amdgpu" FF_LIBRARY_EXTENSION " failed", "libdrm_amdgpu" FF_LIBRARY_EXTENSION, 1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_device_initialize)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_get_marketing_name)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_gpu_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_sensor_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_query_heap_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, amdgpu_device_deinitialize)
{
const char* error = drmFindRenderFromCard(drmKey, buffer);
if (error) return error;
}
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd < 0) return "Failed to open DRM device";
amdgpu_device_handle handle;
uint32_t majorVersion, minorVersion;
if (ffamdgpu_device_initialize(fd, &majorVersion, &minorVersion, &handle) < 0)
return "Failed to initialize AMDGPU device";
ffStrbufAppendF(&gpu->driver, " %u.%u", (unsigned) majorVersion, (unsigned) minorVersion);
uint32_t value;
if (options->temp)
{
if (ffamdgpu_query_sensor_info(handle, AMDGPU_INFO_SENSOR_GPU_TEMP, sizeof(value), &value) >= 0)
gpu->temperature = value / 1000.;
}
ffStrbufSetS(&gpu->name, ffamdgpu_get_marketing_name(handle));
struct amdgpu_gpu_info gpuInfo;
if (ffamdgpu_query_gpu_info(handle, &gpuInfo) >= 0)
{
gpu->coreCount = (int32_t) gpuInfo.cu_active_number;
gpu->frequency = (uint32_t) (gpuInfo.max_engine_clk / 1000u);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->type = gpuInfo.ids_flags & AMDGPU_IDS_FLAGS_FUSION ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
struct amdgpu_heap_info heapInfo;
if (ffamdgpu_query_heap_info(handle, AMDGPU_GEM_DOMAIN_VRAM, 0, &heapInfo) >= 0)
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
{
gpu->dedicated.total = heapInfo.heap_size;
gpu->dedicated.used = heapInfo.heap_usage;
}
else
{
gpu->shared.total = heapInfo.heap_size;
gpu->shared.used = heapInfo.heap_usage;
}
}
}
if (ffamdgpu_query_sensor_info(handle, AMDGPU_INFO_SENSOR_GPU_LOAD, sizeof(value), &value) >= 0)
gpu->coreUsage = value;
ffamdgpu_device_deinitialize(handle);
return NULL;
#else
FF_UNUSED(options, gpu, drmKey, buffer);
return "Fastfetch is compiled without libdrm support";
#endif
}
static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
{
// https://www.kernel.org/doc/html/v5.10/gpu/amdgpu.html#mem-info-vis-vram-total
@@ -186,6 +211,11 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_total");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
{
if (gpu->type == FF_GPU_TYPE_DISCRETE)
gpu->dedicated.total = value;
else
gpu->shared.total = value;
ffStrbufSubstrBefore(pciDir, pciDir->length - (uint32_t) strlen("/mem_info_vis_vram_total"));
ffStrbufAppendS(pciDir, "/mem_info_vis_vram_used");
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
@@ -199,61 +229,174 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
}
}
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const FFstrbuf* coreName)
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey)
{
// Works for Intel GPUs
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
if ((coreName->chars[0] == 'D' || coreName->chars[0] == 'S') &&
coreName->chars[1] == 'G' &&
ffCharIsDigit(coreName->chars[2]))
gpu->type = FF_GPU_TYPE_DISCRETE; // DG1 / DG2 / SG1
else
gpu->type = FF_GPU_TYPE_INTEGRATED;
// 0000:00:02.0 is reserved for Intel integrated graphics
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
if (!drmKey) return;
if (ffStrbufEqualS(&gpu->driver, "xe"))
{
ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq");
}
else
{
ffStrbufAppendS(pciDir, "/drm/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "card")) break;
}
if (!entry) return;
ffStrbufAppendS(pciDir, entry->d_name);
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
}
ffStrbufAppendF(pciDir, "/drm/%s/gt_max_freq_mhz", drmKey);
if (ffReadFileBuffer(pciDir->chars, buffer))
gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0);
}
static bool loadPciIds(FFstrbuf* pciids)
static inline int popcountBytes(uint8_t* bytes, uint32_t length)
{
#ifdef FF_CUSTOM_PCI_IDS_PATH
int count = 0;
while (length >= 8)
{
count += __builtin_popcountll(*(uint64_t*) bytes);
bytes += 8;
length -= 8;
}
if (length >= 4)
{
count += __builtin_popcountl(*(uint32_t*) bytes);
bytes += 4;
length -= 4;
}
if (length >= 2)
{
count += __builtin_popcountl(*(uint16_t*) bytes);
bytes += 2;
length -= 2;
}
if (length)
{
count += __builtin_popcountl(*(uint8_t*) bytes);
}
return count;
}
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), pciids);
if (pciids->length > 0) return true;
static const char* drmDetectIntelSpecific(FFGPUResult* gpu, const char* drmKey, FFstrbuf* buffer)
{
#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd < 0) return "Failed to open drm device";
if (ffStrbufEqualS(&gpu->driver, "xe"))
{
{
struct drm_xe_device_query query = {
.extensions = 0,
.query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY,
.size = 0,
.data = 0,
};
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
FF_AUTO_FREE uint8_t* buffer = malloc(query.size);
query.data = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
int dssCount = 0, euPerDssCount = 0;
for (struct drm_xe_query_topology_mask* topo = (void*) buffer;
(uint8_t*) topo < buffer + query.size;
topo = (void*) (topo->mask + topo->num_bytes)
) {
switch (topo->type)
{
case DRM_XE_TOPO_DSS_COMPUTE:
case DRM_XE_TOPO_DSS_GEOMETRY:
dssCount += popcountBytes(topo->mask, topo->num_bytes);
break;
case DRM_XE_TOPO_EU_PER_DSS:
euPerDssCount += popcountBytes(topo->mask, topo->num_bytes);
break;
}
}
gpu->coreCount = dssCount * euPerDssCount;
}
}
}
{
struct drm_xe_device_query query = {
.query = DRM_XE_DEVICE_QUERY_MEM_REGIONS,
};
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
FF_AUTO_FREE uint8_t* buffer = malloc(query.size);
query.data = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0)
{
gpu->dedicated.total = gpu->shared.total = gpu->dedicated.used = gpu->shared.used = 0;
struct drm_xe_query_mem_regions* regionInfo = (void*) buffer;
for (uint32_t i = 0; i < regionInfo->num_mem_regions; i++)
{
struct drm_xe_mem_region* region = regionInfo->mem_regions + i;
switch (region->mem_class)
{
case DRM_XE_MEM_REGION_CLASS_SYSMEM:
gpu->shared.total += region->total_size;
gpu->shared.used += region->used;
break;
case DRM_XE_MEM_REGION_CLASS_VRAM:
gpu->dedicated.total += region->total_size;
gpu->dedicated.used += region->used;
break;
}
}
}
}
}
}
else if (ffStrbufEqualS(&gpu->driver, "i915"))
{
{
int value;
drm_i915_getparam_t getparam = { .param = I915_PARAM_EU_TOTAL, .value = &value };
if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &getparam) >= 0)
gpu->coreCount = value;
}
{
struct drm_i915_query_item queryItem = {
.query_id = DRM_I915_QUERY_MEMORY_REGIONS,
};
struct drm_i915_query query = {
.items_ptr = (uintptr_t) &queryItem,
.num_items = 1,
};
if (ioctl(fd, DRM_IOCTL_I915_QUERY, &query) >= 0 )
{
FF_AUTO_FREE uint8_t* buffer = calloc(1, (size_t) queryItem.length);
queryItem.data_ptr = (uintptr_t) buffer;
if (ioctl(fd, DRM_IOCTL_I915_QUERY, &query) >= 0)
{
gpu->dedicated.total = gpu->shared.total = gpu->dedicated.used = gpu->shared.used = 0;
struct drm_i915_query_memory_regions* regionInfo = (void*) buffer;
for (uint32_t i = 0; i < regionInfo->num_regions; i++)
{
struct drm_i915_memory_region_info* region = regionInfo->regions + i;
switch (region->region.memory_class)
{
case I915_MEMORY_CLASS_SYSTEM:
gpu->shared.total += region->probed_size;
gpu->shared.used += region->probed_size - region->unallocated_size;
break;
case I915_MEMORY_CLASS_DEVICE:
gpu->dedicated.total += region->probed_size;
gpu->dedicated.used += region->probed_size - region->unallocated_size;
break;
}
}
}
}
}
}
return NULL;
#else
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", pciids); // debian?
if (pciids->length > 0) return true;
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", pciids);
if (pciids->length > 0) return true;
return "Fastfetch is not compiled with drm support";
#endif
return false;
}
static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf* buffer, FFstrbuf* deviceDir, const char* drmKey)
@@ -262,7 +405,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
uint32_t vendorId, deviceId, subVendorId, subDeviceId;
uint8_t classId, subclassId;
if (sscanf(buffer->chars + strlen("pci:"), "v%8" SCNx32 "d%8" SCNx32 "sv%8" SCNx32 "sd%8" SCNx32 "bc%2" SCNx8 "sc%2" SCNx8, &vendorId, &deviceId, &subVendorId, &subDeviceId, &classId, &subclassId) != 6)
return "Invalid modalias string";
return "Failed to parse pci modalias";
if (classId != 0x03 /*PCI_BASE_CLASS_DISPLAY*/)
return "Not a GPU device";
@@ -295,61 +438,78 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
gpu->deviceId = ((uint64_t) pciDomain << 6) | ((uint64_t) pciBus << 4) | (deviceId << 2) | pciFunc;
gpu->deviceId = (pciDomain * 100000ull) + (pciBus * 1000ull) + (pciDevice * 10ull) + pciFunc;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
if (drmKey) ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
char drmKeyBuffer[8];
if (!drmKey)
{
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer))
ffStrbufAppendS(deviceDir, "/drm");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(deviceDir->chars);
if (dirp)
{
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars)
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
#else
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
#endif
if (ffStrStartsWith(entry->d_name, "card"))
{
strncpy(drmKeyBuffer, entry->d_name, sizeof(drmKeyBuffer) - 1);
drmKeyBuffer[sizeof(drmKeyBuffer) - 1] = '\0';
drmKey = drmKeyBuffer;
break;
}
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
if (gpu->name.length == 0)
{
static FFstrbuf pciids;
if (pciids.chars == NULL)
{
ffStrbufInit(&pciids);
loadPciIds(&pciids);
}
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu, &coreName);
}
if (drmKey) ffStrbufSetF(&gpu->platformApi, "DRM (%s)", drmKey);
pciDetectDriver(gpu, deviceDir, buffer, drmKey);
pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
{
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
bool ok = false;
if (drmKey && options->driverSpecific)
ok = drmDetectAmdSpecific(options, gpu, drmKey, buffer) == NULL;
if (!ok)
{
pciDetectAmdSpecific(options, gpu, deviceDir, buffer);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
ffStrbufAppendS(deviceDir, "/revision");
if (ffReadFileBuffer(deviceDir->chars, buffer))
{
char* pend;
uint64_t revision = strtoul(buffer->chars, &pend, 16);
if (pend != buffer->chars)
{
char query[32];
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
#ifdef FF_CUSTOM_AMDGPU_IDS_PATH
ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name);
#else
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
#endif
}
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
pciDetectIntelSpecific(gpu, deviceDir, buffer, &coreName);
pciDetectIntelSpecific(gpu, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (options->driverSpecific && drmKey)
drmDetectIntelSpecific(gpu, drmKey, buffer);
}
else
{
@@ -366,13 +526,14 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
.func = pciFunc,
},
}, (FFGpuDriverResult) {
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
.name = options->driverSpecific ? &gpu->name : NULL,
.name = &gpu->name,
}, soName);
}
@@ -393,23 +554,92 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
}
}
if (gpu->name.length == 0)
ffGPUFillVendorAndName(subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
return NULL;
}
#if __aarch64__
FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
FF_MAYBE_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FFstrbuf* buffer, const char* drmKey)
{
uint32_t index = ffStrbufFirstIndexS(buffer, "apple,agx-t");
if (index == buffer->length) return "display-subsystem?";
index += (uint32_t) strlen("apple,agx-t");
if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1)
ffStrbufSetStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
#if FF_HAVE_DRM
ffStrbufSetS(buffer, "/dev/dri/");
ffStrbufAppendS(buffer, drmKey);
FF_AUTO_CLOSE_FD int fd = open(buffer->chars, O_RDONLY);
if (fd >= 0)
{
struct drm_asahi_params_global paramsGlobal = {};
if (ioctl(fd, DRM_IOCTL_ASAHI_GET_PARAMS, &(struct drm_asahi_get_params) {
.param_group = DRM_ASAHI_GET_PARAMS,
.pointer = (uint64_t) &paramsGlobal,
.size = sizeof(paramsGlobal),
}) >= 0)
{
ffStrbufAppendF(&gpu->driver, " %u", paramsGlobal.unstable_uabi_version);
// FIXME: They will introduce ABI breaking changes. Always check the latest version
// https://www.reddit.com/r/AsahiLinux/comments/1ei2qiv/comment/lgm0v5s/
if (paramsGlobal.unstable_uabi_version == DRM_ASAHI_UNSTABLE_UABI_VERSION)
{
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
gpu->deviceId = paramsGlobal.chip_id;
if (!gpu->name.length)
{
const char* variant = " Unknown";
switch (paramsGlobal.gpu_variant) {
case 'G':
variant = "";
break;
case 'S':
variant = " Pro";
break;
case 'C':
variant = " Max";
break;
case 'D':
variant = " Ultra";
break;
}
ffStrbufSetF(&gpu->name, "Apple M%d%s (G%d%c %02X)",
paramsGlobal.gpu_generation - 12, variant,
paramsGlobal.gpu_generation, paramsGlobal.gpu_variant,
paramsGlobal.gpu_revision + 0xA0);
}
}
}
}
#endif
return NULL;
}
#endif
static const char* detectOf(FFlist* gpus, FFstrbuf* buffer, FFstrbuf* drmDir, const char* drmKey)
{
char compatible[256]; // vendor,model-name
if (sscanf(buffer->chars + strlen("of:"), "NgpuT%*[^C]C%256[^C]", compatible) != 1)
return "Failed to parse of modalias or not a GPU device";
char* name = strchr(compatible, ',');
if (name)
{
*name = '\0';
++name;
}
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
gpu->deviceId = strtoul(buffer->chars + index, NULL, 10);
ffStrbufInitStatic(&gpu->name, ffCPUAppleCodeToName((uint32_t) gpu->deviceId));
if (!gpu->name.length)
ffStrbufAppendF(&gpu->name, "Apple Silicon T%u", (uint32_t) gpu->deviceId);
ffStrbufInitStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_APPLE);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->deviceId = 0;
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInitF(&gpu->platformApi, "DRM (%s)", drmKey);
gpu->temperature = FF_GPU_TEMP_UNSET;
@@ -419,36 +649,23 @@ 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)
{
struct drm_asahi_params_global paramsGlobal = {};
if (ioctl(fd, DRM_IOCTL_ASAHI_GET_PARAMS, &(struct drm_asahi_get_params){
.param_group = DRM_ASAHI_GET_PARAMS,
.pointer = (uint64_t) &paramsGlobal,
.size = sizeof(paramsGlobal),
}) >= 0)
{
// 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;
}
}
}
#ifdef __aarch64__
if (ffStrbufEqualS(&gpu->driver, "asahi"))
drmDetectAsahiSpecific(gpu, name, buffer, drmKey);
#endif
if (!gpu->name.length)
ffStrbufSetS(&gpu->name, name ? name : compatible);
if (!gpu->vendor.length && name)
{
compatible[0] = (char) toupper(compatible[0]);
ffStrbufSetS(&gpu->vendor, compatible);
}
return NULL;
}
#endif
static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
{
@@ -478,10 +695,8 @@ static const char* drmDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
if (ffStrbufStartsWithS(&buffer, "pci:"))
detectPci(options, gpus, &buffer, &drmDir, entry->d_name);
#ifdef __aarch64__
else if (ffStrbufStartsWithS(&buffer, "of:"))
detectAsahi(gpus, &buffer, &drmDir, entry->d_name);
#endif
detectOf(gpus, &buffer, &drmDir, entry->d_name);
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
+8 -1
View File
@@ -30,7 +30,7 @@ struct FFMtmlData
MtmlSystem *sys;
} mtmlData;
static void shutdownMtml()
FF_MAYBE_UNUSED static void shutdownMtml(void)
{
mtmlData.ffmtmlLibraryShutDown(mtmlData.lib);
}
@@ -134,6 +134,13 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive
}
}
if (result.index)
{
unsigned int value;
if (mtmlData.ffmtmlDeviceGetIndex(device, &value) == MTML_SUCCESS)
*result.index = value;
}
if (result.temp)
{
MtmlGpu *gpu = NULL;
+10
View File
@@ -14,6 +14,7 @@ struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo)
FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates)
FF_LIBRARY_SYMBOL(nvmlDeviceGetBrand)
FF_LIBRARY_SYMBOL(nvmlDeviceGetIndex)
FF_LIBRARY_SYMBOL(nvmlDeviceGetName)
bool inited;
@@ -39,6 +40,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetBrand)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetIndex)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetName)
if (ffnvmlInit_v2() != NVML_SUCCESS)
@@ -105,6 +107,14 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
}
}
if (result.index)
{
unsigned int value;
if (nvmlData.ffnvmlDeviceGetIndex(device, &value) == NVML_SUCCESS)
*result.index = value;
}
if (result.temp)
{
uint32_t value;
+112 -6
View File
@@ -1,6 +1,54 @@
#include "gpu.h"
#include "common/io/io.h"
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName)
#include <stdlib.h>
#ifdef __FreeBSD__
#include <paths.h>
#endif
#if FF_HAVE_EMBEDDED_PCIIDS
#include "fastfetch_pciids.c.inc"
#endif
#define FF_STR_INDIR(x) #x
#define FF_STR(x) FF_STR_INDIR(x)
static const FFstrbuf* loadPciIds()
{
static FFstrbuf pciids;
if (pciids.chars) return &pciids;
ffStrbufInit(&pciids);
#ifdef FF_CUSTOM_PCI_IDS_PATH
ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), &pciids);
#else // FF_CUSTOM_PCI_IDS_PATH
#if __linux__
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", &pciids);
if (pciids.length == 0)
{
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", &pciids); // debian?
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids);
}
#elif __FreeBSD__
// https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pciconf/pathnames.h
ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids);
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/pciids/pci.ids", &pciids);
#elif __sun
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
#endif
#endif // FF_CUSTOM_PCI_IDS_PATH
return &pciids;
}
static void parsePciIdsFile(const FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
if (content->length)
{
@@ -52,11 +100,6 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
{
openingBracket++;
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
if (coreName)
{
ffStrbufSetNS(coreName, (uint32_t) (openingBracket - start) - 1, start);
ffStrbufTrimRight(coreName, ' ');
}
}
}
if (!gpu->name.length)
@@ -79,3 +122,66 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr);
}
}
#if FF_HAVE_EMBEDDED_PCIIDS
static inline int pciDeviceCmp(const uint16_t* key, const FFPciDevice* element)
{
return (int) *key - (int) element->id;
}
static bool loadPciidsInc(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
for (const FFPciVendor* pvendor = ffPciVendors; pvendor->name; pvendor++)
{
if (pvendor->id != vendor) continue;
if (!gpu->vendor.length)
ffStrbufSetS(&gpu->vendor, pvendor->name);
const FFPciDevice* pdevice = (const FFPciDevice*) bsearch(&device, pvendor->devices, pvendor->nDevices, sizeof(FFPciDevice), (void*) pciDeviceCmp);
if (pdevice)
{
uint32_t nameLen = (uint32_t) strlen(pdevice->name);
const char* closingBracket = pdevice->name + nameLen - 1;
if (*closingBracket == ']')
{
const char* openingBracket = memrchr(pdevice->name, '[', nameLen - 1);
if (openingBracket)
{
openingBracket++;
ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket);
}
}
if (!gpu->name.length)
ffStrbufSetNS(&gpu->name, nameLen, pdevice->name);
return true;
}
if (!gpu->name.length)
{
const char* subclassStr;
switch (subclass)
{
case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break;
case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break;
case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break;
default: subclassStr = ""; break;
}
ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr);
}
return true;
}
return false;
}
#endif
void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
{
#if FF_HAVE_EMBEDDED_PCIIDS
bool ok = loadPciidsInc(subclass, vendor, device, gpu);
if (ok) return;
#endif
return parsePciIdsFile(loadPciIds(), subclass, vendor, device, gpu);
}
+2 -5
View File
@@ -20,8 +20,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (!ffStrbufStartsWithS(&buffer, "\npci "))
return "Invalid scanpci result";
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
// Device unknown
// CardVendor 0x0000 card 0x0000 (Card unknown)
@@ -57,6 +55,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
@@ -74,9 +73,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
if (gpu->name.length == 0)
{
if (pciids.length == 0)
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu, NULL);
ffGPUFillVendorAndName((uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
}
}
+63 -44
View File
@@ -38,6 +38,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufInit(&gpu->name);
ffStrbufInit(&gpu->driver);
ffStrbufInitStatic(&gpu->platformApi, "SetupAPI");
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
@@ -46,9 +47,18 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->deviceId = 0;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
uint32_t pciBus = 0, pciAddr = UINT32_MAX, pciDev = 0, pciFunc = 0;
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
{
pciDev = (pciAddr >> 16) & 0xFFFF;
pciFunc = pciAddr & 0xFFFF;
gpu->deviceId = (pciBus * 1000ull) + (pciDev * 10ull) + pciFunc;
}
wchar_t buffer[256];
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
ffStrbufSetWS(&gpu->name, buffer);
uint64_t adapterLuid = 0;
FF_HKEY_AUTO_DESTROY hVideoIdKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
if (!hVideoIdKey) continue;
@@ -60,9 +70,19 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
{
uint32_t vendorId = 0;
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
gpu->type = gpu->deviceId == 20 ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
uint64_t dedicatedVideoMemory = 0;
if(ffRegReadUint64(hDirectxKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, NULL))
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
{
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
uint64_t dedicatedSystemMemory, sharedSystemMemory;
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
@@ -72,7 +92,10 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
gpu->shared.total = sharedSystemMemory;
}
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
if (ffRegReadUint64(hDirectxKey, L"AdapterLuid", &adapterLuid, NULL))
{
if (!gpu->deviceId) gpu->deviceId = adapterLuid;
}
uint32_t featureLevel = 0;
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
@@ -90,10 +113,6 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
(unsigned) (driverVersion >> 0) & 0xFFFF
);
}
uint32_t vendorId = 0;
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
}
}
@@ -131,43 +150,43 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
}
uint32_t pciBus, pciAddr;
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_BUSNUMBER, NULL, (PBYTE) &pciBus, sizeof(pciBus), NULL) &&
SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_ADDRESS, NULL, (PBYTE) &pciAddr, sizeof(pciAddr), NULL))
{
uint32_t pciDev = (pciAddr >> 16) & 0xFFFF;
uint32_t pciFunc = pciAddr & 0xFFFF;
detectFn(
&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
| (adapterLuid > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
| (pciAddr > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
.pciDeviceId = {
.deviceId = deviceId,
.vendorId = vendorId,
.subSystemId = subSystemId,
.revId = revId,
},
.pciBusId = {
.domain = 0,
.bus = pciBus,
.device = pciDev,
.func = pciFunc,
},
.luid = adapterLuid,
},
(FFGpuDriverResult){
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.name = &gpu->name,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
},
dllName
);
}
detectFn(
&(FFGpuDriverCondition) {
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
| (gpu->deviceId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
| (vendorId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
.pciDeviceId = {
.deviceId = deviceId,
.vendorId = vendorId,
.subSystemId = subSystemId,
.revId = revId,
},
.pciBusId = {
.domain = 0,
.bus = pciBus,
.device = pciDev,
.func = pciFunc,
},
.luid = gpu->deviceId,
},
(FFGpuDriverResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.coreUsage = options->driverSpecific ? &gpu->coreUsage : NULL,
.type = &gpu->type,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
},
dllName
);
}
if (!gpu->name.length)
{
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
ffStrbufSetWS(&gpu->name, buffer);
}
}
+3 -1
View File
@@ -70,6 +70,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
FFGPUResult* gpu = (FFGPUResult*) ffListAdd(gpus);
ffStrbufInitS(&gpu->name, desc);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
@@ -117,7 +118,8 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
.revId = hardwareId.revision,
},
};
ffDetectNvidiaGpuInfo(&cond, (FFGpuDriverResult) {
ffDetectNvidiaGpuInfo(&cond, (FFGpuDriverResult){
.index = &gpu->index,
.temp = options->temp ? &gpu->temperature : NULL,
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
+125
View File
@@ -0,0 +1,125 @@
#pragma once
/* SPDX-License-Identifier: MIT */
#include <drm.h>
// xe_drm.h
/*
* Copyright © 2023 Intel Corporation
*/
#define DRM_XE_DEVICE_QUERY 0x00
#define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query)
enum drm_xe_memory_class {
DRM_XE_MEM_REGION_CLASS_SYSMEM = 0,
DRM_XE_MEM_REGION_CLASS_VRAM
};
struct drm_xe_mem_region {
__u16 mem_class;
__u16 instance;
__u32 min_page_size;
__u64 total_size;
__u64 used;
__u64 cpu_visible_size;
__u64 cpu_visible_used;
__u64 reserved[6];
};
struct drm_xe_query_mem_regions {
__u32 num_mem_regions;
__u32 pad;
struct drm_xe_mem_region mem_regions[];
};
struct drm_xe_query_topology_mask {
__u16 gt_id;
#define DRM_XE_TOPO_DSS_GEOMETRY 1
#define DRM_XE_TOPO_DSS_COMPUTE 2
#define DRM_XE_TOPO_EU_PER_DSS 4
__u16 type;
__u32 num_bytes;
__u8 mask[];
};
struct drm_xe_device_query {
__u64 extensions;
#define DRM_XE_DEVICE_QUERY_MEM_REGIONS 1
#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
__u32 query;
__u32 size;
__u64 data;
__u64 reserved[2];
};
// i915_drm.h
/*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*/
#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
struct drm_i915_getparam {
__s32 param;
int *value;
};
typedef struct drm_i915_getparam drm_i915_getparam_t;
#define DRM_I915_GETPARAM 0x06
#define DRM_I915_QUERY 0x39
#define DRM_I915_QUERY_MEMORY_REGIONS 4
#define DRM_IOCTL_I915_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_QUERY, struct drm_i915_query)
#define I915_PARAM_EU_TOTAL 34
struct drm_i915_query_item {
__u64 query_id;
#define DRM_I915_QUERY_MEMORY_REGIONS 4
__s32 length;
__u32 flags;
__u64 data_ptr;
};
struct drm_i915_query {
__u32 num_items;
__u32 flags;
__u64 items_ptr;
};
enum drm_i915_gem_memory_class {
I915_MEMORY_CLASS_SYSTEM = 0,
I915_MEMORY_CLASS_DEVICE,
};
struct drm_i915_gem_memory_class_instance {
__u16 memory_class;
__u16 memory_instance;
};
struct drm_i915_memory_region_info {
struct drm_i915_gem_memory_class_instance region;
__u32 rsvd0;
__u64 probed_size;
__u64 unallocated_size;
union {
__u64 rsvd1[8];
struct {
__u64 probed_cpu_visible_size;
__u64 unallocated_cpu_visible_size;
};
};
};
struct drm_i915_query_memory_regions {
__u32 num_regions;
__u32 rsvd[3];
struct drm_i915_memory_region_info regions[];
};
+2
View File
@@ -132,5 +132,7 @@ extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType
extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type);
// Retrieves the current utilization rates for the device
extern nvmlReturn_t nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *utilization);
// Retrieves the globally unique immutable UUID associated with this device, as a 5 part hexadecimal string, that augments the immutable, board serial identifier.
extern nvmlReturn_t nvmlDeviceGetIndex(nvmlDevice_t device, unsigned int *index);
// Retrieves the name of this device.
extern nvmlReturn_t nvmlDeviceGetName(nvmlDevice_t device, char *name, unsigned int length);
+1 -1
View File
@@ -29,7 +29,7 @@ static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
for (NSScreen* screen in NSScreen.screens)
{
if (screen == mainScreen) continue;
NSNumber* screenNumber = [screen.deviceDescription valueForKey:@"NSScreenNumber"];
NSNumber* screenNumber = screen.deviceDescription[@"NSScreenNumber"];
if (screenNumber && screenNumber.longValue == (long) display->id)
{
#ifdef MAC_OS_X_VERSION_10_15
+8 -8
View File
@@ -176,7 +176,7 @@ FF_MAYBE_UNUSED static const char* detectByDrm(FFlist* results)
{
const char* drmDirPath = "/sys/class/drm/";
DIR* dirp = opendir(drmDirPath);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return "opendir(drmDirPath) == NULL";
@@ -232,23 +232,23 @@ FF_MAYBE_UNUSED static const char* detectByDrm(FFlist* results)
ffStrbufSubstrBefore(&drmDir, drmDirLength);
}
closedir(dirp);
return NULL;
}
#endif // __linux__
const char* ffDetectMonitor(FFlist* results)
{
const char* error = "Fastfetch was compiled without xrandr support";
const char* error = NULL;
#if defined(__linux__)
error = detectByDrm(results);
if (!error && results->length > 0) return NULL;
#endif
#ifdef FF_HAVE_XRANDR
error = detectByXrandr(results);
if (!error) return NULL;
#endif
#if defined(__linux__)
error = detectByDrm(results);
#endif
return error;
return "Fastfetch was compiled without xrandr support";
}
+1
View File
@@ -75,6 +75,7 @@ static const char* openCLHandleData(OpenCLData* data, FFOpenCLResult* result)
ffStrbufInit(&gpu->vendor);
ffStrbufInit(&gpu->driver);
ffStrbufInit(&gpu->platformApi);
gpu->index = FF_GPU_INDEX_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->type = FF_GPU_TYPE_UNKNOWN;
+3 -3
View File
@@ -19,11 +19,11 @@ static void parseSystemVersion(FFOSResult* os)
NSString* value;
if((value = [dict valueForKey:@"ProductName"]))
if((value = dict[@"ProductName"]))
ffStrbufInitS(&os->name, value.UTF8String);
if((value = [dict valueForKey:@"ProductUserVisibleVersion"]))
if((value = dict[@"ProductUserVisibleVersion"]))
ffStrbufInitS(&os->version, value.UTF8String);
if((value = [dict valueForKey:@"ProductBuildVersion"]))
if((value = dict[@"ProductBuildVersion"]))
ffStrbufInitS(&os->buildID, value.UTF8String);
}
+1
View File
@@ -35,6 +35,7 @@ typedef struct FFPackagesResult
uint32_t sorcery;
uint32_t winget;
uint32_t xbps;
uint32_t pacstall;
uint32_t all; //Make sure this goes last
+75 -2
View File
@@ -467,6 +467,78 @@ static uint32_t getGuixPackages(FFstrbuf* baseDir, const char* dirname)
return num_elements;
}
static inline uint32_t getFlatpakRuntimePackagesArch(FFstrbuf* baseDir)
{
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
if (dirp == NULL)
return 0;
uint32_t num_elements = 0;
struct dirent *entry;
while ((entry = readdir(dirp)) != NULL)
{
if(entry->d_type == DT_DIR && entry->d_name[0] != '.')
{
num_elements += getNumElements(baseDir, entry->d_name, DT_DIR);
}
}
return num_elements;
}
static inline uint32_t getFlatpakRuntimePackages(FFstrbuf* baseDir)
{
ffStrbufAppendS(baseDir, "runtime/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
if (dirp == NULL)
return 0;
uint32_t runtimeDirLength = baseDir->length;
uint32_t num_elements = 0;
struct dirent *entry;
while ((entry = readdir(dirp)) != NULL)
{
if(entry->d_type == DT_DIR && entry->d_name[0] != '.')
{
// `flatpak list` ignores `.Locale` and `.Debug` packages, and maybe others
const char* dot = strrchr(entry->d_name, '.');
if (__builtin_expect(!dot, false)) continue;
dot++;
if (ffStrEquals(dot, "Locale") || ffStrEquals(dot, "Debug"))
continue;
ffStrbufAppendS(baseDir, entry->d_name);
ffStrbufAppendC(baseDir, '/');
num_elements += getFlatpakRuntimePackagesArch(baseDir);
ffStrbufSubstrBefore(baseDir, runtimeDirLength);
}
}
return num_elements;
}
static uint32_t getFlatpakPackages(FFstrbuf* baseDir, const char* dirname)
{
uint32_t num_elements = 0;
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, dirname);
ffStrbufAppendS(baseDir, "/flatpak/");
uint32_t flatpakDirLength = baseDir->length;
ffStrbufAppendS(baseDir, "app");
num_elements += getNumElementsImpl(baseDir->chars, DT_DIR);
ffStrbufSubstrBefore(baseDir, flatpakDirLength);
num_elements += getFlatpakRuntimePackages(baseDir);
ffStrbufSubstrBefore(baseDir, baseDirLength);
return num_elements;
}
static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q", "apk");
@@ -474,7 +546,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n", "lpkg");
if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE");
if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getFlatpakPackages(baseDir, "/var/lib");
if (!(options->disabled & FF_PACKAGES_FLAG_NIX_BIT))
{
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
@@ -500,6 +572,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile");
}
if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR);
if (!(options->disabled & FF_PACKAGES_FLAG_PACSTALL_BIT)) packageCounts->pacstall += getNumElements(baseDir, "/var/lib/pacstall/metadata", DT_REG);
}
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
@@ -603,5 +676,5 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
}
if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT))
result->flatpakUser = getNumElements(&baseDir, "/.local/share/flatpak/app", DT_DIR);
result->flatpakUser = getFlatpakPackages(&baseDir, "/.local/share");
}
+26 -14
View File
@@ -1,12 +1,34 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "detection/temps/temps_linux.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
static double detectNvmeTemp(const char* devName)
{
char pathSysBlock[PATH_MAX];
int index = snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/hwmon$/temp1_input", devName);
if (index <= 0) return FF_PHYSICALDISK_TEMP_UNSET;
index -= (int) sizeof("/temp1_input");
for (char c = '0'; c <= '9'; c++) // hopefully there's only one digit
{
pathSysBlock[index] = c;
char buffer[64];
ssize_t size = ffReadFileData(pathSysBlock, sizeof(buffer), buffer);
if (size > 0)
{
buffer[size] = '\0';
double temp = strtod(buffer, NULL);
return temp > 0 ? temp / 1000 : FF_PHYSICALDISK_TEMP_UNSET;
}
}
return FF_PHYSICALDISK_TEMP_UNSET;
}
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
@@ -157,20 +179,10 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
}
}
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
if (options->temp)
{
const FFlist* tempsResult = ffDetectTemps();
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
{
if (ffStrStartsWith(devName, value->deviceName.chars)) // nvme0 - nvme0n1
{
device->temperature = value->value;
break;
}
}
}
device->temperature = detectNvmeTemp(devName);
else
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
}
return NULL;
-24
View File
@@ -1,24 +0,0 @@
#include "temps_bsd.h"
#include "common/sysctl.h"
const char* ffDetectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
const char* ffDetectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
-4
View File
@@ -1,4 +0,0 @@
#pragma once
const char* ffDetectCpuTemp(double* current);
const char* ffDetectThermalTemp(double* current);
-101
View File
@@ -1,101 +0,0 @@
#include "fastfetch.h"
#include "common/io/io.h"
#include "common/thread.h"
#include "temps_linux.h"
#include <string.h>
#include <dirent.h>
static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
{
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
uint32_t dirLength = dir->length;
FF_STRBUF_AUTO_DESTROY valueBuffer = ffStrbufCreate();
ffStrbufAppendS(dir, "temp1_input");
if(!ffReadFileBuffer(dir->chars, &valueBuffer))
return false;
ffStrbufSubstrBefore(dir, dirLength);
value->value = ffStrbufToDouble(&valueBuffer) / 1000; // valueBuffer is millidegree Celsius
if(value->value != value->value)
return false;
ffStrbufAppendS(dir, "name");
ffReadFileBuffer(dir->chars, &value->name);
ffStrbufTrimRightSpace(&value->name);
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/class");
if(!ffReadFileBuffer(dir->chars, &valueBuffer))
{
ffStrbufSubstrBefore(dir, dirLength);
ffStrbufAppendS(dir, "device/device/class");
ffReadFileBuffer(dir->chars, &valueBuffer);
}
ffStrbufTrimRightSpace(&valueBuffer);
ffStrbufSubstrBefore(dir, dirLength);
if(valueBuffer.length)
value->deviceClass = (uint32_t) strtoul(valueBuffer.chars, NULL, 16);
ffStrbufClear(&valueBuffer);
ffStrbufEnsureFree(&valueBuffer, 64);
ffStrbufAppendS(dir, "device");
ssize_t linkLen = readlink(dir->chars, valueBuffer.chars, valueBuffer.allocated - 1);
if (linkLen > 0)
{
valueBuffer.length = (uint32_t) linkLen;
valueBuffer.chars[linkLen] = 0;
ffStrbufSubstrAfterLastC(&valueBuffer, '/');
ffStrbufInitMove(&value->deviceName, &valueBuffer);
}
else
ffStrbufInit(&value->deviceName);
return value->name.length > 0 || value->deviceClass > 0;
}
const FFlist* ffDetectTemps(void)
{
static FFlist result;
if(result.elementSize > 0)
return &result;
ffListInitA(&result, sizeof(FFTempValue), 16);
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
uint32_t baseDirLength = baseDir.length;
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
if(dirp == NULL)
return &result;
struct dirent* entry;
while((entry = readdir(dirp)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
ffStrbufAppendS(&baseDir, entry->d_name);
ffStrbufAppendC(&baseDir, '/');
FFTempValue* temp = ffListAdd(&result);
ffStrbufInit(&temp->name);
temp->deviceClass = 0;
if(!parseHwmonDir(&baseDir, temp))
{
ffStrbufDestroy(&temp->name);
--result.length;
}
ffStrbufSubstrBefore(&baseDir, baseDirLength);
}
return &result;
}
-13
View File
@@ -1,13 +0,0 @@
#pragma once
#include "fastfetch.h"
typedef struct FFTempValue
{
FFstrbuf name;
FFstrbuf deviceName;
uint32_t deviceClass;
double value;
} FFTempValue;
const FFlist* /* List of FFTempValue */ ffDetectTemps();
-3
View File
@@ -1,3 +0,0 @@
#pragma once
const char* ffDetectSmbiosTemp(double* current, double* critical);
+1 -1
View File
@@ -82,7 +82,7 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResul
if (ffGetTerminalResponse(
"\eP+q6b697474792d71756572792d666f6e745f66616d696c79;6b697474792d71756572792d666f6e745f73697a65\e\\", // kitty-query-font_family;kitty-query-font_size
2,
"\eP1+r%*[^=]=%64[^\e]\e\\\eP1+r%*[^=]=%64[^\e]\e\\", fontHex, sizeHex) == NULL && *fontHex && *sizeHex)
"\eP1+r%*[^=]=%512[^\e]\e\\\eP1+r%*[^=]=%512[^\e]\e\\", fontHex, sizeHex) == NULL && *fontHex && *sizeHex)
{
// decode hex string
for (const char* p = fontHex; p[0] && p[1]; p += 2)
@@ -26,12 +26,12 @@ static void detectIterm2(FFTerminalFontResult* terminalFont)
return;
}
for(NSDictionary* bookmark in [dict valueForKey:@"New Bookmarks"])
for(NSDictionary* bookmark in dict[@"New Bookmarks"])
{
if(![[bookmark valueForKey:@"Name"] isEqualToString:@(profile)])
if(![bookmark[@"Name"] isEqualToString:@(profile)])
continue;
NSString* normalFont = [bookmark valueForKey:@"Normal Font"];
NSString* normalFont = bookmark[@"Normal Font"];
if(!normalFont)
{
ffStrbufAppendF(&terminalFont->error, "`Normal Font` key in profile `%s` doesn't exist", profile);
@@ -39,10 +39,10 @@ static void detectIterm2(FFTerminalFontResult* terminalFont)
}
ffFontInitWithSpace(&terminalFont->font, normalFont.UTF8String);
NSNumber* useNonAsciiFont = [bookmark valueForKey:@"Use Non-ASCII Font"];
NSNumber* useNonAsciiFont = bookmark[@"Use Non-ASCII Font"];
if(useNonAsciiFont.boolValue)
{
NSString* nonAsciiFont = [bookmark valueForKey:@"Non Ascii Font"];
NSString* nonAsciiFont = bookmark[@"Non Ascii Font"];
if (nonAsciiFont)
ffFontInitWithSpace(&terminalFont->fallback, nonAsciiFont.UTF8String);
}
@@ -78,13 +78,13 @@ static void detectWarpTerminal(FFTerminalFontResult* terminalFont)
return;
}
NSString* fontName = [dict valueForKey:@"FontName"];
NSString* fontName = dict[@"FontName"];
if(!fontName)
fontName = @"Hack";
else
fontName = [fontName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]];
NSString* fontSize = [dict valueForKey:@"FontSize"];
NSString* fontSize = dict[@"FontSize"];
if(!fontSize)
fontSize = @"13";
@@ -244,13 +244,19 @@ static void detectFootTerminal(FFTerminalFontResult* terminalFont)
return;
}
uint32_t equal = ffStrbufNextIndexS(&font, colon, "size=");
font.chars[colon] = 0;
font.chars[colon] = '\0';
if (equal == font.length)
{
ffFontInitValues(&terminalFont->font, font.chars, "8");
return;
}
ffFontInitValues(&terminalFont->font, font.chars, &font.chars[equal + strlen("size=")]);
uint32_t size = equal + strlen("size=");
uint32_t comma = ffStrbufNextIndexC(&font, size, ',');
if (comma < font.length)
font.chars[comma] = '\0';
ffFontInitValues(&terminalFont->font, font.chars, &font.chars[size]);
if (comma < font.length)
ffFontInitValues(&terminalFont->fallback, &font.chars[comma + 1], NULL);
}
static void detectQTerminal(FFTerminalFontResult* terminalFont)
+8 -1
View File
@@ -365,6 +365,13 @@ FF_MAYBE_UNUSED static bool getTerminalVersionKonsole(FFstrbuf* exe, FFstrbuf* v
FF_MAYBE_UNUSED static bool getTerminalVersionFoot(FFstrbuf* exe, FFstrbuf* version)
{
uint32_t major = 0, minor = 0, patch = 0;
if (ffGetTerminalResponse("\e[>c", 3, "\e[>1;%2u%2u%2u;0c", &major, &minor, &patch) == NULL)
{
ffStrbufSetF(version, "%u.%u.%u", major, minor, patch);
return true;
}
if(!getExeVersionRaw(exe, version)) return false;
//foot version: 1.13.1 -pgo +ime -graphemes -assertions
@@ -664,7 +671,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
return getTerminalVersionKonsole(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "yakuake"))
return getExeVersionGeneral(exe, version);//yakuake 22.12.3
return getTerminalVersionKonsole(exe, version); // yakuake shares code with konsole
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
return getTerminalVersionXfce4Terminal(exe, version);
@@ -83,6 +83,8 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
{
//Known shells
if (
ffStrbufEqualS(&result->processName, "sudo") ||
ffStrbufEqualS(&result->processName, "su") ||
ffStrbufEqualS(&result->processName, "sh") ||
ffStrbufEqualS(&result->processName, "ash") ||
ffStrbufEqualS(&result->processName, "bash") ||
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#include "fastfetch.h"
typedef struct FFTPMResult
{
FFstrbuf version;
FFstrbuf description;
} FFTPMResult;
const char* ffDetectTPM(FFTPMResult* result);
+21
View File
@@ -0,0 +1,21 @@
#include "tpm.h"
#include "common/sysctl.h"
#include "util/kmod.h"
const char* ffDetectTPM(FFTPMResult* result)
{
if (ffSysctlGetString("dev.tpmcrb.0.%desc", &result->description) != NULL)
{
if (!ffKmodLoaded("tpm")) return "`tpm` kernel module is not loaded";
return "TPM device is not found";
}
if (ffStrbufContainS(&result->description, "2.0"))
ffStrbufSetStatic(&result->version, "2.0");
else if (ffStrbufContainS(&result->description, "1.2"))
ffStrbufSetStatic(&result->version, "1.2");
else
ffStrbufSetStatic(&result->version, "unknown");
return NULL;
}
+24
View File
@@ -0,0 +1,24 @@
#include "tpm.h"
#include "common/io/io.h"
const char* ffDetectTPM(FFTPMResult* result)
{
if (!ffPathExists("/sys/class/tpm/tpm0", FF_PATHTYPE_DIRECTORY))
{
if (!ffPathExists("/sys/class/tpm", FF_PATHTYPE_DIRECTORY))
return "TPM is not supported by kernel";
return "TPM device is not found";
}
if (ffReadFileBuffer("/sys/class/tpm/tpm0/tpm_version_major", &result->version))
{
ffStrbufTrimRightSpace(&result->version);
if (ffStrbufEqualS(&result->version, "2"))
ffStrbufSetStatic(&result->version, "2.0");
}
if (ffReadFileBuffer("/sys/class/tpm/tpm0/device/description", &result->description))
ffStrbufTrimRightSpace(&result->description);
return NULL;
}
+6
View File
@@ -0,0 +1,6 @@
#include "tpm.h"
const char* ffDetectTPM(FF_MAYBE_UNUSED FFTPMResult* result)
{
return "Not supported on this platform";
}
+82
View File
@@ -0,0 +1,82 @@
#include "tpm.h"
#include "common/library.h"
// #include <tbs.h>
#define TBS_SUCCESS 0u
#define TBS_E_INTERNAL_ERROR 0x80284001u
#define TBS_E_INVALID_CONTEXT 0x80284004u
typedef UINT32 TBS_RESULT;
#define TPM_VERSION_UNKNOWN 0
#define TPM_VERSION_12 1
#define TPM_VERSION_20 2
#define TPM_IFTYPE_UNKNOWN 0
#define TPM_IFTYPE_1 1 // for 1.2 - use I/O-port or MMIO
#define TPM_IFTYPE_TRUSTZONE 2 // 2.0: Trustzone
#define TPM_IFTYPE_HW 3 // 2.0: HW TPM
#define TPM_IFTYPE_EMULATOR 4 // 2.0: SW-emulator
#define TPM_IFTYPE_SPB 5 // 2.0: SPB attached
typedef struct _TPM_DEVICE_INFO
{
UINT32 structVersion; // = 1 for now
UINT32 tpmVersion; // 1.2 / 2.0
UINT32 tpmInterfaceType; // HW, simulator, ...
UINT32 tpmImpRevision; // code-drop revision,
// implenmentation-specific
} TPM_DEVICE_INFO, *PTPM_DEVICE_INFO;
typedef const TPM_DEVICE_INFO *PCTPM_DEVICE_INFO;
TBS_RESULT WINAPI
Tbsi_GetDeviceInfo(
_In_ UINT32 Size,
_Out_writes_bytes_(Size) PVOID Info);
const char* ffDetectTPM(FFTPMResult* result)
{
FF_LIBRARY_LOAD(tbs, "dlopen TBS" FF_LIBRARY_EXTENSION " failed", "TBS" FF_LIBRARY_EXTENSION, -1)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(tbs, Tbsi_GetDeviceInfo)
TPM_DEVICE_INFO deviceInfo = {};
TBS_RESULT code = ffTbsi_GetDeviceInfo(sizeof(deviceInfo), &deviceInfo);
if (code != TBS_SUCCESS)
return code == (TBS_RESULT) TBS_E_INVALID_CONTEXT ? "TPM device is not found" : "Tbsi_GetDeviceInfo() failed";
switch (deviceInfo.tpmVersion)
{
case TPM_VERSION_12:
ffStrbufSetStatic(&result->version, "1.2");
break;
case TPM_VERSION_20:
ffStrbufSetStatic(&result->version, "2.0");
break;
default:
ffStrbufSetStatic(&result->version, "unknown");
break;
}
switch (deviceInfo.tpmInterfaceType)
{
case TPM_IFTYPE_1:
ffStrbufSetF(&result->description, "I/O-port or MMIO TPM %s", result->version.chars);
break;
case TPM_IFTYPE_TRUSTZONE:
ffStrbufSetF(&result->description, "Trustzone TPM %s", result->version.chars);
break;
case TPM_IFTYPE_HW:
ffStrbufSetF(&result->description, "HW TPM %s", result->version.chars);
break;
case TPM_IFTYPE_EMULATOR:
ffStrbufSetF(&result->description, "SW-emulator TPM %s", result->version.chars);
break;
case TPM_IFTYPE_SPB:
ffStrbufSetF(&result->description, "SPB attached TPM %s", result->version.chars);
break;
default:
break;
}
return NULL;
}
+1
View File
@@ -234,6 +234,7 @@ static const char* detectVulkan(FFVulkanResult* result)
}
//No way to detect those using vulkan
gpu->index = FF_GPU_INDEX_UNSET;
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
+4 -4
View File
@@ -18,16 +18,16 @@ const char* ffDetectWallpaper(FFstrbuf* result)
NSArray* choices = [dict valueForKeyPath:@"SystemDefault.Desktop.Content.Choices"];
if (choices.count > 0)
{
NSDictionary* choice = [choices objectAtIndex:0];
NSArray* files = [choice valueForKey:@"Files"];
NSDictionary* choice = choices[0];
NSArray* files = choice[@"Files"];
if (files.count > 0)
{
NSString* file = [[files objectAtIndex: 0] valueForKey: @"relative"];
NSString* file = files[0][@"relative"];
ffStrbufAppendS(result, [NSURL URLWithString:file].path.UTF8String);
}
else
{
NSString* provider = [choice valueForKey:@"Provider"];
NSString* provider = choice[@"Provider"];
NSString* builtinPrefix = @"com.apple.wallpaper.choice.";
if ([provider hasPrefix:builtinPrefix])
provider = [provider substringFromIndex:builtinPrefix.length];
+1 -1
View File
@@ -134,7 +134,7 @@ const char* ffDetectWifi(FFlist* result)
ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)");
break;
default:
if (inf.activePHYMode < 64)
if (inf.activePHYMode < 8)
ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode);
else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName)))
{
+2 -2
View File
@@ -15,7 +15,7 @@ bool ffDetectWmTheme(FFstrbuf* themeOrError)
return false;
}
NSNumber* wmThemeColor = [dict valueForKey:@"AppleAccentColor"];
NSNumber* wmThemeColor = dict[@"AppleAccentColor"];
if(!wmThemeColor)
ffStrbufAppendS(themeOrError, "Multicolor");
else
@@ -34,7 +34,7 @@ bool ffDetectWmTheme(FFstrbuf* themeOrError)
}
}
NSString* wmTheme = [dict valueForKey:@"AppleInterfaceStyle"];
NSString* wmTheme = dict[@"AppleInterfaceStyle"];
ffStrbufAppendF(themeOrError, " (%s)", wmTheme ? wmTheme.UTF8String : "Light");
return true;
}
+6 -1
View File
@@ -1,6 +1,7 @@
#include "zpool.h"
#ifdef FF_HAVE_LIBZFS
#include "util/kmod.h"
#ifdef __sun
#define FF_DISABLE_DLOPEN
@@ -82,7 +83,11 @@ const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init);
libzfs_handle_t* handle = fflibzfs_init();
if (!handle) return "libzfs_init() failed";
if (!handle)
{
if (!ffKmodLoaded("zfs")) return "`zfs` kernel module is not loaded";
return "libzfs_init() failed";
}
__attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = {
.handle = handle,
+1 -1
View File
@@ -1,4 +1,4 @@
$1 ............
............
.';;;;;. .,;,.
.,;;;;;;;. ';;;;;;;.
.;::::::::' .,::;;,''''',.
+8
View File
@@ -0,0 +1,8 @@
________ ________ ___ ___ ________ ________
|\ _____\\ __ \ |\ \ / /|\ __ \|\ ____\
\ \ \__/\ \ \|\ \ \ \ \/ / | \ \|\ \ \ \___|_
\ \ __\\ \ \\\ \ \ \ / / \ \ \\\ \ \_____ \
\ \ \_| \ \ \\\ \ / \/ \ \ \\\ \|____|\ \
\ \__\ \ \_______\/ /\ \ \ \_______\____\_\ \
\|__| \|_______/__/ /\ __\ \|_______|\_________\
|__|/ \|__| \|_________|
+18
View File
@@ -1666,6 +1666,14 @@ static const FFlogo F[] = {
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_WHITE,
},
// FoxOS
{
.names = {"FoxOS"},
.lines = FASTFETCH_DATATEXT_LOGO_FOXOS,
.colors = {
FF_COLOR_FG_YELLOW,
},
},
// FreeBSD
{
.names = {"Freebsd"},
@@ -1914,6 +1922,16 @@ static const FFlogo G[] = {
.colorKeys = FF_COLOR_FG_YELLOW,
.colorTitle = FF_COLOR_FG_WHITE,
},
// GXDE
{
.names = {"GXDE"},
.lines = FASTFETCH_DATATEXT_LOGO_DEEPIN,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// LAST
{},
};
+2 -11
View File
@@ -6,7 +6,7 @@
#include "modules/cpu/cpu.h"
#include "util/stringUtils.h"
#define FF_CPU_NUM_FORMAT_ARGS 10
#define FF_CPU_NUM_FORMAT_ARGS 9
static int sortCores(const FFCPUCore* a, const FFCPUCore* b)
{
@@ -19,7 +19,6 @@ void ffPrintCPU(FFCPUOptions* options)
.temperature = FF_CPU_TEMP_UNSET,
.frequencyMax = 0,
.frequencyBase = 0,
.frequencyBiosLimit = 0,
.name = ffStrbufCreate(),
.vendor = ffStrbufCreate(),
};
@@ -71,9 +70,7 @@ void ffPrintCPU(FFCPUOptions* options)
else if(cpu.coresOnline > 1)
ffStrbufAppendF(&str, " (%u)", cpu.coresOnline);
uint32_t freq = cpu.frequencyBiosLimit;
if(freq == 0)
freq = cpu.frequencyMax;
uint32_t freq = cpu.frequencyMax;
if(freq == 0)
freq = cpu.frequencyBase;
if(freq > 0)
@@ -96,8 +93,6 @@ void ffPrintCPU(FFCPUOptions* options)
ffParseFrequency(cpu.frequencyBase, &freqBase);
FF_STRBUF_AUTO_DESTROY freqMax = ffStrbufCreate();
ffParseFrequency(cpu.frequencyMax, &freqMax);
FF_STRBUF_AUTO_DESTROY freqBioslimit = ffStrbufCreate();
ffParseFrequency(cpu.frequencyBiosLimit, &freqBioslimit);
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs);
@@ -111,7 +106,6 @@ void ffPrintCPU(FFCPUOptions* options)
FF_FORMAT_ARG(freqMax, "freq-max"),
FF_FORMAT_ARG(tempStr, "temperature"),
FF_FORMAT_ARG(coreTypes, "core-types"),
FF_FORMAT_ARG(freqBioslimit, "freq-bios-limit"),
}));
}
}
@@ -190,7 +184,6 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
.temperature = FF_CPU_TEMP_UNSET,
.frequencyMax = 0,
.frequencyBase = 0,
.frequencyBiosLimit = 0,
.name = ffStrbufCreate(),
.vendor = ffStrbufCreate(),
};
@@ -219,7 +212,6 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
yyjson_mut_val* frequency = yyjson_mut_obj_add_obj(doc, obj, "frequency");
yyjson_mut_obj_add_uint(doc, frequency, "base", cpu.frequencyBase);
yyjson_mut_obj_add_uint(doc, frequency, "max", cpu.frequencyMax);
yyjson_mut_obj_add_uint(doc, frequency, "biosLimit", cpu.frequencyBiosLimit);
yyjson_mut_val* coreTypes = yyjson_mut_obj_add_arr(doc, obj, "coreTypes");
for (uint32_t i = 0; i < sizeof (cpu.coreTypes) / sizeof (cpu.coreTypes[0]) && cpu.coreTypes[i].count > 0; i++)
@@ -248,7 +240,6 @@ void ffPrintCPUHelpFormat(void)
"Max frequency (formatted) - freq-max",
"Temperature (formatted) - temperature",
"Logical core count grouped by frequency - core-types",
"Bios limited frequency (formatted) - freq-bios-limit",
}));
}
+3 -3
View File
@@ -100,7 +100,7 @@ void ffPrintDisplay(FFDisplayOptions* options)
}
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
double inch = sqrt(result->physicalWidth * result->physicalWidth + result->physicalHeight * result->physicalHeight) / 25.4;
uint32_t inch = (uint32_t) (sqrt(result->physicalWidth * result->physicalWidth + result->physicalHeight * result->physicalHeight) / 25.4 + 0.5);
if(options->moduleArgs.outputFormat.length == 0)
{
@@ -121,8 +121,8 @@ void ffPrintDisplay(FFDisplayOptions* options)
result->scaledHeight > 0 && result->scaledHeight != result->height)
ffStrbufAppendF(&buffer, " (as %ix%i)", result->scaledWidth, result->scaledHeight);
if (inch > 0)
ffStrbufAppendF(&buffer, " in %i″", (uint32_t) (inch + 0.5));
if (inch > 1)
ffStrbufAppendF(&buffer, " in %i″", inch);
if(result->type != FF_DISPLAY_TYPE_UNKNOWN)
ffStrbufAppendS(&buffer, result->type == FF_DISPLAY_TYPE_BUILTIN ? " [Built-in]" : " [External]");
+9 -1
View File
@@ -10,7 +10,7 @@
#include <stdlib.h>
#define FF_GPU_NUM_FORMAT_ARGS 12
#define FF_GPU_NUM_FORMAT_ARGS 13
static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResult* gpu)
{
@@ -103,6 +103,7 @@ static void printGPUResult(FFGPUOptions* options, uint8_t index, const FFGPUResu
FF_FORMAT_ARG(sUsed, "shared-used"),
FF_FORMAT_ARG(gpu->platformApi, "platform-api"),
FF_FORMAT_ARG(frequency, "frequency"),
FF_FORMAT_ARG(index, "index"),
}));
}
}
@@ -322,6 +323,12 @@ void ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
FF_LIST_FOR_EACH(FFGPUResult, gpu, gpus)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
if (gpu->index != FF_GPU_INDEX_UNSET)
yyjson_mut_obj_add_uint(doc, obj, "index", gpu->index);
else
yyjson_mut_obj_add_null(doc, obj, "index");
if (gpu->coreCount != FF_GPU_CORE_COUNT_UNSET)
yyjson_mut_obj_add_int(doc, obj, "coreCount", gpu->coreCount);
else
@@ -402,6 +409,7 @@ void ffPrintGPUHelpFormat(void)
"GPU used shared memory - shared-used",
"The platform API used when detecting the GPU - platform-api",
"Current frequency in GHz - frequency",
"GPU vendor specific index - index",
}));
}
-1
View File
@@ -32,7 +32,6 @@ void ffPrintLoadavg(FFLoadavgOptions* options)
.temperature = FF_CPU_TEMP_UNSET,
.frequencyMax = 0,
.frequencyBase = 0,
.frequencyBiosLimit = 0,
.name = ffStrbufCreate(),
.vendor = ffStrbufCreate(),
};
+1
View File
@@ -62,6 +62,7 @@
#include "modules/terminaltheme/terminaltheme.h"
#include "modules/theme/theme.h"
#include "modules/title/title.h"
#include "modules/tpm/tpm.h"
#include "modules/uptime/uptime.h"
#include "modules/users/users.h"
#include "modules/version/version.h"
+1
View File
@@ -62,6 +62,7 @@
#include "modules/terminaltheme/option.h"
#include "modules/theme/option.h"
#include "modules/title/option.h"
#include "modules/tpm/option.h"
#include "modules/uptime/option.h"
#include "modules/users/option.h"
#include "modules/version/option.h"
+1
View File
@@ -32,6 +32,7 @@ typedef enum FFPackagesFlags
FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1 << 22,
FF_PACKAGES_FLAG_GUIX_BIT = 1 << 23,
FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24,
FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25,
} FFPackagesFlags;
typedef struct FFPackagesOptions
+10 -3
View File
@@ -4,7 +4,7 @@
#include "modules/packages/packages.h"
#include "util/stringUtils.h"
#define FF_PACKAGES_NUM_FORMAT_ARGS 37
#define FF_PACKAGES_NUM_FORMAT_ARGS 38
void ffPrintPackages(FFPackagesOptions* options)
{
@@ -72,6 +72,7 @@ void ffPrintPackages(FFPackagesOptions* options)
FF_PRINT_PACKAGE_NAME(guixUser, "guix-user")
FF_PRINT_PACKAGE_NAME(guixHome, "guix-home")
FF_PRINT_PACKAGE(linglong)
FF_PRINT_PACKAGE(pacstall)
putchar('\n');
}
@@ -115,6 +116,7 @@ void ffPrintPackages(FFPackagesOptions* options)
FF_FORMAT_ARG(counts.guixUser, "guix-user"),
FF_FORMAT_ARG(counts.guixHome, "guix-home"),
FF_FORMAT_ARG(counts.linglong, "linglong"),
FF_FORMAT_ARG(counts.pacstall, "pacstall"),
FF_FORMAT_ARG(nixAll, "nix-all"),
FF_FORMAT_ARG(flatpakAll, "flatpak-all"),
FF_FORMAT_ARG(brewAll, "brew-all"),
@@ -186,9 +188,10 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key,
break;
case 'P': if (false);
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PACSTALL)
FF_TEST_PACKAGE_NAME(PALUDIS)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(PALUDIS)
break;
case 'R': if (false);
FF_TEST_PACKAGE_NAME(RPM)
@@ -295,9 +298,10 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module)
break;
case 'P': if (false);
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PACSTALL)
FF_TEST_PACKAGE_NAME(PALUDIS)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(PALUDIS)
break;
case 'R': if (false);
FF_TEST_PACKAGE_NAME(RPM)
@@ -352,6 +356,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do
FF_TEST_PACKAGE_NAME(NIX)
FF_TEST_PACKAGE_NAME(OPKG)
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PACSTALL)
FF_TEST_PACKAGE_NAME(PALUDIS)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
@@ -412,6 +417,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy
FF_APPEND_PACKAGE_COUNT(guixUser)
FF_APPEND_PACKAGE_COUNT(guixHome)
FF_APPEND_PACKAGE_COUNT(linglong)
FF_APPEND_PACKAGE_COUNT(pacstall)
yyjson_mut_obj_add_strbuf(doc, obj, "pacmanBranch", &counts.pacmanBranch);
}
@@ -451,6 +457,7 @@ void ffPrintPackagesHelpFormat(void)
"Number of guix-user packages - guix-user",
"Number of guix-home packages - guix-home",
"Number of linglong packages - linglong",
"Number of pacstall packages - pacstall",
"Total number of all nix packages - nix-all",
"Total number of all flatpak app packages - flatpak-all",
"Total number of all brew packages - brew-all",
+11
View File
@@ -0,0 +1,11 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFTPMOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFTPMOptions;
+127
View File
@@ -0,0 +1,127 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/tpm/tpm.h"
#include "modules/tpm/tpm.h"
#include "util/stringUtils.h"
#define FF_TPM_NUM_FORMAT_ARGS 2
void ffPrintTPM(FFTPMOptions* options)
{
FFTPMResult result = {
.version = ffStrbufCreate(),
.description = ffStrbufCreate()
};
const char* error = ffDetectTPM(&result);
if(error)
{
ffPrintError(FF_TPM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_TPM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
if (result.description.length > 0)
ffStrbufPutTo(&result.description, stdout);
else
ffStrbufPutTo(&result.version, stdout);
}
else
{
FF_PRINT_FORMAT_CHECKED(FF_TPM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_TPM_NUM_FORMAT_ARGS, ((FFformatarg[]){
FF_FORMAT_ARG(result.version, "version"),
FF_FORMAT_ARG(result.description, "description"),
}));
}
ffStrbufDestroy(&result.version);
ffStrbufDestroy(&result.description);
}
bool ffParseTPMCommandOptions(FFTPMOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_TPM_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParseTPMJsonObject(FFTPMOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_TPM_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateTPMJsonConfig(FFTPMOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyTPMOptions))) FFTPMOptions defaultOptions;
ffInitTPMOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGenerateTPMJsonResult(FF_MAYBE_UNUSED FFTerminalOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FFTPMResult result = {
.version = ffStrbufCreate(),
.description = ffStrbufCreate()
};
const char* error = ffDetectTPM(&result);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result.version);
yyjson_mut_obj_add_strbuf(doc, obj, "description", &result.description);
ffStrbufDestroy(&result.version);
ffStrbufDestroy(&result.description);
}
void ffPrintTPMHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_TPM_MODULE_NAME, "{2}", FF_TPM_NUM_FORMAT_ARGS, ((const char* []) {
"TPM device version - version",
"TPM general description - description",
}));
}
void ffInitTPMOptions(FFTPMOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_TPM_MODULE_NAME,
"Print info of Trusted Platform Module (TPM) Security Device",
ffParseTPMCommandOptions,
ffParseTPMJsonObject,
ffPrintTPM,
ffGenerateTPMJsonResult,
ffPrintTPMHelpFormat,
ffGenerateTPMJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs, "");
}
void ffDestroyTPMOptions(FFTPMOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_TPM_MODULE_NAME "TPM"
void ffPrintTPM(FFTPMOptions* options);
void ffInitTPMOptions(FFTPMOptions* options);
void ffDestroyTPMOptions(FFTPMOptions* options);
+2
View File
@@ -63,6 +63,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitTerminalThemeOptions(&options->terminalTheme);
ffInitThemeOptions(&options->theme);
ffInitTitleOptions(&options->title);
ffInitTPMOptions(&options->tpm);
ffInitUptimeOptions(&options->uptime);
ffInitUsersOptions(&options->users);
ffInitVersionOptions(&options->version);
@@ -137,6 +138,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyTerminalThemeOptions(&options->terminalTheme);
ffDestroyThemeOptions(&options->theme);
ffDestroyTitleOptions(&options->title);
ffDestroyTPMOptions(&options->tpm);
ffDestroyUptimeOptions(&options->uptime);
ffDestroyUsersOptions(&options->users);
ffDestroyVersionOptions(&options->version);
+1
View File
@@ -64,6 +64,7 @@ typedef struct FFOptionsModules
FFTerminalThemeOptions terminalTheme;
FFThemeOptions theme;
FFTitleOptions title;
FFTPMOptions tpm;
FFUptimeOptions uptime;
FFUsersOptions users;
FFVersionOptions version;
+20
View File
@@ -211,6 +211,14 @@ void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value)
strbuf->length += length;
}
void ffStrbufPrependC(FFstrbuf* strbuf, char c)
{
ffStrbufEnsureFree(strbuf, 1);
memmove(strbuf->chars + 1, strbuf->chars, strbuf->length + 1); // + 1 for the null byte
strbuf->chars[0] = c;
strbuf->length += 1;
}
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value)
{
ffStrbufClear(strbuf);
@@ -511,3 +519,15 @@ void ffStrbufLowerCase(FFstrbuf* strbuf)
for (uint32_t i = 0; i < strbuf->length; ++i)
strbuf->chars[i] = (char) tolower(strbuf->chars[i]);
}
void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c)
{
if(num == 0) return;
if (index >= strbuf->length)
index = strbuf->length;
ffStrbufEnsureFree(strbuf, num);
memmove(strbuf->chars + index + num, strbuf->chars + index, strbuf->length - index + 1);
memset(&strbuf->chars[index], c, num);
strbuf->length += num;
}
+3
View File
@@ -47,6 +47,9 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufPrependC(FFstrbuf* strbuf, char c);
void ffStrbufInsertNC(FFstrbuf* strbuf, uint32_t index, uint32_t num, char c);
void ffStrbufSetNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufSet(FFstrbuf* strbuf, const FFstrbuf* value);
@@ -1,5 +1,5 @@
#include "fastfetch.h"
#include "temps_apple.h"
#include "smc_temps.h"
#include "util/stringUtils.h"
#include <stdint.h>
@@ -1,7 +1,6 @@
#pragma once
#include "fastfetch.h"
#include "util/FFlist.h"
typedef struct FFTempValue
{
+52
View File
@@ -0,0 +1,52 @@
#include "kmod.h"
#if __linux__
#include "common/io/io.h"
bool ffKmodLoaded(const char* modName)
{
static FFstrbuf modules;
if (modules.chars == NULL)
{
ffStrbufInitS(&modules, "\n");
ffAppendFileBuffer("/proc/modules", &modules);
}
if (modules.length == 0) return false;
uint32_t len = (uint32_t) strlen(modName);
if (len > 250) return false;
char temp[256];
temp[0] = '\n';
memcpy(temp + 1, modName, len);
temp[1 + len] = ' ';
return memmem(modules.chars, modules.length, temp, len + 2) != NULL;
}
#elif __FreeBSD__
#include <sys/param.h>
#include <sys/module.h>
bool ffKmodLoaded(const char* modName)
{
return modfind(modName) >= 0;
}
#elif __APPLE__
#include "util/apple/cf_helpers.h"
#include <IOKit/kext/KextManager.h>
#include <CoreFoundation/CoreFoundation.h>
bool ffKmodLoaded(const char* modName)
{
FF_CFTYPE_AUTO_RELEASE CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, modName, kCFStringEncodingUTF8);
FF_CFTYPE_AUTO_RELEASE CFArrayRef identifiers = CFArrayCreate(kCFAllocatorDefault, (const void**) &name, 1, &kCFTypeArrayCallBacks);
FF_CFTYPE_AUTO_RELEASE CFArrayRef keys = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef kextInfo = KextManagerCopyLoadedKextInfo(identifiers, keys);
return CFDictionaryContainsKey(kextInfo, name);
}
#else
bool ffKmodLoaded(FF_MAYBE_UNUSED const char* modName)
{
return true; // Don't generate kernel module related errors
}
#endif
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
bool ffKmodLoaded(const char* modName);
+26
View File
@@ -279,6 +279,20 @@ int main(void)
VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST"));
VERIFY(strbuf.length == 9);
VERIFY(strbuf.allocated >= 10);
ffStrbufAppendC(&strbuf, '_');
VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST_"));
ffStrbufDestroy(&strbuf);
VERIFY(strbuf.length == 0);
VERIFY(strbuf.allocated == 0);
//ffStrbufCreateStatic / Prepend
ffStrbufInitStatic(&strbuf, "TEST");
ffStrbufPrependS(&strbuf, "TEST_");
VERIFY(ffStrbufEqualS(&strbuf, "TEST_TEST"));
VERIFY(strbuf.length == 9);
VERIFY(strbuf.allocated >= 10);
ffStrbufPrependC(&strbuf, '_');
VERIFY(ffStrbufEqualS(&strbuf, "_TEST_TEST"));
ffStrbufDestroy(&strbuf);
VERIFY(strbuf.length == 0);
VERIFY(strbuf.allocated == 0);
@@ -416,6 +430,18 @@ int main(void)
VERIFY(ffStrbufEqualS(&strbuf, "__TEST__"));
ffStrbufDestroy(&strbuf);
//ffStrbufInsertNC
ffStrbufInitStatic(&strbuf, "123456");
ffStrbufInsertNC(&strbuf, 0, 2, 'A');
VERIFY(ffStrbufEqualS(&strbuf, "AA123456"));
ffStrbufInsertNC(&strbuf, 4, 2, 'B');
VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456"));
ffStrbufInsertNC(&strbuf, strbuf.length, 2, 'C');
VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456CC"));
ffStrbufInsertNC(&strbuf, 999, 2, 'D');
VERIFY(ffStrbufEqualS(&strbuf, "AA12BB3456CCDD"));
ffStrbufDestroy(&strbuf);
//Success
puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
}