mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
139 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 636126c57d | |||
| 2e475d590f | |||
| 0cf45c1dcd | |||
| 435516373d | |||
| 64735245e7 | |||
| 85d89395a9 | |||
| 093940e504 | |||
| e427a5112b | |||
| 1ab86a8ab9 | |||
| 99e0dc9aaa | |||
| 73e9db5b6e | |||
| adc03bd792 | |||
| 10fdc8e4a7 | |||
| d75803794e | |||
| d25ac86283 | |||
| de8bbc9a5c | |||
| 66977de5c7 | |||
| f828d3a9b9 | |||
| f0bc08e006 | |||
| e0f8e39a47 | |||
| 8b9f787095 | |||
| d946cf27fe | |||
| 5842ad1d56 | |||
| 201047251d | |||
| 5c8e771939 | |||
| b22e28b548 | |||
| 8c51836a47 | |||
| df729938c5 | |||
| 67d0dfcef0 | |||
| 03c95e5cad | |||
| c0a07002f2 | |||
| 5a9c3154fa | |||
| e35aed761b | |||
| 823f2ef028 | |||
| 11cfdba5cb | |||
| 5b78b2e897 | |||
| 773b8db337 | |||
| d15d4c621c | |||
| 788cad3cbe | |||
| f6ccbf7711 | |||
| e6fb545d1d | |||
| ce7ecd3863 | |||
| c8d85e09d7 | |||
| 34bc662065 | |||
| a54cbee79a | |||
| df873a19e1 | |||
| b5695b50c2 | |||
| f22b8ede02 | |||
| 893b3a6bff | |||
| e199a2fb79 | |||
| b4aac9d7d7 | |||
| cf9bd0f373 | |||
| 17deaf963e | |||
| e66a83a4cf | |||
| 96905012a4 | |||
| 591dba8829 | |||
| d10dd2095a | |||
| 22e25d0c78 | |||
| 1c8375908c | |||
| 099a390f2f | |||
| dd2d343630 | |||
| 543eed9a53 | |||
| 4860bc35d6 | |||
| 8559ab2dcd | |||
| 811485661f | |||
| 31ead528f1 | |||
| 8641442c3f | |||
| 418902512d | |||
| fbfe2b2d1a | |||
| f71c4f6d5a | |||
| b46d9d8b8e | |||
| 9d27106964 | |||
| bbb873c27b | |||
| da50a48dd5 | |||
| c8e4de9831 | |||
| e0d733f030 | |||
| ff8e0e72d2 | |||
| 63971fd245 | |||
| 6b6827b915 | |||
| 7447a95299 | |||
| bfdcab5b57 | |||
| 01c202bd93 | |||
| 0c2953ac66 | |||
| c0774b89d6 | |||
| 030f34d405 | |||
| cedc93fe7b | |||
| e155767289 | |||
| 4e41223b81 | |||
| 2ee4d7daac | |||
| a6a0a03b44 | |||
| 4b3241a286 | |||
| d37bf7252d | |||
| dd66626165 | |||
| fe7e684e85 | |||
| 2281caaff8 | |||
| 96c838d3f3 | |||
| c6e1677369 | |||
| ea18d93a40 | |||
| f6e1e5c96b | |||
| 0b85fc74eb | |||
| 946eb0eacd | |||
| a11ec589f0 | |||
| a89955b080 | |||
| df4350666a | |||
| 55b1603b83 | |||
| fb1c727641 | |||
| 87d964c7ca | |||
| bdb0a9262c | |||
| e42dfe63c3 | |||
| e8932895e8 | |||
| 4091d33c56 | |||
| 5df2a751ea | |||
| 65b9f0005b | |||
| a3e4b4fe22 | |||
| 0749704400 | |||
| 9977cb688d | |||
| 8c26e776c2 | |||
| e174eddef1 | |||
| f866c90687 | |||
| a61a956b84 | |||
| ef73c4a97d | |||
| 79c02ebf7c | |||
| 1394a0ae2e | |||
| e8ebae7ee9 | |||
| 3fae29ba8f | |||
| a9373fb4e4 | |||
| 2e2cf64452 | |||
| 7c3835bd9f | |||
| 945fd3a402 | |||
| 53d2dbd420 | |||
| eaa4721b36 | |||
| f695ae9116 | |||
| b0270f36f9 | |||
| fe5b07e0d0 | |||
| 8396f000e1 | |||
| 1361e8cd18 | |||
| b3ac696312 | |||
| 2205712bc0 | |||
| f1741c66bf |
+2
-2
@@ -7,10 +7,10 @@ tab_width = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{md,fflogo}]
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{fflogo}]
|
||||
[*.txt]
|
||||
insert_final_newline = false
|
||||
|
||||
[*.yml]
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
github: [LinusDierheimer, CarterLi]
|
||||
github: [CarterLi, LinusDierheimer]
|
||||
|
||||
+12
-12
@@ -35,7 +35,7 @@ jobs:
|
||||
run: uname -a
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OSMESA=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_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_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 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
|
||||
|
||||
- name: install linuxbrew packages
|
||||
run: |
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev directx-headers-dev rpm
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -181,7 +181,7 @@ jobs:
|
||||
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
|
||||
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
|
||||
dpkg -i *.deb
|
||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev directx-headers-dev rpm
|
||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -216,7 +216,7 @@ jobs:
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev directx-headers-dev rpm
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -247,7 +247,7 @@ 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 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 gcc g++
|
||||
shell: alpine.sh --root {0}
|
||||
|
||||
- name: build
|
||||
@@ -288,7 +288,7 @@ 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 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 gcc g++
|
||||
shell: alpine.sh --root {0}
|
||||
|
||||
- name: build
|
||||
@@ -388,8 +388,8 @@ jobs:
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
@@ -422,12 +422,12 @@ jobs:
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd v4l_compat
|
||||
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 .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./fastfetch -c presets/ci.jsonc --stat false
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
+102
@@ -1,3 +1,105 @@
|
||||
# 2.23.0
|
||||
|
||||
Features:
|
||||
* Support unity version detection (DE, Linux)
|
||||
* Print model name in Battery keys if available (Battery)
|
||||
* Add module `Zpool`
|
||||
* Improve performance (Shell / Terminal, Linux)
|
||||
* Support syntax of padded strings in `--<module>-format`. `{variable<padlength}` and `{variable>padlength}` are supported.
|
||||
* If pad length is greater than the length of the variable, the variable will be padded with spaces.
|
||||
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1<20})'` prints `Command: output(12345 )`
|
||||
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1>20})'` prints `Command: output( 12345)`
|
||||
* If pad length is less than the length of the variable, the variable will be truncated.
|
||||
|
||||
Bugfixes:
|
||||
* Fix broken `--list-presets`
|
||||
* Update zsh completion script
|
||||
* Don't print `*` if `defaultRouteOnly` is set (NetIO)
|
||||
* Fix Camera module incorrectly disabled on FreeBSD (Camera, FreeBSD)
|
||||
* Fix hanging on screen 5.0 (Terminal)
|
||||
* Improve image logo support on Windows (Logo, Windows)
|
||||
|
||||
Logos:
|
||||
* Update AmogOS
|
||||
* Add Magix
|
||||
* Make ubuntu logo colorable
|
||||
* Add Steam Deck Logo
|
||||
* add Huawei Cloud EulerOS
|
||||
|
||||
# 2.22.0
|
||||
|
||||
Features:
|
||||
* Small performance improvements (Terminal, Editor)
|
||||
* Improve arm32 and loongarch support (CPU, Linux)
|
||||
* Ignore the parent process if env `$FFTS_IGNORE_PARENT` is set to `1` (Shell)
|
||||
* Add code name of Apple M4 (CPU, Linux)
|
||||
* Add ethernet speed rate detection support (LocalIP)
|
||||
* Add zsh completion script
|
||||
* Add Linglong package manager detection support (Packages, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix building on macOS 10.14
|
||||
* Fix tmux in linux TTY (Colors)
|
||||
* Fix hang in WSL when custom format is used (Disk, Linux)
|
||||
* Fix `/proc/loadavg` parsing (Loadavg, Linux)
|
||||
* Disable use of `LC_NUMERIC` locale settings to fix parsing of decimal numbers
|
||||
* Fix possible segfault (DiskIO, Linux)
|
||||
* Honor `preciseRefreshRate` in custom format (Display)
|
||||
|
||||
Logos:
|
||||
* Add Lingmo OS
|
||||
* Add Sleeper OS
|
||||
|
||||
# 2.21.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix bad Intel Arc GPU name detection, which was supposed to be fixed in the last version but the change was reverted accidentally (#1177, GPU, Linux)
|
||||
* Fix arm32 CPU name detection no longer work. Regression of 2.21.2 (CPU, Linux)
|
||||
|
||||
# 2.21.2
|
||||
|
||||
Features:
|
||||
* Support `--stat <num_in_ms>` to display long running modules in yellow or red
|
||||
|
||||
Bugfixes:
|
||||
* Fix bad Intel Arc GPU name and type detection (GPU, Linux)
|
||||
* Fix uninited struct fields (GPU, Linux)
|
||||
* Skip cpu model smbios detection on ARM platforms (CPU, Linux)
|
||||
* Always use `CurrentControlSet` instead of `ControlSet001` when querying registry (Windows)
|
||||
* Fix NVIDIA GPUs are missing in GPU detection sometimes (GPU, Windows)
|
||||
* Fixing detection of `pthread_timedjoin_np` (Linux)
|
||||
|
||||
Logos:
|
||||
* Add HyprOS
|
||||
* Add GoldenDog Linux
|
||||
|
||||
# 2.21.1
|
||||
|
||||
Hotfix for a regression that breaks WM detection when running `startx` from TTY (Regression from 2.21.0, #1172 / #1162)
|
||||
|
||||
Changes:
|
||||
* On Linux, FreeBSD and SunOS, a new recommended dependency `libelf` is introduced to extract strings in ELF binary, used for
|
||||
* st term font detection when the term font is compiled directly into the binary
|
||||
* fast path of systemd version detection
|
||||
|
||||
Features:
|
||||
* Improve performance of
|
||||
* kitty version detection (Terminal, Linux)
|
||||
* st term font detection (TerminalFont, Linux)
|
||||
* systemd version detection (InitSystem, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix building error without `linux/wireless.h` (Wifi, Linux)
|
||||
* Fix wrong GPU max frequency on Asahi Linux (GPU, Linux)
|
||||
* Don't rely `$XDG_SESSION_TYPE` for detecting wm protocol (#1172 / #1162, WM, Linux)
|
||||
* Fix light color doesn't work on Linux console (Colors, Linux)
|
||||
* `LC_ALL`, if set, overrides every other locale-related environment variable (Locale)
|
||||
* Increase timeout of DBus calls (Linux)
|
||||
|
||||
Logos:
|
||||
* Add vanilla_small and vanilla2
|
||||
* Add LFS (Linux From Scratch)
|
||||
|
||||
# 2.21.0
|
||||
|
||||
Changes:
|
||||
|
||||
+78
-11
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.21.0
|
||||
VERSION 2.23.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -69,7 +69,9 @@ cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
@@ -201,10 +203,10 @@ if (SET_TWEAK AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
execute_process(
|
||||
COMMAND git describe --tags
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE PROJECT_VERSION_TWEAK
|
||||
OUTPUT_VARIABLE PROJECT_VERSION_GIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(REGEX MATCH "-[0-9]+" PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}")
|
||||
string(REGEX MATCH "-[0-9]+" PROJECT_VERSION_TWEAK "${PROJECT_VERSION_GIT}")
|
||||
endif()
|
||||
if(PROJECT_VERSION_TWEAK)
|
||||
string(REGEX MATCH "[0-9]+" PROJECT_VERSION_TWEAK_NUM "${PROJECT_VERSION_TWEAK}")
|
||||
@@ -391,6 +393,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/wifi/wifi.c
|
||||
src/modules/wm/wm.c
|
||||
src/modules/wmtheme/wmtheme.c
|
||||
src/modules/zpool/zpool.c
|
||||
src/options/display.c
|
||||
src/options/modules.c
|
||||
src/options/logo.c
|
||||
@@ -400,6 +403,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/util/base64.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFstrbuf.c
|
||||
src/util/path.c
|
||||
src/util/platform/FFPlatform.c
|
||||
src/util/smbiosHelper.c
|
||||
)
|
||||
@@ -479,7 +483,9 @@ if(LINUX)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -540,7 +546,9 @@ elseif(ANDROID)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/camera/camera_android.c
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -618,7 +626,9 @@ elseif(FreeBSD)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_linux.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -681,9 +691,11 @@ elseif(APPLE)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/camera/camera_apple.m
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/apple/cf_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_apple.c
|
||||
)
|
||||
elseif(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -744,12 +756,14 @@ elseif(WIN32)
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/detection/camera/camera_windows.cpp
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/com.cpp
|
||||
src/util/windows/registry.c
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/wmi.cpp
|
||||
src/util/platform/FFPlatform_windows.c
|
||||
src/util/binary_windows.c
|
||||
)
|
||||
elseif(SunOS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
@@ -825,7 +839,9 @@ elseif(SunOS)
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_nosupport.c
|
||||
src/detection/zpool/zpool_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
src/util/binary_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1075,10 +1091,33 @@ ff_lib_enable(DDCUTIL
|
||||
"ddcutil"
|
||||
"Ddcutil"
|
||||
)
|
||||
ff_lib_enable(ELF
|
||||
"libelf"
|
||||
"libelf"
|
||||
)
|
||||
ff_lib_enable(DIRECTX_HEADERS
|
||||
"DirectX-Headers"
|
||||
"DirectX-Headers"
|
||||
)
|
||||
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
|
||||
if(ENABLE_LIBZFS)
|
||||
if(BINARY_LINK_TYPE STREQUAL "dlopen")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
|
||||
check_function_exists("libzfs_init" LIBZFS_FOUND)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
|
||||
if(NOT LIBZFS_FOUND)
|
||||
message(STATUS "Library: missing: LIBZFS")
|
||||
else()
|
||||
message(STATUS "Library: found LIBZFS")
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
|
||||
target_link_libraries(libfastfetch PRIVATE zfs)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(ENABLE_THREADS)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
|
||||
@@ -1127,6 +1166,7 @@ elseif(WIN32)
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "hid"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "imagehlp"
|
||||
)
|
||||
elseif(FreeBSD)
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -1140,6 +1180,8 @@ elseif(SunOS)
|
||||
PRIVATE "socket"
|
||||
PRIVATE "kstat"
|
||||
PRIVATE "proc"
|
||||
PRIVATE "zfs"
|
||||
PRIVATE "nvpair"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
@@ -1183,11 +1225,16 @@ if(WIN32)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
if(LINUX)
|
||||
if(FreeBSD)
|
||||
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
|
||||
endif()
|
||||
if(LINUX OR FreeBSD)
|
||||
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
|
||||
if(HAVE_LINUX_VIDEODEV2)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
|
||||
endif()
|
||||
endif()
|
||||
if(LINUX)
|
||||
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
|
||||
if(HAVE_LINUX_WIRELESS)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
|
||||
@@ -1202,13 +1249,19 @@ if(NOT WIN32)
|
||||
if(HAVE_WORDEXP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WORDEXP=1)
|
||||
endif()
|
||||
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
|
||||
if(HAVE_PTHREAD_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_PTHREAD_NP=1)
|
||||
endif()
|
||||
check_function_exists("pthread_timedjoin_np" HAVE_TIMEDJOIN_NP)
|
||||
if(HAVE_TIMEDJOIN_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_TIMEDJOIN_NP=1)
|
||||
if(ENABLE_THREADS AND CMAKE_USE_PTHREADS_INIT)
|
||||
CHECK_INCLUDE_FILE("pthread_np.h" HAVE_PTHREAD_NP)
|
||||
if(HAVE_PTHREAD_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_PTHREAD_NP=1)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} pthread_np.h)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} Threads::Threads)
|
||||
check_function_exists("pthread_timedjoin_np" HAVE_TIMEDJOIN_NP)
|
||||
if(HAVE_TIMEDJOIN_NP)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_TIMEDJOIN_NP=1)
|
||||
else()
|
||||
message(WARNING "pthread_timedjoin_np was not found; networking timeout will not work")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1289,9 +1342,17 @@ if (BUILD_TESTS)
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
add_executable(fastfetch-test-format
|
||||
tests/format.c
|
||||
)
|
||||
target_link_libraries(fastfetch-test-format
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
|
||||
add_test(NAME test-list COMMAND fastfetch-test-list)
|
||||
add_test(NAME test-format COMMAND fastfetch-test-format)
|
||||
endif()
|
||||
|
||||
##################
|
||||
@@ -1318,6 +1379,12 @@ install(
|
||||
RENAME "${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.zsh"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions"
|
||||
RENAME "_${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.fish"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d"
|
||||
|
||||
@@ -30,17 +30,23 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian: `apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
* Arch Linux: `pacman -S fastfetch`
|
||||
* Fedora: `dnf install fastfetch`
|
||||
* Gentoo: `emerge --ask app-misc/fastfetch`
|
||||
* Alpine: `apk add --upgrade fastfetch`
|
||||
* NixOS: `nix-shell -p fastfetch`
|
||||
* openSUSE: `sudo zypper install fastfetch`
|
||||
* ALT Linux: `sudo apt-get install fastfetch`
|
||||
* openSUSE: `zypper install fastfetch`
|
||||
* ALT Linux: `apt-get install fastfetch`
|
||||
* Exherbo: `cave resolve --execute app-misc/fastfetch`
|
||||
* GNU Guix: `guix install fastfetch`
|
||||
* Solus: `eopkg install fastfetch`
|
||||
* Slackware: `sbopkg -i fastfetch`
|
||||
* Void Linux: `xbps-install fastfetch`
|
||||
* Venom Linux: `scratch install fastfetch`
|
||||
|
||||
Replace sudo with doas depending on what you use.
|
||||
You may need `sudo`, `doas` or `sup` to run these commands.
|
||||
|
||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging).
|
||||
|
||||
@@ -54,8 +60,9 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
|
||||
### Windows
|
||||
|
||||
* [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch`
|
||||
* [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch`
|
||||
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
|
||||
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#compdef fastfetch
|
||||
|
||||
function _fastfetch() {
|
||||
local state
|
||||
|
||||
local -a opts=("${(f)$(
|
||||
python3 <<EOF
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
data: dict[str, list[dict]] = json.loads(
|
||||
subprocess.check_output(["fastfetch", "--help-raw"])
|
||||
)
|
||||
|
||||
for key in data:
|
||||
for flag in data[key]:
|
||||
if flag["long"] == "logo-color-[1-9]":
|
||||
for i in range(1, 10):
|
||||
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
|
||||
print_command(command_prefix, flag)
|
||||
continue
|
||||
|
||||
if flag.get("pseudo", False):
|
||||
continue
|
||||
|
||||
if "short" in flag:
|
||||
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
if "long" in flag:
|
||||
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
|
||||
print_command(command_prefix, flag)
|
||||
|
||||
|
||||
def print_command(command_prefix: str, flag: dict):
|
||||
if "arg" in flag:
|
||||
type: str = flag["arg"]["type"]
|
||||
if type == "bool":
|
||||
print(f"{command_prefix}::bool:(true false)")
|
||||
elif type == "color":
|
||||
print(f"{command_prefix}:color:->colors")
|
||||
elif type == "command":
|
||||
print(f"{command_prefix}::module:->modules")
|
||||
elif type == "config":
|
||||
print(f"{command_prefix}:preset:->presets")
|
||||
elif type == "enum":
|
||||
temp: str = " ".join(flag["arg"]["enum"])
|
||||
print(f'{command_prefix}:type:({temp})')
|
||||
elif type == "logo":
|
||||
print(f"{command_prefix}:logo:->logos")
|
||||
elif type == "structure":
|
||||
print(f"{command_prefix}:structure:->structures")
|
||||
elif type == "path":
|
||||
print(f"{command_prefix}::path:_files")
|
||||
else:
|
||||
print(f"{command_prefix}:")
|
||||
else:
|
||||
print(f"{command_prefix}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
sys.exit(1)
|
||||
EOF
|
||||
)}")
|
||||
|
||||
_arguments "$opts[@]"
|
||||
|
||||
case $state in
|
||||
colors)
|
||||
local -a colors=(black red green yellow blue magenta cyan white default)
|
||||
_describe 'color' colors
|
||||
;;
|
||||
modules)
|
||||
local -a modules=("${(f)$(fastfetch --list-modules autocompletion)}")
|
||||
modules=(${(L)^modules[@]%%:*}-format format color)
|
||||
_describe 'module' modules
|
||||
;;
|
||||
presets)
|
||||
local -a presets=(
|
||||
"${(f)$(fastfetch --list-presets autocompletion)}"
|
||||
"none:Disable loading config file"
|
||||
)
|
||||
_describe 'preset' presets || _files
|
||||
;;
|
||||
structures)
|
||||
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
|
||||
_describe 'structure' structures
|
||||
;;
|
||||
logos)
|
||||
local -a logos=(
|
||||
"${(f)$(fastfetch --list-logos autocompletion)}"
|
||||
"none:Don't print logo"
|
||||
"small:Print small ascii logo if available"
|
||||
)
|
||||
_describe 'logo' logos
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_fastfetch "$@"
|
||||
Vendored
+36
@@ -1,3 +1,39 @@
|
||||
fastfetch (2.22.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.22.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 26 Aug 2024 18:53:35 +0800
|
||||
|
||||
fastfetch (2.21.3) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.3
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 15 Aug 2024 16:14:52 +0800
|
||||
|
||||
fastfetch (2.21.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.2
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 14 Aug 2024 14:42:07 +0800
|
||||
|
||||
fastfetch (2.21.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 09 Aug 2024 14:27:10 +0800
|
||||
|
||||
fastfetch (2.21.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.21.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 05 Aug 2024 14:35:43 +0800
|
||||
|
||||
fastfetch (2.20.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.20.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 26 Jul 2024 14:02:50 +0800
|
||||
|
||||
fastfetch (2.19.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.19.1
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.19.1_source.buildinfo universe/utils optional
|
||||
fastfetch_2.22.0_source.buildinfo universe/utils optional
|
||||
|
||||
+21
-4
@@ -357,9 +357,17 @@
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"stat": {
|
||||
"type": "boolean",
|
||||
"description": "Show time usage (in ms) for individual modules",
|
||||
"default": false
|
||||
"description": "Show time usage (in ms) for individual modules with optional threshold",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"pipe": {
|
||||
"type": "boolean",
|
||||
@@ -730,6 +738,10 @@
|
||||
"ddcutil": {
|
||||
"description": "Used for brightness detection of external displays (Linux)",
|
||||
"type": "string"
|
||||
},
|
||||
"elf": {
|
||||
"description": "Used for st terminal font detection and systemd version detection (Linux)",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -808,7 +820,8 @@
|
||||
"weather",
|
||||
"wm",
|
||||
"wifi",
|
||||
"wmtheme"
|
||||
"wmtheme",
|
||||
"zpool"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -981,6 +994,10 @@
|
||||
{
|
||||
"const": "wmtheme",
|
||||
"description": "Print current theme of window manager"
|
||||
},
|
||||
{
|
||||
"const": "zpool",
|
||||
"description": "Print ZFS storage pools"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
+5
-1
@@ -54,11 +54,15 @@
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"zpool",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
"publicip",
|
||||
{
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"showIpv6": true,
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
},
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "WAN IP"
|
||||
"key": "WAN IP",
|
||||
"timeout": 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+5
-1
@@ -56,11 +56,15 @@
|
||||
"physicalmemory",
|
||||
"swap",
|
||||
"disk",
|
||||
"zpool",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
"publicip",
|
||||
{
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"showIpv6": true,
|
||||
|
||||
@@ -97,7 +97,8 @@
|
||||
{
|
||||
"key": "Public IP ",
|
||||
"keyColor": "cyan",
|
||||
"type": "publicip"
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
"break",
|
||||
{
|
||||
|
||||
@@ -66,7 +66,10 @@
|
||||
"type": "localip",
|
||||
"compact": true
|
||||
},
|
||||
"publicip",
|
||||
{
|
||||
"type": "publicip",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "wifi",
|
||||
"format": "{ssid}"
|
||||
|
||||
@@ -111,8 +111,7 @@
|
||||
{
|
||||
"type": "loadavg",
|
||||
"compact": false,
|
||||
// {duration} is not fixed length, hack it
|
||||
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
|
||||
"key": "│ LOAD {duration>2}m │{$1}" // pad duration to 2 chars
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// designed for presenting Vanilla Linux
|
||||
// inspired from imstilllearnin's Vanilla Logo Ultra
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"color": {
|
||||
"output": "cyan"
|
||||
},
|
||||
"separator": ""
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "[_Kernel___> ",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"outputColor": "white",
|
||||
"key": " [_Packages_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"outputColor": "white",
|
||||
"key": " [_Local_IP_> ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_RAM______> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"format": "[{3}] {1} / {2}",
|
||||
"key": " [_SWAP_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"format": "[{3}] {1} / {2} {9}",
|
||||
"key": " [_Disk_____> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"format": "[{4}] {5}",
|
||||
"key": " [_Battery__> ",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 9,
|
||||
"symbol": "circle"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -161,7 +161,8 @@
|
||||
{
|
||||
"type": "publicip",
|
||||
"key": "├─",
|
||||
"keyColor": "blue"
|
||||
"keyColor": "blue",
|
||||
"timeout": 1000
|
||||
},
|
||||
{
|
||||
"type": "wifi",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "commandoption.h"
|
||||
#include "common/color.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/time.h"
|
||||
#include "common/jsonconfig.h"
|
||||
@@ -105,32 +106,35 @@ static void parseStructureCommand(
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
//Parse the structure and call the modules
|
||||
int32_t thres = instance.config.display.stat;
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
uint64_t ms = 0;
|
||||
if(instance.config.display.stat)
|
||||
double ms = 0;
|
||||
if(thres >= 0)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc);
|
||||
|
||||
if(instance.config.display.stat)
|
||||
if(thres >= 0)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
char str[64];
|
||||
int len = snprintf(str, sizeof str, "%.3fms", ms);
|
||||
if (thres > 0)
|
||||
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
|
||||
printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -6,7 +6,8 @@
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "common/library.h"
|
||||
|
||||
#define FF_DBUS_TIMEOUT_MILLISECONDS 35
|
||||
#define FF_DBUS_TIMEOUT_MILLISECONDS 100
|
||||
|
||||
typedef struct FFDBusLibrary
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(dbus_bus_get)
|
||||
|
||||
+58
-13
@@ -265,18 +265,34 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t truncLength = INT32_MAX;
|
||||
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pColon != NULL)
|
||||
int32_t truncLength = 0;
|
||||
char align = '\0';
|
||||
char* pSep = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pSep)
|
||||
align = ':';
|
||||
else
|
||||
{
|
||||
pSep = memchr(placeholderValue.chars, '<', placeholderValue.length);
|
||||
if (pSep)
|
||||
align = '<';
|
||||
else
|
||||
{
|
||||
pSep = memchr(placeholderValue.chars, '>', placeholderValue.length);
|
||||
if (pSep)
|
||||
align = '>';
|
||||
}
|
||||
}
|
||||
|
||||
if (pSep)
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
|
||||
truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
|
||||
if (*pEnd != '\0')
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
*pColon = '\0';
|
||||
*pSep = '\0';
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
@@ -287,7 +303,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
|
||||
if (index > numArgs)
|
||||
{
|
||||
if (pColon) *pColon = ':';
|
||||
if (pSep) *pSep = align;
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
@@ -299,14 +315,43 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
truncLength = -truncLength;
|
||||
}
|
||||
|
||||
uint32_t oldLength = buffer->length;
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
if (buffer->length - oldLength > (uint32_t) truncLength)
|
||||
if (!align)
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
else
|
||||
{
|
||||
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
ffStrbufClear(&placeholderValue);
|
||||
ffFormatAppendFormatArg(&placeholderValue, &arguments[index - 1]);
|
||||
if (placeholderValue.length == (uint32_t) truncLength)
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
else if (placeholderValue.length > (uint32_t) truncLength)
|
||||
{
|
||||
if (align == ':')
|
||||
{
|
||||
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(&placeholderValue);
|
||||
}
|
||||
else
|
||||
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
}
|
||||
else if (align == ':')
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
else
|
||||
{
|
||||
if (align == '<')
|
||||
{
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
|
||||
ffStrbufAppend(buffer, &placeholderValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -54,10 +54,6 @@ void ffInitInstance(void)
|
||||
#else
|
||||
// Never use `setlocale(LC_ALL, "")`
|
||||
setlocale(LC_TIME, "");
|
||||
setlocale(LC_NUMERIC, "");
|
||||
#ifdef LC_MESSAGES
|
||||
setlocale(LC_MESSAGES, "");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
initState(&instance.state);
|
||||
@@ -248,6 +244,12 @@ void ffListFeatures(void)
|
||||
#if FF_HAVE_DDCUTIL
|
||||
"libddcutil\n"
|
||||
#endif
|
||||
#if FF_HAVE_ELF
|
||||
"libelf\n"
|
||||
#endif
|
||||
#if FF_HAVE_LIBZFS
|
||||
"libzfs\n"
|
||||
#endif
|
||||
#if FF_HAVE_DIRECTX_HEADERS
|
||||
"Directx Headers\n"
|
||||
#endif
|
||||
|
||||
@@ -144,7 +144,7 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
if (ftty < 0)
|
||||
{
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
|
||||
if (ftty < 0)
|
||||
return "open(\"/dev/tty\", O_RDWR | O_NOCTTY | O_CLOEXEC) failed";
|
||||
|
||||
@@ -232,12 +232,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(entry->d_name[0] == '.') // skip hidden files
|
||||
continue;
|
||||
|
||||
bool isDir = false;
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
#ifndef __sun
|
||||
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
|
||||
isDir = entry->d_type == DT_DIR;
|
||||
else
|
||||
#else
|
||||
#endif
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
|
||||
@@ -245,12 +248,8 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
else
|
||||
isDir = S_ISDIR(stbuf.st_mode);
|
||||
}
|
||||
#endif
|
||||
if (isDir)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(folder, entry->d_name);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
|
||||
|
||||
+11
-7
@@ -1,4 +1,5 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/color.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/io/io.h"
|
||||
@@ -181,12 +182,13 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
if (!modules) return NULL;
|
||||
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
||||
|
||||
int32_t thres = instance.config.display.stat;
|
||||
yyjson_val* item;
|
||||
size_t idx, max;
|
||||
yyjson_arr_foreach(modules, idx, max, item)
|
||||
{
|
||||
uint64_t ms = 0;
|
||||
if(!prepare && instance.config.display.stat)
|
||||
double ms = 0;
|
||||
if(!prepare && thres >= 0)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
yyjson_val* module = item;
|
||||
@@ -208,19 +210,21 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
else if(!parseModuleJsonObject(type, module, jsonDoc))
|
||||
return "Unknown module type";
|
||||
|
||||
if(!prepare && instance.config.display.stat)
|
||||
if(!prepare && thres >= 0)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_obj_add_real(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
char str[64];
|
||||
int len = snprintf(str, sizeof str, "%.3fms", ms);
|
||||
if (thres > 0)
|
||||
snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms);
|
||||
printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ static FFModuleBaseInfo* Y[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* Z[] = {
|
||||
(void*) &instance.config.modules.zpool,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -9,22 +9,22 @@
|
||||
#include <sysinfoapi.h>
|
||||
#endif
|
||||
|
||||
static inline uint64_t ffTimeGetTick() //In msec
|
||||
static inline double ffTimeGetTick(void) //In msec
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
LARGE_INTEGER start;
|
||||
QueryPerformanceCounter(&start);
|
||||
return (uint64_t)(start.QuadPart * 1000 / frequency.QuadPart);
|
||||
return (double) start.QuadPart * 1000 / (double) frequency.QuadPart;
|
||||
#else
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
|
||||
return (double) timeNow.tv_sec * 1000. + (double) timeNow.tv_nsec / 1000000.;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint64_t ffTimeGetNow()
|
||||
static inline uint64_t ffTimeGetNow(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
uint64_t timeNow;
|
||||
|
||||
@@ -935,6 +935,13 @@
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-elf",
|
||||
"desc": "Used for st terminal font detection and systemd version detection",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Module specific": [
|
||||
|
||||
@@ -13,6 +13,10 @@ For example: "--title-format '{user-name:5}'" will truncate user name into 5-len
|
||||
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
|
||||
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
|
||||
|
||||
In 2.23.0 or newer, `<` or `>` can be specified instead of `:` to set a left or right padding.
|
||||
For example: "--title-format '{user-name<20}'" will generate `<user-name> `;
|
||||
"--title-format '{user-name>20}'" will generate ` <user-name>`
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
|
||||
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
|
||||
|
||||
@@ -46,7 +46,7 @@ const char* ffDetectBootmgr(FFBootmgrResult* result)
|
||||
ffEfiFillLoadOption((FFEfiLoadOption *)buffer, result);
|
||||
|
||||
DWORD uefiSecureBootEnabled = 0, bufSize = 0;
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\ControlSet001\\Control\\SecureBoot\\State", L"UEFISecureBootEnabled", RRF_RT_REG_DWORD, NULL, &uefiSecureBootEnabled, &bufSize) == ERROR_SUCCESS)
|
||||
if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State", L"UEFISecureBootEnabled", RRF_RT_REG_DWORD, NULL, &uefiSecureBootEnabled, &bufSize) == ERROR_SUCCESS)
|
||||
result->secureBoot = !!uefiSecureBootEnabled;
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -36,6 +36,7 @@ const char* ffCPUAppleCodeToName(uint32_t code)
|
||||
case 6030: return "Apple M3 Pro";
|
||||
case 6031:
|
||||
case 6034: return "Apple M3 Max";
|
||||
case 8132: return "Apple M4";
|
||||
default: return "Apple Silicon";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,3 +30,30 @@ typedef struct FFCPUResult
|
||||
|
||||
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
|
||||
const char* ffCPUAppleCodeToName(uint32_t code);
|
||||
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
// WARNING: CPUID may report frequencies of efficient cores
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* ffCPUDetectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
// https://github.com/util-linux/util-linux/blob/master/sys-utils/lscpu-arm.c
|
||||
// We use the util-linux's data but not its code. Call me if it violates util-linux's GPL license.
|
||||
|
||||
static const char* hwImplId2Vendor(uint32_t implId)
|
||||
{
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: return "ARM";
|
||||
case 0x42: return "Broadcom";
|
||||
case 0x43: return "Cavium";
|
||||
case 0x44: return "DEC";
|
||||
case 0x46: return "FUJITSU";
|
||||
case 0x48: return "HiSilicon";
|
||||
case 0x49: return "Infineon";
|
||||
case 0x4d: return "Motorola";
|
||||
case 0x4e: return "NVIDIA";
|
||||
case 0x50: return "APM";
|
||||
case 0x51: return "Qualcomm";
|
||||
case 0x53: return "Samsung";
|
||||
case 0x56: return "Marvell";
|
||||
case 0x61: return "Apple";
|
||||
case 0x66: return "Faraday";
|
||||
case 0x69: return "Intel";
|
||||
case 0x6D: return "Microsoft";
|
||||
case 0x70: return "Phytium";
|
||||
case 0xc0: return "Ampere";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* armPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x810: return "ARM810";
|
||||
case 0x920: return "ARM920";
|
||||
case 0x922: return "ARM922";
|
||||
case 0x926: return "ARM926";
|
||||
case 0x940: return "ARM940";
|
||||
case 0x946: return "ARM946";
|
||||
case 0x966: return "ARM966";
|
||||
case 0xa20: return "ARM1020";
|
||||
case 0xa22: return "ARM1022";
|
||||
case 0xa26: return "ARM1026";
|
||||
case 0xb02: return "ARM11 MPCore";
|
||||
case 0xb36: return "ARM1136";
|
||||
case 0xb56: return "ARM1156";
|
||||
case 0xb76: return "ARM1176";
|
||||
case 0xc05: return "Cortex-A5";
|
||||
case 0xc07: return "Cortex-A7";
|
||||
case 0xc08: return "Cortex-A8";
|
||||
case 0xc09: return "Cortex-A9";
|
||||
case 0xc0d: return "Cortex-A17"; /* Originally A12 */
|
||||
case 0xc0f: return "Cortex-A15";
|
||||
case 0xc0e: return "Cortex-A17";
|
||||
case 0xc14: return "Cortex-R4";
|
||||
case 0xc15: return "Cortex-R5";
|
||||
case 0xc17: return "Cortex-R7";
|
||||
case 0xc18: return "Cortex-R8";
|
||||
case 0xc20: return "Cortex-M0";
|
||||
case 0xc21: return "Cortex-M1";
|
||||
case 0xc23: return "Cortex-M3";
|
||||
case 0xc24: return "Cortex-M4";
|
||||
case 0xc27: return "Cortex-M7";
|
||||
case 0xc60: return "Cortex-M0+";
|
||||
case 0xd01: return "Cortex-A32";
|
||||
case 0xd02: return "Cortex-A34";
|
||||
case 0xd03: return "Cortex-A53";
|
||||
case 0xd04: return "Cortex-A35";
|
||||
case 0xd05: return "Cortex-A55";
|
||||
case 0xd06: return "Cortex-A65";
|
||||
case 0xd07: return "Cortex-A57";
|
||||
case 0xd08: return "Cortex-A72";
|
||||
case 0xd09: return "Cortex-A73";
|
||||
case 0xd0a: return "Cortex-A75";
|
||||
case 0xd0b: return "Cortex-A76";
|
||||
case 0xd0c: return "Neoverse-N1";
|
||||
case 0xd0d: return "Cortex-A77";
|
||||
case 0xd0e: return "Cortex-A76AE";
|
||||
case 0xd13: return "Cortex-R52";
|
||||
case 0xd15: return "Cortex-R82";
|
||||
case 0xd16: return "Cortex-R52+";
|
||||
case 0xd20: return "Cortex-M23";
|
||||
case 0xd21: return "Cortex-M33";
|
||||
case 0xd22: return "Cortex-M55";
|
||||
case 0xd23: return "Cortex-M85";
|
||||
case 0xd40: return "Neoverse-V1";
|
||||
case 0xd41: return "Cortex-A78";
|
||||
case 0xd42: return "Cortex-A78AE";
|
||||
case 0xd43: return "Cortex-A65AE";
|
||||
case 0xd44: return "Cortex-X1";
|
||||
case 0xd46: return "Cortex-A510";
|
||||
case 0xd47: return "Cortex-A710";
|
||||
case 0xd48: return "Cortex-X2";
|
||||
case 0xd49: return "Neoverse-N2";
|
||||
case 0xd4a: return "Neoverse-E1";
|
||||
case 0xd4b: return "Cortex-A78C";
|
||||
case 0xd4c: return "Cortex-X1C";
|
||||
case 0xd4d: return "Cortex-A715";
|
||||
case 0xd4e: return "Cortex-X3";
|
||||
case 0xd4f: return "Neoverse-V2";
|
||||
case 0xd80: return "Cortex-A520";
|
||||
case 0xd81: return "Cortex-A720";
|
||||
case 0xd82: return "Cortex-X4";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* brcmPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x0f: return "Brahma-B15";
|
||||
case 0x100: return "Brahma-B53";
|
||||
case 0x516: return "ThunderX2";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* decPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xa10: return "SA110";
|
||||
case 0xa11: return "SA1100";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* caviumPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x0a0: return "ThunderX";
|
||||
case 0x0a1: return "ThunderX-88XX";
|
||||
case 0x0a2: return "ThunderX-81XX";
|
||||
case 0x0a3: return "ThunderX-83XX";
|
||||
case 0x0af: return "ThunderX2-99xx";
|
||||
case 0x0b0: return "OcteonTX2";
|
||||
case 0x0b1: return "OcteonTX2-98XX";
|
||||
case 0x0b2: return "OcteonTX2-96XX";
|
||||
case 0x0b3: return "OcteonTX2-95XX";
|
||||
case 0x0b4: return "OcteonTX2-95XXN";
|
||||
case 0x0b5: return "OcteonTX2-95XXMM";
|
||||
case 0x0b6: return "OcteonTX2-95XXO";
|
||||
case 0x0b8: return "ThunderX3-T110";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* apmPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "X-Gene";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* qcomPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "Oryon";
|
||||
case 0x00f: return "Scorpion";
|
||||
case 0x02d: return "Scorpion";
|
||||
case 0x04d: return "Krait";
|
||||
case 0x06f: return "Krait";
|
||||
case 0x201: return "Kryo";
|
||||
case 0x205: return "Kryo";
|
||||
case 0x211: return "Kryo";
|
||||
case 0x800: return "Falkor-V1/Kryo";
|
||||
case 0x801: return "Kryo-V2";
|
||||
case 0x802: return "Kryo-3XX-Gold";
|
||||
case 0x803: return "Kryo-3XX-Silver";
|
||||
case 0x804: return "Kryo-4XX-Gold";
|
||||
case 0x805: return "Kryo-4XX-Silver";
|
||||
case 0xc00: return "Falkor";
|
||||
case 0xc01: return "Saphira";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* samsungPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "Exynos-M1";
|
||||
case 0x002: return "Exynos-M3";
|
||||
case 0x003: return "Exynos-M4";
|
||||
case 0x004: return "Exynos-M5";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* nvidiaPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "Denver";
|
||||
case 0x003: return "Denver 2";
|
||||
case 0x004: return "Carmel";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* marvellPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x131: return "Feroceon-88FR131";
|
||||
case 0x581: return "PJ4/PJ4b";
|
||||
case 0x584: return "PJ4B-MP";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* applePartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x000: return "Swift";
|
||||
case 0x001: return "Cyclone";
|
||||
case 0x002: return "Typhoon";
|
||||
case 0x003: return "Typhoon/Capri";
|
||||
case 0x004: return "Twister";
|
||||
case 0x005: return "Twister/Elba/Malta";
|
||||
case 0x006: return "Hurricane";
|
||||
case 0x007: return "Hurricane/Myst";
|
||||
case 0x008: return "Monsoon";
|
||||
case 0x009: return "Mistral";
|
||||
case 0x00b: return "Vortex";
|
||||
case 0x00c: return "Tempest";
|
||||
case 0x00f: return "Tempest-M9";
|
||||
case 0x010: return "Vortex/Aruba";
|
||||
case 0x011: return "Tempest/Aruba";
|
||||
case 0x012: return "Lightning";
|
||||
case 0x013: return "Thunder";
|
||||
case 0x020: return "Icestorm-A14";
|
||||
case 0x021: return "Firestorm-A14";
|
||||
case 0x022: return "Icestorm-M1";
|
||||
case 0x023: return "Firestorm-M1";
|
||||
case 0x024: return "Icestorm-M1-Pro";
|
||||
case 0x025: return "Firestorm-M1-Pro";
|
||||
case 0x026: return "Thunder-M10";
|
||||
case 0x028: return "Icestorm-M1-Max";
|
||||
case 0x029: return "Firestorm-M1-Max";
|
||||
case 0x030: return "Blizzard-A15";
|
||||
case 0x031: return "Avalanche-A15";
|
||||
case 0x032: return "Blizzard-M2";
|
||||
case 0x033: return "Avalanche-M2";
|
||||
case 0x034: return "Blizzard-M2-Pro";
|
||||
case 0x035: return "Avalanche-M2-Pro";
|
||||
case 0x036: return "Sawtooth-A16";
|
||||
case 0x037: return "Everest-A16";
|
||||
case 0x038: return "Blizzard-M2-Max";
|
||||
case 0x039: return "Avalanche-M2-Max";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* faradayPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x526: return "FA526";
|
||||
case 0x626: return "FA626";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* intelPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x200: return "i80200";
|
||||
case 0x210: return "PXA250A";
|
||||
case 0x212: return "PXA210A";
|
||||
case 0x242: return "i80321-400";
|
||||
case 0x243: return "i80321-600";
|
||||
case 0x290: return "PXA250B/PXA26x";
|
||||
case 0x292: return "PXA210B";
|
||||
case 0x2c2: return "i80321-400-B0";
|
||||
case 0x2c3: return "i80321-600-B0";
|
||||
case 0x2d0: return "PXA250C/PXA255/PXA26x";
|
||||
case 0x2d2: return "PXA210C";
|
||||
case 0x411: return "PXA27x";
|
||||
case 0x41c: return "IPX425-533";
|
||||
case 0x41d: return "IPX425-400";
|
||||
case 0x41f: return "IPX425-266";
|
||||
case 0x682: return "PXA32x";
|
||||
case 0x683: return "PXA930/PXA935";
|
||||
case 0x688: return "PXA30x";
|
||||
case 0x689: return "PXA31x";
|
||||
case 0xb11: return "SA1110";
|
||||
case 0xc12: return "IPX1200";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* fujitsuPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x001: return "A64FX";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* hisiPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xd01: return "TaiShan-v110"; /* used in Kunpeng-920 SoC */
|
||||
case 0xd02: return "TaiShan-v120"; /* used in Kirin 990A and 9000S SoCs */
|
||||
case 0xd40: return "Cortex-A76"; /* HiSilicon uses this ID though advertises A76 */
|
||||
case 0xd41: return "Cortex-A77"; /* HiSilicon uses this ID though advertises A77 */
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* amperePartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xac3: return "Ampere-1";
|
||||
case 0xac4: return "Ampere-1a";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* ftPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0x303: return "FTC310";
|
||||
case 0x660: return "FTC660";
|
||||
case 0x661: return "FTC661";
|
||||
case 0x662: return "FTC662";
|
||||
case 0x663: return "FTC663";
|
||||
case 0x664: return "FTC664";
|
||||
case 0x862: return "FTC862";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* msPartId2name(uint32_t partId)
|
||||
{
|
||||
switch (partId)
|
||||
{
|
||||
case 0xd49: return "Azure-Cobalt-100";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
|
||||
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
|
||||
{
|
||||
ffStrbufClear(&buffer);
|
||||
|
||||
+124
-122
@@ -74,62 +74,120 @@ static void detectAndroid(FFCPUResult* cpu)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
|
||||
#if __arm__ || __aarch64__
|
||||
#include "cpu_arm.h"
|
||||
|
||||
static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
|
||||
{
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
rewind(cpuinfo);
|
||||
size_t len = 0;
|
||||
uint32_t lastPartId = UINT32_MAX;
|
||||
uint32_t num = 0;
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
if (!ffStrStartsWith(line, "CPU part\t: ")) continue;
|
||||
uint32_t partId = (uint32_t) strtoul(line + strlen("CPU part\t: "), NULL, 16);
|
||||
const char* name = NULL;
|
||||
if (partId > 0) // Linux reports 0 for unknown CPUs
|
||||
{
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: name = armPartId2name(partId); break;
|
||||
case 0x42: name = brcmPartId2name(partId); break;
|
||||
case 0x43: name = caviumPartId2name(partId); break;
|
||||
case 0x44: name = decPartId2name(partId); break;
|
||||
case 0x46: name = fujitsuPartId2name(partId); break;
|
||||
case 0x48: name = hisiPartId2name(partId); break;
|
||||
case 0x4e: name = nvidiaPartId2name(partId); break;
|
||||
case 0x50: name = apmPartId2name(partId); break;
|
||||
case 0x51: name = qcomPartId2name(partId); break;
|
||||
case 0x53: name = samsungPartId2name(partId); break;
|
||||
case 0x56: name = marvellPartId2name(partId); break;
|
||||
case 0x61: name = applePartId2name(partId); break;
|
||||
case 0x66: name = faradayPartId2name(partId); break;
|
||||
case 0x69: name = intelPartId2name(partId); break;
|
||||
case 0x6d: name = msPartId2name(partId); break;
|
||||
case 0x70: name = ftPartId2name(partId); break;
|
||||
case 0xc0: name = amperePartId2name(partId); break;
|
||||
}
|
||||
}
|
||||
if (lastPartId != partId)
|
||||
{
|
||||
if (lastPartId != UINT32_MAX)
|
||||
{
|
||||
if (num > 1)
|
||||
ffStrbufAppendF(&cpu->name, "*%u", num);
|
||||
ffStrbufAppendS(&cpu->name, " + ");
|
||||
}
|
||||
if (name)
|
||||
ffStrbufAppendS(&cpu->name, name);
|
||||
else if (partId)
|
||||
ffStrbufAppendF(&cpu->name, "%s-%X", cpu->vendor.chars, partId);
|
||||
else
|
||||
ffStrbufAppend(&cpu->name, &cpu->vendor);
|
||||
lastPartId = partId;
|
||||
num = 1;
|
||||
}
|
||||
else
|
||||
++num;
|
||||
}
|
||||
if (num > 1)
|
||||
ffStrbufAppendF(&cpu->name, "*%u", num);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* parseCpuInfo(
|
||||
FF_MAYBE_UNUSED FILE* cpuinfo,
|
||||
FF_MAYBE_UNUSED FFCPUResult* cpu,
|
||||
FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuMHz,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuIsa,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuUarch,
|
||||
FF_MAYBE_UNUSED FFstrbuf* cpuImplementer)
|
||||
{
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
#ifdef __aarch64__
|
||||
FF_STRBUF_AUTO_DESTROY implementer = ffStrbufCreate();
|
||||
#endif
|
||||
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
//Stop after the first CPU
|
||||
if(*line == '\0' || *line == '\n')
|
||||
//Stop after reasonable information is acquired
|
||||
if((*line == '\0' || *line == '\n')
|
||||
#if __arm__ || __loongarch__
|
||||
&& cpu->name.length > 0 // #1202 #1204
|
||||
#endif
|
||||
)
|
||||
break;
|
||||
|
||||
(void)(
|
||||
ffParsePropLine(line, "model name :", &cpu->name) ||
|
||||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
|
||||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
|
||||
ffParsePropLine(line, "cpu MHz :", cpuMHz) ||
|
||||
ffParsePropLine(line, "isa :", cpuIsa) ||
|
||||
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
||||
|
||||
#ifdef __aarch64__
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", &implementer)) ||
|
||||
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
|
||||
// "Hardware" should always be used in this case
|
||||
#if !(__arm__ || __aarch64__)
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
|
||||
#endif
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
|
||||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
|
||||
#endif
|
||||
|
||||
#if __arm__ || __aarch64__
|
||||
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
|
||||
#endif
|
||||
#if __powerpc__ || __powerpc
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
#endif
|
||||
#if __mips__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
|
||||
#endif
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef __aarch64__
|
||||
// https://github.com/util-linux/util-linux/blob/2cd89de14549d2b2c079a4f8b73f75500d229fee/sys-utils/lscpu-arm.c#L286
|
||||
if (cpu->vendor.length == 0 && implementer.length > 2 /* 0xX */)
|
||||
{
|
||||
uint32_t implId = (uint32_t) strtoul(implementer.chars, NULL, 16);
|
||||
switch (implId)
|
||||
{
|
||||
case 0x41: ffStrbufSetStatic(&cpu->vendor, "ARM"); break;
|
||||
case 0x42: ffStrbufSetStatic(&cpu->vendor, "Broadcom"); break;
|
||||
case 0x48: ffStrbufSetStatic(&cpu->vendor, "HiSilicon"); break;
|
||||
case 0x4e: ffStrbufSetStatic(&cpu->vendor, "Nvidia"); break;
|
||||
case 0x51: ffStrbufSetStatic(&cpu->vendor, "Qualcomm"); break;
|
||||
case 0x53: ffStrbufSetStatic(&cpu->vendor, "Samsung"); break;
|
||||
case 0x61: ffStrbufSetStatic(&cpu->vendor, "Apple"); break;
|
||||
case 0x69: ffStrbufSetStatic(&cpu->vendor, "Intel"); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -223,16 +281,19 @@ static double detectCPUTemp(void)
|
||||
{
|
||||
if(
|
||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||
ffStrbufCompS(&value->name, "coretemp") == 0
|
||||
ffStrbufEqualS(&value->name, "k10temp") ||
|
||||
ffStrbufEqualS(&value->name, "coretemp")
|
||||
) return value->value;
|
||||
}
|
||||
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
static void parseIsa(FFstrbuf* cpuIsa)
|
||||
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
|
||||
{
|
||||
// Always use the last part of the ISA string. Ref: #590 #1204
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
|
||||
if(ffStrbufStartsWithS(cpuIsa, "rv"))
|
||||
{
|
||||
// RISC-V ISA string example: "rv64imafdch_zicsr_zifencei".
|
||||
@@ -248,13 +309,9 @@ static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
// The final ISA output of the above example is "rv64gch".
|
||||
}
|
||||
if(ffStrbufStartsWithS(cpuIsa, "mips"))
|
||||
{
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
void detectAsahi(FFCPUResult* cpu)
|
||||
FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu)
|
||||
{
|
||||
// In Asahi Linux, reading /proc/device-tree/compatible gives
|
||||
// information on the device model. It consists of 3 NUL terminated
|
||||
@@ -279,23 +336,31 @@ void detectAsahi(FFCPUResult* cpu)
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
return "fopen(\"/proc/cpuinfo\", \"r\") failed";
|
||||
|
||||
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
|
||||
|
||||
const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch);
|
||||
const char* error = parseCpuInfo(cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
|
||||
if (error) return error;
|
||||
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
|
||||
|
||||
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
|
||||
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
|
||||
|
||||
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
|
||||
if(cpuUarch.length > 0)
|
||||
{
|
||||
if(cpu->name.length > 0)
|
||||
@@ -310,84 +375,21 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
ffStrbufAppendC(&cpu->name, ' ');
|
||||
ffStrbufAppend(&cpu->name, &cpuIsa);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__aarch64__)
|
||||
#if __arm__ || __aarch64__
|
||||
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
|
||||
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
|
||||
|
||||
#if __ANDROID__
|
||||
detectAndroid(cpu);
|
||||
#elif __aarch64__
|
||||
detectAsahi(cpu);
|
||||
#endif
|
||||
|
||||
if (cpu->name.length == 0)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (ffProcessAppendStdOut(&buffer, (char *const[]) { "lscpu", NULL }) == NULL)
|
||||
{
|
||||
char* pstart = buffer.chars;
|
||||
|
||||
if (cpu->vendor.length == 0)
|
||||
{
|
||||
pstart = strstr(pstart, "Vendor ID:");
|
||||
if (pstart)
|
||||
{
|
||||
pstart += strlen("Vendor ID:");
|
||||
while (isspace(*pstart)) ++pstart;
|
||||
if (*pstart)
|
||||
{
|
||||
char* pend = strchr(pstart, '\n');
|
||||
if (pend != NULL)
|
||||
ffStrbufAppendNS(&cpu->vendor, (uint32_t) (pend - pstart), pstart);
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&cpu->vendor, pstart);
|
||||
}
|
||||
pstart = pend + 1;
|
||||
if (pstart >= buffer.chars + buffer.length)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pstart = buffer.chars;
|
||||
}
|
||||
}
|
||||
|
||||
while ((pstart = strstr(pstart, "Model name:")))
|
||||
{
|
||||
pstart += strlen("Model name:");
|
||||
while (isspace(*pstart)) ++pstart;
|
||||
if (*pstart == '\0')
|
||||
break;
|
||||
|
||||
if (cpu->name.length > 0)
|
||||
ffStrbufAppendS(&cpu->name, " + ");
|
||||
|
||||
if (*pstart == '-')
|
||||
{
|
||||
if (cpu->vendor.length > 0)
|
||||
ffStrbufAppend(&cpu->name, &cpu->vendor);
|
||||
else
|
||||
ffStrbufAppendS(&cpu->name, "Unknown");
|
||||
++pstart;
|
||||
continue;
|
||||
}
|
||||
|
||||
char* pend = strchr(pstart, '\n');
|
||||
if (pend != NULL)
|
||||
ffStrbufAppendNS(&cpu->name, (uint32_t) (pend - pstart), pstart);
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&cpu->name, pstart);
|
||||
break;
|
||||
}
|
||||
|
||||
pstart = pend + 1;
|
||||
if (pstart >= buffer.chars + buffer.length)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
detectArmName(cpuinfo, cpu, cpuImplementer);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
if (kn->value.ui32 > cpu->frequencyBase)
|
||||
cpu->frequencyBase = kn->value.ui32;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||
|
||||
@@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo
|
||||
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
|
||||
"FFSmbiosProcessorInfo: Wrong struct alignment");
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
uint32_t base = 0, max = 0, bus = 0, unused = 0;
|
||||
if (!__get_cpuid(0x16, &base, &max, &bus, &unused))
|
||||
return "Unsupported instruction";
|
||||
|
||||
// cpuid returns 0 MHz when hyper-v is enabled
|
||||
if (base) cpu->frequencyBase = base;
|
||||
if (max) cpu->frequencyMax = max;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu)
|
||||
{
|
||||
return "Unsupported platform";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
@@ -193,7 +168,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
detectSpeedByCpuid(cpu);
|
||||
ffCPUDetectSpeedByCpuid(cpu);
|
||||
if (options->showPeCoreCount) detectCoreTypes(cpu);
|
||||
|
||||
if (cpu->frequencyMax == 0)
|
||||
|
||||
@@ -178,6 +178,12 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
|
||||
}
|
||||
|
||||
static void getUnity(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
if (ffParsePropFile("/usr/bin/unity", "parser = OptionParser(version= \"%prog ", result))
|
||||
ffStrbufSubstrBeforeFirstC(result, '"');
|
||||
}
|
||||
|
||||
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
if (!instance.config.general.detectVersion) return "Disabled by config";
|
||||
@@ -196,6 +202,8 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
|
||||
getLXQt(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
|
||||
getBudgie(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_UNITY))
|
||||
getUnity(result, options);
|
||||
else
|
||||
return "Unsupported DE";
|
||||
return NULL;
|
||||
|
||||
@@ -72,7 +72,7 @@ static bool isPhysicalDevice(const struct mntent* device)
|
||||
) return false;
|
||||
|
||||
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
return false;
|
||||
|
||||
#endif // __ANDROID__
|
||||
@@ -240,8 +240,16 @@ static void detectStats(FFDisk* disk)
|
||||
disk->bytesAvailable = fs.f_bavail * fs.f_frsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
if (fs.f_files >= fs.f_ffree)
|
||||
{
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows filesystem in WSL
|
||||
disk->filesTotal = disk->filesUsed = 0;
|
||||
}
|
||||
|
||||
if(fs.f_flag & ST_RDONLY)
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
|
||||
@@ -37,24 +37,23 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->name);
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||
if (ffAppendFileBuffer(pathSysBlock, &device->name))
|
||||
if (ffAppendFileBuffer(pathSysBlock, &name))
|
||||
{
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
if (device->name.length > 0)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
if (name.length > 0)
|
||||
ffStrbufAppendC(&name, ' ');
|
||||
}
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
ffStrbufTrimRightSpace(&device->name);
|
||||
ffAppendFileBuffer(pathSysBlock, &name);
|
||||
ffStrbufTrimRightSpace(&name);
|
||||
|
||||
if (device->name.length == 0)
|
||||
ffStrbufSetS(&device->name, devName);
|
||||
if (name.length == 0)
|
||||
ffStrbufSetS(&name, devName);
|
||||
else if (ffStrStartsWith(devName, "nvme"))
|
||||
{
|
||||
int devid, nsid;
|
||||
@@ -69,17 +68,13 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (multiNs)
|
||||
{
|
||||
// In Asahi Linux, there are multiple namespaces for the same NVMe drive.
|
||||
ffStrbufAppendF(&device->name, " - %d", nsid);
|
||||
ffStrbufAppendF(&name, " - %d", nsid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// I/Os merges sectors ticks ...
|
||||
@@ -94,6 +89,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
continue;
|
||||
}
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||
device->bytesRead = sectorRead * 512;
|
||||
device->bytesWritten = sectorWritten * 512;
|
||||
|
||||
@@ -34,7 +34,6 @@ FFDisplayResult* ffdsAppendDisplay(
|
||||
|
||||
display->bitDepth = 0;
|
||||
display->hdrEnabled = false;
|
||||
display->wcgEnabled = false;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ typedef struct FFDisplayResult
|
||||
bool primary;
|
||||
uint8_t bitDepth;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
} FFDisplayResult;
|
||||
|
||||
typedef struct FFDisplayServerResult
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
#include <CoreGraphics/CGDirectDisplay.h>
|
||||
#include <CoreVideo/CVDisplayLink.h>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
extern CFDictionaryRef CoreDisplay_IODisplayCreateInfoDictionary(io_service_t framebuffer, IOOptionBits options) __attribute__((weak_import));
|
||||
extern Boolean CoreDisplay_Display_IsHDRModeEnabled(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
#else
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#endif
|
||||
|
||||
static void detectDisplays(FFDisplayServerResult* ds)
|
||||
@@ -43,30 +44,22 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = NULL;
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
if(CoreDisplay_DisplayCreateInfoDictionary)
|
||||
{
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen);
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
}
|
||||
displayInfo = CoreDisplay_DisplayCreateInfoDictionary(screen);
|
||||
#else
|
||||
if(CoreDisplay_IODisplayCreateInfoDictionary)
|
||||
{
|
||||
io_service_t servicePort = CGDisplayIOServicePort(screen);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
}
|
||||
#endif
|
||||
if(displayInfo)
|
||||
{
|
||||
CFDictionaryRef productNames;
|
||||
if(!ffCfDictGetDict(displayInfo, CFSTR(kDisplayProductName), &productNames))
|
||||
ffCfDictGetString(productNames, CFSTR("en_US"), &name);
|
||||
}
|
||||
|
||||
CGSize size = CGDisplayScreenSize(screen);
|
||||
|
||||
@@ -95,6 +88,13 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
ffCfDictGetInt(dict, kCGDisplayBitsPerSample, &bitDepth);
|
||||
display->bitDepth = (uint8_t) bitDepth;
|
||||
}
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
if (CoreDisplay_Display_IsHDRModeEnabled)
|
||||
{
|
||||
display->hdrEnabled = CoreDisplay_Display_IsHDRModeEnabled(screen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
CGDisplayModeRelease(mode);
|
||||
}
|
||||
|
||||
@@ -178,7 +178,6 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
||||
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
|
||||
{
|
||||
display->hdrEnabled = !!advColorInfo.advancedColorEnabled;
|
||||
display->wcgEnabled = !!advColorInfo.wideColorEnforced;
|
||||
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,7 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
{
|
||||
getWMProtocolNameFromEnv(ds);
|
||||
|
||||
if (!ffStrbufEqualS(&ds->wmProtocolName, FF_WM_PROTOCOL_TTY) &&instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
|
||||
if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
|
||||
{
|
||||
//We try wayland as our preferred display server, as it supports the most features.
|
||||
//This method can't detect the name of our WM / DE
|
||||
@@ -96,6 +94,9 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ds->wmProtocolName.length == 0)
|
||||
getWMProtocolNameFromEnv(ds);
|
||||
|
||||
if(!ffStrbufEqualS(&ds->wmProtocolName, FF_WM_PROTOCOL_TTY))
|
||||
{
|
||||
//This fills in missing information about WM / DE by using env vars and iterating processes
|
||||
|
||||
@@ -119,12 +119,6 @@ static void waylandKdeHdrListener(void *data, FF_MAYBE_UNUSED struct kde_output_
|
||||
display->hdrEnabled = !!hdr_enabled;
|
||||
}
|
||||
|
||||
static void waylandKdeWcgListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t wcg_enabled)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->wcgEnabled = !!wcg_enabled;
|
||||
}
|
||||
|
||||
static struct kde_output_device_v2_listener outputListener = {
|
||||
.geometry = waylandKdeGeometryListener,
|
||||
.current_mode = waylandKdeCurrentModeListener,
|
||||
@@ -143,7 +137,7 @@ static struct kde_output_device_v2_listener outputListener = {
|
||||
.name = waylandKdeNameListener,
|
||||
.high_dynamic_range = waylandKdeHdrListener,
|
||||
.sdr_brightness = (void*) stubListener,
|
||||
.wide_color_gamut = waylandKdeWcgListener,
|
||||
.wide_color_gamut = (void*) stubListener,
|
||||
.auto_rotate_policy = (void*) stubListener,
|
||||
.icc_profile_path = (void*) stubListener,
|
||||
.brightness_metadata = (void*) stubListener,
|
||||
@@ -202,7 +196,6 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry,
|
||||
if (item)
|
||||
{
|
||||
item->hdrEnabled = display.hdrEnabled;
|
||||
item->wcgEnabled = display.wcgEnabled;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
|
||||
@@ -47,7 +47,6 @@ typedef struct WaylandDisplay
|
||||
FFstrbuf edidName;
|
||||
uint64_t id;
|
||||
bool hdrEnabled;
|
||||
bool wcgEnabled;
|
||||
void* internal;
|
||||
} WaylandDisplay;
|
||||
|
||||
|
||||
@@ -238,6 +238,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
ffStrbufSetS(&result->deProcessName, "ukui-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UKUI);
|
||||
}
|
||||
|
||||
else if(
|
||||
ffStrStartsWithIgnCase(name, "Unity:Unity")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "unity-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UNITY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,41 @@
|
||||
#include "editor.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/library.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/path.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
|
||||
{
|
||||
return _fullpath(resolved_name, file_name, _MAX_PATH);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "NVIM v")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
|
||||
ffStrbufSubstrBeforeFirstC(userdata, ' ');
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool extractNanoVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "GNU nano ")) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffDetectEditor(FFEditorResult* result)
|
||||
{
|
||||
ffStrbufSetS(&result->name, getenv("VISUAL"));
|
||||
@@ -26,41 +50,26 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
return "$VISUAL or $EDITOR not set";
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (result->name.chars[0] != '/')
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
FASTFETCH_TARGET_DIR_USR "/bin/which",
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\'))
|
||||
{
|
||||
char buf[32];
|
||||
uint32_t len = GetSystemDirectoryA(buf, sizeof(buf));
|
||||
if (len < strlen("C:\\WINDOWS\\system32")) return NULL;
|
||||
strncpy(buf + len, "\\where.exe", sizeof(buf) - len);
|
||||
if (ffProcessAppendStdOut(&result->path, (char* const[]){
|
||||
buf,
|
||||
result->name.chars,
|
||||
NULL,
|
||||
}) != NULL || result->path.length == 0)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
if (ffIsAbsolutePath(result->name.chars))
|
||||
ffStrbufSet(&result->path, &result->name);
|
||||
else
|
||||
{
|
||||
const char* error = ffFindExecutableInPath(result->name.chars, &result->path);
|
||||
if (error) return NULL;
|
||||
}
|
||||
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
{
|
||||
char buf[PATH_MAX + 1];
|
||||
if (!realpath(result->path.chars, buf))
|
||||
return NULL;
|
||||
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
// WIN32: Should we handle scoop shim exe here?
|
||||
|
||||
#ifdef __linux__
|
||||
if (!ffStrEndsWith(buf, "/snap"))
|
||||
#endif
|
||||
ffStrbufSetS(&result->path, buf);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t index = ffStrbufLastIndexC(&result->path,
|
||||
@@ -82,6 +91,17 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
if (ffStrbufEqualS(&result->exe, "nvim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
|
||||
else if (ffStrbufEqualS(&result->exe, "vim"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
|
||||
else if (ffStrbufEqualS(&result->exe, "nano"))
|
||||
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
|
||||
|
||||
if (result->version.length > 0) return NULL;
|
||||
|
||||
const char* param = NULL;
|
||||
if (
|
||||
ffStrbufEqualS(&result->exe, "nano") ||
|
||||
|
||||
@@ -33,11 +33,11 @@ typedef struct FFGPUResult
|
||||
FFstrbuf driver;
|
||||
FFstrbuf platformApi;
|
||||
double temperature;
|
||||
double coreUsage;
|
||||
int32_t coreCount;
|
||||
uint32_t frequency; // Maximum time clock frequency in MHz
|
||||
FFGPUMemory dedicated;
|
||||
FFGPUMemory shared;
|
||||
double coreUsage;
|
||||
uint64_t deviceId; // Used internally, may be uninitialized
|
||||
} FFGPUResult;
|
||||
|
||||
@@ -47,5 +47,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);
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName);
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <sys/pciio.h>
|
||||
@@ -70,11 +71,12 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
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);
|
||||
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))
|
||||
@@ -114,7 +116,12 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
|
||||
{
|
||||
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
#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
|
||||
@@ -46,8 +47,9 @@
|
||||
__u32 pad1;
|
||||
__u64 vm_user_start;
|
||||
__u64 vm_user_end;
|
||||
__u64 vm_shader_start;
|
||||
__u64 vm_shader_end;
|
||||
__u64 vm_usc_start;
|
||||
__u64 vm_usc_end;
|
||||
__u64 vm_kernel_min_size;
|
||||
|
||||
__u32 max_syncs_per_submission;
|
||||
__u32 max_commands_per_submission;
|
||||
@@ -61,6 +63,8 @@
|
||||
|
||||
__u32 result_render_size;
|
||||
__u32 result_compute_size;
|
||||
|
||||
__u32 firmware_version[4];
|
||||
};
|
||||
|
||||
struct drm_asahi_get_params
|
||||
@@ -85,7 +89,6 @@
|
||||
{
|
||||
DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
@@ -196,14 +199,17 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
|
||||
}
|
||||
}
|
||||
|
||||
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
|
||||
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const FFstrbuf* coreName)
|
||||
{
|
||||
// Works for Intel GPUs
|
||||
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
|
||||
|
||||
if (ffStrbufStartsWithS(&gpu->name, "Intel "))
|
||||
ffStrbufSubstrAfter(&gpu->name, (uint32_t) strlen("Intel "));
|
||||
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
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;
|
||||
|
||||
if (ffStrbufEqualS(&gpu->driver, "xe"))
|
||||
{
|
||||
@@ -290,6 +296,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
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;
|
||||
@@ -319,6 +326,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY coreName = ffStrbufCreate();
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
static FFstrbuf pciids;
|
||||
@@ -327,7 +335,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
ffStrbufInit(&pciids);
|
||||
loadPciIds(&pciids);
|
||||
}
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
ffGPUParsePciIds(&pciids, subclassId, (uint16_t) vendorId, (uint16_t) deviceId, gpu, &coreName);
|
||||
}
|
||||
|
||||
pciDetectDriver(gpu, deviceDir, buffer, drmKey);
|
||||
@@ -340,7 +348,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
|
||||
{
|
||||
pciDetectIntelSpecific(gpu, deviceDir, buffer);
|
||||
pciDetectIntelSpecific(gpu, deviceDir, buffer, &coreName);
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
}
|
||||
else
|
||||
@@ -424,9 +432,14 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
|
||||
.size = sizeof(paramsGlobal),
|
||||
}) >= 0)
|
||||
{
|
||||
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
|
||||
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
|
||||
gpu->deviceId = paramsGlobal.chip_id;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -516,14 +529,14 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
|
||||
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
#ifdef FF_HAVE_DIRECTX_HEADERS
|
||||
const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus);
|
||||
if (ffGPUDetectByDirectX(options, gpus) == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if (options->detectionMethod == FF_GPU_DETECTION_METHOD_AUTO)
|
||||
{
|
||||
#ifdef FF_HAVE_DIRECTX_HEADERS
|
||||
const char* ffGPUDetectByDirectX(const FFGPUOptions* options, FFlist* gpus);
|
||||
if (ffGPUDetectByDirectX(options, gpus) == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if (drmDetectGPUs(options, gpus) == NULL && gpus->length > 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "gpu.h"
|
||||
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu)
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu, FFstrbuf* coreName)
|
||||
{
|
||||
if (content->length)
|
||||
{
|
||||
@@ -44,13 +44,20 @@ void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint
|
||||
if (!end)
|
||||
end = content->chars + content->length;
|
||||
|
||||
char* openingBracket = memchr(start, '[', (uint32_t) (end - start));
|
||||
if (openingBracket)
|
||||
char* closingBracket = end - 1;
|
||||
if (*closingBracket == ']')
|
||||
{
|
||||
openingBracket++;
|
||||
char* closingBracket = memchr(openingBracket, ']', (uint32_t) (end - openingBracket));
|
||||
if (closingBracket)
|
||||
char* openingBracket = memrchr(start, '[', (size_t) (closingBracket - start));
|
||||
if (openingBracket)
|
||||
{
|
||||
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)
|
||||
ffStrbufSetNS(&gpu->name, (uint32_t) (end - start), start);
|
||||
|
||||
@@ -76,7 +76,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
{
|
||||
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);
|
||||
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,12 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
}
|
||||
|
||||
#define FF_EMPTY_GUID_STR L"{00000000-0000-0000-0000-000000000000}"
|
||||
#define FF_GUID_STRLEN (sizeof(FF_EMPTY_GUID_STR) / sizeof(wchar_t) - 1)
|
||||
enum { FF_GUID_STRLEN = sizeof(FF_EMPTY_GUID_STR) / sizeof(wchar_t) - 1 };
|
||||
|
||||
wchar_t regDirectxKey[] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR;
|
||||
const uint32_t regDirectxKeyPrefixLength = (uint32_t) __builtin_strlen("SOFTWARE\\Microsoft\\DirectX\\");
|
||||
wchar_t regDriverKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\" FF_EMPTY_GUID_STR L"\\0000";
|
||||
const uint32_t regDriverKeyPrefixLength = (uint32_t) __builtin_strlen("SYSTEM\\CurrentControlSet\\Control\\Class\\");
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
@@ -25,39 +30,14 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_DISPLAY) failed";
|
||||
|
||||
wchar_t regDirectxKey[] = L"SOFTWARE\\Microsoft\\DirectX\\" FF_EMPTY_GUID_STR;
|
||||
const uint32_t regDirectxKeyPrefixLength = (uint32_t) strlen("SOFTWARE\\Microsoft\\DirectX\\");
|
||||
wchar_t regControlVideoKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\" FF_EMPTY_GUID_STR L"\\0000";
|
||||
const uint32_t regControlVideoKeyPrefixLength = (uint32_t) strlen("SYSTEM\\CurrentControlSet\\Control\\Video\\");
|
||||
|
||||
SP_DEVINFO_DATA did = { .cbSize = sizeof(did) };
|
||||
for (DWORD idev = 0; SetupDiEnumDeviceInfo(hdev, idev, &did); ++idev)
|
||||
{
|
||||
wchar_t hardwareId[256];
|
||||
if (!SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_HARDWAREID, NULL, (PBYTE) hardwareId, sizeof(hardwareId), NULL))
|
||||
continue;
|
||||
|
||||
wchar_t videoId[39];
|
||||
{
|
||||
FF_HKEY_AUTO_DESTROY hKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
|
||||
if (!hKey) continue;
|
||||
DWORD videoIdLength = sizeof(videoId);
|
||||
if (RegGetValueW(hKey, NULL, L"VideoID", RRF_RT_REG_SZ, NULL, videoId, &videoIdLength) != ERROR_SUCCESS || videoIdLength != (FF_GUID_STRLEN + 1) * sizeof(wchar_t))
|
||||
continue;
|
||||
}
|
||||
|
||||
wmemcpy(regControlVideoKey + regControlVideoKeyPrefixLength, videoId, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regControlVideoKey, &hKey, NULL)) continue;
|
||||
|
||||
unsigned vendorId = 0, deviceId = 0, subSystemId = 0, revId = 0;
|
||||
swscanf(hardwareId, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInitStatic(&gpu->platformApi, "Direct3D");
|
||||
ffStrbufInitStatic(&gpu->platformApi, "SetupAPI");
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
||||
@@ -66,55 +46,77 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
gpu->deviceId = 0;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (!ffRegReadStrbuf(hKey, L"DriverDesc", &gpu->name, NULL)) // faster, for some reason
|
||||
{
|
||||
wchar_t name[256];
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) name, sizeof(name), NULL))
|
||||
ffStrbufSetWS(&gpu->name, name);
|
||||
}
|
||||
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
|
||||
wchar_t buffer[256];
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DEVICEDESC, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
|
||||
ffStrbufSetWS(&gpu->name, buffer);
|
||||
|
||||
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, videoId, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
|
||||
FF_HKEY_AUTO_DESTROY hVideoIdKey = SetupDiOpenDevRegKey(hdev, &did, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
|
||||
if (!hVideoIdKey) continue;
|
||||
DWORD bufferLen = sizeof(buffer);
|
||||
if (RegGetValueW(hVideoIdKey, NULL, L"VideoID", RRF_RT_REG_SZ, NULL, buffer, &bufferLen) == ERROR_SUCCESS &&
|
||||
bufferLen == (FF_GUID_STRLEN + 1) * sizeof(wchar_t))
|
||||
{
|
||||
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;
|
||||
|
||||
uint64_t dedicatedSystemMemory, sharedSystemMemory;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
|
||||
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
|
||||
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, buffer, FF_GUID_STRLEN);
|
||||
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
|
||||
{
|
||||
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
|
||||
gpu->shared.total = sharedSystemMemory;
|
||||
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;
|
||||
|
||||
uint64_t dedicatedSystemMemory, sharedSystemMemory;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, NULL) &&
|
||||
ffRegReadUint64(hDirectxKey, L"SharedSystemMemory", &sharedSystemMemory, NULL))
|
||||
{
|
||||
gpu->dedicated.total = dedicatedVideoMemory + dedicatedSystemMemory;
|
||||
gpu->shared.total = sharedSystemMemory;
|
||||
}
|
||||
|
||||
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
|
||||
|
||||
uint32_t featureLevel = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 12.%u", (featureLevel & 0x0F00) >> 8);
|
||||
else if(ffRegReadUint(hDirectxKey, L"MaxD3D11FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 11.%u", (featureLevel & 0x0F00) >> 8);
|
||||
|
||||
uint64_t driverVersion = 0;
|
||||
if(ffRegReadUint64(hDirectxKey, L"DriverVersion", &driverVersion, NULL) && driverVersion)
|
||||
{
|
||||
ffStrbufSetF(&gpu->driver, "%u.%u.%u.%u",
|
||||
(unsigned) (driverVersion >> 48) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 32) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 16) & 0xFFFF,
|
||||
(unsigned) (driverVersion >> 0) & 0xFFFF
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t vendorId = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"VendorId", &vendorId, NULL) && vendorId)
|
||||
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
}
|
||||
|
||||
ffRegReadUint64(hDirectxKey, L"AdapterLuid", &gpu->deviceId, NULL);
|
||||
|
||||
uint32_t featureLevel = 0;
|
||||
if(ffRegReadUint(hDirectxKey, L"MaxD3D12FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 12.%u", (featureLevel & 0x0F00) >> 8);
|
||||
else if(ffRegReadUint(hDirectxKey, L"MaxD3D11FeatureLevel", &featureLevel, NULL) && featureLevel)
|
||||
ffStrbufSetF(&gpu->platformApi, "Direct3D 11.%u", (featureLevel & 0x0F00) >> 8);
|
||||
}
|
||||
else if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
|
||||
{
|
||||
uint32_t vmem = 0;
|
||||
if (ffRegReadUint(hKey, L"HardwareInformation.MemorySize", &vmem, NULL))
|
||||
gpu->dedicated.total = vmem;
|
||||
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
|
||||
if (gpu->vendor.length == 0)
|
||||
{
|
||||
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);
|
||||
if (ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
bufferLen = sizeof(buffer);
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_DRIVER, NULL, (PBYTE) buffer, sizeof(buffer), &bufferLen) && bufferLen == (FF_GUID_STRLEN + strlen("\\0000") + 1) * 2)
|
||||
{
|
||||
wmemcpy(regDriverKey + regDriverKeyPrefixLength, buffer, FF_GUID_STRLEN + strlen("\\0000"));
|
||||
FF_HKEY_AUTO_DESTROY hRegDriverKey = NULL;
|
||||
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDriverKey, &hRegDriverKey, NULL))
|
||||
{
|
||||
if (ffRegReadStrbuf(hRegDriverKey, L"ProviderName", &gpu->vendor, NULL))
|
||||
{
|
||||
if (ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else if (ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
|
||||
@@ -122,6 +124,13 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
|
||||
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
|
||||
{
|
||||
unsigned vendorId = 0, deviceId = 0, subSystemId = 0, revId = 0;
|
||||
if (SetupDiGetDeviceRegistryPropertyW(hdev, &did, SPDRP_HARDWAREID, NULL, (PBYTE) buffer, sizeof(buffer), NULL))
|
||||
{
|
||||
swscanf(buffer, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x&REV_%x", &vendorId, &deviceId, &subSystemId, &revId);
|
||||
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))
|
||||
@@ -133,7 +142,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
&(FFGpuDriverCondition) {
|
||||
.type = FF_GPU_DRIVER_CONDITION_TYPE_DEVICE_ID
|
||||
| (gpu->deviceId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_LUID : 0)
|
||||
| FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID,
|
||||
| (vendorId > 0 ? FF_GPU_DRIVER_CONDITION_TYPE_BUS_ID : 0),
|
||||
.pciDeviceId = {
|
||||
.deviceId = deviceId,
|
||||
.vendorId = vendorId,
|
||||
|
||||
@@ -28,7 +28,7 @@ private:
|
||||
extern "C"
|
||||
const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libdxcore, nullptr, "dlopen libdxcore.so failed. Make sure WSLg is enabled", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
|
||||
FF_LIBRARY_LOAD(libdxcore, nullptr, "dlopen libdxcore.so failed", "/usr/lib/wsl/lib/libdxcore" FF_LIBRARY_EXTENSION, 4)
|
||||
// DXCoreCreateAdapterFactory is a reloaded function, so we can't use FF_LIBRARY_LOAD_SYMBOL_MESSAGE here
|
||||
typedef HRESULT (*DXCoreCreateAdapterFactory_t)(REFIID riid, void** ppvFactory);
|
||||
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
#include "initsystem.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/binary.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
FF_MAYBE_UNUSED static bool extractSystemdVersion(const char* str, uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(str, "systemd ")) return true;
|
||||
const char* pstart = str + strlen("systemd ");
|
||||
const char* pend = memmem(pstart, len - strlen("systemd "), " running in ", strlen(" running in "));
|
||||
if (!pend) return true;
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (pend - pstart), pstart);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
{
|
||||
const char* error = ffProcessGetBasicInfoLinux((int) result->pid, &result->name, NULL, NULL);
|
||||
@@ -31,24 +44,30 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
|
||||
if (instance.config.general.detectVersion)
|
||||
{
|
||||
#if __linux__ && !__ANDROID__
|
||||
if (ffStrbufEqualS(&result->name, "systemd"))
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
ffStrbufEndsWithS(&result->exe, "/systemd") ? result->exe.chars : "systemctl", // use exe path in case users have another systemd installed
|
||||
"--version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
ffBinaryExtractStrings(result->exe.chars, extractSystemdVersion, &result->version, (uint32_t) strlen("systemd 0.0 running in x"));
|
||||
if (result->version.length == 0)
|
||||
{
|
||||
uint32_t iStart = ffStrbufFirstIndexC(&result->version, '(');
|
||||
if (iStart < result->version.length)
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
ffStrbufEndsWithS(&result->exe, "/systemd") ? result->exe.chars : "systemctl", // use exe path in case users have another systemd installed
|
||||
"--version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
{
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ')');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
uint32_t iStart = ffStrbufFirstIndexC(&result->version, '(');
|
||||
if (iStart < result->version.length)
|
||||
{
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ')');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ffStrbufEqualS(&result->name, "launchd"))
|
||||
#elif __APPLE__
|
||||
if (ffStrbufEqualS(&result->name, "launchd"))
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
"/bin/launchctl",
|
||||
@@ -66,6 +85,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -9,12 +9,12 @@ const char* ffDetectLoadavg(double result[3])
|
||||
|
||||
// Don't use syscall for container compatibility. #620
|
||||
char buf[64];
|
||||
ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf);
|
||||
ssize_t nRead = ffReadFileData("/proc/loadavg", sizeof(buf) - 1, buf);
|
||||
if (nRead > 0)
|
||||
{
|
||||
buf[nRead] = '\0';
|
||||
|
||||
if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3)
|
||||
if (sscanf(buf, "%lf%lf%lf", &result[0], &result[1], &result[2]) == 3)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
void ffDetectLocale(FFstrbuf* result)
|
||||
{
|
||||
ffStrbufAppendS(result, getenv("LC_MESSAGES"));
|
||||
ffStrbufAppendS(result, getenv("LC_ALL"));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
@@ -12,11 +12,5 @@ void ffDetectLocale(FFstrbuf* result)
|
||||
if(result->length > 0)
|
||||
return;
|
||||
|
||||
#ifdef LC_MESSAGES
|
||||
ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL));
|
||||
if(result->length > 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
ffStrbufAppendS(result, setlocale(LC_TIME, NULL));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ typedef struct FFLocalIpResult
|
||||
FFstrbuf ipv6;
|
||||
FFstrbuf mac;
|
||||
int32_t mtu;
|
||||
int32_t speed;
|
||||
bool defaultRoute;
|
||||
} FFLocalIpResult;
|
||||
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
@@ -40,6 +46,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
ip->speed = -1;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
@@ -172,9 +179,388 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
|
||||
if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0)
|
||||
iface->mtu = (int32_t) ifr.ifr_mtu;
|
||||
|
||||
#ifdef __linux__
|
||||
struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET };
|
||||
ifr.ifr_data = (void*) &edata;
|
||||
if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0)
|
||||
iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android
|
||||
#elif __FreeBSD__ || __APPLE__
|
||||
struct ifmediareq ifmr = {};
|
||||
strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0)
|
||||
{
|
||||
switch (IFM_SUBTYPE(ifmr.ifm_active))
|
||||
{
|
||||
#ifdef IFM_HPNA_1
|
||||
case IFM_HPNA_1:
|
||||
#endif
|
||||
iface->speed = 1; break;
|
||||
#ifdef IFM_1000_CX
|
||||
case IFM_1000_CX:
|
||||
#endif
|
||||
#ifdef IFM_1000_CX_SGMII
|
||||
case IFM_1000_CX_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_KX
|
||||
case IFM_1000_KX:
|
||||
#endif
|
||||
#ifdef IFM_1000_LX
|
||||
case IFM_1000_LX:
|
||||
#endif
|
||||
#ifdef IFM_1000_SGMII
|
||||
case IFM_1000_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_1000_SX
|
||||
case IFM_1000_SX:
|
||||
#endif
|
||||
#ifdef IFM_1000_T
|
||||
case IFM_1000_T:
|
||||
#endif
|
||||
iface->speed = 1000; break;
|
||||
#ifdef IFM_100G_AUI2
|
||||
case IFM_100G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI2_AC
|
||||
case IFM_100G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4
|
||||
case IFM_100G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_AUI4_AC
|
||||
case IFM_100G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2
|
||||
case IFM_100G_CAUI2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI2_AC
|
||||
case IFM_100G_CAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4
|
||||
case IFM_100G_CAUI4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CAUI4_AC
|
||||
case IFM_100G_CAUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_100G_CP2
|
||||
case IFM_100G_CP2:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR4
|
||||
case IFM_100G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_CR_PAM4
|
||||
case IFM_100G_CR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_DR
|
||||
case IFM_100G_DR:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR2_PAM4
|
||||
case IFM_100G_KR2_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR4
|
||||
case IFM_100G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_KR_PAM4
|
||||
case IFM_100G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_100G_LR4
|
||||
case IFM_100G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR2
|
||||
case IFM_100G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_100G_SR4
|
||||
case IFM_100G_SR4:
|
||||
#endif
|
||||
iface->speed = 100000; break;
|
||||
#ifdef IFM_100_FX
|
||||
case IFM_100_FX:
|
||||
#endif
|
||||
#ifdef IFM_100_SGMII
|
||||
case IFM_100_SGMII:
|
||||
#endif
|
||||
#ifdef IFM_100_T
|
||||
case IFM_100_T:
|
||||
#endif
|
||||
#ifdef IFM_100_T2
|
||||
case IFM_100_T2:
|
||||
#endif
|
||||
#ifdef IFM_100_T4
|
||||
case IFM_100_T4:
|
||||
#endif
|
||||
#ifdef IFM_100_TX
|
||||
case IFM_100_TX:
|
||||
#endif
|
||||
#ifdef IFM_100_VG
|
||||
case IFM_100_VG:
|
||||
#endif
|
||||
iface->speed = 100; break;
|
||||
#ifdef IFM_10G_AOC
|
||||
case IFM_10G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_10G_CR1
|
||||
case IFM_10G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_10G_CX4
|
||||
case IFM_10G_CX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_ER
|
||||
case IFM_10G_ER:
|
||||
#endif
|
||||
#ifdef IFM_10G_KR
|
||||
case IFM_10G_KR:
|
||||
#endif
|
||||
#ifdef IFM_10G_KX4
|
||||
case IFM_10G_KX4:
|
||||
#endif
|
||||
#ifdef IFM_10G_LR
|
||||
case IFM_10G_LR:
|
||||
#endif
|
||||
#ifdef IFM_10G_LRM
|
||||
case IFM_10G_LRM:
|
||||
#endif
|
||||
#ifdef IFM_10G_SFI
|
||||
case IFM_10G_SFI:
|
||||
#endif
|
||||
#ifdef IFM_10G_SR
|
||||
case IFM_10G_SR:
|
||||
#endif
|
||||
#ifdef IFM_10G_T
|
||||
case IFM_10G_T:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX
|
||||
case IFM_10G_TWINAX:
|
||||
#endif
|
||||
#ifdef IFM_10G_TWINAX_LONG
|
||||
case IFM_10G_TWINAX_LONG:
|
||||
#endif
|
||||
iface->speed = 10000; break;
|
||||
#ifdef IFM_10_2
|
||||
case IFM_10_2:
|
||||
#endif
|
||||
#ifdef IFM_10_5
|
||||
case IFM_10_5:
|
||||
#endif
|
||||
#ifdef IFM_10_FL
|
||||
case IFM_10_FL:
|
||||
#endif
|
||||
#ifdef IFM_10_STP
|
||||
case IFM_10_STP:
|
||||
#endif
|
||||
#ifdef IFM_10_T
|
||||
case IFM_10_T:
|
||||
#endif
|
||||
iface->speed = 10; break;
|
||||
#ifdef IFM_200G_AUI4
|
||||
case IFM_200G_AUI4:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI4_AC
|
||||
case IFM_200G_AUI4_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8
|
||||
case IFM_200G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_200G_AUI8_AC
|
||||
case IFM_200G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_200G_CR4_PAM4
|
||||
case IFM_200G_CR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_DR4
|
||||
case IFM_200G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_FR4
|
||||
case IFM_200G_FR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_KR4_PAM4
|
||||
case IFM_200G_KR4_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_200G_LR4
|
||||
case IFM_200G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_200G_SR4
|
||||
case IFM_200G_SR4:
|
||||
#endif
|
||||
iface->speed = 200000; break;
|
||||
#ifdef IFM_20G_KR2
|
||||
case IFM_20G_KR2:
|
||||
#endif
|
||||
iface->speed = 20000; break;
|
||||
#ifdef IFM_2500_KX
|
||||
case IFM_2500_KX:
|
||||
#endif
|
||||
#ifdef IFM_2500_SX
|
||||
case IFM_2500_SX:
|
||||
#endif
|
||||
#ifdef IFM_2500_T
|
||||
case IFM_2500_T:
|
||||
#endif
|
||||
#ifdef IFM_2500_X
|
||||
case IFM_2500_X:
|
||||
#endif
|
||||
iface->speed = 2500; break;
|
||||
#ifdef IFM_25G_ACC
|
||||
case IFM_25G_ACC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AOC
|
||||
case IFM_25G_AOC:
|
||||
#endif
|
||||
#ifdef IFM_25G_AUI
|
||||
case IFM_25G_AUI:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR
|
||||
case IFM_25G_CR:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR1
|
||||
case IFM_25G_CR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_CR_S
|
||||
case IFM_25G_CR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR
|
||||
case IFM_25G_KR:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR1
|
||||
case IFM_25G_KR1:
|
||||
#endif
|
||||
#ifdef IFM_25G_KR_S
|
||||
case IFM_25G_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_25G_LR
|
||||
case IFM_25G_LR:
|
||||
#endif
|
||||
#ifdef IFM_25G_PCIE
|
||||
case IFM_25G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_25G_SR
|
||||
case IFM_25G_SR:
|
||||
#endif
|
||||
#ifdef IFM_25G_T
|
||||
case IFM_25G_T:
|
||||
#endif
|
||||
iface->speed = 25000; break;
|
||||
#ifdef IFM_400G_AUI8
|
||||
case IFM_400G_AUI8:
|
||||
#endif
|
||||
#ifdef IFM_400G_AUI8_AC
|
||||
case IFM_400G_AUI8_AC:
|
||||
#endif
|
||||
#ifdef IFM_400G_DR4
|
||||
case IFM_400G_DR4:
|
||||
#endif
|
||||
#ifdef IFM_400G_FR8
|
||||
case IFM_400G_FR8:
|
||||
#endif
|
||||
#ifdef IFM_400G_LR8
|
||||
case IFM_400G_LR8:
|
||||
#endif
|
||||
iface->speed = 400000; break;
|
||||
#ifdef IFM_40G_CR4
|
||||
case IFM_40G_CR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_ER4
|
||||
case IFM_40G_ER4:
|
||||
#endif
|
||||
#ifdef IFM_40G_KR4
|
||||
case IFM_40G_KR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_LR4
|
||||
case IFM_40G_LR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_SR4
|
||||
case IFM_40G_SR4:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI
|
||||
case IFM_40G_XLAUI:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLAUI_AC
|
||||
case IFM_40G_XLAUI_AC:
|
||||
#endif
|
||||
#ifdef IFM_40G_XLPPI
|
||||
case IFM_40G_XLPPI:
|
||||
#endif
|
||||
#ifdef IFM_40G_LM4
|
||||
case IFM_40G_LM4:
|
||||
#endif
|
||||
iface->speed = 40000; break;
|
||||
#ifdef IFM_5000_KR
|
||||
case IFM_5000_KR:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR1
|
||||
case IFM_5000_KR1:
|
||||
#endif
|
||||
#ifdef IFM_5000_KR_S
|
||||
case IFM_5000_KR_S:
|
||||
#endif
|
||||
#ifdef IFM_5000_T
|
||||
case IFM_5000_T:
|
||||
#endif
|
||||
iface->speed = 5000; break;
|
||||
#ifdef IFM_50G_AUI1
|
||||
case IFM_50G_AUI1:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI1_AC
|
||||
case IFM_50G_AUI1_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2
|
||||
case IFM_50G_AUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_AUI2_AC
|
||||
case IFM_50G_AUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_CP
|
||||
case IFM_50G_CP:
|
||||
#endif
|
||||
#ifdef IFM_50G_CR2
|
||||
case IFM_50G_CR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_FR
|
||||
case IFM_50G_FR:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR2
|
||||
case IFM_50G_KR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR_PAM4
|
||||
case IFM_50G_KR_PAM4:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2
|
||||
case IFM_50G_LAUI2:
|
||||
#endif
|
||||
#ifdef IFM_50G_LAUI2_AC
|
||||
case IFM_50G_LAUI2_AC:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR
|
||||
case IFM_50G_LR:
|
||||
#endif
|
||||
#ifdef IFM_50G_LR2
|
||||
case IFM_50G_LR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_PCIE
|
||||
case IFM_50G_PCIE:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR
|
||||
case IFM_50G_SR:
|
||||
#endif
|
||||
#ifdef IFM_50G_SR2
|
||||
case IFM_50G_SR2:
|
||||
#endif
|
||||
#ifdef IFM_50G_KR4
|
||||
case IFM_50G_KR4:
|
||||
#endif
|
||||
iface->speed = 50000; break;
|
||||
#ifdef IFM_56G_R4
|
||||
case IFM_56G_R4:
|
||||
#endif
|
||||
iface->speed = 56000; break;
|
||||
default:
|
||||
iface->speed = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __sun
|
||||
if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->speed = -1;
|
||||
ip->mtu = -1;
|
||||
}
|
||||
else
|
||||
@@ -150,7 +151,11 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
}
|
||||
|
||||
if (!newIp)
|
||||
FF_LIST_GET(FFLocalIpResult, *results, results->length - 1)->mtu = (int32_t) adapter->Mtu;
|
||||
{
|
||||
FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1);
|
||||
result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000);
|
||||
result->mtu = (int32_t) adapter->Mtu;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#define FF_DBUS_MPRIS_PREFIX "org.mpris.MediaPlayer2."
|
||||
#define FF_DBUS_TIMEOUT_MILLISECONDS 35
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include "common/dbus.h"
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_15
|
||||
extern CFDictionaryRef CoreDisplay_DisplayCreateInfoDictionary(CGDirectDisplayID display) __attribute__((weak_import));
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
extern CFDictionaryRef CoreDisplay_IODisplayCreateInfoDictionary(io_service_t framebuffer, IOOptionBits options) __attribute__((weak_import));
|
||||
#else
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#endif
|
||||
|
||||
static bool detectHdrSupportWithNSScreen(FFDisplayResult* display)
|
||||
@@ -57,7 +56,7 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_DisplayCreateInfoDictionary((CGDirectDisplayID) display->id);
|
||||
#else
|
||||
io_service_t servicePort = CGDisplayIOServicePort((CGDirectDisplayID) display->id);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
|
||||
#endif
|
||||
if(!displayInfo) continue;
|
||||
|
||||
@@ -67,7 +66,7 @@ const char* ffDetectMonitor(FFlist* results)
|
||||
|
||||
uint8_t edidData[128] = {};
|
||||
uint32_t edidLength = 0;
|
||||
if (ffCfDictGetData(displayInfo, CFSTR("IODisplayEDID"), 0, sizeof(edidData), edidData, &edidLength) == NULL)
|
||||
if (ffCfDictGetData(displayInfo, CFSTR(kIODisplayEDIDKey), 0, sizeof(edidData), edidData, &edidLength) == NULL)
|
||||
{
|
||||
uint32_t width, height;
|
||||
ffEdidGetPhysicalResolution(edidData, &width, &height);
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef struct FFPackagesResult
|
||||
uint32_t guixHome;
|
||||
uint32_t guixSystem;
|
||||
uint32_t guixUser;
|
||||
uint32_t linglong;
|
||||
uint32_t lpkg;
|
||||
uint32_t lpkgbuild;
|
||||
uint32_t nixDefault;
|
||||
|
||||
@@ -471,6 +471,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);
|
||||
}
|
||||
|
||||
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
static const char* getSystemMonospaceFont(void)
|
||||
{
|
||||
@@ -286,6 +287,13 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
}
|
||||
|
||||
static bool extractStTermFont(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
|
||||
{
|
||||
if (!ffStrContains(str, "size=")) return true;
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, len, str);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult* terminal)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", terminal->pid);
|
||||
@@ -306,30 +314,18 @@ static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult*
|
||||
else
|
||||
{
|
||||
ffStrbufClear(&font);
|
||||
if (ffProcessAppendStdOut(&font, (char* const[]) {
|
||||
"strings",
|
||||
terminal->exePath.chars,
|
||||
NULL,
|
||||
}) != NULL || font.length == 0)
|
||||
|
||||
const char* error = ffBinaryExtractStrings(terminal->exePath.chars, extractStTermFont, &font, (uint32_t) strlen("size=0"));
|
||||
if (error)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "Failed to run `strings st`");
|
||||
ffStrbufAppendS(&terminalFont->error, error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Search font config string in st binary
|
||||
uint32_t middleIndex = ffStrbufFirstIndexS(&font, "size=");
|
||||
if (middleIndex == font.length)
|
||||
if (font.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&terminalFont->error, "No font config found in st binary");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t startIndex = ffStrbufPreviousIndexC(&font, middleIndex, '\n');
|
||||
if (startIndex == font.length) startIndex = 0;
|
||||
uint32_t endIndex = ffStrbufNextIndexC(&font, middleIndex, '\n');
|
||||
|
||||
ffStrbufSubstrBefore(&font, endIndex);
|
||||
ffStrbufSubstrAfter(&font, startIndex);
|
||||
}
|
||||
|
||||
// JetBrainsMono Nerd Font Mono:pixelsize=12:antialias=true:autohint=true
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "common/processing.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/binary.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef __FreeBSD__
|
||||
@@ -63,16 +64,29 @@ static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
|
||||
static bool extractBashVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(line, "@(#)Bash version ")) return true;
|
||||
const char* start = line + strlen("@(#)Bash version ");
|
||||
const char* end = strchr(start, '(');
|
||||
if (!end) return true;
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
|
||||
{
|
||||
const char* path = exePath->chars;
|
||||
if (*path == '\0')
|
||||
path = exe->chars;
|
||||
ffBinaryExtractStrings(path, extractBashVersion, version, (uint32_t) strlen("@(#)Bash version 0.0.0(0) release GNU"));
|
||||
|
||||
if(!getExeVersionRaw(exe, version))
|
||||
return false;
|
||||
|
||||
// GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright...
|
||||
ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)
|
||||
ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release
|
||||
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release
|
||||
ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16
|
||||
ffStrbufSubstrBeforeFirstC(version, '('); // GNU bash, version 5.1.16
|
||||
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -188,6 +202,29 @@ static bool getShellVersionXonsh(FFstrbuf* exe, FFstrbuf* version)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool extractZshVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
if (!ffStrStartsWith(line, "zsh-")) return true;
|
||||
const char* start = line + strlen("zsh-");
|
||||
const char* end = strchr(start, '-');
|
||||
if (!end) return true;
|
||||
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getShellVersionZsh(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
|
||||
{
|
||||
const char* path = exePath->chars;
|
||||
if (*path == '\0')
|
||||
path = exe->chars;
|
||||
|
||||
ffBinaryExtractStrings(path, extractZshVersion, version, (uint32_t) strlen("zsh-0.0-0"));
|
||||
if (version->length) return true;
|
||||
|
||||
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
@@ -202,7 +239,7 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version)
|
||||
{
|
||||
if (!instance.config.general.detectVersion) return false;
|
||||
|
||||
@@ -210,9 +247,9 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
return false;
|
||||
|
||||
if(ffStrEqualsIgnCase(exeName, "bash"))
|
||||
return getShellVersionBash(exe, version);
|
||||
return getShellVersionBash(exe, exePath, version);
|
||||
if(ffStrEqualsIgnCase(exeName, "zsh"))
|
||||
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
|
||||
return getShellVersionZsh(exe, exePath, version);
|
||||
if(ffStrEqualsIgnCase(exeName, "fish"))
|
||||
return getShellVersionFish(exe, version);
|
||||
if(ffStrEqualsIgnCase(exeName, "pwsh"))
|
||||
@@ -250,8 +287,24 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
|
||||
return version->length > 0;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
|
||||
static bool extractGeneralVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
if (!ffCharIsDigit(str[0])) return true;
|
||||
int count = 0;
|
||||
sscanf(str, "%*d.%*d.%*d%n", &count);
|
||||
if (count == 0) return true;
|
||||
ffStrbufSetS((FFstrbuf*) userdata, str);
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if (exe->chars[0] == '/')
|
||||
{
|
||||
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
|
||||
if (version->length) return true;
|
||||
}
|
||||
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
"gnome-terminal",
|
||||
"--version",
|
||||
@@ -264,6 +317,17 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
|
||||
return true;
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionXfce4Terminal(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
if (exe->chars[0] == '/')
|
||||
{
|
||||
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
|
||||
if (version->length) return true;
|
||||
}
|
||||
|
||||
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
|
||||
}
|
||||
|
||||
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
|
||||
{
|
||||
if(ffProcessAppendStdOut(version, (char* const[]){
|
||||
@@ -485,6 +549,33 @@ static bool getTerminalVersionZed(FFstrbuf* exe, FFstrbuf* version)
|
||||
#ifndef _WIN32
|
||||
static bool getTerminalVersionKitty(FFstrbuf* exe, FFstrbuf* version)
|
||||
{
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
char buffer[1024] = {};
|
||||
if (
|
||||
#ifdef __linux__
|
||||
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib64/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer) ||
|
||||
ffReadFileData(FASTFETCH_TARGET_DIR_USR "/lib/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
|
||||
#else
|
||||
ffReadFileData(_PATH_LOCALBASE "/share/kitty/kitty/constants.py", sizeof(buffer) - 1, buffer)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
// Starts from version 0.17.0
|
||||
// https://github.com/kovidgoyal/kitty/blob/master/kitty/constants.py#L25
|
||||
const char* p = memmem(buffer, sizeof(buffer) - 1, "version: Version = Version(", strlen("version: Version = Version("));
|
||||
if (p)
|
||||
{
|
||||
p += strlen("version: Version = Version(");
|
||||
int major, minor, patch;
|
||||
if (sscanf(p, "%d,%d,%d", &major, &minor, &patch) == 3)
|
||||
{
|
||||
ffStrbufSetF(version, "%d.%d.%d", major, minor, patch);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
char versionHex[64];
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/1030#discussioncomment-9845233
|
||||
if (ffGetTerminalResponse(
|
||||
@@ -563,7 +654,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal"))
|
||||
return getTerminalVersionGnome(version);
|
||||
return getTerminalVersionGnome(exe, version);
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "konsole"))
|
||||
return getTerminalVersionKonsole(exe, version);
|
||||
@@ -572,7 +663,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
||||
return getExeVersionGeneral(exe, version);//yakuake 22.12.3
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
|
||||
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
|
||||
return getTerminalVersionXfce4Terminal(exe, version);
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(processName, "terminator"))
|
||||
return getExeVersionGeneral(exe, version);//terminator 2.1.3
|
||||
|
||||
@@ -274,14 +274,14 @@ static void getUserShellFromEnv(FFShellResult* result)
|
||||
}
|
||||
}
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version);
|
||||
|
||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||
|
||||
static void setShellInfoDetails(FFShellResult* result)
|
||||
{
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
|
||||
fftsGetShellVersion(&result->exe, result->exeName, &result->exePath, &result->version);
|
||||
|
||||
if(ffStrbufEqualS(&result->processName, "pwsh"))
|
||||
ffStrbufInitStatic(&result->prettyName, "PowerShell");
|
||||
@@ -384,6 +384,14 @@ const FFShellResult* ffDetectShell()
|
||||
result.tty = -1;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate();
|
||||
ffProcessGetBasicInfoLinux(ppid, &_, &ppid, NULL);
|
||||
}
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
@@ -37,7 +38,7 @@ static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, const FFstrbuf* exePath, FFstrbuf* version);
|
||||
|
||||
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
|
||||
{
|
||||
@@ -345,6 +346,10 @@ const FFShellResult* ffDetectShell(void)
|
||||
if(!ffProcessGetInfoWindows(0, &ppid, NULL, NULL, NULL, NULL, NULL))
|
||||
return &result;
|
||||
|
||||
const char* ignoreParent = getenv("FFTS_IGNORE_PARENT");
|
||||
if (ignoreParent && ffStrEquals(ignoreParent, "1"))
|
||||
ffProcessGetInfoWindows(ppid, &ppid, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
|
||||
if (result.processName.length > 0)
|
||||
@@ -354,7 +359,7 @@ const FFShellResult* ffDetectShell(void)
|
||||
strcpy(tmp, result.exeName);
|
||||
char* ext = strrchr(tmp, '.');
|
||||
if (ext) *ext = '\0';
|
||||
fftsGetShellVersion(&result.exe, tmp, &result.version);
|
||||
fftsGetShellVersion(&result.exe, tmp, &result.exePath, &result.version);
|
||||
}
|
||||
|
||||
return &result;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "version.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
|
||||
#if defined(__x86_64__)
|
||||
#define FF_ARCHITECTURE "x86_64"
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686)
|
||||
#elif defined(__i386__)
|
||||
#define FF_ARCHITECTURE "i386"
|
||||
#elif defined(__aarch64__)
|
||||
#define FF_ARCHITECTURE "aarch64"
|
||||
@@ -16,6 +16,8 @@
|
||||
#define FF_ARCHITECTURE "riscv"
|
||||
#elif defined(__s390x__)
|
||||
#define FF_ARCHITECTURE "s390x"
|
||||
#elif defined(__loongarch__)
|
||||
#define FF_ARCHITECTURE "loongarch"
|
||||
#else
|
||||
#define FF_ARCHITECTURE "unknown"
|
||||
#endif
|
||||
@@ -44,6 +46,7 @@ FFVersionResult ffVersionResult = {
|
||||
.architecture = FF_ARCHITECTURE,
|
||||
.version = FASTFETCH_PROJECT_VERSION,
|
||||
.versionTweak = FASTFETCH_PROJECT_VERSION_TWEAK,
|
||||
.versionGit = FASTFETCH_PROJECT_VERSION_GIT,
|
||||
.cmakeBuiltType = FASTFETCH_PROJECT_CMAKE_BUILD_TYPE,
|
||||
.compileTime = __DATE__ ", " __TIME__,
|
||||
.compiler =
|
||||
|
||||
@@ -9,6 +9,7 @@ typedef struct FFVersionResult
|
||||
const char* architecture;
|
||||
const char* version;
|
||||
const char* versionTweak;
|
||||
const char* versionGit;
|
||||
const char* cmakeBuiltType;
|
||||
const char* compileTime;
|
||||
const char* compiler;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "wifi.h"
|
||||
#include "common/dbus.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/processing.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
@@ -177,8 +178,6 @@ static const char* detectWifiWithIw(FFWifiResult* item, FFstrbuf* buffer)
|
||||
}
|
||||
|
||||
#if FF_HAVE_LINUX_WIRELESS
|
||||
#include "common/io/io.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
// From https://github.com/openzfs/zfs/blob/master/include/libzfs.h
|
||||
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or https://opensource.org/licenses/CDDL-1.0.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ZPOOL_PROP_INVAL = -1,
|
||||
ZPOOL_PROP_NAME,
|
||||
ZPOOL_PROP_SIZE,
|
||||
ZPOOL_PROP_CAPACITY,
|
||||
ZPOOL_PROP_ALTROOT,
|
||||
ZPOOL_PROP_HEALTH,
|
||||
ZPOOL_PROP_GUID,
|
||||
ZPOOL_PROP_VERSION,
|
||||
ZPOOL_PROP_BOOTFS,
|
||||
ZPOOL_PROP_DELEGATION,
|
||||
ZPOOL_PROP_AUTOREPLACE,
|
||||
ZPOOL_PROP_CACHEFILE,
|
||||
ZPOOL_PROP_FAILUREMODE,
|
||||
ZPOOL_PROP_LISTSNAPS,
|
||||
ZPOOL_PROP_AUTOEXPAND,
|
||||
ZPOOL_PROP_DEDUPDITTO,
|
||||
ZPOOL_PROP_DEDUPRATIO,
|
||||
ZPOOL_PROP_FREE,
|
||||
ZPOOL_PROP_ALLOCATED,
|
||||
ZPOOL_PROP_READONLY,
|
||||
ZPOOL_PROP_ASHIFT,
|
||||
ZPOOL_PROP_COMMENT,
|
||||
ZPOOL_PROP_EXPANDSZ,
|
||||
ZPOOL_PROP_FREEING,
|
||||
ZPOOL_PROP_FRAGMENTATION,
|
||||
ZPOOL_PROP_LEAKED,
|
||||
ZPOOL_PROP_MAXBLOCKSIZE,
|
||||
ZPOOL_PROP_TNAME,
|
||||
ZPOOL_PROP_MAXDNODESIZE,
|
||||
ZPOOL_PROP_MULTIHOST,
|
||||
ZPOOL_PROP_CHECKPOINT,
|
||||
ZPOOL_PROP_LOAD_GUID,
|
||||
ZPOOL_PROP_AUTOTRIM,
|
||||
ZPOOL_PROP_COMPATIBILITY,
|
||||
ZPOOL_PROP_BCLONEUSED,
|
||||
ZPOOL_PROP_BCLONESAVED,
|
||||
ZPOOL_PROP_BCLONERATIO,
|
||||
ZPOOL_NUM_PROPS
|
||||
} zpool_prop_t;
|
||||
|
||||
typedef enum {
|
||||
ZPROP_SRC_NONE = 0x1,
|
||||
ZPROP_SRC_DEFAULT = 0x2,
|
||||
ZPROP_SRC_TEMPORARY = 0x4,
|
||||
ZPROP_SRC_LOCAL = 0x8,
|
||||
ZPROP_SRC_INHERITED = 0x10,
|
||||
ZPROP_SRC_RECEIVED = 0x20
|
||||
} zprop_source_t;
|
||||
|
||||
typedef bool boolean_t;
|
||||
|
||||
typedef struct libzfs_handle libzfs_handle_t;
|
||||
typedef struct zpool_handle zpool_handle_t;
|
||||
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
|
||||
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
|
||||
|
||||
extern libzfs_handle_t *libzfs_init(void);
|
||||
extern void libzfs_fini(libzfs_handle_t *);
|
||||
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *);
|
||||
extern const char *zpool_get_name(zpool_handle_t *);
|
||||
extern const char *zpool_get_state_str(zpool_handle_t *);
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFZpoolResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf state;
|
||||
uint64_t used;
|
||||
uint64_t total;
|
||||
uint64_t version;
|
||||
uint64_t fragmentation;
|
||||
} FFZpoolResult;
|
||||
|
||||
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */);
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "zpool.h"
|
||||
|
||||
#ifdef FF_HAVE_LIBZFS
|
||||
|
||||
#ifdef __sun
|
||||
#define FF_DISABLE_DLOPEN
|
||||
#include <libzfs.h>
|
||||
|
||||
const char* zpool_get_state_str(zpool_handle_t* zpool)
|
||||
{
|
||||
if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL)
|
||||
return "FAULTED";
|
||||
else
|
||||
{
|
||||
const char *str;
|
||||
zpool_errata_t errata;
|
||||
zpool_status_t status = zpool_get_status(zpool, (char**) &str, &errata);
|
||||
if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
|
||||
status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
|
||||
status == ZPOOL_STATUS_IO_FAILURE_MMP)
|
||||
return "SUSPENDED";
|
||||
else
|
||||
{
|
||||
nvlist_t *nvroot = fnvlist_lookup_nvlist(zpool_get_config(zpool, NULL), ZPOOL_CONFIG_VDEV_TREE);
|
||||
uint_t vsc;
|
||||
vdev_stat_t *vs;
|
||||
#ifdef __x86_64__
|
||||
if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint64_t**) &vs, &vsc) != 0)
|
||||
#else
|
||||
if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint32_t**) &vs, &vsc) != 0)
|
||||
#endif
|
||||
return "UNKNOWN";
|
||||
else
|
||||
return zpool_state_to_name(vs->vs_state, vs->vs_aux);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#include "libzfs_simplified.h"
|
||||
#endif
|
||||
|
||||
#include "common/library.h"
|
||||
|
||||
typedef struct FFZfsData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(libzfs_fini)
|
||||
FF_LIBRARY_SYMBOL(zpool_iter)
|
||||
FF_LIBRARY_SYMBOL(zpool_get_prop_int)
|
||||
FF_LIBRARY_SYMBOL(zpool_get_name)
|
||||
FF_LIBRARY_SYMBOL(zpool_get_state_str)
|
||||
|
||||
libzfs_handle_t* handle;
|
||||
FFlist* result;
|
||||
} FFZfsData;
|
||||
|
||||
static inline void cleanLibzfs(FFZfsData* data)
|
||||
{
|
||||
if (data->fflibzfs_fini && data->handle)
|
||||
{
|
||||
data->fflibzfs_fini(data->handle);
|
||||
data->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int enumZpoolCallback(zpool_handle_t* zpool, void* param)
|
||||
{
|
||||
FFZfsData* data = (FFZfsData*) param;
|
||||
zprop_source_t source;
|
||||
FFZpoolResult* item = ffListAdd(data->result);
|
||||
ffStrbufInitS(&item->name, data->ffzpool_get_name(zpool));
|
||||
ffStrbufInitS(&item->state, data->ffzpool_get_state_str(zpool));
|
||||
item->version = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_VERSION, &source);
|
||||
item->total = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_SIZE, &source);
|
||||
item->used = item->total - data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FREE, &source);
|
||||
item->fragmentation = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FRAGMENTATION, &source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libzfs, NULL, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init);
|
||||
|
||||
libzfs_handle_t* handle = fflibzfs_init();
|
||||
if (!handle) return "libzfs_init() failed";
|
||||
|
||||
__attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = {
|
||||
.handle = handle,
|
||||
.result = result,
|
||||
};
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_name);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_state_str);
|
||||
|
||||
if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0)
|
||||
return "zpool_iter() failed";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Fastfetch was compiled without libzfs support";
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "zpool.h"
|
||||
|
||||
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result /* list of FFZpoolResult */)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#define FASTFETCH_PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
|
||||
#define FASTFETCH_PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
|
||||
#define FASTFETCH_PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
|
||||
#define FASTFETCH_PROJECT_VERSION_GIT "@PROJECT_VERSION_GIT@"
|
||||
#define FASTFETCH_PROJECT_VERSION_TWEAK "@PROJECT_VERSION_TWEAK@"
|
||||
#define FASTFETCH_PROJECT_VERSION_TWEAK_NUM @PROJECT_VERSION_TWEAK_NUM@
|
||||
#define FASTFETCH_PROJECT_CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
|
||||
|
||||
@@ -13,4 +13,4 @@ ${c1} ///////${c3}\\\\\\\\\\//
|
||||
/\\\/${c1}\\/
|
||||
/\\\\//
|
||||
//////
|
||||
/// ${c3}\\\\\
|
||||
/// ${c3}\\\\\
|
||||
@@ -18,4 +18,4 @@ oOO OOo
|
||||
oO OOo
|
||||
oOO OOo
|
||||
oOO OOo
|
||||
ooo OOO OOO ooo
|
||||
ooo OOO OOO ooo
|
||||
@@ -12,4 +12,4 @@ ${c1}g@@@@M" ${c2}"VP`${c3}.L! ${c4}<@JJJJ`
|
||||
${c3}.@FJJJF`${c4},@LFFFF`
|
||||
${c3}_@FFFFF ${c4}VLLLP`
|
||||
${c3}J@@LL@" ${c4}`"
|
||||
${c3}V@@"
|
||||
${c3}V@@"
|
||||
@@ -3,4 +3,4 @@ ${c1} /\\ /\\
|
||||
/${c2}// ${c1}\\ \\
|
||||
/${c2}// ${c1}\\ \\
|
||||
${c2}// ${c1}\\ \\
|
||||
\\
|
||||
\\
|
||||
@@ -17,4 +17,4 @@
|
||||
@~:~~: ~:~~:~:(zltlltlO a,wwwwww
|
||||
8~~:~~:~~~~:~~~~_1ltltu ,www
|
||||
5~~:~~:~~:~~:~~:~~~_1ltq N,,
|
||||
g~:~~:~~~:~~:~~:~:~~~~1q N,
|
||||
g~:~~:~~~:~~:~~:~:~~~~1q N,
|
||||
@@ -19,4 +19,4 @@
|
||||
#####$2##%:$3######$2:############$1##
|
||||
##$2+##*$3########$2############$1
|
||||
$2###$3#########$2##########$1
|
||||
$3########$2######
|
||||
$3########$2######
|
||||
@@ -16,4 +16,4 @@ dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
|
||||
dMMMMMMMMMMMMMMMMh yMMMMMMMMMMMMMMMMd
|
||||
.:+ydNMMMMMMMMMMMh yMMMMMMMMMMMNdy+:.
|
||||
`.:+shNMMMMMh yMMMMMNhs+:``
|
||||
`-+shy shs+:`
|
||||
`-+shy shs+:`
|
||||
@@ -7,4 +7,4 @@
|
||||
~~~ /
|
||||
~~._. _/
|
||||
_/ _/
|
||||
_/m/'
|
||||
_/m/'
|
||||
+19
-19
@@ -1,19 +1,19 @@
|
||||
${c1} ___________
|
||||
/ \
|
||||
/ ${c2}______${c1} \
|
||||
/ ${c2}/ \${c1} \
|
||||
| ${c2}( )${c1} \
|
||||
/ ${c2}\______/${c1} |
|
||||
| |
|
||||
/ \
|
||||
| |
|
||||
| |
|
||||
/ |
|
||||
| |
|
||||
| _______ |
|
||||
____/ / \ |
|
||||
/ | | |
|
||||
| / ____/ |
|
||||
\_________/ / |
|
||||
\ __/
|
||||
\_______/
|
||||
___________
|
||||
/ \
|
||||
/ ${c2}______${c1} \
|
||||
/ ${c2}/ \${c1} \
|
||||
| ${c2}( )${c1} \
|
||||
/ ${c2}\______/${c1} |
|
||||
| |
|
||||
/ \
|
||||
| |
|
||||
| |
|
||||
/ |
|
||||
| |
|
||||
| _______ |
|
||||
____/ / \ |
|
||||
/ | | |
|
||||
| / ____/ |
|
||||
\_________/ / |
|
||||
\ __/
|
||||
\_______/
|
||||
@@ -25,4 +25,4 @@
|
||||
${c2}.${c1} ${c2}.:+++${c1}.
|
||||
${c2}.:${c1}:
|
||||
${c2}..${c1}
|
||||
${c2}..${c1}
|
||||
${c2}..${c1}
|
||||
@@ -16,4 +16,4 @@ dmmmdddddddhhhyso${c1}++++++${c2}shhhhhddddddmmmmh
|
||||
-dmmmdddddddhhys${c1}o++++o${c2}shhhhdddddddmmmmd-
|
||||
.smmmmddddddddhhhhhhhhhdddddddddmmmms.
|
||||
`+ydmmmdddddddddddddddddddmmmmdy/.
|
||||
`.:+ooyyddddddddddddyyso+:.`
|
||||
`.:+ooyyddddddddddddyyso+:.`
|
||||
@@ -9,4 +9,4 @@
|
||||
\,_/\_/ | |_/|_/|_/_/ \,
|
||||
, / ,\
|
||||
, / , ' \
|
||||
' - , _ _ _ , '
|
||||
' - , _ _ _ , '
|
||||
@@ -14,4 +14,4 @@ ${c4}^MMM@@@@@@@@@@@MP" ${c3},ggppww__
|
||||
${c3}_gBNNNNNNNNNNNNNNNNNP"
|
||||
${c3}_wNNNNNNNNNNNNNNNNNNNM^
|
||||
${c3}""Y^^MNNNNNNNNNNNNP`
|
||||
${c3}`"""""""
|
||||
${c3}`"""""""
|
||||
@@ -17,4 +17,4 @@
|
||||
+NMMMMMms/.` mMMMMMMMMMMMN+
|
||||
`+mMMMMMMMMNmddMMMMMMMMMMm+`
|
||||
.ohNMMMMMMMMMMMMMMNho.
|
||||
.:+syhhhhys+:.
|
||||
.:+syhhhhys+:.
|
||||
@@ -15,4 +15,4 @@ ${c2} .........
|
||||
${c3}................ ${c4}***********
|
||||
${c3}................ ${c4}###########
|
||||
${c3}****************
|
||||
${c3}################
|
||||
${c3}################
|
||||
@@ -6,4 +6,4 @@ ${c2} _____ ${c1}_____${c2}
|
||||
\\ / _____ \\${c4}___
|
||||
${c3}|${c2}/_/ ${c3}| ${c4}| |
|
||||
${c3}| | ${c4}|___|
|
||||
${c3}|_____|
|
||||
${c3}|_____|
|
||||
@@ -17,4 +17,4 @@
|
||||
=XMMM@MM@MM#H;,-+HMM@M+ /MMMX=
|
||||
=%@M@M#@S-.=S@MM@@@M; %M%=
|
||||
,:+S+-,/H#MMMMMMM@= =,
|
||||
=++%%%%+/:-.
|
||||
=++%%%%+/:-.
|
||||
@@ -15,4 +15,4 @@ MMMMMM/`.-/ohmNMMMMMMy-
|
||||
MMMMMMNmNNMMMMMMMMmo.
|
||||
MMMMMMMMMMMMMMMms:`
|
||||
MMMMMMMMMMNds/.
|
||||
dhhyys+/-`
|
||||
dhhyys+/-`
|
||||
@@ -16,4 +16,4 @@ $2 .oossssso-````/ossssss+`
|
||||
`/ossssso+/:- -:/+osssso+-
|
||||
`+sso+:-` `.-/+oso:
|
||||
`++:. `-/+/
|
||||
.` `/
|
||||
.` `/
|
||||
@@ -16,4 +16,4 @@ $2 ▟█████████▛▀▀▜████████▙
|
||||
▟██████████▛ ▜█████████▙
|
||||
▟██████▀▀▀ ▀▀██████▙
|
||||
▟███▀▘ ▝▀███▙
|
||||
▟▛▀ ▀▜▙
|
||||
▟▛▀ ▀▜▙
|
||||
@@ -16,4 +16,4 @@ $2 / ,.-+-.. \
|
||||
/ __,--+" "+--.__ \
|
||||
/ _,+'" "'+._ \
|
||||
/,-' `-.\
|
||||
' '
|
||||
' '
|
||||
@@ -4,4 +4,4 @@
|
||||
/ \
|
||||
$2 / ,, \
|
||||
/ | | \
|
||||
/_-'' ''-_\
|
||||
/_-'' ''-_\
|
||||
@@ -16,4 +16,4 @@
|
||||
/:::+`hhhhoos` `hhhhhhhhhhhhhhhhhs+`
|
||||
`--/:` /: `hhhhhhhhhhhho/-
|
||||
-/:. `hhhhhhs+:-`
|
||||
::::/ho/-`
|
||||
::::/ho/-`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user