mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
Compare commits
281 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 | |||
| 315cb24046 | |||
| 4cabc5684b | |||
| 256c9be19b | |||
| 1b3d713e50 | |||
| 6e816fca6e | |||
| 5a699af610 | |||
| 390119c592 | |||
| 11d7eec4db | |||
| f59be1faf2 | |||
| 7bc4c63eb4 | |||
| 4bf9f524d9 | |||
| 6508ccfc0d | |||
| d0a8d3cdc4 | |||
| 494cc1493e | |||
| 761c649817 | |||
| a2f576f3e5 | |||
| 3b9b03a086 | |||
| ab51a209d7 | |||
| 38ac339011 | |||
| b4777fe73a | |||
| b6e759f3a2 | |||
| 9ddefbc1a2 | |||
| a16851f5de | |||
| 8fe291d161 | |||
| 9ac50fc42f | |||
| c6e5221826 | |||
| 5b2006cd06 | |||
| d3f673dc6f | |||
| b99f444234 | |||
| c504096181 | |||
| c9ef47271a | |||
| fc3891c913 | |||
| cd07354b6f | |||
| fd5aeb2052 | |||
| b1b583721a | |||
| 4c3372a886 | |||
| cf66679323 | |||
| 55b41144db | |||
| ae34208247 | |||
| b462006280 | |||
| 485bcbf054 | |||
| 2e30a57889 | |||
| b439d9c203 | |||
| 08a717f5f7 | |||
| 3a84a1a5fa | |||
| 627d5fc659 | |||
| 25849dc4bb | |||
| 63032cd840 | |||
| 2414246de9 | |||
| c52353b4b8 | |||
| 799628c083 | |||
| 38d5791d57 | |||
| 9d664e2b61 | |||
| 2eb21e3521 | |||
| bfe1265c44 | |||
| dd3109cd89 | |||
| 130d5a5202 | |||
| cda4c62e9e | |||
| df245f32ec | |||
| 04409f4381 | |||
| 155e4a5b80 | |||
| 59a9209621 | |||
| cd5e14a834 | |||
| e707cf8464 | |||
| 8bdd410e97 | |||
| f45654620f | |||
| 72d138f8c4 | |||
| 6a0df7ae49 | |||
| 23def0a1c7 | |||
| 3236ef075d | |||
| d00b301904 | |||
| 6c82686283 | |||
| 399e2235d4 | |||
| bd898e4006 | |||
| 2c49dcceaf | |||
| 3c5b002414 | |||
| ca37206a49 | |||
| 8a939e981c | |||
| bed1b4cf0f | |||
| 04c3a4ccf7 | |||
| f50368a949 | |||
| 4e018dbf26 | |||
| fa02217ff4 | |||
| 22080d36b0 | |||
| 3303f4e1ce | |||
| 11d03ad59e | |||
| 504f1533c2 | |||
| bf1d1cbac5 | |||
| 94119d1674 | |||
| f4a263df01 | |||
| 533231825c | |||
| 40e2787d94 | |||
| 281af9c86f | |||
| fc0db8c291 | |||
| 48d2dbad34 | |||
| be2af8aeaf | |||
| a7621a7301 | |||
| ec87790e4f | |||
| 44632e9bf6 | |||
| 824ada49b6 | |||
| e7938216ba | |||
| 40d6d0b7b5 | |||
| 3f4d4c8eea | |||
| e2fe94d4e4 | |||
| debb5d8ad1 | |||
| f61794ea70 | |||
| d15a977431 |
@@ -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
|
||||
+61
-33
@@ -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,16 +204,19 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/freebsd-vm@v0
|
||||
uses: cross-platform-actions/action@v0.21.1
|
||||
with:
|
||||
prepare: |
|
||||
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
|
||||
operating_system: freebsd
|
||||
version: '13.2'
|
||||
run: |
|
||||
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
|
||||
@@ -214,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 .
|
||||
@@ -235,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
|
||||
@@ -293,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
|
||||
@@ -302,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
|
||||
|
||||
+160
-11
@@ -1,3 +1,150 @@
|
||||
# 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
|
||||
|
||||
Changes:
|
||||
* `--pipe` and `--stat` are moved from `general` options to `display` options. This affects cjson configuration.
|
||||
* Display keys `percent*` and `size*` in JSON config are restructured. e.g. `{ "sizeNdigits": 1 }` is now `{ "size": { "ndigits": 1 } }`
|
||||
* With the introduction of `--migrate-config`, the old flag based config file is deprecated, and will be removed in 3.0.0 (next major version)
|
||||
* Support of `--gen-config conf` is deprecated accordingly, and will be removed in 2.3.0 (next minor version)
|
||||
* The global flag `--allow-slow-operations` is 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.
|
||||
* `--wm-detect-plugin`: control whether WM plugins should be detected. Note it's implemented with global processes enumeration and can report false results.
|
||||
* `--de-slow-version-detection`: control DE version should be detected with slow operations. It's usually not necessary and only provided as a backup.
|
||||
* `--localip-default-route-only` and `--netio-default-route-only` defaults to true to avoid large number of results
|
||||
|
||||
Features:
|
||||
* Quirks for MIPS platforms (CPU, Linux)
|
||||
* Use devicetree path for OBP hosts (Host, Linux)
|
||||
* Detect `tmux: server` as tmux (Terminal, Linux)
|
||||
* Support urxvt version detection (Terminal, Linux)
|
||||
* Support st version detection (Terminal, Linux)
|
||||
* Support st terminal font detection (TerminalFont, Linux)
|
||||
* Support xfce4-terminal 1.1.0+ terminal font detection (TerminalFont, Linux)
|
||||
* Add option `--migrate-config <?target-file-path>`
|
||||
* Support Nvidia GPU temp and cuda core count detection via nvml. Use `--gpu-use-nvml` to enable it (GPU)
|
||||
* Try supporting Wifi authentication type detection in macOS Sonoma. Please file a feature request if you get `to be supported (num)` with result of `/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep auth` (Wifi, macOS)
|
||||
|
||||
Bugfixes:
|
||||
* Better GPU memory and type detection (GPU, Windows)
|
||||
* Don't print display type twice (Display)
|
||||
* Detect BSSID instead of Wifi MAC address to align with other platforms (Wifi, macOS)
|
||||
* Remove support of used GPU memory detection, which is not reliable and only supported with `--gpu-force-vulkan`. (GPU)
|
||||
* Fix flag `--brightness-ddcci-sleep` (Brightness, Linux)
|
||||
* Fix hanging if a child process prints to both stdout and stderr (Linux)
|
||||
|
||||
Logos:
|
||||
* Add Black Mesa
|
||||
* Add cycledream
|
||||
* Add Evolinx
|
||||
* Add azos
|
||||
* Add Interix
|
||||
|
||||
# 2.1.2
|
||||
|
||||
Bugfixes:
|
||||
@@ -27,6 +174,8 @@ Logo:
|
||||
* Add Chimera Linux
|
||||
* Add EndeavourSmall
|
||||
* Add Xenia
|
||||
* Add MainsailOS
|
||||
* Fix phyOS
|
||||
|
||||
# 2.1.0
|
||||
|
||||
@@ -34,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)
|
||||
|
||||
@@ -116,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:
|
||||
@@ -128,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`).
|
||||
@@ -184,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:
|
||||
@@ -272,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`
|
||||
@@ -295,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)
|
||||
@@ -331,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
|
||||
@@ -376,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
|
||||
|
||||
@@ -458,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:
|
||||
@@ -467,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
|
||||
|
||||
+76
-35
@@ -1,9 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.1.2
|
||||
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)
|
||||
@@ -70,8 +71,9 @@ cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
cmake_dependent_option(ENABLE_PCI_MEMORY "Enable detecting GPU memory size with libpci" OFF "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embeded) yyjson library" OFF "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch 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
|
||||
|
||||
@@ -97,7 +99,7 @@ endif()
|
||||
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
|
||||
|
||||
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
||||
enable_language(CXX)
|
||||
@@ -116,7 +118,8 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
|
||||
endif()
|
||||
|
||||
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
if(ENABLE_ASAN)
|
||||
message(STATUS "Address sanitizer enabled (DEBUG only)")
|
||||
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
|
||||
@@ -202,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)
|
||||
@@ -226,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}")
|
||||
@@ -297,7 +304,6 @@ set(LIBFASTFETCH_SRC
|
||||
src/logo/image/im7.c
|
||||
src/logo/image/image.c
|
||||
src/logo/logo.c
|
||||
src/logo/option.c
|
||||
src/modules/battery/battery.c
|
||||
src/modules/bios/bios.c
|
||||
src/modules/bluetooth/bluetooth.c
|
||||
@@ -355,6 +361,11 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/wifi/wifi.c
|
||||
src/modules/wm/wm.c
|
||||
src/modules/wmtheme/wmtheme.c
|
||||
src/options/display.c
|
||||
src/options/modules.c
|
||||
src/options/logo.c
|
||||
src/options/general.c
|
||||
src/options/library.c
|
||||
src/util/edidHelper.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFstrbuf.c
|
||||
@@ -382,12 +393,14 @@ 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
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/gpu/gpu_nvidia.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_linux.c
|
||||
src/detection/icons/icons_linux.c
|
||||
@@ -416,6 +429,8 @@ if(LINUX)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_linux.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
)
|
||||
@@ -465,6 +480,8 @@ elseif(ANDROID)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_nosupport.c
|
||||
src/detection/wifi/wifi_android.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
)
|
||||
@@ -488,12 +505,14 @@ 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
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/gpu/gpu_nvidia.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_bsd.c
|
||||
src/detection/lm/lm_linux.c
|
||||
@@ -522,6 +541,8 @@ elseif(BSD)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_bsd.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
)
|
||||
@@ -535,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
|
||||
@@ -572,6 +593,8 @@ elseif(APPLE)
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_apple.c
|
||||
src/detection/wifi/wifi_apple.m
|
||||
src/detection/wm/wm_apple.c
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/util/apple/cf_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
@@ -597,6 +620,7 @@ elseif(WIN32)
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.c
|
||||
src/detection/gpu/gpu_nvidia.c
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/icons/icons_windows.c
|
||||
src/detection/libc/libc_windows.cpp
|
||||
@@ -623,6 +647,8 @@ elseif(WIN32)
|
||||
src/detection/users/users_windows.c
|
||||
src/detection/wallpaper/wallpaper_windows.c
|
||||
src/detection/wifi/wifi_windows.c
|
||||
src/detection/wm/wm_windows.cpp
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/com.cpp
|
||||
@@ -763,6 +789,10 @@ ff_lib_enable(X11
|
||||
"x11"
|
||||
"X11"
|
||||
)
|
||||
ff_lib_enable(DRM
|
||||
"libdrm"
|
||||
"Libdrm"
|
||||
)
|
||||
ff_lib_enable(GIO
|
||||
"gio-2.0"
|
||||
"GIO"
|
||||
@@ -868,32 +898,32 @@ elseif(APPLE)
|
||||
PRIVATE "-framework OpenCL"
|
||||
PRIVATE "-framework SystemConfiguration"
|
||||
PRIVATE "-weak_framework CoreDisplay"
|
||||
PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks"
|
||||
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
|
||||
|
||||
PRIVATE "-F /System/Library/PrivateFrameworks"
|
||||
PRIVATE "-weak_framework DisplayServices"
|
||||
PRIVATE "-weak_framework MediaRemote"
|
||||
PRIVATE "-weak_framework Apple80211"
|
||||
)
|
||||
elseif(WIN32)
|
||||
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)
|
||||
@@ -1010,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}"
|
||||
@@ -1020,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)
|
||||
|
||||
@@ -23,147 +23,53 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
|
||||
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
||||
|
||||
## Customization
|
||||
## Installation
|
||||
|
||||
With customization and speed being two competing goals, this project actually builds two executables:
|
||||
### Linux
|
||||
|
||||
* The main one is `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent by modifying `$XDG_CONFIG_HOME/fastfetch/config.conf`. Use `fastfetch --gen-config conf` to generate one. To view the available options, run `fastfetch --help`.
|
||||
* The second executable is called `flashfetch`, which is configured at compile time to eliminate any possible overhead. Configuration of it can be very easily done in [`src/flashfetch.c`](src/flashfetch.c).
|
||||
* Debian / Ubuntu: Download `fastfetch-<version>-Linux.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and `sudo apt install fastfetch-<version>-Linux.deb`
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
* Gentoo: `sudo emerge --ask app-misc/fastfetch`
|
||||
|
||||
Currently, the performance difference is measurable, but too small to be recognizable by humans. But with more options planned, the leap will get bigger over time and on slow machines this might actually make a difference.
|
||||
|
||||
There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config <filename>`. They may also serve as a good example for format arguments.
|
||||
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
### Customization with new JSONC format
|
||||
|
||||
A new, structure based, and user-friendly config file format was introduced in v2.0.0. This format is based on [JSONC](https://jsonc.org/). [See more details in Wiki](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration)
|
||||
|
||||
## Dependencies
|
||||
|
||||
Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl`, `libm` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most Linux distributions.
|
||||
|
||||
The following libraries are used if present at runtime:
|
||||
|
||||
### Linux and FreeBSD
|
||||
|
||||
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
|
||||
* [`libxcb-randr`](https://xcb.freedesktop.org/),
|
||||
[`libXrandr`](https://gitlab.freedesktop.org/xorg/lib/libxrandr),
|
||||
[`libxcb`](https://xcb.freedesktop.org/),
|
||||
[`libX11`](https://gitlab.freedesktop.org/xorg/lib/libx11): At least one of them sould be present in X11 sessions for better display detection and faster WM detection. The `*randr` ones provide multi monitor support The `libxcb*` ones usually have better performance.
|
||||
* [`libwayland-client`](https://wayland.freedesktop.org/): Better display performance and output in wayland sessions. Supports different refresh rates per monitor.
|
||||
* [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings.
|
||||
* [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings.
|
||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol.
|
||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art.
|
||||
* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol.
|
||||
* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Bluetooth, Player & Media detection.
|
||||
* [`libEGL`](https://www.khronos.org/registry/EGL/),
|
||||
[`libGLX`](https://dri.freedesktop.org/wiki/GLX/),
|
||||
[`libOSMesa`](https://docs.mesa3d.org/osmesa.html): At least one of them is needed by the OpenGL module for gl context creation.
|
||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module
|
||||
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
|
||||
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
|
||||
* [`libnm`](https://networkmanager.dev/docs/libnm/latest/): Used for Wifi detection.
|
||||
* [`libpulse`](https://freedesktop.org/software/pulseaudio/doxygen/): Used for Sound detection.
|
||||
* [`libddcutil`](https://github.com/rockowitz/ddcutil): Used for brightness detection of external displays
|
||||
* [`DirectX-Headers`](https://github.com/microsoft/DirectX-Headers): Used for GPU detection in WSL
|
||||
[See also if fastfetch has been packaged for your favorite Linux distro](#Packaging)
|
||||
|
||||
### macOS
|
||||
|
||||
* [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system.
|
||||
* [`DisplayServices`](https://developer.apple.com/forums/thread/666383#663154022): Need for screen brightness detection. It's a private framework provided by newer macOS system.
|
||||
* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb)
|
||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb)
|
||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb)
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Used for fast wallpaper detection ( fallback to AppleScript )
|
||||
|
||||
For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported.
|
||||
`brew install fastfetch`
|
||||
|
||||
### Windows
|
||||
|
||||
* [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection.
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers)
|
||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd)
|
||||
`scoop install fastfetch`
|
||||
|
||||
Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, as fastfetch for Windows targets [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library, [it must be installed manually](https://support.microsoft.com/en-us/topic/update-for-universal-c-runtime-in-windows-c0514201-7fe6-95a3-b0a5-287930f3560c) as UCRT is only pre-installed in Windows 10 and later.
|
||||
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
|
||||
|
||||
For the image logo, WezTerm with iterm image protocol is known to work, surprisingly.
|
||||
### FreeBSD
|
||||
|
||||
### Android
|
||||
`pkg install fastfetch`
|
||||
|
||||
* [`freetype`](https://www.freetype.org/): Used for Termux font detection. [`freetype`](https://github.com/termux/termux-packages/tree/master/packages/freetype)
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. [`vulkan-loader-android`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-loader-android) [`vulkan-headers`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-headers)
|
||||
* [`termux-api`](https://github.com/termux/termux-api-package): Used for Wifi / Battery detection. Both the package [termux-api](https://github.com/termux/termux-packages/tree/master/packages/termux-api) and the Android app [Termux API](https://github.com/termux/termux-api) must be installed and the app `Termux API` must be configured to be able to self-running. In order to make Wifi detection actuall work, location privilege must be granted to the app `Termux API`. Read [the official doc](https://wiki.termux.com/wiki/Termux:API) for detail.
|
||||
* [`libandroid-wordexp-static`](https://github.com/termux/termux-packages/tree/master/packages/libandroid-wordexp): `wordexp.h` support for Android.
|
||||
### Android (Termux)
|
||||
|
||||
For the image logo, [Termux Monet](https://github.com/HardcodedCat/termux-monet) supports iterm image protocol.
|
||||
`pkg install fastfetch`
|
||||
|
||||
## Support status
|
||||
All categories not listed here should work without needing a specific implementation.
|
||||
## Build from source
|
||||
|
||||
##### Available Modules
|
||||
```
|
||||
Battery, Bios, Bluetooth, Board, Break, Brightness, Colors, Command, CPU, CPUUsage, Cursor, Custom, Date, DateTime, DE, Disk, DiskIO, Display, Font, Gamepad, GPU, Host, Icons, Kernel, LM, Locale, LocalIP, Media, Memory, Monitor, NetIO, OpenCL, OpenGL, OS, Packages, Player, Power Adapter, Processes, PublicIP, Separator, Shell, Sound, Swap, Terminal, Terminal Font, Terminal Size, Theme, Time, Title, Uptime, Version, Vulkan, Wallpaper, Weather, Wifi, WM, WMTheme
|
||||
```
|
||||
See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
|
||||
##### Builtin logos
|
||||
## Usage
|
||||
|
||||
<!-- `Content of src/logo/builtin.c`.split('\n').map(x => x.trim()).filter(x => x.startsWith('// ')).map(x => x.slice(3)).filter(x => x != 'LAST').sort((a, b)=>a.toUpperCase().localeCompare(b.toUpperCase())).join(', ') -->
|
||||
```
|
||||
AerOS, Afterglow, AIX, AlmaLinux, Alpine, Alpine2Small, AlpineSmall, Alter, Amazon, AmazonLinux, AmogOS, Anarchy, Android, AndroidSmall, Antergos, Antix, AoscOS, AoscOS_old, AoscOsRetro, AoscOsRetro_small, Aperture, Apple, AppleSmall, Apricity, Arch, Arch2, ArchBox, Archcraft, Archcraft2, Archlabs, ArchSmall, ArchStrike, ArcoLinux, ArcoLinuxSmall, ArseLinux, Artix, Artix2Small, ArtixSmall, Arya, Asahi, Aster, AsteroidOS, AstOS, Astra, Ataraxia, Athena, Bedrock, BigLinux, Bitrig, BlackArch, BlackPanther, BLAG, BlankOn, BlueLight, Bodhi, Bonsai, BSD, BunsenLabs, CachyOS, CachyOSSmall, Calculate, CalinixOS, CalinixOSSmall, Carbs, CBL-Mariner, CelOS, Center, CentOS, CentOSSmall, Chakra, ChaletOS, Chapeau, Chimera Linux, ChonkySealOS, Chrom, Cleanjaro, CleanjaroSmall, ClearLinux, ClearOS, Clover, Cobalt, Condres, ContainerLinux, CRUX, CRUXSmall, CrystalLinux, Cucumber, CutefishOS, CuteOS, CyberOS, Dahlia, DarkOS, Debian, DebianSmall, Deepin, DesaOS, Devuan, DevuanSmall, DietPi, DracOS, DragonFly, DragonFlyOld, DragonFlySmall, Drauger, Droidian, Elbrus, Elementary, ElementarySmall, Elive, EncryptOS, Endeavour, EndeavourSmall, Endless, Enso, EuroLinux, EvolutionOS, EvolutionOS_old, EvolutionOSSmall, Exherbo, ExodiaPredator, Fedora, FedoraOld, FedoraSmall, FemboyOS, Feren, Finnix, Floflis, FreeBSD, FreeBSDSmall, FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, GarudaDragon, GarudaSmall, Gentoo, GentooSmall, GhostBSD, Glaucus, GNewSense, Gnome, GNU, GoboLinux, GrapheneOS, Grombyang, Guix, GuixSmall, Haiku, HaikuSmall, HamoniKR, HarDClanZ, HardenedBSD, Hash, Huayra, Hybrid, HydroOS, Hyperbola, HyperbolaSmall, Iglunix, InstantOS, IRIX, Itc, Januslinux, Kaisen, Kali, KaliSmall, KaOS, KDENeon, Kibojoe, KISSLinux, Kogaion, Korora, KrassOS, KSLinux, Kubuntu, LainOS, LangitKetujuh, Laxeros, LEDE, LibreELEC, Linspire, Linux, LinuxLight, LinuxLightSmall, LinuxMint, LinuxMintOld, LinuxMintSmall, LinuxSmall, Live_Raizo, LMDE, Lunar, MacOS, MacOS2, MacOS2Small, MacOSSmall, Mageia, MageiaSmall, MagpieOS, Mandriva, Manjaro, ManjaroSmall, MassOS, MatuusOS, MaUI, Meowix, Mer, Minix, Mint, MintOld, MintSmall, MiracleLinux, MOS, Msys2, MX, MXSmall, Namib, Nekos, Neptune, NetBSD, NetRunner, Nitrux, NixOS, NixOS_small, NixOsOld, NixOsSmall, Nobara, NomadBSD, Nurunner, NuTyX, Obarun, OBRevenge, OmniOS, OpenBSD, OpenBSDSmall, OpenEuler, OpenIndiana, OpenKylin, OpenMamba, OpenMandriva, OpenStage, OpenSuse, OpenSuseLeap, OpenSuseSmall, OpenSuseTumbleweed, OpenWrt, OPNsense, Oracle, Orchid, OrchidSmall, OS_Elbrus, OSMC, OSX, OSXSmall, PacBSD, Panwah, Parabola, ParabolaSmall, Parch, Pardus, Parrot, Parsix, PCBSD, PCLinuxOS, PearOS, Pengwin, Pentoo, Peppermint, PhyOS, Pisi, PNMLinux, Pop, PopSmall, Porteus, PostMarketOS, PostMarketOSSmall, Proxmox, PuffOS, Puppy, PureOS, PureOSSmall, Q4OS, Qubes, Qubyt, Quibian, Radix, Raspbian, RaspbianSmall, RavynOS, Reborn, RebornSmall, RedCore, RedHatEnterpriseLinux, RedHatEnterpriseLinux_old, RedstarOS, Refracted Devuan, Regata, Regolith, RhaymOS, RockyLinux, RockyLinuxSmall, RosaLinux, Sabayon, Sabotage, Sailfish, SalentOS, SalientOS, Salix, SambaBOX, Sasanqua, Scientific, Semc, Septor, Serene, SharkLinux, ShastraOS, Siduction, SkiffOS, Slackel, Slackware, SlackwareSmall, Slitaz, SmartOS, Soda, Solaris, SolarisSmall, Solus, SourceMage, Sparky, Star, SteamOS, StockLinux, Sulin, Suse, SuseSmall, Swagarch, T2, Tails, TeArch, TorizonCore, Trisquel, TuxedoOS, Twister, Ubuntu, Ubuntu2Old, Ubuntu2Small, UbuntuBudgie, UbuntuCinnamon, UbuntuGnome, UbuntuKde, UbuntuKylin, UbuntuMate, UbuntuOld, UbuntuSmall, UbuntuStudio, UbuntuSway, UbuntuTouch, UbuntuUnity, Ultramarine, Univalent, Univention, UOS, UrukOS, Uwuntu, Vanilla, Venom, VenomSmall, Vnux, Void, VoidSmall, Vzlinux, WiiLinuxNgx, Windows, Windows11, Windows11Small, Windows8, Windows95, Xenia, Xferience, YiffOS, Zorin
|
||||
```
|
||||
* Run it with default configuration: `fastfetch`
|
||||
* Run it with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) and find what you interest: `fastfetch -c all.jsonc`
|
||||
* Find all data that fastfetch detects: `fastfetch -s <module> --format json`
|
||||
* Display help messages: `fastfetch --help`
|
||||
* Generate config file based on command line arguments: `fastfetch --arg1 --arg2 --gen-config`
|
||||
|
||||
Run `fastfetch --print-logos` to print them
|
||||
## Customization
|
||||
|
||||
##### Package managers
|
||||
```
|
||||
apk, brew, Chocolatey, dpkg, emerge, eopkg, Flatpak, MacPorts, nix, opkg, Pacman, paludis, pkg, pkgtool, rpm, scoop, Snap, xbps
|
||||
```
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
|
||||
|
||||
##### WM themes
|
||||
```
|
||||
DWM (Windows), KWin, Marco, Muffin, Mutter, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), XFWM
|
||||
```
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
##### DE versions
|
||||
```
|
||||
Budgie, Cinnamon, Gnome, KDE Plasma, LXQt, Mate, XFCE4
|
||||
```
|
||||
|
||||
##### Terminal fonts
|
||||
```
|
||||
Alacritty, Apple Terminal, ConEmu, Deepin Terminal, foot, Gnome Console, Gnome Terminal, iTerm2, Kitty, Konsole, LXTerminal, MATE Terminal, mintty, QTerminal, Tabby, Terminator, Termux, Tilix, TTY, Warp, WezTerm, Windows Terminal, XFCE4 Terminal, Yakuake
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are:
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --target fastfetch --target flashfetch
|
||||
```
|
||||
|
||||
If the build process fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available.
|
||||
|
||||
### Building on Windows
|
||||
|
||||
Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 subsystem (or CLANGARM64 if needed) is suggested (and tested) to build fastfetch. If you need Windows 7 / 8.x support, using MINGW64 is suggested.
|
||||
|
||||
1. Install [MSYS2](https://www.msys2.org/#installation)
|
||||
1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime)
|
||||
1. Install dependencies
|
||||
```bash
|
||||
pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
|
||||
```
|
||||
|
||||
Follow the building instructions of Linux next.
|
||||
|
||||
## Packaging
|
||||
|
||||
@@ -179,7 +85,7 @@ Follow the building instructions of Linux next.
|
||||
## 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
|
||||
+327
-209
File diff suppressed because it is too large
Load Diff
@@ -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": "=",
|
||||
|
||||
Vendored
+10359
File diff suppressed because it is too large
Load Diff
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/NVIDIA/nvidia-settings/blob/main/src/nvml.h",
|
||||
"license": "Embed in source",
|
||||
"version": "545.23.06",
|
||||
"author": "NVIDIA Corporation"
|
||||
}
|
||||
+27
-21
@@ -6,15 +6,17 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
||||
{
|
||||
assert(green <= 100 && yellow <= 100 && red <= 100);
|
||||
|
||||
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * instance.config.barWidth + 0.5);
|
||||
uint32_t blocksGreen = (uint32_t) (green / 100.0 * instance.config.barWidth + 0.5);
|
||||
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * instance.config.barWidth + 0.5);
|
||||
uint32_t blocksRed = (uint32_t) (red / 100.0 * instance.config.barWidth + 0.5);
|
||||
assert(blocksPercent <= instance.config.barWidth);
|
||||
const FFOptionsDisplay* options = &instance.config.display;
|
||||
|
||||
if(instance.config.barBorder)
|
||||
uint32_t blocksPercent = (uint32_t) (percent / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksGreen = (uint32_t) (green / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksYellow = (uint32_t) (yellow / 100.0 * options->barWidth + 0.5);
|
||||
uint32_t blocksRed = (uint32_t) (red / 100.0 * options->barWidth + 0.5);
|
||||
assert(blocksPercent <= options->barWidth);
|
||||
|
||||
if(options->barBorder)
|
||||
{
|
||||
if(!instance.config.pipe)
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m[ ");
|
||||
else
|
||||
ffStrbufAppendS(buffer, "[ ");
|
||||
@@ -22,7 +24,7 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
||||
|
||||
for (uint32_t i = 0; i < blocksPercent; ++i)
|
||||
{
|
||||
if(!instance.config.pipe)
|
||||
if(!options->pipe)
|
||||
{
|
||||
if (i == blocksGreen)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||
@@ -31,26 +33,26 @@ void ffAppendPercentBar(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
||||
else if (i == blocksRed)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||
}
|
||||
ffStrbufAppend(buffer, &instance.config.barCharElapsed);
|
||||
ffStrbufAppend(buffer, &options->barCharElapsed);
|
||||
}
|
||||
|
||||
if (blocksPercent < instance.config.barWidth)
|
||||
if (blocksPercent < options->barWidth)
|
||||
{
|
||||
if(!instance.config.pipe)
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m");
|
||||
for (uint32_t i = blocksPercent; i < instance.config.barWidth; ++i)
|
||||
ffStrbufAppend(buffer, &instance.config.barCharTotal);
|
||||
for (uint32_t i = blocksPercent; i < options->barWidth; ++i)
|
||||
ffStrbufAppend(buffer, &options->barCharTotal);
|
||||
}
|
||||
|
||||
if(instance.config.barBorder)
|
||||
if(options->barBorder)
|
||||
{
|
||||
if(!instance.config.pipe)
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_WHITE "m ]");
|
||||
else
|
||||
ffStrbufAppendS(buffer, " ]");
|
||||
}
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!options->pipe)
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
@@ -67,14 +69,18 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
||||
{
|
||||
assert(green <= 100 && yellow <= 100);
|
||||
|
||||
bool colored = !!(instance.config.percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
|
||||
const FFOptionsDisplay* options = &instance.config.display;
|
||||
|
||||
bool colored = !!(options->percentType & FF_PERCENTAGE_TYPE_NUM_COLOR_BIT);
|
||||
|
||||
if (parentheses)
|
||||
ffStrbufAppendC(buffer, '(');
|
||||
|
||||
if (colored && !instance.config.pipe)
|
||||
if (colored && !options->pipe)
|
||||
{
|
||||
if(green < yellow)
|
||||
if(percent != percent)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_BLACK "m");
|
||||
else if(green < yellow)
|
||||
{
|
||||
if (percent <= green)
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_GREEN "m");
|
||||
@@ -93,9 +99,9 @@ void ffAppendPercentNum(FFstrbuf* buffer, double percent, uint8_t green, uint8_t
|
||||
ffStrbufAppendS(buffer, "\e[" FF_COLOR_FG_LIGHT_RED "m");
|
||||
}
|
||||
}
|
||||
ffStrbufAppendF(buffer, "%.*f%%", instance.config.percentNdigits, percent);
|
||||
ffStrbufAppendF(buffer, "%.*f%%", options->percentNdigits, percent);
|
||||
|
||||
if (colored && !instance.config.pipe)
|
||||
if (colored && !options->pipe)
|
||||
{
|
||||
ffStrbufAppendS(buffer, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+92
-51
@@ -1,6 +1,7 @@
|
||||
#include "commandoption.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/time.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "fastfetch_datatext.h"
|
||||
#include "modules/modules.h"
|
||||
#include "util/stringUtils.h"
|
||||
@@ -8,37 +9,6 @@
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
|
||||
{
|
||||
yyjson_mut_doc* doc = instance.state.resultDoc;
|
||||
if (__builtin_expect(!doc, true)) return NULL;
|
||||
|
||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||
if (baseInfo->generateJson)
|
||||
baseInfo->generateJson(baseInfo, doc, module);
|
||||
else
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||
return module;
|
||||
}
|
||||
|
||||
bool ffParseModuleCommand(const char* type)
|
||||
{
|
||||
if(!isalpha(type[0])) return false;
|
||||
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(type[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
||||
{
|
||||
if (!genJson(baseInfo))
|
||||
baseInfo->printModule(baseInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value)
|
||||
{
|
||||
if (!ffStrStartsWith(key, "--") || !isalpha(key[2])) return false;
|
||||
@@ -53,6 +23,7 @@ bool ffParseModuleOptions(const char* key, const char* value)
|
||||
|
||||
void ffPrepareCommandOption(FFdata* data)
|
||||
{
|
||||
FFOptionsModules* const options = &instance.config.modules;
|
||||
//If we don't have a custom structure, use the default one
|
||||
if(data->structure.length == 0)
|
||||
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||
@@ -61,22 +32,57 @@ void ffPrepareCommandOption(FFdata* data)
|
||||
ffPrepareCPUUsage();
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_DISKIO_MODULE_NAME))
|
||||
ffPrepareDiskIO(&instance.config.diskIo);
|
||||
ffPrepareDiskIO(&options->diskIo);
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_NETIO_MODULE_NAME))
|
||||
ffPrepareNetIO(&instance.config.netIo);
|
||||
ffPrepareNetIO(&options->netIo);
|
||||
|
||||
if(instance.config.multithreading)
|
||||
if(instance.config.general.multithreading)
|
||||
{
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_PUBLICIP_MODULE_NAME))
|
||||
ffPreparePublicIp(&instance.config.publicIP);
|
||||
ffPreparePublicIp(&options->publicIP);
|
||||
|
||||
if(ffStrbufContainIgnCaseS(&data->structure, FF_WEATHER_MODULE_NAME))
|
||||
ffPrepareWeather(&instance.config.weather);
|
||||
ffPrepareWeather(&options->weather);
|
||||
}
|
||||
}
|
||||
|
||||
static void parseStructureCommand(const char* line, FFlist* customValues)
|
||||
static void genJsonConfig(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_val* modules = yyjson_mut_obj_get(doc->root, "modules");
|
||||
if (!modules)
|
||||
modules = yyjson_mut_obj_add_arr(doc, doc->root, "modules");
|
||||
|
||||
yyjson_mut_val* module = yyjson_mut_obj(doc);
|
||||
FF_STRBUF_AUTO_DESTROY type = ffStrbufCreateS(baseInfo->name);
|
||||
ffStrbufLowerCase(&type);
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "type", &type);
|
||||
|
||||
if (baseInfo->generateJsonConfig)
|
||||
baseInfo->generateJsonConfig(baseInfo, doc, module);
|
||||
|
||||
if (yyjson_mut_obj_size(module) > 1)
|
||||
yyjson_mut_arr_add_val(modules, module);
|
||||
else
|
||||
yyjson_mut_arr_add_strbuf(doc, modules, &type);
|
||||
}
|
||||
|
||||
static void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||
if (baseInfo->generateJsonResult)
|
||||
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||
else
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||
}
|
||||
|
||||
static void parseStructureCommand(
|
||||
const char* line,
|
||||
FFlist* customValues,
|
||||
void (*fn)(FFModuleBaseInfo *baseInfo, yyjson_mut_doc* jsonDoc),
|
||||
yyjson_mut_doc* jsonDoc
|
||||
)
|
||||
{
|
||||
// handle `--set` and `--set-keyless`
|
||||
FF_LIST_FOR_EACH(FFCustomValue, customValue, *customValues)
|
||||
@@ -88,19 +94,35 @@ static void parseStructureCommand(const char* line, FFlist* customValues)
|
||||
if (customValue->printKey)
|
||||
ffStrbufAppend(&options.moduleArgs.key, &customValue->key);
|
||||
ffStrbufAppend(&options.moduleArgs.outputFormat, &customValue->value);
|
||||
ffPrintCustom(&options);
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
fn((FFModuleBaseInfo*) &options, jsonDoc);
|
||||
else
|
||||
ffPrintCustom(&options);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ffParseModuleCommand(line))
|
||||
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
||||
if(isalpha(line[0]))
|
||||
{
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(line[0]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
if (ffStrEqualsIgnCase(line, baseInfo->name))
|
||||
{
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
fn(baseInfo, jsonDoc);
|
||||
else
|
||||
baseInfo->printModule(baseInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffPrintErrorString(line, 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "<no implementation provided>");
|
||||
}
|
||||
|
||||
void ffPrintCommandOption(FFdata* data)
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
|
||||
|
||||
//Parse the structure and call the modules
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
@@ -109,25 +131,25 @@ void ffPrintCommandOption(FFdata* data)
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
uint64_t ms = 0;
|
||||
if(instance.config.stat)
|
||||
if(instance.config.display.stat)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues);
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonResult, jsonDoc);
|
||||
|
||||
if(instance.config.stat)
|
||||
if(instance.config.display.stat)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
|
||||
if (resultDoc)
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
|
||||
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.pipe)
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
@@ -135,9 +157,28 @@ void ffPrintCommandOption(FFdata* data)
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!instance.config.noBuffer) fflush(stdout);
|
||||
if (!jsonDoc && !instance.config.display.noBuffer) fflush(stdout);
|
||||
#endif
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
//If we don't have a custom structure, use the default one
|
||||
if(data->structure.length == 0)
|
||||
ffStrbufAppendS(&data->structure, FASTFETCH_DATATEXT_STRUCTURE);
|
||||
|
||||
//Parse the structure and call the modules
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < data->structure.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&data->structure, startIndex, ':');
|
||||
data->structure.chars[colonIndex] = '\0';
|
||||
|
||||
parseStructureCommand(data->structure.chars + startIndex, &data->customValues, genJsonConfig, jsonDoc);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ffParseModuleCommand(const char* type);
|
||||
bool ffParseModuleOptions(const char* key, const char* value);
|
||||
void ffPrepareCommandOption(FFdata* data);
|
||||
void ffPrintCommandOption(FFdata* data);
|
||||
|
||||
#endif
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
|
||||
+1
-5
@@ -7,7 +7,7 @@
|
||||
|
||||
static bool loadLibSymbols(FFDBusLibrary* lib)
|
||||
{
|
||||
FF_LIBRARY_LOAD(dbus, &instance.config.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD(dbus, &instance.config.library.libDBus, false, "libdbus-1" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_bus_get, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_new_method_call, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(dbus, lib, dbus_message_iter_init, false)
|
||||
@@ -33,9 +33,6 @@ static const FFDBusLibrary* loadLib(void)
|
||||
static FFDBusLibrary lib;
|
||||
static bool loaded = false;
|
||||
static bool loadSuccess = false;
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
||||
|
||||
ffThreadMutexLock(&mutex);
|
||||
|
||||
if(!loaded)
|
||||
{
|
||||
@@ -43,7 +40,6 @@ static const FFDBusLibrary* loadLib(void)
|
||||
loadSuccess = loadLibSymbols(&lib);
|
||||
}
|
||||
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
return loadSuccess ? &lib : NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+20
-253
@@ -15,8 +15,6 @@
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "modules/modules.h"
|
||||
|
||||
FFinstance instance; // Global singleton
|
||||
|
||||
static void initState(FFstate* state)
|
||||
@@ -32,133 +30,11 @@ static void initState(FFstate* state)
|
||||
|
||||
static void defaultConfig(void)
|
||||
{
|
||||
ffInitLogoOptions(&instance.config.logo);
|
||||
|
||||
ffStrbufInit(&instance.config.colorKeys);
|
||||
ffStrbufInit(&instance.config.colorTitle);
|
||||
instance.config.brightColor = true;
|
||||
ffStrbufInitStatic(&instance.config.keyValueSeparator, ": ");
|
||||
instance.config.processingTimeout = 1000;
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
ffStrbufInit(&instance.config.playerName);
|
||||
ffStrbufInit(&instance.config.osFile);
|
||||
instance.config.dsForceDrm = false;
|
||||
#elif defined(_WIN32)
|
||||
instance.config.wmiTimeout = 5000;
|
||||
#endif
|
||||
|
||||
instance.config.showErrors = false;
|
||||
instance.config.allowSlowOperations = false;
|
||||
instance.config.pipe = !isatty(STDOUT_FILENO);
|
||||
|
||||
#ifdef NDEBUG
|
||||
instance.config.disableLinewrap = !instance.config.pipe;
|
||||
instance.config.hideCursor = !instance.config.pipe;
|
||||
#else
|
||||
instance.config.disableLinewrap = false;
|
||||
instance.config.hideCursor = false;
|
||||
#endif
|
||||
|
||||
instance.config.escapeBedrock = true;
|
||||
instance.config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
|
||||
instance.config.sizeNdigits = 2;
|
||||
instance.config.sizeMaxPrefix = UINT8_MAX;
|
||||
instance.config.temperatureUnit = FF_TEMPERATURE_UNIT_CELSIUS;
|
||||
instance.config.multithreading = true;
|
||||
instance.config.stat = false;
|
||||
instance.config.noBuffer = false;
|
||||
instance.config.keyWidth = 0;
|
||||
|
||||
ffStrbufInitStatic(&instance.config.barCharElapsed, "■");
|
||||
ffStrbufInitStatic(&instance.config.barCharTotal, "-");
|
||||
instance.config.barWidth = 10;
|
||||
instance.config.barBorder = true;
|
||||
instance.config.percentType = 1;
|
||||
instance.config.percentNdigits = 0;
|
||||
|
||||
ffInitBatteryOptions(&instance.config.battery);
|
||||
ffInitBiosOptions(&instance.config.bios);
|
||||
ffInitBluetoothOptions(&instance.config.bluetooth);
|
||||
ffInitBoardOptions(&instance.config.board);
|
||||
ffInitBreakOptions(&instance.config.break_);
|
||||
ffInitBrightnessOptions(&instance.config.brightness);
|
||||
ffInitCPUOptions(&instance.config.cpu);
|
||||
ffInitCPUUsageOptions(&instance.config.cpuUsage);
|
||||
ffInitChassisOptions(&instance.config.chassis);
|
||||
ffInitColorsOptions(&instance.config.colors);
|
||||
ffInitCommandOptions(&instance.config.command);
|
||||
ffInitCursorOptions(&instance.config.cursor);
|
||||
ffInitCustomOptions(&instance.config.custom);
|
||||
ffInitDEOptions(&instance.config.de);
|
||||
ffInitDateTimeOptions(&instance.config.dateTime);
|
||||
ffInitDiskOptions(&instance.config.disk);
|
||||
ffInitDiskIOOptions(&instance.config.diskIo);
|
||||
ffInitDisplayOptions(&instance.config.display);
|
||||
ffInitFontOptions(&instance.config.font);
|
||||
ffInitGPUOptions(&instance.config.gpu);
|
||||
ffInitGamepadOptions(&instance.config.gamepad);
|
||||
ffInitHostOptions(&instance.config.host);
|
||||
ffInitIconsOptions(&instance.config.icons);
|
||||
ffInitKernelOptions(&instance.config.kernel);
|
||||
ffInitLMOptions(&instance.config.lm);
|
||||
ffInitLocalIpOptions(&instance.config.localIP);
|
||||
ffInitLocaleOptions(&instance.config.locale);
|
||||
ffInitMediaOptions(&instance.config.media);
|
||||
ffInitMemoryOptions(&instance.config.memory);
|
||||
ffInitMonitorOptions(&instance.config.monitor);
|
||||
ffInitNetIOOptions(&instance.config.netIo);
|
||||
ffInitOSOptions(&instance.config.os);
|
||||
ffInitOpenCLOptions(&instance.config.openCL);
|
||||
ffInitOpenGLOptions(&instance.config.openGL);
|
||||
ffInitPackagesOptions(&instance.config.packages);
|
||||
ffInitPlayerOptions(&instance.config.player);
|
||||
ffInitPowerAdapterOptions(&instance.config.powerAdapter);
|
||||
ffInitProcessesOptions(&instance.config.processes);
|
||||
ffInitPublicIpOptions(&instance.config.publicIP);
|
||||
ffInitSeparatorOptions(&instance.config.separator);
|
||||
ffInitShellOptions(&instance.config.shell);
|
||||
ffInitSoundOptions(&instance.config.sound);
|
||||
ffInitSwapOptions(&instance.config.swap);
|
||||
ffInitTerminalFontOptions(&instance.config.terminalFont);
|
||||
ffInitTerminalOptions(&instance.config.terminal);
|
||||
ffInitTerminalSizeOptions(&instance.config.terminalSize);
|
||||
ffInitThemeOptions(&instance.config.theme);
|
||||
ffInitTitleOptions(&instance.config.title);
|
||||
ffInitUptimeOptions(&instance.config.uptime);
|
||||
ffInitUsersOptions(&instance.config.users);
|
||||
ffInitVersionOptions(&instance.config.version);
|
||||
ffInitVulkanOptions(&instance.config.vulkan);
|
||||
ffInitWMOptions(&instance.config.wm);
|
||||
ffInitWMThemeOptions(&instance.config.wmTheme);
|
||||
ffInitWallpaperOptions(&instance.config.wallpaper);
|
||||
ffInitWeatherOptions(&instance.config.weather);
|
||||
ffInitWifiOptions(&instance.config.wifi);
|
||||
|
||||
ffStrbufInit(&instance.config.libPCI);
|
||||
ffStrbufInit(&instance.config.libVulkan);
|
||||
ffStrbufInit(&instance.config.libWayland);
|
||||
ffStrbufInit(&instance.config.libXcbRandr);
|
||||
ffStrbufInit(&instance.config.libXcb);
|
||||
ffStrbufInit(&instance.config.libXrandr);
|
||||
ffStrbufInit(&instance.config.libX11);
|
||||
ffStrbufInit(&instance.config.libGIO);
|
||||
ffStrbufInit(&instance.config.libDConf);
|
||||
ffStrbufInit(&instance.config.libDBus);
|
||||
ffStrbufInit(&instance.config.libXFConf);
|
||||
ffStrbufInit(&instance.config.libSQLite3);
|
||||
ffStrbufInit(&instance.config.librpm);
|
||||
ffStrbufInit(&instance.config.libImageMagick);
|
||||
ffStrbufInit(&instance.config.libZ);
|
||||
ffStrbufInit(&instance.config.libChafa);
|
||||
ffStrbufInit(&instance.config.libEGL);
|
||||
ffStrbufInit(&instance.config.libGLX);
|
||||
ffStrbufInit(&instance.config.libOSMesa);
|
||||
ffStrbufInit(&instance.config.libOpenCL);
|
||||
ffStrbufInit(&instance.config.libfreetype);
|
||||
ffStrbufInit(&instance.config.libPulse);
|
||||
ffStrbufInit(&instance.config.libnm);
|
||||
ffStrbufInit(&instance.config.libDdcutil);
|
||||
ffOptionsInitLogo(&instance.config.logo);
|
||||
ffOptionsInitGeneral(&instance.config.general);
|
||||
ffOptionsInitModules(&instance.config.modules);
|
||||
ffOptionsInitDisplay(&instance.config.display);
|
||||
ffOptionsInitLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
void ffInitInstance(void)
|
||||
@@ -175,29 +51,6 @@ void ffInitInstance(void)
|
||||
defaultConfig();
|
||||
}
|
||||
|
||||
#if defined(FF_HAVE_THREADS) && !(defined(__APPLE__) || defined(_WIN32) || defined(__ANDROID__))
|
||||
|
||||
#include "detection/gtk_qt/gtk_qt.h"
|
||||
|
||||
#define FF_START_DETECTION_THREADS
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffConnectDisplayServer)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectQt)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK2)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK3)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(ffDetectGTK4)
|
||||
|
||||
void startDetectionThreads(void)
|
||||
{
|
||||
ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, NULL));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, NULL));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, NULL));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, NULL));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, NULL));
|
||||
}
|
||||
|
||||
#endif //FF_HAVE_THREADS
|
||||
|
||||
static volatile bool ffDisableLinewrap = true;
|
||||
static volatile bool ffHideCursor = true;
|
||||
|
||||
@@ -233,15 +86,15 @@ static void exitSignalHandler(int signal)
|
||||
void ffStart(void)
|
||||
{
|
||||
#ifdef FF_START_DETECTION_THREADS
|
||||
if(instance.config.multithreading)
|
||||
if(instance.config.general.multithreading)
|
||||
startDetectionThreads();
|
||||
#endif
|
||||
|
||||
ffDisableLinewrap = instance.config.disableLinewrap && !instance.config.pipe && !instance.state.resultDoc;
|
||||
ffHideCursor = instance.config.hideCursor && !instance.config.pipe && !instance.state.resultDoc;
|
||||
ffDisableLinewrap = instance.config.display.disableLinewrap && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||
|
||||
#ifdef _WIN32
|
||||
setvbuf(stdout, NULL, _IOFBF, instance.config.noBuffer ? 0 : 4096);
|
||||
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
|
||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
@@ -249,7 +102,7 @@ void ffStart(void)
|
||||
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#else
|
||||
if (instance.config.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
|
||||
if (instance.config.display.noBuffer) setvbuf(stdout, NULL, _IONBF, 0);
|
||||
struct sigaction action = { .sa_handler = exitSignalHandler };
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
@@ -257,7 +110,7 @@ void ffStart(void)
|
||||
#endif
|
||||
|
||||
//reset everything to default before we start printing
|
||||
if(!instance.config.pipe && !instance.state.resultDoc)
|
||||
if(!instance.config.display.pipe && !instance.state.resultDoc)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
if(ffHideCursor)
|
||||
@@ -279,101 +132,11 @@ void ffFinish(void)
|
||||
|
||||
static void destroyConfig(void)
|
||||
{
|
||||
ffDestroyLogoOptions(&instance.config.logo);
|
||||
|
||||
ffStrbufDestroy(&instance.config.colorKeys);
|
||||
ffStrbufDestroy(&instance.config.colorTitle);
|
||||
ffStrbufDestroy(&instance.config.keyValueSeparator);
|
||||
ffStrbufDestroy(&instance.config.barCharElapsed);
|
||||
ffStrbufDestroy(&instance.config.barCharTotal);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
ffStrbufDestroy(&instance.config.playerName);
|
||||
ffStrbufDestroy(&instance.config.osFile);
|
||||
#endif
|
||||
|
||||
ffDestroyBatteryOptions(&instance.config.battery);
|
||||
ffDestroyBiosOptions(&instance.config.bios);
|
||||
ffDestroyBluetoothOptions(&instance.config.bluetooth);
|
||||
ffDestroyBoardOptions(&instance.config.board);
|
||||
ffDestroyBreakOptions(&instance.config.break_);
|
||||
ffDestroyBrightnessOptions(&instance.config.brightness);
|
||||
ffDestroyCPUOptions(&instance.config.cpu);
|
||||
ffDestroyCPUUsageOptions(&instance.config.cpuUsage);
|
||||
ffDestroyChassisOptions(&instance.config.chassis);
|
||||
ffDestroyColorsOptions(&instance.config.colors);
|
||||
ffDestroyCommandOptions(&instance.config.command);
|
||||
ffDestroyCursorOptions(&instance.config.cursor);
|
||||
ffDestroyCustomOptions(&instance.config.custom);
|
||||
ffDestroyDEOptions(&instance.config.de);
|
||||
ffDestroyDateTimeOptions(&instance.config.dateTime);
|
||||
ffDestroyDiskOptions(&instance.config.disk);
|
||||
ffDestroyDiskIOOptions(&instance.config.diskIo);
|
||||
ffDestroyDisplayOptions(&instance.config.display);
|
||||
ffDestroyFontOptions(&instance.config.font);
|
||||
ffDestroyGPUOptions(&instance.config.gpu);
|
||||
ffDestroyGamepadOptions(&instance.config.gamepad);
|
||||
ffDestroyHostOptions(&instance.config.host);
|
||||
ffDestroyIconsOptions(&instance.config.icons);
|
||||
ffDestroyKernelOptions(&instance.config.kernel);
|
||||
ffDestroyLMOptions(&instance.config.lm);
|
||||
ffDestroyLocalIpOptions(&instance.config.localIP);
|
||||
ffDestroyLocaleOptions(&instance.config.locale);
|
||||
ffDestroyMediaOptions(&instance.config.media);
|
||||
ffDestroyMemoryOptions(&instance.config.memory);
|
||||
ffDestroyMonitorOptions(&instance.config.monitor);
|
||||
ffDestroyNetIOOptions(&instance.config.netIo);
|
||||
ffDestroyOSOptions(&instance.config.os);
|
||||
ffDestroyOpenCLOptions(&instance.config.openCL);
|
||||
ffDestroyOpenGLOptions(&instance.config.openGL);
|
||||
ffDestroyPackagesOptions(&instance.config.packages);
|
||||
ffDestroyPlayerOptions(&instance.config.player);
|
||||
ffDestroyPowerAdapterOptions(&instance.config.powerAdapter);
|
||||
ffDestroyProcessesOptions(&instance.config.processes);
|
||||
ffDestroyPublicIpOptions(&instance.config.publicIP);
|
||||
ffDestroySeparatorOptions(&instance.config.separator);
|
||||
ffDestroyShellOptions(&instance.config.shell);
|
||||
ffDestroySoundOptions(&instance.config.sound);
|
||||
ffDestroySwapOptions(&instance.config.swap);
|
||||
ffDestroyTerminalFontOptions(&instance.config.terminalFont);
|
||||
ffDestroyTerminalOptions(&instance.config.terminal);
|
||||
ffDestroyTerminalSizeOptions(&instance.config.terminalSize);
|
||||
ffDestroyThemeOptions(&instance.config.theme);
|
||||
ffDestroyTitleOptions(&instance.config.title);
|
||||
ffDestroyUptimeOptions(&instance.config.uptime);
|
||||
ffDestroyUsersOptions(&instance.config.users);
|
||||
ffDestroyVersionOptions(&instance.config.version);
|
||||
ffDestroyVulkanOptions(&instance.config.vulkan);
|
||||
ffDestroyWMOptions(&instance.config.wm);
|
||||
ffDestroyWMThemeOptions(&instance.config.wmTheme);
|
||||
ffDestroyWallpaperOptions(&instance.config.wallpaper);
|
||||
ffDestroyWeatherOptions(&instance.config.weather);
|
||||
ffDestroyWifiOptions(&instance.config.wifi);
|
||||
|
||||
ffStrbufDestroy(&instance.config.libPCI);
|
||||
ffStrbufDestroy(&instance.config.libVulkan);
|
||||
ffStrbufDestroy(&instance.config.libWayland);
|
||||
ffStrbufDestroy(&instance.config.libXcbRandr);
|
||||
ffStrbufDestroy(&instance.config.libXcb);
|
||||
ffStrbufDestroy(&instance.config.libXrandr);
|
||||
ffStrbufDestroy(&instance.config.libX11);
|
||||
ffStrbufDestroy(&instance.config.libGIO);
|
||||
ffStrbufDestroy(&instance.config.libDConf);
|
||||
ffStrbufDestroy(&instance.config.libDBus);
|
||||
ffStrbufDestroy(&instance.config.libXFConf);
|
||||
ffStrbufDestroy(&instance.config.libSQLite3);
|
||||
ffStrbufDestroy(&instance.config.librpm);
|
||||
ffStrbufDestroy(&instance.config.libImageMagick);
|
||||
ffStrbufDestroy(&instance.config.libZ);
|
||||
ffStrbufDestroy(&instance.config.libChafa);
|
||||
ffStrbufDestroy(&instance.config.libEGL);
|
||||
ffStrbufDestroy(&instance.config.libGLX);
|
||||
ffStrbufDestroy(&instance.config.libOSMesa);
|
||||
ffStrbufDestroy(&instance.config.libOpenCL);
|
||||
ffStrbufDestroy(&instance.config.libfreetype);
|
||||
ffStrbufDestroy(&instance.config.libPulse);
|
||||
ffStrbufDestroy(&instance.config.libnm);
|
||||
ffStrbufDestroy(&instance.config.libDdcutil);
|
||||
ffOptionsDestroyLogo(&instance.config.logo);
|
||||
ffOptionsDestroyGeneral(&instance.config.general);
|
||||
ffOptionsDestroyModules(&instance.config.modules);
|
||||
ffOptionsDestroyDisplay(&instance.config.display);
|
||||
ffOptionsDestroyLibrary(&instance.config.library);
|
||||
}
|
||||
|
||||
static void destroyState(void)
|
||||
@@ -381,6 +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.genConfigPath);
|
||||
}
|
||||
|
||||
void ffDestroyInstance(void)
|
||||
@@ -417,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, ...)
|
||||
|
||||
+48
-295
@@ -35,6 +35,18 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs)
|
||||
{
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->key, &moduleArgs->key))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "key", &moduleArgs->key);
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->outputFormat, &moduleArgs->outputFormat))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "format", &moduleArgs->outputFormat);
|
||||
if (!ffStrbufEqual(&defaultModuleArgs->keyColor, &moduleArgs->keyColor))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
|
||||
if (moduleArgs->keyWidth != defaultModuleArgs->keyWidth)
|
||||
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
|
||||
}
|
||||
|
||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
|
||||
{
|
||||
if (yyjson_is_int(val))
|
||||
@@ -70,21 +82,17 @@ const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair p
|
||||
return "Invalid enum value type; must be a string or integer";
|
||||
}
|
||||
|
||||
static inline yyjson_mut_val* genJson(FFModuleBaseInfo* baseInfo)
|
||||
static inline void genJsonResult(FFModuleBaseInfo* baseInfo, yyjson_mut_doc* doc)
|
||||
{
|
||||
yyjson_mut_doc* doc = instance.state.resultDoc;
|
||||
if (__builtin_expect(!doc, true)) return NULL;
|
||||
|
||||
yyjson_mut_val* module = yyjson_mut_arr_add_obj(doc, doc->root);
|
||||
yyjson_mut_obj_add_str(doc, module, "type", baseInfo->name);
|
||||
if (baseInfo->generateJson)
|
||||
baseInfo->generateJson(baseInfo, doc, module);
|
||||
if (baseInfo->generateJsonResult)
|
||||
baseInfo->generateJsonResult(baseInfo, doc, module);
|
||||
else
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Unsupported for JSON format");
|
||||
return module;
|
||||
}
|
||||
|
||||
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
|
||||
static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
if(!isalpha(type[0])) return false;
|
||||
|
||||
@@ -94,7 +102,9 @@ static bool parseModuleJsonObject(const char* type, yyjson_val* jsonVal)
|
||||
if (ffStrEqualsIgnCase(type, baseInfo->name))
|
||||
{
|
||||
if (jsonVal) baseInfo->parseJsonObject(baseInfo, jsonVal);
|
||||
if (!genJson(baseInfo))
|
||||
if (__builtin_expect(jsonDoc != NULL, false))
|
||||
genJsonResult(baseInfo, jsonDoc);
|
||||
else
|
||||
baseInfo->printModule(baseInfo);
|
||||
return true;
|
||||
}
|
||||
@@ -115,39 +125,39 @@ static void prepareModuleJsonObject(const char* type, yyjson_val* module)
|
||||
case 'd': case 'D': {
|
||||
if (ffStrEqualsIgnCase(type, FF_DISKIO_MODULE_NAME))
|
||||
{
|
||||
if (module) ffParseDiskIOJsonObject(&cfg->diskIo, module);
|
||||
ffPrepareDiskIO(&cfg->diskIo);
|
||||
if (module) cfg->modules.diskIo.moduleInfo.parseJsonObject(&cfg->modules.diskIo, module);
|
||||
ffPrepareDiskIO(&cfg->modules.diskIo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'n': case 'N': {
|
||||
if (ffStrEqualsIgnCase(type, FF_NETIO_MODULE_NAME))
|
||||
{
|
||||
if (module) ffParseNetIOJsonObject(&cfg->netIo, module);
|
||||
ffPrepareNetIO(&cfg->netIo);
|
||||
if (module) cfg->modules.netIo.moduleInfo.parseJsonObject(&cfg->modules.netIo, module);
|
||||
ffPrepareNetIO(&cfg->modules.netIo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'p': case 'P': {
|
||||
if (ffStrEqualsIgnCase(type, FF_PUBLICIP_MODULE_NAME))
|
||||
{
|
||||
if (module) ffParsePublicIpJsonObject(&cfg->publicIP, module);
|
||||
ffPreparePublicIp(&cfg->publicIP);
|
||||
if (module) cfg->modules.publicIP.moduleInfo.parseJsonObject(&cfg->modules.publicIP, module);
|
||||
ffPreparePublicIp(&cfg->modules.publicIP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'w': case 'W': {
|
||||
if (ffStrEqualsIgnCase(type, FF_WEATHER_MODULE_NAME))
|
||||
{
|
||||
if (module) ffParseWeatherJsonObject(&cfg->weather, module);
|
||||
ffPrepareWeather(&cfg->weather);
|
||||
if (module) cfg->modules.weather.moduleInfo.parseJsonObject(&cfg->modules.weather, module);
|
||||
ffPrepareWeather(&cfg->modules.weather);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char* printJsonConfig(bool prepare)
|
||||
static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||
assert(root);
|
||||
@@ -159,14 +169,12 @@ static const char* printJsonConfig(bool prepare)
|
||||
if (!modules) return NULL;
|
||||
if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects";
|
||||
|
||||
yyjson_mut_doc* resultDoc = instance.state.resultDoc;
|
||||
|
||||
yyjson_val* item;
|
||||
size_t idx, max;
|
||||
yyjson_arr_foreach(modules, idx, max, item)
|
||||
{
|
||||
uint64_t ms = 0;
|
||||
if(!prepare && instance.config.stat)
|
||||
if(!prepare && instance.config.display.stat)
|
||||
ms = ffTimeGetTick();
|
||||
|
||||
yyjson_val* module = item;
|
||||
@@ -185,22 +193,22 @@ static const char* printJsonConfig(bool prepare)
|
||||
|
||||
if(prepare)
|
||||
prepareModuleJsonObject(type, module);
|
||||
else if(!parseModuleJsonObject(type, module))
|
||||
else if(!parseModuleJsonObject(type, module, jsonDoc))
|
||||
return "Unknown module type";
|
||||
|
||||
if(!prepare && instance.config.stat)
|
||||
if(!prepare && instance.config.display.stat)
|
||||
{
|
||||
ms = ffTimeGetTick() - ms;
|
||||
if (resultDoc)
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(resultDoc->root);
|
||||
yyjson_mut_obj_add_uint(resultDoc, moduleJson, "stat", ms);
|
||||
yyjson_mut_val* moduleJson = yyjson_mut_arr_get_last(jsonDoc->root);
|
||||
yyjson_mut_obj_add_uint(jsonDoc, moduleJson, "stat", ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.pipe)
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
@@ -208,280 +216,25 @@ static const char* printJsonConfig(bool prepare)
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!instance.config.noBuffer && !resultDoc) fflush(stdout);
|
||||
if (!instance.config.display.noBuffer && !jsonDoc) fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffParseGeneralJsonConfig(void)
|
||||
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
FFconfig* config = &instance.config;
|
||||
|
||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||
assert(root);
|
||||
|
||||
if (!yyjson_is_obj(root))
|
||||
return "Invalid JSON config format. Root value must be an object";
|
||||
|
||||
yyjson_val* object = yyjson_obj_get(root, "general");
|
||||
if (!object) return NULL;
|
||||
if (!yyjson_is_obj(object)) return "Property 'general' must be an object";
|
||||
|
||||
yyjson_val *key_, *val;
|
||||
size_t idx, max;
|
||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
||||
{
|
||||
const char* key = yyjson_get_str(key_);
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "allowSlowOperations"))
|
||||
config->allowSlowOperations = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "thread") || ffStrEqualsIgnCase(key, "multithreading"))
|
||||
config->multithreading = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "stat"))
|
||||
{
|
||||
if ((config->stat = yyjson_get_bool(val)))
|
||||
config->showErrors = true;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "escapeBedrock"))
|
||||
config->escapeBedrock = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "pipe"))
|
||||
config->pipe = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "processingTimeout"))
|
||||
config->processingTimeout = (int32_t) yyjson_get_int(val);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
else if (ffStrEqualsIgnCase(key, "playerName"))
|
||||
ffStrbufSetS(&config->playerName, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "osFile"))
|
||||
ffStrbufSetS(&config->osFile, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
|
||||
config->dsForceDrm = yyjson_get_bool(val);
|
||||
#elif defined(_WIN32)
|
||||
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
|
||||
config->wmiTimeout = (int32_t) yyjson_get_int(val);
|
||||
#endif
|
||||
|
||||
else
|
||||
return "Unknown general property";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffParseDisplayJsonConfig(void)
|
||||
{
|
||||
FFconfig* config = &instance.config;
|
||||
|
||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||
assert(root);
|
||||
|
||||
if (!yyjson_is_obj(root))
|
||||
return "Invalid JSON config format. Root value must be an object";
|
||||
|
||||
yyjson_val* object = yyjson_obj_get(root, "display");
|
||||
if (!object) return NULL;
|
||||
if (!yyjson_is_obj(object)) return "Property 'display' must be an object";
|
||||
|
||||
yyjson_val *key_, *val;
|
||||
size_t idx, max;
|
||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
||||
{
|
||||
const char* key = yyjson_get_str(key_);
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "showErrors"))
|
||||
config->showErrors = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "disableLinewrap"))
|
||||
config->disableLinewrap = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "hideCursor"))
|
||||
config->hideCursor = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "separator"))
|
||||
ffStrbufSetS(&config->keyValueSeparator, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "color"))
|
||||
{
|
||||
if (yyjson_is_str(val))
|
||||
{
|
||||
ffOptionParseColor(yyjson_get_str(val), &config->colorKeys);
|
||||
ffStrbufSet(&config->colorTitle, &config->colorKeys);
|
||||
}
|
||||
else if (yyjson_is_obj(val))
|
||||
{
|
||||
const char* colorKeys = yyjson_get_str(yyjson_obj_get(val, "keys"));
|
||||
if (colorKeys)
|
||||
ffOptionParseColor(colorKeys, &config->colorKeys);
|
||||
const char* colorTitle = yyjson_get_str(yyjson_obj_get(val, "title"));
|
||||
if (colorTitle)
|
||||
ffOptionParseColor(colorTitle, &config->colorTitle);
|
||||
}
|
||||
else
|
||||
return "display.color must be either a string or an object";
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "brightColor"))
|
||||
config->brightColor = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "binaryPrefix"))
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "iec", FF_BINARY_PREFIX_TYPE_IEC },
|
||||
{ "si", FF_BINARY_PREFIX_TYPE_SI },
|
||||
{ "jedec", FF_BINARY_PREFIX_TYPE_JEDEC },
|
||||
{},
|
||||
});
|
||||
if (error) return error;
|
||||
config->binaryPrefixType = (FFBinaryPrefixType) value;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "sizeNdigits"))
|
||||
config->sizeNdigits = (uint8_t) yyjson_get_uint(val);
|
||||
else if (ffStrEqualsIgnCase(key, "sizeMaxPrefix"))
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "B", 0 },
|
||||
{ "kB", 1 },
|
||||
{ "MB", 2 },
|
||||
{ "GB", 3 },
|
||||
{ "TB", 4 },
|
||||
{ "PB", 5 },
|
||||
{ "EB", 6 },
|
||||
{ "ZB", 7 },
|
||||
{ "YB", 8 },
|
||||
{}
|
||||
});
|
||||
if (error) return error;
|
||||
config->sizeMaxPrefix = (uint8_t) value;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "temperatureUnit"))
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "CELSIUS", FF_TEMPERATURE_UNIT_CELSIUS },
|
||||
{ "C", FF_TEMPERATURE_UNIT_CELSIUS },
|
||||
{ "FAHRENHEIT", FF_TEMPERATURE_UNIT_FAHRENHEIT },
|
||||
{ "F", FF_TEMPERATURE_UNIT_FAHRENHEIT },
|
||||
{ "KELVIN", FF_TEMPERATURE_UNIT_KELVIN },
|
||||
{ "K", FF_TEMPERATURE_UNIT_KELVIN },
|
||||
{},
|
||||
});
|
||||
if (error) return error;
|
||||
config->temperatureUnit = (FFTemperatureUnit) value;
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "percentType"))
|
||||
config->percentType = (uint8_t) yyjson_get_uint(val);
|
||||
else if (ffStrEqualsIgnCase(key, "percentNdigits"))
|
||||
config->percentNdigits = (uint8_t) yyjson_get_uint(val);
|
||||
else if (ffStrEqualsIgnCase(key, "bar"))
|
||||
{
|
||||
if (yyjson_is_obj(val))
|
||||
{
|
||||
const char* charElapsed = yyjson_get_str(yyjson_obj_get(val, "charElapsed"));
|
||||
if (charElapsed)
|
||||
ffStrbufSetS(&config->barCharElapsed, charElapsed);
|
||||
|
||||
const char* charTotal = yyjson_get_str(yyjson_obj_get(val, "charTotal"));
|
||||
if (charTotal)
|
||||
ffStrbufSetS(&config->barCharTotal, charTotal);
|
||||
|
||||
yyjson_val* border = yyjson_obj_get(val, "border");
|
||||
if (border)
|
||||
config->barBorder = yyjson_get_bool(border);
|
||||
|
||||
yyjson_val* width = yyjson_obj_get(val, "width");
|
||||
if (width)
|
||||
config->barWidth = (uint8_t) yyjson_get_uint(width);
|
||||
}
|
||||
else
|
||||
return "display.bar must be an object";
|
||||
}
|
||||
else if (ffStrEqualsIgnCase(key, "noBuffer"))
|
||||
config->noBuffer = yyjson_get_bool(val);
|
||||
else if (ffStrEqualsIgnCase(key, "keyWidth"))
|
||||
config->keyWidth = (uint32_t) yyjson_get_uint(val);
|
||||
else
|
||||
return "Unknown display property";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* ffParseLibraryJsonConfig(void)
|
||||
{
|
||||
FFconfig* config = &instance.config;
|
||||
|
||||
yyjson_val* const root = yyjson_doc_get_root(instance.state.configDoc);
|
||||
assert(root);
|
||||
|
||||
if (!yyjson_is_obj(root))
|
||||
return "Invalid JSON config format. Root value must be an object";
|
||||
|
||||
yyjson_val* object = yyjson_obj_get(root, "library");
|
||||
if (!object) return NULL;
|
||||
if (!yyjson_is_obj(object)) return "Property 'library' must be an object";
|
||||
|
||||
yyjson_val *key_, *val;
|
||||
size_t idx, max;
|
||||
yyjson_obj_foreach(object, idx, max, key_, val)
|
||||
{
|
||||
const char* key = yyjson_get_str(key_);
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "pci"))
|
||||
ffStrbufSetS(&config->libPCI, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "vulkan"))
|
||||
ffStrbufSetS(&config->libVulkan, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "freetype"))
|
||||
ffStrbufSetS(&config->libfreetype, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "wayland"))
|
||||
ffStrbufSetS(&config->libWayland, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "xcbRandr"))
|
||||
ffStrbufSetS(&config->libXcbRandr, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "xcb"))
|
||||
ffStrbufSetS(&config->libXcb, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "Xrandr"))
|
||||
ffStrbufSetS(&config->libXrandr, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "X11"))
|
||||
ffStrbufSetS(&config->libX11, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "gio"))
|
||||
ffStrbufSetS(&config->libGIO, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "DConf"))
|
||||
ffStrbufSetS(&config->libDConf, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "dbus"))
|
||||
ffStrbufSetS(&config->libDBus, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "XFConf"))
|
||||
ffStrbufSetS(&config->libXFConf, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "sqlite") || ffStrEqualsIgnCase(key, "sqlite3"))
|
||||
ffStrbufSetS(&config->libSQLite3, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "rpm"))
|
||||
ffStrbufSetS(&config->librpm, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "imagemagick"))
|
||||
ffStrbufSetS(&config->libImageMagick, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "z"))
|
||||
ffStrbufSetS(&config->libZ, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "chafa"))
|
||||
ffStrbufSetS(&config->libChafa, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "egl"))
|
||||
ffStrbufSetS(&config->libEGL, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "glx"))
|
||||
ffStrbufSetS(&config->libGLX, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "osmesa"))
|
||||
ffStrbufSetS(&config->libOSMesa, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "opencl"))
|
||||
ffStrbufSetS(&config->libOpenCL, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "pulse"))
|
||||
ffStrbufSetS(&config->libPulse, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "nm"))
|
||||
ffStrbufSetS(&config->libnm, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "ddcutil"))
|
||||
ffStrbufSetS(&config->libDdcutil, yyjson_get_str(val));
|
||||
else
|
||||
return "Unknown library property";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffPrintJsonConfig(bool prepare)
|
||||
{
|
||||
const char* error = printJsonConfig(prepare);
|
||||
const char* error = printJsonConfig(prepare, jsonDoc);
|
||||
if (error)
|
||||
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||
{
|
||||
if (jsonDoc)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_obj(jsonDoc);
|
||||
yyjson_mut_obj_add_str(jsonDoc, obj, "error", error);
|
||||
yyjson_mut_doc_set_root(jsonDoc, obj);
|
||||
}
|
||||
else
|
||||
ffPrintErrorString("JsonConfig", 0, NULL, FF_PRINT_TYPE_NO_CUSTOM_KEY, "%s", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs* moduleArgs);
|
||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]);
|
||||
void ffPrintJsonConfig(bool prepare);
|
||||
const char* ffParseGeneralJsonConfig(void);
|
||||
const char* ffParseDisplayJsonConfig(void);
|
||||
const char* ffParseLibraryJsonConfig(void);
|
||||
void ffPrintJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc);
|
||||
void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* module, FFModuleArgs* defaultModuleArgs, FFModuleArgs* moduleArgs);
|
||||
|
||||
yyjson_api_inline yyjson_mut_val* yyjson_mut_strbuf(yyjson_mut_doc *doc, const FFstrbuf* buf) {
|
||||
return yyjson_mut_strncpy(doc, buf->chars, buf->length);
|
||||
}
|
||||
|
||||
yyjson_api_inline bool yyjson_mut_obj_add_strbuf(yyjson_mut_doc *doc,
|
||||
yyjson_mut_val *obj,
|
||||
|
||||
@@ -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
|
||||
|
||||
+57
-57
@@ -5,32 +5,32 @@ static FFModuleBaseInfo* A[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* B[] = {
|
||||
(void*) &instance.config.battery,
|
||||
(void*) &instance.config.bios,
|
||||
(void*) &instance.config.bluetooth,
|
||||
(void*) &instance.config.board,
|
||||
(void*) &instance.config.break_,
|
||||
(void*) &instance.config.brightness,
|
||||
(void*) &instance.config.modules.battery,
|
||||
(void*) &instance.config.modules.bios,
|
||||
(void*) &instance.config.modules.bluetooth,
|
||||
(void*) &instance.config.modules.board,
|
||||
(void*) &instance.config.modules.break_,
|
||||
(void*) &instance.config.modules.brightness,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* C[] = {
|
||||
(void*) &instance.config.chassis,
|
||||
(void*) &instance.config.command,
|
||||
(void*) &instance.config.colors,
|
||||
(void*) &instance.config.cpu,
|
||||
(void*) &instance.config.cpuUsage,
|
||||
(void*) &instance.config.cursor,
|
||||
(void*) &instance.config.custom,
|
||||
(void*) &instance.config.modules.chassis,
|
||||
(void*) &instance.config.modules.command,
|
||||
(void*) &instance.config.modules.colors,
|
||||
(void*) &instance.config.modules.cpu,
|
||||
(void*) &instance.config.modules.cpuUsage,
|
||||
(void*) &instance.config.modules.cursor,
|
||||
(void*) &instance.config.modules.custom,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* D[] = {
|
||||
(void*) &instance.config.dateTime,
|
||||
(void*) &instance.config.de,
|
||||
(void*) &instance.config.display,
|
||||
(void*) &instance.config.disk,
|
||||
(void*) &instance.config.diskIo,
|
||||
(void*) &instance.config.modules.dateTime,
|
||||
(void*) &instance.config.modules.de,
|
||||
(void*) &instance.config.modules.display,
|
||||
(void*) &instance.config.modules.disk,
|
||||
(void*) &instance.config.modules.diskIo,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -39,23 +39,23 @@ static FFModuleBaseInfo* E[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* F[] = {
|
||||
(void*) &instance.config.font,
|
||||
(void*) &instance.config.modules.font,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* G[] = {
|
||||
(void*) &instance.config.gamepad,
|
||||
(void*) &instance.config.gpu,
|
||||
(void*) &instance.config.modules.gamepad,
|
||||
(void*) &instance.config.modules.gpu,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* H[] = {
|
||||
(void*) &instance.config.host,
|
||||
(void*) &instance.config.modules.host,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* I[] = {
|
||||
(void*) &instance.config.icons,
|
||||
(void*) &instance.config.modules.icons,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -64,42 +64,42 @@ static FFModuleBaseInfo* J[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* K[] = {
|
||||
(void*) &instance.config.kernel,
|
||||
(void*) &instance.config.modules.kernel,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* L[] = {
|
||||
(void*) &instance.config.lm,
|
||||
(void*) &instance.config.locale,
|
||||
(void*) &instance.config.localIP,
|
||||
(void*) &instance.config.modules.lm,
|
||||
(void*) &instance.config.modules.locale,
|
||||
(void*) &instance.config.modules.localIP,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* M[] = {
|
||||
(void*) &instance.config.media,
|
||||
(void*) &instance.config.memory,
|
||||
(void*) &instance.config.monitor,
|
||||
(void*) &instance.config.modules.media,
|
||||
(void*) &instance.config.modules.memory,
|
||||
(void*) &instance.config.modules.monitor,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* N[] = {
|
||||
(void*) &instance.config.netIo,
|
||||
(void*) &instance.config.modules.netIo,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* O[] = {
|
||||
(void*) &instance.config.openCL,
|
||||
(void*) &instance.config.openGL,
|
||||
(void*) &instance.config.os,
|
||||
(void*) &instance.config.modules.openCL,
|
||||
(void*) &instance.config.modules.openGL,
|
||||
(void*) &instance.config.modules.os,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* P[] = {
|
||||
(void*) &instance.config.packages,
|
||||
(void*) &instance.config.player,
|
||||
(void*) &instance.config.powerAdapter,
|
||||
(void*) &instance.config.processes,
|
||||
(void*) &instance.config.publicIP,
|
||||
(void*) &instance.config.modules.packages,
|
||||
(void*) &instance.config.modules.player,
|
||||
(void*) &instance.config.modules.powerAdapter,
|
||||
(void*) &instance.config.modules.processes,
|
||||
(void*) &instance.config.modules.publicIP,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -112,40 +112,40 @@ static FFModuleBaseInfo* R[] = {
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* S[] = {
|
||||
(void*) &instance.config.separator,
|
||||
(void*) &instance.config.shell,
|
||||
(void*) &instance.config.sound,
|
||||
(void*) &instance.config.swap,
|
||||
(void*) &instance.config.modules.separator,
|
||||
(void*) &instance.config.modules.shell,
|
||||
(void*) &instance.config.modules.sound,
|
||||
(void*) &instance.config.modules.swap,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* T[] = {
|
||||
(void*) &instance.config.terminal,
|
||||
(void*) &instance.config.terminalFont,
|
||||
(void*) &instance.config.terminalSize,
|
||||
(void*) &instance.config.title,
|
||||
(void*) &instance.config.theme,
|
||||
(void*) &instance.config.modules.terminal,
|
||||
(void*) &instance.config.modules.terminalFont,
|
||||
(void*) &instance.config.modules.terminalSize,
|
||||
(void*) &instance.config.modules.title,
|
||||
(void*) &instance.config.modules.theme,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* U[] = {
|
||||
(void*) &instance.config.uptime,
|
||||
(void*) &instance.config.users,
|
||||
(void*) &instance.config.modules.uptime,
|
||||
(void*) &instance.config.modules.users,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* V[] = {
|
||||
(void*) &instance.config.version,
|
||||
(void*) &instance.config.vulkan,
|
||||
(void*) &instance.config.modules.version,
|
||||
(void*) &instance.config.modules.vulkan,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static FFModuleBaseInfo* W[] = {
|
||||
(void*) &instance.config.wallpaper,
|
||||
(void*) &instance.config.weather,
|
||||
(void*) &instance.config.wm,
|
||||
(void*) &instance.config.wifi,
|
||||
(void*) &instance.config.wmTheme,
|
||||
(void*) &instance.config.modules.wallpaper,
|
||||
(void*) &instance.config.modules.weather,
|
||||
(void*) &instance.config.modules.wm,
|
||||
(void*) &instance.config.modules.wifi,
|
||||
(void*) &instance.config.modules.wmTheme,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
-4
@@ -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
|
||||
@@ -17,26 +18,31 @@ typedef struct FFModuleBaseInfo
|
||||
bool (*parseCommandOptions)(void* options, const char* key, const char* value);
|
||||
void (*parseJsonObject)(void* options, struct yyjson_val *module);
|
||||
void (*printModule)(void* options);
|
||||
void (*generateJson)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
||||
void (*generateJsonResult)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* module);
|
||||
void (*printHelpFormat)(void);
|
||||
void (*generateJsonConfig)(void* options, struct yyjson_mut_doc* doc, struct yyjson_mut_val* obj);
|
||||
} 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)
|
||||
void* generateJson, // void (*const generateJson)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
void (*printHelpFormat)(void)
|
||||
void* generateJsonResult, // void (*const generateJsonResult)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
void (*printHelpFormat)(void),
|
||||
void* generateJsonConfig // void (*const generateJsonConfig)(void* options, yyjson_mut_doc* doc, yyjson_mut_val* obj)
|
||||
)
|
||||
{
|
||||
baseInfo->name = name;
|
||||
baseInfo->description = description;
|
||||
baseInfo->parseCommandOptions = (__typeof__(baseInfo->parseCommandOptions)) parseCommandOptions;
|
||||
baseInfo->parseJsonObject = (__typeof__(baseInfo->parseJsonObject)) parseJsonObject;
|
||||
baseInfo->printModule = (__typeof__(baseInfo->printModule)) printModule;
|
||||
baseInfo->generateJson = (__typeof__(baseInfo->generateJson)) generateJson;
|
||||
baseInfo->generateJsonResult = (__typeof__(baseInfo->generateJsonResult)) generateJsonResult;
|
||||
baseInfo->printHelpFormat = printHelpFormat;
|
||||
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
|
||||
}
|
||||
|
||||
typedef struct FFModuleArgs
|
||||
|
||||
@@ -65,7 +65,7 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
||||
double size = (double) bytes;
|
||||
uint8_t counter = 0;
|
||||
|
||||
while(size >= base && counter < instance.config.sizeMaxPrefix && prefixes[counter + 1])
|
||||
while(size >= base && counter < instance.config.display.sizeMaxPrefix && prefixes[counter + 1])
|
||||
{
|
||||
size /= base;
|
||||
counter++;
|
||||
@@ -74,12 +74,12 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
||||
if(counter == 0)
|
||||
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
|
||||
else
|
||||
ffStrbufAppendF(result, "%.*f %s", instance.config.sizeNdigits, size, prefixes[counter]);
|
||||
ffStrbufAppendF(result, "%.*f %s", instance.config.display.sizeNdigits, size, prefixes[counter]);
|
||||
}
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||
{
|
||||
switch (instance.config.binaryPrefixType)
|
||||
switch (instance.config.display.binaryPrefixType)
|
||||
{
|
||||
case FF_BINARY_PREFIX_TYPE_IEC:
|
||||
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
|
||||
@@ -98,7 +98,7 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
|
||||
|
||||
void ffParseTemperature(double celsius, FFstrbuf* buffer)
|
||||
{
|
||||
switch (instance.config.temperatureUnit)
|
||||
switch (instance.config.display.temperatureUnit)
|
||||
{
|
||||
case FF_TEMPERATURE_UNIT_CELSIUS:
|
||||
ffStrbufAppendF(buffer, "%.1f°C", celsius);
|
||||
|
||||
@@ -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
|
||||
|
||||
+12
-12
@@ -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;
|
||||
|
||||
@@ -14,16 +14,16 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
if(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " "))
|
||||
return;
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
if (instance.config.brightColor)
|
||||
if (instance.config.display.brightColor)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
||||
|
||||
if(moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0)
|
||||
ffPrintColor(&moduleArgs->keyColor);
|
||||
else
|
||||
ffPrintColor(&instance.config.colorKeys);
|
||||
ffPrintColor(&instance.config.display.colorKeys);
|
||||
}
|
||||
|
||||
//NULL check is required for modules with custom keys, e.g. disk with the folder path
|
||||
@@ -43,18 +43,18 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
ffStrbufWriteTo(&key, stdout);
|
||||
}
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
ffStrbufWriteTo(&instance.config.keyValueSeparator, stdout);
|
||||
ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
|
||||
if (!instance.config.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
||||
if (!instance.config.display.pipe && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH))
|
||||
{
|
||||
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.keyWidth;
|
||||
uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
|
||||
if (keyWidth > 0)
|
||||
printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
|
||||
}
|
||||
@@ -77,17 +77,17 @@ void ffPrintFormatString(const char* moduleName, uint8_t moduleIndex, const FFMo
|
||||
|
||||
static void printError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, va_list arguments)
|
||||
{
|
||||
if(!instance.config.showErrors)
|
||||
if(!instance.config.display.showErrors)
|
||||
return;
|
||||
|
||||
ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
|
||||
|
||||
vprintf(message, arguments);
|
||||
|
||||
if(!instance.config.pipe)
|
||||
if(!instance.config.display.pipe)
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
putchar('\n');
|
||||
|
||||
@@ -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,48 +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 | O_CLOEXEC);
|
||||
dup2(pipes[1], useStdErr ? STDERR_FILENO : STDOUT_FILENO);
|
||||
close(pipes[0]);
|
||||
close(pipes[1]);
|
||||
close(useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||
dup2(nullFile, useStdErr ? STDOUT_FILENO : STDERR_FILENO);
|
||||
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.processingTimeout;
|
||||
if (timeout >= 0)
|
||||
fcntl(childPipeFd, F_SETFL, fcntl(childPipeFd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
do
|
||||
while(1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
{
|
||||
@@ -69,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,11 +4,11 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
enum { FF_PIPE_BUFSIZ = 4096 };
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
|
||||
const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool useStdErr)
|
||||
{
|
||||
int timeout = instance.config.processingTimeout;
|
||||
int timeout = instance.config.general.processingTimeout;
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hChildPipeRead = CreateNamedPipeW(
|
||||
L"\\\\.\\pipe\\LOCAL\\",
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-11
@@ -15,18 +15,14 @@ typedef enum FFInitState
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
|
||||
static dataObject data; \
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
||||
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
|
||||
ffThreadMutexLock(&mutex); \
|
||||
if(initState != FF_INITSTATE_UNINITIALIZED) {\
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
|
||||
} \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
|
||||
if(libraryHandle == NULL) { \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
@@ -35,20 +31,17 @@ typedef enum FFInitState
|
||||
if(data.ff ## symbolName == NULL) { \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_RETURN \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return &data;
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_ERROR \
|
||||
{ \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
@@ -99,7 +92,7 @@ typedef struct GSettingsData
|
||||
|
||||
static const GSettingsData* getGSettingsData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance.config.library.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
|
||||
@@ -172,7 +165,7 @@ typedef struct DConfData
|
||||
|
||||
static const DConfData* getDConfData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance.config.library.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
|
||||
@@ -243,7 +236,7 @@ typedef struct XFConfData
|
||||
|
||||
static const XFConfData* getXFConfData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance.config.library.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
|
||||
@@ -305,7 +298,7 @@ typedef struct SQLiteData
|
||||
|
||||
static const SQLiteData* getSQLiteData(void)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance.config.library.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
|
||||
|
||||
@@ -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
-174
@@ -1,175 +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
|
||||
--gen-config <?type>: Generate a sample config file in the default path. Param `type` can be `jsonc` or `conf`
|
||||
--gen-config-force <?type>: Generate a sample config file in the default path. Overwrite the existing one
|
||||
|
||||
General options:
|
||||
--load-config <file>: Load a config file or preset (+)
|
||||
--config <file>: Alias of --load-config (+)
|
||||
--multithreading <?value>: Use multiple threads to detect values
|
||||
--stat <?value>: Show time usage (in ms) for individual modules
|
||||
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
|
||||
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
|
||||
--pipe <?value>: Disable logo and all escape sequences
|
||||
--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
|
||||
|
||||
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-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.
|
||||
--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`)
|
||||
--separator-string <str>: Set the string printed by the separator module
|
||||
--os-file <path>: Set the path to the file containing OS information
|
||||
--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
|
||||
--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/
|
||||
--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
|
||||
--gpu-temp <?value>: Detect and display GPU temperature if supported. 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 false
|
||||
--localip-compact <?value>: Show all IPs in one line. Default is false
|
||||
--netio-name-prefix <str>: Show interfaces with given name prefix only. Default is empty
|
||||
--netio-default-route-only <?value>: Show the interfac that is used for default routing only. Default is false
|
||||
--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.
|
||||
--player-name: The name of the player to use
|
||||
--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: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(instance.config.allowSlowOperations)
|
||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
||||
SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevsW(&GUID_DEVCLASS_BATTERY) failed";
|
||||
|
||||
SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) };
|
||||
for(DWORD idev = 0; SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did); idev++)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||
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,22 +96,35 @@ 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)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
||||
FF_LIBRARY_LOAD(libddcutil, &instance.config.library.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
|
||||
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
|
||||
@@ -12,7 +9,5 @@ typedef struct FFChassisResult
|
||||
FFstrbuf version;
|
||||
} FFChassisResult;
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result);
|
||||
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options);
|
||||
const char* ffChassisTypeToString(uint32_t type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "common/settings.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result)
|
||||
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||
{
|
||||
// Unlike other platforms, `smbios.chassis.type` return display string directly on my machine
|
||||
ffSettingsGetFreeBSDKenv("smbios.chassis.type", &result->type);
|
||||
|
||||
@@ -17,7 +17,7 @@ static void getSmbiosValue(const char* devicesPath, const char* classPath, FFstr
|
||||
ffStrbufClear(buffer);
|
||||
}
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result)
|
||||
const char* ffDetectChassis(FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||
{
|
||||
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->type);
|
||||
getSmbiosValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->vendor);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "chassis.h"
|
||||
|
||||
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result)
|
||||
const char* ffDetectChassis(FF_MAYBE_UNUSED FFChassisResult* result, FF_MAYBE_UNUSED FFChassisOptions* options)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
|
||||
{
|
||||
auto [arr, len] = vtProp.get<std::pair<const int32_t*, uint32_t>>();
|
||||
if(len == 0)
|
||||
return "ChassisTypes contain no data failed";
|
||||
return "ChassisTypes contain no data";
|
||||
for (uint32_t i = 0; i < len; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
@@ -65,9 +65,9 @@ FF_MAYBE_UNUSED static const char* detectWithWmi(FFChassisResult* result)
|
||||
}
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectChassis(FFChassisResult* result)
|
||||
const char* ffDetectChassis(FFChassisResult* result, FFChassisOptions* options)
|
||||
{
|
||||
if (instance.config.allowSlowOperations)
|
||||
if (options->useWmi)
|
||||
return detectWithWmi(result);
|
||||
return detectWithRegistry(result);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,7 +47,8 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
|
||||
ffParsePropLine(line, "isa :", cpuIsa) ||
|
||||
ffParsePropLine(line, "uarch :", cpuUarch) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) //For POWER
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) //For MIPS
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,12 +83,10 @@ static double getFrequency(const char* info, const char* scaling)
|
||||
|
||||
static double detectCPUTemp(void)
|
||||
{
|
||||
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 ||
|
||||
@@ -115,6 +114,10 @@ static void parseIsa(FFstrbuf* cpuIsa)
|
||||
}
|
||||
// The final ISA output of the above example is "rv64gch".
|
||||
}
|
||||
if(ffStrbufStartsWithS(cpuIsa, "mips"))
|
||||
{
|
||||
ffStrbufSubstrAfterLastC(cpuIsa, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
|
||||
@@ -27,6 +27,7 @@ const char* ffGetCpuUsageResult(FFlist* result)
|
||||
if(cpuTimes1.length == 0) return "No CPU cores found";
|
||||
|
||||
FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate(sizeof(FFCpuUsageInfo));
|
||||
uint32_t retryCount = 0;
|
||||
|
||||
retry:
|
||||
error = ffGetCpuUsageInfo(&cpuTimes2);
|
||||
@@ -39,9 +40,12 @@ retry:
|
||||
FFCpuUsageInfo* cpuTime2 = ffListGet(&cpuTimes2, i);
|
||||
if (cpuTime2->totalAll <= cpuTime1->totalAll)
|
||||
{
|
||||
ffListClear(&cpuTimes2);
|
||||
ffTimeSleep(200);
|
||||
goto retry;
|
||||
if (++retryCount <= 3)
|
||||
{
|
||||
ffListClear(&cpuTimes2);
|
||||
ffTimeSleep(200);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options);
|
||||
@@ -0,0 +1,173 @@
|
||||
#include "de.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
static void getKDE(FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileValues("/usr/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) {
|
||||
{"X-KDE-PluginInfo-Version =", result}
|
||||
});
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("xsessions/plasma5.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||
if(result->length == 0)
|
||||
{
|
||||
ffParsePropFileValues("/usr/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) {
|
||||
{"X-KDE-PluginInfo-Version =", result}
|
||||
});
|
||||
}
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", result);
|
||||
|
||||
if(result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
"plasmashell",
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL) // plasmashell 5.27.5
|
||||
ffStrbufSubstrAfterLastC(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("gnome-shell/org.gnome.Extensions", "version :", result);
|
||||
|
||||
if (result->length == 0)
|
||||
{
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
"gnome-shell",
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL) // GNOME Shell 44.1
|
||||
ffStrbufSubstrAfterLastC(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||
}
|
||||
|
||||
static void getMate(FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY major = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY micro = ffStrbufCreate();
|
||||
|
||||
ffParsePropFileDataValues("mate-about/mate-version.xml", 3, (FFpropquery[]) {
|
||||
{"<platform>", &major},
|
||||
{"<minor>", &minor},
|
||||
{"<micro>", µ}
|
||||
});
|
||||
|
||||
ffParseSemver(result, &major, &minor, µ);
|
||||
|
||||
if(result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
ffProcessAppendStdOut(result, (char* const[]){
|
||||
"mate-session",
|
||||
"--version",
|
||||
NULL
|
||||
});
|
||||
|
||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||
ffStrbufTrim(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if(result->length == 0)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
|
||||
if (dirp)
|
||||
{
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
|
||||
continue;
|
||||
ffStrbufAppendS(result, &entry->d_name[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
//This is somewhat slow
|
||||
ffProcessAppendStdOut(result, (char* const[]){
|
||||
"xfce4-session",
|
||||
"--version",
|
||||
NULL
|
||||
});
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(result, '(');
|
||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||
ffStrbufTrim(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getLXQt(FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("gconfig/lxqt.pc", "Version:", result);
|
||||
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("cmake/lxqt/lxqt-config.cmake", "set ( LXQT_VERSION", result);
|
||||
if(result->length == 0)
|
||||
ffParsePropFileData("cmake/lxqt/lxqt-config-version.cmake", "set ( PACKAGE_VERSION", result);
|
||||
|
||||
if(result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
//This is really, really, really slow. Thank you, LXQt developers
|
||||
ffProcessAppendStdOut(result, (char* const[]){
|
||||
"lxqt-session",
|
||||
"-v",
|
||||
NULL
|
||||
});
|
||||
|
||||
result->length = 0; //don't set '\0' byte
|
||||
ffParsePropLines(result->chars , "liblxqt", result);
|
||||
}
|
||||
}
|
||||
|
||||
static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
|
||||
}
|
||||
|
||||
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
|
||||
getKDE(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
|
||||
getGnome(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_CINNAMON))
|
||||
getCinnamon(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_XFCE4))
|
||||
getXFCE4(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_MATE))
|
||||
getMate(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_LXQT))
|
||||
getLXQt(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
|
||||
getBudgie(result, options);
|
||||
else
|
||||
return "Unsupported DE";
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "de.h"
|
||||
|
||||
const char* ffDetectDEVersion(FF_MAYBE_UNUSED const FFstrbuf* deName, FF_MAYBE_UNUSED FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user