mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:06:11 +02:00
Compare commits
174 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 923997f0a2 | |||
| 0182e32f00 | |||
| bd40205427 | |||
| 30b9f95b49 | |||
| 74b9fd01ff | |||
| 03f4ffb9d7 | |||
| a00cb2aede | |||
| 6799076fa6 | |||
| 573a315d61 | |||
| 0cd6cb841d | |||
| af94cf4d0d | |||
| ac76107940 | |||
| c25fe53251 | |||
| 4137b3829a | |||
| 0bb08049bf | |||
| 293576f6d6 | |||
| 0bc725c5f6 | |||
| c1c735001c | |||
| e350cce99e | |||
| 1c24cb3ebb | |||
| 0662af17f4 | |||
| 9fee532cb6 | |||
| 57f88d2167 | |||
| ed879ee53c | |||
| 6eae425679 | |||
| 182c90b22c | |||
| 2c2e0582a9 | |||
| 4216d40696 | |||
| af6f395ba3 | |||
| 3fda6e425a | |||
| 82581aa9e4 | |||
| 6bd515fed4 | |||
| 20970c6b71 | |||
| 532007267c | |||
| 87a4758497 | |||
| 6a9cce62ab | |||
| 2816ea3797 | |||
| 5144081971 | |||
| ccfe961a1f | |||
| 97211df285 | |||
| 4868517d53 | |||
| 2979bfe4ca | |||
| 42fd1a9cd7 | |||
| 36298b8e93 | |||
| 7168cc2ef2 | |||
| c398dc6c07 | |||
| 390801aee7 | |||
| e3f5563f8d | |||
| 4a54b20c68 | |||
| ea3d904bfe | |||
| 67f4b991d7 | |||
| 53922779ba | |||
| 1431cdcc83 | |||
| 968a43cb29 | |||
| 0c522bdc10 | |||
| 5db3c903e5 | |||
| 91c23c533a | |||
| 00721630ce | |||
| 167b130011 | |||
| aca502e9a0 | |||
| 36f18d0961 | |||
| e67a6856ce | |||
| 3a0b132001 | |||
| f63f31db0a | |||
| 96d60184d5 | |||
| 919bd8231e | |||
| 41fed1da5f | |||
| a846780382 | |||
| c10d7a8233 | |||
| cdcc976cd3 | |||
| b52e812c2c | |||
| aa45945b57 | |||
| eea6e81276 | |||
| 0bac93093b | |||
| 7bcb015a06 | |||
| 02bdcd355c | |||
| fa90e01bc5 | |||
| 1dec514129 | |||
| f81d09bddc | |||
| 03916b6a1d | |||
| 5338583c48 | |||
| 6c492882a3 | |||
| 98c7c7ed4f | |||
| a7a96a8954 | |||
| 1a5044add9 | |||
| 7befd71069 | |||
| 3d44a1befe | |||
| 57e734e628 | |||
| 3eadd332bb | |||
| 825db4fead | |||
| ad5be0f0c2 | |||
| 6d22a76946 | |||
| 40e977be31 | |||
| 29d93d5c67 | |||
| 9b2c59936f | |||
| bb02ba0b2e | |||
| 0987f68409 | |||
| 647403fc30 | |||
| 854a7cfeba | |||
| f78f6ceb54 | |||
| 975081aa27 | |||
| b0d3e7ef9e | |||
| 6fe0eb5677 | |||
| 42c03b2383 | |||
| b1319b34e7 | |||
| 5162b4fdec | |||
| 42f647378a | |||
| 97b3938dd5 | |||
| 2e46b5932e | |||
| 4510ef7e1c | |||
| 36bf978dc1 | |||
| 7f999dfaaf | |||
| 6f6a68f7e5 | |||
| 960bbfef59 | |||
| cabd5899f7 | |||
| 730c0d1c92 | |||
| ce6041938a | |||
| 998193b014 | |||
| f8ba138b8d | |||
| 3f9462d7c8 | |||
| 413984963e | |||
| 5aab0e2dd9 | |||
| 1ba5e6e8f7 | |||
| 2a53b012ea | |||
| 5d44efbf62 | |||
| 6ad83af2b5 | |||
| fceb19affe | |||
| ee7d3d471e | |||
| 8e9c571293 | |||
| a44b8264af | |||
| 84a5a4033e | |||
| f2fc92dbf7 | |||
| 2af338f425 | |||
| 41aaaa3429 | |||
| f9597eba39 | |||
| b4cd47cbc4 | |||
| 22de71efeb | |||
| ac654ff346 | |||
| df2fdf05e6 | |||
| 788307e98d | |||
| f93341ac61 | |||
| 3e0d97db2e | |||
| 864e707224 | |||
| c42b68404f | |||
| 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 |
@@ -0,0 +1,5 @@
|
||||
[codespell]
|
||||
check-filenames =
|
||||
builtin = clear,rare,usage,informal
|
||||
skip = */.git,*/cmake-build-*,*/.idea,*/completions,*/presets,*/screenshots,*/tests,*/3rdparty,*/logo/ascii
|
||||
ignore-words-list = iterm,compiletime,unknwn,pengwin,siduction,master,sur,doas
|
||||
+59
-32
@@ -5,6 +5,20 @@ on:
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
spellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install codespell
|
||||
shell: bash
|
||||
run: sudo apt update && sudo apt install -y codespell
|
||||
|
||||
- name: Run Spellchecker
|
||||
run: codespell
|
||||
|
||||
linux-buildtest:
|
||||
name: Linux build test
|
||||
permissions:
|
||||
@@ -28,14 +42,17 @@ jobs:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- 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 librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev directx-headers-dev libdrm-dev
|
||||
|
||||
- name: configure project
|
||||
env:
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
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 }} -DENABLE_DRM=${{ matrix.enableFeatures }} .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
@@ -43,11 +60,14 @@ jobs:
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: run fastfetch --list-features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
@@ -64,8 +84,16 @@ jobs:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- 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 librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-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 ddcutil --ignore-dependencies
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
@@ -73,10 +101,10 @@ jobs:
|
||||
languages: c
|
||||
|
||||
- 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
|
||||
run: cmake --build . --target package
|
||||
run: cmake --build . --target package --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -85,10 +113,10 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
@@ -119,8 +147,13 @@ jobs:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: uname -a
|
||||
run: uname -a
|
||||
|
||||
- name: install required packages
|
||||
run: brew install vulkan-loader molten-vk imagemagick chafa
|
||||
run: |
|
||||
brew update
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
@@ -131,7 +164,7 @@ jobs:
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package
|
||||
run: cmake --build . --target package --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -140,10 +173,10 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
@@ -171,17 +204,19 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: cross-platform-actions/action@v0.21.0
|
||||
uses: cross-platform-actions/action@v0.21.1
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: '13.2'
|
||||
run: |
|
||||
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
|
||||
uname -a
|
||||
sudo pkg update
|
||||
sudo pkg install -y cmake git pkgconf binutils pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd pulseaudio
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package
|
||||
cmake --build . --target package --verbose
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci
|
||||
time ./fastfetch -c presets/ci --format json
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
@@ -215,19 +250,11 @@ jobs:
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c, cpp
|
||||
|
||||
- name: configure project
|
||||
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
run: cmake --build . --verbose
|
||||
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||
@@ -236,10 +263,10 @@ jobs:
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
@@ -294,7 +321,7 @@ jobs:
|
||||
run: env PKG_CONFIG_PATH=/clang32/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
run: cmake --build . --verbose
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -303,10 +330,10 @@ jobs:
|
||||
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
- name: run fastfetch --format json
|
||||
run: time ./fastfetch -c presets/ci --format json
|
||||
run: time ./fastfetch -c presets/ci.jsonc --format json
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
+115
-12
@@ -1,3 +1,106 @@
|
||||
# 2.3.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix `--help` doesn't work in Windows and some other platforms
|
||||
|
||||
# 2.3.2
|
||||
|
||||
Bugfixes:
|
||||
* Fix fish completion script, and install the script correctly
|
||||
|
||||
Logo:
|
||||
* Fix Xray-OS logo name
|
||||
|
||||
# 2.3.1
|
||||
|
||||
Bugfixes:
|
||||
* Fix man page install location
|
||||
|
||||
# 2.3.0
|
||||
|
||||
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.**
|
||||
|
||||
Config related changes:
|
||||
* The deprecated flag `--gen-config conf` is removed
|
||||
* Flag `--gen-config` now does the same thing as `--migrate-config`, which can be used as config migration and default config file generation. Flag `--migrate-config` is removed
|
||||
* Fastfetch now searches for config files in the order of `fastfetch --list-config-paths`, and won't load other config if one is found.
|
||||
* The undocumented flag `--load-user-config` is removed. As an alternative, `--config none` can be used to disable loading config files.
|
||||
* `--config` (previously named `--load-config`) is now supported for command line arguments only. If specified, other config files won't be loaded, which works like other programs.
|
||||
* Config files will always be loaded before other command line flags being parsed. That is to say, command line flags will always override options defined in config files.
|
||||
* the value of GPUType `integrated` contained a typo and was fixed. Existing config files may need to be updated.
|
||||
|
||||
Features:
|
||||
* Support Oils and elvish shell version detection (Shell)
|
||||
* Support Windows Server Core (Windows)
|
||||
* Better ddcutil 2.x compatibility (Brightness, Linux)
|
||||
* Add completion support for fish (natively) and nushell (via [carapace-bin](https://github.com/rsteube/carapace-bin))
|
||||
* Support nix in macOS (Packages, macOS)
|
||||
* Print module description for `--list-modules`
|
||||
* Support `alacritty.toml` (TerminalFont)
|
||||
* Support board detection on macOS. It simplily prints machine model identifier as for now (Board, macOS)
|
||||
* Add general method to query product name (Host, macOS)
|
||||
* Use `libdrm` as a better fall back for detecting displays, which correctly detects current mode; supports refresh rate detection and maybe also faster than using `/sys/class/drm` (Display, Linux)
|
||||
* Support physical disk size detection (DiskIO)
|
||||
* Support physical disk name and type detection (DiskIO, FreeBSD)
|
||||
|
||||
Bugfixes:
|
||||
* End `va_list` before returning (@VoltrexKeyva)
|
||||
* Don't use background color when printing blocks (Color)
|
||||
* Fix lots of typos
|
||||
* Fix compatibility with Linux containers (Linux)
|
||||
* Don't report disabled monitors when using DRM (Linux)
|
||||
* Fix bad performance in some cases when using X11 (Display, Linux)
|
||||
* Fix some memory leaks
|
||||
* Fix used swap space detection (Swap, FreeBSD)
|
||||
* Don't leak fds to child processes (Linux)
|
||||
* Fix possible issues when reading procfs (Linux, @apocelipes)
|
||||
|
||||
Logos:
|
||||
* Add Adelie, Ironclad
|
||||
* Update parch
|
||||
|
||||
# 2.2.3
|
||||
|
||||
Features:
|
||||
* Update the latest mac models (Host, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Fix local ips detection on Android. Regression from `2.0.0` (LocalIP, Android)
|
||||
* Fix terminal detection on NixOS (Terminal)
|
||||
|
||||
# 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 consistent with other platforms
|
||||
* Linux binaries are built with imagemagick7 support
|
||||
|
||||
Bugfixes:
|
||||
* Fix uninitialized 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
|
||||
@@ -7,7 +110,7 @@ Changes:
|
||||
* 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
|
||||
* The global flag `--allow-slow-operations` is split into some explicit flags in different 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.
|
||||
@@ -80,9 +183,9 @@ This release introduces a new output format: JSON result
|
||||
|
||||
Changes:
|
||||
* Users module detects and prints user login time by default. Specifying `--users-compact` to disable it
|
||||
* Fastfetch now requires yyjson 0.8.0 or later, which is embeded in fastfetch source tree. If you build fastfetch with `-DENABLE_SYSTEM_YYJSON` cmake option, you must upgrade your yyjson package
|
||||
* Fastfetch now requires yyjson 0.8.0 or later, which is embedded in fastfetch source tree. If you build fastfetch with `-DENABLE_SYSTEM_YYJSON` cmake option, you must upgrade your yyjson package
|
||||
* Reduced information supported by `--terminal-format`, `--shell-format`
|
||||
* Some config presets (`devinfo` and `verbose`) are obseleted and removed. They are barely maintained and can be replaced with `--format json` now.
|
||||
* Some config presets (`devinfo` and `verbose`) are obsolete and removed. They are barely maintained and can be replaced with `--format json` now.
|
||||
* Custom strings in `--module-key` and `--module-format` are no longer trimmed.
|
||||
* `/boot` is hidden by default (FreeBSD, Disk)
|
||||
|
||||
@@ -162,7 +265,7 @@ Features:
|
||||
# 2.0.2
|
||||
|
||||
Bugfixes:
|
||||
* Workarund [a compiler bug of GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282) (Windows)
|
||||
* Workaround [a compiler bug of GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282) (Windows)
|
||||
* Fix presets not detected by file name (#529)
|
||||
|
||||
Logo:
|
||||
@@ -174,7 +277,7 @@ First stable release of Fastfetch V2
|
||||
|
||||
Changes:
|
||||
* Unescape strings only when parsing `.conf` files
|
||||
* Previously: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\: *`. Note the backslashs are unescaped twice (once by shell and once by fastfetch).
|
||||
* Previously: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\: *`. Note the backslashes are unescaped twice (once by shell and once by fastfetch).
|
||||
* Now: `$ NO_CONFIG=1 fastfetch --os-key \\\\ -s os -l none` prints `\\: *`
|
||||
* Remove option shortcut `-c` (alias of `--color`), which is more commonly used as alias of `--config`
|
||||
* Rename `--recache` to `--logo-recache` (which is used for regenerate image logo cache). Remove option shortcut `-r` (alias of `--recache`).
|
||||
@@ -230,7 +333,7 @@ Features:
|
||||
* Better CPU and Host detection for Android (Android)
|
||||
* Support yakuake terminal version & font detection (Terminal, Linux)
|
||||
* Add new option `--bright-color` which can be used to disable the default bright color of keys, title and ASCII logo.
|
||||
* Add module `Monitor` which prints physical parameters (native resolutions and demensions) of connected monitors
|
||||
* Add module `Monitor` which prints physical parameters (native resolutions and dimensions) of connected monitors
|
||||
* Support path with environment variables for `--logo-source` and `--load-config`.
|
||||
|
||||
Bugfixes:
|
||||
@@ -318,7 +421,7 @@ Bugfixes:
|
||||
* Fix Windows drives detection in WSL (Disk)
|
||||
|
||||
Changes:
|
||||
* In order to make Icons module consistant between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
|
||||
* `--theme-format` no longer supports individual GTK / plasma theme params.
|
||||
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
|
||||
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
|
||||
@@ -341,7 +444,7 @@ Bugfixes:
|
||||
* Fix iTerm being detected as iTermServer-* sometimes
|
||||
* Fix sound device volume being incorrectly detected as muted sometimes (Sound)
|
||||
* Fix memleaks reported by LeakSanitizer (Linux)
|
||||
* Fix potential memory curruption bug in unicode.c (Windows)
|
||||
* Fix potential memory corruption bug in unicode.c (Windows)
|
||||
|
||||
Logo:
|
||||
* Update Windows 11 ASCII logo to look more visually consistent (#445)
|
||||
@@ -377,7 +480,7 @@ Bugfixes:
|
||||
* Fix compiling errors (Windows)
|
||||
|
||||
Improvements:
|
||||
* Improve preformance (WmTheme amd Font, Windows and macOS)
|
||||
* Improve performance (WmTheme amd Font, Windows and macOS)
|
||||
* Enable nonblocking public-ip / weather detection (Android)
|
||||
|
||||
# 1.10.2
|
||||
@@ -422,7 +525,7 @@ Other:
|
||||
|
||||
* Simplified wmtheme output format (Windows)
|
||||
* Improved GPU detection performance on Windows 11
|
||||
* Lastest Mac model identifier support (macOS)
|
||||
* Latest Mac model identifier support (macOS)
|
||||
|
||||
# 1.9.1
|
||||
|
||||
@@ -504,7 +607,7 @@ Bugfixes:
|
||||
This release introduces Windows support! Fastfetch now fully support all major desktop OSes (Linux, macOS, Windows and FreeBSD)
|
||||
|
||||
Notable Changes:
|
||||
* Bios / Board / Chassis modules are splitted against Host module for performance reasons
|
||||
* Bios / Board / Chassis modules are split against Host module for performance reasons
|
||||
* Caching is removed. Option `--nocache` is removed accordingly
|
||||
|
||||
Features:
|
||||
@@ -513,7 +616,7 @@ Features:
|
||||
* Adds a new flag `--stat`, which prints time usage for individual modules
|
||||
* Adds Wifi module which supports Windows and macOS
|
||||
* Adds data source option for logo printing
|
||||
* Detects Homebrew Cellar and Cask seperately
|
||||
* Detects Homebrew Cellar and Cask separately
|
||||
* Detects WSL version
|
||||
* Detects disk based on mount point
|
||||
* Exposes more chafa configs
|
||||
|
||||
+49
-30
@@ -1,9 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.2.0
|
||||
VERSION 2.3.3
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast system information tool"
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
)
|
||||
|
||||
@@ -49,6 +49,7 @@ cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF
|
||||
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF)
|
||||
@@ -71,7 +72,7 @@ cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" O
|
||||
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)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF)
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
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
|
||||
@@ -204,19 +205,32 @@ endif()
|
||||
# Text data #
|
||||
#############
|
||||
|
||||
function(fastfetch_load_text FILENAME OUTVAR)
|
||||
file(READ "${FILENAME}" TEMP)
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
||||
function(fastfetch_encode_c_string STR OUTVAR)
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
|
||||
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||
string(REPLACE "$\\" "" TEMP "${TEMP}") # Remove $\, so we can unescape some things
|
||||
set("${OUTVAR}" "${TEMP}" PARENT_SCOPE)
|
||||
set(${OUTVAR} "\"${TEMP}\"" PARENT_SCOPE)
|
||||
endfunction(fastfetch_encode_c_string)
|
||||
|
||||
function(fastfetch_load_text FILENAME OUTVAR)
|
||||
file(READ "${FILENAME}" TEMP)
|
||||
fastfetch_encode_c_string("${TEMP}" TEMP)
|
||||
set(${OUTVAR} "${TEMP}" PARENT_SCOPE)
|
||||
endfunction(fastfetch_load_text)
|
||||
|
||||
find_package(Python)
|
||||
if(Python_FOUND)
|
||||
# Minify JSON string. `io.open(0,encoding='utf-8')` is needed to avoid encoding issues on Windows
|
||||
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
|
||||
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
|
||||
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
|
||||
else()
|
||||
file(READ "src/data/help.json" TEMP)
|
||||
endif()
|
||||
|
||||
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
|
||||
fastfetch_load_text(src/data/structure.txt DATATEXT_STRUCTURE)
|
||||
fastfetch_load_text(src/data/config_system.txt DATATEXT_CONFIG_SYSTEM)
|
||||
fastfetch_load_text(src/data/config_user.txt DATATEXT_CONFIG_USER)
|
||||
fastfetch_load_text(src/data/config_user.jsonc DATATEXT_CONFIG_USER_JSONC)
|
||||
fastfetch_load_text(src/data/help.txt DATATEXT_HELP)
|
||||
fastfetch_load_text(src/data/help_color.txt DATATEXT_HELP_COLOR)
|
||||
fastfetch_load_text(src/data/help_format.txt DATATEXT_HELP_FORMAT)
|
||||
@@ -228,26 +242,17 @@ if(APPLE)
|
||||
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
|
||||
endif()
|
||||
|
||||
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y")
|
||||
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
|
||||
|
||||
####################
|
||||
# Ascii image data #
|
||||
####################
|
||||
|
||||
function(fastfetch_load_raw_text FILENAME OUTVAR)
|
||||
file(READ "${FILENAME}" TEMP)
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
||||
string(JSON TEMP SET "{}" "${TEMP}" "0") # Encode raw strings using JSON_SET
|
||||
string(REGEX REPLACE "^\\{[ \t\r\n]*" "" TEMP "${TEMP}") # Remove JSON braces
|
||||
string(REGEX REPLACE "[ \t\r\n]*:[ \t\r\n]*0[ \t\r\n]*\\}$" "" TEMP "${TEMP}") # Remove trailing ` : 0 }`
|
||||
if(NOT "${TEMP}" MATCHES "^\"[^\n]*\"")
|
||||
message(FATAL_ERROR "Internal error: unexpected output: '${TEMP}'")
|
||||
endif()
|
||||
set(${OUTVAR} "${TEMP}" PARENT_SCOPE)
|
||||
endfunction(fastfetch_load_raw_text)
|
||||
|
||||
file(GLOB LOGO_FILES "src/logo/ascii/*.txt")
|
||||
set(LOGO_BUILTIN_H "#pragma once\n\n")
|
||||
set(LOGO_BUILTIN_H "#pragma once\n#pragma GCC diagnostic ignored \"-Wtrigraphs\"\n\n")
|
||||
foreach(file ${LOGO_FILES})
|
||||
fastfetch_load_raw_text("${file}" content)
|
||||
fastfetch_load_text("${file}" content)
|
||||
get_filename_component(file "${file}" NAME_WLE)
|
||||
string(TOUPPER "${file}" file)
|
||||
string(REGEX REPLACE "\\$\\{c([0-9]+)\\}" "$\\1" content "${content}")
|
||||
@@ -388,6 +393,7 @@ if(LINUX)
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
@@ -499,6 +505,7 @@ elseif(BSD)
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/diskio/diskio_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
@@ -549,7 +556,7 @@ elseif(APPLE)
|
||||
src/detection/battery/battery_apple.c
|
||||
src/detection/bios/bios_apple.c
|
||||
src/detection/bluetooth/bluetooth_apple.m
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/board/board_apple.c
|
||||
src/detection/brightness/brightness_apple.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
@@ -782,6 +789,10 @@ ff_lib_enable(X11
|
||||
"x11"
|
||||
"X11"
|
||||
)
|
||||
ff_lib_enable(DRM
|
||||
"libdrm"
|
||||
"Libdrm"
|
||||
)
|
||||
ff_lib_enable(GIO
|
||||
"gio-2.0"
|
||||
"GIO"
|
||||
@@ -896,26 +907,23 @@ elseif(APPLE)
|
||||
elseif(WIN32)
|
||||
target_compile_definitions(libfastfetch PRIVATE -D_WIN32_WINNT=0x0601)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "bthprops"
|
||||
PRIVATE "dwmapi"
|
||||
PRIVATE "gdi32"
|
||||
PRIVATE "iphlpapi"
|
||||
PRIVATE "ole32"
|
||||
PRIVATE "oleaut32"
|
||||
PRIVATE "opengl32"
|
||||
PRIVATE "ws2_32"
|
||||
PRIVATE "ntdll"
|
||||
PRIVATE "version"
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "hid"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "dxva2"
|
||||
)
|
||||
elseif(BSD)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "usbhid"
|
||||
PRIVATE "devstat"
|
||||
PRIVATE "geom"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
@@ -1032,6 +1040,12 @@ install(
|
||||
RENAME "${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/fish"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d"
|
||||
RENAME "${CMAKE_PROJECT_NAME}.fish"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/presets"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}"
|
||||
@@ -1042,6 +1056,11 @@ install(
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/fastfetch.1"
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
|
||||
)
|
||||
|
||||
##################
|
||||
# package target #
|
||||
##################
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Here i just add things that are easy to forget.
|
||||
- [ ] ZSH completions
|
||||
- [ ] Fish completions
|
||||
- [ ] Make CPU usage detection much faster and more accurate
|
||||
- [ ] Detect CPU usage in a common detection methode and expose it both to the cpuUsage module and the cpu format string
|
||||
- [ ] Detect CPU usage in a common detection method and expose it both to the cpuUsage module and the cpu format string
|
||||
- [ ] Per session caching
|
||||
|
||||
### General
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Fastfetch
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
[](https://github.com/fastfetch-cli/fastfetch/actions)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/blob/dev/LICENSE)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/graphs/contributors)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L5)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/commits)
|
||||
[](https://formulae.brew.sh/formula/fastfetch#default)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/releases)
|
||||
[](https://github.com/fastfetch-cli/fastfetch/releases)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
|
||||
@@ -62,7 +62,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
* 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`
|
||||
* 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 --mirgrate-config`
|
||||
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --gen-config`
|
||||
|
||||
## Customization
|
||||
|
||||
@@ -85,7 +85,7 @@ Logos can be heavily customized too; see the [logo documentation](https://github
|
||||
## FAQ
|
||||
|
||||
Q: Why do you need a very performant version of neofetch?
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overview whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
|
||||
Q: It does not display [*] correctly for me, what can I do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
|
||||
+5
-6
@@ -5,7 +5,7 @@ __fastfetch_complete_help()
|
||||
local __ff_helps=(
|
||||
"color"
|
||||
"format"
|
||||
"load-config"
|
||||
"config"
|
||||
"os-format"
|
||||
"host-format"
|
||||
"kernel-format"
|
||||
@@ -66,7 +66,7 @@ __fastfetch_complete_path()
|
||||
|
||||
__fastfetch_complete_logo()
|
||||
{
|
||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos-autocompletion)" -- "$CURRENT_WORD"))
|
||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos autocompletion)" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_logo_type()
|
||||
@@ -182,7 +182,6 @@ __fastfetch_completion()
|
||||
"--cpu-temp"
|
||||
"--gpu-temp"
|
||||
"--battery-temp"
|
||||
"--display-detect-name"
|
||||
"--display-precise-refresh-rate"
|
||||
"--localip-show-ipv4"
|
||||
"--localip-show-ipv6"
|
||||
@@ -218,10 +217,9 @@ __fastfetch_completion()
|
||||
"--logo-color-6"
|
||||
"--logo-color-7"
|
||||
"--logo-color-8"
|
||||
"--logo-color-9"
|
||||
"--logo-width"
|
||||
"--logo-height"
|
||||
"--logo-color-9"
|
||||
"-c"
|
||||
"--color"
|
||||
"--color-keys"
|
||||
"--color-title"
|
||||
@@ -360,7 +358,8 @@ __fastfetch_completion()
|
||||
)
|
||||
|
||||
local FF_OPTIONS_PATH=(
|
||||
"--load-config"
|
||||
"-c"
|
||||
"--config"
|
||||
"--os-file"
|
||||
"--lib-pci"
|
||||
"--lib-vulkan"
|
||||
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
if not type -q fastfetch
|
||||
return
|
||||
end
|
||||
|
||||
complete -c fastfetch -f
|
||||
|
||||
function __fastfetch_complete_bool
|
||||
echo -e "true\tBool"
|
||||
echo -e "false\tBool"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_color
|
||||
echo -e "black\tColor"
|
||||
echo -e "red\tColor"
|
||||
echo -e "green\tColor"
|
||||
echo -e "yellow\tColor"
|
||||
echo -e "blue\tColor"
|
||||
echo -e "magenta\tColor"
|
||||
echo -e "cyan\tColor"
|
||||
echo -e "white\tColor"
|
||||
echo -e "default\tColor"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_command
|
||||
for line in (fastfetch --list-modules autocompletion)
|
||||
set -l pair (string split -m 2 : $line)
|
||||
set -l module (string lower $pair[1])
|
||||
|
||||
echo -e "$module-format\tModule format"
|
||||
end
|
||||
echo -e "format\tCustom format"
|
||||
echo -e "color\tColor format"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_config
|
||||
for line in (fastfetch --list-presets autocompletion)
|
||||
echo -e "$line\tPreset"
|
||||
end
|
||||
echo -e "none\tDisable loading config file"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_logo
|
||||
for line in (fastfetch --list-logos autocompletion)
|
||||
echo -e "$line\tBuiltin logo"
|
||||
end
|
||||
echo -e "none\tDon't print logo"
|
||||
echo -e "small\tPrint small ascii logo if available"
|
||||
end
|
||||
|
||||
function __fastfetch_complete_structure
|
||||
for line in (fastfetch --list-modules autocompletion)
|
||||
set -l pair (string split -m 2 : $line)
|
||||
echo -e "$pair[1]\t$pair[2]"
|
||||
end
|
||||
end
|
||||
|
||||
string match -r -a -g "^###> ?(.*)" < (status -f) | string collect | python3 | source
|
||||
|
||||
###> #!/usr/bin/env python3
|
||||
###>
|
||||
###> import json, subprocess, sys
|
||||
###>
|
||||
###> def main():
|
||||
###> data: dict[str, list[dict]] = json.loads(subprocess.check_output(['fastfetch', '--help-raw']))
|
||||
###>
|
||||
###> for key in data:
|
||||
###> for flag in data[key]:
|
||||
###> if flag.get('pseudo', False):
|
||||
###> continue
|
||||
###>
|
||||
###> command_prefix: str = f'complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}"';
|
||||
###> if 'short' in flag:
|
||||
###> command_prefix += f' -o "{flag["short"]}"'
|
||||
###>
|
||||
###> if 'arg' in flag:
|
||||
###> type: str = flag['arg']['type'];
|
||||
###> if type == 'bool':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_bool)"')
|
||||
###> elif type == 'color':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_color)"')
|
||||
###> elif type == 'command':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_command)"')
|
||||
###> elif type == 'config':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_config)"')
|
||||
###> elif type == 'enum':
|
||||
###> temp: str = ' '.join(map(lambda x: f"{x[0]}\\t{x[1]}", flag["arg"]["enum"].items()))
|
||||
###> print(f'{command_prefix} -x -a "{temp}"')
|
||||
###> elif type == 'logo':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_logo)"')
|
||||
###> elif type == 'structure':
|
||||
###> print(f'{command_prefix} -x -a "(__fish_complete_list : __fastfetch_complete_structure)"')
|
||||
###> elif type == 'path':
|
||||
###> print(f'{command_prefix} -r -F')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -x')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -f')
|
||||
###>
|
||||
###> if __name__ == "__main__":
|
||||
###> try:
|
||||
###> main()
|
||||
###> except:
|
||||
###> sys.exit(1)
|
||||
###>
|
||||
@@ -0,0 +1,134 @@
|
||||
.TH FASTFETCH 1 "@FASTFETCH_BUILD_DATE@" "@CMAKE_PROJECT_NAME@ @CMAKE_PROJECT_VERSION@"
|
||||
|
||||
.SH NAME
|
||||
fastfetch \- a neofetch\-like tool for fetching system information and
|
||||
displaying them in a pretty way
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
.B fastfetch
|
||||
.I [options...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
Fastfetch is a neofetch\-like tool for fetching system information and
|
||||
displaying them in a pretty way. It is written mainly in C, with performance
|
||||
and customizability in mind.
|
||||
Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
|
||||
|
||||
.SH "EXIT STATUS"
|
||||
|
||||
On successful execution, fastfetch returns zero. If any error happened,
|
||||
the exit code will be non\-zero.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.SS "Informative Options"
|
||||
.TP
|
||||
|
||||
.B \-h, \-\-help \fI [command]
|
||||
Show help output, displaying all available options or help for given command
|
||||
.TP
|
||||
|
||||
.B \-v, \-\-version
|
||||
Show version of fastfetch
|
||||
.TP
|
||||
|
||||
.B \-\-list\-config\-paths
|
||||
List search paths of config files
|
||||
.TP
|
||||
|
||||
.B \-\-list\-data\-paths
|
||||
List search paths of presets and logos
|
||||
.TP
|
||||
|
||||
.B \-\-list\-logos
|
||||
List available logos, they can be loaded with \fI \-\-logo
|
||||
.TP
|
||||
|
||||
.B \-\-list\-modules
|
||||
List available modules
|
||||
.TP
|
||||
|
||||
.B \-\-list\-presets
|
||||
List available presets, they can be loaded with \fI \-\-config
|
||||
.TP
|
||||
|
||||
.B \-\-list\-features
|
||||
List the supported features fastfetch was compiled with
|
||||
.TP
|
||||
|
||||
.B \-\-print\-logos
|
||||
Print available logos
|
||||
.TP
|
||||
|
||||
.B \-\-print\-structure
|
||||
Print the default structure
|
||||
|
||||
|
||||
.SS "Display Options"
|
||||
.TP
|
||||
|
||||
.B \-l, \-\-logo \fI <logo>
|
||||
Set the logo to display
|
||||
.TP
|
||||
|
||||
.B \-s, \-\-structure \fI <structure>
|
||||
Set the structure of the fetch. For details about the structure,
|
||||
see the CONFIGURATION section.
|
||||
|
||||
|
||||
.SS "Config Options"
|
||||
.TP
|
||||
|
||||
.B \-c, \-\-config \fI <config>
|
||||
Use the specified config file or preset. If "none", disable further config
|
||||
loading. For details about config files, see the CONFIGURATION section
|
||||
.TP
|
||||
|
||||
.B \-\-gen\-config \fI [file]
|
||||
Generate a config file with options specified on the command line.
|
||||
If \fI file \fR is specified, the configuration will written to the
|
||||
file, otherwise it will be written to stdout.
|
||||
.TP
|
||||
|
||||
.B \-\-gen\-config\-force \fI [file]
|
||||
Same as \fB \-\-gen\-config\fR, but overwrites existing config
|
||||
.TP
|
||||
|
||||
|
||||
To list all options, use \fB \-\-help\fR this will also print all available module options.
|
||||
|
||||
.SH CONFIGURATION
|
||||
.SS "Fetch Structure"
|
||||
The structure of a fetch describes the modules that should be included in
|
||||
the output. It consists of a string of modules, separated by a colon (:).
|
||||
To list all available modules, use \fB \-\-list\-modules \fR
|
||||
|
||||
.SS "Config Files"
|
||||
|
||||
fastfetch supports two types of config files. The legacy
|
||||
configuration files and a JSONC based format.
|
||||
|
||||
A JSONC config file is a JSON file that also supports comments with (//). Those
|
||||
files must have the extension '.jsonc'. You can migrate a legacy config
|
||||
file to the JSONC format by using \fB\-\-gen\-config\fR.
|
||||
|
||||
The specified configuration/preset files are searched in the following order:
|
||||
|
||||
1. relative to the current working directory
|
||||
|
||||
2. relative to ~/.local/share/fastfetch/presets/
|
||||
|
||||
3. relative to /usr/share/fastfetch/presets/
|
||||
|
||||
When both a '.jsonc' and a '.conf' file with the same name is found,
|
||||
the '.jsonc' file is preferred.
|
||||
|
||||
Fastfetch provides some default presets. List them with \fB \-\-print\-available\-presets\fR.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR neofetch (1)
|
||||
|
||||
.SH BUGS
|
||||
Please report bugs to:\fI https://github.com/fastfetch\-cli/fastfetch/issues \fR
|
||||
+13
-9
@@ -156,7 +156,7 @@
|
||||
"description": "Whether to print the remaining logo, if it has more lines than modules to display",
|
||||
"default": false
|
||||
},
|
||||
"preserveAspectRadio": {
|
||||
"preserveAspectRatio": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to preserve the aspect ratio of the logo. Supported by iTerm image protocol",
|
||||
"default": false
|
||||
@@ -415,7 +415,7 @@
|
||||
"description": "Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both, 6 for bar only, 9 for colored number",
|
||||
"minimum": 0,
|
||||
"maximum": 255,
|
||||
"default": 1
|
||||
"default": 9
|
||||
},
|
||||
"ndigits": {
|
||||
"type": "number",
|
||||
@@ -452,7 +452,7 @@
|
||||
},
|
||||
"wayland": {
|
||||
"type": "string",
|
||||
"description": "Better display performance and output in wayland sessions.\nSupports different refresh rates per monitor.\n(Linux)"
|
||||
"description": "Better display performance and output in wayland sessions.\nSupports different refresh rates per monitor.\n(Linux, FreeBSD)"
|
||||
},
|
||||
"xcbRandr": {
|
||||
"type": "string",
|
||||
@@ -470,6 +470,10 @@
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)"
|
||||
},
|
||||
"drm": {
|
||||
"type": "string",
|
||||
"description": "Used for fast resolution and refresh rate detection (Linux)"
|
||||
},
|
||||
"gio": {
|
||||
"type": "string",
|
||||
"description": "Needed for values that are only stored GSettings (Linux, FreeBSD)"
|
||||
@@ -729,15 +733,15 @@
|
||||
},
|
||||
{
|
||||
"const": "theme",
|
||||
"description": "Print current theme information"
|
||||
"description": "Print current theme of desktop environment"
|
||||
},
|
||||
{
|
||||
"const": "uptime",
|
||||
"description": "Print system uptime"
|
||||
"description": "Print how long system has been running"
|
||||
},
|
||||
{
|
||||
"const": "users",
|
||||
"description": "List users currently logged in"
|
||||
"description": "Print users currently logged in"
|
||||
},
|
||||
{
|
||||
"const": "version",
|
||||
@@ -844,7 +848,7 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "brightness",
|
||||
"description": "Print current brightness / luminance of your monitors"
|
||||
"description": "Print current brightness level of your monitors"
|
||||
},
|
||||
"ddcciSleep": {
|
||||
"type": "integer",
|
||||
@@ -1033,7 +1037,7 @@
|
||||
"preciseRefreshRate": {
|
||||
"description": "Set if decimal refresh rates should not be rounded into integers when printing",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
@@ -1059,7 +1063,7 @@
|
||||
},
|
||||
"folders": {
|
||||
"type": "string",
|
||||
"description": "A colon (semicolon on Windows) separated list of folder paths for the disk output\nDefault: \"/:/home\" (\"C:\\\\;D:\\\\ ...\" on Windows)"
|
||||
"description": "A colon (semicolon on Windows) separated list of folder paths for the disk output\nDefault: auto detection using mount-points"
|
||||
},
|
||||
"showExternal": {
|
||||
"type": "boolean",
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
-c all
|
||||
--pipe
|
||||
--show-errors
|
||||
--no-buffer
|
||||
--publicip-timeout 1000
|
||||
--weather-timeout 1000
|
||||
--stat
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"display": {
|
||||
"stat": true,
|
||||
"pipe": true,
|
||||
"showErrors": true,
|
||||
"noBuffer": true
|
||||
},
|
||||
"modules": [
|
||||
"title",
|
||||
"separator",
|
||||
"os",
|
||||
"host",
|
||||
"bios",
|
||||
"board",
|
||||
"chassis",
|
||||
"kernel",
|
||||
"uptime",
|
||||
"processes",
|
||||
"packages",
|
||||
"shell",
|
||||
"display",
|
||||
"brightness",
|
||||
"monitor",
|
||||
"lm",
|
||||
"de",
|
||||
"wm",
|
||||
"wmtheme",
|
||||
"theme",
|
||||
"icons",
|
||||
"font",
|
||||
"cursor",
|
||||
"wallpaper",
|
||||
"terminal",
|
||||
"terminalfont",
|
||||
"terminalsize",
|
||||
"cpu",
|
||||
"cpuusage",
|
||||
"gpu",
|
||||
"memory",
|
||||
"swap",
|
||||
"disk",
|
||||
"battery",
|
||||
"poweradapter",
|
||||
"player",
|
||||
"media",
|
||||
"publicip",
|
||||
"localip",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
"vulkan",
|
||||
"opengl",
|
||||
"opencl",
|
||||
"users",
|
||||
"bluetooth",
|
||||
"sound",
|
||||
"gamepad",
|
||||
{
|
||||
"type": "weather",
|
||||
"timeout": 1000
|
||||
},
|
||||
"netio",
|
||||
"diskio",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
]
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"percentType": 9,
|
||||
"separator": "\u001b[31m-> "
|
||||
},
|
||||
"modules": [
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
"color": {
|
||||
"keys": "magenta"
|
||||
},
|
||||
"sizeNdigits": 0,
|
||||
"sizeMaxPrefix": "MB",
|
||||
"percentType": 9
|
||||
"size": {
|
||||
"ndigits": 0,
|
||||
"maxPrefix": "MB"
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"type": "small"
|
||||
},
|
||||
"display": {
|
||||
"percentType": 6,
|
||||
"keyWidth": 11,
|
||||
"bar": {
|
||||
"charElapsed": "=",
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_bar
|
||||
#define FF_INCLUDED_common_bar
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
enum
|
||||
@@ -15,5 +12,3 @@ enum
|
||||
|
||||
void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, uint8_t red);
|
||||
void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t yellow, bool parentheses);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_commandoption
|
||||
#define FF_INCLUDED_common_commandoption
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCustomValue
|
||||
@@ -17,12 +14,10 @@ typedef struct FFdata
|
||||
{
|
||||
FFstrbuf structure;
|
||||
FFlist customValues; // List of FFCustomValue
|
||||
bool loadUserConfig;
|
||||
bool configLoaded;
|
||||
} FFdata;
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value);
|
||||
void ffPrepareCommandOption(FFdata* data);
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_dbus
|
||||
#define FF_INCLUDED_common_dbus
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
@@ -54,4 +51,3 @@ DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char
|
||||
void ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
|
||||
|
||||
#endif // FF_HAVE_DBUS
|
||||
#endif // FF_INCLUDED_common_dbus
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_font
|
||||
#define FF_INCLUDED_common_font
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "util/FFlist.h"
|
||||
|
||||
@@ -21,5 +18,3 @@ void ffFontInitCopy(FFfont* font, const char* name);
|
||||
void ffFontInitValues(FFfont* font, const char* name, const char* size);
|
||||
void ffFontInitWithSpace(FFfont* font, const char* rawName);
|
||||
void ffFontDestroy(FFfont* font);
|
||||
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -203,7 +203,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
}
|
||||
|
||||
// fastforward to the end of the if without printing the in between
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increament it again directly after continue
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{?}") + 2; // 2 is the length of "{?}" - 1 because the loop will increment it again directly after continue
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
}
|
||||
|
||||
// fastforward to the end of the if without printing the in between
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increament it again directly after continue
|
||||
i = ffStrbufNextIndexS(formatstr, i, "{/}") + 2; // 2 is the length of "{/}" - 1 because the loop will increment it again directly after continue
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_format
|
||||
#define FF_INCLUDED_common_format
|
||||
|
||||
typedef enum FFformatargtype
|
||||
{
|
||||
FF_FORMAT_ARG_TYPE_NULL = 0,
|
||||
@@ -27,5 +24,3 @@ typedef struct FFformatarg
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
|
||||
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -144,7 +144,7 @@ static void destroyState(void)
|
||||
ffPlatformDestroy(&instance.state.platform);
|
||||
yyjson_doc_free(instance.state.configDoc);
|
||||
yyjson_mut_doc_free(instance.state.resultDoc);
|
||||
ffStrbufDestroy(&instance.state.migrateConfigPath);
|
||||
ffStrbufDestroy(&instance.state.genConfigPath);
|
||||
}
|
||||
|
||||
void ffDestroyInstance(void)
|
||||
@@ -181,6 +181,9 @@ void ffListFeatures(void)
|
||||
#ifdef FF_HAVE_X11
|
||||
"x11\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_DRM
|
||||
"drm\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_GIO
|
||||
"gio\n"
|
||||
#endif
|
||||
|
||||
+8
-9
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_io_io
|
||||
#define FF_INCLUDED_common_io_io
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -14,6 +11,10 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
typedef int FFNativeFD;
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
|
||||
#define PROC_FILE_BUFFSIZ 8192
|
||||
#endif
|
||||
|
||||
static inline FFNativeFD FFUnixFD2NativeFD(int unixfd)
|
||||
@@ -52,11 +53,11 @@ static inline ssize_t ffReadFDData(FFNativeFD fd, size_t dataSize, void* data)
|
||||
#ifndef _WIN32
|
||||
return read(fd, data, dataSize);
|
||||
#else
|
||||
DWORD readed;
|
||||
if(!ReadFile(fd, data, (DWORD)dataSize, &readed, NULL))
|
||||
DWORD bytesRead;
|
||||
if(!ReadFile(fd, data, (DWORD)dataSize, &bytesRead, NULL))
|
||||
return -1;
|
||||
|
||||
return (ssize_t)readed;
|
||||
return (ssize_t)bytesRead;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -102,7 +103,7 @@ static inline void ffUnsuppressIO(bool* suppressed)
|
||||
|
||||
#define FF_SUPPRESS_IO() bool __attribute__((__cleanup__(ffUnsuppressIO), __unused__)) io_suppressed__ = ffSuppressIO(true)
|
||||
|
||||
void ffListFilesRecursively(const char* path);
|
||||
void ffListFilesRecursively(const char* path, bool pretty);
|
||||
|
||||
static inline bool wrapClose(FFNativeFD* pfd)
|
||||
{
|
||||
@@ -153,5 +154,3 @@ static inline bool wrapClosedir(HANDLE* pdir)
|
||||
}
|
||||
#endif
|
||||
#define FF_AUTO_CLOSE_DIR __attribute__((__cleanup__(wrapClosedir)))
|
||||
|
||||
#endif // FF_INCLUDED_common_io_io
|
||||
|
||||
+51
-25
@@ -16,18 +16,18 @@ static void createSubfolders(const char* fileName)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
|
||||
while(*fileName != '\0')
|
||||
char *token = NULL;
|
||||
while((token = strchr(fileName, '/')) != NULL)
|
||||
{
|
||||
ffStrbufAppendC(&path, *fileName);
|
||||
if(*fileName == '/')
|
||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
++fileName;
|
||||
ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
|
||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
fileName = token + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
|
||||
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
@@ -44,20 +44,35 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
|
||||
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t readed = 0;
|
||||
ssize_t bytesRead = 0;
|
||||
|
||||
struct stat fileInfo;
|
||||
if(fstat(fd, &fileInfo) != 0)
|
||||
return false;
|
||||
|
||||
ffStrbufEnsureFree(buffer, fileInfo.st_size > 0 ? (uint32_t)fileInfo.st_size : 31);
|
||||
if (fileInfo.st_size > 0)
|
||||
{
|
||||
// optimize for files has a fixed length,
|
||||
// file can be very large, only keep necessary memory to save time and resources.
|
||||
ffStrbufEnsureFixedLengthFree(buffer, (uint32_t)fileInfo.st_size);
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureFree(buffer, 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
// procfs file's st_size is always zero
|
||||
// choose a signed int type so that can store a native number
|
||||
ssize_t remain = fileInfo.st_size;
|
||||
|
||||
while(
|
||||
(readed = read(fd, buffer->chars + buffer->length, free)) > 0
|
||||
(bytesRead = read(fd, buffer->chars + buffer->length, free)) > 0
|
||||
) {
|
||||
buffer->length += (uint32_t) readed;
|
||||
if((uint32_t) readed == free)
|
||||
buffer->length += (uint32_t) bytesRead;
|
||||
// if remain > 0, it means there is some data left in the file.
|
||||
// if remain == 0, it means reading has completed, no need to grow up the buffer.
|
||||
// if remain < 0, we are reading a file from procfs/sysfs and its st_size is zero,
|
||||
// we cannot detect how many data remains in the file, we only can call ffStrbufEnsureFree and read again.
|
||||
remain -= bytesRead;
|
||||
if((uint32_t) bytesRead == free && remain != 0)
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
@@ -72,7 +87,7 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
{
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY);
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC);
|
||||
if(fd == -1)
|
||||
return -1;
|
||||
|
||||
@@ -81,7 +96,7 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY);
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, O_RDONLY | O_CLOEXEC);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
|
||||
@@ -94,7 +109,7 @@ bool ffPathExists(const char* path, FFPathType type)
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
|
||||
int mode = fileStat.st_mode & S_IFMT;
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
|
||||
if(type & FF_PATHTYPE_REGULAR && mode == S_IFREG)
|
||||
return true;
|
||||
@@ -153,14 +168,14 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
ssize_t readed = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
|
||||
if(readed <= 0)
|
||||
if(bytesRead <= 0)
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
|
||||
buffer[readed] = '\0';
|
||||
buffer[bytesRead] = '\0';
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
@@ -184,7 +199,7 @@ bool ffSuppressIO(bool suppress)
|
||||
|
||||
origOut = dup(STDOUT_FILENO);
|
||||
origErr = dup(STDERR_FILENO);
|
||||
nullFile = open("/dev/null", O_WRONLY);
|
||||
nullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
|
||||
init = true;
|
||||
}
|
||||
|
||||
@@ -199,7 +214,7 @@ bool ffSuppressIO(bool suppress)
|
||||
return true;
|
||||
}
|
||||
|
||||
void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* folderName)
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
{
|
||||
DIR* dir = opendir(folder->chars);
|
||||
if(dir == NULL)
|
||||
@@ -207,8 +222,12 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol
|
||||
|
||||
uint32_t folderLength = folder->length;
|
||||
|
||||
if(folderName != NULL)
|
||||
if(pretty && folderName != NULL)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation - 1; i++)
|
||||
fputs(" | ", stdout);
|
||||
printf("%s/\n", folderName);
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
|
||||
@@ -221,13 +240,20 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol
|
||||
|
||||
ffStrbufAppendS(folder, entry->d_name);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(folder, (uint8_t) (indentation + 1), entry->d_name);
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
if (pretty)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(folder->chars + baseLength, stdout);
|
||||
}
|
||||
|
||||
puts(entry->d_name);
|
||||
}
|
||||
@@ -235,9 +261,9 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
void ffListFilesRecursively(const char* path)
|
||||
void ffListFilesRecursively(const char* path, bool pretty)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||
listFilesRecursively(&folder, 0, NULL);
|
||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
||||
}
|
||||
|
||||
+40
-19
@@ -6,12 +6,12 @@
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
while(*fileName != '\0')
|
||||
char *token = NULL;
|
||||
while((token = strchr(fileName, '/')) != NULL)
|
||||
{
|
||||
ffStrbufAppendC(&path, *fileName);
|
||||
if(*fileName == '/')
|
||||
CreateDirectoryA(path.chars, NULL);
|
||||
++fileName;
|
||||
ffStrbufAppendNS(&path, (uint32_t)(token - fileName + 1), fileName);
|
||||
CreateDirectoryA(path.chars, NULL);
|
||||
fileName = token + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,22 +32,31 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
|
||||
bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
|
||||
{
|
||||
DWORD readed = 0;
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if(!GetFileSizeEx(handle, &fileSize))
|
||||
fileSize.QuadPart = 0;
|
||||
|
||||
ffStrbufEnsureFree(buffer, fileSize.QuadPart > 0 ? (uint32_t)fileSize.QuadPart : 31);
|
||||
|
||||
if (fileSize.QuadPart > 0)
|
||||
{
|
||||
// optimize for files has a fixed length,
|
||||
// file can be very large, only keep necessary memory to save time and resources.
|
||||
ffStrbufEnsureFixedLengthFree(buffer, (uint32_t)fileSize.QuadPart);
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureFree(buffer, 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
ssize_t remain = fileSize.QuadPart;
|
||||
|
||||
bool success;
|
||||
while(
|
||||
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &readed, NULL)) &&
|
||||
readed > 0
|
||||
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &bytesRead, NULL)) &&
|
||||
bytesRead > 0
|
||||
) {
|
||||
buffer->length += (uint32_t) readed;
|
||||
if((uint32_t) readed == free)
|
||||
buffer->length += (uint32_t) bytesRead;
|
||||
remain -= (ssize_t)bytesRead;
|
||||
if((uint32_t) bytesRead == free && remain != 0)
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
@@ -114,16 +123,21 @@ bool ffSuppressIO(bool suppress)
|
||||
return false;
|
||||
}
|
||||
|
||||
void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* folderName)
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
{
|
||||
uint32_t folderLength = folder->length;
|
||||
|
||||
if(folderName != NULL)
|
||||
if(pretty && folderName != NULL)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation - 1; i++)
|
||||
fputs(" | ", stdout);
|
||||
printf("%s/\n", folderName);
|
||||
}
|
||||
|
||||
ffStrbufAppendC(folder, '*');
|
||||
WIN32_FIND_DATAA entry;
|
||||
HANDLE hFind = FindFirstFileA(folder->chars, &entry);
|
||||
ffStrbufTrimRight(folder, '*');
|
||||
if(hFind == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
@@ -137,24 +151,31 @@ void listFilesRecursively(FFstrbuf* folder, uint8_t indentation, const char* fol
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
ffStrbufAppendS(folder, entry.cFileName);
|
||||
ffStrbufAppendC(folder, '/');
|
||||
listFilesRecursively(folder, (uint8_t) (indentation + 1), entry.cFileName);
|
||||
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry.cFileName, pretty);
|
||||
ffStrbufSubstrBefore(folder, folderLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
if (pretty)
|
||||
{
|
||||
for(uint8_t i = 0; i < indentation; i++)
|
||||
fputs(" | ", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(folder->chars + baseLength, stdout);
|
||||
}
|
||||
|
||||
puts(entry.cFileName);
|
||||
} while (FindNextFileA(hFind, &entry));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
void ffListFilesRecursively(const char* path)
|
||||
void ffListFilesRecursively(const char* path, bool pretty)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY folder = ffStrbufCreateS(path);
|
||||
ffStrbufEnsureEndsWithC(&folder, '/');
|
||||
listFilesRecursively(&folder, 0, NULL);
|
||||
listFilesRecursively(folder.length, &folder, 0, NULL, pretty);
|
||||
}
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_library
|
||||
#define FF_INCLUDED_common_library
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.h"
|
||||
|
||||
@@ -74,5 +71,3 @@ static inline void ffLibraryUnload(void** handle)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_networking
|
||||
#define FF_INCLUDED_common_networking
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
@@ -35,5 +32,3 @@ static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint3
|
||||
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@ struct yyjson_mut_val;
|
||||
typedef struct FFModuleBaseInfo
|
||||
{
|
||||
const char* name;
|
||||
const char* description;
|
||||
// A dirty polymorphic implementation in C.
|
||||
// This is UB, because `void*` is not compatible with `FF*Options*`.
|
||||
// However we can't do it better unless we move to C++, so that `option` becomes a `this` pointer
|
||||
@@ -25,6 +26,7 @@ typedef struct FFModuleBaseInfo
|
||||
static inline void ffOptionInitModuleBaseInfo(
|
||||
FFModuleBaseInfo* baseInfo,
|
||||
const char* name,
|
||||
const char* description,
|
||||
void* parseCommandOptions, // bool (*const parseCommandOptions)(void* options, const char* key, const char* value)
|
||||
void* parseJsonObject, // void (*const parseJsonObject)(void* options, yyjson_val *module)
|
||||
void* printModule, // void (*const printModule)(void* options)
|
||||
@@ -34,6 +36,7 @@ static inline void ffOptionInitModuleBaseInfo(
|
||||
)
|
||||
{
|
||||
baseInfo->name = name;
|
||||
baseInfo->description = description;
|
||||
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
||||
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
||||
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_parsing_h
|
||||
#define FF_INCLUDED_parsing_h
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -24,5 +21,3 @@ int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result);
|
||||
void ffParseTemperature(double celsius, FFstrbuf* buffer);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
{
|
||||
ffLogoPrintLine();
|
||||
|
||||
//This is used by --set-keyless, in this case we wan't neither the module name nor the separator
|
||||
//This is used by --set-keyless, in this case we want neither the module name nor the separator
|
||||
if(moduleName == NULL)
|
||||
return;
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_printing
|
||||
#define FF_INCLUDED_common_printing
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
|
||||
@@ -26,5 +23,3 @@ void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
|
||||
void ffPrintModuleFormatHelp(const char* name, const char* def, uint32_t numArgs, const char* args[]);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_processing
|
||||
#define FF_INCLUDED_common_processing
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr);
|
||||
@@ -28,5 +25,3 @@ static inline const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const ar
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,49 +11,62 @@
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
enum { FF_PIPE_BUFSIZ = 4096 };
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
static inline void waitpid_wrapper(pid_t* pid)
|
||||
static inline void waitpid_wrapper(const pid_t* pid)
|
||||
{
|
||||
// remove zombie processes
|
||||
if (*pid > 0)
|
||||
waitpid(*pid, NULL, 0);
|
||||
}
|
||||
|
||||
static inline int ffPipe2(int *fds, int flags)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
if(pipe(fds) == -1)
|
||||
return -1;
|
||||
fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | flags);
|
||||
fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | flags);
|
||||
return 0;
|
||||
#else
|
||||
return pipe2(fds, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||
{
|
||||
int pipes[2];
|
||||
const int timeout = instance.config.general.processingTimeout;
|
||||
|
||||
if(pipe(pipes) == -1)
|
||||
if(ffPipe2(pipes, O_CLOEXEC) == -1)
|
||||
return "pipe() failed";
|
||||
|
||||
__attribute__((__cleanup__(waitpid_wrapper))) pid_t childPid = fork();
|
||||
if(childPid == -1)
|
||||
{
|
||||
close(pipes[0]);
|
||||
close(pipes[1]);
|
||||
return "fork() failed";
|
||||
}
|
||||
|
||||
//Child
|
||||
if(childPid == 0)
|
||||
{
|
||||
int nullFile = open("/dev/null", O_WRONLY);
|
||||
int nullFile = open("/dev/null", O_WRONLY | O_CLOEXEC);
|
||||
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
||||
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||
close(pipes[0]);
|
||||
close(pipes[1]);
|
||||
setenv("LANG", "C", 1);
|
||||
execvp(argv[0], argv);
|
||||
exit(901);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
//Parent
|
||||
close(pipes[1]);
|
||||
|
||||
int FF_AUTO_CLOSE_FD childPipeFd = pipes[0];
|
||||
char str[FF_PIPE_BUFSIZ];
|
||||
|
||||
int timeout = instance.config.general.processingTimeout;
|
||||
if (timeout >= 0)
|
||||
fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
do
|
||||
while(1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
{
|
||||
@@ -70,18 +83,14 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
|
||||
}
|
||||
}
|
||||
|
||||
char str[FF_PIPE_BUFSIZ];
|
||||
while (true)
|
||||
{
|
||||
ssize_t nRead = read(childPipeFd, str, FF_PIPE_BUFSIZ);
|
||||
if (nRead > 0)
|
||||
ffStrbufAppendNS(buffer, (uint32_t) nRead, str);
|
||||
else if (nRead == 0)
|
||||
return NULL;
|
||||
else if (nRead < 0)
|
||||
break;
|
||||
}
|
||||
} while (errno == EAGAIN);
|
||||
ssize_t nRead = read(childPipeFd, str, FF_PIPE_BUFSIZ);
|
||||
if (nRead > 0)
|
||||
ffStrbufAppendNS(buffer, (uint32_t) nRead, str);
|
||||
else if (nRead == 0)
|
||||
return NULL;
|
||||
else if (nRead < 0)
|
||||
break;
|
||||
};
|
||||
|
||||
return NULL;
|
||||
return "read(childPipeFd, str, FF_PIPE_BUFSIZ) failed";
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
enum { FF_PIPE_BUFSIZ = 4096 };
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
|
||||
|
||||
// The following functions return true if the file was found, independently if start was found
|
||||
// Buffers which already contain content are not overwritten
|
||||
// The last occurence of start in the first file will be the one used
|
||||
// The last occurrence of start in the first file will be the one used
|
||||
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_properties
|
||||
#define FF_INCLUDED_common_properties
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFpropquery
|
||||
@@ -51,5 +48,3 @@ static inline bool ffParsePropFileData(const char* relativeFile, const char* sta
|
||||
{
|
||||
return ffParsePropFileDataValues(relativeFile, 1, (FFpropquery[]){{start, buffer}});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_settings
|
||||
#define FF_INCLUDED_common_settings
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef enum FFvarianttype
|
||||
@@ -38,5 +35,3 @@ bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
#elif defined(__FreeBSD__)
|
||||
bool ffSettingsGetFreeBSDKenv(const char* propName, FFstrbuf* result);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_sysctl
|
||||
#define FF_INCLUDED_common_sysctl
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.h"
|
||||
|
||||
@@ -13,5 +10,3 @@ const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_thread
|
||||
#define FF_INCLUDED_common_thread
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
@@ -82,5 +79,3 @@
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType)
|
||||
#endif //FF_HAVE_THREADS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_time
|
||||
#define FF_INCLUDED_common_time
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef _WIN32
|
||||
#include <synchapi.h>
|
||||
@@ -48,5 +45,3 @@ static inline void ffTimeSleep(uint32_t msec)
|
||||
nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Fastfetch system configuration
|
||||
# This file sets the default config for all users of the system.
|
||||
|
||||
# For more information about how configuration files work,
|
||||
# see ~/.config/fastfetch/config.conf, generated during first run.
|
||||
# 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
|
||||
# to overwrite this file with the current default file.
|
||||
|
||||
# User config option
|
||||
# Sets if fastfetch should load user provided configuration.
|
||||
# If this is off, fastfetch ignores the user config file and any passed arguments
|
||||
# Must be true or false
|
||||
# Default is true.
|
||||
#--load-user-config true
|
||||
@@ -1,43 +0,0 @@
|
||||
// ~/.config/fastfetch/config.jsonc
|
||||
// See https://github.com/fastfetch-cli/fastfetch/wiki/Configuration for more details
|
||||
// See *.jsonc in https://github.com/fastfetch-cli/fastfetch/tree/dev/presets/examples for more examples
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"padding": {
|
||||
"top": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"percentType": 9 // colored percent number
|
||||
},
|
||||
"modules": [
|
||||
"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"
|
||||
]
|
||||
}
|
||||
@@ -1,519 +0,0 @@
|
||||
# Fastfetch configuration
|
||||
# Write every argument in different lines.
|
||||
# Direct arguments will overwrite the corresponding ones in this file.
|
||||
# Argument keys are not case sensitive.
|
||||
# Whitespaces are trimmed at the beginning and the end.
|
||||
# Empty lines or lines starting with # are ignored.
|
||||
|
||||
# This file was shipped with $" FASTFETCH_PROJECT_VERSION $".
|
||||
# Use fastfetch --gen-config-force to overwrite this file with the current defaults
|
||||
|
||||
# Below some often usefull options are listed. Uncomment and modify them so they take affect.
|
||||
# Note that there are a lot more options than the ones listed here, take a look at "fastfetch --help".
|
||||
# Of course all of them can be made persistent here too.
|
||||
|
||||
# Config option:
|
||||
# Load additional config files.
|
||||
# Some are shipped with fastfetch, list them with "fastfetch --list-presets".
|
||||
# Must be a path to a config file or the name of a shipped preset.
|
||||
# The config file is completely loaded before continuing in the current file, so the placement of this option matters, as later options overwrite already set ones.
|
||||
# Can be used multiple times to load multiple config files / presets.
|
||||
#--load-config /path/to/config.txt
|
||||
|
||||
# Structure option:
|
||||
# Sets the modules to use and their order.
|
||||
# Must be a list of module names, separated by colons.
|
||||
# List available modules with "fastfetch --list-modules".
|
||||
# Get the default structure with "fastfetch --print-structure".
|
||||
#--structure $" FASTFETCH_DATATEXT_STRUCTURE $"
|
||||
|
||||
# Multithreading option:
|
||||
# Sets if fastfetch should use multiple threads to detect the values.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--multithreading true
|
||||
|
||||
# Print stat option:
|
||||
# Sets if fastfetch should print time usage (in ms) for individual modules
|
||||
# If true, it will also enable --show-errors
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--stat true
|
||||
|
||||
# Slow operations option:
|
||||
# Sets if fastfetch is allowed to use known slow operations to detect more / better values.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--allow-slow-operations false
|
||||
|
||||
# Linewrap option:
|
||||
# Sets if fastfetch should disable linewrap during the run.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--disable-linewrap true
|
||||
|
||||
# Cursor option:
|
||||
# Sets if fastfetch should hide the console cursor during the run.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--hide-cursor true
|
||||
|
||||
# Processing timeout option:
|
||||
# Sets the timeout (ms) when waiting for child processes
|
||||
# Must be an integer.
|
||||
# Default is 1000
|
||||
#--processing-timeout 1000
|
||||
|
||||
# WMI timeout option:
|
||||
# Sets the timeout (ms) for WMI queries. Windows only
|
||||
# Must be an integer.
|
||||
# Default is 5000
|
||||
#--wmi-timeout 5000
|
||||
|
||||
# Logo option:
|
||||
# Sets the logo to use.
|
||||
# List available logos with "fastfetch --list-logos".
|
||||
# Print available logos with "fastfetch --print-logos".
|
||||
# Must be the name of an available logo or a path to a text file containing a custom logo.
|
||||
# Default is the current distribution.
|
||||
#--logo arch
|
||||
|
||||
# Logo type option:
|
||||
# Sets the logo type to use.
|
||||
# Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa.
|
||||
# Default is auto.
|
||||
#--logo-type auto
|
||||
|
||||
# Logo width option:
|
||||
# Sets the width of the logo (in characters) if the logo is an image.
|
||||
# Must be a positive integer.
|
||||
# Default is 65.
|
||||
#--logo-width 65
|
||||
|
||||
# Logo height option:
|
||||
# Sets the height of the logo (in characters) if the logo is an image.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (keeps aspect ration).
|
||||
#--logo-height 0
|
||||
|
||||
# Logo color options:
|
||||
# Overwrite a color in the logo. Also works for user provided logos.
|
||||
# In the user logo, they replace $[1-9]. Use $$ to print a single $ sign.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the one specified by the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
# Valid index range is [1-9].
|
||||
#--logo-color-1 red
|
||||
#--logo-color-2 32
|
||||
# [...]
|
||||
#--logo-color-9 yellow
|
||||
|
||||
# Logo padding option:
|
||||
# Adds a padding to the left and the right side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding 0
|
||||
|
||||
# Logo padding left option:
|
||||
# Adds a padding to the left side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding-left 0
|
||||
|
||||
# Logo padding right option:
|
||||
# Adds a padding to the right side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding-right 0
|
||||
|
||||
# Logo padding top option:
|
||||
# Adds a padding to the top side of the logo.
|
||||
# Must be a positive integer.
|
||||
# Default is 0.
|
||||
#--logo-padding-top 0
|
||||
|
||||
# Logo print remaining option:
|
||||
# Sets if the remaining logo should be printed, it is has more lines than modules to show.
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--logo-print-remaining true
|
||||
|
||||
# Color keys option:
|
||||
# Sets the color of the keys.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the key color of the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
#--color-keys magenta
|
||||
|
||||
# Color title option:
|
||||
# Sets the color of the title.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the title color of the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
#--color-title magenta
|
||||
|
||||
# Binary prefix option:
|
||||
# Sets the binary prefix to use.
|
||||
# Must be a IEC, SI or JEDEC.
|
||||
# Default is IEC.
|
||||
#--binary-prefix IEC
|
||||
|
||||
# Size number of digits option:
|
||||
# Sets the number of digits to keep after the decimal point when formatting sizes.
|
||||
# Must be an possitive integer.
|
||||
# Default is 2.
|
||||
#--size-ndigits 2
|
||||
|
||||
# Size max prefix option:
|
||||
# Sets the largest binary prefix to use when formatting sizes.
|
||||
# Must be one of B, kB, MB, GB, TB, PB, EB, ZB, YB
|
||||
# Default is YB.
|
||||
#--size-max-prefix YB
|
||||
|
||||
# Disable output buffer option:
|
||||
# Sets if the stdout application buffer should be disabled.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--no-buffer false
|
||||
|
||||
# Title FQDN option:
|
||||
# Sets if the title should use the fully qualified domain name.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--title-fqdn false
|
||||
|
||||
# Title user color option:
|
||||
# Sets color of the user name (left part).
|
||||
# Default is empty (use color of `--color-title`).
|
||||
#--title-color-user
|
||||
|
||||
# Title at color option:
|
||||
# Sets color of the @ symbol (middle part).
|
||||
# Default is empty (use color of `--color-title`).
|
||||
#--title-color-at
|
||||
|
||||
# Title host color option:
|
||||
# Sets color of the host name (right part).
|
||||
# Default is empty (use color of `--color-title`).
|
||||
#--title-color-host
|
||||
|
||||
# Separator option:
|
||||
# Sets the string placed between a key and its value.
|
||||
# Can be any string.
|
||||
# Default is ": ".
|
||||
#--separator ": "
|
||||
|
||||
# Separator string option:
|
||||
# Sets the string printed by the "separator" module (usually between title and rest of output)
|
||||
# Must be any string. It is repated / cut to fit perfectly.
|
||||
# Default is "-"
|
||||
#--separator-string -
|
||||
|
||||
# Public IP URL option:
|
||||
# Sets the URL of public IP detection server to be used.
|
||||
# Only HTTP protocol is supported, and the value should not contain "http://" prefix.
|
||||
# Default is "ipinfo.io/ip".
|
||||
#--publicip-url "ipinfo.io/ip"
|
||||
|
||||
# Public IP timeout option:
|
||||
# Sets the time to wait for the public ip server to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--publicip-timeout 0
|
||||
|
||||
# Weather location option:
|
||||
# Sets the location to be used. It must be URI encoded (eg a whitespace must be encoded as `+`).
|
||||
# Default is empty (guessing by public IP)
|
||||
#--weather-location "Location"
|
||||
|
||||
# Weather output format option:
|
||||
# Sets the weather format to be used. It must be URI encoded.
|
||||
# See: https://github.com/chubin/wttr.in#one-line-output
|
||||
# Default is "%t+-+%C+(%l)".
|
||||
#--weather-output-format "%t+-+%C+(%l)"
|
||||
|
||||
# Weather timeout option:
|
||||
# Sets the time to wait for the weather server (wttr.in) to respond.
|
||||
# Must be a positive integer.
|
||||
# Default is 0 (disabled).
|
||||
#--weather-timeout 0
|
||||
|
||||
# OS file option
|
||||
# Sets the path to the file containing the operating system information.
|
||||
# Should be a valid path to an existing file.
|
||||
# Default is /etc/os-release.
|
||||
#--os-file /etc/os-release
|
||||
|
||||
# Player name option
|
||||
# Sets the name of the player. This is also used in song detection
|
||||
# Must be the exact name of the player or a dbus address (e.g. org.mpris.MediaPlayer2.spotify)
|
||||
# Default is the first match starting with org.mpris.MediaPlayer2.
|
||||
#--player-name spotify
|
||||
|
||||
# Display server force DRM option
|
||||
# Sets if fastfetch should only use `/sys/class/drm` to detect displays if you get issues with the default behavior.
|
||||
# Note DRM doesn't support refresh rate or scaled resolution detection.
|
||||
# Only supported on Linux.
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--ds-force-drm false
|
||||
|
||||
# Escape bedrock option
|
||||
# Sets if fastfetch should escape the bedrock jail, if it detectes that it is running in one
|
||||
# Must be true or false.
|
||||
# Default is true.
|
||||
#--escape-bedrock true
|
||||
|
||||
# OpenGL option
|
||||
# Sets with opengl context creation library to use
|
||||
# Must be either auto, egl, glx or osmesa
|
||||
# Default is auto.
|
||||
#--opengl-library auto
|
||||
|
||||
# GPU hide options
|
||||
# Sets whether to hide certain gpu types
|
||||
# Must be either true or false
|
||||
# Default is false.
|
||||
#--gpu-hide-integrated
|
||||
#--gpu-hide-discrete
|
||||
|
||||
# GPU detection options
|
||||
# Forces using vulkan to detect GPUs
|
||||
# which support video memory usage detection with `--allow-slow-operations`
|
||||
# Must be either true or false
|
||||
# Default is false.
|
||||
#--gpu-force-vulkan
|
||||
|
||||
# Disk show options
|
||||
# Sets if certain types of disk should be printed
|
||||
# Must be either true or false
|
||||
# Default is false except for --disk-show-external.
|
||||
#--disk-show-external true
|
||||
#--disk-show-hidden false
|
||||
#--disk-show-subvolumes false
|
||||
#--disk-show-unknown false
|
||||
|
||||
# Disk option
|
||||
# A colon (semicolon on Windows) separated list of folder paths for the disk output
|
||||
# This option override `--disk-show-*` options above
|
||||
# Must be a string
|
||||
# Default is "/:/home" ("C:\\;D:\\ ..." on Windows).
|
||||
#--disk-folders /:/home
|
||||
|
||||
# Bluetooth show disconnected option
|
||||
# Sets if disconnected bluetooth devices should be printed
|
||||
# Must be either true or false
|
||||
# Default is false.
|
||||
#--bluetooth-show-disconnected false
|
||||
|
||||
# Display compact output option
|
||||
# Sets if all displays should be printed in one line
|
||||
# Must be either original (print pixel resolution) or scaled (print scaled resolution)
|
||||
# Default is none.
|
||||
#--display-compact-type none
|
||||
|
||||
# Display detect name option
|
||||
# Sets if display name should be detected and printed (if supported)
|
||||
# Must be either true of false
|
||||
# Default is false.
|
||||
#--display-detect-name none
|
||||
|
||||
# Display precise refresh rate option
|
||||
# Sets if decimal refresh rates should not be rounded into integers when printing
|
||||
# Must be either true (keep decimals) of false (round into integers)
|
||||
# Default is false.
|
||||
#--display-precise-refresh-rate false
|
||||
|
||||
# Sound show all option
|
||||
# Sets if all sound devices should be printed
|
||||
# Must be either main, active or all. Default is main
|
||||
# Default is main.
|
||||
#--sound-type main
|
||||
|
||||
# Percentage output type option
|
||||
# Applies to all modules that prints percentage values. Currently memory, swap, disk, battery and CPU usage are supported.
|
||||
# Only works with default format ( without --module-format option ).
|
||||
# 0: prints none; 1: prints percent number only; 2: prints bar only; 3: prints both percent number and bar; 6: prints bar and hide other texts; 9: prints colored number
|
||||
#--percent-type 1
|
||||
|
||||
# Key options:
|
||||
# Sets the displayed key of a module
|
||||
# Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help.
|
||||
#--os-key OS
|
||||
#--host-key Host
|
||||
#--chassis-key Chassis
|
||||
#--kernel-key Kernel
|
||||
#--uptime-key Uptime
|
||||
#--processes-key Processes
|
||||
#--packages-key Packages
|
||||
#--shell-key Shell
|
||||
#--display-key Display {1}
|
||||
#--brightness-key Brightness ({1})
|
||||
#--monitor-key Monitor
|
||||
#--de-key DE
|
||||
#--wm-key WM
|
||||
#--wmtheme-key WM Theme
|
||||
#--theme-key Theme
|
||||
#--icons-key Icons
|
||||
#--font-key Font
|
||||
#--cursor-key Cursor
|
||||
#--terminal-key Terminal
|
||||
#--terminalfont-key Terminal Font
|
||||
#--cpu-key CPU
|
||||
#--cpuusage-key CPU Usage
|
||||
#--gpu-key GPU {1}
|
||||
#--memory-key Memory
|
||||
#--swap-key Swap
|
||||
#--disk-key Disk ({1})
|
||||
#--battery-key Battery {1}
|
||||
#--poweradapter-key Power Adapter {1}
|
||||
#--lm-key LM
|
||||
#--locale-key Locale
|
||||
#--localip-key Local IP ({1})
|
||||
#--netio-key Network IO ({1})
|
||||
#--publicip-key Public IP
|
||||
#--wifi-key Wifi
|
||||
#--weather-key Weather
|
||||
#--player-key Media Player
|
||||
#--media-key Media
|
||||
#--datetime-key Date Time
|
||||
#--version-key Version
|
||||
#--vulkan-key Vulkan
|
||||
#--opengl-key OpenGL
|
||||
#--opencl-key OpenCL
|
||||
#--users-key Users
|
||||
#--bluetooth-key Bluetooth
|
||||
#--sound-key Sound
|
||||
#--gamepad-key Gamepad
|
||||
#--wallpaper-key Wallpaper
|
||||
|
||||
# Format options:
|
||||
# Sets the format string for module values.
|
||||
# For information on format strings, see "fastfetch --help format".
|
||||
# To see the parameter they take and their default value, see "fastfetch --help *-format", e.g. "fastfetch --help os-format".
|
||||
# An empty format string (As they are currently below) will behave as if it was not set.
|
||||
#--title-format
|
||||
#--os-format
|
||||
#--host-format
|
||||
#--chassis-format
|
||||
#--kernel-format
|
||||
#--uptime-format
|
||||
#--processes-format
|
||||
#--packages-format
|
||||
#--shell-format
|
||||
#--display-format
|
||||
#--brightness-format
|
||||
#--de-format
|
||||
#--wm-format
|
||||
#--wmtheme-format
|
||||
#--theme-format
|
||||
#--icons-format
|
||||
#--font-format
|
||||
#--cursor-format
|
||||
#--terminal-format
|
||||
#--terminalfont-format
|
||||
#--cpu-format
|
||||
#--cpuusage-format
|
||||
#--gpu-format
|
||||
#--memory-format
|
||||
#--swap-format
|
||||
#--disk-format
|
||||
#--battery-format
|
||||
#--poweradapter-format
|
||||
#--lm-format
|
||||
#--locale-format
|
||||
#--localip-format
|
||||
#--netio-format
|
||||
#--publicip-format
|
||||
#--weather-format
|
||||
#--monitor-format
|
||||
#--player-format
|
||||
#--media-format
|
||||
#--datetime-format
|
||||
#--version-format
|
||||
#--vulkan-format
|
||||
#--opengl-format
|
||||
#--opencl-format
|
||||
#--users-format
|
||||
#--bluetooth-format
|
||||
#--sound-format
|
||||
#--gamepad-format
|
||||
#--wallpaper-format
|
||||
|
||||
# Key color options:
|
||||
# Overrides the global `--color-keys` for one specified module
|
||||
#--title-key-color
|
||||
#--os-key-color
|
||||
#--host-key-color
|
||||
#--chassis-key-color
|
||||
#--kernel-key-color
|
||||
#--uptime-key-color
|
||||
#--processes-key-color
|
||||
#--packages-key-color
|
||||
#--shell-key-color
|
||||
#--display-key-color
|
||||
#--brightness-key-color
|
||||
#--de-key-color
|
||||
#--wm-key-color
|
||||
#--wmtheme-key-color
|
||||
#--theme-key-color
|
||||
#--icons-key-color
|
||||
#--font-key-color
|
||||
#--cursor-key-color
|
||||
#--terminal-key-color
|
||||
#--terminalfont-key-color
|
||||
#--cpu-key-color
|
||||
#--cpuusage-key-color
|
||||
#--gpu-key-color
|
||||
#--memory-key-color
|
||||
#--swap-key-color
|
||||
#--disk-key-color
|
||||
#--battery-key-color
|
||||
#--poweradapter-key-color
|
||||
#--lm-key-color
|
||||
#--locale-key-color
|
||||
#--localip-key-color
|
||||
#--netio-key-color
|
||||
#--publicip-key-color
|
||||
#--weather-key-color
|
||||
#--monitor-key-color
|
||||
#--player-key-color
|
||||
#--media-key-color
|
||||
#--datetime-key-color
|
||||
#--version-key-color
|
||||
#--vulkan-key-color
|
||||
#--opengl-key-color
|
||||
#--opencl-key-color
|
||||
#--users-key-color
|
||||
#--bluetooth-key-color
|
||||
#--sound-key-color
|
||||
#--gamepad-key-color
|
||||
#--wallpaper-key-color
|
||||
|
||||
# Library options:
|
||||
# Sets an user specific path to a library to load.
|
||||
# Must be a valid path to a library.
|
||||
#--lib-PCI /usr/lib/libpci.so
|
||||
#--lib-vulkan /usr/lib/libvulkan.so (libMoltenVK.dylib on macOS)
|
||||
#--lib-wayland /usr/lib/libwayland-client.so
|
||||
#--lib-xcb-randr /usr/lib/libxcb-randr.so
|
||||
#--lib-xcb /usr/lib/libxcb.so
|
||||
#--lib-Xrandr /usr/lib/libXrandr.so
|
||||
#--lib-X11 /usr/lib/libX11.so
|
||||
#--lib-gio /usr/lib/libgio-2.0.so
|
||||
#--lib-DConf /usr/lib/libdconf.so
|
||||
#--lib-DBus /usr/lib/libdbus-1.so
|
||||
#--lib-XFConf /usr/lib/libxfconf-0.so
|
||||
#--lib-sqlite3 /usr/lib/libsqlite3.so
|
||||
#--lib-rpm /usr/lib/librpm.so
|
||||
#--lib-imagemagick /usr/lib/libMagickCore-7.Q16HDRI.so
|
||||
#--lib-z /usr/lib/libz.so
|
||||
#--lib-chafa /usr/lib/libchafa.so
|
||||
#--lib-egl /usr/lib/libEGL.so
|
||||
#--lib-glx /usr/lib/libGLX.so
|
||||
#--lib-osmesa /usr/lib/libOSMesa.so
|
||||
#--lib-opencl /usr/lib/libOpenCL.so
|
||||
#--lib-freetype /data/data/com.termux/files/usr/lib
|
||||
#--lib-pulse /usr/lib/libpulse.so
|
||||
#--lib-ddcutil /usr/lib/libddcutil.so
|
||||
#--lib-nm /usr/lib/libnm.so
|
||||
+1354
File diff suppressed because it is too large
Load Diff
+3
-183
@@ -1,184 +1,4 @@
|
||||
Usage: fastfetch <options>
|
||||
|
||||
Informative options:
|
||||
-h,--help: Show this message
|
||||
-h,--help <command>: Show help for a specific command
|
||||
-v,--version: Show the version of fastfetch
|
||||
--list-config-paths: List search paths of config files
|
||||
--list-data-paths: List search paths of presets and logos
|
||||
--list-logos: List available logos
|
||||
--list-modules: List available modules
|
||||
--list-presets: List presets fastfetch knows about; they can be loaded with --load-config (+)
|
||||
--list-features: List the supported features fastfetch was compiled with (mainly for development)
|
||||
--print-logos: Print available logos
|
||||
--print-config-system: Print the default system config
|
||||
--print-config-user: Print the default user config
|
||||
--print-structure: Print the default structure
|
||||
|
||||
Config options:
|
||||
--load-config,--config,-c <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:
|
||||
--multithreading,--thread <?value>: Use multiple threads to detect values
|
||||
--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
|
||||
--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
|
||||
--ds-force-drm <?value>: Set if only DRM should be used to detect displays. Default is false. Linux only
|
||||
|
||||
Logo options:
|
||||
-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-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-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-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-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-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-separate <?value>: If true, print modules at bottom of the logo
|
||||
--logo-recache <?value>: If true, regenerate image logo cache
|
||||
--file <file>: Short for --logo-type file --logo <file>
|
||||
--file-raw <file>: Short for --logo-type file-raw --logo <file>
|
||||
--data <data>: Short for --logo-type data --logo <data>
|
||||
--data-raw <data>: Short for --logo-type data-raw --logo <data>
|
||||
--sixel <file>: Short for --logo-type sixel --logo <file>
|
||||
--kitty <file>: Short for --logo-type kitty --logo <file>
|
||||
--iterm <file>: Short for --logo-type iterm --logo <file>
|
||||
--chafa <file>: Short for --logo-type chafa --logo <file>
|
||||
--chafa-fg-only <?value>: Produce character-cell output using foreground colors only. See chafa document for detail
|
||||
--chafa-symbols <str>: Specify character symbols to employ in final output. See chafa document for detail
|
||||
--chafa-canvas-mode <value>: Determine how colors are used in the output. This value maps the int value of enum ChafaCanvasMode. See chafa document for detail
|
||||
--chafa-color-space <value>: Set color space used for quantization. 0 for RGB; 1 for DIN99d. 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:
|
||||
-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-title <color>: Set the color of the title
|
||||
--color <color>: Set the color of both the keys and title
|
||||
--key-width <num>: Align the width of keys to <num> characters
|
||||
--bright-color <?value>: Set if the keys, title and ASCII logo should be printed in bright color. Default is true
|
||||
--separator <str>: Set the separator between key and value. Default is a colon with a space
|
||||
--set <key=value>: Hard set the value of a key
|
||||
--set-keyless <key=value>: Hard set the value of a key, but don't print the key or the separator
|
||||
--show-errors <?value>: Print occurring errors
|
||||
--disable-linewrap <?value>: Whether to disable line wrap 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
|
||||
--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-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-total <str>: Set the character to use in total part. Default is '-'
|
||||
--bar-width <?num>: Set the width of the bar, in number of characters. Default is 10
|
||||
--bar-border <?value>: Whether to show a border around the bar. Default is true
|
||||
--no-buffer <?value>: Set if the stdout application buffer should be disabled. Default is false
|
||||
--size-ndigits <value>: Set the number of digits to keep after the decimal point when formatting sizes
|
||||
--size-max-prefix <value>: Set the largest binary prefix to use when formatting sizes. Default is YB
|
||||
--temperature-unit <value>: Set the unit of the temperature. Must be one of C, F and K. Default is C
|
||||
|
||||
General module options:
|
||||
--<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 help about a specific format string, use fastfetch --help <module>-format.
|
||||
|
||||
--<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.
|
||||
|
||||
--<module>-key-color <format>: Override the global `--color-keys` 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
|
||||
--lib-PCI <path>
|
||||
--lib-vulkan <path>
|
||||
--lib-wayland <path>
|
||||
--lib-xcb-randr <path>
|
||||
--lib-xcb <path>
|
||||
--lib-Xrandr <path>
|
||||
--lib-X11 <path>
|
||||
--lib-gio <path>
|
||||
--lib-DConf <path>
|
||||
--lib-DBus <path>
|
||||
--lib-XFConf <path>
|
||||
--lib-sqlite3 <path>
|
||||
--lib-rpm <path>
|
||||
--lib-imagemagick <path>
|
||||
--lib-z <path>
|
||||
--lib-chafa <path>
|
||||
--lib-egl <path>
|
||||
--lib-glx <path>
|
||||
--lib-osmesa <path>
|
||||
--lib-opencl <path>
|
||||
--lib-pulse <path>
|
||||
--lib-freetype <path>
|
||||
--lib-ddcutil <path>
|
||||
|
||||
Module specific options:
|
||||
--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-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`)
|
||||
--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
|
||||
--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-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-hidden <?value>: Set if hidden volumes should be printed. Default is false
|
||||
--disk-show-subvolumes <?value>: Set if subvolumes should be printed. Default is false
|
||||
--disk-show-readonly <?value>: Set if read only 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
|
||||
--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
|
||||
--packages-winget: <?value>: Set if winget package count should be detected. Default is false
|
||||
--display-compact-type: <?string>: Set if all displays should be printed in one line. Default is none
|
||||
--display-detect-name: <?value>: Set if display name should be detected and printed (if supported). Default is false
|
||||
--display-precise-refresh-rate: <?value>:Set if decimal refresh rates should not be rounded into integers when printing. Default is true
|
||||
--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
|
||||
--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-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
|
||||
--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-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-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
|
||||
--localip-show-ipv4 <?value>: Show IPv4 addresses in local ip module. Default is true
|
||||
--localip-show-ipv6 <?value>: Show IPv6 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-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 true
|
||||
--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-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-url: 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-timeout: 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.
|
||||
--wm-detect-plugin: Set if window manager plugin should be detected on supported platforms. Default is false
|
||||
--player-name: The name of the player to use for module Media and Player. Linux only
|
||||
--opengl-library <value>: 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-key <str>: Set the module key to display
|
||||
--command-text <str>: Set the command text to be executed
|
||||
--colors-symbol <str>: Set the symbol to be printed by Colors module. Default is block
|
||||
--colors-padding-left <value>: Set the number of white spaces to print before the symbol. Default is 0
|
||||
|
||||
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.
|
||||
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
|
||||
If a value starts with a ?, it is optional. An optional boolean value defaults to true if not specified.
|
||||
More detailed help messages for each options can be printed with "-h <option_without_dash_prefix>"
|
||||
All options can be made permanent with command "fastfetch <options> --gen-config"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
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.
|
||||
Examples:
|
||||
--color 35: sets the color to pink
|
||||
--color 35: sets the color to magenta. `--color magenta` is also supported
|
||||
--color 4;92: sets the color to bright Green with underline
|
||||
--color 5;104: blinking text on a blue background
|
||||
If no color is set, the main color of the logo will be used.
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
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.
|
||||
If the file is relative it looks in the following order:
|
||||
- relative to the current working directory
|
||||
- relative to ~/.local/share/fastfetch/presets/
|
||||
- relative to /usr/share/fastfetch/presets/
|
||||
Fastfetch provides some default presets. List them with --print-available-presets.
|
||||
Note that this will only print presets fastfetch knows about and not every possible one.
|
||||
Fastfetch provides some default presets. List them with "fastfetch --list-presets".
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
A format string is a string that contains placeholders for values.
|
||||
These placeholders begin with a '{', containing the index of the value, and end with a '}'.
|
||||
For example the format string "Values: {1} ({2})", with the values "First" and "My second val", will produce
|
||||
The format string can contain placeholders in any order and have multiple occurences.
|
||||
The format string can contain placeholders in any order and have multiple occurrences.
|
||||
To include spaces when setting from the command line, surround the whole string with double quotes (").
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
@@ -22,7 +22,7 @@ For example to print a fallback for a second value if it is not set, use "{?2}{2
|
||||
To stop formatting at any point in the format string, use "{-}".
|
||||
|
||||
To print something with color, start a placeholder with a '#' and then the linux terminal color encoding.
|
||||
"\\033[" at the start, and an 'm' at the end is automatically added, so don't do that.
|
||||
"\033[" at the start, and an 'm' at the end is automatically added, so don't do that.
|
||||
A "{#}" is equivalent to a "{#0}" and resets everything to normal.
|
||||
For example to print something pink and underline, use "{#4;35}...{#}".
|
||||
Information about what the numbers mean can be found here: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Sele
|
||||
|
||||
@@ -1 +1 @@
|
||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap: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
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_battery_battery
|
||||
#define FF_INCLUDED_detection_battery_battery
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_BATTERY_TEMP_UNSET (0/0.0)
|
||||
@@ -15,8 +12,7 @@ typedef struct FFBatteryResult
|
||||
double capacity;
|
||||
FFstrbuf status;
|
||||
double temperature;
|
||||
uint32_t cycleCount;
|
||||
} FFBatteryResult;
|
||||
|
||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@ static const char* parseTermuxApi(FFBatteryOptions* options, FFlist* results)
|
||||
|
||||
FFBatteryResult* battery = ffListAdd(results);
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
battery->cycleCount = 0;
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
|
||||
@@ -5,16 +5,6 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
io_iterator_t iterator;
|
||||
@@ -24,7 +14,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
@@ -35,7 +25,13 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
const char* error;
|
||||
|
||||
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;
|
||||
|
||||
int currentCapacity, 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;
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffCfDictGetString(properties, CFSTR("DeviceName"), &battery->modelName);
|
||||
|
||||
if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
||||
ffStrbufAppendS(&battery->modelName, "Builtin");
|
||||
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
|
||||
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");
|
||||
ffStrbufAppendS(&battery->modelName, "Unknown");
|
||||
ffStrbufAppendS(&battery->technology, "Unknown");
|
||||
int64_t temp;
|
||||
if (!ffCfDictGetInt64(properties, CFSTR("Temperature"), &temp))
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
||||
if(units == 0)
|
||||
return NULL;
|
||||
|
||||
FF_AUTO_CLOSE_FD int acpifd = open("/dev/acpi", O_RDONLY);
|
||||
FF_AUTO_CLOSE_FD int acpifd = open("/dev/acpi", O_RDONLY | O_CLOEXEC);
|
||||
if(acpifd < 0)
|
||||
return "open(\"/dev/acpi\", O_RDONLY) failed";
|
||||
return "open(\"/dev/acpi\", O_RDONLY | O_CLOEXEC) failed";
|
||||
|
||||
for(int i = 0; i < units; ++i)
|
||||
{
|
||||
@@ -34,6 +34,7 @@ const char* ffDetectBattery(FF_MAYBE_UNUSED FFBatteryOptions* options, FFlist* r
|
||||
|
||||
FFBatteryResult* battery = ffListAdd(results);
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
battery->cycleCount = 0;
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->status);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io/io.h"
|
||||
#include "battery.h"
|
||||
#include "common/io/io.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
#include "util/stringUtils.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;
|
||||
|
||||
@@ -65,7 +65,26 @@ static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
ffReadFileBuffer(dir->chars, &result->status);
|
||||
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;
|
||||
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)
|
||||
@@ -84,7 +103,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
return "opendir(batteryDir) == NULL";
|
||||
|
||||
@@ -95,12 +114,10 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
parseBattery(&baseDir, results);
|
||||
parseBattery(&baseDir, entry->d_name, options, results);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
if(results->length == 0)
|
||||
return "batteryDir doesn't contain any battery folder";
|
||||
|
||||
|
||||
@@ -30,137 +30,146 @@ static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
SetupDiDestroyDeviceInfoList(*hdev);
|
||||
}
|
||||
|
||||
const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
|
||||
static const char* detectWithSetupApi(FFBatteryOptions* options, FFlist* results)
|
||||
{
|
||||
if(options->useSetupApi)
|
||||
//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
|
||||
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";
|
||||
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");
|
||||
|
||||
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->manufacturer);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->status);
|
||||
battery->temperature = 0.0/0.0;
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
{
|
||||
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->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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_bios_bios
|
||||
#define FF_INCLUDED_detection_bios_bios
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBiosResult
|
||||
@@ -11,8 +8,7 @@ typedef struct FFBiosResult
|
||||
FFstrbuf release;
|
||||
FFstrbuf vendor;
|
||||
FFstrbuf version;
|
||||
FFstrbuf type;
|
||||
} FFBiosResult;
|
||||
|
||||
const char* ffDetectBios(FFBiosResult* bios);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,5 +9,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
if (ffStrbufIgnCaseEqualS(&bios->version, "unknown"))
|
||||
ffStrbufClear(&bios->version);
|
||||
|
||||
ffStrbufSetStatic(&bios->type, "Bootloader");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
ffCfDictGetString(properties, CFSTR("vendor"), &bios->vendor);
|
||||
ffCfDictGetString(properties, CFSTR("version"), &bios->version);
|
||||
ffCfDictGetString(properties, CFSTR("release-date"), &bios->date);
|
||||
ffStrbufAppendS(&bios->release, "Efi");
|
||||
ffStrbufSetStatic(&bios->type, "UEFI");
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
@@ -54,12 +54,12 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
uint32_t index = ffStrbufFirstIndexC(&bios->version, '-');
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&bios->release, "iBoot");
|
||||
ffStrbufSetStatic(&bios->type, "iBoot");
|
||||
}
|
||||
CFRelease(properties);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "bios.h"
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
|
||||
const char* ffDetectBios(FFBiosResult* result)
|
||||
@@ -13,5 +14,6 @@ const char* ffDetectBios(FFBiosResult* result)
|
||||
ffCleanUpSmbiosValue(&result->vendor);
|
||||
ffSettingsGetFreeBSDKenv("smbios.bios.version", &result->version);
|
||||
ffCleanUpSmbiosValue(&result->version);
|
||||
ffSysctlGetString("machdep.bootmethod", &result->type);
|
||||
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_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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,30 @@
|
||||
#include "util/windows/registry.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)
|
||||
{
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
@@ -24,5 +48,18 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_bluetooth_bluetooth
|
||||
#define FF_INCLUDED_detection_bluetooth_bluetooth
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBluetoothResult
|
||||
@@ -15,5 +12,3 @@ typedef struct FFBluetoothResult
|
||||
} FFBluetoothResult;
|
||||
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
#include "bluetooth.h"
|
||||
#include "common/library.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <bluetoothapis.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpointer-sign"
|
||||
|
||||
const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
{
|
||||
// Actually bluetoothapis.dll, but it's missing on Windows 7
|
||||
FF_LIBRARY_LOAD(bluetoothapis, NULL, "dlopen bthprops.cpl failed", "bthprops.cpl", 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindFirstDevice)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindNextDevice)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(bluetoothapis, BluetoothFindDeviceClose)
|
||||
|
||||
BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = {
|
||||
.fReturnConnected = TRUE,
|
||||
.fReturnRemembered = TRUE,
|
||||
@@ -20,9 +26,14 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
BLUETOOTH_DEVICE_INFO btdi = {
|
||||
.dwSize = sizeof(btdi)
|
||||
};
|
||||
HBLUETOOTH_DEVICE_FIND hFind = BluetoothFindFirstDevice(&btsp, &btdi);
|
||||
HBLUETOOTH_DEVICE_FIND hFind = ffBluetoothFindFirstDevice(&btsp, &btdi);
|
||||
if(!hFind)
|
||||
return "BluetoothFindFirstDevice() failed or no devices found";
|
||||
{
|
||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||
return "No Bluetooth devices found";
|
||||
else
|
||||
return "BluetoothFindFirstDevice() failed";
|
||||
}
|
||||
|
||||
do {
|
||||
FFBluetoothResult* device = ffListAdd(devices);
|
||||
@@ -114,9 +125,9 @@ const char* ffDetectBluetooth(FFlist* devices /* FFBluetoothResult */)
|
||||
ffStrbufTrimRight(&device->type, ' ');
|
||||
ffStrbufTrimRight(&device->type, ',');
|
||||
}
|
||||
} while (BluetoothFindNextDevice(hFind, &btdi));
|
||||
} while (ffBluetoothFindNextDevice(hFind, &btdi));
|
||||
|
||||
ffBluetoothFindDeviceClose(hFind);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_board_board
|
||||
#define FF_INCLUDED_detection_board_board
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBoardResult
|
||||
@@ -12,6 +9,4 @@ typedef struct FFBoardResult
|
||||
FFstrbuf version;
|
||||
} FFBoardResult;
|
||||
|
||||
const char* ffDetectBoard(FFBoardResult* result);
|
||||
|
||||
#endif
|
||||
const char* ffDetectBoard(FFBoardResult* board);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "board.h"
|
||||
|
||||
#include "common/sysctl.h"
|
||||
|
||||
const char* ffDetectBoard(FFBoardResult* result)
|
||||
{
|
||||
const char* error = ffSysctlGetString("hw.model", &result->name);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ffStrbufSetStatic(&result->vendor, "Apple");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_brightness_brightness
|
||||
#define FF_INCLUDED_detection_brightness_brightness
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFlist.h"
|
||||
|
||||
@@ -13,5 +10,3 @@ typedef struct FFBrightnessResult
|
||||
} FFBrightnessResult;
|
||||
|
||||
const char* ffDetectBrightness(FFBrightnessOptions* options, FFlist* result); // list of FFBrightnessResult
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,7 @@ const char* ffDetectBrightness(FF_MAYBE_UNUSED FFBrightnessOptions* options, FFl
|
||||
{
|
||||
path[sizeof(path) - 2] = i;
|
||||
|
||||
FF_AUTO_CLOSE_FD int blfd = open(path, O_RDONLY);
|
||||
FF_AUTO_CLOSE_FD int blfd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (blfd < 0)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ static const char* detectWithBacklight(FFlist* result)
|
||||
// Try to be compatible with ddcutil 2.0
|
||||
#if DDCUTIL_VMAJOR >= 2
|
||||
double ddca_set_default_sleep_multiplier(double multiplier); // ddcutil 1.4
|
||||
#else
|
||||
DDCA_Status ddca_init(const char *libopts, int syslog_level, int opts);
|
||||
#endif
|
||||
|
||||
static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
|
||||
@@ -107,11 +109,22 @@ static const char* detectWithDdcci(FFBrightnessOptions* options, FFlist* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
|
||||
|
||||
__typeof__(&ddca_set_default_sleep_multiplier) ffddca_set_default_sleep_multiplier = dlsym(libddcutil, "ddca_set_default_sleep_multiplier");
|
||||
if (ffddca_set_default_sleep_multiplier)
|
||||
ffddca_set_default_sleep_multiplier(options->ddcciSleep / 40.0);
|
||||
__typeof__(&ddca_init) ffddca_init = dlsym(libddcutil, "ddca_init");
|
||||
if (ffddca_init)
|
||||
{
|
||||
FF_SUPPRESS_IO();
|
||||
// Ref: https://github.com/rockowitz/ddcutil/issues/344
|
||||
if (ffddca_init("--disable-watch-displays", -1 /*DDCA_SYSLOG_NOT_SET*/, 1 /*DDCA_INIT_OPTIONS_DISABLE_CONFIG_FILE*/) < 0)
|
||||
return "ddca_init() failed";
|
||||
}
|
||||
else
|
||||
{
|
||||
__typeof__(&ddca_set_default_sleep_multiplier) ffddca_set_default_sleep_multiplier = dlsym(libddcutil, "ddca_set_default_sleep_multiplier");
|
||||
if (ffddca_set_default_sleep_multiplier)
|
||||
ffddca_set_default_sleep_multiplier(options->ddcciSleep / 40.0);
|
||||
|
||||
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
|
||||
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
|
||||
}
|
||||
|
||||
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
|
||||
if (ffddca_get_display_info_list2(false, &infoList) < 0)
|
||||
|
||||
@@ -2,6 +2,7 @@ extern "C"
|
||||
{
|
||||
#include "brightness.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "common/library.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
#include "util/windows/unicode.hpp"
|
||||
@@ -36,15 +37,19 @@ static const char* detectWithWmi(FFlist* result)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result)
|
||||
static const char* detectWithDdcci(const FFDisplayServerResult* displayServer, FFlist* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(dxva2, NULL, "dlopen dxva2" FF_LIBRARY_EXTENSION " failed", "dxva2" FF_LIBRARY_EXTENSION, 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetPhysicalMonitorsFromHMONITOR)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(dxva2, GetMonitorBrightness)
|
||||
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, display, displayServer->displays)
|
||||
{
|
||||
PHYSICAL_MONITOR physicalMonitor;
|
||||
if (GetPhysicalMonitorsFromHMONITOR((HMONITOR)(uintptr_t) display->id, 1, &physicalMonitor))
|
||||
if (ffGetPhysicalMonitorsFromHMONITOR((HMONITOR)(uintptr_t) display->id, 1, &physicalMonitor))
|
||||
{
|
||||
DWORD min = 0, curr = 0, max = 0;
|
||||
if (GetMonitorBrightness(physicalMonitor.hPhysicalMonitor, &min, &curr, &max))
|
||||
if (ffGetMonitorBrightness(physicalMonitor.hPhysicalMonitor, &min, &curr, &max))
|
||||
{
|
||||
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_chassis_chassis
|
||||
#define FF_INCLUDED_detection_chassis_chassis
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFChassisResult
|
||||
@@ -14,5 +11,3 @@ typedef struct FFChassisResult
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options);
|
||||
const char* ffChassisTypeToString(uint32_t type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cpu_cpu
|
||||
#define FF_INCLUDED_detection_cpu_cpu
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_CPU_TEMP_UNSET (0/0.0)
|
||||
@@ -23,5 +20,3 @@ typedef struct FFCPUResult
|
||||
} FFCPUResult;
|
||||
|
||||
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -83,12 +83,10 @@ static double getFrequency(const char* info, const char* scaling)
|
||||
|
||||
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(
|
||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cpuusage_cpuusage
|
||||
#define FF_INCLUDED_detection_cpuusage_cpuusage
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCpuUsageInfo {
|
||||
@@ -12,5 +9,3 @@ typedef struct FFCpuUsageInfo {
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes);
|
||||
|
||||
const char* ffGetCpuUsageResult(FFlist* result); // list of double
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,30 +7,42 @@
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* procStat = fopen("/proc/stat", "r");
|
||||
if(procStat == NULL)
|
||||
char buf[PROC_FILE_BUFFSIZ];
|
||||
ssize_t nRead = ffReadFileData("/proc/stat", sizeof(buf) - 1, buf);
|
||||
if(nRead < 0)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
return "Accessing \"/proc/stat\" is restricted on Android O+";
|
||||
#else
|
||||
return "fopen(\"""/proc/stat\", \"r\") == NULL";
|
||||
return "ffReadFileData(\"/proc/stat\", sizeof(buf) - 1, buf) failed";
|
||||
#endif
|
||||
}
|
||||
buf[nRead] = '\0';
|
||||
|
||||
// Skip first line
|
||||
if (fscanf(procStat, "cpu%*[^\n]\n") < 0)
|
||||
return "fscanf() first line failed";
|
||||
char *start = NULL;
|
||||
if((start = strchr(buf, '\n')) == NULL)
|
||||
return "skip first line failed";
|
||||
++start;
|
||||
|
||||
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
|
||||
while (fscanf(procStat, "cpu%*d%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%*[^\n]\n", &user, &nice, &system, &idle, &iowait, &irq, &softirq) == 7)
|
||||
char *token = NULL;
|
||||
while ((token = strchr(start, '\n')))
|
||||
{
|
||||
uint64_t inUse = user + nice + system;
|
||||
uint64_t total = inUse + idle + iowait + irq + softirq;
|
||||
if(sscanf(start, "cpu%*d%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%*[^\n]\n", &user, &nice, &system, &idle, &iowait, &irq, &softirq) == 7)
|
||||
{
|
||||
uint64_t inUse = user + nice + system;
|
||||
uint64_t total = inUse + idle + iowait + irq + softirq;
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = (uint64_t)inUse,
|
||||
.totalAll = (uint64_t)total,
|
||||
};
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = (uint64_t)inUse,
|
||||
.totalAll = (uint64_t)total,
|
||||
};
|
||||
}
|
||||
else
|
||||
break;
|
||||
start = token + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cursor_cursor
|
||||
#define FF_INCLUDED_detection_cursor_cursor
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCursorResult
|
||||
@@ -13,5 +10,3 @@ typedef struct FFCursorResult
|
||||
} FFCursorResult;
|
||||
|
||||
void ffDetectCursor(FFCursorResult* result);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,7 +155,7 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
|
||||
{
|
||||
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
|
||||
getKDE(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME) || ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
|
||||
getGnome(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_CINNAMON))
|
||||
getCinnamon(result, options);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_disk_disk
|
||||
#define FF_INCLUDED_detection_disk_disk
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFDisk
|
||||
@@ -26,6 +23,4 @@ typedef struct FFDisk
|
||||
* Returns a List of FFDisk, sorted alphabetically by mountpoint.
|
||||
* If error is not set, disks contains at least one disk.
|
||||
*/
|
||||
const char* ffDetectDisks(FFDiskOptions* options, FFlist* result /* list of FFDisk */);
|
||||
|
||||
#endif
|
||||
const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks /* list of FFDisk */);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
static bool isPhysicalDevice(const struct mntent* device)
|
||||
{
|
||||
#ifndef __ANDROID__ //On Android, `/dev` is not accessable, so that the following checks always fail
|
||||
#ifndef __ANDROID__ //On Android, `/dev` is not accessible, so that the following checks always fail
|
||||
|
||||
//Always show the root path
|
||||
if(ffStrEquals(device->mnt_dir, "/"))
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef struct FFDiskIOResult
|
||||
FFstrbuf name;
|
||||
FFstrbuf interconnect;
|
||||
FFDiskIOPhysicalType type;
|
||||
uint64_t size;
|
||||
FFstrbuf devPath;
|
||||
uint64_t bytesRead;
|
||||
uint64_t readCount;
|
||||
|
||||
@@ -49,6 +49,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
ffStrbufInitS(&device->name, deviceName);
|
||||
ffStrbufInit(&device->devPath);
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
device->size = 0;
|
||||
|
||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
|
||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
|
||||
@@ -62,6 +63,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
ffStrbufPrependS(&device->devPath, "/dev/");
|
||||
}
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (mediaSize)
|
||||
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
|
||||
else
|
||||
device->size = 0;
|
||||
|
||||
ffStrbufInit(&device->interconnect);
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
|
||||
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
|
||||
|
||||
@@ -1,51 +1,70 @@
|
||||
#include "diskio.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <devstat.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disk.h>
|
||||
#include <libgeom.h>
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
if (devstat_checkversion(NULL) < 0)
|
||||
return "devstat_checkversion() failed";
|
||||
struct gmesh geomTree;
|
||||
if (geom_gettree(&geomTree) < 0)
|
||||
return "geom_gettree() failed";
|
||||
|
||||
struct statinfo stats = {
|
||||
.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)),
|
||||
};
|
||||
if (devstat_getdevs(NULL, &stats) < 0)
|
||||
return "devstat_getdevs() failed";
|
||||
if (geom_stats_open() < 0)
|
||||
return "geom_stats_open() failed";
|
||||
|
||||
for (int i = 0; i < stats.dinfo->numdevs; i++)
|
||||
void* snap = geom_stats_snapshot_get();
|
||||
struct devstat* snapIter;
|
||||
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
||||
{
|
||||
struct devstat* current = &stats.dinfo->devices[i];
|
||||
if (current->device_type & DEVSTAT_TYPE_PASS)
|
||||
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
|
||||
continue;
|
||||
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
|
||||
if (geomId == NULL)
|
||||
continue;
|
||||
if (geomId->lg_what != ISPROVIDER)
|
||||
continue;
|
||||
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
|
||||
if (provider->lg_geom->lg_rank != 1)
|
||||
continue;
|
||||
|
||||
char deviceName[128];
|
||||
snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number);
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
|
||||
FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
||||
{
|
||||
if (ffStrEquals(ptr->lg_name, "descr"))
|
||||
ffStrbufSetS(&name, ptr->lg_val);
|
||||
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
|
||||
type = ffStrEquals(ptr->lg_val, "0") ? FF_DISKIO_PHYSICAL_TYPE_SSD : FF_DISKIO_PHYSICAL_TYPE_HDD;
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitS(&device->name, deviceName);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", deviceName);
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
switch (current->device_type & DEVSTAT_TYPE_IF_MASK)
|
||||
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
|
||||
{
|
||||
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
|
||||
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
|
||||
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
|
||||
}
|
||||
device->bytesRead = current->bytes[DEVSTAT_READ];
|
||||
device->readCount = current->operations[DEVSTAT_READ];
|
||||
device->bytesWritten = current->bytes[DEVSTAT_WRITE];
|
||||
device->writeCount = current->operations[DEVSTAT_WRITE];
|
||||
device->bytesRead = snapIter->bytes[DEVSTAT_READ];
|
||||
device->readCount = snapIter->operations[DEVSTAT_READ];
|
||||
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
|
||||
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
|
||||
device->size = (uint64_t) provider->lg_mediasize;
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
device->type = type;
|
||||
}
|
||||
|
||||
if (stats.dinfo->mem_ptr)
|
||||
free(stats.dinfo->mem_ptr);
|
||||
free(stats.dinfo);
|
||||
geom_stats_snapshot_free(snap);
|
||||
geom_stats_close();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (part && isdigit(part[strlen("-part")]))
|
||||
continue;
|
||||
|
||||
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive indentifier
|
||||
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive identifier
|
||||
continue;
|
||||
|
||||
// Other exceptions?
|
||||
@@ -102,6 +102,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
||||
else
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
|
||||
if (ffReadFileBuffer(pathSysBlock, &buffer))
|
||||
device->size = ffStrbufToUInt(&buffer, 0);
|
||||
else
|
||||
device->size = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -82,6 +82,20 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
||||
else
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
|
||||
DISK_GEOMETRY_EX dge = {};
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||
NULL,
|
||||
0,
|
||||
&dge,
|
||||
sizeof(dge),
|
||||
&retSize,
|
||||
NULL))
|
||||
device->size = (uint64_t) dge.DiskSize.QuadPart;
|
||||
else
|
||||
device->size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_displayserver
|
||||
#define FF_INCLUDED_detection_displayserver
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_DE_PRETTY_PLASMA "KDE Plasma"
|
||||
@@ -85,5 +82,3 @@ bool ffdsAppendDisplay(
|
||||
FFDisplayType type,
|
||||
bool primary,
|
||||
uint64_t id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,82 +1,5 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static void parseDRM(FFDisplayServerResult* result)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||
|
||||
uint32_t drmDirLength = drmDir.length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
ffStrbufAppendS(&drmDir, "/modes");
|
||||
|
||||
FILE* modeFile = fopen(drmDir.chars, "r");
|
||||
if(modeFile == NULL)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t width = 0, height = 0;
|
||||
|
||||
int scanned = fscanf(modeFile, "%ux%u", &width, &height);
|
||||
if(scanned == 2 && width > 0 && height > 0)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
ffStrbufAppendS(&drmDir, "/edid");
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
uint8_t edidData[128];
|
||||
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
|
||||
ffEdidGetName(edidData, &name);
|
||||
else
|
||||
{
|
||||
const char* plainName = entry->d_name;
|
||||
if (ffStrStartsWith(plainName, "card"))
|
||||
{
|
||||
const char* tmp = strchr(plainName + strlen("card"), '-');
|
||||
if (tmp) plainName = tmp + 1;
|
||||
}
|
||||
ffStrbufAppendS(&name, plainName);
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(
|
||||
result,
|
||||
width, height,
|
||||
0,
|
||||
0, 0,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
fclose(modeFile);
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
{
|
||||
@@ -89,7 +12,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
|
||||
if (!instance.config.general.dsForceDrm)
|
||||
{
|
||||
//We try wayland as our prefered display server, as it supports the most features.
|
||||
//We try wayland as our preferred display server, as it supports the most features.
|
||||
//This method can't detect the name of our WM / DE
|
||||
ffdsConnectWayland(ds);
|
||||
|
||||
@@ -113,7 +36,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
//This display detection method is display server independent.
|
||||
//Use it if all connections failed
|
||||
if(ds->displays.length == 0)
|
||||
parseDRM(ds);
|
||||
ffdsConnectDrm(ds);
|
||||
|
||||
//This fills in missing information about WM / DE by using env vars and iterating processes
|
||||
ffdsDetectWMDE(ds);
|
||||
|
||||
@@ -13,6 +13,8 @@ void ffdsConnectXcb(FFDisplayServerResult* result);
|
||||
void ffdsConnectXrandr(FFDisplayServerResult* result);
|
||||
void ffdsConnectXlib(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsConnectDrm(FFDisplayServerResult* result);
|
||||
|
||||
void ffdsDetectWMDE(FFDisplayServerResult* result);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return "opendir(drmDirPath) failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||
|
||||
uint32_t drmDirLength = drmDir.length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
uint32_t drmDirWithDnameLength = drmDir.length;
|
||||
|
||||
ffStrbufAppendS(&drmDir, "/enabled");
|
||||
char enabled = 'd'; // disabled
|
||||
ffReadFileData(drmDir.chars, sizeof(enabled), &enabled);
|
||||
if (enabled != 'e') // enabled
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
|
||||
ffStrbufAppendS(&drmDir, "/modes");
|
||||
|
||||
char modes[32];
|
||||
if (ffReadFileData(drmDir.chars, sizeof(modes), modes) < 3)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t width = 0, height = 0;
|
||||
|
||||
int scanned = sscanf(modes, "%ux%u", &width, &height);
|
||||
if(scanned == 2 && width > 0 && height > 0)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
ffStrbufAppendS(&drmDir, "/edid");
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
uint8_t edidData[128];
|
||||
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
|
||||
ffEdidGetName(edidData, &name);
|
||||
else
|
||||
{
|
||||
const char* plainName = entry->d_name;
|
||||
if (ffStrStartsWith(plainName, "card"))
|
||||
{
|
||||
const char* tmp = strchr(plainName + strlen("card"), '-');
|
||||
if (tmp) plainName = tmp + 1;
|
||||
}
|
||||
ffStrbufAppendS(&name, plainName);
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(
|
||||
result,
|
||||
width, height,
|
||||
0,
|
||||
0, 0,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_DRM
|
||||
|
||||
#include "common/library.h"
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// https://gitlab.freedesktop.org/mesa/drm/-/blob/main/xf86drmMode.c#L1785
|
||||
// It's not supported on Ubuntu 20.04
|
||||
static inline const char* drmType2Name(uint32_t connector_type)
|
||||
{
|
||||
/* Keep the strings in sync with the kernel's drm_connector_enum_list in
|
||||
* drm_connector.c. */
|
||||
switch (connector_type)
|
||||
{
|
||||
case DRM_MODE_CONNECTOR_Unknown:
|
||||
return "Unknown";
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
return "VGA";
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
return "DVI-I";
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
return "DVI-D";
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
return "DVI-A";
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
return "Composite";
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
return "SVIDEO";
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
return "LVDS";
|
||||
case DRM_MODE_CONNECTOR_Component:
|
||||
return "Component";
|
||||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
return "DIN";
|
||||
case DRM_MODE_CONNECTOR_DisplayPort:
|
||||
return "DP";
|
||||
case DRM_MODE_CONNECTOR_HDMIA:
|
||||
return "HDMI-A";
|
||||
case DRM_MODE_CONNECTOR_HDMIB:
|
||||
return "HDMI-B";
|
||||
case DRM_MODE_CONNECTOR_TV:
|
||||
return "TV";
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
return "eDP";
|
||||
case DRM_MODE_CONNECTOR_VIRTUAL:
|
||||
return "Virtual";
|
||||
case DRM_MODE_CONNECTOR_DSI:
|
||||
return "DSI";
|
||||
case DRM_MODE_CONNECTOR_DPI:
|
||||
return "DPI";
|
||||
case DRM_MODE_CONNECTOR_WRITEBACK:
|
||||
return "Writeback";
|
||||
case DRM_MODE_CONNECTOR_SPI:
|
||||
return "SPI";
|
||||
case 20 /*DRM_MODE_CONNECTOR_USB*/:
|
||||
return "USB";
|
||||
default:
|
||||
return "Unsupported";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmGetDevices)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetResources)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetConnectorCurrent)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetCrtc)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeProperty)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreePropertyBlob)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmFreeDevices)
|
||||
|
||||
drmDevice* devices[64];
|
||||
int nDevices = ffdrmGetDevices(devices, sizeof(devices) / sizeof(devices[0]));
|
||||
if (nDevices < 0)
|
||||
return "drmGetDevices() failed";
|
||||
|
||||
for (int iDev = 0; iDev < nDevices; ++iDev)
|
||||
{
|
||||
drmDevice* dev = devices[iDev];
|
||||
|
||||
if (!(dev->available_nodes & (1 << DRM_NODE_PRIMARY)))
|
||||
continue;
|
||||
|
||||
const char* path = dev->nodes[DRM_NODE_PRIMARY];
|
||||
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
drmModeRes* res = ffdrmModeGetResources(fd);
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
for (int iConn = 0; iConn < res->count_connectors; ++iConn)
|
||||
{
|
||||
drmModeConnector* conn = ffdrmModeGetConnectorCurrent(fd, res->connectors[iConn]);
|
||||
if (!conn)
|
||||
continue;
|
||||
|
||||
if (conn->connection != DRM_MODE_CONNECTED)
|
||||
goto next_conn;
|
||||
|
||||
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
|
||||
if (!encoder)
|
||||
goto next_conn;
|
||||
|
||||
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
|
||||
if (!crtc)
|
||||
goto next_encoder;
|
||||
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
for (int iProp = 0; iProp < conn->count_props; ++iProp)
|
||||
{
|
||||
drmModePropertyRes *prop = ffdrmModeGetProperty(fd, conn->props[iProp]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
|
||||
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
|
||||
{
|
||||
// Stangely, prop->count_blobs is 0 and prop->blob_ids is NULL
|
||||
drmModePropertyBlobPtr blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
|
||||
if (blob->length >= 128)
|
||||
ffEdidGetName(blob->data, &name);
|
||||
ffdrmModeFreePropertyBlob(blob);
|
||||
break;
|
||||
}
|
||||
ffdrmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
if (name.length == 0)
|
||||
{
|
||||
const char* connectorTypeName = drmType2Name(conn->connector_type);
|
||||
if (connectorTypeName == NULL)
|
||||
connectorTypeName = "Unknown";
|
||||
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn);
|
||||
}
|
||||
|
||||
uint32_t refreshRate = crtc->mode.vrefresh;
|
||||
if (refreshRate == 0)
|
||||
{
|
||||
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
|
||||
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||
{
|
||||
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
|
||||
{
|
||||
refreshRate = mode->vrefresh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(
|
||||
result,
|
||||
crtc->width, crtc->height,
|
||||
refreshRate,
|
||||
0, 0,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
ffdrmModeFreeCrtc(crtc);
|
||||
|
||||
next_encoder:
|
||||
ffdrmModeFreeEncoder(encoder);
|
||||
|
||||
next_conn:
|
||||
ffdrmModeFreeConnector(conn);
|
||||
}
|
||||
}
|
||||
|
||||
ffdrmFreeDevices(devices, nDevices);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
{
|
||||
#ifdef FF_HAVE_DRM
|
||||
if (drmConnectLibdrm(result) == NULL)
|
||||
return;
|
||||
#endif
|
||||
|
||||
drmParseSysfs(result);
|
||||
}
|
||||
@@ -333,7 +333,7 @@ void ffdsDetectWMDE(FFDisplayServerResult* result)
|
||||
applyPrettyNameIfDE(result, env);
|
||||
|
||||
//If WM was found by connection to the sever, and DE in the environment, we can return
|
||||
//This way we never call getFromProcDir(), which has slow initalization time
|
||||
//This way we never call getFromProcDir(), which has slow initialization time
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
return;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "common/time.h"
|
||||
|
||||
#ifdef FF_HAVE_XCB
|
||||
#include "common/library.h"
|
||||
@@ -60,7 +61,7 @@ static void* xcbGetProperty(XcbPropertyData* data, xcb_connection_t* connection,
|
||||
}
|
||||
|
||||
//Why are xcb property strings not null terminated???
|
||||
void* replyValue = malloc((size_t) (length + 1));
|
||||
void* replyValue = malloc((size_t)length + 1);
|
||||
memcpy(replyValue, data->ffxcb_get_property_value(propertyReply), (size_t) length);
|
||||
((char*) replyValue)[length] = '\0';
|
||||
|
||||
@@ -159,11 +160,9 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
|
||||
|
||||
typedef struct XcbRandrData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_reply)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_modes_iterator)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_info)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_info_reply)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current_reply)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_screen_resources_current_modes_iterator)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_mode_info_next)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_monitors)
|
||||
FF_LIBRARY_SYMBOL(xcb_randr_get_monitors_reply)
|
||||
@@ -189,9 +188,7 @@ typedef struct XcbRandrData
|
||||
XcbPropertyData propData;
|
||||
|
||||
//init per screen
|
||||
uint32_t defaultRefreshRate;
|
||||
uint32_t defaultRotation;
|
||||
xcb_randr_get_screen_resources_reply_t* screenResources;
|
||||
xcb_randr_get_screen_resources_current_reply_t* screenResources;
|
||||
} XcbRandrData;
|
||||
|
||||
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary)
|
||||
@@ -202,7 +199,7 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo
|
||||
data->result,
|
||||
(uint32_t) modeInfo->width,
|
||||
(uint32_t) modeInfo->height,
|
||||
refreshRate == 0 ? data->defaultRefreshRate : refreshRate,
|
||||
refreshRate,
|
||||
(uint32_t) modeInfo->width,
|
||||
(uint32_t) modeInfo->height,
|
||||
rotation,
|
||||
@@ -219,7 +216,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
|
||||
if(data->screenResources == NULL)
|
||||
return false;
|
||||
|
||||
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_modes_iterator(data->screenResources);
|
||||
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(data->screenResources);
|
||||
|
||||
while(modesIterator.rem > 0)
|
||||
{
|
||||
@@ -260,7 +257,7 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
|
||||
data->result,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
data->defaultRefreshRate,
|
||||
0,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
rotation,
|
||||
@@ -334,10 +331,10 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
|
||||
data->result,
|
||||
(uint32_t) monitor->width,
|
||||
(uint32_t) monitor->height,
|
||||
data->defaultRefreshRate,
|
||||
0,
|
||||
(uint32_t) monitor->width,
|
||||
(uint32_t) monitor->height,
|
||||
data->defaultRotation,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
!!monitor->primary,
|
||||
@@ -370,38 +367,10 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
|
||||
static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
{
|
||||
//Init screen info. This is used to get the default refresh rate. If this fails, default refresh rate is simply 0.
|
||||
xcb_randr_get_screen_info_cookie_t screenInfoCookie = data->ffxcb_randr_get_screen_info(data->connection, screen->root);
|
||||
xcb_randr_get_screen_info_reply_t* screenInfoReply = data->ffxcb_randr_get_screen_info_reply(data->connection, screenInfoCookie, NULL);
|
||||
|
||||
if(screenInfoReply != NULL)
|
||||
{
|
||||
data->defaultRefreshRate = screenInfoReply->rate;
|
||||
switch (screenInfoReply->rotation)
|
||||
{
|
||||
case XCB_RANDR_ROTATION_ROTATE_90:
|
||||
data->defaultRotation = 90;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_180:
|
||||
data->defaultRotation = 180;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_270:
|
||||
data->defaultRotation = 270;
|
||||
break;
|
||||
default:
|
||||
data->defaultRotation = 0;
|
||||
break;
|
||||
}
|
||||
free(screenInfoReply);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->defaultRefreshRate = 0;
|
||||
data->defaultRotation = 0;
|
||||
}
|
||||
//Init screen resources. They are used to iterate over all modes. xcbRandrHandleMode checks for " == NULL", to fail as late as possible.
|
||||
xcb_randr_get_screen_resources_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources(data->connection, screen->root);
|
||||
data->screenResources = data->ffxcb_randr_get_screen_resources_reply(data->connection, screenResourcesCookie, NULL);
|
||||
xcb_randr_get_screen_resources_current_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources_current(data->connection, screen->root);
|
||||
|
||||
data->screenResources = data->ffxcb_randr_get_screen_resources_current_reply(data->connection, screenResourcesCookie, NULL);
|
||||
|
||||
//With all the initialisation done, start the detection
|
||||
bool ret = xcbRandrHandleMonitors(data, screen);
|
||||
@@ -416,10 +385,10 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
data->result,
|
||||
(uint32_t) screen->width_in_pixels,
|
||||
(uint32_t) screen->height_in_pixels,
|
||||
data->defaultRefreshRate,
|
||||
0,
|
||||
(uint32_t) screen->width_in_pixels,
|
||||
(uint32_t) screen->height_in_pixels,
|
||||
data->defaultRotation,
|
||||
0,
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
@@ -440,11 +409,9 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_intern_atom_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_modes_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_current_modes_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_mode_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_reply,)
|
||||
@@ -464,17 +431,21 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
|
||||
bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &data.propData);
|
||||
|
||||
|
||||
data.connection = ffxcb_connect(NULL, NULL);
|
||||
if(data.connection == NULL)
|
||||
return;
|
||||
|
||||
|
||||
data.result = result;
|
||||
|
||||
xcb_screen_iterator_t iterator = ffxcb_setup_roots_iterator(ffxcb_get_setup(data.connection));
|
||||
|
||||
|
||||
if(iterator.rem > 0 && propertyDataInitialized)
|
||||
xcbDetectWMfromEWMH(&data.propData, data.connection, iterator.data->root, result);
|
||||
|
||||
|
||||
while(iterator.rem > 0)
|
||||
{
|
||||
xcbRandrHandleScreen(&data, iterator.data);
|
||||
@@ -483,6 +454,7 @@ void ffdsConnectXcbRandr(FFDisplayServerResult* result)
|
||||
|
||||
ffxcb_disconnect(data.connection);
|
||||
|
||||
|
||||
//If wayland hasn't set this, connection failed for it. So we are running only a X Server, not XWayland.
|
||||
if(result->wmProtocolName.length == 0)
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
|
||||
@@ -117,11 +117,9 @@ typedef struct XrandrData
|
||||
FF_LIBRARY_SYMBOL(XInternAtom)
|
||||
FF_LIBRARY_SYMBOL(XGetAtomName);
|
||||
FF_LIBRARY_SYMBOL(XFree);
|
||||
FF_LIBRARY_SYMBOL(XRRGetScreenInfo)
|
||||
FF_LIBRARY_SYMBOL(XRRConfigCurrentConfiguration)
|
||||
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
|
||||
FF_LIBRARY_SYMBOL(XRRGetMonitors)
|
||||
FF_LIBRARY_SYMBOL(XRRGetScreenResources)
|
||||
FF_LIBRARY_SYMBOL(XRRGetScreenResourcesCurrent)
|
||||
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
|
||||
FF_LIBRARY_SYMBOL(XRRGetOutputProperty)
|
||||
FF_LIBRARY_SYMBOL(XRRGetCrtcInfo)
|
||||
@@ -129,15 +127,12 @@ typedef struct XrandrData
|
||||
FF_LIBRARY_SYMBOL(XRRFreeOutputInfo)
|
||||
FF_LIBRARY_SYMBOL(XRRFreeScreenResources)
|
||||
FF_LIBRARY_SYMBOL(XRRFreeMonitors)
|
||||
FF_LIBRARY_SYMBOL(XRRFreeScreenConfigInfo)
|
||||
|
||||
//Init once
|
||||
Display* display;
|
||||
FFDisplayServerResult* result;
|
||||
|
||||
//Init per screen
|
||||
uint32_t defaultRefreshRate;
|
||||
uint32_t defaultRotation;
|
||||
XRRScreenResources* screenResources;
|
||||
} XrandrData;
|
||||
|
||||
@@ -151,7 +146,7 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode)
|
||||
return (double) modeInfo->dotClock / (double) (modeInfo->hTotal * modeInfo->vTotal);
|
||||
}
|
||||
}
|
||||
return data->defaultRefreshRate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary)
|
||||
@@ -246,10 +241,10 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
data->result,
|
||||
(uint32_t) monitorInfo->width,
|
||||
(uint32_t) monitorInfo->height,
|
||||
data->defaultRefreshRate,
|
||||
0,
|
||||
(uint32_t) monitorInfo->width,
|
||||
(uint32_t) monitorInfo->height,
|
||||
data->defaultRotation,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
!!monitorInfo->primary,
|
||||
@@ -279,39 +274,8 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
|
||||
|
||||
static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
{
|
||||
//Init screen configuration. This is used to get the default refresh rate. If this fails, default refresh rate is simply 0.
|
||||
XRRScreenConfiguration* screenConfiguration = data->ffXRRGetScreenInfo(data->display, RootWindowOfScreen(screen));
|
||||
|
||||
if(screenConfiguration != NULL)
|
||||
{
|
||||
data->defaultRefreshRate = (uint32_t) data->ffXRRConfigCurrentRate(screenConfiguration);
|
||||
Rotation rotation = 0;
|
||||
data->ffXRRConfigCurrentConfiguration(screenConfiguration, &rotation);
|
||||
switch (rotation)
|
||||
{
|
||||
case RR_Rotate_90:
|
||||
data->defaultRotation = 90;
|
||||
break;
|
||||
case RR_Rotate_180:
|
||||
data->defaultRotation = 180;
|
||||
break;
|
||||
case RR_Rotate_270:
|
||||
data->defaultRotation = 270;
|
||||
break;
|
||||
default:
|
||||
data->defaultRotation = 0;
|
||||
break;
|
||||
}
|
||||
data->ffXRRFreeScreenConfigInfo(screenConfiguration);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->defaultRefreshRate = 0;
|
||||
data->defaultRotation = 0;
|
||||
}
|
||||
|
||||
//Init screen resources
|
||||
data->screenResources = data->ffXRRGetScreenResources(data->display, RootWindowOfScreen(screen));
|
||||
data->screenResources = data->ffXRRGetScreenResourcesCurrent(data->display, RootWindowOfScreen(screen));
|
||||
|
||||
bool ret = xrandrHandleMonitors(data, screen);
|
||||
|
||||
@@ -325,10 +289,10 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
data->result,
|
||||
(uint32_t) WidthOfScreen(screen),
|
||||
(uint32_t) HeightOfScreen(screen),
|
||||
data->defaultRefreshRate,
|
||||
0,
|
||||
(uint32_t) WidthOfScreen(screen),
|
||||
(uint32_t) HeightOfScreen(screen),
|
||||
data->defaultRotation,
|
||||
0,
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
@@ -348,11 +312,9 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenInfo,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentConfiguration,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResources,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputProperty,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetCrtcInfo,);
|
||||
@@ -360,7 +322,6 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeOutputInfo,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenResources,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeMonitors,);
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRFreeScreenConfigInfo,);
|
||||
|
||||
X11PropertyData propertyData;
|
||||
bool propertyDataInitialized = x11InitPropertyData(xrandr, &propertyData);
|
||||
@@ -388,7 +349,7 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
|
||||
void ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
{
|
||||
//Do nothing here. There are more x11 implementaions to come.
|
||||
//Do nothing here. There are more x11 implementations to come.
|
||||
FF_UNUSED(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_font_font
|
||||
#define FF_INCLUDED_detection_font_font
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_DETECT_FONT_NUM_FONTS 4
|
||||
@@ -20,5 +17,3 @@ typedef struct FFFontResult
|
||||
} FFFontResult;
|
||||
|
||||
const char* ffDetectFont(FFFontResult* font);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_gamepad_gamepad
|
||||
#define FF_INCLUDED_detection_gamepad_gamepad
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFGamepadDevice
|
||||
@@ -12,5 +9,3 @@ typedef struct FFGamepadDevice
|
||||
} FFGamepadDevice;
|
||||
|
||||
const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,9 +20,9 @@ const char* ffDetectGamepad(FFlist* devices /* List of FFGamepadDevice */)
|
||||
report_desc_t repDesc = hid_get_report_desc(fd);
|
||||
if (!repDesc) continue;
|
||||
|
||||
int repId = hid_get_report_id(fd);
|
||||
int reportId = hid_get_report_id(fd);
|
||||
|
||||
struct hid_data* hData = hid_start_parse(repDesc, 0, repId);
|
||||
struct hid_data* hData = hid_start_parse(repDesc, 0, reportId);
|
||||
if (hData)
|
||||
{
|
||||
struct hid_item hItem;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_gpu_gpu
|
||||
#define FF_INCLUDED_detection_gpu_gpu
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
@@ -42,5 +39,3 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
|
||||
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
|
||||
|
||||
const char* ffGetGPUVendorString(unsigned vendorId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -138,12 +138,10 @@ static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev*
|
||||
|
||||
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
|
||||
if(tempValue->deviceClass == device->device_class * 256)
|
||||
{
|
||||
@@ -194,7 +192,7 @@ FF_MAYBE_UNUSED static void pciDetectType(FFGPUResult* gpu)
|
||||
//and their memory sizes are usually smaller than 1GB.
|
||||
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
|
||||
{
|
||||
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 // 1GB
|
||||
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 // 1GB
|
||||
? FF_GPU_TYPE_DISCRETE
|
||||
: FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
@@ -254,7 +252,7 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
}, "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;
|
||||
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_gtkqt_gtkqt
|
||||
#define FF_INCLUDED_detection_gtkqt_gtkqt
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFGTKResult
|
||||
@@ -28,5 +25,3 @@ const FFGTKResult* ffDetectGTK2(void);
|
||||
const FFGTKResult* ffDetectGTK4(void);
|
||||
const FFGTKResult* ffDetectGTK3(void);
|
||||
const FFQtResult* ffDetectQt(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_host_host
|
||||
#define FF_INCLUDED_detection_host_host
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFHostResult
|
||||
@@ -14,6 +11,4 @@ typedef struct FFHostResult
|
||||
FFstrbuf sysVendor;
|
||||
} FFHostResult;
|
||||
|
||||
const char* ffDetectHost(FFHostResult* result);
|
||||
|
||||
#endif
|
||||
const char* ffDetectHost(FFHostResult* host);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#include "host.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
static const char* getProductName(const FFstrbuf* hwModel)
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static const char* getProductNameWithHwModel(const FFstrbuf* hwModel)
|
||||
{
|
||||
// Macbook Pro: https://support.apple.com/en-us/HT201300
|
||||
// Macbook Air: https://support.apple.com/en-us/HT201862
|
||||
@@ -108,6 +111,15 @@ static const char* getProductName(const FFstrbuf* hwModel)
|
||||
else if(ffStrbufStartsWithS(hwModel, "Mac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Mac");
|
||||
if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,4")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
|
||||
if(ffStrEquals(version, "15,5")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
|
||||
if(ffStrEquals(version, "15,6") ||
|
||||
ffStrEquals(version, "15,8") ||
|
||||
ffStrEquals(version, "15,10")) return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "15,7") ||
|
||||
ffStrEquals(version, "15,9") ||
|
||||
ffStrEquals(version, "15,11")) return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)";
|
||||
if(ffStrEquals(version, "14,15")) return "MacBook Air (15-inch, M2, 2023)";
|
||||
if(ffStrEquals(version, "14,14")) return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
|
||||
if(ffStrEquals(version, "14,13")) return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
|
||||
@@ -152,15 +164,45 @@ static const char* getProductName(const FFstrbuf* hwModel)
|
||||
if(ffStrEquals(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(ffStrEquals(version, "9,1")) return "iMac (24/20-inch, Early 2009)";
|
||||
}
|
||||
return hwModel->chars;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* getProductNameWithIokit(FFstrbuf* result)
|
||||
{
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceNameMatching("product"), &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ffCfDictGetString(properties, CFSTR("product-name"), result))
|
||||
break;
|
||||
}
|
||||
|
||||
IOObjectRelease(registryEntry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffDetectHost(FFHostResult* host)
|
||||
{
|
||||
ffStrbufAppendS(&host->sysVendor, "Apple");
|
||||
ffStrbufSetStatic(&host->sysVendor, "Apple");
|
||||
|
||||
const char* error = ffSysctlGetString("hw.model", &host->productFamily);
|
||||
if (error) return error;
|
||||
ffStrbufAppendS(&host->productName, getProductName(&host->productFamily));
|
||||
|
||||
ffStrbufSetStatic(&host->productName, getProductNameWithHwModel(&host->productFamily));
|
||||
if (host->productName.length == 0)
|
||||
getProductNameWithIokit(&host->productName);
|
||||
if (host->productName.length == 0)
|
||||
ffStrbufSet(&host->productName, &host->productFamily);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_icons
|
||||
#define FF_INCLUDED_detection_icons
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDetectIcons(FFstrbuf* result);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_internal
|
||||
#define FF_INCLUDED_detection_internal
|
||||
|
||||
#include "common/thread.h"
|
||||
|
||||
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
|
||||
@@ -12,6 +9,4 @@
|
||||
return &result; \
|
||||
init = true; \
|
||||
__VA_ARGS__; \
|
||||
return &result; \
|
||||
|
||||
#endif
|
||||
return &result;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user