mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Compare commits
137 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 18374467e6 | |||
| 499e6c85a0 | |||
| 0610faf1be | |||
| 778c6f0513 | |||
| c55ba2685f | |||
| aae66aa966 | |||
| a95b60167c | |||
| f5b987dba9 | |||
| f8eabdd8a6 | |||
| 5ab2c3456d | |||
| 97d9ffd193 | |||
| fa86bb1f0b | |||
| 5b9c5ebb5a | |||
| 56b03a93c5 | |||
| 3b319f0a1e | |||
| c3352d6d28 | |||
| f8426384d8 | |||
| 8791281b48 | |||
| 76ec8aff2e | |||
| 7660b0a091 | |||
| 7a8e484634 | |||
| ed01272b91 | |||
| 1c660caa85 | |||
| c241ead1d5 | |||
| 168d96a182 | |||
| 2075761282 | |||
| d59de1f158 | |||
| d64716ab74 | |||
| 0ffbb8c364 | |||
| c29960abf2 | |||
| 315cb24046 | |||
| 4cabc5684b | |||
| 256c9be19b | |||
| 1b3d713e50 | |||
| 6e816fca6e | |||
| 5a699af610 | |||
| 390119c592 | |||
| 11d7eec4db | |||
| f59be1faf2 | |||
| 7bc4c63eb4 | |||
| 4bf9f524d9 | |||
| 6508ccfc0d | |||
| d0a8d3cdc4 | |||
| 494cc1493e | |||
| 761c649817 | |||
| a2f576f3e5 | |||
| 3b9b03a086 | |||
| ab51a209d7 | |||
| 38ac339011 | |||
| b4777fe73a | |||
| b6e759f3a2 | |||
| 9ddefbc1a2 | |||
| a16851f5de | |||
| 8fe291d161 | |||
| 9ac50fc42f | |||
| c6e5221826 | |||
| 5b2006cd06 | |||
| d3f673dc6f | |||
| b99f444234 | |||
| c504096181 | |||
| c9ef47271a | |||
| fc3891c913 | |||
| cd07354b6f | |||
| fd5aeb2052 | |||
| b1b583721a | |||
| 4c3372a886 | |||
| cf66679323 | |||
| 55b41144db | |||
| ae34208247 | |||
| b462006280 | |||
| 485bcbf054 | |||
| 2e30a57889 | |||
| b439d9c203 | |||
| 08a717f5f7 | |||
| 3a84a1a5fa | |||
| 627d5fc659 | |||
| 25849dc4bb | |||
| 63032cd840 | |||
| 2414246de9 | |||
| c52353b4b8 | |||
| 799628c083 | |||
| 38d5791d57 | |||
| 9d664e2b61 | |||
| 2eb21e3521 | |||
| bfe1265c44 | |||
| dd3109cd89 | |||
| 130d5a5202 | |||
| cda4c62e9e | |||
| df245f32ec | |||
| 04409f4381 | |||
| 155e4a5b80 | |||
| 59a9209621 | |||
| cd5e14a834 | |||
| e707cf8464 | |||
| 8bdd410e97 | |||
| f45654620f | |||
| 72d138f8c4 | |||
| 6a0df7ae49 | |||
| 23def0a1c7 | |||
| 3236ef075d | |||
| d00b301904 | |||
| 6c82686283 | |||
| 399e2235d4 | |||
| bd898e4006 | |||
| 2c49dcceaf | |||
| 3c5b002414 | |||
| ca37206a49 | |||
| 8a939e981c | |||
| bed1b4cf0f | |||
| 04c3a4ccf7 | |||
| f50368a949 | |||
| 4e018dbf26 | |||
| fa02217ff4 | |||
| 22080d36b0 | |||
| 3303f4e1ce | |||
| 11d03ad59e | |||
| 504f1533c2 | |||
| bf1d1cbac5 | |||
| 94119d1674 | |||
| f4a263df01 | |||
| 533231825c | |||
| 40e2787d94 | |||
| 281af9c86f | |||
| fc0db8c291 | |||
| 48d2dbad34 | |||
| be2af8aeaf | |||
| a7621a7301 | |||
| ec87790e4f | |||
| 44632e9bf6 | |||
| 824ada49b6 | |||
| e7938216ba | |||
| 40d6d0b7b5 | |||
| 3f4d4c8eea | |||
| e2fe94d4e4 | |||
| debb5d8ad1 | |||
| f61794ea70 | |||
| d15a977431 |
+33
-19
@@ -28,6 +28,9 @@ jobs:
|
|||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
- name: install required packages
|
- name: install required packages
|
||||||
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
|
run: sudo apt-get update && sudo apt-get install -y musl-dev musl-tools linux-headers-generic libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
|
||||||
|
|
||||||
@@ -35,7 +38,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler.cc }}
|
CC: ${{ matrix.compiler.cc }}
|
||||||
CXX: ${{ matrix.compiler.cxx }}
|
CXX: ${{ matrix.compiler.cxx }}
|
||||||
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_JSONC=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} .
|
run: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_LIBPCI=${{ matrix.enableFeatures }} -DENABLE_VULKAN=${{ matrix.enableFeatures }} -DENABLE_WAYLAND=${{ matrix.enableFeatures }} -DENABLE_XCB_RANDR=${{ matrix.enableFeatures }} -DENABLE_XCB=${{ matrix.enableFeatures }} -DENABLE_XRANDR=${{ matrix.enableFeatures }} -DENABLE_X11=${{ matrix.enableFeatures }} -DENABLE_GIO=${{ matrix.enableFeatures }} -DENABLE_DCONF=${{ matrix.enableFeatures }} -DENABLE_DBUS=${{ matrix.enableFeatures }} -DENABLE_XFCONF=${{ matrix.enableFeatures }} -DENABLE_SQLITE3=${{ matrix.enableFeatures }} -DENABLE_RPM=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK7=${{ matrix.enableFeatures }} -DENABLE_IMAGEMAGICK6=${{ matrix.enableFeatures }} -DENABLE_CHAFA=${{ matrix.enableFeatures }} -DENABLE_ZLIB=${{ matrix.enableFeatures }} -DENABLE_EGL=${{ matrix.enableFeatures }} -DENABLE_GLX=${{ matrix.enableFeatures }} -DENABLE_OSMESA=${{ matrix.enableFeatures }} -DENABLE_OPENCL=${{ matrix.enableFeatures }} -DENABLE_LIBNM=${{ matrix.enableFeatures }} -DENABLE_PULSE=${{ matrix.enableFeatures }} -DENABLE_DIRECTX_HEADERS=${{ matrix.enableFeatures }} .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build .
|
run: cmake --build .
|
||||||
@@ -43,6 +46,9 @@ jobs:
|
|||||||
- name: run tests
|
- name: run tests
|
||||||
run: ctest
|
run: ctest
|
||||||
|
|
||||||
|
- name: run fastfetch --list-features
|
||||||
|
run: ./fastfetch --list-features
|
||||||
|
|
||||||
- name: run fastfetch
|
- name: run fastfetch
|
||||||
run: time ./fastfetch -c presets/ci
|
run: time ./fastfetch -c presets/ci
|
||||||
|
|
||||||
@@ -64,19 +70,27 @@ jobs:
|
|||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
- name: install required packages
|
- name: install required packages
|
||||||
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
|
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev rpm librpm-dev libzstd-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev
|
||||||
|
|
||||||
|
- name: install linuxbrew packages
|
||||||
|
run: |
|
||||||
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
|
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick --ignore-dependencies
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
with:
|
with:
|
||||||
languages: c
|
languages: c
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package
|
run: cmake --build . --target package --verbose
|
||||||
|
|
||||||
- name: perform CodeQL analysis
|
- name: perform CodeQL analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v2
|
||||||
@@ -119,8 +133,13 @@ jobs:
|
|||||||
- name: checkout repository
|
- name: checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: uname -a
|
||||||
|
run: uname -a
|
||||||
|
|
||||||
- name: install required packages
|
- name: install required packages
|
||||||
run: brew install vulkan-loader molten-vk imagemagick chafa
|
run: |
|
||||||
|
brew update
|
||||||
|
brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v2
|
||||||
@@ -131,7 +150,7 @@ jobs:
|
|||||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build . --target package
|
run: cmake --build . --target package --verbose
|
||||||
|
|
||||||
- name: perform CodeQL analysis
|
- name: perform CodeQL analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v2
|
||||||
@@ -171,13 +190,16 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: run VM
|
- name: run VM
|
||||||
uses: vmactions/freebsd-vm@v0
|
uses: cross-platform-actions/action@v0.21.1
|
||||||
with:
|
with:
|
||||||
prepare: |
|
operating_system: freebsd
|
||||||
pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
|
version: '13.2'
|
||||||
run: |
|
run: |
|
||||||
|
uname -a
|
||||||
|
sudo pkg update
|
||||||
|
sudo pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
|
||||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||||
cmake --build . --target package
|
cmake --build . --target package --verbose
|
||||||
./fastfetch --list-features
|
./fastfetch --list-features
|
||||||
time ./fastfetch -c presets/ci
|
time ./fastfetch -c presets/ci
|
||||||
time ./fastfetch -c presets/ci --format json
|
time ./fastfetch -c presets/ci --format json
|
||||||
@@ -214,19 +236,11 @@ jobs:
|
|||||||
- name: print msys version
|
- name: print msys version
|
||||||
run: uname -a
|
run: uname -a
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v2
|
|
||||||
with:
|
|
||||||
languages: c, cpp
|
|
||||||
|
|
||||||
- name: configure project
|
- name: configure project
|
||||||
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build .
|
run: cmake --build . --verbose
|
||||||
|
|
||||||
- name: perform CodeQL analysis
|
|
||||||
uses: github/codeql-action/analyze@v2
|
|
||||||
|
|
||||||
- name: copy necessary dlls
|
- name: copy necessary dlls
|
||||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||||
@@ -293,7 +307,7 @@ jobs:
|
|||||||
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||||
|
|
||||||
- name: build project
|
- name: build project
|
||||||
run: cmake --build .
|
run: cmake --build . --verbose
|
||||||
|
|
||||||
- name: perform CodeQL analysis
|
- name: perform CodeQL analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|||||||
@@ -1,3 +1,80 @@
|
|||||||
|
# 2.2.2
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* `--percent-type` now defaults to 9 (colored percentage numbers)
|
||||||
|
* `fastfetch` now prints LocalIp module by default
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* LocalIP module now prints netmask in CIDR format for IPv4 (LocalIP)
|
||||||
|
* Bios module now detects system firmware type (Bios)
|
||||||
|
* Improve detection of `Battery`
|
||||||
|
* Detect cycle count on supported platforms
|
||||||
|
* Detect temperature on Linux when supported
|
||||||
|
* Status detection on macOS has been adjusted to be consistant with other platforms
|
||||||
|
* Linux binaries are built with imagemagick7 support
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix unitialized variables (#609)
|
||||||
|
* Fix spelling of `--preserve-aspect-ratio` (#614)
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
|
||||||
|
* Update NixOS_small
|
||||||
|
|
||||||
|
# 2.2.1
|
||||||
|
|
||||||
|
Hotfix release for #606
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Fix broken presets due to the breaking changes introduced in 2.2.0
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Pretty print `fastfetch --help`
|
||||||
|
|
||||||
|
# 2.2.0
|
||||||
|
|
||||||
|
This release introduces a new option `--migrate-config`, which migrates old flag based config file to new JSONC format
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* `--pipe` and `--stat` are moved from `general` options to `display` options. This affects cjson configuration.
|
||||||
|
* Display keys `percent*` and `size*` in JSON config are restructured. e.g. `{ "sizeNdigits": 1 }` is now `{ "size": { "ndigits": 1 } }`
|
||||||
|
* With the introduction of `--migrate-config`, the old flag based config file is deprecated, and will be removed in 3.0.0 (next major version)
|
||||||
|
* Support of `--gen-config conf` is deprecated accordingly, and will be removed in 2.3.0 (next minor version)
|
||||||
|
* The global flag `--allow-slow-operations` is splitted into some explicit flags in differnet modules
|
||||||
|
* `--packages-winget`: control whether `winget` packages count should be detected. Note it's a very slow operation, please enable it with caution.
|
||||||
|
* `--chassis-use-wmi`: control whether `WMI` query should be used to detect chassis type, which detects more information, but slower. This flag only affects `--chassis-format` and `--format json`.
|
||||||
|
* `--battery-use-setup-api`: control whether `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower.
|
||||||
|
* `--wm-detect-plugin`: control whether WM plugins should be detected. Note it's implemented with global processes enumeration and can report false results.
|
||||||
|
* `--de-slow-version-detection`: control DE version should be detected with slow operations. It's usually not necessary and only provided as a backup.
|
||||||
|
* `--localip-default-route-only` and `--netio-default-route-only` defaults to true to avoid large number of results
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Quirks for MIPS platforms (CPU, Linux)
|
||||||
|
* Use devicetree path for OBP hosts (Host, Linux)
|
||||||
|
* Detect `tmux: server` as tmux (Terminal, Linux)
|
||||||
|
* Support urxvt version detection (Terminal, Linux)
|
||||||
|
* Support st version detection (Terminal, Linux)
|
||||||
|
* Support st terminal font detection (TerminalFont, Linux)
|
||||||
|
* Support xfce4-terminal 1.1.0+ terminal font detection (TerminalFont, Linux)
|
||||||
|
* Add option `--migrate-config <?target-file-path>`
|
||||||
|
* Support Nvidia GPU temp and cuda core count detection via nvml. Use `--gpu-use-nvml` to enable it (GPU)
|
||||||
|
* Try supporting Wifi authentication type detection in macOS Sonoma. Please file a feature request if you get `to be supported (num)` with result of `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep auth` (Wifi, macOS)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
* Better GPU memory and type detection (GPU, Windows)
|
||||||
|
* Don't print display type twice (Display)
|
||||||
|
* Detect BSSID instead of Wifi MAC address to align with other platforms (Wifi, macOS)
|
||||||
|
* Remove support of used GPU memory detection, which is not reliable and only supported with `--gpu-force-vulkan`. (GPU)
|
||||||
|
* Fix flag `--brightness-ddcci-sleep` (Brightness, Linux)
|
||||||
|
* Fix hanging if a child process prints to both stdout and stderr (Linux)
|
||||||
|
|
||||||
|
Logos:
|
||||||
|
* Add Black Mesa
|
||||||
|
* Add cycledream
|
||||||
|
* Add Evolinx
|
||||||
|
* Add azos
|
||||||
|
* Add Interix
|
||||||
|
|
||||||
# 2.1.2
|
# 2.1.2
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
@@ -27,6 +104,8 @@ Logo:
|
|||||||
* Add Chimera Linux
|
* Add Chimera Linux
|
||||||
* Add EndeavourSmall
|
* Add EndeavourSmall
|
||||||
* Add Xenia
|
* Add Xenia
|
||||||
|
* Add MainsailOS
|
||||||
|
* Fix phyOS
|
||||||
|
|
||||||
# 2.1.0
|
# 2.1.0
|
||||||
|
|
||||||
|
|||||||
+35
-16
@@ -1,9 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||||
|
|
||||||
project(fastfetch
|
project(fastfetch
|
||||||
VERSION 2.1.2
|
VERSION 2.2.2
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
DESCRIPTION "Fast system information tool"
|
DESCRIPTION "Fast neofetch-like system information tool"
|
||||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -70,8 +70,9 @@ 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_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||||
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
|
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
|
||||||
cmake_dependent_option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
|
|
||||||
|
|
||||||
|
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF)
|
||||||
|
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||||
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ endif()
|
|||||||
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
|
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
||||||
|
|
||||||
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
||||||
enable_language(CXX)
|
enable_language(CXX)
|
||||||
@@ -116,7 +117,8 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
|
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
|
||||||
if(NOT WIN32 AND NOT APPLE)
|
if(ENABLE_ASAN)
|
||||||
|
message(STATUS "Address sanitizer enabled (DEBUG only)")
|
||||||
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address")
|
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address")
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
|
||||||
@@ -232,14 +234,11 @@ endif()
|
|||||||
|
|
||||||
function(fastfetch_load_raw_text FILENAME OUTVAR)
|
function(fastfetch_load_raw_text FILENAME OUTVAR)
|
||||||
file(READ "${FILENAME}" TEMP)
|
file(READ "${FILENAME}" TEMP)
|
||||||
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
||||||
string(JSON TEMP SET "{}" "${TEMP}" "0") # Encode raw strings using JSON_SET
|
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
|
||||||
string(REGEX REPLACE "^\\{[ \t\r\n]*" "" TEMP "${TEMP}") # Remove JSON braces
|
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||||
string(REGEX REPLACE "[ \t\r\n]*:[ \t\r\n]*0[ \t\r\n]*\\}$" "" TEMP "${TEMP}") # Remove trailing ` : 0 }`
|
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||||
if(NOT "${TEMP}" MATCHES "^\"[^\n]*\"")
|
set(${OUTVAR} "\"${TEMP}\"" PARENT_SCOPE)
|
||||||
message(FATAL_ERROR "Internal error: unexpected output: '${TEMP}'")
|
|
||||||
endif()
|
|
||||||
set(${OUTVAR} "${TEMP}" PARENT_SCOPE)
|
|
||||||
endfunction(fastfetch_load_raw_text)
|
endfunction(fastfetch_load_raw_text)
|
||||||
|
|
||||||
file(GLOB LOGO_FILES "src/logo/ascii/*.txt")
|
file(GLOB LOGO_FILES "src/logo/ascii/*.txt")
|
||||||
@@ -297,7 +296,6 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/logo/image/im7.c
|
src/logo/image/im7.c
|
||||||
src/logo/image/image.c
|
src/logo/image/image.c
|
||||||
src/logo/logo.c
|
src/logo/logo.c
|
||||||
src/logo/option.c
|
|
||||||
src/modules/battery/battery.c
|
src/modules/battery/battery.c
|
||||||
src/modules/bios/bios.c
|
src/modules/bios/bios.c
|
||||||
src/modules/bluetooth/bluetooth.c
|
src/modules/bluetooth/bluetooth.c
|
||||||
@@ -355,6 +353,11 @@ set(LIBFASTFETCH_SRC
|
|||||||
src/modules/wifi/wifi.c
|
src/modules/wifi/wifi.c
|
||||||
src/modules/wm/wm.c
|
src/modules/wm/wm.c
|
||||||
src/modules/wmtheme/wmtheme.c
|
src/modules/wmtheme/wmtheme.c
|
||||||
|
src/options/display.c
|
||||||
|
src/options/modules.c
|
||||||
|
src/options/logo.c
|
||||||
|
src/options/general.c
|
||||||
|
src/options/library.c
|
||||||
src/util/edidHelper.c
|
src/util/edidHelper.c
|
||||||
src/util/FFlist.c
|
src/util/FFlist.c
|
||||||
src/util/FFstrbuf.c
|
src/util/FFstrbuf.c
|
||||||
@@ -388,6 +391,7 @@ if(LINUX)
|
|||||||
src/detection/displayserver/linux/xlib.c
|
src/detection/displayserver/linux/xlib.c
|
||||||
src/detection/font/font_linux.c
|
src/detection/font/font_linux.c
|
||||||
src/detection/gpu/gpu_linux.c
|
src/detection/gpu/gpu_linux.c
|
||||||
|
src/detection/gpu/gpu_nvidia.c
|
||||||
src/detection/gtk_qt/gtk.c
|
src/detection/gtk_qt/gtk.c
|
||||||
src/detection/host/host_linux.c
|
src/detection/host/host_linux.c
|
||||||
src/detection/icons/icons_linux.c
|
src/detection/icons/icons_linux.c
|
||||||
@@ -416,6 +420,8 @@ if(LINUX)
|
|||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_linux.c
|
src/detection/wallpaper/wallpaper_linux.c
|
||||||
src/detection/wifi/wifi_linux.c
|
src/detection/wifi/wifi_linux.c
|
||||||
|
src/detection/wm/wm_nosupport.c
|
||||||
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
src/util/platform/FFPlatform_unix.c
|
||||||
)
|
)
|
||||||
@@ -465,6 +471,8 @@ elseif(ANDROID)
|
|||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_nosupport.c
|
src/detection/wallpaper/wallpaper_nosupport.c
|
||||||
src/detection/wifi/wifi_android.c
|
src/detection/wifi/wifi_android.c
|
||||||
|
src/detection/wm/wm_nosupport.c
|
||||||
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_nosupport.c
|
src/detection/wmtheme/wmtheme_nosupport.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
src/util/platform/FFPlatform_unix.c
|
||||||
)
|
)
|
||||||
@@ -494,6 +502,7 @@ elseif(BSD)
|
|||||||
src/detection/displayserver/linux/xlib.c
|
src/detection/displayserver/linux/xlib.c
|
||||||
src/detection/font/font_linux.c
|
src/detection/font/font_linux.c
|
||||||
src/detection/gpu/gpu_linux.c
|
src/detection/gpu/gpu_linux.c
|
||||||
|
src/detection/gpu/gpu_nvidia.c
|
||||||
src/detection/gtk_qt/gtk.c
|
src/detection/gtk_qt/gtk.c
|
||||||
src/detection/host/host_bsd.c
|
src/detection/host/host_bsd.c
|
||||||
src/detection/lm/lm_linux.c
|
src/detection/lm/lm_linux.c
|
||||||
@@ -522,6 +531,8 @@ elseif(BSD)
|
|||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_linux.c
|
src/detection/wallpaper/wallpaper_linux.c
|
||||||
src/detection/wifi/wifi_bsd.c
|
src/detection/wifi/wifi_bsd.c
|
||||||
|
src/detection/wm/wm_nosupport.c
|
||||||
|
src/detection/de/de_linux.c
|
||||||
src/detection/wmtheme/wmtheme_linux.c
|
src/detection/wmtheme/wmtheme_linux.c
|
||||||
src/util/platform/FFPlatform_unix.c
|
src/util/platform/FFPlatform_unix.c
|
||||||
)
|
)
|
||||||
@@ -572,6 +583,8 @@ elseif(APPLE)
|
|||||||
src/detection/users/users_linux.c
|
src/detection/users/users_linux.c
|
||||||
src/detection/wallpaper/wallpaper_apple.c
|
src/detection/wallpaper/wallpaper_apple.c
|
||||||
src/detection/wifi/wifi_apple.m
|
src/detection/wifi/wifi_apple.m
|
||||||
|
src/detection/wm/wm_apple.c
|
||||||
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_apple.m
|
src/detection/wmtheme/wmtheme_apple.m
|
||||||
src/util/apple/cf_helpers.c
|
src/util/apple/cf_helpers.c
|
||||||
src/util/apple/osascript.m
|
src/util/apple/osascript.m
|
||||||
@@ -597,6 +610,7 @@ elseif(WIN32)
|
|||||||
src/detection/displayserver/displayserver_windows.c
|
src/detection/displayserver/displayserver_windows.c
|
||||||
src/detection/font/font_windows.c
|
src/detection/font/font_windows.c
|
||||||
src/detection/gpu/gpu_windows.c
|
src/detection/gpu/gpu_windows.c
|
||||||
|
src/detection/gpu/gpu_nvidia.c
|
||||||
src/detection/host/host_windows.c
|
src/detection/host/host_windows.c
|
||||||
src/detection/icons/icons_windows.c
|
src/detection/icons/icons_windows.c
|
||||||
src/detection/libc/libc_windows.cpp
|
src/detection/libc/libc_windows.cpp
|
||||||
@@ -623,6 +637,8 @@ elseif(WIN32)
|
|||||||
src/detection/users/users_windows.c
|
src/detection/users/users_windows.c
|
||||||
src/detection/wallpaper/wallpaper_windows.c
|
src/detection/wallpaper/wallpaper_windows.c
|
||||||
src/detection/wifi/wifi_windows.c
|
src/detection/wifi/wifi_windows.c
|
||||||
|
src/detection/wm/wm_windows.cpp
|
||||||
|
src/detection/de/de_nosupport.c
|
||||||
src/detection/wmtheme/wmtheme_windows.c
|
src/detection/wmtheme/wmtheme_windows.c
|
||||||
src/util/windows/getline.c
|
src/util/windows/getline.c
|
||||||
src/util/windows/com.cpp
|
src/util/windows/com.cpp
|
||||||
@@ -868,8 +884,11 @@ elseif(APPLE)
|
|||||||
PRIVATE "-framework OpenCL"
|
PRIVATE "-framework OpenCL"
|
||||||
PRIVATE "-framework SystemConfiguration"
|
PRIVATE "-framework SystemConfiguration"
|
||||||
PRIVATE "-weak_framework CoreDisplay"
|
PRIVATE "-weak_framework CoreDisplay"
|
||||||
PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks"
|
|
||||||
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
|
PRIVATE "-F /System/Library/PrivateFrameworks"
|
||||||
|
PRIVATE "-weak_framework DisplayServices"
|
||||||
|
PRIVATE "-weak_framework MediaRemote"
|
||||||
|
PRIVATE "-weak_framework Apple80211"
|
||||||
)
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
|
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
|
||||||
|
|||||||
@@ -23,147 +23,53 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
|
|||||||
|
|
||||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
||||||
|
|
||||||
## Customization
|
## Installation
|
||||||
|
|
||||||
With customization and speed being two competing goals, this project actually builds two executables:
|
### Linux
|
||||||
|
|
||||||
* The main one is `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent by modifying `$XDG_CONFIG_HOME/fastfetch/config.conf`. Use `fastfetch --gen-config conf` to generate one. To view the available options, run `fastfetch --help`.
|
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `sudo apt install fastfetch-<version>-Linux.deb`
|
||||||
* The second executable is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c).
|
* Arch Linux: `sudo pacman -S fastfetch`
|
||||||
|
* Fedora: `sudo dnf install fastfetch`
|
||||||
|
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||||
|
|
||||||
Currently, the performance difference is measurable, but too small to be recognizable by humans. But with more options planned, the leap will get bigger over time and on slow machines this might actually make a difference.
|
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging)
|
||||||
|
|
||||||
There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config <filename>`. They may also serve as a good example for format arguments.
|
|
||||||
|
|
||||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
|
||||||
|
|
||||||
### Customization with new JSONC format
|
|
||||||
|
|
||||||
A new, structure based, and user-friendly config file format was introduced in v2.0.0. This format is based on [JSONC](https://jsonc.org/). [See more details in Wiki](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration)
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`, `libm` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most Linux distributions.
|
|
||||||
|
|
||||||
The following libraries are used if present at runtime:
|
|
||||||
|
|
||||||
### Linux and FreeBSD
|
|
||||||
|
|
||||||
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
|
|
||||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
|
|
||||||
* [`libxcb-randr`](https://xcb.freedesktop.org/),
|
|
||||||
[`libXrandr`](https://gitlab.freedesktop.org/xorg/lib/libxrandr),
|
|
||||||
[`libxcb`](https://xcb.freedesktop.org/),
|
|
||||||
[`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better display detection and faster WM detection. The `*randr` ones provide multi monitor support The `libxcb*` ones usually have better performance.
|
|
||||||
* [`libwayland-client`](https://wayland.freedesktop.org/): Better display performance and output in wayland sessions. Supports different refresh rates per monitor.
|
|
||||||
* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings.
|
|
||||||
* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings.
|
|
||||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol.
|
|
||||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art.
|
|
||||||
* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol.
|
|
||||||
* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Bluetooth, Player & Media detection.
|
|
||||||
* [`libEGL`](https://www.khronos.org/registry/EGL/),
|
|
||||||
[`libGLX`](https://dri.freedesktop.org/wiki/GLX/),
|
|
||||||
[`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation.
|
|
||||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
|
|
||||||
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
|
|
||||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
|
|
||||||
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
|
|
||||||
* [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection.
|
|
||||||
* [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection.
|
|
||||||
* [`libddcutil`](https://github.com/rockowitz/ddcutil): Used for brightness detection of external displays
|
|
||||||
* [`DirectX-Headers`](https://github.com/microsoft/DirectX-Headers): Used for GPU detection in WSL
|
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
* [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system.
|
`brew install fastfetch`
|
||||||
* [`DisplayServices`](https://developer.apple.com/forums/thread/666383#663154022): Need for screen brightness detection. It's a private framework provided by newer macOS system.
|
|
||||||
* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb)
|
|
||||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb)
|
|
||||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb)
|
|
||||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Used for fast wallpaper detection ( fallback to AppleScript )
|
|
||||||
|
|
||||||
For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported.
|
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
* [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection.
|
`scoop install fastfetch`
|
||||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers)
|
|
||||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd)
|
|
||||||
|
|
||||||
Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, as fastfetch for Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library, [it must be installed manually](https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c) as UCRT is only pre-installed in Windows 10 and later.
|
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
|
||||||
|
|
||||||
For the image logo, WezTerm with iterm image protocol is known to work, surprisingly.
|
### FreeBSD
|
||||||
|
|
||||||
### Android
|
`pkg install fastfetch`
|
||||||
|
|
||||||
* [`freetype`](https://www.freetype.org/): Used for Termux font detection. [`freetype`](https://github.com/termux/termux-packages/tree/master/packages/freetype)
|
### Android (Termux)
|
||||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. [`vulkan-loader-android`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-loader-android) [`vulkan-headers`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-headers)
|
|
||||||
* [`termux-api`](https://github.com/termux/termux-api-package): Used for Wifi / Battery detection. Both the package [termux-api](https://github.com/termux/termux-packages/tree/master/packages/termux-api) and the Android app [Termux API](https://github.com/termux/termux-api) must be installed and the app `Termux API` must be configured to be able to self-running. In order to make Wifi detection actuall work, location privilege must be granted to the app `Termux API`. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail.
|
|
||||||
* [`libandroid-wordexp-static`](https://github.com/termux/termux-packages/tree/master/packages/libandroid-wordexp): `wordexp.h` support for Android.
|
|
||||||
|
|
||||||
For the image logo, [Termux Monet](https://github.com/HardcodedCat/termux-monet) supports iterm image protocol.
|
`pkg install fastfetch`
|
||||||
|
|
||||||
## Support status
|
## Build from source
|
||||||
All categories not listed here should work without needing a specific implementation.
|
|
||||||
|
|
||||||
##### Available Modules
|
See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||||
```
|
|
||||||
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, DiskIO, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, NetIO, OpenCL, OpenGL, OS, Packages, Player, Power Adapter, Processes, PublicIP, Separator, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Version, Vulkan, Wallpaper, Weather, Wifi, WM, WMTheme
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Builtin logos
|
## Usage
|
||||||
|
|
||||||
<!-- `Content of src/logo/builtin.c`.split('\n').map(x => x.trim()).filter(x => x.startsWith('// ')).map(x => x.slice(3)).filter(x => x != 'LAST').sort((a, b)=>a.toUpperCase().localeCompare(b.toUpperCase())).join(', ') -->
|
* Run it with default configuration: `fastfetch`
|
||||||
```
|
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what you interest: `fastfetch -c all.jsonc`
|
||||||
AerOS, Afterglow, AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmazonLinux, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOS_old, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, Chimera Linux, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elbrus, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, EndeavourSmall, Endless, Enso, EuroLinux, EvolutionOS, EvolutionOS_old, EvolutionOSSmall, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, MOS, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, TuxedoOS, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, VenomSmall, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xenia, Xferience, YiffOS, Zorin
|
* Find all data that fastfetch detects: `fastfetch -s <module> --format json`
|
||||||
```
|
* Display help messages: `fastfetch --help`
|
||||||
|
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --migrate-config`
|
||||||
|
|
||||||
Run `fastfetch --print-logos` to print them
|
## Customization
|
||||||
|
|
||||||
##### Package managers
|
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
|
||||||
```
|
|
||||||
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, opkg, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
|
|
||||||
```
|
|
||||||
|
|
||||||
##### WM themes
|
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||||
```
|
|
||||||
DWM (Windows), KWin, Marco, Muffin, Mutter, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), XFWM
|
|
||||||
```
|
|
||||||
|
|
||||||
##### DE versions
|
|
||||||
```
|
|
||||||
Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Terminal fonts
|
|
||||||
```
|
|
||||||
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Console, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are:
|
|
||||||
```bash
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
cmake --build . --target fastfetch --target flashfetch
|
|
||||||
```
|
|
||||||
|
|
||||||
If the build process fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available.
|
|
||||||
|
|
||||||
### Building on Windows
|
|
||||||
|
|
||||||
Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 subsystem (or CLANGARM64 if needed) is suggested (and tested) to build fastfetch. If you need Windows 7 / 8.x support, using MINGW64 is suggested.
|
|
||||||
|
|
||||||
1. Install [MSYS2](https://www.msys2.org/#installation)
|
|
||||||
1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime)
|
|
||||||
1. Install dependencies
|
|
||||||
```bash
|
|
||||||
pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
|
|
||||||
```
|
|
||||||
|
|
||||||
Follow the building instructions of Linux next.
|
|
||||||
|
|
||||||
## Packaging
|
## Packaging
|
||||||
|
|
||||||
|
|||||||
+318
-204
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@
|
|||||||
"type": "small"
|
"type": "small"
|
||||||
},
|
},
|
||||||
"display": {
|
"display": {
|
||||||
"percentType": 9,
|
|
||||||
"separator": "\u001b[31m-> "
|
"separator": "\u001b[31m-> "
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
"color": {
|
"color": {
|
||||||
"keys": "magenta"
|
"keys": "magenta"
|
||||||
},
|
},
|
||||||
"sizeNdigits": 0,
|
"size": {
|
||||||
"sizeMaxPrefix": "MB",
|
"ndigits": 0,
|
||||||
"percentType": 9
|
"maxPrefix": "MB"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"type": "small"
|
"type": "small"
|
||||||
},
|
},
|
||||||
"display": {
|
"display": {
|
||||||
"percentType": 6,
|
|
||||||
"keyWidth": 11,
|
"keyWidth": 11,
|
||||||
"bar": {
|
"bar": {
|
||||||
"charElapsed": "=",
|
"charElapsed": "=",
|
||||||
|
|||||||
Vendored
+10359
File diff suppressed because it is too large
Load Diff
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"home": "https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h",
|
||||||
|
"license": "Embed in source",
|
||||||
|
"version": "545.23.06",
|
||||||
|
"author": "NVIDIA Corporation"
|
||||||
|
}
|
||||||
+27
-21
@@ -6,15 +6,17 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
|||||||
{
|
{
|
||||||
assert(green <= 100 && yellow <= 100 && red <= 100);
|
assert(green <= 100 && yellow <= 100 && red <= 100);
|
||||||
|
|
||||||
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * instance.config.barWidth + 0.5);
|
const FFOptionsDisplay* options = &instance.config.display;
|
||||||
uint32_t blocksGreen = (uint32_t) (green / 100.0 * instance.config.barWidth + 0.5);
|
|
||||||
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * instance.config.barWidth + 0.5);
|
|
||||||
uint32_t blocksRed = (uint32_t) (red / 100.0 * instance.config.barWidth + 0.5);
|
|
||||||
assert(blocksPercent <= instance.config.barWidth);
|
|
||||||
|
|
||||||
if(instance.config.barBorder)
|
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * options->barWidth + 0.5);
|
||||||
|
uint32_t blocksGreen = (uint32_t) (green / 100.0 * options->barWidth + 0.5);
|
||||||
|
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * options->barWidth + 0.5);
|
||||||
|
uint32_t blocksRed = (uint32_t) (red / 100.0 * options->barWidth + 0.5);
|
||||||
|
assert(blocksPercent <= options->barWidth);
|
||||||
|
|
||||||
|
if(options->barBorder)
|
||||||
{
|
{
|
||||||
if(!instance.config.pipe)
|
if(!options->pipe)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
|
||||||
else
|
else
|
||||||
ffStrbufAppendS(buffer, "[ ");
|
ffStrbufAppendS(buffer, "[ ");
|
||||||
@@ -22,7 +24,7 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < blocksPercent; ++i)
|
for (uint32_t i = 0; i < blocksPercent; ++i)
|
||||||
{
|
{
|
||||||
if(!instance.config.pipe)
|
if(!options->pipe)
|
||||||
{
|
{
|
||||||
if (i == blocksGreen)
|
if (i == blocksGreen)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||||
@@ -31,26 +33,26 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
|||||||
else if (i == blocksRed)
|
else if (i == blocksRed)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||||
}
|
}
|
||||||
ffStrbufAppend(buffer, &instance.config.barCharElapsed);
|
ffStrbufAppend(buffer, &options->barCharElapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocksPercent < instance.config.barWidth)
|
if (blocksPercent < options->barWidth)
|
||||||
{
|
{
|
||||||
if(!instance.config.pipe)
|
if(!options->pipe)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
|
||||||
for (uint32_t i = blocksPercent; i < instance.config.barWidth; ++i)
|
for (uint32_t i = blocksPercent; i < options->barWidth; ++i)
|
||||||
ffStrbufAppend(buffer, &instance.config.barCharTotal);
|
ffStrbufAppend(buffer, &options->barCharTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instance.config.barBorder)
|
if(options->barBorder)
|
||||||
{
|
{
|
||||||
if(!instance.config.pipe)
|
if(!options->pipe)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
|
||||||
else
|
else
|
||||||
ffStrbufAppendS(buffer, " ]");
|
ffStrbufAppendS(buffer, " ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!options->pipe)
|
||||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +69,18 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
|||||||
{
|
{
|
||||||
assert(green <= 100 && yellow <= 100);
|
assert(green <= 100 && yellow <= 100);
|
||||||
|
|
||||||
bool colored = !!(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
|
const FFOptionsDisplay* options = &instance.config.display;
|
||||||
|
|
||||||
|
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
|
||||||
|
|
||||||
if (parentheses)
|
if (parentheses)
|
||||||
ffStrbufAppendC(buffer, '(');
|
ffStrbufAppendC(buffer, '(');
|
||||||
|
|
||||||
if (colored && !instance.config.pipe)
|
if (colored && !options->pipe)
|
||||||
{
|
{
|
||||||
if(green < yellow)
|
if(percent != percent)
|
||||||
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
|
||||||
|
else if(green < yellow)
|
||||||
{
|
{
|
||||||
if (percent <= green)
|
if (percent <= green)
|
||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||||
@@ -93,9 +99,9 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
|||||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ffStrbufAppendF(buffer, "%.*f%%", instance.config.percentNdigits, percent);
|
ffStrbufAppendF(buffer, "%.*f%%", options->percentNdigits, percent);
|
||||||
|
|
||||||
if (colored && !instance.config.pipe)
|
if (colored && !options->pipe)
|
||||||
{
|
{
|
||||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||||
}
|
}
|
||||||
|
|||||||
+92
-51
@@ -1,6 +1,7 @@
|
|||||||
#include "commandoption.h"
|
#include "commandoption.h"
|
||||||
#include "common/printing.h"
|
#include "common/printing.h"
|
||||||
#include "common/time.h"
|
#include "common/time.h"
|
||||||
|
#include "common/jsonconfig.h"
|
||||||
#include "fastfetch_datatext.h"
|
#include "fastfetch_datatext.h"
|
||||||
#include "modules/modules.h"
|
#include "modules/modules.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
@@ -8,37 +9,6 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
|
|
||||||
{
|
|
||||||
yyjson_mut_doc* doc = instance.state.resultDoc;
|
|
||||||
if (__builtin_expect(!doc, true)) return NULL;
|
|
||||||
|
|
||||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
|
||||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
|
||||||
if (baseInfo->generateJson)
|
|
||||||
baseInfo->generateJson(baseInfo, doc, module);
|
|
||||||
else
|
|
||||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ffParseModuleCommand(const char* type)
|
|
||||||
{
|
|
||||||
if(!isalpha(type[0])) return false;
|
|
||||||
|
|
||||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
|
|
||||||
{
|
|
||||||
FFModuleBaseInfo* baseInfo = *modules;
|
|
||||||
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
|
||||||
{
|
|
||||||
if (!genJson(baseInfo))
|
|
||||||
baseInfo->printModule(baseInfo);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ffParseModuleOptions(const char* key, const char* value)
|
bool ffParseModuleOptions(const char* key, const char* value)
|
||||||
{
|
{
|
||||||
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
|
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
|
||||||
@@ -53,6 +23,7 @@ bool ffParseModuleOptions(const char* key, const char* value)
|
|||||||
|
|
||||||
void ffPrepareCommandOption(FFdata* data)
|
void ffPrepareCommandOption(FFdata* data)
|
||||||
{
|
{
|
||||||
|
FFOptionsModules* const options = &instance.config.modules;
|
||||||
//If we don't have a custom structure, use the default one
|
//If we don't have a custom structure, use the default one
|
||||||
if(data->structure.length == 0)
|
if(data->structure.length == 0)
|
||||||
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||||
@@ -61,22 +32,57 @@ void ffPrepareCommandOption(FFdata* data)
|
|||||||
ffPrepareCPUUsage();
|
ffPrepareCPUUsage();
|
||||||
|
|
||||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
|
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
|
||||||
ffPrepareDiskIO(&instance.config.diskIo);
|
ffPrepareDiskIO(&options->diskIo);
|
||||||
|
|
||||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
|
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
|
||||||
ffPrepareNetIO(&instance.config.netIo);
|
ffPrepareNetIO(&options->netIo);
|
||||||
|
|
||||||
if(instance.config.multithreading)
|
if(instance.config.general.multithreading)
|
||||||
{
|
{
|
||||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
|
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
|
||||||
ffPreparePublicIp(&instance.config.publicIP);
|
ffPreparePublicIp(&options->publicIP);
|
||||||
|
|
||||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
|
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
|
||||||
ffPrepareWeather(&instance.config.weather);
|
ffPrepareWeather(&options->weather);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseStructureCommand(const char* line, FFlist* customValues)
|
static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||||
|
{
|
||||||
|
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
|
||||||
|
if (!modules)
|
||||||
|
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
|
||||||
|
|
||||||
|
yyjson_mut_val* module = yyjson_mut_obj(doc);
|
||||||
|
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
|
||||||
|
ffStrbufLowerCase(&type);
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
|
||||||
|
|
||||||
|
if (baseInfo->generateJsonConfig)
|
||||||
|
baseInfo->generateJsonConfig(baseInfo, doc, module);
|
||||||
|
|
||||||
|
if (yyjson_mut_obj_size(module) > 1)
|
||||||
|
yyjson_mut_arr_add_val(modules, module);
|
||||||
|
else
|
||||||
|
yyjson_mut_arr_add_strbuf(doc, modules, &type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||||
|
{
|
||||||
|
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||||
|
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||||
|
if (baseInfo->generateJsonResult)
|
||||||
|
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||||
|
else
|
||||||
|
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parseStructureCommand(
|
||||||
|
const char* line,
|
||||||
|
FFlist* customValues,
|
||||||
|
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
|
||||||
|
yyjson_mut_doc* jsonDoc
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// handle `--set` and `--set-keyless`
|
// handle `--set` and `--set-keyless`
|
||||||
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
|
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
|
||||||
@@ -88,19 +94,35 @@ static void parseStructureCommand(const char* line, FFlist* customValues)
|
|||||||
if (customValue->printKey)
|
if (customValue->printKey)
|
||||||
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
|
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
|
||||||
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
|
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
|
||||||
ffPrintCustom(&options);
|
if (__builtin_expect(jsonDoc != NULL, false))
|
||||||
|
fn((FFModuleBaseInfo*) &options, jsonDoc);
|
||||||
|
else
|
||||||
|
ffPrintCustom(&options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ffParseModuleCommand(line))
|
if(isalpha(line[0]))
|
||||||
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
{
|
||||||
|
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
|
||||||
|
{
|
||||||
|
FFModuleBaseInfo* baseInfo = *modules;
|
||||||
|
if (ffStrEqualsIgnCase(line, baseInfo->name))
|
||||||
|
{
|
||||||
|
if (__builtin_expect(jsonDoc != NULL, false))
|
||||||
|
fn(baseInfo, jsonDoc);
|
||||||
|
else
|
||||||
|
baseInfo->printModule(baseInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffPrintCommandOption(FFdata* data)
|
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||||
{
|
{
|
||||||
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
|
|
||||||
|
|
||||||
//Parse the structure and call the modules
|
//Parse the structure and call the modules
|
||||||
uint32_t startIndex = 0;
|
uint32_t startIndex = 0;
|
||||||
while (startIndex < data->structure.length)
|
while (startIndex < data->structure.length)
|
||||||
@@ -109,25 +131,25 @@ void ffPrintCommandOption(FFdata* data)
|
|||||||
data->structure.chars[colonIndex] = '\0';
|
data->structure.chars[colonIndex] = '\0';
|
||||||
|
|
||||||
uint64_t ms = 0;
|
uint64_t ms = 0;
|
||||||
if(instance.config.stat)
|
if(instance.config.display.stat)
|
||||||
ms = ffTimeGetTick();
|
ms = ffTimeGetTick();
|
||||||
|
|
||||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues);
|
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
|
||||||
|
|
||||||
if(instance.config.stat)
|
if(instance.config.display.stat)
|
||||||
{
|
{
|
||||||
ms = ffTimeGetTick() - ms;
|
ms = ffTimeGetTick() - ms;
|
||||||
|
|
||||||
if (resultDoc)
|
if (jsonDoc)
|
||||||
{
|
{
|
||||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
|
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||||
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
|
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char str[32];
|
char str[32];
|
||||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||||
if(instance.config.pipe)
|
if(instance.config.display.pipe)
|
||||||
puts(str);
|
puts(str);
|
||||||
else
|
else
|
||||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||||
@@ -135,9 +157,28 @@ void ffPrintCommandOption(FFdata* data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (!instance.config.noBuffer) fflush(stdout);
|
if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
startIndex = colonIndex + 1;
|
startIndex = colonIndex + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||||
|
{
|
||||||
|
//If we don't have a custom structure, use the default one
|
||||||
|
if(data->structure.length == 0)
|
||||||
|
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||||
|
|
||||||
|
//Parse the structure and call the modules
|
||||||
|
uint32_t startIndex = 0;
|
||||||
|
while (startIndex < data->structure.length)
|
||||||
|
{
|
||||||
|
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||||
|
data->structure.chars[colonIndex] = '\0';
|
||||||
|
|
||||||
|
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
|
||||||
|
|
||||||
|
startIndex = colonIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ typedef struct FFdata
|
|||||||
bool loadUserConfig;
|
bool loadUserConfig;
|
||||||
} FFdata;
|
} FFdata;
|
||||||
|
|
||||||
bool ffParseModuleCommand(const char* type);
|
|
||||||
bool ffParseModuleOptions(const char* key, const char* value);
|
bool ffParseModuleOptions(const char* key, const char* value);
|
||||||
void ffPrepareCommandOption(FFdata* data);
|
void ffPrepareCommandOption(FFdata* data);
|
||||||
void ffPrintCommandOption(FFdata* data);
|
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||||
|
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-5
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
static bool loadLibSymbols(FFDBusLibrary* lib)
|
static bool loadLibSymbols(FFDBusLibrary* lib)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(dbus, &instance.config.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false)
|
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false)
|
||||||
@@ -33,9 +33,6 @@ static const FFDBusLibrary* loadLib(void)
|
|||||||
static FFDBusLibrary lib;
|
static FFDBusLibrary lib;
|
||||||
static bool loaded = false;
|
static bool loaded = false;
|
||||||
static bool loadSuccess = false;
|
static bool loadSuccess = false;
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
|
|
||||||
if(!loaded)
|
if(!loaded)
|
||||||
{
|
{
|
||||||
@@ -43,7 +40,6 @@ static const FFDBusLibrary* loadLib(void)
|
|||||||
loadSuccess = loadLibSymbols(&lib);
|
loadSuccess = loadLibSymbols(&lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return loadSuccess ? &lib : NULL;
|
return loadSuccess ? &lib : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-253
@@ -15,8 +15,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "modules/modules.h"
|
|
||||||
|
|
||||||
FFinstance instance; // Global singleton
|
FFinstance instance; // Global singleton
|
||||||
|
|
||||||
static void initState(FFstate* state)
|
static void initState(FFstate* state)
|
||||||
@@ -32,133 +30,11 @@ static void initState(FFstate* state)
|
|||||||
|
|
||||||
static void defaultConfig(void)
|
static void defaultConfig(void)
|
||||||
{
|
{
|
||||||
ffInitLogoOptions(&instance.config.logo);
|
ffOptionsInitLogo(&instance.config.logo);
|
||||||
|
ffOptionsInitGeneral(&instance.config.general);
|
||||||
ffStrbufInit(&instance.config.colorKeys);
|
ffOptionsInitModules(&instance.config.modules);
|
||||||
ffStrbufInit(&instance.config.colorTitle);
|
ffOptionsInitDisplay(&instance.config.display);
|
||||||
instance.config.brightColor = true;
|
ffOptionsInitLibrary(&instance.config.library);
|
||||||
ffStrbufInitStatic(&instance.config.keyValueSeparator, ": ");
|
|
||||||
instance.config.processingTimeout = 1000;
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
|
||||||
ffStrbufInit(&instance.config.playerName);
|
|
||||||
ffStrbufInit(&instance.config.osFile);
|
|
||||||
instance.config.dsForceDrm = false;
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
instance.config.wmiTimeout = 5000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
instance.config.showErrors = false;
|
|
||||||
instance.config.allowSlowOperations = false;
|
|
||||||
instance.config.pipe = !isatty(STDOUT_FILENO);
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
instance.config.disableLinewrap = !instance.config.pipe;
|
|
||||||
instance.config.hideCursor = !instance.config.pipe;
|
|
||||||
#else
|
|
||||||
instance.config.disableLinewrap = false;
|
|
||||||
instance.config.hideCursor = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
instance.config.escapeBedrock = true;
|
|
||||||
instance.config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
|
|
||||||
instance.config.sizeNdigits = 2;
|
|
||||||
instance.config.sizeMaxPrefix = UINT8_MAX;
|
|
||||||
instance.config.temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
|
|
||||||
instance.config.multithreading = true;
|
|
||||||
instance.config.stat = false;
|
|
||||||
instance.config.noBuffer = false;
|
|
||||||
instance.config.keyWidth = 0;
|
|
||||||
|
|
||||||
ffStrbufInitStatic(&instance.config.barCharElapsed, "■");
|
|
||||||
ffStrbufInitStatic(&instance.config.barCharTotal, "-");
|
|
||||||
instance.config.barWidth = 10;
|
|
||||||
instance.config.barBorder = true;
|
|
||||||
instance.config.percentType = 1;
|
|
||||||
instance.config.percentNdigits = 0;
|
|
||||||
|
|
||||||
ffInitBatteryOptions(&instance.config.battery);
|
|
||||||
ffInitBiosOptions(&instance.config.bios);
|
|
||||||
ffInitBluetoothOptions(&instance.config.bluetooth);
|
|
||||||
ffInitBoardOptions(&instance.config.board);
|
|
||||||
ffInitBreakOptions(&instance.config.break_);
|
|
||||||
ffInitBrightnessOptions(&instance.config.brightness);
|
|
||||||
ffInitCPUOptions(&instance.config.cpu);
|
|
||||||
ffInitCPUUsageOptions(&instance.config.cpuUsage);
|
|
||||||
ffInitChassisOptions(&instance.config.chassis);
|
|
||||||
ffInitColorsOptions(&instance.config.colors);
|
|
||||||
ffInitCommandOptions(&instance.config.command);
|
|
||||||
ffInitCursorOptions(&instance.config.cursor);
|
|
||||||
ffInitCustomOptions(&instance.config.custom);
|
|
||||||
ffInitDEOptions(&instance.config.de);
|
|
||||||
ffInitDateTimeOptions(&instance.config.dateTime);
|
|
||||||
ffInitDiskOptions(&instance.config.disk);
|
|
||||||
ffInitDiskIOOptions(&instance.config.diskIo);
|
|
||||||
ffInitDisplayOptions(&instance.config.display);
|
|
||||||
ffInitFontOptions(&instance.config.font);
|
|
||||||
ffInitGPUOptions(&instance.config.gpu);
|
|
||||||
ffInitGamepadOptions(&instance.config.gamepad);
|
|
||||||
ffInitHostOptions(&instance.config.host);
|
|
||||||
ffInitIconsOptions(&instance.config.icons);
|
|
||||||
ffInitKernelOptions(&instance.config.kernel);
|
|
||||||
ffInitLMOptions(&instance.config.lm);
|
|
||||||
ffInitLocalIpOptions(&instance.config.localIP);
|
|
||||||
ffInitLocaleOptions(&instance.config.locale);
|
|
||||||
ffInitMediaOptions(&instance.config.media);
|
|
||||||
ffInitMemoryOptions(&instance.config.memory);
|
|
||||||
ffInitMonitorOptions(&instance.config.monitor);
|
|
||||||
ffInitNetIOOptions(&instance.config.netIo);
|
|
||||||
ffInitOSOptions(&instance.config.os);
|
|
||||||
ffInitOpenCLOptions(&instance.config.openCL);
|
|
||||||
ffInitOpenGLOptions(&instance.config.openGL);
|
|
||||||
ffInitPackagesOptions(&instance.config.packages);
|
|
||||||
ffInitPlayerOptions(&instance.config.player);
|
|
||||||
ffInitPowerAdapterOptions(&instance.config.powerAdapter);
|
|
||||||
ffInitProcessesOptions(&instance.config.processes);
|
|
||||||
ffInitPublicIpOptions(&instance.config.publicIP);
|
|
||||||
ffInitSeparatorOptions(&instance.config.separator);
|
|
||||||
ffInitShellOptions(&instance.config.shell);
|
|
||||||
ffInitSoundOptions(&instance.config.sound);
|
|
||||||
ffInitSwapOptions(&instance.config.swap);
|
|
||||||
ffInitTerminalFontOptions(&instance.config.terminalFont);
|
|
||||||
ffInitTerminalOptions(&instance.config.terminal);
|
|
||||||
ffInitTerminalSizeOptions(&instance.config.terminalSize);
|
|
||||||
ffInitThemeOptions(&instance.config.theme);
|
|
||||||
ffInitTitleOptions(&instance.config.title);
|
|
||||||
ffInitUptimeOptions(&instance.config.uptime);
|
|
||||||
ffInitUsersOptions(&instance.config.users);
|
|
||||||
ffInitVersionOptions(&instance.config.version);
|
|
||||||
ffInitVulkanOptions(&instance.config.vulkan);
|
|
||||||
ffInitWMOptions(&instance.config.wm);
|
|
||||||
ffInitWMThemeOptions(&instance.config.wmTheme);
|
|
||||||
ffInitWallpaperOptions(&instance.config.wallpaper);
|
|
||||||
ffInitWeatherOptions(&instance.config.weather);
|
|
||||||
ffInitWifiOptions(&instance.config.wifi);
|
|
||||||
|
|
||||||
ffStrbufInit(&instance.config.libPCI);
|
|
||||||
ffStrbufInit(&instance.config.libVulkan);
|
|
||||||
ffStrbufInit(&instance.config.libWayland);
|
|
||||||
ffStrbufInit(&instance.config.libXcbRandr);
|
|
||||||
ffStrbufInit(&instance.config.libXcb);
|
|
||||||
ffStrbufInit(&instance.config.libXrandr);
|
|
||||||
ffStrbufInit(&instance.config.libX11);
|
|
||||||
ffStrbufInit(&instance.config.libGIO);
|
|
||||||
ffStrbufInit(&instance.config.libDConf);
|
|
||||||
ffStrbufInit(&instance.config.libDBus);
|
|
||||||
ffStrbufInit(&instance.config.libXFConf);
|
|
||||||
ffStrbufInit(&instance.config.libSQLite3);
|
|
||||||
ffStrbufInit(&instance.config.librpm);
|
|
||||||
ffStrbufInit(&instance.config.libImageMagick);
|
|
||||||
ffStrbufInit(&instance.config.libZ);
|
|
||||||
ffStrbufInit(&instance.config.libChafa);
|
|
||||||
ffStrbufInit(&instance.config.libEGL);
|
|
||||||
ffStrbufInit(&instance.config.libGLX);
|
|
||||||
ffStrbufInit(&instance.config.libOSMesa);
|
|
||||||
ffStrbufInit(&instance.config.libOpenCL);
|
|
||||||
ffStrbufInit(&instance.config.libfreetype);
|
|
||||||
ffStrbufInit(&instance.config.libPulse);
|
|
||||||
ffStrbufInit(&instance.config.libnm);
|
|
||||||
ffStrbufInit(&instance.config.libDdcutil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffInitInstance(void)
|
void ffInitInstance(void)
|
||||||
@@ -175,29 +51,6 @@ void ffInitInstance(void)
|
|||||||
defaultConfig();
|
defaultConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FF_HAVE_THREADS) && !(defined(__APPLE__) || defined(_WIN32) || defined(__ANDROID__))
|
|
||||||
|
|
||||||
#include "detection/gtk_qt/gtk_qt.h"
|
|
||||||
|
|
||||||
#define FF_START_DETECTION_THREADS
|
|
||||||
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffConnectDisplayServer)
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectQt)
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK2)
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK3)
|
|
||||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK4)
|
|
||||||
|
|
||||||
void startDetectionThreads(void)
|
|
||||||
{
|
|
||||||
ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, NULL));
|
|
||||||
ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, NULL));
|
|
||||||
ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, NULL));
|
|
||||||
ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, NULL));
|
|
||||||
ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //FF_HAVE_THREADS
|
|
||||||
|
|
||||||
static volatile bool ffDisableLinewrap = true;
|
static volatile bool ffDisableLinewrap = true;
|
||||||
static volatile bool ffHideCursor = true;
|
static volatile bool ffHideCursor = true;
|
||||||
|
|
||||||
@@ -233,15 +86,15 @@ static void exitSignalHandler(int signal)
|
|||||||
void ffStart(void)
|
void ffStart(void)
|
||||||
{
|
{
|
||||||
#ifdef FF_START_DETECTION_THREADS
|
#ifdef FF_START_DETECTION_THREADS
|
||||||
if(instance.config.multithreading)
|
if(instance.config.general.multithreading)
|
||||||
startDetectionThreads();
|
startDetectionThreads();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe && !instance.state.resultDoc;
|
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||||
ffHideCursor = instance.config.hideCursor && !instance.config.pipe && !instance.state.resultDoc;
|
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
setvbuf(stdout, NULL, _IOFBF, instance.config.noBuffer ? 0 : 4096);
|
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
|
||||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
DWORD mode = 0;
|
DWORD mode = 0;
|
||||||
@@ -249,7 +102,7 @@ void ffStart(void)
|
|||||||
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
#else
|
#else
|
||||||
if (instance.config.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
|
if (instance.config.display.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
struct sigaction action = { .sa_handler = exitSignalHandler };
|
struct sigaction action = { .sa_handler = exitSignalHandler };
|
||||||
sigaction(SIGINT, &action, NULL);
|
sigaction(SIGINT, &action, NULL);
|
||||||
sigaction(SIGTERM, &action, NULL);
|
sigaction(SIGTERM, &action, NULL);
|
||||||
@@ -257,7 +110,7 @@ void ffStart(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//reset everything to default before we start printing
|
//reset everything to default before we start printing
|
||||||
if(!instance.config.pipe && !instance.state.resultDoc)
|
if(!instance.config.display.pipe && !instance.state.resultDoc)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||||
|
|
||||||
if(ffHideCursor)
|
if(ffHideCursor)
|
||||||
@@ -279,101 +132,11 @@ void ffFinish(void)
|
|||||||
|
|
||||||
static void destroyConfig(void)
|
static void destroyConfig(void)
|
||||||
{
|
{
|
||||||
ffDestroyLogoOptions(&instance.config.logo);
|
ffOptionsDestroyLogo(&instance.config.logo);
|
||||||
|
ffOptionsDestroyGeneral(&instance.config.general);
|
||||||
ffStrbufDestroy(&instance.config.colorKeys);
|
ffOptionsDestroyModules(&instance.config.modules);
|
||||||
ffStrbufDestroy(&instance.config.colorTitle);
|
ffOptionsDestroyDisplay(&instance.config.display);
|
||||||
ffStrbufDestroy(&instance.config.keyValueSeparator);
|
ffOptionsDestroyLibrary(&instance.config.library);
|
||||||
ffStrbufDestroy(&instance.config.barCharElapsed);
|
|
||||||
ffStrbufDestroy(&instance.config.barCharTotal);
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
|
||||||
ffStrbufDestroy(&instance.config.playerName);
|
|
||||||
ffStrbufDestroy(&instance.config.osFile);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ffDestroyBatteryOptions(&instance.config.battery);
|
|
||||||
ffDestroyBiosOptions(&instance.config.bios);
|
|
||||||
ffDestroyBluetoothOptions(&instance.config.bluetooth);
|
|
||||||
ffDestroyBoardOptions(&instance.config.board);
|
|
||||||
ffDestroyBreakOptions(&instance.config.break_);
|
|
||||||
ffDestroyBrightnessOptions(&instance.config.brightness);
|
|
||||||
ffDestroyCPUOptions(&instance.config.cpu);
|
|
||||||
ffDestroyCPUUsageOptions(&instance.config.cpuUsage);
|
|
||||||
ffDestroyChassisOptions(&instance.config.chassis);
|
|
||||||
ffDestroyColorsOptions(&instance.config.colors);
|
|
||||||
ffDestroyCommandOptions(&instance.config.command);
|
|
||||||
ffDestroyCursorOptions(&instance.config.cursor);
|
|
||||||
ffDestroyCustomOptions(&instance.config.custom);
|
|
||||||
ffDestroyDEOptions(&instance.config.de);
|
|
||||||
ffDestroyDateTimeOptions(&instance.config.dateTime);
|
|
||||||
ffDestroyDiskOptions(&instance.config.disk);
|
|
||||||
ffDestroyDiskIOOptions(&instance.config.diskIo);
|
|
||||||
ffDestroyDisplayOptions(&instance.config.display);
|
|
||||||
ffDestroyFontOptions(&instance.config.font);
|
|
||||||
ffDestroyGPUOptions(&instance.config.gpu);
|
|
||||||
ffDestroyGamepadOptions(&instance.config.gamepad);
|
|
||||||
ffDestroyHostOptions(&instance.config.host);
|
|
||||||
ffDestroyIconsOptions(&instance.config.icons);
|
|
||||||
ffDestroyKernelOptions(&instance.config.kernel);
|
|
||||||
ffDestroyLMOptions(&instance.config.lm);
|
|
||||||
ffDestroyLocalIpOptions(&instance.config.localIP);
|
|
||||||
ffDestroyLocaleOptions(&instance.config.locale);
|
|
||||||
ffDestroyMediaOptions(&instance.config.media);
|
|
||||||
ffDestroyMemoryOptions(&instance.config.memory);
|
|
||||||
ffDestroyMonitorOptions(&instance.config.monitor);
|
|
||||||
ffDestroyNetIOOptions(&instance.config.netIo);
|
|
||||||
ffDestroyOSOptions(&instance.config.os);
|
|
||||||
ffDestroyOpenCLOptions(&instance.config.openCL);
|
|
||||||
ffDestroyOpenGLOptions(&instance.config.openGL);
|
|
||||||
ffDestroyPackagesOptions(&instance.config.packages);
|
|
||||||
ffDestroyPlayerOptions(&instance.config.player);
|
|
||||||
ffDestroyPowerAdapterOptions(&instance.config.powerAdapter);
|
|
||||||
ffDestroyProcessesOptions(&instance.config.processes);
|
|
||||||
ffDestroyPublicIpOptions(&instance.config.publicIP);
|
|
||||||
ffDestroySeparatorOptions(&instance.config.separator);
|
|
||||||
ffDestroyShellOptions(&instance.config.shell);
|
|
||||||
ffDestroySoundOptions(&instance.config.sound);
|
|
||||||
ffDestroySwapOptions(&instance.config.swap);
|
|
||||||
ffDestroyTerminalFontOptions(&instance.config.terminalFont);
|
|
||||||
ffDestroyTerminalOptions(&instance.config.terminal);
|
|
||||||
ffDestroyTerminalSizeOptions(&instance.config.terminalSize);
|
|
||||||
ffDestroyThemeOptions(&instance.config.theme);
|
|
||||||
ffDestroyTitleOptions(&instance.config.title);
|
|
||||||
ffDestroyUptimeOptions(&instance.config.uptime);
|
|
||||||
ffDestroyUsersOptions(&instance.config.users);
|
|
||||||
ffDestroyVersionOptions(&instance.config.version);
|
|
||||||
ffDestroyVulkanOptions(&instance.config.vulkan);
|
|
||||||
ffDestroyWMOptions(&instance.config.wm);
|
|
||||||
ffDestroyWMThemeOptions(&instance.config.wmTheme);
|
|
||||||
ffDestroyWallpaperOptions(&instance.config.wallpaper);
|
|
||||||
ffDestroyWeatherOptions(&instance.config.weather);
|
|
||||||
ffDestroyWifiOptions(&instance.config.wifi);
|
|
||||||
|
|
||||||
ffStrbufDestroy(&instance.config.libPCI);
|
|
||||||
ffStrbufDestroy(&instance.config.libVulkan);
|
|
||||||
ffStrbufDestroy(&instance.config.libWayland);
|
|
||||||
ffStrbufDestroy(&instance.config.libXcbRandr);
|
|
||||||
ffStrbufDestroy(&instance.config.libXcb);
|
|
||||||
ffStrbufDestroy(&instance.config.libXrandr);
|
|
||||||
ffStrbufDestroy(&instance.config.libX11);
|
|
||||||
ffStrbufDestroy(&instance.config.libGIO);
|
|
||||||
ffStrbufDestroy(&instance.config.libDConf);
|
|
||||||
ffStrbufDestroy(&instance.config.libDBus);
|
|
||||||
ffStrbufDestroy(&instance.config.libXFConf);
|
|
||||||
ffStrbufDestroy(&instance.config.libSQLite3);
|
|
||||||
ffStrbufDestroy(&instance.config.librpm);
|
|
||||||
ffStrbufDestroy(&instance.config.libImageMagick);
|
|
||||||
ffStrbufDestroy(&instance.config.libZ);
|
|
||||||
ffStrbufDestroy(&instance.config.libChafa);
|
|
||||||
ffStrbufDestroy(&instance.config.libEGL);
|
|
||||||
ffStrbufDestroy(&instance.config.libGLX);
|
|
||||||
ffStrbufDestroy(&instance.config.libOSMesa);
|
|
||||||
ffStrbufDestroy(&instance.config.libOpenCL);
|
|
||||||
ffStrbufDestroy(&instance.config.libfreetype);
|
|
||||||
ffStrbufDestroy(&instance.config.libPulse);
|
|
||||||
ffStrbufDestroy(&instance.config.libnm);
|
|
||||||
ffStrbufDestroy(&instance.config.libDdcutil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyState(void)
|
static void destroyState(void)
|
||||||
@@ -381,6 +144,7 @@ static void destroyState(void)
|
|||||||
ffPlatformDestroy(&instance.state.platform);
|
ffPlatformDestroy(&instance.state.platform);
|
||||||
yyjson_doc_free(instance.state.configDoc);
|
yyjson_doc_free(instance.state.configDoc);
|
||||||
yyjson_mut_doc_free(instance.state.resultDoc);
|
yyjson_mut_doc_free(instance.state.resultDoc);
|
||||||
|
ffStrbufDestroy(&instance.state.migrateConfigPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffDestroyInstance(void)
|
void ffDestroyInstance(void)
|
||||||
|
|||||||
+48
-295
@@ -35,6 +35,18 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs)
|
||||||
|
{
|
||||||
|
if (!ffStrbufEqual(&defaultModuleArgs->key, &moduleArgs->key))
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, module, "key", &moduleArgs->key);
|
||||||
|
if (!ffStrbufEqual(&defaultModuleArgs->outputFormat, &moduleArgs->outputFormat))
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, module, "format", &moduleArgs->outputFormat);
|
||||||
|
if (!ffStrbufEqual(&defaultModuleArgs->keyColor, &moduleArgs->keyColor))
|
||||||
|
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
|
||||||
|
if (moduleArgs->keyWidth != defaultModuleArgs->keyWidth)
|
||||||
|
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
|
||||||
|
}
|
||||||
|
|
||||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
|
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
|
||||||
{
|
{
|
||||||
if (yyjson_is_int(val))
|
if (yyjson_is_int(val))
|
||||||
@@ -70,21 +82,17 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
|||||||
return "Invalid enum value type; must be a string or integer";
|
return "Invalid enum value type; must be a string or integer";
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
|
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||||
{
|
{
|
||||||
yyjson_mut_doc* doc = instance.state.resultDoc;
|
|
||||||
if (__builtin_expect(!doc, true)) return NULL;
|
|
||||||
|
|
||||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||||
if (baseInfo->generateJson)
|
if (baseInfo->generateJsonResult)
|
||||||
baseInfo->generateJson(baseInfo, doc, module);
|
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||||
else
|
else
|
||||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||||
return module;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
|
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
|
||||||
{
|
{
|
||||||
if(!isalpha(type[0])) return false;
|
if(!isalpha(type[0])) return false;
|
||||||
|
|
||||||
@@ -94,7 +102,9 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
|
|||||||
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
||||||
{
|
{
|
||||||
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
|
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
|
||||||
if (!genJson(baseInfo))
|
if (__builtin_expect(jsonDoc != NULL, false))
|
||||||
|
genJsonResult(baseInfo, jsonDoc);
|
||||||
|
else
|
||||||
baseInfo->printModule(baseInfo);
|
baseInfo->printModule(baseInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -115,39 +125,39 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
|
|||||||
case 'd': case 'D': {
|
case 'd': case 'D': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
|
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
|
||||||
{
|
{
|
||||||
if (module) ffParseDiskIOJsonObject(&cfg->diskIo, module);
|
if (module) cfg->modules.diskIo.moduleInfo.parseJsonObject(&cfg->modules.diskIo, module);
|
||||||
ffPrepareDiskIO(&cfg->diskIo);
|
ffPrepareDiskIO(&cfg->modules.diskIo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'n': case 'N': {
|
case 'n': case 'N': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
|
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
|
||||||
{
|
{
|
||||||
if (module) ffParseNetIOJsonObject(&cfg->netIo, module);
|
if (module) cfg->modules.netIo.moduleInfo.parseJsonObject(&cfg->modules.netIo, module);
|
||||||
ffPrepareNetIO(&cfg->netIo);
|
ffPrepareNetIO(&cfg->modules.netIo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'p': case 'P': {
|
case 'p': case 'P': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
|
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
|
||||||
{
|
{
|
||||||
if (module) ffParsePublicIpJsonObject(&cfg->publicIP, module);
|
if (module) cfg->modules.publicIP.moduleInfo.parseJsonObject(&cfg->modules.publicIP, module);
|
||||||
ffPreparePublicIp(&cfg->publicIP);
|
ffPreparePublicIp(&cfg->modules.publicIP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'w': case 'W': {
|
case 'w': case 'W': {
|
||||||
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
|
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
|
||||||
{
|
{
|
||||||
if (module) ffParseWeatherJsonObject(&cfg->weather, module);
|
if (module) cfg->modules.weather.moduleInfo.parseJsonObject(&cfg->modules.weather, module);
|
||||||
ffPrepareWeather(&cfg->weather);
|
ffPrepareWeather(&cfg->modules.weather);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* printJsonConfig(bool prepare)
|
static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||||
{
|
{
|
||||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||||
assert(root);
|
assert(root);
|
||||||
@@ -159,14 +169,12 @@ static const char* printJsonConfig(bool prepare)
|
|||||||
if (!modules) return NULL;
|
if (!modules) return NULL;
|
||||||
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
||||||
|
|
||||||
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
|
|
||||||
|
|
||||||
yyjson_val* item;
|
yyjson_val* item;
|
||||||
size_t idx, max;
|
size_t idx, max;
|
||||||
yyjson_arr_foreach(modules, idx, max, item)
|
yyjson_arr_foreach(modules, idx, max, item)
|
||||||
{
|
{
|
||||||
uint64_t ms = 0;
|
uint64_t ms = 0;
|
||||||
if(!prepare && instance.config.stat)
|
if(!prepare && instance.config.display.stat)
|
||||||
ms = ffTimeGetTick();
|
ms = ffTimeGetTick();
|
||||||
|
|
||||||
yyjson_val* module = item;
|
yyjson_val* module = item;
|
||||||
@@ -185,22 +193,22 @@ static const char* printJsonConfig(bool prepare)
|
|||||||
|
|
||||||
if(prepare)
|
if(prepare)
|
||||||
prepareModuleJsonObject(type, module);
|
prepareModuleJsonObject(type, module);
|
||||||
else if(!parseModuleJsonObject(type, module))
|
else if(!parseModuleJsonObject(type, module, jsonDoc))
|
||||||
return "Unknown module type";
|
return "Unknown module type";
|
||||||
|
|
||||||
if(!prepare && instance.config.stat)
|
if(!prepare && instance.config.display.stat)
|
||||||
{
|
{
|
||||||
ms = ffTimeGetTick() - ms;
|
ms = ffTimeGetTick() - ms;
|
||||||
if (resultDoc)
|
if (jsonDoc)
|
||||||
{
|
{
|
||||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
|
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||||
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
|
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char str[32];
|
char str[32];
|
||||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||||
if(instance.config.pipe)
|
if(instance.config.display.pipe)
|
||||||
puts(str);
|
puts(str);
|
||||||
else
|
else
|
||||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||||
@@ -208,280 +216,25 @@ static const char* printJsonConfig(bool prepare)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
if (!instance.config.noBuffer && !resultDoc) fflush(stdout);
|
if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffParseGeneralJsonConfig(void)
|
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||||
{
|
{
|
||||||
FFconfig* config = &instance.config;
|
const char* error = printJsonConfig(prepare, jsonDoc);
|
||||||
|
|
||||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
|
||||||
assert(root);
|
|
||||||
|
|
||||||
if (!yyjson_is_obj(root))
|
|
||||||
return "Invalid JSON config format. Root value must be an object";
|
|
||||||
|
|
||||||
yyjson_val* object = yyjson_obj_get(root, "general");
|
|
||||||
if (!object) return NULL;
|
|
||||||
if (!yyjson_is_obj(object)) return "Property 'general' must be an object";
|
|
||||||
|
|
||||||
yyjson_val *key_, *val;
|
|
||||||
size_t idx, max;
|
|
||||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
|
||||||
{
|
|
||||||
const char* key = yyjson_get_str(key_);
|
|
||||||
|
|
||||||
if (ffStrEqualsIgnCase(key, "allowSlowOperations"))
|
|
||||||
config->allowSlowOperations = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading"))
|
|
||||||
config->multithreading = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "stat"))
|
|
||||||
{
|
|
||||||
if ((config->stat = yyjson_get_bool(val)))
|
|
||||||
config->showErrors = true;
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "escapeBedrock"))
|
|
||||||
config->escapeBedrock = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "pipe"))
|
|
||||||
config->pipe = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "processingTimeout"))
|
|
||||||
config->processingTimeout = (int32_t) yyjson_get_int(val);
|
|
||||||
|
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
|
||||||
else if (ffStrEqualsIgnCase(key, "playerName"))
|
|
||||||
ffStrbufSetS(&config->playerName, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "osFile"))
|
|
||||||
ffStrbufSetS(&config->osFile, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
|
|
||||||
config->dsForceDrm = yyjson_get_bool(val);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
|
|
||||||
config->wmiTimeout = (int32_t) yyjson_get_int(val);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
else
|
|
||||||
return "Unknown general property";
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffParseDisplayJsonConfig(void)
|
|
||||||
{
|
|
||||||
FFconfig* config = &instance.config;
|
|
||||||
|
|
||||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
|
||||||
assert(root);
|
|
||||||
|
|
||||||
if (!yyjson_is_obj(root))
|
|
||||||
return "Invalid JSON config format. Root value must be an object";
|
|
||||||
|
|
||||||
yyjson_val* object = yyjson_obj_get(root, "display");
|
|
||||||
if (!object) return NULL;
|
|
||||||
if (!yyjson_is_obj(object)) return "Property 'display' must be an object";
|
|
||||||
|
|
||||||
yyjson_val *key_, *val;
|
|
||||||
size_t idx, max;
|
|
||||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
|
||||||
{
|
|
||||||
const char* key = yyjson_get_str(key_);
|
|
||||||
|
|
||||||
if (ffStrEqualsIgnCase(key, "showErrors"))
|
|
||||||
config->showErrors = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "disableLinewrap"))
|
|
||||||
config->disableLinewrap = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "hideCursor"))
|
|
||||||
config->hideCursor = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "separator"))
|
|
||||||
ffStrbufSetS(&config->keyValueSeparator, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "color"))
|
|
||||||
{
|
|
||||||
if (yyjson_is_str(val))
|
|
||||||
{
|
|
||||||
ffOptionParseColor(yyjson_get_str(val), &config->colorKeys);
|
|
||||||
ffStrbufSet(&config->colorTitle, &config->colorKeys);
|
|
||||||
}
|
|
||||||
else if (yyjson_is_obj(val))
|
|
||||||
{
|
|
||||||
const char* colorKeys = yyjson_get_str(yyjson_obj_get(val, "keys"));
|
|
||||||
if (colorKeys)
|
|
||||||
ffOptionParseColor(colorKeys, &config->colorKeys);
|
|
||||||
const char* colorTitle = yyjson_get_str(yyjson_obj_get(val, "title"));
|
|
||||||
if (colorTitle)
|
|
||||||
ffOptionParseColor(colorTitle, &config->colorTitle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "display.color must be either a string or an object";
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "brightColor"))
|
|
||||||
config->brightColor = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "binaryPrefix"))
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
|
||||||
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
|
|
||||||
{ "si", FF_BINARY_PREFIX_TYPE_SI },
|
|
||||||
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
|
|
||||||
{},
|
|
||||||
});
|
|
||||||
if (error) return error;
|
|
||||||
config->binaryPrefixType = (FFBinaryPrefixType) value;
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "sizeNdigits"))
|
|
||||||
config->sizeNdigits = (uint8_t) yyjson_get_uint(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "sizeMaxPrefix"))
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
|
||||||
{ "B", 0 },
|
|
||||||
{ "kB", 1 },
|
|
||||||
{ "MB", 2 },
|
|
||||||
{ "GB", 3 },
|
|
||||||
{ "TB", 4 },
|
|
||||||
{ "PB", 5 },
|
|
||||||
{ "EB", 6 },
|
|
||||||
{ "ZB", 7 },
|
|
||||||
{ "YB", 8 },
|
|
||||||
{}
|
|
||||||
});
|
|
||||||
if (error) return error;
|
|
||||||
config->sizeMaxPrefix = (uint8_t) value;
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "temperatureUnit"))
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
|
||||||
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
|
|
||||||
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
|
|
||||||
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
|
|
||||||
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
|
|
||||||
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
|
|
||||||
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
|
|
||||||
{},
|
|
||||||
});
|
|
||||||
if (error) return error;
|
|
||||||
config->temperatureUnit = (FFTemperatureUnit) value;
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "percentType"))
|
|
||||||
config->percentType = (uint8_t) yyjson_get_uint(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "percentNdigits"))
|
|
||||||
config->percentNdigits = (uint8_t) yyjson_get_uint(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "bar"))
|
|
||||||
{
|
|
||||||
if (yyjson_is_obj(val))
|
|
||||||
{
|
|
||||||
const char* charElapsed = yyjson_get_str(yyjson_obj_get(val, "charElapsed"));
|
|
||||||
if (charElapsed)
|
|
||||||
ffStrbufSetS(&config->barCharElapsed, charElapsed);
|
|
||||||
|
|
||||||
const char* charTotal = yyjson_get_str(yyjson_obj_get(val, "charTotal"));
|
|
||||||
if (charTotal)
|
|
||||||
ffStrbufSetS(&config->barCharTotal, charTotal);
|
|
||||||
|
|
||||||
yyjson_val* border = yyjson_obj_get(val, "border");
|
|
||||||
if (border)
|
|
||||||
config->barBorder = yyjson_get_bool(border);
|
|
||||||
|
|
||||||
yyjson_val* width = yyjson_obj_get(val, "width");
|
|
||||||
if (width)
|
|
||||||
config->barWidth = (uint8_t) yyjson_get_uint(width);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "display.bar must be an object";
|
|
||||||
}
|
|
||||||
else if (ffStrEqualsIgnCase(key, "noBuffer"))
|
|
||||||
config->noBuffer = yyjson_get_bool(val);
|
|
||||||
else if (ffStrEqualsIgnCase(key, "keyWidth"))
|
|
||||||
config->keyWidth = (uint32_t) yyjson_get_uint(val);
|
|
||||||
else
|
|
||||||
return "Unknown display property";
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffParseLibraryJsonConfig(void)
|
|
||||||
{
|
|
||||||
FFconfig* config = &instance.config;
|
|
||||||
|
|
||||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
|
||||||
assert(root);
|
|
||||||
|
|
||||||
if (!yyjson_is_obj(root))
|
|
||||||
return "Invalid JSON config format. Root value must be an object";
|
|
||||||
|
|
||||||
yyjson_val* object = yyjson_obj_get(root, "library");
|
|
||||||
if (!object) return NULL;
|
|
||||||
if (!yyjson_is_obj(object)) return "Property 'library' must be an object";
|
|
||||||
|
|
||||||
yyjson_val *key_, *val;
|
|
||||||
size_t idx, max;
|
|
||||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
|
||||||
{
|
|
||||||
const char* key = yyjson_get_str(key_);
|
|
||||||
|
|
||||||
if (ffStrEqualsIgnCase(key, "pci"))
|
|
||||||
ffStrbufSetS(&config->libPCI, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "vulkan"))
|
|
||||||
ffStrbufSetS(&config->libVulkan, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "freetype"))
|
|
||||||
ffStrbufSetS(&config->libfreetype, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "wayland"))
|
|
||||||
ffStrbufSetS(&config->libWayland, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "xcbRandr"))
|
|
||||||
ffStrbufSetS(&config->libXcbRandr, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "xcb"))
|
|
||||||
ffStrbufSetS(&config->libXcb, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "Xrandr"))
|
|
||||||
ffStrbufSetS(&config->libXrandr, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "X11"))
|
|
||||||
ffStrbufSetS(&config->libX11, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "gio"))
|
|
||||||
ffStrbufSetS(&config->libGIO, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "DConf"))
|
|
||||||
ffStrbufSetS(&config->libDConf, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "dbus"))
|
|
||||||
ffStrbufSetS(&config->libDBus, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "XFConf"))
|
|
||||||
ffStrbufSetS(&config->libXFConf, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "sqlite") || ffStrEqualsIgnCase(key, "sqlite3"))
|
|
||||||
ffStrbufSetS(&config->libSQLite3, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "rpm"))
|
|
||||||
ffStrbufSetS(&config->librpm, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "imagemagick"))
|
|
||||||
ffStrbufSetS(&config->libImageMagick, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "z"))
|
|
||||||
ffStrbufSetS(&config->libZ, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "chafa"))
|
|
||||||
ffStrbufSetS(&config->libChafa, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "egl"))
|
|
||||||
ffStrbufSetS(&config->libEGL, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "glx"))
|
|
||||||
ffStrbufSetS(&config->libGLX, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "osmesa"))
|
|
||||||
ffStrbufSetS(&config->libOSMesa, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "opencl"))
|
|
||||||
ffStrbufSetS(&config->libOpenCL, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "pulse"))
|
|
||||||
ffStrbufSetS(&config->libPulse, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "nm"))
|
|
||||||
ffStrbufSetS(&config->libnm, yyjson_get_str(val));
|
|
||||||
else if (ffStrEqualsIgnCase(key, "ddcutil"))
|
|
||||||
ffStrbufSetS(&config->libDdcutil, yyjson_get_str(val));
|
|
||||||
else
|
|
||||||
return "Unknown library property";
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffPrintJsonConfig(bool prepare)
|
|
||||||
{
|
|
||||||
const char* error = printJsonConfig(prepare);
|
|
||||||
if (error)
|
if (error)
|
||||||
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
{
|
||||||
|
if (jsonDoc)
|
||||||
|
{
|
||||||
|
yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc);
|
||||||
|
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
|
||||||
|
yyjson_mut_doc_set_root(jsonDoc, obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
|
|
||||||
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
|
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
|
||||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
|
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
|
||||||
void ffPrintJsonConfig(bool prepare);
|
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc);
|
||||||
const char* ffParseGeneralJsonConfig(void);
|
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs);
|
||||||
const char* ffParseDisplayJsonConfig(void);
|
|
||||||
const char* ffParseLibraryJsonConfig(void);
|
yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc *doc, const FFstrbuf* buf) {
|
||||||
|
return yyjson_mut_strncpy(doc, buf->chars, buf->length);
|
||||||
|
}
|
||||||
|
|
||||||
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
|
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
|
||||||
yyjson_mut_val *obj,
|
yyjson_mut_val *obj,
|
||||||
|
|||||||
+57
-57
@@ -5,32 +5,32 @@ static FFModuleBaseInfo* A[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* B[] = {
|
static FFModuleBaseInfo* B[] = {
|
||||||
(void*) &instance.config.battery,
|
(void*) &instance.config.modules.battery,
|
||||||
(void*) &instance.config.bios,
|
(void*) &instance.config.modules.bios,
|
||||||
(void*) &instance.config.bluetooth,
|
(void*) &instance.config.modules.bluetooth,
|
||||||
(void*) &instance.config.board,
|
(void*) &instance.config.modules.board,
|
||||||
(void*) &instance.config.break_,
|
(void*) &instance.config.modules.break_,
|
||||||
(void*) &instance.config.brightness,
|
(void*) &instance.config.modules.brightness,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* C[] = {
|
static FFModuleBaseInfo* C[] = {
|
||||||
(void*) &instance.config.chassis,
|
(void*) &instance.config.modules.chassis,
|
||||||
(void*) &instance.config.command,
|
(void*) &instance.config.modules.command,
|
||||||
(void*) &instance.config.colors,
|
(void*) &instance.config.modules.colors,
|
||||||
(void*) &instance.config.cpu,
|
(void*) &instance.config.modules.cpu,
|
||||||
(void*) &instance.config.cpuUsage,
|
(void*) &instance.config.modules.cpuUsage,
|
||||||
(void*) &instance.config.cursor,
|
(void*) &instance.config.modules.cursor,
|
||||||
(void*) &instance.config.custom,
|
(void*) &instance.config.modules.custom,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* D[] = {
|
static FFModuleBaseInfo* D[] = {
|
||||||
(void*) &instance.config.dateTime,
|
(void*) &instance.config.modules.dateTime,
|
||||||
(void*) &instance.config.de,
|
(void*) &instance.config.modules.de,
|
||||||
(void*) &instance.config.display,
|
(void*) &instance.config.modules.display,
|
||||||
(void*) &instance.config.disk,
|
(void*) &instance.config.modules.disk,
|
||||||
(void*) &instance.config.diskIo,
|
(void*) &instance.config.modules.diskIo,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,23 +39,23 @@ static FFModuleBaseInfo* E[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* F[] = {
|
static FFModuleBaseInfo* F[] = {
|
||||||
(void*) &instance.config.font,
|
(void*) &instance.config.modules.font,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* G[] = {
|
static FFModuleBaseInfo* G[] = {
|
||||||
(void*) &instance.config.gamepad,
|
(void*) &instance.config.modules.gamepad,
|
||||||
(void*) &instance.config.gpu,
|
(void*) &instance.config.modules.gpu,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* H[] = {
|
static FFModuleBaseInfo* H[] = {
|
||||||
(void*) &instance.config.host,
|
(void*) &instance.config.modules.host,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* I[] = {
|
static FFModuleBaseInfo* I[] = {
|
||||||
(void*) &instance.config.icons,
|
(void*) &instance.config.modules.icons,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,42 +64,42 @@ static FFModuleBaseInfo* J[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* K[] = {
|
static FFModuleBaseInfo* K[] = {
|
||||||
(void*) &instance.config.kernel,
|
(void*) &instance.config.modules.kernel,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* L[] = {
|
static FFModuleBaseInfo* L[] = {
|
||||||
(void*) &instance.config.lm,
|
(void*) &instance.config.modules.lm,
|
||||||
(void*) &instance.config.locale,
|
(void*) &instance.config.modules.locale,
|
||||||
(void*) &instance.config.localIP,
|
(void*) &instance.config.modules.localIP,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* M[] = {
|
static FFModuleBaseInfo* M[] = {
|
||||||
(void*) &instance.config.media,
|
(void*) &instance.config.modules.media,
|
||||||
(void*) &instance.config.memory,
|
(void*) &instance.config.modules.memory,
|
||||||
(void*) &instance.config.monitor,
|
(void*) &instance.config.modules.monitor,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* N[] = {
|
static FFModuleBaseInfo* N[] = {
|
||||||
(void*) &instance.config.netIo,
|
(void*) &instance.config.modules.netIo,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* O[] = {
|
static FFModuleBaseInfo* O[] = {
|
||||||
(void*) &instance.config.openCL,
|
(void*) &instance.config.modules.openCL,
|
||||||
(void*) &instance.config.openGL,
|
(void*) &instance.config.modules.openGL,
|
||||||
(void*) &instance.config.os,
|
(void*) &instance.config.modules.os,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* P[] = {
|
static FFModuleBaseInfo* P[] = {
|
||||||
(void*) &instance.config.packages,
|
(void*) &instance.config.modules.packages,
|
||||||
(void*) &instance.config.player,
|
(void*) &instance.config.modules.player,
|
||||||
(void*) &instance.config.powerAdapter,
|
(void*) &instance.config.modules.powerAdapter,
|
||||||
(void*) &instance.config.processes,
|
(void*) &instance.config.modules.processes,
|
||||||
(void*) &instance.config.publicIP,
|
(void*) &instance.config.modules.publicIP,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,40 +112,40 @@ static FFModuleBaseInfo* R[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* S[] = {
|
static FFModuleBaseInfo* S[] = {
|
||||||
(void*) &instance.config.separator,
|
(void*) &instance.config.modules.separator,
|
||||||
(void*) &instance.config.shell,
|
(void*) &instance.config.modules.shell,
|
||||||
(void*) &instance.config.sound,
|
(void*) &instance.config.modules.sound,
|
||||||
(void*) &instance.config.swap,
|
(void*) &instance.config.modules.swap,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* T[] = {
|
static FFModuleBaseInfo* T[] = {
|
||||||
(void*) &instance.config.terminal,
|
(void*) &instance.config.modules.terminal,
|
||||||
(void*) &instance.config.terminalFont,
|
(void*) &instance.config.modules.terminalFont,
|
||||||
(void*) &instance.config.terminalSize,
|
(void*) &instance.config.modules.terminalSize,
|
||||||
(void*) &instance.config.title,
|
(void*) &instance.config.modules.title,
|
||||||
(void*) &instance.config.theme,
|
(void*) &instance.config.modules.theme,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* U[] = {
|
static FFModuleBaseInfo* U[] = {
|
||||||
(void*) &instance.config.uptime,
|
(void*) &instance.config.modules.uptime,
|
||||||
(void*) &instance.config.users,
|
(void*) &instance.config.modules.users,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* V[] = {
|
static FFModuleBaseInfo* V[] = {
|
||||||
(void*) &instance.config.version,
|
(void*) &instance.config.modules.version,
|
||||||
(void*) &instance.config.vulkan,
|
(void*) &instance.config.modules.vulkan,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FFModuleBaseInfo* W[] = {
|
static FFModuleBaseInfo* W[] = {
|
||||||
(void*) &instance.config.wallpaper,
|
(void*) &instance.config.modules.wallpaper,
|
||||||
(void*) &instance.config.weather,
|
(void*) &instance.config.modules.weather,
|
||||||
(void*) &instance.config.wm,
|
(void*) &instance.config.modules.wm,
|
||||||
(void*) &instance.config.wifi,
|
(void*) &instance.config.modules.wifi,
|
||||||
(void*) &instance.config.wmTheme,
|
(void*) &instance.config.modules.wmTheme,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+7
-4
@@ -17,8 +17,9 @@ typedef struct FFModuleBaseInfo
|
|||||||
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
|
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
|
||||||
void (*parseJsonObject)(void* options, struct yyjson_val *module);
|
void (*parseJsonObject)(void* options, struct yyjson_val *module);
|
||||||
void (*printModule)(void* options);
|
void (*printModule)(void* options);
|
||||||
void (*generateJson)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
||||||
void (*printHelpFormat)(void);
|
void (*printHelpFormat)(void);
|
||||||
|
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
|
||||||
} FFModuleBaseInfo;
|
} FFModuleBaseInfo;
|
||||||
|
|
||||||
static inline void ffOptionInitModuleBaseInfo(
|
static inline void ffOptionInitModuleBaseInfo(
|
||||||
@@ -27,16 +28,18 @@ static inline void ffOptionInitModuleBaseInfo(
|
|||||||
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
|
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
|
||||||
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
|
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
|
||||||
void* printModule, // void (*const printModule)(void* options)
|
void* printModule, // void (*const printModule)(void* options)
|
||||||
void* generateJson, // void (*const generateJson)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||||
void (*printHelpFormat)(void)
|
void (*printHelpFormat)(void),
|
||||||
|
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
baseInfo->name = name;
|
baseInfo->name = name;
|
||||||
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
||||||
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
||||||
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
||||||
baseInfo->generateJson = (__typeof__(baseInfo->generateJson)) generateJson;
|
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
|
||||||
baseInfo->printHelpFormat = printHelpFormat;
|
baseInfo->printHelpFormat = printHelpFormat;
|
||||||
|
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct FFModuleArgs
|
typedef struct FFModuleArgs
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
|||||||
double size = (double) bytes;
|
double size = (double) bytes;
|
||||||
uint8_t counter = 0;
|
uint8_t counter = 0;
|
||||||
|
|
||||||
while(size >= base && counter < instance.config.sizeMaxPrefix && prefixes[counter + 1])
|
while(size >= base && counter < instance.config.display.sizeMaxPrefix && prefixes[counter + 1])
|
||||||
{
|
{
|
||||||
size /= base;
|
size /= base;
|
||||||
counter++;
|
counter++;
|
||||||
@@ -74,12 +74,12 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
|||||||
if(counter == 0)
|
if(counter == 0)
|
||||||
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
|
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
|
||||||
else
|
else
|
||||||
ffStrbufAppendF(result, "%.*f %s", instance.config.sizeNdigits, size, prefixes[counter]);
|
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||||
{
|
{
|
||||||
switch (instance.config.binaryPrefixType)
|
switch (instance.config.display.binaryPrefixType)
|
||||||
{
|
{
|
||||||
case FF_BINARY_PREFIX_TYPE_IEC:
|
case FF_BINARY_PREFIX_TYPE_IEC:
|
||||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
|
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
|
||||||
@@ -98,7 +98,7 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
|||||||
|
|
||||||
void ffParseTemperature(double celsius, FFstrbuf* buffer)
|
void ffParseTemperature(double celsius, FFstrbuf* buffer)
|
||||||
{
|
{
|
||||||
switch (instance.config.temperatureUnit)
|
switch (instance.config.display.temperatureUnit)
|
||||||
{
|
{
|
||||||
case FF_TEMPERATURE_UNIT_CELSIUS:
|
case FF_TEMPERATURE_UNIT_CELSIUS:
|
||||||
ffStrbufAppendF(buffer, "%.1f°C", celsius);
|
ffStrbufAppendF(buffer, "%.1f°C", celsius);
|
||||||
|
|||||||
+11
-11
@@ -14,16 +14,16 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
|||||||
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
|
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!instance.config.display.pipe)
|
||||||
{
|
{
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||||
if (instance.config.brightColor)
|
if (instance.config.display.brightColor)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
||||||
|
|
||||||
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
|
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
|
||||||
ffPrintColor(&moduleArgs->keyColor);
|
ffPrintColor(&moduleArgs->keyColor);
|
||||||
else
|
else
|
||||||
ffPrintColor(&instance.config.colorKeys);
|
ffPrintColor(&instance.config.display.colorKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
//NULL check is required for modules with custom keys, e.g. disk with the folder path
|
//NULL check is required for modules with custom keys, e.g. disk with the folder path
|
||||||
@@ -43,18 +43,18 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
|||||||
ffStrbufWriteTo(&key, stdout);
|
ffStrbufWriteTo(&key, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!instance.config.display.pipe)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||||
|
|
||||||
ffStrbufWriteTo(&instance.config.keyValueSeparator, stdout);
|
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!instance.config.display.pipe)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||||
|
|
||||||
|
|
||||||
if (!instance.config.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
||||||
{
|
{
|
||||||
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.keyWidth;
|
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
|
||||||
if (keyWidth > 0)
|
if (keyWidth > 0)
|
||||||
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
|
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
|
||||||
}
|
}
|
||||||
@@ -77,17 +77,17 @@ void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFMo
|
|||||||
|
|
||||||
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
|
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
|
||||||
{
|
{
|
||||||
if(!instance.config.showErrors)
|
if(!instance.config.display.showErrors)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
|
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!instance.config.display.pipe)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
|
||||||
|
|
||||||
vprintf(message, arguments);
|
vprintf(message, arguments);
|
||||||
|
|
||||||
if(!instance.config.pipe)
|
if(!instance.config.display.pipe)
|
||||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||||
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|||||||
@@ -34,10 +34,11 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
|
|||||||
//Child
|
//Child
|
||||||
if(childPid == 0)
|
if(childPid == 0)
|
||||||
{
|
{
|
||||||
|
int nullFile = open("/dev/null", O_WRONLY);
|
||||||
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
||||||
|
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||||
close(pipes[0]);
|
close(pipes[0]);
|
||||||
close(pipes[1]);
|
close(pipes[1]);
|
||||||
close(useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
|
||||||
setenv("LANG", "C", 1);
|
setenv("LANG", "C", 1);
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
exit(901);
|
exit(901);
|
||||||
@@ -48,7 +49,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
|
|||||||
|
|
||||||
int FF_AUTO_CLOSE_FD childPipeFd = pipes[0];
|
int FF_AUTO_CLOSE_FD childPipeFd = pipes[0];
|
||||||
|
|
||||||
int timeout = instance.config.processingTimeout;
|
int timeout = instance.config.general.processingTimeout;
|
||||||
if (timeout >= 0)
|
if (timeout >= 0)
|
||||||
fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK);
|
fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK);
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ enum { FF_PIPE_BUFSIZ = 4096 };
|
|||||||
|
|
||||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||||
{
|
{
|
||||||
int timeout = instance.config.processingTimeout;
|
int timeout = instance.config.general.processingTimeout;
|
||||||
|
|
||||||
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
|
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
|
||||||
L"\\\\.\\pipe\\LOCAL\\",
|
L"\\\\.\\pipe\\LOCAL\\",
|
||||||
|
|||||||
+4
-11
@@ -15,18 +15,14 @@ typedef enum FFInitState
|
|||||||
|
|
||||||
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
|
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
|
||||||
static dataObject data; \
|
static dataObject data; \
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
|
||||||
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
|
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
|
||||||
ffThreadMutexLock(&mutex); \
|
|
||||||
if(initState != FF_INITSTATE_UNINITIALIZED) {\
|
if(initState != FF_INITSTATE_UNINITIALIZED) {\
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
|
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
|
||||||
} \
|
} \
|
||||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||||
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
|
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
|
||||||
if(libraryHandle == NULL) { \
|
if(libraryHandle == NULL) { \
|
||||||
initState = FF_INITSTATE_FAILED; \
|
initState = FF_INITSTATE_FAILED; \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return NULL; \
|
return NULL; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
@@ -35,20 +31,17 @@ typedef enum FFInitState
|
|||||||
if(data.ff ## symbolName == NULL) { \
|
if(data.ff ## symbolName == NULL) { \
|
||||||
dlclose(libraryHandle); \
|
dlclose(libraryHandle); \
|
||||||
initState = FF_INITSTATE_FAILED; \
|
initState = FF_INITSTATE_FAILED; \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FF_LIBRARY_DATA_LOAD_RETURN \
|
#define FF_LIBRARY_DATA_LOAD_RETURN \
|
||||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return &data;
|
return &data;
|
||||||
|
|
||||||
#define FF_LIBRARY_DATA_LOAD_ERROR \
|
#define FF_LIBRARY_DATA_LOAD_ERROR \
|
||||||
{ \
|
{ \
|
||||||
dlclose(libraryHandle); \
|
dlclose(libraryHandle); \
|
||||||
initState = FF_INITSTATE_FAILED; \
|
initState = FF_INITSTATE_FAILED; \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +92,7 @@ typedef struct GSettingsData
|
|||||||
|
|
||||||
static const GSettingsData* getGSettingsData(void)
|
static const GSettingsData* getGSettingsData(void)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||||
|
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
|
||||||
@@ -172,7 +165,7 @@ typedef struct DConfData
|
|||||||
|
|
||||||
static const DConfData* getDConfData(void)
|
static const DConfData* getDConfData(void)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||||
|
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
|
||||||
@@ -243,7 +236,7 @@ typedef struct XFConfData
|
|||||||
|
|
||||||
static const XFConfData* getXFConfData(void)
|
static const XFConfData* getXFConfData(void)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||||
|
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
|
||||||
@@ -305,7 +298,7 @@ typedef struct SQLiteData
|
|||||||
|
|
||||||
static const SQLiteData* getSQLiteData(void)
|
static const SQLiteData* getSQLiteData(void)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||||
|
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
|
||||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
|
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# This file sets the default config for all users of the system.
|
# This file sets the default config for all users of the system.
|
||||||
|
|
||||||
# For more information about how configuration files work,
|
# For more information about how configuration files work,
|
||||||
# see ~/.config/fastfetch/config.conf, generated during first run.
|
# see ~/.config/fastfetch/config.conf.
|
||||||
# All options that can be put there (or passed as argument) can be put here too.
|
# All options that can be put there (or passed as argument) can be put here too.
|
||||||
|
|
||||||
# Use fastfetch --print-config-system > /etc/fastfetch/config.conf
|
# Use fastfetch --print-config-system > /etc/fastfetch/config.conf
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
"top": 2
|
"top": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"display": {
|
|
||||||
"percentType": 9 // colored percent number
|
|
||||||
},
|
|
||||||
"modules": [
|
"modules": [
|
||||||
"title",
|
"title",
|
||||||
"separator",
|
"separator",
|
||||||
@@ -34,6 +31,7 @@
|
|||||||
"gpu",
|
"gpu",
|
||||||
"memory",
|
"memory",
|
||||||
"disk",
|
"disk",
|
||||||
|
"localip",
|
||||||
"battery",
|
"battery",
|
||||||
"poweradapter",
|
"poweradapter",
|
||||||
"locale",
|
"locale",
|
||||||
|
|||||||
+71
-60
@@ -1,9 +1,11 @@
|
|||||||
Usage: fastfetch <options>
|
Fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way
|
||||||
|
|
||||||
|
Usage: fastfetch <?options>
|
||||||
|
|
||||||
Informative options:
|
Informative options:
|
||||||
-h,--help: Show this message
|
-h, --help: Show this message
|
||||||
-h,--help <command>: Show help for a specific command
|
-h, --help <command>: Show help for a specific command
|
||||||
-v,--version: Show the version of fastfetch
|
-v, --version: Show the version of fastfetch
|
||||||
--list-config-paths: List search paths of config files
|
--list-config-paths: List search paths of config files
|
||||||
--list-data-paths: List search paths of presets and logos
|
--list-data-paths: List search paths of presets and logos
|
||||||
--list-logos: List available logos
|
--list-logos: List available logos
|
||||||
@@ -14,33 +16,33 @@ Informative options:
|
|||||||
--print-config-system: Print the default system config
|
--print-config-system: Print the default system config
|
||||||
--print-config-user: Print the default user config
|
--print-config-user: Print the default user config
|
||||||
--print-structure: Print the default structure
|
--print-structure: Print the default structure
|
||||||
--gen-config <?type>: Generate a sample config file in the default path. Param `type` can be `jsonc` or `conf`
|
|
||||||
--gen-config-force <?type>: Generate a sample config file in the default path. Overwrite the existing one
|
Config options:
|
||||||
|
-c, --load-config <file>: Load a config file or preset (+)
|
||||||
|
--gen-config <type>: Generate a sample config file in the default path. Param `type` can be `jsonc` or deprecated `conf`
|
||||||
|
--gen-config-force <type>: Generate a sample config file in the default path. Overwrite the existing one
|
||||||
|
--migrate-config <?path>: Migrate old flag based config file to new JSONC format. Optional param `path` is the file path that new file should be write to
|
||||||
|
|
||||||
General options:
|
General options:
|
||||||
--load-config <file>: Load a config file or preset (+)
|
--thread <?value>: Use separate threads to send HTTP requests
|
||||||
--config <file>: Alias of --load-config (+)
|
|
||||||
--multithreading <?value>: Use multiple threads to detect values
|
|
||||||
--stat <?value>: Show time usage (in ms) for individual modules
|
|
||||||
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
|
|
||||||
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
|
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
|
||||||
--pipe <?value>: Disable logo and all escape sequences
|
|
||||||
--wmi-timeout <num>: Set the timeout (ms) for WMI queries. Windows only. Default is 5000
|
--wmi-timeout <num>: Set the timeout (ms) for WMI queries. Windows only. Default is 5000
|
||||||
--processing-timeout <num>: Set the timeout (ms) when waiting for child processes. Default is 1000
|
--processing-timeout <num>: Set the timeout (ms) when waiting for child processes. Default is 1000
|
||||||
--ds-force-drm <?value>: Set if only DRM should be used to detect displays. Default is false
|
--ds-force-drm <?value>: Set if only DRM should be used to detect displays. Default is false. Linux only
|
||||||
|
|
||||||
Logo options:
|
Logo options:
|
||||||
-l,--logo <logo>: Set the logo; if default, the name of a builtin logo or a path to a file
|
-l, --logo <logo>: Set the logo; if default, the name of a builtin logo or a path to a file
|
||||||
--logo-type <type>: Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty, iterm or chafa
|
--logo-type <type>: Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty, iterm or chafa
|
||||||
--logo-width <width>: Set the width of the logo (in characters), if it is an image. Required for iTerm image protocol
|
--logo-width <width>: Set the width of the logo (in characters), if it is an image. Required for iTerm image protocol
|
||||||
--logo-height <height>: Set the height of the logo (in characters), if it is an image. Required for iTerm image protocol
|
--logo-height <height>: Set the height of the logo (in characters), if it is an image. Required for iTerm image protocol
|
||||||
--logo-preserve-aspect-radio <?value>: Set if the logo should fill the specified width and height as much as possible without stretching. Supported by iTerm image protocol
|
--logo-preserve-aspect-ratio <?value>: Set if the logo should fill the specified width and height as much as possible without stretching. Supported by iTerm image protocol
|
||||||
--logo-color-[1-9] <color>: Overwrite a color in the logo
|
--logo-color-[1-9] <color>: Overwrite a color in the logo
|
||||||
--logo-padding <padding>: Set the padding on the left and the right of the logo
|
--logo-padding <padding>: Set the padding on the left and the right of the logo
|
||||||
--logo-padding-left <padding>: Set the padding on the left of the logo
|
--logo-padding-left <padding>: Set the padding on the left of the logo
|
||||||
--logo-padding-right <padding>: Set the padding on the right of the logo
|
--logo-padding-right <padding>: Set the padding on the right of the logo
|
||||||
--logo-padding-top <padding>: Set the padding on the top of the logo
|
--logo-padding-top <padding>: Set the padding on the top of the logo
|
||||||
--logo-print-remaining <?value>: Whether to print the remaining logo, if it has more lines than modules to display
|
--logo-print-remaining <?value>: Whether to print the remaining logo, if it has more lines than modules to display
|
||||||
|
--logo-separate <?value>: If true, print modules at bottom of the logo
|
||||||
--logo-recache <?value>: If true, regenerate image logo cache
|
--logo-recache <?value>: If true, regenerate image logo cache
|
||||||
--file <file>: Short for --logo-type file --logo <file>
|
--file <file>: Short for --logo-type file --logo <file>
|
||||||
--file-raw <file>: Short for --logo-type file-raw --logo <file>
|
--file-raw <file>: Short for --logo-type file-raw --logo <file>
|
||||||
@@ -57,7 +59,9 @@ Logo options:
|
|||||||
--chafa-dither-mode <value>: Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail
|
--chafa-dither-mode <value>: Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail
|
||||||
|
|
||||||
Display options:
|
Display options:
|
||||||
-s,--structure <structure>: Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
|
-s,--structure <structure>: Set the structure of the fetch. Must be a colon separated list of keys. Use `fastfetch --list-modules` to see the ones available.
|
||||||
|
--stat <?value>: Show time usage (in ms) for individual modules
|
||||||
|
--pipe <?value>: Disable logo and all escape sequences
|
||||||
--color-keys <color>: Set the color of the keys
|
--color-keys <color>: Set the color of the keys
|
||||||
--color-title <color>: Set the color of the title
|
--color-title <color>: Set the color of the title
|
||||||
--color <color>: Set the color of both the keys and title
|
--color <color>: Set the color of both the keys and title
|
||||||
@@ -70,7 +74,7 @@ Display options:
|
|||||||
--disable-linewrap <?value>: Whether to disable line wrap during the run
|
--disable-linewrap <?value>: Whether to disable line wrap during the run
|
||||||
--hide-cursor <?value>: Whether to hide the cursor during the run
|
--hide-cursor <?value>: Whether to hide the cursor during the run
|
||||||
--binary-prefix <value>: Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC
|
--binary-prefix <value>: Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC
|
||||||
--percent-type <value>: Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number. Default is 1
|
--percent-type <value>: Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number. Default is 9
|
||||||
--percent-ndigits <value>: Set the number of digits to keep after the decimal point when formatting percentage numbers. Default is 0
|
--percent-ndigits <value>: Set the number of digits to keep after the decimal point when formatting percentage numbers. Default is 0
|
||||||
--bar-char-elapsed <str>: Set the character to use in elapsed part. Default is '■'
|
--bar-char-elapsed <str>: Set the character to use in elapsed part. Default is '■'
|
||||||
--bar-char-total <str>: Set the character to use in total part. Default is '-'
|
--bar-char-total <str>: Set the character to use in total part. Default is '-'
|
||||||
@@ -83,8 +87,8 @@ Display options:
|
|||||||
|
|
||||||
General module options:
|
General module options:
|
||||||
--<module>-format <format>: Set the format string to use for each specific module.
|
--<module>-format <format>: Set the format string to use for each specific module.
|
||||||
To see how a format string works, use fastfetch --help format.
|
To see how a format string works, use `fastfetch --help format`.
|
||||||
To see help about a specific format string, use fastfetch --help <module>-format.
|
To see help about a specific format string, use `fastfetch --help <module>-format`.
|
||||||
|
|
||||||
--<module>-key <key>: Set the key to use for each specific module.
|
--<module>-key <key>: Set the key to use for each specific module.
|
||||||
For modules which print multiple lines, the string is parsed as a format string with the index as first character.
|
For modules which print multiple lines, the string is parsed as a format string with the index as first character.
|
||||||
@@ -93,37 +97,39 @@ General module options:
|
|||||||
--<module>-key-width <num>: Override the global `--key-width` option for each specific module.
|
--<module>-key-width <num>: Override the global `--key-width` option for each specific module.
|
||||||
|
|
||||||
Library options: Set the path of a library to load
|
Library options: Set the path of a library to load
|
||||||
--lib-PCI <path>
|
--lib-PCI <path>: GPU output
|
||||||
--lib-vulkan <path>
|
--lib-vulkan <path>: Vulkan module & fallback for GPU output
|
||||||
--lib-wayland <path>
|
--lib-wayland <path>: Better display performance and output in wayland sessions
|
||||||
--lib-xcb-randr <path>
|
--lib-xcb-randr <path>: X11 sessions for better display detection and faster WM detection
|
||||||
--lib-xcb <path>
|
--lib-xcb <path>: X11 sessions for better display detection and faster WM detection
|
||||||
--lib-Xrandr <path>
|
--lib-Xrandr <path>: X11 sessions for better display detection and faster WM detection
|
||||||
--lib-X11 <path>
|
--lib-X11 <path>: X11 sessions for better display detection and faster WM detection
|
||||||
--lib-gio <path>
|
--lib-gio <path>: Needed for values that are only stored GSettings
|
||||||
--lib-DConf <path>
|
--lib-DConf <path>: Needed for values that are only stored in DConf + Fallback for GSettings
|
||||||
--lib-DBus <path>
|
--lib-DBus <path>: Bluetooth, Player & Media detection
|
||||||
--lib-XFConf <path>
|
--lib-XFConf <path>: Needed for XFWM theme and XFCE Terminal font
|
||||||
--lib-sqlite3 <path>
|
--lib-sqlite3 <path>: Needed for pkg & rpm package count
|
||||||
--lib-rpm <path>
|
--lib-rpm <path>: Slower fallback for rpm package count
|
||||||
--lib-imagemagick <path>
|
--lib-imagemagick <path>: Images in terminal using sixel or kitty graphics protocol
|
||||||
--lib-z <path>
|
--lib-z <path>: Libz. Faster image output when using kitty graphics protocol
|
||||||
--lib-chafa <path>
|
--lib-chafa <path>: Image output as ascii art
|
||||||
--lib-egl <path>
|
--lib-egl <path>: Needed by the OpenGL module for gl context creation
|
||||||
--lib-glx <path>
|
--lib-glx <path>: Needed by the OpenGL module for gl context creation
|
||||||
--lib-osmesa <path>
|
--lib-osmesa <path>: Needed by the OpenGL module for gl context creation
|
||||||
--lib-opencl <path>
|
--lib-opencl <path>: OpenCL module
|
||||||
--lib-pulse <path>
|
--lib-pulse <path>: Pulseaudio. Used for Sound detection
|
||||||
--lib-freetype <path>
|
--lib-nm: NetworkManager. Used for Wifi detection
|
||||||
--lib-ddcutil <path>
|
--lib-freetype <path>: Used for Termux font detection
|
||||||
|
--lib-ddcutil <path>: Used for brightness detection of external displays
|
||||||
|
|
||||||
Module specific options:
|
Module specific options:
|
||||||
--title-fqdn <?value>: Set if the title should use fully qualified domain name. Default is false
|
--title-fqdn <?value>: Set if the title should use fully qualified domain name. Default is false
|
||||||
--title-color-user <color>: Set color of the user name (left part). Default is empty (use color of `--color-title`).
|
--title-color-user <color>: Set color of the user name (left part). Default is empty (use color of `--color-title`).
|
||||||
--title-color-at <color>: Set color of the @ symbol (middle part). Default is empty (use color of `--color-title`)
|
--title-color-at <color>: Set color of the @ symbol (middle part). Default is empty (use color of `--color-title`)
|
||||||
--title-color-host <color>: Set color of the host name (right part). Default is empty (use color of `--color-title`)
|
--title-color-host <color>: Set color of the host name (right part). Default is empty (use color of `--color-title`)
|
||||||
|
--chassis-use-wmi <?value>: Set if WMI query should be used on Windows, which detects more information but slower. Default is false
|
||||||
--separator-string <str>: Set the string printed by the separator module
|
--separator-string <str>: Set the string printed by the separator module
|
||||||
--os-file <path>: Set the path to the file containing OS information
|
--os-file <path>: Set the path to the file containing OS information. Linux only
|
||||||
--disk-folders <folders>: A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows)
|
--disk-folders <folders>: A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows)
|
||||||
--disk-show-regular <?value>: Set if regular volume should be printed. Default is true
|
--disk-show-regular <?value>: Set if regular volume should be printed. Default is true
|
||||||
--disk-show-external <?value>: Set if external volume should be printed. Default is true
|
--disk-show-external <?value>: Set if external volume should be printed. Default is true
|
||||||
@@ -133,17 +139,21 @@ Module specific options:
|
|||||||
--disk-show-unknown <?value>: Set if unknown (unable to detect sizes) volumes should be printed. Default is false
|
--disk-show-unknown <?value>: Set if unknown (unable to detect sizes) volumes should be printed. Default is false
|
||||||
--disk-use-available <?value>: Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes. Default is false
|
--disk-use-available <?value>: Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes. Default is false
|
||||||
--diskio-name-prefix <str>: Show disks with given name prefix only. Default is empty
|
--diskio-name-prefix <str>: Show disks with given name prefix only. Default is empty
|
||||||
--bluetooth-show-disconnected: <?value>: Set if disconnected bluetooth devices should be printed. Default is false
|
--bluetooth-show-disconnected <?value>: Set if disconnected bluetooth devices should be printed. Default is false
|
||||||
--display-compact-type: <?string>: Set if all displays should be printed in one line. Default is none
|
--packages-winget <?value>: Set if winget package count should be detected. Default is false
|
||||||
--display-detect-name: <?value>: Set if display name should be detected and printed (if supported). Default is false
|
--display-compact-type <?string>: Set if all displays should be printed in one line. Default is none
|
||||||
--display-precise-refresh-rate: <?value>:Set if decimal refresh rates should not be rounded into integers when printing. Default is true
|
--display-detect-name <?value>: Set if display name should be detected and printed (if supported). Default is false
|
||||||
--brightness-ddcci-sleep: <num> Set the sleep times (in ms) when sending DDC/CI requests. See <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail. Default is 10
|
--display-precise-refresh-rate <?value>: Set if decimal refresh rates should not be rounded into integers when printing. Default is true
|
||||||
--sound-type: <value>: Set what type of sound devices should be printed. Should be either main, active or all. Default is main
|
--brightness-ddcci-sleep <num>: Set the sleep times (in ms) when sending DDC/CI requests. See <https://www.ddcutil.com/performance_options/#option-sleep-multiplier> for detail. Default is 10
|
||||||
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
|
--sound-type <value>: Set what type of sound devices should be printed. Should be either main, active or all. Default is main
|
||||||
|
--battery-dir <folder>: The directory where the battery folders are. Standard: `/sys/class/power_supply/`. Linux only
|
||||||
|
--battery-use-setup-api <?value>: Set if `SetupAPI` should be used on Windows to detect battery info, which supports multi batteries, but slower. Windows only
|
||||||
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
|
--cpu-temp <?value>: Detect and display CPU temperature if supported. Default is false
|
||||||
--cpu-freq-ndigits <num>: Set the number of digits to keep after the decimal point when printing CPU frequency. Default is 2
|
--cpu-freq-ndigits <num>: Set the number of digits to keep after the decimal point when printing CPU frequency. Default is 2
|
||||||
--cpuusage-separate <?value>: Display CPU usage per CPU logical core, instead of an average result. Default is false
|
--cpuusage-separate <?value>: Display CPU usage per CPU logical core, instead of an average result. Default is false
|
||||||
|
--de-slow-version-detection <?value>: Set if DE version should be detected with slow operations. Default is false
|
||||||
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
|
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
|
||||||
|
--gpu-use-nvml <?value>: Use nvml (NVIDIA Management Library) to detect more detailed GPU information (memory usage, CUDA core count, etc). Default is false
|
||||||
--gpu-force-vulkan <?value>: Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false
|
--gpu-force-vulkan <?value>: Force using vulkan to detect GPUs, which support video memory usage detection with `--allow-slow-operations`. Default is false
|
||||||
--gpu-hide-type <?value>: Specify the type of GPUs should not be printed. Must be `integrated`, `discrete` or `none`. Default is none
|
--gpu-hide-type <?value>: Specify the type of GPUs should not be printed. Must be `integrated`, `discrete` or `none`. Default is none
|
||||||
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
|
--battery-temp <?value>: Detect and display Battery temperature if supported. Default is false
|
||||||
@@ -152,17 +162,18 @@ Module specific options:
|
|||||||
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
|
--localip-show-mac <?value>: Show mac addresses in local ip module. Default is false
|
||||||
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
|
--localip-show-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
|
||||||
--localip-name-prefix <str>: Show interfaces with given interface name prefix only. Default is empty
|
--localip-name-prefix <str>: Show interfaces with given interface name prefix only. Default is empty
|
||||||
--localip-default-route-only <?value>: Show the interface that is used for default routing only. Default is false
|
--localip-default-route-only <?value>: Show the interface that is used for default routing only. Default is true
|
||||||
--localip-compact <?value>: Show all IPs in one line. Default is false
|
--localip-compact <?value>: Show all IPs in one line. Default is false
|
||||||
--netio-name-prefix <str>: Show interfaces with given name prefix only. Default is empty
|
--netio-name-prefix <str>: Show interfaces with given name prefix only. Default is empty
|
||||||
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is false
|
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is true
|
||||||
--publicip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
|
--publicip-timeout <num>: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
|
||||||
--publicip-url: The URL of public IP detection server to be used.
|
--publicip-url <str>: The URL of public IP detection server to be used.
|
||||||
--weather-location: Set the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`).
|
--weather-location <str>: Set the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`).
|
||||||
--weather-timeout: Time in milliseconds to wait for the weather server to respond. Default is disabled (0)
|
--weather-timeout <num>: Time in milliseconds to wait for the weather server to respond. Default is disabled (0)
|
||||||
--weather-output-format: The output weather format to be used. It must be URI encoded.
|
--weather-output-format <str>: The output weather format to be used. It must be URI encoded.
|
||||||
--player-name: The name of the player to use
|
--wm-detect-plugin <?value>: Set if window manager plugin should be detected on supported platforms. Default is false
|
||||||
--opengl-library <value>: Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
|
--player-name <str>: The name of the player to use for module Media and Player. Linux only
|
||||||
|
--opengl-library <str>: Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
|
||||||
--command-shell <str>: Set the shell program to execute the command text. Default is cmd for Windows, /bin/sh for *nix
|
--command-shell <str>: Set the shell program to execute the command text. Default is cmd for Windows, /bin/sh for *nix
|
||||||
--command-key <str>: Set the module key to display
|
--command-key <str>: Set the module key to display
|
||||||
--command-text <str>: Set the command text to be executed
|
--command-text <str>: Set the command text to be executed
|
||||||
@@ -172,4 +183,4 @@ Module specific options:
|
|||||||
Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci"
|
Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci"
|
||||||
If a value starts with a ?, it is optional. "true" will be used if not set.
|
If a value starts with a ?, it is optional. "true" will be used if not set.
|
||||||
A (+) at the end indicates that more help can be printed with --help <option>
|
A (+) at the end indicates that more help can be printed with --help <option>
|
||||||
All options can be made permanent in $XDG_CONFIG_HOME/fastfetch/config.conf
|
All options can be made permanent with command `fastfetch <options> --migrate-config`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
usage: fastfetch --color <color>
|
Usage: fastfetch --color <color>
|
||||||
|
|
||||||
<color> must be a color encoding for linux terminals. It is inserted between "ESC[" and "m".
|
<color> must be a color encoding as ANSI escape sequences. It is inserted between "ESC[" and "m".
|
||||||
Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
|
Infos about them can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters.
|
||||||
Examples:
|
Examples:
|
||||||
--color 35: sets the color to pink
|
--color 35: sets the color to pink
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
usage: fastfetch --load-config <file>
|
Usage: fastfetch -c <file>
|
||||||
|
|
||||||
Loads a config file. A config file contains one flag per line. Empty lines or lines starting with # are ignored.
|
Loads a config file. A config file contains one flag per line. Empty lines or lines starting with # are ignored.
|
||||||
If the file is relative it looks in the following order:
|
If the file is relative it looks in the following order:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:PowerAdapter:Locale:Break:Colors
|
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:LocalIp:Battery:PowerAdapter:Locale:Break:Colors
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ typedef struct FFBatteryResult
|
|||||||
double capacity;
|
double capacity;
|
||||||
FFstrbuf status;
|
FFstrbuf status;
|
||||||
double temperature;
|
double temperature;
|
||||||
|
uint32_t cycleCount;
|
||||||
} FFBatteryResult;
|
} FFBatteryResult;
|
||||||
|
|
||||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results);
|
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
|
|||||||
|
|
||||||
FFBatteryResult* battery = ffListAdd(results);
|
FFBatteryResult* battery = ffListAdd(results);
|
||||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||||
|
battery->cycleCount = 0;
|
||||||
ffStrbufInit(&battery->manufacturer);
|
ffStrbufInit(&battery->manufacturer);
|
||||||
ffStrbufInit(&battery->modelName);
|
ffStrbufInit(&battery->modelName);
|
||||||
ffStrbufInit(&battery->status);
|
ffStrbufInit(&battery->status);
|
||||||
|
|||||||
@@ -5,16 +5,6 @@
|
|||||||
|
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
|
|
||||||
static double detectBatteryTemp(void)
|
|
||||||
{
|
|
||||||
double result = 0;
|
|
||||||
|
|
||||||
if(ffDetectCoreTemps(FF_TEMP_BATTERY, &result))
|
|
||||||
return FF_BATTERY_TEMP_UNSET;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||||
{
|
{
|
||||||
io_iterator_t iterator;
|
io_iterator_t iterator;
|
||||||
@@ -24,7 +14,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
io_registry_entry_t registryEntry;
|
io_registry_entry_t registryEntry;
|
||||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||||
{
|
{
|
||||||
CFMutableDictionaryRef properties;
|
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
|
||||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||||
{
|
{
|
||||||
IOObjectRelease(registryEntry);
|
IOObjectRelease(registryEntry);
|
||||||
@@ -35,7 +25,13 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
const char* error;
|
const char* error;
|
||||||
|
|
||||||
FFBatteryResult* battery = ffListAdd(results);
|
FFBatteryResult* battery = ffListAdd(results);
|
||||||
|
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||||
|
ffStrbufInit(&battery->manufacturer);
|
||||||
|
ffStrbufInit(&battery->modelName);
|
||||||
|
ffStrbufInit(&battery->technology);
|
||||||
|
ffStrbufInit(&battery->status);
|
||||||
battery->capacity = 0.0/0.0;
|
battery->capacity = 0.0/0.0;
|
||||||
|
|
||||||
int currentCapacity, maxCapacity;
|
int currentCapacity, maxCapacity;
|
||||||
|
|
||||||
if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity)))
|
if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity)))
|
||||||
@@ -50,33 +46,38 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
|
|
||||||
battery->capacity = currentCapacity * 100.0 / maxCapacity;
|
battery->capacity = currentCapacity * 100.0 / maxCapacity;
|
||||||
|
|
||||||
ffStrbufInit(&battery->manufacturer);
|
ffCfDictGetString(properties, CFSTR("DeviceName"), &battery->modelName);
|
||||||
ffStrbufInit(&battery->modelName);
|
|
||||||
ffStrbufInit(&battery->technology);
|
|
||||||
if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
|
if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
|
||||||
{
|
{
|
||||||
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
||||||
ffStrbufAppendS(&battery->modelName, "Builtin");
|
|
||||||
ffStrbufAppendS(&battery->technology, "Lithium");
|
ffStrbufAppendS(&battery->technology, "Lithium");
|
||||||
|
if (!battery->modelName.length)
|
||||||
|
ffStrbufAppendS(&battery->modelName, "Built-in");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffCfDictGetInt(properties, CFSTR("CycleCount"), (int32_t*) &battery->cycleCount);
|
||||||
|
|
||||||
|
if (!ffCfDictGetBool(properties, CFSTR("ExternalConnected"), &boolValue) && boolValue)
|
||||||
|
ffStrbufAppendS(&battery->status, "AC connected, ");
|
||||||
else
|
else
|
||||||
|
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||||
|
if (!ffCfDictGetBool(properties, CFSTR("IsCharging"), &boolValue) && boolValue)
|
||||||
|
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||||
|
if (!ffCfDictGetBool(properties, CFSTR("AtCriticalLevel"), &boolValue) && boolValue)
|
||||||
|
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||||
|
ffStrbufTrimRight(&battery->status, ' ');
|
||||||
|
ffStrbufTrimRight(&battery->status, ',');
|
||||||
|
|
||||||
|
if (options->temp)
|
||||||
{
|
{
|
||||||
ffStrbufAppendS(&battery->manufacturer, "Unknown");
|
int64_t temp;
|
||||||
ffStrbufAppendS(&battery->modelName, "Unknown");
|
if (!ffCfDictGetInt64(properties, CFSTR("Temperature"), &temp))
|
||||||
ffStrbufAppendS(&battery->technology, "Unknown");
|
battery->temperature = (double) temp / 10 - 273.15;
|
||||||
|
else
|
||||||
|
ffDetectCoreTemps(FF_TEMP_BATTERY, &battery->temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufInit(&battery->status);
|
|
||||||
if (!ffCfDictGetBool(properties, CFSTR("FullyCharged"), &boolValue) && boolValue)
|
|
||||||
ffStrbufAppendS(&battery->status, "Fully charged");
|
|
||||||
else if (!ffCfDictGetBool(properties, CFSTR("IsCharging"), &boolValue) && boolValue)
|
|
||||||
ffStrbufAppendS(&battery->status, "Charging");
|
|
||||||
else
|
|
||||||
ffStrbufAppendS(&battery->status, "");
|
|
||||||
|
|
||||||
battery->temperature = options->temp ? detectBatteryTemp() : FF_BATTERY_TEMP_UNSET;
|
|
||||||
|
|
||||||
CFRelease(properties);
|
|
||||||
IOObjectRelease(registryEntry);
|
IOObjectRelease(registryEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
|||||||
|
|
||||||
FFBatteryResult* battery = ffListAdd(results);
|
FFBatteryResult* battery = ffListAdd(results);
|
||||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||||
|
battery->cycleCount = 0;
|
||||||
ffStrbufInit(&battery->manufacturer);
|
ffStrbufInit(&battery->manufacturer);
|
||||||
ffStrbufInit(&battery->modelName);
|
ffStrbufInit(&battery->modelName);
|
||||||
ffStrbufInit(&battery->status);
|
ffStrbufInit(&battery->status);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "fastfetch.h"
|
|
||||||
#include "common/io/io.h"
|
|
||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
|
#include "detection/temps/temps_linux.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
static void parseBattery(FFstrbuf* dir, FFlist* results)
|
static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* options, FFlist* results)
|
||||||
{
|
{
|
||||||
uint32_t dirLength = dir->length;
|
uint32_t dirLength = dir->length;
|
||||||
|
|
||||||
@@ -65,7 +65,26 @@ static void parseBattery(FFstrbuf* dir, FFlist* results)
|
|||||||
ffReadFileBuffer(dir->chars, &result->status);
|
ffReadFileBuffer(dir->chars, &result->status);
|
||||||
ffStrbufSubstrBefore(dir, dirLength);
|
ffStrbufSubstrBefore(dir, dirLength);
|
||||||
|
|
||||||
|
ffStrbufAppendS(dir, "/cycle_count");
|
||||||
|
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||||
|
ffStrbufSubstrBefore(dir, dirLength);
|
||||||
|
if(dir->length)
|
||||||
|
result->cycleCount = (uint32_t) ffStrbufToUInt(&testBatteryBuffer, 0);
|
||||||
|
|
||||||
result->temperature = FF_BATTERY_TEMP_UNSET;
|
result->temperature = FF_BATTERY_TEMP_UNSET;
|
||||||
|
if (options->temp)
|
||||||
|
{
|
||||||
|
const FFlist* tempsResult = ffDetectTemps();
|
||||||
|
|
||||||
|
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
|
||||||
|
{
|
||||||
|
if (ffStrbufEqualS(&value->name, id))
|
||||||
|
{
|
||||||
|
result->temperature = value->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||||
@@ -84,7 +103,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
|
|
||||||
uint32_t baseDirLength = baseDir.length;
|
uint32_t baseDirLength = baseDir.length;
|
||||||
|
|
||||||
DIR* dirp = opendir(baseDir.chars);
|
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
|
||||||
if(dirp == NULL)
|
if(dirp == NULL)
|
||||||
return "opendir(batteryDir) == NULL";
|
return "opendir(batteryDir) == NULL";
|
||||||
|
|
||||||
@@ -95,12 +114,10 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||||
parseBattery(&baseDir, results);
|
parseBattery(&baseDir, entry->d_name, options, results);
|
||||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dirp);
|
|
||||||
|
|
||||||
if(results->length == 0)
|
if(results->length == 0)
|
||||||
return "batteryDir doesn't contain any battery folder";
|
return "batteryDir doesn't contain any battery folder";
|
||||||
|
|
||||||
|
|||||||
@@ -30,137 +30,146 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
|||||||
SetupDiDestroyDeviceInfoList(*hdev);
|
SetupDiDestroyDeviceInfoList(*hdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results)
|
||||||
{
|
{
|
||||||
if(instance.config.allowSlowOperations)
|
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||||
|
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
||||||
|
SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||||
|
if(hdev == INVALID_HANDLE_VALUE)
|
||||||
|
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY) failed";
|
||||||
|
|
||||||
|
SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) };
|
||||||
|
for(DWORD idev = 0; SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did); idev++)
|
||||||
{
|
{
|
||||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
DWORD cbRequired = 0;
|
||||||
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer
|
||||||
SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired);
|
||||||
if(hdev == INVALID_HANDLE_VALUE)
|
if(!pdidd)
|
||||||
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY) failed";
|
break; //Out of memory
|
||||||
|
|
||||||
|
pdidd->cbSize = sizeof(*pdidd);
|
||||||
|
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
|
||||||
|
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if(hBattery == INVALID_HANDLE_VALUE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BATTERY_QUERY_INFORMATION bqi = { .InformationLevel = BatteryInformation };
|
||||||
|
|
||||||
|
DWORD dwWait = 0;
|
||||||
|
DWORD dwOut;
|
||||||
|
|
||||||
|
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BATTERY_INFORMATION bi = {0};
|
||||||
|
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
|
||||||
|
|
||||||
|
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Lead Acid");
|
||||||
|
else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Lithium Ion");
|
||||||
|
else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Nickel Cadmium");
|
||||||
|
else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Nickel Metal Hydride");
|
||||||
|
else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Nickel Zinc");
|
||||||
|
else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
|
||||||
|
ffStrbufInitS(&battery->technology, "Rechargeable Alkaline-Manganese");
|
||||||
|
else
|
||||||
|
ffStrbufInitS(&battery->technology, "Unknown");
|
||||||
|
|
||||||
SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) };
|
|
||||||
for(DWORD idev = 0; SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did); idev++)
|
|
||||||
{
|
{
|
||||||
DWORD cbRequired = 0;
|
|
||||||
SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer
|
|
||||||
SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired);
|
|
||||||
if(!pdidd)
|
|
||||||
break; //Out of memory
|
|
||||||
|
|
||||||
pdidd->cbSize = sizeof(*pdidd);
|
|
||||||
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
|
|
||||||
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
|
|
||||||
if(hBattery == INVALID_HANDLE_VALUE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BATTERY_QUERY_INFORMATION bqi = { .InformationLevel = BatteryInformation };
|
|
||||||
|
|
||||||
DWORD dwWait = 0;
|
|
||||||
DWORD dwOut;
|
|
||||||
|
|
||||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BATTERY_INFORMATION bi = {0};
|
|
||||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
|
|
||||||
|
|
||||||
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Lead Acid");
|
|
||||||
else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Lithium Ion");
|
|
||||||
else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Nickel Cadmium");
|
|
||||||
else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Nickel Metal Hydride");
|
|
||||||
else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Nickel Zinc");
|
|
||||||
else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
|
|
||||||
ffStrbufInitS(&battery->technology, "Rechargeable Alkaline-Manganese");
|
|
||||||
else
|
|
||||||
ffStrbufInitS(&battery->technology, "Unknown");
|
|
||||||
|
|
||||||
{
|
|
||||||
ffStrbufInit(&battery->modelName);
|
|
||||||
bqi.InformationLevel = BatteryDeviceName;
|
|
||||||
wchar_t name[64];
|
|
||||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
|
||||||
ffStrbufSetWS(&battery->modelName, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ffStrbufInit(&battery->manufacturer);
|
|
||||||
bqi.InformationLevel = BatteryManufactureName;
|
|
||||||
wchar_t name[64];
|
|
||||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
|
||||||
ffStrbufSetWS(&battery->manufacturer, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
battery->temperature = 0.0/0.0;
|
|
||||||
if(options->temp)
|
|
||||||
{
|
|
||||||
bqi.InformationLevel = BatteryTemperature;
|
|
||||||
ULONG temp;
|
|
||||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
|
|
||||||
battery->temperature = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
BATTERY_STATUS bs;
|
|
||||||
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
|
|
||||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY)
|
|
||||||
battery->capacity = bs.Capacity * 100.0 / bi.FullChargedCapacity;
|
|
||||||
else
|
|
||||||
battery->capacity = 0;
|
|
||||||
|
|
||||||
ffStrbufInit(&battery->status);
|
|
||||||
if(bs.PowerState & BATTERY_POWER_ON_LINE)
|
|
||||||
ffStrbufAppendS(&battery->status, "AC Connected, ");
|
|
||||||
if(bs.PowerState & BATTERY_DISCHARGING)
|
|
||||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
|
||||||
if(bs.PowerState & BATTERY_CHARGING)
|
|
||||||
ffStrbufAppendS(&battery->status, "Charging");
|
|
||||||
if(bs.PowerState & BATTERY_CRITICAL)
|
|
||||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
|
||||||
ffStrbufTrimRight(&battery->status, ' ');
|
|
||||||
ffStrbufTrimRight(&battery->status, ',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SYSTEM_BATTERY_STATE info;
|
|
||||||
if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
|
|
||||||
{
|
|
||||||
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
|
|
||||||
ffStrbufInit(&battery->modelName);
|
ffStrbufInit(&battery->modelName);
|
||||||
ffStrbufInit(&battery->manufacturer);
|
bqi.InformationLevel = BatteryDeviceName;
|
||||||
ffStrbufInit(&battery->technology);
|
wchar_t name[64];
|
||||||
ffStrbufInit(&battery->status);
|
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||||
battery->temperature = 0.0/0.0;
|
ffStrbufSetWS(&battery->modelName, name);
|
||||||
|
}
|
||||||
|
|
||||||
battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity;
|
{
|
||||||
if(info.AcOnLine)
|
ffStrbufInit(&battery->manufacturer);
|
||||||
{
|
bqi.InformationLevel = BatteryManufactureName;
|
||||||
ffStrbufAppendS(&battery->status, "AC Connected");
|
wchar_t name[64];
|
||||||
if(info.Charging)
|
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||||
ffStrbufAppendS(&battery->status, ", Charging");
|
ffStrbufSetWS(&battery->manufacturer, name);
|
||||||
}
|
}
|
||||||
else if(info.Discharging)
|
|
||||||
ffStrbufAppendS(&battery->status, "Discharging");
|
battery->cycleCount = bi.CycleCount;
|
||||||
|
|
||||||
|
battery->temperature = 0.0/0.0;
|
||||||
|
if(options->temp)
|
||||||
|
{
|
||||||
|
bqi.InformationLevel = BatteryTemperature;
|
||||||
|
ULONG temp;
|
||||||
|
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
|
||||||
|
battery->temperature = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
BATTERY_STATUS bs;
|
||||||
|
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
|
||||||
|
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY)
|
||||||
|
battery->capacity = bs.Capacity * 100.0 / bi.FullChargedCapacity;
|
||||||
|
else
|
||||||
|
battery->capacity = 0;
|
||||||
|
|
||||||
|
ffStrbufInit(&battery->status);
|
||||||
|
if(bs.PowerState & BATTERY_POWER_ON_LINE)
|
||||||
|
ffStrbufAppendS(&battery->status, "AC Connected, ");
|
||||||
|
if(bs.PowerState & BATTERY_DISCHARGING)
|
||||||
|
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||||
|
if(bs.PowerState & BATTERY_CHARGING)
|
||||||
|
ffStrbufAppendS(&battery->status, "Charging, ");
|
||||||
|
if(bs.PowerState & BATTERY_CRITICAL)
|
||||||
|
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||||
|
ffStrbufTrimRight(&battery->status, ' ');
|
||||||
|
ffStrbufTrimRight(&battery->status, ',');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* detectWithNtApi(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* results)
|
||||||
|
{
|
||||||
|
SYSTEM_BATTERY_STATE info;
|
||||||
|
if (NT_SUCCESS(NtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
|
||||||
|
{
|
||||||
|
FFBatteryResult* battery = (FFBatteryResult*)ffListAdd(results);
|
||||||
|
ffStrbufInit(&battery->modelName);
|
||||||
|
ffStrbufInit(&battery->manufacturer);
|
||||||
|
ffStrbufInit(&battery->technology);
|
||||||
|
ffStrbufInit(&battery->status);
|
||||||
|
battery->temperature = 0.0/0.0;
|
||||||
|
battery->cycleCount = 0;
|
||||||
|
|
||||||
|
battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity;
|
||||||
|
if(info.AcOnLine)
|
||||||
|
{
|
||||||
|
ffStrbufAppendS(&battery->status, "AC Connected");
|
||||||
|
if(info.Charging)
|
||||||
|
ffStrbufAppendS(&battery->status, ", Charging");
|
||||||
|
}
|
||||||
|
else if(info.Discharging)
|
||||||
|
ffStrbufAppendS(&battery->status, "Discharging");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return "NtPowerInformation(SystemBatteryState) failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||||
|
{
|
||||||
|
return true
|
||||||
|
? detectWithSetupApi(options, results)
|
||||||
|
: detectWithNtApi(options, results);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ typedef struct FFBiosResult
|
|||||||
FFstrbuf release;
|
FFstrbuf release;
|
||||||
FFstrbuf vendor;
|
FFstrbuf vendor;
|
||||||
FFstrbuf version;
|
FFstrbuf version;
|
||||||
|
FFstrbuf type;
|
||||||
} FFBiosResult;
|
} FFBiosResult;
|
||||||
|
|
||||||
const char* ffDetectBios(FFBiosResult* bios);
|
const char* ffDetectBios(FFBiosResult* bios);
|
||||||
|
|||||||
@@ -9,5 +9,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
if (ffStrbufIgnCaseEqualS(&bios->version, "unknown"))
|
if (ffStrbufIgnCaseEqualS(&bios->version, "unknown"))
|
||||||
ffStrbufClear(&bios->version);
|
ffStrbufClear(&bios->version);
|
||||||
|
|
||||||
|
ffStrbufSetStatic(&bios->type, "Bootloader");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
ffCfDictGetString(properties, CFSTR("vendor"), &bios->vendor);
|
ffCfDictGetString(properties, CFSTR("vendor"), &bios->vendor);
|
||||||
ffCfDictGetString(properties, CFSTR("version"), &bios->version);
|
ffCfDictGetString(properties, CFSTR("version"), &bios->version);
|
||||||
ffCfDictGetString(properties, CFSTR("release-date"), &bios->date);
|
ffCfDictGetString(properties, CFSTR("release-date"), &bios->date);
|
||||||
ffStrbufAppendS(&bios->release, "Efi");
|
ffStrbufSetStatic(&bios->type, "UEFI");
|
||||||
|
|
||||||
CFRelease(properties);
|
CFRelease(properties);
|
||||||
IOObjectRelease(registryEntry);
|
IOObjectRelease(registryEntry);
|
||||||
@@ -54,12 +54,12 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
uint32_t index = ffStrbufFirstIndexC(&bios->version, '-');
|
uint32_t index = ffStrbufFirstIndexC(&bios->version, '-');
|
||||||
if (index != bios->version.length)
|
if (index != bios->version.length)
|
||||||
{
|
{
|
||||||
ffStrbufAppendNS(&bios->release, index, bios->version.chars);
|
ffStrbufAppendNS(&bios->type, index, bios->version.chars);
|
||||||
ffStrbufRemoveSubstr(&bios->version, 0, index + 1);
|
ffStrbufRemoveSubstr(&bios->version, 0, index + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ffStrbufAppendS(&bios->release, "iBoot");
|
ffStrbufSetStatic(&bios->type, "iBoot");
|
||||||
}
|
}
|
||||||
CFRelease(properties);
|
CFRelease(properties);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "common/sysctl.h"
|
||||||
#include "util/smbiosHelper.h"
|
#include "util/smbiosHelper.h"
|
||||||
|
|
||||||
const char* ffDetectBios(FFBiosResult* result)
|
const char* ffDetectBios(FFBiosResult* result)
|
||||||
@@ -13,5 +14,6 @@ const char* ffDetectBios(FFBiosResult* result)
|
|||||||
ffCleanUpSmbiosValue(&result->vendor);
|
ffCleanUpSmbiosValue(&result->vendor);
|
||||||
ffSettingsGetFreeBSDKenv("smbios.bios.version", &result->version);
|
ffSettingsGetFreeBSDKenv("smbios.bios.version", &result->version);
|
||||||
ffCleanUpSmbiosValue(&result->version);
|
ffCleanUpSmbiosValue(&result->version);
|
||||||
|
ffSysctlGetString("machdep.bootmethod", &result->type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,9 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
|
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->release);
|
||||||
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor);
|
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->vendor);
|
||||||
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version);
|
getSmbiosValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->version);
|
||||||
|
if (ffPathExists("/sys/firmware/efi", FF_PATHTYPE_DIRECTORY) || ffPathExists("/sys/firmware/acpi/tables/UEFI", FF_PATHTYPE_FILE))
|
||||||
|
ffStrbufSetStatic(&bios->type, "UEFI");
|
||||||
|
else
|
||||||
|
ffStrbufSetStatic(&bios->type, "BIOS");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,30 @@
|
|||||||
#include "util/windows/registry.h"
|
#include "util/windows/registry.h"
|
||||||
#include "util/smbiosHelper.h"
|
#include "util/smbiosHelper.h"
|
||||||
|
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
|
||||||
|
typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
||||||
|
{
|
||||||
|
GUID BootIdentifier;
|
||||||
|
FIRMWARE_TYPE FirmwareType;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ULONGLONG BootFlags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONGLONG DbgMenuOsSelection : 1; // REDSTONE4
|
||||||
|
ULONGLONG DbgHiberBoot : 1;
|
||||||
|
ULONGLONG DbgSoftBoot : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunch : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchCapable : 1; // 19H1
|
||||||
|
ULONGLONG DbgSystemHiveReplace : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchSmmProtections : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunchSmmLevel : 7; // 20H1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||||
|
|
||||||
const char* ffDetectBios(FFBiosResult* bios)
|
const char* ffDetectBios(FFBiosResult* bios)
|
||||||
{
|
{
|
||||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||||
@@ -24,5 +48,18 @@ const char* ffDetectBios(FFBiosResult* bios)
|
|||||||
)
|
)
|
||||||
ffStrbufAppendF(&bios->release, "%u.%u", (unsigned)major, (unsigned)minor);
|
ffStrbufAppendF(&bios->release, "%u.%u", (unsigned)major, (unsigned)minor);
|
||||||
|
|
||||||
|
// Same as GetFirmwareType, but support (?) Windows 7
|
||||||
|
// https://ntdoc.m417z.com/system_information_class
|
||||||
|
SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei;
|
||||||
|
if (NT_SUCCESS(NtQuerySystemInformation(90 /*SystemBootEnvironmentInformation*/, &sbei, sizeof(sbei), NULL)))
|
||||||
|
{
|
||||||
|
switch (sbei.FirmwareType)
|
||||||
|
{
|
||||||
|
case FirmwareTypeBios: ffStrbufSetStatic(&bios->type, "BIOS"); break;
|
||||||
|
case FirmwareTypeUefi: ffStrbufSetStatic(&bios->type, "UEFI"); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ double ddca_set_default_sleep_multiplier(double multiplier); // ddcutil 1.4
|
|||||||
|
|
||||||
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
|
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
FF_LIBRARY_LOAD(libddcutil, &instance.config.library.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ typedef struct FFChassisResult
|
|||||||
FFstrbuf version;
|
FFstrbuf version;
|
||||||
} FFChassisResult;
|
} FFChassisResult;
|
||||||
|
|
||||||
const char* ffDetectChassis(FFChassisResult* result);
|
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options);
|
||||||
const char* ffChassisTypeToString(uint32_t type);
|
const char* ffChassisTypeToString(uint32_t type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "util/smbiosHelper.h"
|
#include "util/smbiosHelper.h"
|
||||||
|
|
||||||
const char* ffDetectChassis(FFChassisResult* result)
|
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||||
{
|
{
|
||||||
// Unlike other platforms, `smbios.chassis.type` return display string directly on my machine
|
// Unlike other platforms, `smbios.chassis.type` return display string directly on my machine
|
||||||
ffSettingsGetFreeBSDKenv("smbios.chassis.type", &result->type);
|
ffSettingsGetFreeBSDKenv("smbios.chassis.type", &result->type);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstr
|
|||||||
ffStrbufClear(buffer);
|
ffStrbufClear(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectChassis(FFChassisResult* result)
|
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||||
{
|
{
|
||||||
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->type);
|
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->type);
|
||||||
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->vendor);
|
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->vendor);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "chassis.h"
|
#include "chassis.h"
|
||||||
|
|
||||||
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result)
|
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||||
{
|
{
|
||||||
return "Not supported on this platform";
|
return "Not supported on this platform";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
|
|||||||
{
|
{
|
||||||
auto [arr, len] = vtProp.get<std::pair<const int32_t*, uint32_t>>();
|
auto [arr, len] = vtProp.get<std::pair<const int32_t*, uint32_t>>();
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
return "ChassisTypes contain no data failed";
|
return "ChassisTypes contain no data";
|
||||||
for (uint32_t i = 0; i < len; ++i)
|
for (uint32_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
@@ -65,9 +65,9 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
const char* ffDetectChassis(FFChassisResult* result)
|
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options)
|
||||||
{
|
{
|
||||||
if (instance.config.allowSlowOperations)
|
if (options->useWmi)
|
||||||
return detectWithWmi(result);
|
return detectWithWmi(result);
|
||||||
return detectWithRegistry(result);
|
return detectWithRegistry(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
|
|||||||
ffParsePropLine(line, "isa :", cpuIsa) ||
|
ffParsePropLine(line, "isa :", cpuIsa) ||
|
||||||
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
||||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
(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 :", &cpu->name)) || //For POWER
|
||||||
|
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +83,10 @@ static double getFrequency(const char* info, const char* scaling)
|
|||||||
|
|
||||||
static double detectCPUTemp(void)
|
static double detectCPUTemp(void)
|
||||||
{
|
{
|
||||||
const FFTempsResult* temps = ffDetectTemps();
|
const FFlist* tempsResult = ffDetectTemps();
|
||||||
|
|
||||||
for(uint32_t i = 0; i < temps->values.length; i++)
|
FF_LIST_FOR_EACH(FFTempValue, value, *tempsResult)
|
||||||
{
|
{
|
||||||
FFTempValue* value = ffListGet(&temps->values, i);
|
|
||||||
|
|
||||||
if(
|
if(
|
||||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||||
@@ -115,6 +114,10 @@ static void parseIsa(FFstrbuf* cpuIsa)
|
|||||||
}
|
}
|
||||||
// The final ISA output of the above example is "rv64gch".
|
// The final ISA output of the above example is "rv64gch".
|
||||||
}
|
}
|
||||||
|
if(ffStrbufStartsWithS(cpuIsa, "mips"))
|
||||||
|
{
|
||||||
|
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const char* ffGetCpuUsageResult(FFlist* result)
|
|||||||
if(cpuTimes1.length == 0) return "No CPU cores found";
|
if(cpuTimes1.length == 0) return "No CPU cores found";
|
||||||
|
|
||||||
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
|
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
|
||||||
|
uint32_t retryCount = 0;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
error = ffGetCpuUsageInfo(&cpuTimes2);
|
error = ffGetCpuUsageInfo(&cpuTimes2);
|
||||||
@@ -39,9 +40,12 @@ retry:
|
|||||||
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
|
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
|
||||||
if (cpuTime2->totalAll <= cpuTime1->totalAll)
|
if (cpuTime2->totalAll <= cpuTime1->totalAll)
|
||||||
{
|
{
|
||||||
ffListClear(&cpuTimes2);
|
if (++retryCount <= 3)
|
||||||
ffTimeSleep(200);
|
{
|
||||||
goto retry;
|
ffListClear(&cpuTimes2);
|
||||||
|
ffTimeSleep(200);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fastfetch.h"
|
||||||
|
|
||||||
|
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options);
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
#include "de.h"
|
||||||
|
|
||||||
|
#include "common/io/io.h"
|
||||||
|
#include "common/parsing.h"
|
||||||
|
#include "common/properties.h"
|
||||||
|
#include "common/processing.h"
|
||||||
|
#include "detection/displayserver/displayserver.h"
|
||||||
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
static void getKDE(FFstrbuf* result, FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
|
||||||
|
{"X-KDE-PluginInfo-Version =", result}
|
||||||
|
});
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||||
|
if(result->length == 0)
|
||||||
|
{
|
||||||
|
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
|
||||||
|
{"X-KDE-PluginInfo-Version =", result}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||||
|
|
||||||
|
if(result->length == 0 && options->slowVersionDetection)
|
||||||
|
{
|
||||||
|
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||||
|
"plasmashell",
|
||||||
|
"--version",
|
||||||
|
NULL
|
||||||
|
}) == NULL) // plasmashell 5.27.5
|
||||||
|
ffStrbufSubstrAfterLastC(result, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", result);
|
||||||
|
|
||||||
|
if (result->length == 0)
|
||||||
|
{
|
||||||
|
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||||
|
"gnome-shell",
|
||||||
|
"--version",
|
||||||
|
NULL
|
||||||
|
}) == NULL) // GNOME Shell 44.1
|
||||||
|
ffStrbufSubstrAfterLastC(result, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getMate(FFstrbuf* result, FFDEOptions* options)
|
||||||
|
{
|
||||||
|
FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate();
|
||||||
|
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
|
||||||
|
FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate();
|
||||||
|
|
||||||
|
ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) {
|
||||||
|
{"<platform>", &major},
|
||||||
|
{"<minor>", &minor},
|
||||||
|
{"<micro>", µ}
|
||||||
|
});
|
||||||
|
|
||||||
|
ffParseSemver(result, &major, &minor, µ);
|
||||||
|
|
||||||
|
if(result->length == 0 && options->slowVersionDetection)
|
||||||
|
{
|
||||||
|
ffProcessAppendStdOut(result, (char* const[]){
|
||||||
|
"mate-session",
|
||||||
|
"--version",
|
||||||
|
NULL
|
||||||
|
});
|
||||||
|
|
||||||
|
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||||
|
ffStrbufTrim(result, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if(result->length == 0)
|
||||||
|
{
|
||||||
|
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
|
||||||
|
if (dirp)
|
||||||
|
{
|
||||||
|
struct dirent* entry;
|
||||||
|
while((entry = readdir(dirp)) != NULL)
|
||||||
|
{
|
||||||
|
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
|
||||||
|
continue;
|
||||||
|
ffStrbufAppendS(result, &entry->d_name[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(result->length == 0 && options->slowVersionDetection)
|
||||||
|
{
|
||||||
|
//This is somewhat slow
|
||||||
|
ffProcessAppendStdOut(result, (char* const[]){
|
||||||
|
"xfce4-session",
|
||||||
|
"--version",
|
||||||
|
NULL
|
||||||
|
});
|
||||||
|
|
||||||
|
ffStrbufSubstrBeforeFirstC(result, '(');
|
||||||
|
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||||
|
ffStrbufTrim(result, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getLXQt(FFstrbuf* result, FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileData("gconfig/lxqt.pc", "Version:", result);
|
||||||
|
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", result);
|
||||||
|
if(result->length == 0)
|
||||||
|
ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", result);
|
||||||
|
|
||||||
|
if(result->length == 0 && options->slowVersionDetection)
|
||||||
|
{
|
||||||
|
//This is really, really, really slow. Thank you, LXQt developers
|
||||||
|
ffProcessAppendStdOut(result, (char* const[]){
|
||||||
|
"lxqt-session",
|
||||||
|
"-v",
|
||||||
|
NULL
|
||||||
|
});
|
||||||
|
|
||||||
|
result->length = 0; //don't set '\0' byte
|
||||||
|
ffParsePropLines(result->chars , "liblxqt", result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||||
|
{
|
||||||
|
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
|
||||||
|
{
|
||||||
|
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
|
||||||
|
getKDE(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME) || ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
|
||||||
|
getGnome(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_CINNAMON))
|
||||||
|
getCinnamon(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_XFCE4))
|
||||||
|
getXFCE4(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_MATE))
|
||||||
|
getMate(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_LXQT))
|
||||||
|
getLXQt(result, options);
|
||||||
|
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
|
||||||
|
getBudgie(result, options);
|
||||||
|
else
|
||||||
|
return "Unsupported DE";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "de.h"
|
||||||
|
|
||||||
|
const char* ffDetectDEVersion(FF_MAYBE_UNUSED const FFstrbuf* deName, FF_MAYBE_UNUSED FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||||
|
{
|
||||||
|
return "Not supported on this platform";
|
||||||
|
}
|
||||||
@@ -68,7 +68,6 @@ typedef struct FFDisplayServerResult
|
|||||||
FFstrbuf wmProtocolName;
|
FFstrbuf wmProtocolName;
|
||||||
FFstrbuf deProcessName;
|
FFstrbuf deProcessName;
|
||||||
FFstrbuf dePrettyName;
|
FFstrbuf dePrettyName;
|
||||||
FFstrbuf deVersion;
|
|
||||||
FFlist displays; //List of FFDisplayResult
|
FFlist displays; //List of FFDisplayResult
|
||||||
} FFDisplayServerResult;
|
} FFDisplayServerResult;
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
|||||||
{
|
{
|
||||||
// Only for MiUI
|
// Only for MiUI
|
||||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||||
;
|
|
||||||
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
|
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
|
||||||
ffStrbufContainC(&buffer, ','))
|
ffStrbufContainC(&buffer, ','))
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,6 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
|||||||
ffStrbufInit(&ds->wmProtocolName);
|
ffStrbufInit(&ds->wmProtocolName);
|
||||||
ffStrbufInit(&ds->deProcessName);
|
ffStrbufInit(&ds->deProcessName);
|
||||||
ffStrbufInit(&ds->dePrettyName);
|
ffStrbufInit(&ds->dePrettyName);
|
||||||
ffStrbufInit(&ds->deVersion);
|
|
||||||
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0);
|
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 0);
|
||||||
|
|
||||||
if (!detectWithGetprop(ds))
|
if (!detectWithGetprop(ds))
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
#include "displayserver.h"
|
#include "displayserver.h"
|
||||||
#include "common/sysctl.h"
|
|
||||||
#include "util/apple/cf_helpers.h"
|
#include "util/apple/cf_helpers.h"
|
||||||
#include "util/mallocHelper.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <CoreGraphics/CGDirectDisplay.h>
|
#include <CoreGraphics/CGDirectDisplay.h>
|
||||||
@@ -70,35 +67,6 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void detectWMPlugin(FFstrbuf* name)
|
|
||||||
{
|
|
||||||
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
|
|
||||||
u_int requestLength = sizeof(request) / sizeof(*request);
|
|
||||||
|
|
||||||
size_t length = 0;
|
|
||||||
FF_AUTO_FREE struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
|
|
||||||
if(processes == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < length / sizeof(struct kinfo_proc); i++)
|
|
||||||
{
|
|
||||||
const char* comm = processes[i].kp_proc.p_comm;
|
|
||||||
|
|
||||||
if(
|
|
||||||
strcasecmp(comm, "spectacle") != 0 &&
|
|
||||||
strcasecmp(comm, "amethyst") != 0 &&
|
|
||||||
strcasecmp(comm, "kwm") != 0 &&
|
|
||||||
strcasecmp(comm, "chunkwm") != 0 &&
|
|
||||||
strcasecmp(comm, "yabai") != 0 &&
|
|
||||||
strcasecmp(comm, "rectangle") != 0
|
|
||||||
) continue;
|
|
||||||
|
|
||||||
ffStrbufAppendS(name, comm);
|
|
||||||
name->chars[0] = (char) toupper(name->chars[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -116,18 +84,8 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
|||||||
}
|
}
|
||||||
ffStrbufInit(&ds->wmProtocolName);
|
ffStrbufInit(&ds->wmProtocolName);
|
||||||
|
|
||||||
if(instance.config.allowSlowOperations)
|
|
||||||
{
|
|
||||||
FF_STRBUF_AUTO_DESTROY name;
|
|
||||||
ffStrbufInit(&name);
|
|
||||||
detectWMPlugin(&name);
|
|
||||||
if(name.length)
|
|
||||||
ffStrbufAppendF(&ds->wmPrettyName, " (with %s)", name.chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
ffStrbufInit(&ds->deProcessName);
|
ffStrbufInit(&ds->deProcessName);
|
||||||
ffStrbufInitStatic(&ds->dePrettyName, "Aqua");
|
ffStrbufInitStatic(&ds->dePrettyName, "Aqua");
|
||||||
ffStrbufInit(&ds->deVersion);
|
|
||||||
|
|
||||||
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
||||||
detectDisplays(ds);
|
detectDisplays(ds);
|
||||||
|
|||||||
@@ -143,20 +143,21 @@ static void detectDisplays(FFDisplayServerResult* ds)
|
|||||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||||
{
|
{
|
||||||
BOOL enabled;
|
BOOL enabled;
|
||||||
if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled == TRUE)
|
if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||||
{
|
{
|
||||||
ffStrbufInitStatic(&ds->wmProcessName, "dwm.exe");
|
ffStrbufInitStatic(&ds->wmProcessName, "dwm.exe");
|
||||||
ffStrbufInitStatic(&ds->wmPrettyName, "Desktop Window Manager");
|
ffStrbufInitStatic(&ds->wmPrettyName, "Desktop Window Manager");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// `explorer.exe` only provides a subset of WM functions, as well as the taskbar and desktop icons.
|
||||||
|
// While a window itself is drawn by kernel (GDI). Killing `explorer.exe` won't affect how windows are displayed generally.
|
||||||
ffStrbufInitStatic(&ds->wmProcessName, "explorer.exe");
|
ffStrbufInitStatic(&ds->wmProcessName, "explorer.exe");
|
||||||
ffStrbufInitStatic(&ds->wmPrettyName, "Windows Explorer");
|
ffStrbufInitStatic(&ds->wmPrettyName, "Internal");
|
||||||
}
|
}
|
||||||
ffStrbufInit(&ds->wmProtocolName);
|
ffStrbufInit(&ds->wmProtocolName);
|
||||||
ffStrbufInit(&ds->deProcessName);
|
ffStrbufInit(&ds->deProcessName);
|
||||||
ffStrbufInit(&ds->dePrettyName);
|
ffStrbufInit(&ds->dePrettyName);
|
||||||
ffStrbufInit(&ds->deVersion);
|
|
||||||
ffListInit(&ds->displays, sizeof(FFDisplayResult));
|
ffListInit(&ds->displays, sizeof(FFDisplayResult));
|
||||||
|
|
||||||
detectDisplays(ds);
|
detectDisplays(ds);
|
||||||
|
|||||||
@@ -85,10 +85,9 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
|||||||
ffStrbufInit(&ds->wmProtocolName);
|
ffStrbufInit(&ds->wmProtocolName);
|
||||||
ffStrbufInit(&ds->deProcessName);
|
ffStrbufInit(&ds->deProcessName);
|
||||||
ffStrbufInit(&ds->dePrettyName);
|
ffStrbufInit(&ds->dePrettyName);
|
||||||
ffStrbufInit(&ds->deVersion);
|
|
||||||
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
||||||
|
|
||||||
if (!instance.config.dsForceDrm)
|
if (!instance.config.general.dsForceDrm)
|
||||||
{
|
{
|
||||||
//We try wayland as our prefered display server, as it supports the most features.
|
//We try wayland as our prefered display server, as it supports the most features.
|
||||||
//This method can't detect the name of our WM / DE
|
//This method can't detect the name of our WM / DE
|
||||||
|
|||||||
@@ -202,9 +202,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
|
|||||||
if(display.width <= 0 || display.height <= 0)
|
if(display.width <= 0 || display.height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
|
|
||||||
switch(display.transform)
|
switch(display.transform)
|
||||||
{
|
{
|
||||||
case WL_OUTPUT_TRANSFORM_90:
|
case WL_OUTPUT_TRANSFORM_90:
|
||||||
@@ -262,8 +259,6 @@ static void waylandOutputHandler(WaylandData* wldata, struct wl_registry* regist
|
|||||||
ffStrbufDestroy(&display.vendorAndModelId);
|
ffStrbufDestroy(&display.vendorAndModelId);
|
||||||
ffStrbufDestroy(&display.name);
|
ffStrbufDestroy(&display.name);
|
||||||
ffStrbufDestroy(&display.edidName);
|
ffStrbufDestroy(&display.edidName);
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void waylandGlobalAddListener(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
|
static void waylandGlobalAddListener(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
|
||||||
@@ -276,7 +271,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
|||||||
|
|
||||||
bool detectWayland(FFDisplayServerResult* result)
|
bool detectWayland(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(wayland, &instance.config.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
|
FF_LIBRARY_LOAD(wayland, &instance.config.library.libWayland, false, "libwayland-client" FF_LIBRARY_EXTENSION, 1)
|
||||||
|
|
||||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
|
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
|
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "displayserver_linux.h"
|
#include "displayserver_linux.h"
|
||||||
#include "common/io/io.h"
|
#include "common/io/io.h"
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/parsing.h"
|
|
||||||
#include "common/processing.h"
|
#include "common/processing.h"
|
||||||
#include "util/stringUtils.h"
|
#include "util/stringUtils.h"
|
||||||
|
|
||||||
@@ -131,177 +130,6 @@ static void applyBetterWM(FFDisplayServerResult* result, const char* processName
|
|||||||
ffStrbufAppend(&result->wmPrettyName, &result->wmProcessName);
|
ffStrbufAppend(&result->wmPrettyName, &result->wmProcessName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getKDE(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "plasmashell");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
|
|
||||||
|
|
||||||
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
|
|
||||||
{"X-KDE-PluginInfo-Version =", &result->deVersion}
|
|
||||||
});
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
{
|
|
||||||
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
|
|
||||||
{"X-KDE-PluginInfo-Version =", &result->deVersion}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
|
||||||
|
|
||||||
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
|
|
||||||
{
|
|
||||||
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
|
|
||||||
"plasmashell",
|
|
||||||
"--version",
|
|
||||||
NULL
|
|
||||||
}) == NULL) // plasmashell 5.27.5
|
|
||||||
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
applyBetterWM(result, getenv("KDEWM"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getGnome(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "gnome-shell");
|
|
||||||
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
|
|
||||||
if (sessionMode && ffStrEquals(sessionMode, "classic"))
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC);
|
|
||||||
else
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_GNOME);
|
|
||||||
|
|
||||||
ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", &result->deVersion);
|
|
||||||
|
|
||||||
if (result->deVersion.length == 0)
|
|
||||||
{
|
|
||||||
if (ffProcessAppendStdOut(&result->deVersion, (char* const[]){
|
|
||||||
"gnome-shell",
|
|
||||||
"--version",
|
|
||||||
NULL
|
|
||||||
}) == NULL) // GNOME Shell 44.1
|
|
||||||
ffStrbufSubstrAfterLastC(&result->deVersion, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getCinnamon(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "cinnamon");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
|
|
||||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", &result->deVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getMate(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "mate-session");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
|
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate();
|
|
||||||
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
|
|
||||||
FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate();
|
|
||||||
|
|
||||||
ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) {
|
|
||||||
{"<platform>", &major},
|
|
||||||
{"<minor>", &minor},
|
|
||||||
{"<micro>", µ}
|
|
||||||
});
|
|
||||||
|
|
||||||
ffParseSemver(&result->deVersion, &major, &minor, µ);
|
|
||||||
|
|
||||||
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
|
|
||||||
{
|
|
||||||
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
|
|
||||||
"mate-session",
|
|
||||||
"--version",
|
|
||||||
NULL
|
|
||||||
});
|
|
||||||
|
|
||||||
ffStrbufSubstrAfterFirstC(&result->deVersion, ' ');
|
|
||||||
ffStrbufTrim(&result->deVersion, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getXFCE4(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "xfce4-session");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
|
|
||||||
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", &result->deVersion);
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
{
|
|
||||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
|
|
||||||
if (dirp)
|
|
||||||
{
|
|
||||||
struct dirent* entry;
|
|
||||||
while((entry = readdir(dirp)) != NULL)
|
|
||||||
{
|
|
||||||
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
|
|
||||||
continue;
|
|
||||||
ffStrbufAppendS(&result->deVersion, &entry->d_name[5]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
|
|
||||||
{
|
|
||||||
//This is somewhat slow
|
|
||||||
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
|
|
||||||
"xfce4-session",
|
|
||||||
"--version",
|
|
||||||
NULL
|
|
||||||
});
|
|
||||||
|
|
||||||
ffStrbufSubstrBeforeFirstC(&result->deVersion, '(');
|
|
||||||
ffStrbufSubstrAfterFirstC(&result->deVersion, ' ');
|
|
||||||
ffStrbufTrim(&result->deVersion, ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getLXQt(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
|
|
||||||
ffParsePropFileData("gconfig/lxqt.pc", "Version:", &result->deVersion);
|
|
||||||
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", &result->deVersion);
|
|
||||||
if(result->deVersion.length == 0)
|
|
||||||
ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", &result->deVersion);
|
|
||||||
|
|
||||||
if(result->deVersion.length == 0 && instance.config.allowSlowOperations)
|
|
||||||
{
|
|
||||||
//This is really, really, really slow. Thank you, LXQt developers
|
|
||||||
ffProcessAppendStdOut(&result->deVersion, (char* const[]){
|
|
||||||
"lxqt-session",
|
|
||||||
"-v",
|
|
||||||
NULL
|
|
||||||
});
|
|
||||||
|
|
||||||
result->deVersion.length = 0; //don't set '\0' byte
|
|
||||||
ffParsePropLines(result->deVersion.chars , "liblxqt", &result->deVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate();
|
|
||||||
|
|
||||||
ffParsePropFileConfig("lxqt/session.conf", "window_manager =", &wmProcessNameBuffer);
|
|
||||||
applyBetterWM(result, wmProcessNameBuffer.chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getBudgie(FFDisplayServerResult* result)
|
|
||||||
{
|
|
||||||
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
|
|
||||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
|
|
||||||
ffParsePropFileData("budgie/budgie-version.xml", "<str>", &result->deVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||||
{
|
{
|
||||||
if(!ffStrSet(name))
|
if(!ffStrSet(name))
|
||||||
@@ -312,19 +140,33 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
strcasecmp(name, "plasma") == 0 ||
|
strcasecmp(name, "plasma") == 0 ||
|
||||||
strcasecmp(name, "plasmashell") == 0 ||
|
strcasecmp(name, "plasmashell") == 0 ||
|
||||||
strcasecmp(name, "plasmawayland") == 0
|
strcasecmp(name, "plasmawayland") == 0
|
||||||
) getKDE(result);
|
) {
|
||||||
|
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
|
||||||
|
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
|
||||||
|
applyBetterWM(result, getenv("KDEWM"));
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "Gnome") == 0 ||
|
strcasecmp(name, "Gnome") == 0 ||
|
||||||
strcasecmp(name, "ubuntu:GNOME") == 0 ||
|
strcasecmp(name, "ubuntu:GNOME") == 0 ||
|
||||||
strcasecmp(name, "ubuntu") == 0 ||
|
strcasecmp(name, "ubuntu") == 0 ||
|
||||||
strcasecmp(name, "gnome-shell") == 0
|
strcasecmp(name, "gnome-shell") == 0
|
||||||
) getGnome(result);
|
) {
|
||||||
|
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
|
||||||
|
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
|
||||||
|
if (sessionMode && ffStrEquals(sessionMode, "classic"))
|
||||||
|
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC);
|
||||||
|
else
|
||||||
|
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_GNOME);
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "X-Cinnamon") == 0 ||
|
strcasecmp(name, "X-Cinnamon") == 0 ||
|
||||||
strcasecmp(name, "Cinnamon") == 0
|
strcasecmp(name, "Cinnamon") == 0
|
||||||
) getCinnamon(result);
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "cinnamon");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "XFCE") == 0 ||
|
strcasecmp(name, "XFCE") == 0 ||
|
||||||
@@ -332,26 +174,41 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
|||||||
strcasecmp(name, "XFCE4") == 0 ||
|
strcasecmp(name, "XFCE4") == 0 ||
|
||||||
strcasecmp(name, "X-XFCE4") == 0 ||
|
strcasecmp(name, "X-XFCE4") == 0 ||
|
||||||
strcasecmp(name, "xfce4-session") == 0
|
strcasecmp(name, "xfce4-session") == 0
|
||||||
) getXFCE4(result);
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "xfce4-session");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "MATE") == 0 ||
|
strcasecmp(name, "MATE") == 0 ||
|
||||||
strcasecmp(name, "X-MATE") == 0 ||
|
strcasecmp(name, "X-MATE") == 0 ||
|
||||||
strcasecmp(name, "mate-session") == 0
|
strcasecmp(name, "mate-session") == 0
|
||||||
) getMate(result);
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "mate-session");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "LXQt") == 0 ||
|
strcasecmp(name, "LXQt") == 0 ||
|
||||||
strcasecmp(name, "X-LXQT") == 0 ||
|
strcasecmp(name, "X-LXQT") == 0 ||
|
||||||
strcasecmp(name, "lxqt-session") == 0
|
strcasecmp(name, "lxqt-session") == 0
|
||||||
) getLXQt(result);
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
|
||||||
|
FF_STRBUF_AUTO_DESTROY wmProcessNameBuffer = ffStrbufCreate();
|
||||||
|
ffParsePropFileConfig("lxqt/session.conf", "window_manager =", &wmProcessNameBuffer);
|
||||||
|
applyBetterWM(result, wmProcessNameBuffer.chars);
|
||||||
|
}
|
||||||
|
|
||||||
else if(
|
else if(
|
||||||
strcasecmp(name, "Budgie") == 0 ||
|
strcasecmp(name, "Budgie") == 0 ||
|
||||||
strcasecmp(name, "X-Budgie") == 0 ||
|
strcasecmp(name, "X-Budgie") == 0 ||
|
||||||
strcasecmp(name, "budgie-desktop") == 0 ||
|
strcasecmp(name, "budgie-desktop") == 0 ||
|
||||||
strcasecmp(name, "Budgie:GNOME") == 0
|
strcasecmp(name, "Budgie:GNOME") == 0
|
||||||
) getBudgie(result);
|
) {
|
||||||
|
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
|
||||||
|
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
|
|||||||
|
|
||||||
void ffdsConnectXcb(FFDisplayServerResult* result)
|
void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(xcb, &instance.config.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2)
|
FF_LIBRARY_LOAD(xcb, &instance.config.library.libXcb, , "libxcb" FF_LIBRARY_EXTENSION, 2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
|
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
|
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
|
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
|
||||||
@@ -429,7 +429,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
|||||||
|
|
||||||
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(xcbRandr, &instance.config.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
FF_LIBRARY_LOAD(xcbRandr, &instance.config.library.libXcbRandr, , "libxcb-randr" FF_LIBRARY_EXTENSION, 1)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
|
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
|
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
|
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
|
|||||||
|
|
||||||
void ffdsConnectXlib(FFDisplayServerResult* result)
|
void ffdsConnectXlib(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(x11, &instance.config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
|
FF_LIBRARY_LOAD(x11, &instance.config.library.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
|
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
|
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
|||||||
|
|
||||||
void ffdsConnectXrandr(FFDisplayServerResult* result)
|
void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(xrandr, &instance.config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
FF_LIBRARY_LOAD(xrandr, &instance.config.library.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
||||||
|
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
|
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
|
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
|
|||||||
const char* FF_GPU_VENDOR_NAME_AMD = "AMD";
|
const char* FF_GPU_VENDOR_NAME_AMD = "AMD";
|
||||||
const char* FF_GPU_VENDOR_NAME_INTEL = "Intel";
|
const char* FF_GPU_VENDOR_NAME_INTEL = "Intel";
|
||||||
const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA";
|
const char* FF_GPU_VENDOR_NAME_NVIDIA = "NVIDIA";
|
||||||
|
const char* FF_GPU_VENDOR_NAME_VMWARE = "VMware";
|
||||||
|
const char* FF_GPU_VENDOR_NAME_PARALLEL = "Parallel";
|
||||||
|
const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft";
|
||||||
|
const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat";
|
||||||
|
const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle";
|
||||||
|
|
||||||
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
|
static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsigned length)
|
||||||
{
|
{
|
||||||
@@ -19,6 +24,7 @@ static inline bool arrayContains(const unsigned arr[], unsigned vendorId, unsign
|
|||||||
|
|
||||||
const char* ffGetGPUVendorString(unsigned vendorId)
|
const char* ffGetGPUVendorString(unsigned vendorId)
|
||||||
{
|
{
|
||||||
|
// https://devicehunt.com/all-pci-vendors
|
||||||
if(vendorId == 0x106b)
|
if(vendorId == 0x106b)
|
||||||
return FF_GPU_VENDOR_NAME_APPLE;
|
return FF_GPU_VENDOR_NAME_APPLE;
|
||||||
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
|
if(arrayContains((const unsigned[]) {0x1002, 0x1022}, vendorId, 2))
|
||||||
@@ -27,6 +33,16 @@ const char* ffGetGPUVendorString(unsigned vendorId)
|
|||||||
return FF_GPU_VENDOR_NAME_INTEL;
|
return FF_GPU_VENDOR_NAME_INTEL;
|
||||||
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
|
else if(arrayContains((const unsigned[]) {0x0955, 0x10de, 0x12d2}, vendorId, 3))
|
||||||
return FF_GPU_VENDOR_NAME_NVIDIA;
|
return FF_GPU_VENDOR_NAME_NVIDIA;
|
||||||
|
else if(arrayContains((const unsigned[]) {0x15ad}, vendorId, 1))
|
||||||
|
return FF_GPU_VENDOR_NAME_VMWARE;
|
||||||
|
else if(arrayContains((const unsigned[]) {0x1af4}, vendorId, 1))
|
||||||
|
return FF_GPU_VENDOR_NAME_REDHAT;
|
||||||
|
else if(arrayContains((const unsigned[]) {0x1ab8}, vendorId, 1))
|
||||||
|
return FF_GPU_VENDOR_NAME_PARALLEL;
|
||||||
|
else if(arrayContains((const unsigned[]) {0x1414}, vendorId, 1))
|
||||||
|
return FF_GPU_VENDOR_NAME_MICROSOFT;
|
||||||
|
else if(arrayContains((const unsigned[]) {0x108e}, vendorId, 1))
|
||||||
|
return FF_GPU_VENDOR_NAME_ORACLE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ extern const char* FF_GPU_VENDOR_NAME_APPLE;
|
|||||||
extern const char* FF_GPU_VENDOR_NAME_AMD;
|
extern const char* FF_GPU_VENDOR_NAME_AMD;
|
||||||
extern const char* FF_GPU_VENDOR_NAME_INTEL;
|
extern const char* FF_GPU_VENDOR_NAME_INTEL;
|
||||||
extern const char* FF_GPU_VENDOR_NAME_NVIDIA;
|
extern const char* FF_GPU_VENDOR_NAME_NVIDIA;
|
||||||
|
extern const char* FF_GPU_VENDOR_NAME_VMWARE;
|
||||||
|
extern const char* FF_GPU_VENDOR_NAME_PARALLEL;
|
||||||
|
extern const char* FF_GPU_VENDOR_NAME_MICROSOFT;
|
||||||
|
extern const char* FF_GPU_VENDOR_NAME_REDHAT;
|
||||||
|
extern const char* FF_GPU_VENDOR_NAME_ORACLE;
|
||||||
|
|
||||||
typedef struct FFGPUMemory
|
typedef struct FFGPUMemory
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#include "detection/gpu/gpu.h"
|
#include "detection/gpu/gpu.h"
|
||||||
|
#include "detection/gpu/gpu_nvidia.h"
|
||||||
#include "detection/vulkan/vulkan.h"
|
#include "detection/vulkan/vulkan.h"
|
||||||
|
|
||||||
#ifdef FF_HAVE_LIBPCI
|
#ifdef FF_HAVE_LIBPCI
|
||||||
|
#include "common/io/io.h"
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
@@ -35,7 +37,7 @@ typedef struct PCIData
|
|||||||
|
|
||||||
static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
||||||
{
|
{
|
||||||
ffStrbufAppendS(&gpu->vendor, ffGetGPUVendorString(device->vendor_id));
|
ffStrbufSetStatic(&gpu->vendor, ffGetGPUVendorString(device->vendor_id));
|
||||||
|
|
||||||
if(gpu->vendor.length > 0)
|
if(gpu->vendor.length > 0)
|
||||||
return;
|
return;
|
||||||
@@ -45,11 +47,11 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
|||||||
ffStrbufRecalculateLength(&gpu->vendor);
|
ffStrbufRecalculateLength(&gpu->vendor);
|
||||||
|
|
||||||
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||||
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
|
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||||
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device)
|
||||||
@@ -110,34 +112,36 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
|||||||
#if PCI_LIB_VERSION >= 0x030800
|
#if PCI_LIB_VERSION >= 0x030800
|
||||||
pci->ffpci_fill_info(device, PCI_FILL_DRIVER);
|
pci->ffpci_fill_info(device, PCI_FILL_DRIVER);
|
||||||
ffStrbufAppendS(&gpu->driver, pci->ffpci_get_string_property(device, PCI_FILL_DRIVER));
|
ffStrbufAppendS(&gpu->driver, pci->ffpci_get_string_property(device, PCI_FILL_DRIVER));
|
||||||
|
|
||||||
if(gpu->driver.length > 0)
|
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
|
const char* base = pci->ffpci_get_param(pci->access, "sysfs.path");
|
||||||
if(!ffStrSet(base))
|
if(!ffStrSet(base))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func);
|
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateF("%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func);
|
||||||
ffStrbufEnsureFree(&gpu->driver, 1023);
|
if (gpu->driver.length == 0)
|
||||||
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
|
|
||||||
if(resultLength > 0)
|
|
||||||
{
|
{
|
||||||
gpu->driver.length = (uint32_t) resultLength;
|
ffStrbufEnsureFree(&gpu->driver, 1023);
|
||||||
gpu->driver.chars[resultLength] = '\0';
|
ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator
|
||||||
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
|
if(resultLength > 0)
|
||||||
|
{
|
||||||
|
gpu->driver.length = (uint32_t) resultLength;
|
||||||
|
gpu->driver.chars[resultLength] = '\0';
|
||||||
|
ffStrbufSubstrAfterLastC(&gpu->driver, '/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffStrbufAppendC(&gpu->driver, ' ');
|
||||||
|
ffStrbufAppendS(&path, "/module/version");
|
||||||
|
ffAppendFileBuffer(path.chars, &gpu->driver);
|
||||||
|
ffStrbufTrimRight(&gpu->driver, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* device)
|
FF_MAYBE_UNUSED static void pciDetectTemp(FFGPUResult* gpu, struct pci_dev* device)
|
||||||
{
|
{
|
||||||
const FFTempsResult* tempsResult = ffDetectTemps();
|
const FFlist* tempsResult = ffDetectTemps();
|
||||||
|
|
||||||
for(uint32_t i = 0; i < tempsResult->values.length; i++)
|
FF_LIST_FOR_EACH(FFTempValue, tempValue, *tempsResult)
|
||||||
{
|
{
|
||||||
FFTempValue* tempValue = ffListGet(&tempsResult->values, i);
|
|
||||||
|
|
||||||
//The kernel exposes the device class multiplied by 256 for some reason
|
//The kernel exposes the device class multiplied by 256 for some reason
|
||||||
if(tempValue->deviceClass == device->device_class * 256)
|
if(tempValue->deviceClass == device->device_class * 256)
|
||||||
{
|
{
|
||||||
@@ -236,8 +240,23 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
|||||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||||
|
|
||||||
|
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->useNvml))
|
||||||
|
{
|
||||||
|
char pciDeviceId[32];
|
||||||
|
snprintf(pciDeviceId, sizeof(pciDeviceId) - 1, "%04x:%02x:%02x.%d", device->domain, device->bus, device->dev, device->func);
|
||||||
|
|
||||||
|
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) { .pciBusId = pciDeviceId }, (FFGpuNvidiaResult) {
|
||||||
|
.temp = options->temp ? &gpu->temperature : NULL,
|
||||||
|
.memory = options->useNvml ? &gpu->dedicated : NULL,
|
||||||
|
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
|
||||||
|
}, "libnvidia-ml.so");
|
||||||
|
|
||||||
|
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
|
||||||
|
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if(options->temp)
|
if(options->temp && gpu->temperature != gpu->temperature)
|
||||||
pciDetectTemp(gpu, device);
|
pciDetectTemp(gpu, device);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -270,7 +289,7 @@ static const char* pciDetectGPUs(const FFGPUOptions* options, FFlist* gpus)
|
|||||||
{
|
{
|
||||||
PCIData pci;
|
PCIData pci;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(libpci, &instance.config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
|
FF_LIBRARY_LOAD(libpci, &instance.config.library.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#include "gpu_nvidia.h"
|
||||||
|
|
||||||
|
#include "3rdparty/nvml/nvml.h"
|
||||||
|
#include "common/library.h"
|
||||||
|
|
||||||
|
struct FFNvmlData {
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetCount_v2)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByIndex_v2)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByPciBusId_v2)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2)
|
||||||
|
FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores)
|
||||||
|
|
||||||
|
bool inited;
|
||||||
|
} nvmlData;
|
||||||
|
|
||||||
|
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result, const char* soName)
|
||||||
|
{
|
||||||
|
if (!nvmlData.inited)
|
||||||
|
{
|
||||||
|
nvmlData.inited = true;
|
||||||
|
FF_LIBRARY_LOAD(libnvml, NULL, "dlopen nvml failed", soName , 1);
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetCount_v2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByIndex_v2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByPciBusId_v2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2)
|
||||||
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores)
|
||||||
|
|
||||||
|
if (ffnvmlInit_v2() != NVML_SUCCESS)
|
||||||
|
{
|
||||||
|
nvmlData.ffnvmlDeviceGetNumGpuCores = NULL;
|
||||||
|
return "nvmlInit_v2() failed";
|
||||||
|
}
|
||||||
|
atexit((void*) ffnvmlShutdown);
|
||||||
|
libnvml = NULL; // don't close nvml
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nvmlData.ffnvmlDeviceGetNumGpuCores == NULL)
|
||||||
|
return "loading nvml library failed";
|
||||||
|
|
||||||
|
nvmlDevice_t device = NULL;
|
||||||
|
if (cond.pciBusId)
|
||||||
|
{
|
||||||
|
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(cond.pciBusId, &device);
|
||||||
|
if (ret != NVML_SUCCESS)
|
||||||
|
return "nvmlDeviceGetHandleByPciBusId_v2() failed";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32_t count;
|
||||||
|
if (nvmlData.ffnvmlDeviceGetCount_v2(&count) != NVML_SUCCESS)
|
||||||
|
return "nvmlDeviceGetCount_v2() failed";
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < count; i++, device = NULL)
|
||||||
|
{
|
||||||
|
if (nvmlData.ffnvmlDeviceGetHandleByIndex_v2(i, &device) != NVML_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nvmlPciInfo_t pciInfo;
|
||||||
|
if (nvmlData.ffnvmlDeviceGetPciInfo_v3(device, &pciInfo) != NVML_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pciInfo.pciDeviceId != cond.pciDeviceId || pciInfo.pciSubSystemId != cond.pciSubSystemId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!device) return "Device not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.temp)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) == NVML_SUCCESS)
|
||||||
|
*result.temp = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.memory)
|
||||||
|
{
|
||||||
|
nvmlMemory_v2_t memory = { .version = nvmlMemory_v2 };
|
||||||
|
if (nvmlData.ffnvmlDeviceGetMemoryInfo_v2(device, &memory) == NVML_SUCCESS)
|
||||||
|
{
|
||||||
|
result.memory->total = memory.used + memory.free;
|
||||||
|
result.memory->used = memory.used;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.coreCount)
|
||||||
|
nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gpu.h"
|
||||||
|
|
||||||
|
// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise
|
||||||
|
typedef struct FFGpuNvidiaCondition
|
||||||
|
{
|
||||||
|
// "domain:bus:device.function"
|
||||||
|
const char* pciBusId;
|
||||||
|
// (deviceId << 16) | vendorId
|
||||||
|
uint32_t pciDeviceId;
|
||||||
|
uint32_t pciSubSystemId;
|
||||||
|
} FFGpuNvidiaCondition;
|
||||||
|
|
||||||
|
// detect x if not NULL
|
||||||
|
typedef struct FFGpuNvidiaResult
|
||||||
|
{
|
||||||
|
double* temp;
|
||||||
|
FFGPUMemory* memory;
|
||||||
|
uint32_t* coreCount;
|
||||||
|
} FFGpuNvidiaResult;
|
||||||
|
|
||||||
|
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result, const char* soName);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "gpu.h"
|
#include "gpu.h"
|
||||||
|
#include "detection/gpu/gpu_nvidia.h"
|
||||||
#include "util/windows/unicode.h"
|
#include "util/windows/unicode.h"
|
||||||
#include "util/windows/registry.h"
|
#include "util/windows/registry.h"
|
||||||
|
|
||||||
@@ -12,9 +13,11 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
|
|||||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||||
{
|
{
|
||||||
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) };
|
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(displayDevice) };
|
||||||
wchar_t regKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{";
|
wchar_t regDirectxKey[MAX_PATH] = L"SOFTWARE\\Microsoft\\DirectX\\{";
|
||||||
const uint32_t regKeyPrefixLength = (uint32_t) wcslen(regKey);
|
const uint32_t regDirectxKeyPrefixLength = (uint32_t) wcslen(regDirectxKey);
|
||||||
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\") + regKeyPrefixLength;
|
wchar_t regControlVideoKey[MAX_PATH] = L"SYSTEM\\CurrentControlSet\\Control\\Video\\{";
|
||||||
|
const uint32_t regControlVideoKeyPrefixLength = (uint32_t) wcslen(regControlVideoKey);
|
||||||
|
const uint32_t deviceKeyPrefixLength = strlen("\\Registry\\Machine\\") + regControlVideoKeyPrefixLength;
|
||||||
|
|
||||||
for (DWORD i = 0; EnumDisplayDevicesW(NULL, i, &displayDevice, 0); ++i)
|
for (DWORD i = 0; EnumDisplayDevicesW(NULL, i, &displayDevice, 0); ++i)
|
||||||
{
|
{
|
||||||
@@ -43,27 +46,61 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
|||||||
|
|
||||||
if (deviceKeyLength == 100 && displayDevice.DeviceKey[deviceKeyPrefixLength - 1] == '{')
|
if (deviceKeyLength == 100 && displayDevice.DeviceKey[deviceKeyPrefixLength - 1] == '{')
|
||||||
{
|
{
|
||||||
wmemcpy(regKey + regKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, 100 - regKeyPrefixLength + 1);
|
wmemcpy(regControlVideoKey + regControlVideoKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, strlen("00000000-0000-0000-0000-000000000000}\\0000"));
|
||||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||||
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regKey, &hKey, NULL)) continue;
|
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regControlVideoKey, &hKey, NULL)) continue;
|
||||||
|
|
||||||
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
|
ffRegReadStrbuf(hKey, L"DriverVersion", &gpu->driver, NULL);
|
||||||
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);
|
ffRegReadStrbuf(hKey, L"ProviderName", &gpu->vendor, NULL);
|
||||||
|
|
||||||
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
if(ffStrbufContainS(&gpu->vendor, "AMD") || ffStrbufContainS(&gpu->vendor, "ATI"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||||
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
|
else if(ffStrbufContainS(&gpu->vendor, "Intel"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||||
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
else if(ffStrbufContainS(&gpu->vendor, "NVIDIA"))
|
||||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
ffStrbufSetStatic(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||||
|
|
||||||
if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
|
wmemcpy(regDirectxKey + regDirectxKeyPrefixLength, displayDevice.DeviceKey + deviceKeyPrefixLength, strlen("00000000-0000-0000-0000-000000000000}"));
|
||||||
|
FF_HKEY_AUTO_DESTROY hDirectxKey = NULL;
|
||||||
|
if (ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, regDirectxKey, &hDirectxKey, NULL))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ffRegReadUint64(hKey, L"HardwareInformation.qwMemorySize", &gpu->dedicated.total, NULL))
|
||||||
{
|
{
|
||||||
uint32_t vmem = 0;
|
uint32_t vmem = 0;
|
||||||
if (ffRegReadUint(hKey, L"HardwareInformation.MemorySize", &vmem, NULL))
|
if (ffRegReadUint(hKey, L"HardwareInformation.MemorySize", &vmem, NULL))
|
||||||
gpu->dedicated.total = vmem;
|
gpu->dedicated.total = vmem;
|
||||||
|
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->useNvml))
|
||||||
|
{
|
||||||
|
uint32_t vendorId, deviceId, subSystemId;
|
||||||
|
// See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html
|
||||||
|
// displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1"
|
||||||
|
if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x", &vendorId, &deviceId, &subSystemId) == 3)
|
||||||
|
{
|
||||||
|
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) {
|
||||||
|
.pciDeviceId = (deviceId << 16) | vendorId,
|
||||||
|
.pciSubSystemId = subSystemId,
|
||||||
|
}, (FFGpuNvidiaResult) {
|
||||||
|
.temp = options->temp ? &gpu->temperature : NULL,
|
||||||
|
.memory = options->useNvml ? &gpu->dedicated : NULL,
|
||||||
|
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
|
||||||
|
}, "nvml.dll");
|
||||||
}
|
}
|
||||||
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#include "common/library.h"
|
#include "common/library.h"
|
||||||
#include "detection/gpu/gpu.h"
|
#include "detection/gpu/gpu.h"
|
||||||
|
#include "detection/gpu/gpu_nvidia.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <wsl/winadapter.h>
|
#include <wsl/winadapter.h>
|
||||||
@@ -92,7 +93,20 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
|||||||
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, sizeof(hardwareId), &hardwareId)))
|
if (SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, sizeof(hardwareId), &hardwareId)))
|
||||||
{
|
{
|
||||||
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
|
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
|
||||||
ffStrbufAppendS(&gpu->vendor, vendorStr);
|
ffStrbufSetStatic(&gpu->vendor, vendorStr);
|
||||||
|
|
||||||
|
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && options->useNvml)
|
||||||
|
{
|
||||||
|
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) {
|
||||||
|
.pciBusId = nullptr,
|
||||||
|
.pciDeviceId = (hardwareId.deviceID << 16) | hardwareId.vendorID,
|
||||||
|
.pciSubSystemId = hardwareId.subSysID
|
||||||
|
}, (FFGpuNvidiaResult) {
|
||||||
|
.temp = options->temp ? &gpu->temperature : NULL,
|
||||||
|
.memory = options->useNvml ? &gpu->dedicated : NULL,
|
||||||
|
.coreCount = options->useNvml ? (uint32_t*) &gpu->coreCount : NULL,
|
||||||
|
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
|
|||||||
|
|
||||||
static void detectGTKFromSettings(FFGTKResult* result)
|
static void detectGTKFromSettings(FFGTKResult* result)
|
||||||
{
|
{
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
static const char* themeName = NULL;
|
static const char* themeName = NULL;
|
||||||
static const char* iconsName = NULL;
|
static const char* iconsName = NULL;
|
||||||
static const char* fontName = NULL;
|
static const char* fontName = NULL;
|
||||||
@@ -47,11 +45,8 @@ static void detectGTKFromSettings(FFGTKResult* result)
|
|||||||
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
|
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
|
|
||||||
if(init)
|
if(init)
|
||||||
{
|
{
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -103,7 +98,6 @@ static void detectGTKFromSettings(FFGTKResult* result)
|
|||||||
wallpaper = ffSettingsGet("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
wallpaper = ffSettingsGet("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,14 +172,10 @@ static void detectGTK(const char* version, FFGTKResult* result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FF_DETECT_GTK_IMPL(version) \
|
#define FF_DETECT_GTK_IMPL(version) \
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
|
||||||
static FFGTKResult result; \
|
static FFGTKResult result; \
|
||||||
static bool init = false; \
|
static bool init = false; \
|
||||||
ffThreadMutexLock(&mutex); \
|
if(init) \
|
||||||
if(init){ \
|
|
||||||
ffThreadMutexUnlock(&mutex);\
|
|
||||||
return &result; \
|
return &result; \
|
||||||
} \
|
|
||||||
init = true; \
|
init = true; \
|
||||||
ffStrbufInit(&result.theme); \
|
ffStrbufInit(&result.theme); \
|
||||||
ffStrbufInit(&result.icons); \
|
ffStrbufInit(&result.icons); \
|
||||||
@@ -194,7 +184,6 @@ static void detectGTK(const char* version, FFGTKResult* result)
|
|||||||
ffStrbufInit(&result.cursorSize); \
|
ffStrbufInit(&result.cursorSize); \
|
||||||
ffStrbufInit(&result.wallpaper); \
|
ffStrbufInit(&result.wallpaper); \
|
||||||
detectGTK(#version, &result); \
|
detectGTK(#version, &result); \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return &result;
|
return &result;
|
||||||
|
|
||||||
const FFGTKResult* ffDetectGTK2(void)
|
const FFGTKResult* ffDetectGTK2(void)
|
||||||
|
|||||||
@@ -138,14 +138,9 @@ const FFQtResult* ffDetectQt(void)
|
|||||||
{
|
{
|
||||||
static FFQtResult result;
|
static FFQtResult result;
|
||||||
|
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
if(init)
|
if(init)
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
init = true;
|
init = true;
|
||||||
|
|
||||||
ffStrbufInit(&result.widgetStyle);
|
ffStrbufInit(&result.widgetStyle);
|
||||||
@@ -161,6 +156,5 @@ const FFQtResult* ffDetectQt(void)
|
|||||||
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0)
|
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0)
|
||||||
detectLXQt(&result);
|
detectLXQt(&result);
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ static void getHostProductName(FFstrbuf* name)
|
|||||||
if(ffIsSmbiosValueSet(name))
|
if(ffIsSmbiosValueSet(name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ffReadFileBuffer("/sys/firmware/devicetree/base/banner-name", name);
|
||||||
|
if(ffIsSmbiosValueSet(name))
|
||||||
|
return;
|
||||||
|
|
||||||
//does a clear before the read
|
//does a clear before the read
|
||||||
ffReadFileBuffer("/tmp/sysinfo/model", name);
|
ffReadFileBuffer("/tmp/sysinfo/model", name);
|
||||||
if(ffIsSmbiosValueSet(name))
|
if(ffIsSmbiosValueSet(name))
|
||||||
|
|||||||
@@ -6,18 +6,12 @@
|
|||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
|
||||||
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
|
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
|
||||||
static ResultType result; \
|
static ResultType result; \
|
||||||
static bool init = false; \
|
static bool init = false; \
|
||||||
ffThreadMutexLock(&mutex); \
|
|
||||||
if(init) \
|
if(init) \
|
||||||
{ \
|
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return &result; \
|
return &result; \
|
||||||
} \
|
|
||||||
init = true; \
|
init = true; \
|
||||||
__VA_ARGS__; \
|
__VA_ARGS__; \
|
||||||
ffThreadMutexUnlock(&mutex); \
|
|
||||||
return &result; \
|
return &result; \
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ static const char* getSshdVersion(FFstrbuf* version)
|
|||||||
|
|
||||||
static const char* getSddmVersion(FFstrbuf* version)
|
static const char* getSddmVersion(FFstrbuf* version)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(zlib, &instance.config.libZ, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2)
|
FF_LIBRARY_LOAD(zlib, &instance.config.library.libZ, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzopen);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzopen)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzread);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzread)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzerror);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzerror)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose)
|
||||||
|
|
||||||
gzFile file = ffgzopen("/usr/share/man/man1/sddm.1.gz", "rb");
|
gzFile file = ffgzopen("/usr/share/man/man1/sddm.1.gz", "rb");
|
||||||
if (file == Z_NULL)
|
if (file == Z_NULL)
|
||||||
|
|||||||
@@ -80,8 +80,17 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
||||||
char addressBuffer[INET_ADDRSTRLEN];
|
char addressBuffer[INET_ADDRSTRLEN + 4];
|
||||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||||
|
|
||||||
|
struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
|
||||||
|
int cidr = __builtin_popcount(inet_netof(netmask->sin_addr));
|
||||||
|
if (cidr != 0)
|
||||||
|
{
|
||||||
|
size_t len = strlen(addressBuffer);
|
||||||
|
snprintf(addressBuffer + len, 4, "/%d", cidr);
|
||||||
|
}
|
||||||
|
|
||||||
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute);
|
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute);
|
||||||
}
|
}
|
||||||
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
else if (ifa->ifa_addr->sa_family == AF_INET6)
|
||||||
|
|||||||
@@ -105,8 +105,15 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
|||||||
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
|
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
|
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
|
||||||
char addressBuffer[INET_ADDRSTRLEN];
|
char addressBuffer[INET_ADDRSTRLEN + 4];
|
||||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||||
|
|
||||||
|
if (ifa->OnLinkPrefixLength)
|
||||||
|
{
|
||||||
|
size_t len = strlen(addressBuffer);
|
||||||
|
snprintf(addressBuffer + len, 4, "/%u", (unsigned) ifa->OnLinkPrefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
addNewIp(results, name, addressBuffer, AF_INET, newIp, isDefaultRoute);
|
addNewIp(results, name, addressBuffer, AF_INET, newIp, isDefaultRoute);
|
||||||
newIp = false;
|
newIp = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ static const char* getMedia(FFMediaResult* result)
|
|||||||
|
|
||||||
// FIXME: This is shared for both player and media module.
|
// FIXME: This is shared for both player and media module.
|
||||||
// However it uses an option in one specific module
|
// However it uses an option in one specific module
|
||||||
if(instance.config.playerName.length > 0)
|
if(instance.config.general.playerName.length > 0)
|
||||||
getCustomBus(&data, &instance.config.playerName, result);
|
getCustomBus(&data, &instance.config.general.playerName, result);
|
||||||
else
|
else
|
||||||
getBestBus(&data, result);
|
getBestBus(&data, result);
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const char* ffDetectOpenCL(FFOpenCLResult* result)
|
|||||||
|
|
||||||
OpenCLData data;
|
OpenCLData data;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(opencl, &instance.config.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
|
FF_LIBRARY_LOAD(opencl, &instance.config.library.libOpenCL, "dlopen libOpenCL"FF_LIBRARY_EXTENSION" failed",
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
"OpenCL"FF_LIBRARY_EXTENSION, -1,
|
"OpenCL"FF_LIBRARY_EXTENSION, -1,
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ static const char* eglPrint(FFOpenGLResult* result)
|
|||||||
{
|
{
|
||||||
EGLData eglData;
|
EGLData eglData;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(egl, &instance.config.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize);
|
||||||
@@ -239,7 +239,7 @@ static const char* glxPrint(FFOpenGLResult* result)
|
|||||||
{
|
{
|
||||||
GLXData data;
|
GLXData data;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(glx, &instance.config.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
|
FF_LIBRARY_LOAD(glx, &instance.config.library.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual);
|
||||||
@@ -303,7 +303,7 @@ static const char* osMesaPrint(FFOpenGLResult* result)
|
|||||||
{
|
{
|
||||||
OSMesaData data;
|
OSMesaData data;
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(osmesa, &instance.config.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
|
FF_LIBRARY_LOAD(osmesa, &instance.config.library.libOSMesa, "dlopen osmesa failed", "libOSMesa" FF_LIBRARY_EXTENSION, 8);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaGetProcAddress);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaCreateContext);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent);
|
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(osmesa, data, OSMesaMakeCurrent);
|
||||||
|
|||||||
+22
-22
@@ -35,10 +35,10 @@ static bool detectOSCodeName(FFOSResult* os)
|
|||||||
|
|
||||||
switch (num)
|
switch (num)
|
||||||
{
|
{
|
||||||
case 14: ffStrbufAppendS(&os->codename, "Sonoma"); return true;
|
case 14: ffStrbufSetStatic(&os->codename, "Sonoma"); return true;
|
||||||
case 13: ffStrbufAppendS(&os->codename, "Ventura"); return true;
|
case 13: ffStrbufSetStatic(&os->codename, "Ventura"); return true;
|
||||||
case 12: ffStrbufAppendS(&os->codename, "Monterey"); return true;
|
case 12: ffStrbufSetStatic(&os->codename, "Monterey"); return true;
|
||||||
case 11: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
|
case 11: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
|
||||||
case 10: {
|
case 10: {
|
||||||
version = str_end + 1;
|
version = str_end + 1;
|
||||||
num = strtoul(version, &str_end, 10);
|
num = strtoul(version, &str_end, 10);
|
||||||
@@ -46,23 +46,23 @@ static bool detectOSCodeName(FFOSResult* os)
|
|||||||
|
|
||||||
switch (num)
|
switch (num)
|
||||||
{
|
{
|
||||||
case 16: ffStrbufAppendS(&os->codename, "Big Sur"); return true;
|
case 16: ffStrbufSetStatic(&os->codename, "Big Sur"); return true;
|
||||||
case 15: ffStrbufAppendS(&os->codename, "Catalina"); return true;
|
case 15: ffStrbufSetStatic(&os->codename, "Catalina"); return true;
|
||||||
case 14: ffStrbufAppendS(&os->codename, "Mojave"); return true;
|
case 14: ffStrbufSetStatic(&os->codename, "Mojave"); return true;
|
||||||
case 13: ffStrbufAppendS(&os->codename, "High Sierra"); return true;
|
case 13: ffStrbufSetStatic(&os->codename, "High Sierra"); return true;
|
||||||
case 12: ffStrbufAppendS(&os->codename, "Sierra"); return true;
|
case 12: ffStrbufSetStatic(&os->codename, "Sierra"); return true;
|
||||||
case 11: ffStrbufAppendS(&os->codename, "El Capitan"); return true;
|
case 11: ffStrbufSetStatic(&os->codename, "El Capitan"); return true;
|
||||||
case 10: ffStrbufAppendS(&os->codename, "Yosemite"); return true;
|
case 10: ffStrbufSetStatic(&os->codename, "Yosemite"); return true;
|
||||||
case 9: ffStrbufAppendS(&os->codename, "Mavericks"); return true;
|
case 9: ffStrbufSetStatic(&os->codename, "Mavericks"); return true;
|
||||||
case 8: ffStrbufAppendS(&os->codename, "Mountain Lion"); return true;
|
case 8: ffStrbufSetStatic(&os->codename, "Mountain Lion"); return true;
|
||||||
case 7: ffStrbufAppendS(&os->codename, "Lion"); return true;
|
case 7: ffStrbufSetStatic(&os->codename, "Lion"); return true;
|
||||||
case 6: ffStrbufAppendS(&os->codename, "Snow Leopard"); return true;
|
case 6: ffStrbufSetStatic(&os->codename, "Snow Leopard"); return true;
|
||||||
case 5: ffStrbufAppendS(&os->codename, "Leopard"); return true;
|
case 5: ffStrbufSetStatic(&os->codename, "Leopard"); return true;
|
||||||
case 4: ffStrbufAppendS(&os->codename, "Tiger"); return true;
|
case 4: ffStrbufSetStatic(&os->codename, "Tiger"); return true;
|
||||||
case 3: ffStrbufAppendS(&os->codename, "Panther"); return true;
|
case 3: ffStrbufSetStatic(&os->codename, "Panther"); return true;
|
||||||
case 2: ffStrbufAppendS(&os->codename, "Jaguar"); return true;
|
case 2: ffStrbufSetStatic(&os->codename, "Jaguar"); return true;
|
||||||
case 1: ffStrbufAppendS(&os->codename, "Puma"); return true;
|
case 1: ffStrbufSetStatic(&os->codename, "Puma"); return true;
|
||||||
case 0: ffStrbufAppendS(&os->codename, "Cheetah"); return true;
|
case 0: ffStrbufSetStatic(&os->codename, "Cheetah"); return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ void ffDetectOSImpl(FFOSResult* os)
|
|||||||
parseSystemVersion(os);
|
parseSystemVersion(os);
|
||||||
|
|
||||||
if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS"))
|
if(ffStrbufStartsWithIgnCaseS(&os->name, "MacOS"))
|
||||||
ffStrbufAppendS(&os->id, "macos");
|
ffStrbufSetStatic(&os->id, "macos");
|
||||||
|
|
||||||
if(os->version.length == 0)
|
if(os->version.length == 0)
|
||||||
ffSysctlGetString("kern.osproductversion", &os->version);
|
ffSysctlGetString("kern.osproductversion", &os->version);
|
||||||
|
|||||||
@@ -133,13 +133,13 @@ static void getDebianVersion(FFOSResult* result)
|
|||||||
|
|
||||||
static void detectOS(FFOSResult* os)
|
static void detectOS(FFOSResult* os)
|
||||||
{
|
{
|
||||||
if(instance.config.osFile.length > 0)
|
if(instance.config.general.osFile.length > 0)
|
||||||
{
|
{
|
||||||
parseFile(instance.config.osFile.chars, os);
|
parseFile(instance.config.general.osFile.chars, os);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instance.config.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
|
if(instance.config.general.escapeBedrock && parseFile(FASTFETCH_TARGET_DIR_ROOT"/bedrock"FASTFETCH_TARGET_DIR_ETC"/bedrock-release", os))
|
||||||
{
|
{
|
||||||
if(os->id.length == 0)
|
if(os->id.length == 0)
|
||||||
ffStrbufAppendS(&os->id, "bedrock");
|
ffStrbufAppendS(&os->id, "bedrock");
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
void ffDetectPackagesImpl(FFPackagesResult* result);
|
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options);
|
||||||
|
|
||||||
const char* ffDetectPackages(FFPackagesResult* result)
|
const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options)
|
||||||
{
|
{
|
||||||
ffDetectPackagesImpl(result);
|
ffDetectPackagesImpl(result, options);
|
||||||
|
|
||||||
for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i)
|
for(uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i)
|
||||||
result->all += ((uint32_t *)result)[i];
|
result->all += ((uint32_t *)result)[i];
|
||||||
|
|||||||
@@ -36,6 +36,6 @@ typedef struct FFPackagesResult
|
|||||||
FFstrbuf pacmanBranch;
|
FFstrbuf pacmanBranch;
|
||||||
} FFPackagesResult;
|
} FFPackagesResult;
|
||||||
|
|
||||||
const char* ffDetectPackages(FFPackagesResult* result);
|
const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ static uint32_t getMacPortsPackages()
|
|||||||
return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local");
|
return countMacPortsPackages(FASTFETCH_TARGET_DIR_ROOT"/opt/local");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffDetectPackagesImpl(FFPackagesResult* result)
|
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
|
||||||
{
|
{
|
||||||
getBrewPackages(result);
|
getBrewPackages(result);
|
||||||
result->port = getMacPortsPackages();
|
result->port = getMacPortsPackages();
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ static uint32_t getFlatpak(FFstrbuf* baseDir, const char* dirname)
|
|||||||
|
|
||||||
static uint32_t getRpmFromLibrpm(void)
|
static uint32_t getRpmFromLibrpm(void)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(rpm, &instance.config.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
|
FF_LIBRARY_LOAD(rpm, &instance.config.library.librpm, 0, "librpm" FF_LIBRARY_EXTENSION, 12)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
|
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
|
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
|
||||||
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
|
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
|
||||||
@@ -327,7 +327,7 @@ static void getPackageCountsBedrock(FFstrbuf* baseDir, FFPackagesResult* package
|
|||||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffDetectPackagesImpl(FFPackagesResult* result)
|
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
|
||||||
{
|
{
|
||||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(512);
|
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(512);
|
||||||
ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT);
|
ffStrbufAppendS(&baseDir, FASTFETCH_TARGET_DIR_ROOT);
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ static void detectWinget(FFPackagesResult* result)
|
|||||||
result->winget = count;
|
result->winget = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ffDetectPackagesImpl(FFPackagesResult* result)
|
void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
|
||||||
{
|
{
|
||||||
detectScoop(result);
|
detectScoop(result);
|
||||||
detectChoco(result);
|
detectChoco(result);
|
||||||
detectPacman(result);
|
detectPacman(result);
|
||||||
if (instance.config.allowSlowOperations)
|
if (options->winget)
|
||||||
detectWinget(result);
|
detectWinget(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,14 +49,23 @@ const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */)
|
|||||||
}, 0, NULL, &dataSize) == kAudioHardwareNoError && dataSize > 0)
|
}, 0, NULL, &dataSize) == kAudioHardwareNoError && dataSize > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint32_t connected;
|
uint32_t dataSource;
|
||||||
dataSize = sizeof(connected);
|
dataSize = sizeof(dataSource);
|
||||||
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
|
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
|
||||||
kAudioDevicePropertyJackIsConnected,
|
kAudioDevicePropertyDataSource,
|
||||||
kAudioObjectPropertyScopeOutput,
|
kAudioObjectPropertyScopeOutput,
|
||||||
kAudioObjectPropertyElementMain
|
kAudioObjectPropertyElementMain
|
||||||
}, 0, NULL, &dataSize, &connected) == kAudioHardwareNoError)
|
}, 0, NULL, &dataSize, &dataSource) == kAudioHardwareNoError && dataSource == 'hdpn')
|
||||||
if (!connected) continue;
|
{
|
||||||
|
uint32_t connected;
|
||||||
|
dataSize = sizeof(connected);
|
||||||
|
if(AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){
|
||||||
|
kAudioDevicePropertyJackIsConnected,
|
||||||
|
kAudioObjectPropertyScopeOutput,
|
||||||
|
kAudioObjectPropertyElementMain
|
||||||
|
}, 0, NULL, &dataSize, &connected) == kAudioHardwareNoError)
|
||||||
|
if (!connected) continue;
|
||||||
|
}
|
||||||
|
|
||||||
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
|
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
|
||||||
device->main = deviceId == mainDeviceId;
|
device->main = deviceId == mainDeviceId;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ static void paServerInfoCallback(pa_context *c, const pa_server_info *i, void *u
|
|||||||
|
|
||||||
static const char* detectSound(FFlist* devices)
|
static const char* detectSound(FFlist* devices)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(pulse, &instance.config.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0)
|
FF_LIBRARY_LOAD(pulse, &instance.config.library.libPulse, "Failed to load libpulse" FF_LIBRARY_EXTENSION, "libpulse" FF_LIBRARY_EXTENSION, 0)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_new)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_new)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_get_api)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_get_api)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_iterate)
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(pulse, pa_mainloop_iterate)
|
||||||
|
|||||||
@@ -41,33 +41,23 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
|
|||||||
return value->name.length > 0 || value->deviceClass > 0;
|
return value->name.length > 0 || value->deviceClass > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FFTempsResult* ffDetectTemps(void)
|
const FFlist* ffDetectTemps(void)
|
||||||
{
|
{
|
||||||
static FFTempsResult result;
|
static FFlist result;
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
static bool init = false;
|
|
||||||
|
|
||||||
ffThreadMutexLock(&mutex);
|
if(result.elementSize > 0)
|
||||||
if(init)
|
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
init = true;
|
|
||||||
|
|
||||||
ffListInitA(&result.values, sizeof(FFTempValue), 16);
|
ffListInitA(&result, sizeof(FFTempValue), 16);
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
|
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
|
||||||
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
|
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
|
||||||
|
|
||||||
uint32_t baseDirLength = baseDir.length;
|
uint32_t baseDirLength = baseDir.length;
|
||||||
|
|
||||||
DIR* dirp = opendir(baseDir.chars);
|
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
|
||||||
if(dirp == NULL)
|
if(dirp == NULL)
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
while((entry = readdir(dirp)) != NULL)
|
while((entry = readdir(dirp)) != NULL)
|
||||||
@@ -78,20 +68,17 @@ const FFTempsResult* ffDetectTemps(void)
|
|||||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||||
ffStrbufAppendC(&baseDir, '/');
|
ffStrbufAppendC(&baseDir, '/');
|
||||||
|
|
||||||
FFTempValue* temp = ffListAdd(&result.values);
|
FFTempValue* temp = ffListAdd(&result);
|
||||||
ffStrbufInit(&temp->name);
|
ffStrbufInit(&temp->name);
|
||||||
temp->deviceClass = 0;
|
temp->deviceClass = 0;
|
||||||
if(!parseHwmonDir(&baseDir, temp))
|
if(!parseHwmonDir(&baseDir, temp))
|
||||||
{
|
{
|
||||||
ffStrbufDestroy(&temp->name);
|
ffStrbufDestroy(&temp->name);
|
||||||
--result.values.length;
|
--result.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dirp);
|
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ typedef struct FFTempValue
|
|||||||
double value;
|
double value;
|
||||||
} FFTempValue;
|
} FFTempValue;
|
||||||
|
|
||||||
typedef struct FFTempsResult
|
const FFlist* /* List of FFTempValue */ ffDetectTemps();
|
||||||
{
|
|
||||||
FFlist values; //List of FFTempValue
|
|
||||||
} FFTempsResult;
|
|
||||||
|
|
||||||
const FFTempsResult* ffDetectTemps();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -242,35 +242,32 @@ FF_MAYBE_UNUSED static bool detectKitty(const FFstrbuf* exe, FFTerminalFontResul
|
|||||||
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
||||||
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY fontSize = ffStrbufCreate();
|
||||||
|
|
||||||
FFpropquery fontQuery[] = {
|
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||||
{"font_family ", &fontName},
|
if(!ffProcessAppendStdOut(&buf, (char* const[]){
|
||||||
{"font_size ", &fontSize},
|
exe->chars,
|
||||||
};
|
"+kitten",
|
||||||
|
"query-terminal",
|
||||||
if(instance.config.allowSlowOperations)
|
NULL,
|
||||||
|
}))
|
||||||
{
|
{
|
||||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
ffParsePropLines(buf.chars, "font_family: ", &fontName);
|
||||||
if(!ffProcessAppendStdOut(&buf, (char* const[]){
|
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
|
||||||
exe->chars,
|
}
|
||||||
"+kitten",
|
else
|
||||||
"query-terminal",
|
{
|
||||||
NULL,
|
FFpropquery fontQuery[] = {
|
||||||
}))
|
{"font_family ", &fontName},
|
||||||
{
|
{"font_size ", &fontSize},
|
||||||
ffParsePropLines(buf.chars, "font_family: ", &fontName);
|
};
|
||||||
ffParsePropLines(buf.chars, "font_size: ", &fontSize);
|
|
||||||
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
|
ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery);
|
||||||
return true;
|
|
||||||
}
|
if(fontName.length == 0)
|
||||||
|
ffStrbufSetS(&fontName, "monospace");
|
||||||
|
if(fontSize.length == 0)
|
||||||
|
ffStrbufSetS(&fontSize, "11.0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ffParsePropFileConfigValues("kitty/kitty.conf", 2, fontQuery))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(fontName.length == 0)
|
|
||||||
ffStrbufSetS(&fontName, "monospace");
|
|
||||||
if(fontSize.length == 0)
|
|
||||||
ffStrbufSetS(&fontSize, "11.0");
|
|
||||||
|
|
||||||
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
|
ffFontInitValues(&result->font, fontName.chars, fontSize.chars);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const char* detectTermux(FFTerminalFontResult* terminalFont)
|
|||||||
{
|
{
|
||||||
#ifdef FF_HAVE_FREETYPE
|
#ifdef FF_HAVE_FREETYPE
|
||||||
|
|
||||||
FF_LIBRARY_LOAD(freetype, &instance.config.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
|
FF_LIBRARY_LOAD(freetype, &instance.config.library.libfreetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Init_FreeType);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Init_FreeType);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_New_Face);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_New_Face);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_Face);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(freetype, FT_Done_Face);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/properties.h"
|
#include "common/properties.h"
|
||||||
#include "common/parsing.h"
|
#include "common/parsing.h"
|
||||||
|
#include "common/io/io.h"
|
||||||
#include "detection/terminalshell/terminalshell.h"
|
#include "detection/terminalshell/terminalshell.h"
|
||||||
#include "detection/displayserver/displayserver.h"
|
#include "detection/displayserver/displayserver.h"
|
||||||
#include "util/mallocHelper.h"
|
#include "util/mallocHelper.h"
|
||||||
@@ -124,15 +125,36 @@ static void detectXFCETerminal(FFTerminalFontResult* terminalFont)
|
|||||||
FF_STRBUF_AUTO_DESTROY useSysFont = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY useSysFont = ffStrbufCreate();
|
||||||
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY fontName = ffStrbufCreate();
|
||||||
|
|
||||||
ffParsePropFileConfigValues("xfce4/terminal/terminalrc", 2, (FFpropquery[]) {
|
const char* path = "xfce4/xfconf/xfce-perchannel-xml/xfce4-terminal.xml";
|
||||||
{"FontUseSystem = ", &useSysFont},
|
bool configFound = ffParsePropFileConfigValues(path, 2, (FFpropquery[]) {
|
||||||
{"FontName = ", &fontName}
|
{"<property name=\"font-use-system\" type=\"bool\" value=\"", &useSysFont},
|
||||||
|
{"<property name=\"font-name\" type=\"string\" value=\"", &fontName}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (configFound)
|
||||||
|
{
|
||||||
|
ffStrbufSubstrBeforeLastC(&useSysFont, '"');
|
||||||
|
ffStrbufSubstrBeforeLastC(&fontName, '"');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = "xfce4/terminal/terminalrc";
|
||||||
|
configFound = ffParsePropFileConfigValues(path, 2, (FFpropquery[]) {
|
||||||
|
{"FontUseSystem = ", &useSysFont},
|
||||||
|
{"FontName = ", &fontName}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!configFound)
|
||||||
|
{
|
||||||
|
ffStrbufSetStatic(&terminalFont->error, "Couldn't find xfce4/xfconf/xfce-perchannel-xml/xfce4-terminal.xml or xfce4/terminal/terminalrc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0)
|
if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0)
|
||||||
{
|
{
|
||||||
if(fontName.length == 0)
|
if(fontName.length == 0)
|
||||||
ffStrbufAppendS(&terminalFont->error, "Couldn't find FontName in .config/xfce4/terminal/terminalrc");
|
ffStrbufAppendF(&terminalFont->error, "Couldn't find FontName in %s", path);
|
||||||
else
|
else
|
||||||
ffFontInitPango(&terminalFont->font, fontName.chars);
|
ffFontInitPango(&terminalFont->font, fontName.chars);
|
||||||
}
|
}
|
||||||
@@ -250,6 +272,38 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
|
|||||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void detectSt(FFTerminalFontResult* terminalFont, uint32_t pid)
|
||||||
|
{
|
||||||
|
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreateF("/proc/%u/cmdline", pid);
|
||||||
|
FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
|
||||||
|
if (!ffAppendFileBuffer(size.chars, &font))
|
||||||
|
{
|
||||||
|
ffStrbufAppendF(&terminalFont->error, "Failed to open %s", size.chars);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* p = memmem(font.chars, font.length, "\0-f", sizeof("\0-f")); // find parameter of `-f`
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
ffStrbufAppendF(&terminalFont->error, "st was not executed with `-f` parameter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffStrbufSubstrAfter(&font, (uint32_t) (p + (sizeof("\0-f") - 1) - font.chars));
|
||||||
|
ffStrbufRecalculateLength(&font);
|
||||||
|
|
||||||
|
// `monospace:size=15` || `monospace` || `:size=15`
|
||||||
|
uint32_t index = ffStrbufFirstIndexS(&font, ":size=");
|
||||||
|
if (index != font.length)
|
||||||
|
{
|
||||||
|
ffStrbufSetS(&size, font.chars + index + strlen(":size="));
|
||||||
|
ffStrbufSubstrBefore(&font, index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ffStrbufClear(&size);
|
||||||
|
ffFontInitValues(&terminalFont->font, font.chars, size.chars);
|
||||||
|
}
|
||||||
|
|
||||||
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont)
|
||||||
{
|
{
|
||||||
if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole"))
|
if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "konsole"))
|
||||||
@@ -276,4 +330,6 @@ void ffDetectTerminalFontPlatform(const FFTerminalShellResult* terminalShell, FF
|
|||||||
detectQTerminal(terminalFont);
|
detectQTerminal(terminalFont);
|
||||||
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xterm"))
|
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "xterm"))
|
||||||
detectXterm(terminalFont);
|
detectXterm(terminalFont);
|
||||||
|
else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "st"))
|
||||||
|
detectSt(terminalFont, terminalShell->terminalPid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,6 +284,36 @@ FF_MAYBE_UNUSED static bool getTerminalVersionXterm(FFstrbuf* exe, FFstrbuf* ver
|
|||||||
return version->length > 0;
|
return version->length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FF_MAYBE_UNUSED static bool getTerminalVersionUrxvt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
|
||||||
|
{
|
||||||
|
if(ffProcessAppendStdErr(version, (char* const[]){
|
||||||
|
"urxvt", // Don't use exe because of urxvtd
|
||||||
|
"-invalid",
|
||||||
|
NULL
|
||||||
|
})) return false;
|
||||||
|
|
||||||
|
//urxvt: "invalid": unknown or malformed option.
|
||||||
|
//rxvt-unicode (urxvt) v9.31 - released: 2023-01-02
|
||||||
|
ffStrbufSubstrAfterFirstS(version, "(urxvt) v");
|
||||||
|
ffStrbufSubstrBeforeFirstC(version, ' ');
|
||||||
|
|
||||||
|
return version->length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FF_MAYBE_UNUSED static bool getTerminalVersionSt(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
|
||||||
|
{
|
||||||
|
if(ffProcessAppendStdErr(version, (char* const[]){
|
||||||
|
exe->chars,
|
||||||
|
"-v",
|
||||||
|
NULL
|
||||||
|
})) return false;
|
||||||
|
|
||||||
|
//st 0.9
|
||||||
|
ffStrbufSubstrAfterFirstC(version, ' ');
|
||||||
|
|
||||||
|
return version->length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
|
static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
|
||||||
{
|
{
|
||||||
const char* env = getenv("TERMINAL_VERSION_STRING");
|
const char* env = getenv("TERMINAL_VERSION_STRING");
|
||||||
@@ -371,6 +401,16 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
|||||||
if(ffStrbufIgnCaseEqualS(processName, "xterm"))
|
if(ffStrbufIgnCaseEqualS(processName, "xterm"))
|
||||||
return getTerminalVersionXterm(exe, version);
|
return getTerminalVersionXterm(exe, version);
|
||||||
|
|
||||||
|
if(ffStrbufIgnCaseEqualS(processName, "st"))
|
||||||
|
return getTerminalVersionSt(exe, version);
|
||||||
|
|
||||||
|
if(ffStrbufIgnCaseEqualS(processName, "urxvt") ||
|
||||||
|
ffStrbufIgnCaseEqualS(processName, "urxvtd") ||
|
||||||
|
ffStrbufIgnCaseEqualS(processName, "rxvt") ||
|
||||||
|
ffStrbufIgnCaseEqualS(processName, "rxvt-unicode")
|
||||||
|
)
|
||||||
|
return getTerminalVersionUrxvt(exe, version);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -415,6 +455,22 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
termProgramVersion = getenv("LC_TERMINAL_VERSION");
|
||||||
|
if(termProgramVersion)
|
||||||
|
{
|
||||||
|
const char* termProgram = getenv("LC_TERMINAL");
|
||||||
|
if(termProgram)
|
||||||
|
{
|
||||||
|
if(ffStrbufStartsWithIgnCaseS(processName, termProgram) || // processName ends with `.exe` on Windows
|
||||||
|
(ffStrEquals(termProgram, "vscode") && ffStrbufStartsWithIgnCaseS(processName, "code")) ||
|
||||||
|
(ffStrStartsWith(termProgram, "iTerm") && ffStrbufStartsWithIgnCaseS(processName, "iTermServer-"))
|
||||||
|
) {
|
||||||
|
ffStrbufSetS(version, termProgramVersion);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
return getFileVersion(exe->chars, version);
|
return getFileVersion(exe->chars, version);
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
|
|||||||
strcasecmp(name, "sshd") == 0 ||
|
strcasecmp(name, "sshd") == 0 ||
|
||||||
strcasecmp(name, "gdb") == 0 ||
|
strcasecmp(name, "gdb") == 0 ||
|
||||||
strcasecmp(name, "lldb") == 0 ||
|
strcasecmp(name, "lldb") == 0 ||
|
||||||
|
strcasecmp(name, "login") == 0 ||
|
||||||
strcasecmp(name, "guake-wrapped") == 0 ||
|
strcasecmp(name, "guake-wrapped") == 0 ||
|
||||||
strcasestr(name, "debug") != NULL ||
|
strcasestr(name, "debug") != NULL ||
|
||||||
strcasestr(name, "command-not-found") != NULL ||
|
strcasestr(name, "command-not-found") != NULL ||
|
||||||
@@ -236,8 +237,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
|||||||
//Termux
|
//Termux
|
||||||
if(!ffStrSet(term) && (
|
if(!ffStrSet(term) && (
|
||||||
getenv("TERMUX_VERSION") != NULL ||
|
getenv("TERMUX_VERSION") != NULL ||
|
||||||
getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL ||
|
getenv("TERMUX_MAIN_PACKAGE_FORMAT") != NULL
|
||||||
getenv("TMUX_TMPDIR") != NULL
|
|
||||||
)) term = "com.termux";
|
)) term = "com.termux";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -252,6 +252,9 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
|||||||
if(!ffStrSet(term))
|
if(!ffStrSet(term))
|
||||||
term = getenv("TERM_PROGRAM");
|
term = getenv("TERM_PROGRAM");
|
||||||
|
|
||||||
|
if(!ffStrSet(term))
|
||||||
|
term = getenv("LC_TERMINAL");
|
||||||
|
|
||||||
//Normal Terminal
|
//Normal Terminal
|
||||||
if(!ffStrSet(term))
|
if(!ffStrSet(term))
|
||||||
term = getenv("TERM");
|
term = getenv("TERM");
|
||||||
@@ -311,15 +314,10 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* vers
|
|||||||
|
|
||||||
const FFTerminalShellResult* ffDetectTerminalShell()
|
const FFTerminalShellResult* ffDetectTerminalShell()
|
||||||
{
|
{
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
static FFTerminalShellResult result;
|
static FFTerminalShellResult result;
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
if(init)
|
if(init)
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
init = true;
|
init = true;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -373,9 +371,10 @@ const FFTerminalShellResult* ffDetectTerminalShell()
|
|||||||
result.terminalExeName + 1);
|
result.terminalExeName + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui"))
|
if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui"))
|
||||||
ffStrbufInitStatic(&result.terminalPrettyName, "WezTerm");
|
ffStrbufInitStatic(&result.terminalPrettyName, "WezTerm");
|
||||||
|
if(ffStrbufStartsWithS(&result.terminalProcessName, "tmux:"))
|
||||||
|
ffStrbufInitStatic(&result.terminalPrettyName, "tmux");
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
@@ -388,6 +387,11 @@ const FFTerminalShellResult* ffDetectTerminalShell()
|
|||||||
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Terminal");
|
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Terminal");
|
||||||
else if(ffStrbufStartsWithS(&result.terminalProcessName, "kgx"))
|
else if(ffStrbufStartsWithS(&result.terminalProcessName, "kgx"))
|
||||||
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Console");
|
ffStrbufInitStatic(&result.terminalPrettyName, "GNOME Console");
|
||||||
|
else if(ffStrbufEqualS(&result.terminalProcessName, "urxvt") ||
|
||||||
|
ffStrbufEqualS(&result.terminalProcessName, "urxvtd") ||
|
||||||
|
ffStrbufEqualS(&result.terminalProcessName, "rxvt")
|
||||||
|
)
|
||||||
|
ffStrbufInitStatic(&result.terminalPrettyName, "rxvt-unicode");
|
||||||
|
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
@@ -408,6 +412,5 @@ const FFTerminalShellResult* ffDetectTerminalShell()
|
|||||||
ffStrbufInit(&result.terminalVersion);
|
ffStrbufInit(&result.terminalVersion);
|
||||||
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
|
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
|||||||
{
|
{
|
||||||
ffStrbufClear(&result->shellPrettyName);
|
ffStrbufClear(&result->shellPrettyName);
|
||||||
|
|
||||||
HANDLE snapshot;
|
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
|
||||||
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
|
||||||
|
|
||||||
if(snapshot)
|
if(snapshot)
|
||||||
@@ -147,7 +147,6 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(snapshot);
|
|
||||||
}
|
}
|
||||||
if(result->shellPrettyName.length == 0)
|
if(result->shellPrettyName.length == 0)
|
||||||
ffStrbufAppendS(&result->shellPrettyName, "Command Prompt");
|
ffStrbufAppendS(&result->shellPrettyName, "Command Prompt");
|
||||||
@@ -355,15 +354,10 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* vers
|
|||||||
|
|
||||||
const FFTerminalShellResult* ffDetectTerminalShell(void)
|
const FFTerminalShellResult* ffDetectTerminalShell(void)
|
||||||
{
|
{
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
static FFTerminalShellResult result;
|
static FFTerminalShellResult result;
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
if(init)
|
if(init)
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
init = true;
|
init = true;
|
||||||
|
|
||||||
ffStrbufInit(&result.shellProcessName);
|
ffStrbufInit(&result.shellProcessName);
|
||||||
@@ -381,7 +375,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(void)
|
|||||||
|
|
||||||
uint32_t ppid;
|
uint32_t ppid;
|
||||||
if(!getProcessInfo(0, &ppid, NULL, NULL, NULL))
|
if(!getProcessInfo(0, &ppid, NULL, NULL, NULL))
|
||||||
goto exit;
|
return &result;
|
||||||
|
|
||||||
ppid = getShellInfo(&result, ppid);
|
ppid = getShellInfo(&result, ppid);
|
||||||
if(ppid)
|
if(ppid)
|
||||||
@@ -393,7 +387,5 @@ const FFTerminalShellResult* ffDetectTerminalShell(void)
|
|||||||
ffStrbufInit(&result.terminalVersion);
|
ffStrbufInit(&result.terminalVersion);
|
||||||
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
|
fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion);
|
||||||
|
|
||||||
exit:
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ static void applyDriverName(VkPhysicalDeviceDriverProperties* properties, FFstrb
|
|||||||
|
|
||||||
static const char* detectVulkan(FFVulkanResult* result)
|
static const char* detectVulkan(FFVulkanResult* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(vulkan, &instance.config.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
|
FF_LIBRARY_LOAD(vulkan, &instance.config.library.libVulkan, "dlopen libvulkan"FF_LIBRARY_EXTENSION " failed",
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
"libMoltenVK"FF_LIBRARY_EXTENSION, -1
|
"libMoltenVK"FF_LIBRARY_EXTENSION, -1
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
@@ -117,11 +117,7 @@ static const char* detectVulkan(FFVulkanResult* result)
|
|||||||
if(!ffvkGetPhysicalDeviceProperties2)
|
if(!ffvkGetPhysicalDeviceProperties2)
|
||||||
ffvkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceProperties");
|
ffvkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceProperties");
|
||||||
|
|
||||||
PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = NULL;
|
PFN_vkGetPhysicalDeviceMemoryProperties ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties");
|
||||||
PFN_vkGetPhysicalDeviceMemoryProperties2 ffvkGetPhysicalDeviceMemoryProperties2 =
|
|
||||||
instance.config.allowSlowOperations ? (PFN_vkGetPhysicalDeviceMemoryProperties2) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties2") : NULL; // 1.1
|
|
||||||
if(!ffvkGetPhysicalDeviceMemoryProperties2)
|
|
||||||
ffvkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) ffvkGetInstanceProcAddr(vkInstance, "vkGetPhysicalDeviceMemoryProperties");
|
|
||||||
|
|
||||||
FFVersion maxDeviceApiVersion = FF_VERSION_INIT;
|
FFVersion maxDeviceApiVersion = FF_VERSION_INIT;
|
||||||
FFVersion maxDeviceConformanceVersion = FF_VERSION_INIT;
|
FFVersion maxDeviceConformanceVersion = FF_VERSION_INIT;
|
||||||
@@ -187,38 +183,22 @@ static const char* detectVulkan(FFVulkanResult* result)
|
|||||||
|
|
||||||
gpu->vulkanDeviceId = physicalDeviceProperties.properties.deviceID;
|
gpu->vulkanDeviceId = physicalDeviceProperties.properties.deviceID;
|
||||||
|
|
||||||
ffStrbufInit(&gpu->name);
|
ffStrbufInitS(&gpu->name, physicalDeviceProperties.properties.deviceName);
|
||||||
ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName);
|
|
||||||
|
|
||||||
if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
gpu->type = physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||||
gpu->type = FF_GPU_TYPE_DISCRETE;
|
|
||||||
else
|
|
||||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
|
||||||
ffStrbufInitS(&gpu->vendor, ffGetGPUVendorString(physicalDeviceProperties.properties.vendorID));
|
ffStrbufInitS(&gpu->vendor, ffGetGPUVendorString(physicalDeviceProperties.properties.vendorID));
|
||||||
ffStrbufInitS(&gpu->driver, driverProperties.driverInfo);
|
ffStrbufInitS(&gpu->driver, driverProperties.driverInfo);
|
||||||
|
|
||||||
VkPhysicalDeviceMemoryBudgetPropertiesEXT budgetProperties = {
|
VkPhysicalDeviceMemoryProperties memoryProperties = {};
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT,
|
ffvkGetPhysicalDeviceMemoryProperties(physicalDevices[i], &memoryProperties);
|
||||||
};
|
|
||||||
VkPhysicalDeviceMemoryProperties2 memoryProperties2 = {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
|
|
||||||
.pNext = &budgetProperties,
|
|
||||||
};
|
|
||||||
|
|
||||||
if(ffvkGetPhysicalDeviceMemoryProperties2)
|
|
||||||
ffvkGetPhysicalDeviceMemoryProperties2(physicalDevices[i], &memoryProperties2);
|
|
||||||
else
|
|
||||||
ffvkGetPhysicalDeviceMemoryProperties(physicalDevices[i], &memoryProperties2.memoryProperties);
|
|
||||||
|
|
||||||
gpu->dedicated.total = gpu->shared.total = 0;
|
gpu->dedicated.total = gpu->shared.total = 0;
|
||||||
gpu->dedicated.used = gpu->shared.used = ffvkGetPhysicalDeviceMemoryProperties2 ? 0 : FF_GPU_VMEM_SIZE_UNSET;
|
gpu->dedicated.used = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||||
for(uint32_t index = 0; index < memoryProperties2.memoryProperties.memoryHeapCount; ++index)
|
for(uint32_t index = 0; index < memoryProperties.memoryHeapCount; ++index)
|
||||||
{
|
{
|
||||||
const VkMemoryHeap* heap = &memoryProperties2.memoryProperties.memoryHeaps[index];
|
const VkMemoryHeap* heap = &memoryProperties.memoryHeaps[index];
|
||||||
FFGPUMemory* vmem = gpu->type == FF_GPU_TYPE_DISCRETE && (heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? &gpu->dedicated : &gpu->shared;
|
FFGPUMemory* vmem = gpu->type == FF_GPU_TYPE_DISCRETE && (heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ? &gpu->dedicated : &gpu->shared;
|
||||||
vmem->total += heap->size;
|
vmem->total += heap->size;
|
||||||
if(ffvkGetPhysicalDeviceMemoryProperties2)
|
|
||||||
vmem->used += heap->size - budgetProperties.heapBudget[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//No way to detect those using vulkan
|
//No way to detect those using vulkan
|
||||||
@@ -248,15 +228,10 @@ static const char* detectVulkan(FFVulkanResult* result)
|
|||||||
FFVulkanResult* ffDetectVulkan(void)
|
FFVulkanResult* ffDetectVulkan(void)
|
||||||
{
|
{
|
||||||
static FFVulkanResult result;
|
static FFVulkanResult result;
|
||||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
|
|
||||||
ffThreadMutexLock(&mutex);
|
|
||||||
if(init)
|
if(init)
|
||||||
{
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
|
||||||
init = true;
|
init = true;
|
||||||
|
|
||||||
ffStrbufInit(&result.driver);
|
ffStrbufInit(&result.driver);
|
||||||
@@ -270,6 +245,5 @@ FFVulkanResult* ffDetectVulkan(void)
|
|||||||
result.error = "fastfetch was compiled without vulkan support";
|
result.error = "fastfetch was compiled without vulkan support";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ffThreadMutexUnlock(&mutex);
|
|
||||||
return &result;
|
return &result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const char* ffDetectWallpaper(FFstrbuf* result)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
|
if (!ffOsascript("tell application \"Finder\" to get POSIX path of (get desktop picture as alias)", result))
|
||||||
return "ffOsascript() failed";
|
return "ffOsascript(get desktop picture) failed";
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,27 @@
|
|||||||
|
|
||||||
#import <CoreWLAN/CoreWLAN.h>
|
#import <CoreWLAN/CoreWLAN.h>
|
||||||
|
|
||||||
|
struct Apple80211; // https://code.google.com/archive/p/iphone-wireless/wikis/Apple80211.wiki
|
||||||
|
|
||||||
|
// 0 is sucessful; < 0 is failure
|
||||||
|
int Apple80211Open(struct Apple80211 **handle) __attribute__((weak_import));
|
||||||
|
int Apple80211BindToInterface(struct Apple80211 *handle, CFStringRef interface) __attribute__((weak_import));
|
||||||
|
int Apple80211GetInfoCopy(struct Apple80211 *handle, CFDictionaryRef *info) __attribute__((weak_import));
|
||||||
|
int Apple80211Close(struct Apple80211 *handle) __attribute__((weak_import));
|
||||||
|
|
||||||
|
static NSDictionary* getWifiInfoByApple80211(NSString* ifName)
|
||||||
|
{
|
||||||
|
if (!Apple80211Open || !Apple80211BindToInterface || !Apple80211GetInfoCopy || !Apple80211Close) return NULL;
|
||||||
|
|
||||||
|
struct Apple80211* handle = NULL;
|
||||||
|
if (Apple80211Open(&handle) < 0) return NULL;
|
||||||
|
if (Apple80211BindToInterface(handle, (CFStringRef)ifName) < 0) return NULL;
|
||||||
|
CFDictionaryRef result;
|
||||||
|
if (Apple80211GetInfoCopy(handle, &result) < 0) return NULL;
|
||||||
|
Apple80211Close(handle);
|
||||||
|
return CFBridgingRelease(result);
|
||||||
|
}
|
||||||
|
|
||||||
const char* ffDetectWifi(FFlist* result)
|
const char* ffDetectWifi(FFlist* result)
|
||||||
{
|
{
|
||||||
NSArray<CWInterface*>* interfaces = CWWiFiClient.sharedWiFiClient.interfaces;
|
NSArray<CWInterface*>* interfaces = CWWiFiClient.sharedWiFiClient.interfaces;
|
||||||
@@ -24,56 +45,53 @@ const char* ffDetectWifi(FFlist* result)
|
|||||||
item->conn.txRate = 0.0/0.0;
|
item->conn.txRate = 0.0/0.0;
|
||||||
|
|
||||||
ffStrbufAppendS(&item->inf.description, inf.interfaceName.UTF8String);
|
ffStrbufAppendS(&item->inf.description, inf.interfaceName.UTF8String);
|
||||||
ffStrbufAppendS(&item->inf.status, inf.powerOn ? "Power On" : "Power Off");
|
ffStrbufSetStatic(&item->inf.status, inf.powerOn ? "Power On" : "Power Off");
|
||||||
if(!inf.powerOn)
|
if(!inf.powerOn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ffStrbufAppendS(&item->conn.status, inf.serviceActive ? "Active" : "Inactive");
|
ffStrbufSetStatic(&item->conn.status, inf.interfaceMode != kCWInterfaceModeNone ? "Active" : "Inactive");
|
||||||
if(!inf.serviceActive)
|
if(!inf.serviceActive)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (inf.ssid)
|
NSDictionary* apple = NULL;
|
||||||
|
|
||||||
|
if (inf.ssid) // https://developer.apple.com/forums/thread/732431
|
||||||
ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String);
|
ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String);
|
||||||
else if (!ffProcessAppendStdOut(&item->conn.ssid, (char* []) {
|
else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
|
||||||
"/usr/sbin/networksetup",
|
ffStrbufAppendS(&item->conn.ssid, [[apple valueForKey:@"SSID_STR"] UTF8String]);
|
||||||
"-getairportnetwork",
|
|
||||||
item->inf.description.chars,
|
|
||||||
NULL
|
|
||||||
}) && item->conn.ssid.length > 0)
|
|
||||||
{
|
|
||||||
uint32_t index = ffStrbufFirstIndexC(&item->conn.ssid, ':');
|
|
||||||
if (index < item->conn.ssid.length)
|
|
||||||
ffStrbufSubstrAfter(&item->conn.ssid, index + 1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
ffStrbufSetStatic(&item->conn.ssid, "<unknown ssid>"); // https://developer.apple.com/forums/thread/732431
|
ffStrbufSetStatic(&item->conn.ssid, "<unknown ssid>"); // https://developer.apple.com/forums/thread/732431
|
||||||
|
|
||||||
ffStrbufAppendS(&item->conn.macAddress, inf.hardwareAddress.UTF8String);
|
if (inf.bssid)
|
||||||
|
ffStrbufAppendS(&item->conn.macAddress, inf.bssid.UTF8String);
|
||||||
|
else if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
|
||||||
|
ffStrbufAppendS(&item->conn.macAddress, [[apple valueForKey:@"BSSID"] UTF8String]);
|
||||||
|
|
||||||
switch(inf.activePHYMode)
|
switch(inf.activePHYMode)
|
||||||
{
|
{
|
||||||
case kCWPHYModeNone:
|
case kCWPHYModeNone:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "none");
|
ffStrbufSetStatic(&item->conn.protocol, "none");
|
||||||
break;
|
break;
|
||||||
case kCWPHYMode11a:
|
case kCWPHYMode11a:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11a");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11a");
|
||||||
break;
|
break;
|
||||||
case kCWPHYMode11b:
|
case kCWPHYMode11b:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11b");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11b");
|
||||||
break;
|
break;
|
||||||
case kCWPHYMode11g:
|
case kCWPHYMode11g:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11g");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11g");
|
||||||
break;
|
break;
|
||||||
case kCWPHYMode11n:
|
case kCWPHYMode11n:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)");
|
||||||
break;
|
break;
|
||||||
case kCWPHYMode11ac:
|
case kCWPHYMode11ac:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
|
||||||
break;
|
break;
|
||||||
case 6 /*kCWPHYMode11ax*/:
|
case 6 /*kCWPHYMode11ax*/:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
|
||||||
break;
|
break;
|
||||||
case 7 /*kCWPHYMode11be?*/:
|
case 7 /*kCWPHYMode11be?*/:
|
||||||
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
|
ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode);
|
ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode);
|
||||||
@@ -85,55 +103,86 @@ const char* ffDetectWifi(FFlist* result)
|
|||||||
switch(inf.security)
|
switch(inf.security)
|
||||||
{
|
{
|
||||||
case kCWSecurityNone:
|
case kCWSecurityNone:
|
||||||
ffStrbufAppendS(&item->conn.security, "Insecure");
|
ffStrbufSetStatic(&item->conn.security, "Insecure");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWEP:
|
case kCWSecurityWEP:
|
||||||
ffStrbufAppendS(&item->conn.security, "WEP");
|
ffStrbufSetStatic(&item->conn.security, "WEP");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPAPersonal:
|
case kCWSecurityWPAPersonal:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA Personal");
|
ffStrbufSetStatic(&item->conn.security, "WPA Personal");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPAPersonalMixed:
|
case kCWSecurityWPAPersonalMixed:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA Persional Mixed");
|
ffStrbufSetStatic(&item->conn.security, "WPA Persional Mixed");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPA2Personal:
|
case kCWSecurityWPA2Personal:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA2 Personal");
|
ffStrbufSetStatic(&item->conn.security, "WPA2 Personal");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityPersonal:
|
case kCWSecurityPersonal:
|
||||||
ffStrbufAppendS(&item->conn.security, "Personal");
|
ffStrbufSetStatic(&item->conn.security, "Personal");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityDynamicWEP:
|
case kCWSecurityDynamicWEP:
|
||||||
ffStrbufAppendS(&item->conn.security, "Dynamic WEP");
|
ffStrbufSetStatic(&item->conn.security, "Dynamic WEP");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPAEnterprise:
|
case kCWSecurityWPAEnterprise:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA Enterprise");
|
ffStrbufSetStatic(&item->conn.security, "WPA Enterprise");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPAEnterpriseMixed:
|
case kCWSecurityWPAEnterpriseMixed:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA Enterprise Mixed");
|
ffStrbufSetStatic(&item->conn.security, "WPA Enterprise Mixed");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPA2Enterprise:
|
case kCWSecurityWPA2Enterprise:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA2 Enterprise");
|
ffStrbufSetStatic(&item->conn.security, "WPA2 Enterprise");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityEnterprise:
|
case kCWSecurityEnterprise:
|
||||||
ffStrbufAppendS(&item->conn.security, "Enterprise");
|
ffStrbufSetStatic(&item->conn.security, "Enterprise");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPA3Personal:
|
case kCWSecurityWPA3Personal:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA3 Personal");
|
ffStrbufSetStatic(&item->conn.security, "WPA3 Personal");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPA3Enterprise:
|
case kCWSecurityWPA3Enterprise:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA3 Enterprise");
|
ffStrbufSetStatic(&item->conn.security, "WPA3 Enterprise");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityWPA3Transition:
|
case kCWSecurityWPA3Transition:
|
||||||
ffStrbufAppendS(&item->conn.security, "WPA3 Transition");
|
ffStrbufSetStatic(&item->conn.security, "WPA3 Transition");
|
||||||
break;
|
break;
|
||||||
case 14 /*kCWSecurityOWE*/:
|
case 14 /*kCWSecurityOWE*/:
|
||||||
ffStrbufAppendS(&item->conn.security, "OWE");
|
ffStrbufSetStatic(&item->conn.security, "OWE");
|
||||||
break;
|
break;
|
||||||
case 15 /*kCWSecurityOWETransition*/:
|
case 15 /*kCWSecurityOWETransition*/:
|
||||||
ffStrbufAppendS(&item->conn.security, "OWE Transition");
|
ffStrbufSetStatic(&item->conn.security, "OWE Transition");
|
||||||
break;
|
break;
|
||||||
case kCWSecurityUnknown:
|
case kCWSecurityUnknown:
|
||||||
// Ignore
|
// Sonoma...
|
||||||
|
if (apple || (apple = getWifiInfoByApple80211(inf.interfaceName)))
|
||||||
|
{
|
||||||
|
NSDictionary* authType = [apple valueForKey:@"AUTH_TYPE"];
|
||||||
|
if (authType)
|
||||||
|
{
|
||||||
|
if ([[authType valueForKey:@"AUTH_LOWER"] intValue] != 1) break; // APPLE80211_AUTH_TYPE_UNICAST?
|
||||||
|
|
||||||
|
NSNumber* authUpper = [authType valueForKey:@"AUTH_UPPER"];
|
||||||
|
if (!authUpper)
|
||||||
|
ffStrbufSetStatic(&item->conn.security, "Insecure");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int authUpperValue = [authUpper intValue];
|
||||||
|
switch (authUpperValue)
|
||||||
|
{
|
||||||
|
case 4096:
|
||||||
|
ffStrbufSetStatic(&item->conn.security, "WPA3-SAE");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
ffStrbufSetStatic(&item->conn.security, "WPA2-PSK");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ffStrbufSetStatic(&item->conn.security, "WPA2");
|
||||||
|
break;
|
||||||
|
default: // TODO: support more auth types
|
||||||
|
ffStrbufAppendF(&item->conn.security, "To be supported (%d)", authUpperValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security);
|
ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
static const char* detectWifiWithLibnm(FFlist* result)
|
static const char* detectWifiWithLibnm(FFlist* result)
|
||||||
{
|
{
|
||||||
FF_LIBRARY_LOAD(nm, &instance.config.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0);
|
FF_LIBRARY_LOAD(nm, &instance.config.library.libnm, "dlopen libnm failed", "libnm" FF_LIBRARY_EXTENSION, 0);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_new);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_new);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_get_devices);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_client_get_devices);
|
||||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_device_get_iface);
|
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(nm, nm_device_get_iface);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user