Compare commits
340 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2540f00a5 | |||
| 643aa7c156 | |||
| 0381d88e2d | |||
| 6a9fd7a84d | |||
| 2a491a8da9 | |||
| 983669019e | |||
| 553f90a7c4 | |||
| 00f5b84660 | |||
| b548c6405b | |||
| 6e190c6f7c | |||
| 661c174348 | |||
| 034f444fca | |||
| 1dd942a7b1 | |||
| 2f6613cb50 | |||
| 7c98450acc | |||
| 510d57e7dd | |||
| da797ecb33 | |||
| 7080449a8c | |||
| 2c51252396 | |||
| 5114051725 | |||
| 959371d1ea | |||
| f7ba00746b | |||
| 8387d8651e | |||
| af6b7dd81b | |||
| 89850535ae | |||
| 09a2f96cf0 | |||
| 8246c6e61d | |||
| cc490294e9 | |||
| 0a55071f88 | |||
| a57e334d73 | |||
| 174d885649 | |||
| 32d3edc690 | |||
| a7e93faac8 | |||
| 49921f5ed1 | |||
| 8849107260 | |||
| ad03c42a28 | |||
| 015ad4a307 | |||
| c0daeb16df | |||
| a0a46ab73f | |||
| bedd6a1d5d | |||
| 8ea2014baf | |||
| e59f4e7e45 | |||
| 0d3d881c24 | |||
| 230d2ac39d | |||
| c7e6e45078 | |||
| db88d413c3 | |||
| eaa4230bf5 | |||
| 145e09d164 | |||
| 01dbd0c266 | |||
| 11f3dc3ea0 | |||
| 87de3f1c4a | |||
| 03511bd014 | |||
| b0ad1294e4 | |||
| fcbeecb0d5 | |||
| b3c501516a | |||
| 9418138892 | |||
| 265254ddf7 | |||
| 946154dbac | |||
| 287ba33d12 | |||
| ca75b6b55b | |||
| 666b596f63 | |||
| 5b68cdc0dd | |||
| 0f47a27d09 | |||
| e6e189497d | |||
| 32d3b265bb | |||
| ca318431f5 | |||
| 8a52836afc | |||
| 9cf95620a9 | |||
| c72c6c4a27 | |||
| e289db184c | |||
| e7c9b80d85 | |||
| b8656d5e12 | |||
| c8486610f6 | |||
| d727f8acde | |||
| 8c64e0c275 | |||
| 40588e1a39 | |||
| 6c024d29ce | |||
| db6ad5a268 | |||
| 5096b4a81d | |||
| 5c64ce3b89 | |||
| 38a6d07c85 | |||
| 4632fe8cd9 | |||
| d8bfebfc0f | |||
| 48300429af | |||
| 218dffadd3 | |||
| f324794f54 | |||
| 6e3a329d3b | |||
| b2da8bac41 | |||
| 100e59fd49 | |||
| 5fdb0719f2 | |||
| d4368f56fd | |||
| 55c939a8ef | |||
| 0be2410925 | |||
| 0f824536f9 | |||
| 51c70bc44a | |||
| 47a0b8969f | |||
| 8df95224ed | |||
| 4481d983a9 | |||
| 24e8158116 | |||
| 5239223ad5 | |||
| 1d9a938ff3 | |||
| cd01d16eb9 | |||
| 8e856c3dd6 | |||
| b6dc436e03 | |||
| 3f80fafc09 | |||
| 8e922abf73 | |||
| 737b36e799 | |||
| f5ac85c4e3 | |||
| 0250d11d97 | |||
| e88472e9f6 | |||
| 2907a26adf | |||
| d337126c80 | |||
| 099fb1a43a | |||
| 6efe186df1 | |||
| f33f172734 | |||
| d6a1caa89f | |||
| ed5d7292ba | |||
| 4b0b6c9000 | |||
| 64d64d5050 | |||
| 1a996c3d67 | |||
| ee7231d87c | |||
| 371b3a2d75 | |||
| 007ded2883 | |||
| c32f2f2f2b | |||
| 98c94b01e5 | |||
| 0dda4efa8d | |||
| 877ed94187 | |||
| 484264027c | |||
| 5498b0b042 | |||
| 8f30d0cdd8 | |||
| 80f18e2473 | |||
| 1700d23c26 | |||
| 195675f078 | |||
| 0115b638de | |||
| 3d0653025e | |||
| 991d02e2c0 | |||
| cbab8d7f70 | |||
| 6e09157235 | |||
| 464a57b319 | |||
| d31d157b00 | |||
| 07231ffbbc | |||
| f9fa482b83 | |||
| 65ed48a1bc | |||
| 3068b5bcb2 | |||
| 9da97f5860 | |||
| fa065c1040 | |||
| 664017ba81 | |||
| 1d6fefd40b | |||
| fea4a9dfd5 | |||
| 183c8d7904 | |||
| e5b110375f | |||
| 6eed53217d | |||
| 254c4e5f50 | |||
| 01a917982c | |||
| a9cb178315 | |||
| ec4bd5d3a2 | |||
| 7f19cb1d21 | |||
| e60537512e | |||
| 431f570f05 | |||
| 482e5a5eff | |||
| c282384dab | |||
| 81bddbf182 | |||
| b8fc471678 | |||
| fd34811c81 | |||
| 67c5a6b7cc | |||
| 6b02e1a0ca | |||
| 92f1604e6a | |||
| f0cee064bd | |||
| 6bd933eba2 | |||
| f3e6d04c8e | |||
| d5846d94ca | |||
| 2a61d29be9 | |||
| 49cdacd5a9 | |||
| ce6d7e386d | |||
| fe1ad0da16 | |||
| 6157de60e6 | |||
| 61e71ed658 | |||
| 381cba2612 | |||
| 34b273186a | |||
| e3acd8c155 | |||
| 55f28ae8ff | |||
| 6f2748e208 | |||
| fb3eb9666e | |||
| 8d663300c7 | |||
| d29d99bd6d | |||
| bbdeb668d6 | |||
| 85578c6807 | |||
| 93871c1e98 | |||
| bcacaa9401 | |||
| d079e25a43 | |||
| b4306b944e | |||
| fd75f0b7e7 | |||
| 87c3459f5d | |||
| 051a043a4b | |||
| 913a3e79d4 | |||
| 59557e06fd | |||
| 6d0d916861 | |||
| a0a1c04011 | |||
| b59227e49f | |||
| c64e2c14c2 | |||
| 8c6cf2ccda | |||
| bd657328d2 | |||
| 45d6f21402 | |||
| 4d569db0fd | |||
| d46f9ab4dc | |||
| 3d4ce07892 | |||
| bb3689b348 | |||
| d5500ad4f7 | |||
| 9e4a55d285 | |||
| 999b9187a0 | |||
| 73095ef9e9 | |||
| f4fc9692eb | |||
| 59ebc745c0 | |||
| 09f3bd5a79 | |||
| 413d126bcc | |||
| 9eeb216b70 | |||
| f362fdb01d | |||
| 155d4e90ae | |||
| df9aec6e86 | |||
| d903ccb6f6 | |||
| 4b612461b8 | |||
| 38013450ae | |||
| ddb0c344f5 | |||
| 67e433750a | |||
| c4b024ec6c | |||
| e98c18a64b | |||
| acba1d29d9 | |||
| dd0f6354ef | |||
| 0e2d353500 | |||
| f9695f4148 | |||
| 8fdbadfbb2 | |||
| 5c43119836 | |||
| 545210e25e | |||
| 6f60423c60 | |||
| 6e6847a66b | |||
| 47c9fb9f6c | |||
| 5e5c144582 | |||
| ac330430bf | |||
| 52275b89dc | |||
| 50bb06535c | |||
| a8b0e77189 | |||
| b815464704 | |||
| 93ac3f1971 | |||
| 7c43e4b8e7 | |||
| d8e7588fc3 | |||
| 9ea5de5efc | |||
| 728759d38e | |||
| b0426828ab | |||
| 6de8153207 | |||
| 2c4b80a093 | |||
| c51903da35 | |||
| 8b7092e4d4 | |||
| c54b7fbd57 | |||
| 820854a2fa | |||
| ad4a71a2d5 | |||
| 22075e2d28 | |||
| a926c9cf7e | |||
| 60c735d1a4 | |||
| 9466ee3e51 | |||
| 126c1a10bb | |||
| 425e135bd8 | |||
| 0a675fec8c | |||
| 2c5b079b97 | |||
| 0be1a41b5c | |||
| 883e0450b0 | |||
| 2fc8a7e70b | |||
| be7f8f4117 | |||
| dd60e8aa75 | |||
| 851899397e | |||
| 60a30d888f | |||
| 999c8208b7 | |||
| 9143b6dbec | |||
| 16a706d3c5 | |||
| 58f436d8a2 | |||
| 47d1f2e673 | |||
| 8be4921bd0 | |||
| b22bcba220 | |||
| 5ee7ea46e7 | |||
| d93c934269 | |||
| 5c1ac33df2 | |||
| 0b3bf3c273 | |||
| 7fd98829b0 | |||
| 282271a65a | |||
| 9ef4b82cb9 | |||
| 10973dd9d1 | |||
| dfdffec1c9 | |||
| 2283700a99 | |||
| 7b647e09da | |||
| 54cb74c999 | |||
| 0f70cb408f | |||
| c80b1761dd | |||
| a1fde6f922 | |||
| 6a44515cf2 | |||
| cfcc4c8375 | |||
| ea60fd0a0d | |||
| a4e0275263 | |||
| 71779fa4b1 | |||
| 475099696f | |||
| 14670b6144 | |||
| 327b1b142e | |||
| 9d106c6672 | |||
| df0e13b198 | |||
| 6d0675820e | |||
| 08b0bac2b9 | |||
| d387800bda | |||
| 542ad5eab6 | |||
| 99f42d0953 | |||
| 3b316bdd3f | |||
| f011f8851e | |||
| 8f23a52f53 | |||
| 8f53d33f29 | |||
| e6fa269f52 | |||
| ca4a327de4 | |||
| f4e777f3d2 | |||
| 136f73ea0b | |||
| 28270541e6 | |||
| 8197eddea8 | |||
| 23bccc4802 | |||
| 873c7d93b6 | |||
| f4ee8667b1 | |||
| 50d3d4cdf4 | |||
| df048035b5 | |||
| 952989c1e8 | |||
| aa1237b0fd | |||
| b87983c86b | |||
| 779dbab647 | |||
| 47373998d5 | |||
| 11809e30b5 | |||
| 35253e085c | |||
| 112e83b7c3 | |||
| c74b34aa39 | |||
| b2e0034c34 | |||
| e3cdf9d9fd | |||
| 6cdb694e33 | |||
| 83016289e9 | |||
| f9562d7132 | |||
| 2f66bc2c95 | |||
| d7c848225c | |||
| 8404ae8e70 | |||
| d75f72c8fe |
@@ -1 +1 @@
|
||||
custom: paypal.me/linusdierheimer
|
||||
github: LinusDierheimer
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
name: manage pull requests
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: manage pull request
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- 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
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . -j$(nproc) --target package
|
||||
|
||||
- name: run fastfetch
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -1,36 +1,41 @@
|
||||
name: manage pushes
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
manage:
|
||||
name: manage push
|
||||
linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
security-events: write
|
||||
contents: read
|
||||
outputs:
|
||||
ffversion: ${{ steps.ffversion.outputs.ffversion }}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- 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
|
||||
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 libcjson-dev
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
# We reuse the build binary only for the releases.
|
||||
# We set tweak version to off, because it is wrong, as git tag will happen after this step. Releases don't have a tweak, so this is ok.
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . -j$(nproc) --target package
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: run fastfetch
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
@@ -38,12 +43,99 @@ jobs:
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
|
||||
- name: get fastfetch version
|
||||
id: get_version_fastfetch
|
||||
run: echo "::set-output name=release::$(./fastfetch --version-raw)"
|
||||
id: ffversion
|
||||
run: echo "::set-output name=ffversion::$(./fastfetch --version-raw)"
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-linux
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
macos:
|
||||
name: MacOS
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: brew install vulkan-loader molten-vk
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: run fastfetch
|
||||
run: ./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-macos
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
bsd:
|
||||
name: BSD
|
||||
runs-on: macos-12
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg install -y cmake git pkgconf pciutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package
|
||||
./fastfetch --recache --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
./flashfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-bsd
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch'
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- bsd
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
|
||||
- name: get latest release version
|
||||
id: get_version_release
|
||||
@@ -52,9 +144,10 @@ jobs:
|
||||
repository: ${{ github.repository }}
|
||||
|
||||
- name: create release
|
||||
if: steps.get_version_fastfetch.outputs.release != steps.get_version_release.outputs.release
|
||||
if: needs.linux.outputs.ffversion != steps.get_version_release.outputs.release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ steps.get_version_fastfetch.outputs.release }}
|
||||
tag: ${{ needs.linux.outputs.ffversion }}
|
||||
commit: ${{ github.sha }}
|
||||
artifacts: ./fastfetch-*.*
|
||||
artifactErrorsFailBuild: true
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
**/.vscode/
|
||||
**/.cache/
|
||||
**/.kdev4/
|
||||
**/.DS_Store
|
||||
cscope.*
|
||||
tags
|
||||
fastfetch.kdev4
|
||||
|
||||
@@ -1,3 +1,79 @@
|
||||
# 1.7.2
|
||||
|
||||
Fixes the bash completions
|
||||
|
||||
# 1.7.1
|
||||
|
||||
This release brings a lot of bug fixes and improvements for MacOS. Big thanks to @CarterLi for the help on this!
|
||||
|
||||
Features:
|
||||
* The color of the title and the keys can now be configured individually, using `--color-keys` and `--color-title` respectively. Some distros have different defaults now, similar to neofetch
|
||||
* Swap module, similar to the Memory module, but for swap. Add `Swap` to your structure to enable it (#225)
|
||||
|
||||
Logos:
|
||||
* Slackware (#227)
|
||||
|
||||
Bugfixes:
|
||||
* Used disk space is now calculated much more accurately
|
||||
* On Linux, GPU names are no longer truncated, if they are longer than 32 characters (#224)
|
||||
* On Linux, NVIDIA GPUs once again have a proper name
|
||||
|
||||
* On M1 platforms, showing the GPU name no longer crashes the program (#222)
|
||||
* Brew package count does now work on M1 platforms too
|
||||
* The Vulkan module now does work on MacOS too
|
||||
* The OpenGL and OpenCL modules now work on MacOS too (@CarterLi, #226)
|
||||
* The LocalIp module now works on MacOS too (@CarterLi, #232)
|
||||
* Detecting custom WMs on MacOS does now work
|
||||
|
||||
Other:
|
||||
* GitHub actions now builds a dmg file for MacOS, as you can see in the release page
|
||||
|
||||
# 1.7.0
|
||||
|
||||
This release brings support for MacOS!
|
||||
The basics things are working, but it is far from feature parity with Linux.
|
||||
I developed this in a VM, so bugs on real hardware are likely.
|
||||
If you have a Mac and no idea what to do with your free time, i am very happy to accept pull requests / work on issues.
|
||||
|
||||
A lot of things were changed under the hood to make this possible, which should bring better performance and stability on all platforms.
|
||||
|
||||
Besides that, the following things have changed:
|
||||
|
||||
Features:
|
||||
* The binary prefix used can now be configured, and is used consistently across all modules. Set `--binary-prefix` to `iec` (default), `si` or `jedec`.
|
||||
* AMD GPUs now have a much better name, if the file `/usr/share/libdrm/amdgpu.ids` exists. For example my dedicated GPU, which was displayed as `AMD/ATI Radeon RX 5600 OEM/5600 XT / 5700/5700 XT`, is now `AMD Radeon RX 5600M`.
|
||||
|
||||
Logos:
|
||||
* MacOS
|
||||
* CachyOS small (@sirlucjan, #220)
|
||||
* MSYS2 (#219)
|
||||
|
||||
Bugfixes:
|
||||
* the `--file` option, which can be used to display the contents of a file as the logo, is now working again.
|
||||
|
||||
# 1.6.5
|
||||
|
||||
Fixes parsing quoted values in config files
|
||||
|
||||
# 1.6.4
|
||||
|
||||
Releasing this, so fedora can package fastfetch. Thanks to @jonathanspw for doing that!
|
||||
|
||||
Features:
|
||||
* --set-keyless option (#215)
|
||||
* Replace `\n`, `\t`, `\e` and `\\` in user provided strings, just like c would do it (#215)
|
||||
* APK (Alpine Package Keeper) support (@mxkrsv, #216)
|
||||
|
||||
Logos:
|
||||
* Alma Linux (@jonathanspw, #214)
|
||||
|
||||
Bugfixes:
|
||||
* replace deprecated gethostbyname call with getaddrinfo (#217)
|
||||
|
||||
# 1.6.3
|
||||
|
||||
Fixes installing presets in their own directory (@ceamac, #212)
|
||||
|
||||
# 1.6.2
|
||||
|
||||
Releasing this, so void linux can package fastfetch.
|
||||
|
||||
@@ -1,38 +1,60 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 1.6.2
|
||||
VERSION 1.7.2
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast system information tool"
|
||||
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
|
||||
)
|
||||
|
||||
###################
|
||||
# Target Platform #
|
||||
###################
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
|
||||
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Bb][Ss][Dd].*")
|
||||
set(BSD TRUE CACHE BOOL "..." FORCE)
|
||||
elseif(NOT APPLE AND NOT ANDROID AND NOT MSYS)
|
||||
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
|
||||
if(MSYS)
|
||||
enable_language(CXX)
|
||||
endif()
|
||||
|
||||
#####################
|
||||
# Configure options #
|
||||
#####################
|
||||
|
||||
OPTION(ENABLE_LIBPCI "Enable libpci" ON)
|
||||
OPTION(ENABLE_VULKAN "Enable vulkan" ON)
|
||||
OPTION(ENABLE_WAYLAND "Enable wayland-client" ON)
|
||||
OPTION(ENABLE_XCB_RANDR "Enable xcb-randr" ON)
|
||||
OPTION(ENABLE_XCB "Enable xcb" ON)
|
||||
OPTION(ENABLE_XRANDR "Enable xrandr" ON)
|
||||
OPTION(ENABLE_X11 "Enable x11" ON)
|
||||
OPTION(ENABLE_GIO "Enable gio-2.0" ON)
|
||||
OPTION(ENABLE_DCONF "Enable dconf" ON)
|
||||
OPTION(ENABLE_DBUS "Enable dbus-1" ON)
|
||||
OPTION(ENABLE_XFCONF "Enable libxfconf-0" ON)
|
||||
OPTION(ENABLE_SQLITE3 "Enable sqlite3" ON)
|
||||
OPTION(ENABLE_RPM "Enable rpm" ON)
|
||||
OPTION(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON)
|
||||
OPTION(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON)
|
||||
OPTION(ENABLE_ZLIB "Enable zlib" ON)
|
||||
OPTION(ENABLE_CHAFA "Enable chafa" ON)
|
||||
OPTION(ENABLE_EGL "Enable egl" ON)
|
||||
OPTION(ENABLE_GLX "Enable glx" ON)
|
||||
OPTION(ENABLE_OSMESA "Enable osmesa" ON)
|
||||
OPTION(ENABLE_OPENCL "Enable opencl" ON)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
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
|
||||
cmake_dependent_option(ENABLE_LIBPCI "Enable libpci" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR MSYS" OFF)
|
||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
|
||||
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_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)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR MSYS" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR MSYS" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" 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
|
||||
|
||||
#############################
|
||||
# Compile time dependencies #
|
||||
@@ -43,6 +65,8 @@ find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
include(CheckIncludeFile)
|
||||
|
||||
####################
|
||||
# Compiler options #
|
||||
####################
|
||||
@@ -51,9 +75,29 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
|
||||
|
||||
if(MSYS)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti")
|
||||
endif()
|
||||
|
||||
# Used for dlopen finding dylibs installed by homebrew
|
||||
# `/opt/homebrew/lib` is not on in dlopen search path by default
|
||||
if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,$ENV{HOMEBREW_PREFIX}/lib")
|
||||
endif()
|
||||
|
||||
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
|
||||
if(NOT MSYS)
|
||||
set(FASTFETCH_FLAGS_DEBUG "${FASTFETCH_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG}")
|
||||
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${FASTFETCH_FLAGS_DEBUG} -rdynamic")
|
||||
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
if(IPO_SUPPORTED)
|
||||
@@ -81,13 +125,28 @@ if(NOT TARGET_DIR_USR)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET_DIR_HOME)
|
||||
if(NOT ANDROID)
|
||||
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/home")
|
||||
else()
|
||||
if(APPLE)
|
||||
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/Users")
|
||||
elseif(ANDROID)
|
||||
set(TARGET_DIR_HOME "/data/data/com.termux/files/home")
|
||||
else()
|
||||
set(TARGET_DIR_HOME "${TARGET_DIR_ROOT}/home")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TARGET_DIR_ETC)
|
||||
set(TARGET_DIR_ETC "${TARGET_DIR_ROOT}/etc")
|
||||
endif()
|
||||
|
||||
#https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${TARGET_DIR_USR}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "${TARGET_DIR_ETC}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
#################
|
||||
# Tweak version #
|
||||
#################
|
||||
@@ -133,7 +192,7 @@ configure_file(src/fastfetch_config.h.in fastfetch_config.h)
|
||||
# libfastfetch target #
|
||||
#######################
|
||||
|
||||
add_library(libfastfetch OBJECT
|
||||
set(LIBFASTFETCH_SRC
|
||||
src/util/FFstrbuf.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFvaluestore.c
|
||||
@@ -143,7 +202,6 @@ add_library(libfastfetch OBJECT
|
||||
src/common/caching.c
|
||||
src/common/properties.c
|
||||
src/common/font.c
|
||||
src/common/processing.c
|
||||
src/common/format.c
|
||||
src/common/parsing.c
|
||||
src/common/settings.c
|
||||
@@ -154,26 +212,27 @@ add_library(libfastfetch OBJECT
|
||||
src/logo/image/image.c
|
||||
src/logo/image/im7.c
|
||||
src/logo/image/im6.c
|
||||
src/detection/os.c
|
||||
src/detection/qt.c
|
||||
src/detection/gtk.c
|
||||
src/detection/terminalShell.c
|
||||
src/detection/vulkan.c
|
||||
src/detection/media.c
|
||||
src/detection/datetime.c
|
||||
src/detection/temps.c
|
||||
src/detection/title.c
|
||||
src/detection/displayserver/displayServer.c
|
||||
src/detection/displayserver/wayland.c
|
||||
src/detection/displayserver/xcb.c
|
||||
src/detection/displayserver/xlib.c
|
||||
src/detection/displayserver/wmde.c
|
||||
src/detection/host/host.c
|
||||
src/detection/os/os.c
|
||||
src/detection/cpu/cpu.c
|
||||
src/detection/cpuUsage/cpuUsage.c
|
||||
src/detection/gpu/gpu.c
|
||||
src/detection/memory/memory.c
|
||||
src/detection/font/font.c
|
||||
src/detection/displayserver/displayserver.c
|
||||
src/detection/terminalfont/terminalfont.c
|
||||
src/detection/media/media.c
|
||||
src/modules/break.c
|
||||
src/modules/custom.c
|
||||
src/modules/title.c
|
||||
src/modules/separator.c
|
||||
src/modules/os.c
|
||||
src/modules/host.c
|
||||
src/modules/bios.c
|
||||
src/modules/board.c
|
||||
src/modules/kernel.c
|
||||
src/modules/uptime.c
|
||||
src/modules/processes.c
|
||||
@@ -195,10 +254,12 @@ add_library(libfastfetch OBJECT
|
||||
src/modules/memory.c
|
||||
src/modules/disk.c
|
||||
src/modules/battery.c
|
||||
src/modules/poweradapter.c
|
||||
src/modules/locale.c
|
||||
src/modules/vulkan.c
|
||||
src/modules/localip.c
|
||||
src/modules/publicip.c
|
||||
src/modules/weather.c
|
||||
src/modules/player.c
|
||||
src/modules/song.c
|
||||
src/modules/datetime.c
|
||||
@@ -207,247 +268,242 @@ add_library(libfastfetch OBJECT
|
||||
src/modules/colors.c
|
||||
src/modules/opengl.c
|
||||
src/modules/opencl.c
|
||||
src/modules/users.c
|
||||
)
|
||||
|
||||
if(ENABLE_LIBPCI)
|
||||
pkg_check_modules(LIBPCI libpci)
|
||||
if(LIBPCI_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBPCI=1)
|
||||
else()
|
||||
message(WARNING "Package libpci not found. Building without support.")
|
||||
endif()
|
||||
if(LINUX OR APPLE OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/users/users_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/detection/disk/disk.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/kernel/kernel_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_VULKAN)
|
||||
pkg_check_modules(VULKAN vulkan)
|
||||
if(VULKAN_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_VULKAN=1)
|
||||
else()
|
||||
message(WARNING "Package vulkan not found. Building without support.")
|
||||
endif()
|
||||
if(BSD OR APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/sysctl.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WAYLAND)
|
||||
pkg_check_modules (WAYLAND wayland-client)
|
||||
if(WAYLAND_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WAYLAND=1)
|
||||
else()
|
||||
message(WARNING "Package wayland-client not found. Building without support.")
|
||||
endif()
|
||||
if(LINUX OR ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XCB_RANDR)
|
||||
pkg_check_modules(XCB_RANDR xcb-randr)
|
||||
if(XCB_RANDR_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XCB_RANDR=1)
|
||||
else()
|
||||
message(WARNING "Package xcb-randr not found. Building without support.")
|
||||
endif()
|
||||
if(LINUX OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/processes/processes_linux.c
|
||||
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XCB)
|
||||
pkg_check_modules (XCB xcb)
|
||||
if(XCB_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XCB=1)
|
||||
else()
|
||||
message(WARNING "Package xcb not found. Building without support.")
|
||||
endif()
|
||||
if(LINUX OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_linux.c
|
||||
src/detection/bios/bios_linux.c
|
||||
src/detection/board/board_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/battery/battery_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/qt.c
|
||||
src/detection/gtk.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XRANDR)
|
||||
pkg_check_modules(XRANDR xrandr)
|
||||
if(XRANDR_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XRANDR=1)
|
||||
else()
|
||||
message(WARNING "Package xrandr not found. Building without support.")
|
||||
endif()
|
||||
if(MSYS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/processing_linux.c
|
||||
src/detection/host/host_windows.cpp
|
||||
src/detection/bios/bios_windows.cpp
|
||||
src/detection/board/board_windows.cpp
|
||||
src/detection/cpu/cpu_windows.cpp
|
||||
src/detection/gpu/gpu_windows.cpp
|
||||
src/detection/battery/battery_windows.cpp
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/detection/opengl/opengl_windows.c
|
||||
src/detection/users/users_windows.cpp
|
||||
src/detection/os/os_windows.cpp
|
||||
src/detection/processes/processes_windows.cpp
|
||||
src/detection/disk/disk_windows.c
|
||||
src/detection/cpuUsage/cpuUsage_windows.c
|
||||
src/detection/cpuUsage/cpuUsage_nowait_windows.cpp
|
||||
src/detection/memory/memory_windows.cpp
|
||||
src/detection/font/font_windows.cpp
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/terminalshell/terminalshell_windows.cpp
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/packages/packages_windows.c
|
||||
src/detection/kernel/kernel_windows.cpp
|
||||
src/detection/localip/localip_windows.c
|
||||
src/util/windows/wmi.cpp
|
||||
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/media/media_nosupport.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_X11)
|
||||
pkg_check_modules(X11 x11)
|
||||
if(X11_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_X11=1)
|
||||
else()
|
||||
message(WARNING "Package x11 not found. Building without support.")
|
||||
endif()
|
||||
if(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_apple.c
|
||||
src/util/apple/cf_helpers.c
|
||||
src/util/apple/osascript.m
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/os/os_apple.m
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/battery/battery_apple.c
|
||||
src/detection/poweradapter/poweradapter_apple.c
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/terminalfont/terminalfont_apple.m
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/disk/disk_apple.m
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
src/detection/temps/temps_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
src/detection/opengl/opengl_apple.c
|
||||
src/detection/processes/processes_apple.c
|
||||
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GIO)
|
||||
pkg_check_modules(GIO gio-2.0)
|
||||
if(GIO_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GIO=1)
|
||||
else()
|
||||
message(WARNING "Package gio-2.0 not found. Building without support.")
|
||||
endif()
|
||||
if(BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DCONF)
|
||||
pkg_check_modules(DCONF dconf)
|
||||
if(DCONF_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_DCONF=1)
|
||||
else()
|
||||
message(WARNING "Package dconf not found. Building without support.")
|
||||
endif()
|
||||
if(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_android.c
|
||||
src/detection/os/os_android.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/displayserver/displayserver_nosupport.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/gpu/gpu_nosupport.c
|
||||
src/detection/font/font_nosupport.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DBUS)
|
||||
pkg_check_modules(DBUS dbus-1)
|
||||
if(DBUS_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_DBUS=1)
|
||||
else()
|
||||
message(WARNING "Package dbus-1 not found. Building without support.")
|
||||
endif()
|
||||
add_library(libfastfetch OBJECT
|
||||
${LIBFASTFETCH_SRC}
|
||||
)
|
||||
|
||||
target_compile_definitions(libfastfetch PUBLIC _GNU_SOURCE)
|
||||
|
||||
CHECK_INCLUDE_FILE("sys/sysinfo.h" HAVE_SYSINFO_H)
|
||||
if(HAVE_SYSINFO_H)
|
||||
# needs to be public, because changes fastfech.h ABI
|
||||
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_SYSINFO_H)
|
||||
endif()
|
||||
|
||||
if(ENABLE_XFCONF)
|
||||
pkg_check_modules(XFCONF libxfconf-0)
|
||||
if(XFCONF_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_XFCONF=1)
|
||||
else()
|
||||
message(WARNING "Package libxfconf-0 not found. Building without support.")
|
||||
endif()
|
||||
CHECK_INCLUDE_FILE("utmpx.h" HAVE_UTMPX_H)
|
||||
if(HAVE_UTMPX_H)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SQLITE3)
|
||||
pkg_check_modules(SQLITE3 sqlite3)
|
||||
if(SQLITE3_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_SQLITE3=1)
|
||||
else()
|
||||
message(WARNING "Package sqlite3 not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_RPM)
|
||||
pkg_check_modules(RPM rpm)
|
||||
if(RPM_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_RPM=1)
|
||||
else()
|
||||
message(WARNING "Package rpm not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_IMAGEMAGICK7)
|
||||
pkg_check_modules(IMAGEMAGICK7 MagickCore-7.Q16HDRI)
|
||||
if(NOT IMAGEMAGICK7_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc)
|
||||
endif()
|
||||
if(NOT IMAGEMAGICK7_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK7 MagickCore-7.Q16)
|
||||
endif()
|
||||
if(NOT IMAGEMAGICK7_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc)
|
||||
function(ff_lib_enable VARNAME)
|
||||
if(NOT ENABLE_${VARNAME})
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(IMAGEMAGICK7_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_IMAGEMAGICK7=1)
|
||||
else()
|
||||
message(WARNING "Package MagickCore-7.Q16HDRI or MagickCore-7.Q16 not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_IMAGEMAGICK6)
|
||||
pkg_check_modules(IMAGEMAGICK6 MagickCore-6.Q16HDRI)
|
||||
if(NOT IMAGEMAGICK6_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc)
|
||||
endif()
|
||||
if(NOT IMAGEMAGICK6_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK6 MagickCore-6.Q16)
|
||||
endif()
|
||||
if(NOT IMAGEMAGICK6_FOUND)
|
||||
pkg_check_modules(IMAGEMAGICK6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc)
|
||||
pkg_search_module(${VARNAME} ${ARGN})
|
||||
if(NOT ${VARNAME}_FOUND)
|
||||
message(WARNING "Package ${ARGV1} not found, building without support.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(IMAGEMAGICK6_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_IMAGEMAGICK6=1)
|
||||
else()
|
||||
message(WARNING "Package MagickCore-6.Q16HDRI or MagickCore-6.Q16 not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_${VARNAME}=1)
|
||||
target_include_directories(libfastfetch PRIVATE ${${VARNAME}_INCLUDE_DIRS})
|
||||
target_link_directories(libfastfetch PRIVATE ${${VARNAME}_LIBRARY_DIRS})
|
||||
|
||||
if(ENABLE_ZLIB)
|
||||
pkg_check_modules(ZLIB zlib)
|
||||
if(ZLIB_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_ZLIB=1)
|
||||
else()
|
||||
message(WARNING "Package zlib not found. Building without support")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_CHAFA)
|
||||
if(IMAGEMAGICK6_FOUND OR IMAGEMAGICK7_FOUND)
|
||||
pkg_check_modules(CHAFA chafa>=1.10)
|
||||
if(CHAFA_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_CHAFA=1)
|
||||
else()
|
||||
message(WARNING "Package chafa>=1.10 not found. Building without support.")
|
||||
foreach(FLAG ${${VARNAME}_CFLAGS_OTHER})
|
||||
if(FLAG MATCHES "-D.*")
|
||||
string(SUBSTRING ${FLAG} 2 -1 FLAG)
|
||||
target_compile_definitions(libfastfetch PRIVATE ${FLAG})
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Chafa not enabled, because neither ImageMagick6 nor ImageMagick7 were found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if(ENABLE_EGL)
|
||||
pkg_check_modules(EGL egl)
|
||||
if(EGL_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_EGL=1)
|
||||
else()
|
||||
message(WARNING "Package egl not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
ff_lib_enable(LIBPCI libpci)
|
||||
ff_lib_enable(VULKAN vulkan)
|
||||
ff_lib_enable(WAYLAND wayland-client)
|
||||
ff_lib_enable(XCB_RANDR xcb-randr)
|
||||
ff_lib_enable(XCB xcb)
|
||||
ff_lib_enable(XRANDR xrandr)
|
||||
ff_lib_enable(X11 x11)
|
||||
ff_lib_enable(GIO gio-2.0)
|
||||
ff_lib_enable(DCONF dconf)
|
||||
ff_lib_enable(DBUS dbus-1)
|
||||
ff_lib_enable(XFCONF libxfconf-0)
|
||||
ff_lib_enable(SQLITE3 sqlite3)
|
||||
ff_lib_enable(RPM rpm)
|
||||
ff_lib_enable(IMAGEMAGICK7 MagickCore-7.Q16HDRI MagickCore-7.Q16 MagickCore-7 /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16HDRI.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.Q16.pc /usr/lib/imagemagick7/pkgconfig/MagickCore-7.pc)
|
||||
ff_lib_enable(IMAGEMAGICK6 MagickCore-6.Q16HDRI MagickCore-6.Q16 MagickCore-6 /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16HDRI.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.Q16.pc /usr/lib/imagemagick6/pkgconfig/MagickCore-6.pc)
|
||||
ff_lib_enable(ZLIB zlib)
|
||||
ff_lib_enable(CHAFA chafa>=1.10)
|
||||
ff_lib_enable(EGL egl)
|
||||
ff_lib_enable(GLX glx)
|
||||
ff_lib_enable(OSMESA osmesa)
|
||||
ff_lib_enable(OPENCL OpenCL)
|
||||
ff_lib_enable(LIBCJSON libcjson)
|
||||
ff_lib_enable(FREETYPE freetype2)
|
||||
|
||||
if(ENABLE_GLX)
|
||||
pkg_check_modules(GLX glx)
|
||||
if(GLX_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_GLX=1)
|
||||
else()
|
||||
message(WARNING "Package glx not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_OSMESA)
|
||||
pkg_check_modules(OSMESA osmesa)
|
||||
if(OSMESA_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_OSMESA=1)
|
||||
else()
|
||||
message(WARNING "Package osmesa not found. Building without support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_OPENCL)
|
||||
pkg_check_modules(OPENCL OpenCL)
|
||||
if(OPENCL_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_OPENCL=1)
|
||||
else()
|
||||
message(WARNING "Package opencl not found. Building without support.")
|
||||
endif()
|
||||
if(APPLE)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "-framework CoreFoundation"
|
||||
PRIVATE "-framework IOKit"
|
||||
PRIVATE "-framework CoreGraphics"
|
||||
PRIVATE "-framework OpenGL"
|
||||
PRIVATE "-framework OpenCL"
|
||||
PRIVATE "-framework Cocoa"
|
||||
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
|
||||
)
|
||||
elseif(MSYS)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "wbemuuid"
|
||||
PRIVATE "ole32"
|
||||
PRIVATE "oleaut32"
|
||||
PRIVATE "dwmapi"
|
||||
PRIVATE "opengl32"
|
||||
PRIVATE "gdi32"
|
||||
PRIVATE "iphlpapi"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(libfastfetch
|
||||
PUBLIC ${PROJECT_BINARY_DIR}
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/src
|
||||
|
||||
PRIVATE ${LIBPCI_INCLUDE_DIRS}
|
||||
PRIVATE ${VULKAN_INCLUDE_DIRS}
|
||||
PRIVATE ${WAYLAND_INCLUDE_DIRS}
|
||||
PRIVATE ${XCB_RANDR_INCLUDE_DIRS}
|
||||
PRIVATE ${XCB_INCLUDE_DIRS}
|
||||
PRIVATE ${XRANDR_INCLUDE_DIRS}
|
||||
PRIVATE ${X11_INCLUDE_DIRS}
|
||||
PRIVATE ${GIO_INCLUDE_DIRS}
|
||||
PRIVATE ${DCONF_INCLUDE_DIRS}
|
||||
PRIVATE ${DBUS_INCLUDE_DIRS}
|
||||
PRIVATE ${XFCONF_INCLUDE_DIRS}
|
||||
PRIVATE ${SQLITE3_INCLUDE_DIRS}
|
||||
PRIVATE ${RPM_INCLUDE_DIRS}
|
||||
PRIVATE ${IMAGEMAGICK7_INCLUDE_DIRS}
|
||||
PRIVATE ${IMAGEMAGICK6_INCLUDE_DIRS}
|
||||
PRIVATE ${ZLIB_INCLUDE_DIRS}
|
||||
PRIVATE ${CHAFA_INCLUDE_DIRS}
|
||||
PRIVATE ${VULKAN_INCLUDE_DIRS}
|
||||
PRIVATE ${EGL_INCLUDE_DIRS}
|
||||
PRIVATE ${GLX_INCLUDE_DIRS}
|
||||
PRIVATE ${OSMESA_INCLUDE_DIRS}
|
||||
PRIVATE ${OPENCL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(libfastfetch
|
||||
@@ -485,23 +541,22 @@ if (BUILD_TESTS)
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
add_executable(fastfetch-test-list
|
||||
tests/list.c
|
||||
)
|
||||
target_link_libraries(fastfetch-test-list
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
|
||||
add_test(NAME test-list COMMAND fastfetch-test-list)
|
||||
endif()
|
||||
|
||||
##################
|
||||
# install target #
|
||||
##################
|
||||
|
||||
#https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${TARGET_DIR_USR}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "${TARGET_DIR_ROOT}/etc")
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
@@ -522,7 +577,7 @@ install(
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/presets/"
|
||||
DIRECTORY "${CMAKE_SOURCE_DIR}/presets"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${CMAKE_PROJECT_NAME}"
|
||||
)
|
||||
|
||||
@@ -535,21 +590,30 @@ install(
|
||||
# package target #
|
||||
##################
|
||||
|
||||
set(CPACK_GENERATOR "DEB;RPM;TGZ;ZIP")
|
||||
set(CPACK_GENERATOR "TGZ;ZIP")
|
||||
|
||||
if(LINUX)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};DEB;RPM")
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION, "utils")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
||||
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
|
||||
elseif(APPLE)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};DragNDrop")
|
||||
|
||||
set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK TRUE)
|
||||
elseif(BSD)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};FreeBSD")
|
||||
endif()
|
||||
|
||||
set(CPACK_SET_DESTDIR ON)
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "Linus Dierheimer <Linus@Dierheimer.de>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Neofetch clone written in C")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "\
|
||||
fastfetch is a neofetch-like tool for fetching system information and displaying them in a pretty way. \
|
||||
It is written in c to achieve much better performance.\
|
||||
")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/LinusDierheimer")
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION, "utils")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
||||
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -11,8 +11,6 @@ Here i just add things that are easy to forget.
|
||||
- `libffdetect`: contains all the detection stuff. To be used by anything that needs system information
|
||||
- `libffprint`: contains the printing functions, logos, format etc
|
||||
- `fastfetch` and `flashfetch`: Executables, that initialize the config of libffprint. Fist one at runtime, second one at compile time
|
||||
- [ ] Better OS output for all possible combinations of /etc/os-release variables.
|
||||
- [ ] Find wayland compositor by looking at \${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}
|
||||
- [ ] Make LocalIP module more configurable
|
||||
- [ ] Automatic migrate old config files to newer versions
|
||||
- [ ] ZSH completions
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
# fastfetch
|
||||
# Fastfetch
|
||||
|
||||
fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in c to achieve much better performance, in return only Linux and Android are supported. It also uses mechanisms like multithreading and caching to finish as fast as possible.
|
||||
|
||||
The output on my personal machine with default configurations looks like this:
|
||||
<img src="screenshots/example.png" alt="example output" width="100%"/>
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, BSD, MacOS and Windows on [MSYS2](https://www.msys2.org/) are supported.
|
||||
|
||||
<img src="screenshots/example1.png" width="49%" align="left" />
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||
<img src="screenshots/example4.png" width="49%" align="left" />
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
|
||||
<img src="screenshots/example2.png" width="48%" align="top" />
|
||||
<img src="screenshots/example3.png" width="48%" align="top" />
|
||||
<img src="screenshots/example5.png" height="15%" align="top" />
|
||||
|
||||
## Customization
|
||||
|
||||
@@ -11,8 +16,8 @@ With customization and speed being two competing goals, this project actually bu
|
||||
The main one being `fastfetch`, which can be very greatly configured via flags. These flags can be made persistent in `~/.config/fastfetch/config.conf`. To view the available options run `fastfetch --help`.
|
||||
The second executable being built 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).
|
||||
At the moment the performance difference is measurable, but too small to be human recognizable. But the leap will get bigger with more and more options coming, and on slow machines this might actually make a difference.
|
||||
|
||||
There are some presets defined for fastfech in [`presets`](presets), you can can load them with `--load-config`. They may also serve as a good example for format arguments.
|
||||
|
||||
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.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -37,35 +42,37 @@ The following libraries are used if present at runtime:
|
||||
[`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 rpm package count.
|
||||
* [`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.
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ).
|
||||
* [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ).
|
||||
|
||||
## Support status
|
||||
All categories not listed here should work without needing a specific implementation.
|
||||
|
||||
##### Available Modules
|
||||
```
|
||||
Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Disk, Battery, Player, Song, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
Title, Separator, OS, Host, Bios, Board, Kernel, Uptime, Processes, Packages, Shell, Resolution, DE, WM, WMTheme, Theme, Icons, Font, Cursor, Terminal, Terminal Font, CPU, CPUUsage, GPU, Memory, Swap, Disk, Battery, Power Adapter, Player, Media, Vulkan, OpenGL, OpenCL, LocalIP, PublicIP, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
```
|
||||
|
||||
##### Logos
|
||||
```
|
||||
Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, Deepin, Endeavour, Fedora, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, Manjaro, Mint, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Ubuntu, Void, Zorin
|
||||
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal, Debian, Devuan, Deepin, Endeavour, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Ubuntu, Void, Windows 11, Windows 8, Windows, Zorin
|
||||
```
|
||||
* Most of the logos have a small variant. Access it by appending _small to the logo name.
|
||||
* Some logos have an old variant. Access it by appending _old to the logo name.
|
||||
* Unknown/unsupported logos will be replaced with a generic linux logo when running fastfetch.
|
||||
* To disable the logo, use `--logo none`.
|
||||
* Get a list of all available logos with `fastfetch --print-logos`.
|
||||
* Printing images as logo is supported using Sixel or Kitty graphics protocol.
|
||||
* Printing images as logo is supported using Sixel / Kitty graphics protocol or chafas image to text conversion.
|
||||
|
||||
##### Package managers
|
||||
```
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop
|
||||
```
|
||||
|
||||
##### WM themes
|
||||
```
|
||||
KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE)
|
||||
KWin, Mutter, Muffin, Marco, XFWM, Openbox (LXDE, LXQT & without DE), Quartz Compositor (macOS), DWM (Windows)
|
||||
```
|
||||
|
||||
##### DE versions
|
||||
@@ -75,7 +82,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
|
||||
|
||||
##### Terminal fonts
|
||||
```
|
||||
konsole, gnome-terminal-server, tilix, xfce4-terminal, alacritty, lxterminal, TTY
|
||||
Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux, mintty
|
||||
```
|
||||
|
||||
## Building
|
||||
@@ -90,6 +97,12 @@ cmake --build . --target fastfetch --target flashfetch
|
||||
|
||||
If pkg-config 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 [MSYS2](https://www.msys2.org/) is required to build fastfetch. Running fastfetch requires msys2 runtime library (`msys-2.0.dll`) but not full MSYS2 environment.
|
||||
|
||||
Full native Windows executable is planned.
|
||||
|
||||
## Packaging
|
||||
|
||||
### Repositories
|
||||
|
||||
@@ -9,28 +9,39 @@ __fastfetch_complete_help()
|
||||
"os-format"
|
||||
"host-format"
|
||||
"kernel-format"
|
||||
"uptime-format"
|
||||
"processes-format"
|
||||
"packages-format"
|
||||
"shell-format"
|
||||
"resolution-format"
|
||||
"de-format"
|
||||
"wm-format"
|
||||
"wm-theme-format"
|
||||
"theme-format"
|
||||
"icons-format"
|
||||
"font-format"
|
||||
"cursor-format"
|
||||
"terminal-format"
|
||||
"terminal-font-format"
|
||||
"cpu-format"
|
||||
"cpu-usage-format"
|
||||
"gpu-format"
|
||||
"memory-format"
|
||||
"swap-format"
|
||||
"disk-format"
|
||||
"battery-format"
|
||||
"poweradapter-format"
|
||||
"locale-format"
|
||||
"local-ip-format"
|
||||
"public-ip-format"
|
||||
"player-format"
|
||||
"media-format"
|
||||
"datetime-format"
|
||||
"date-format"
|
||||
"time-format"
|
||||
"vulkan-format"
|
||||
"opengl-format"
|
||||
"opencl-format"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_helps[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
@@ -57,6 +68,41 @@ __fastfetch_complete_logo()
|
||||
COMPREPLY=($(compgen -W "$(fastfetch --list-logos-autocompletion)" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_logo_type()
|
||||
{
|
||||
local __ff_logo_types=(
|
||||
"auto"
|
||||
"builtin"
|
||||
"file"
|
||||
"raw"
|
||||
"sixel"
|
||||
"kitty"
|
||||
"chafa"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_logo_types[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_binary_prefix()
|
||||
{
|
||||
local __ff_binary_prefixes=(
|
||||
"iec"
|
||||
"si"
|
||||
"jedec"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_binary_prefixes[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_gl()
|
||||
{
|
||||
local __ff_gl_types=(
|
||||
"auto"
|
||||
"egl"
|
||||
"glx"
|
||||
"osmesa"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_gl_types[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
|
||||
__fastfetch_complete_option()
|
||||
{
|
||||
local FF_OPTIONS_ALL=(
|
||||
@@ -64,6 +110,9 @@ __fastfetch_complete_option()
|
||||
"${FF_OPTIONS_STRING[@]}"
|
||||
"${FF_OPTIONS_PATH[@]}"
|
||||
"${FF_OPTIONS_LOGO[@]}"
|
||||
"${FF_OPTIONS_LOGO_TYPE[@]}"
|
||||
"${FF_OPTIONS_BINARY_PREFIX[@]}"
|
||||
"${FF_OPTIONS_GL[@]}"
|
||||
)
|
||||
|
||||
if [[ $WORD_COUND -lt 3 ]]; then
|
||||
@@ -128,12 +177,17 @@ __fastfetch_completion()
|
||||
"--allow-slow-operations"
|
||||
"--disable-linewrap"
|
||||
"--hide-cursor"
|
||||
"--cpu-temp"
|
||||
"--gpu-temp"
|
||||
"--battery-temp"
|
||||
"--localip-show-ipv4"
|
||||
"--localip-show-ipv6"
|
||||
"--localip-show-loop"
|
||||
"--localip-name-prefix"
|
||||
"--escape-bedrock"
|
||||
"--pipe"
|
||||
"--title-fqdn"
|
||||
"--escape-bedrock"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_STRING=(
|
||||
@@ -149,134 +203,153 @@ __fastfetch_completion()
|
||||
"--logo-color-6"
|
||||
"--logo-color-7"
|
||||
"--logo-color-8"
|
||||
"--logo-width"
|
||||
"--logo-height"
|
||||
"--logo-color-9"
|
||||
"-c"
|
||||
"--color"
|
||||
"--color-keys"
|
||||
"--color-title"
|
||||
"--separator"
|
||||
"-s"
|
||||
"--structure"
|
||||
"--set"
|
||||
"--gl"
|
||||
"--os-format"
|
||||
"--set-keyless"
|
||||
"--player-name"
|
||||
"--public-ip-url"
|
||||
"--public-ip-timeout"
|
||||
"--weather-output-format"
|
||||
"--weather-timeout"
|
||||
"--os-key"
|
||||
"--host-format"
|
||||
"--os-format"
|
||||
"--os-error"
|
||||
"--host-key"
|
||||
"--kernel-format"
|
||||
"--host-format"
|
||||
"--host-error"
|
||||
"--kernel-key"
|
||||
"--uptime-format"
|
||||
"--kernel-format"
|
||||
"--kernel-error"
|
||||
"--uptime-key"
|
||||
"--processes-format"
|
||||
"--uptime-format"
|
||||
"--uptime-error"
|
||||
"--processes-key"
|
||||
"--packages-format"
|
||||
"--processes-format"
|
||||
"--processes-error"
|
||||
"--packages-key"
|
||||
"--shell-format"
|
||||
"--packages-format"
|
||||
"--packages-error"
|
||||
"--shell-key"
|
||||
"--resolution-format"
|
||||
"--shell-format"
|
||||
"--shell-error"
|
||||
"--resolution-key"
|
||||
"--de-format"
|
||||
"--resolution-format"
|
||||
"--resolution-error"
|
||||
"--de-key"
|
||||
"--wm-format"
|
||||
"--de-format"
|
||||
"--de-error"
|
||||
"--wm-key"
|
||||
"--wm-theme-format"
|
||||
"--wm-format"
|
||||
"--wm-error"
|
||||
"--wm-theme-key"
|
||||
"--theme-format"
|
||||
"--wm-theme-format"
|
||||
"--wm-theme-error"
|
||||
"--theme-key"
|
||||
"--icons-format"
|
||||
"--theme-format"
|
||||
"--theme-error"
|
||||
"--icons-key"
|
||||
"--font-format"
|
||||
"--icons-format"
|
||||
"--icons-error"
|
||||
"--font-key"
|
||||
"--cursor-format"
|
||||
"--font-format"
|
||||
"--font-error"
|
||||
"--cursor-key"
|
||||
"--terminal-format"
|
||||
"--cursor-format"
|
||||
"--cursor-error"
|
||||
"--terminal-key"
|
||||
"--terminal-font-format"
|
||||
"--terminal-format"
|
||||
"--terminal-error"
|
||||
"--terminal-font-key"
|
||||
"--cpu-format"
|
||||
"--terminal-font-format"
|
||||
"--terminal-font-error"
|
||||
"--cpu-key"
|
||||
"--cpu-usage-format"
|
||||
"--cpu-usage-key"
|
||||
"--gpu-format"
|
||||
"--cpu-format"
|
||||
"--cpu-error"
|
||||
"--cpu-useage-key"
|
||||
"--cpu-useage-format"
|
||||
"--cpu-useage-error"
|
||||
"--gpu-key"
|
||||
"--memory-format"
|
||||
"--gpu-format"
|
||||
"--gpu-error"
|
||||
"--memory-key"
|
||||
"--memory-format"
|
||||
"--memory-error"
|
||||
"--swap-key"
|
||||
"--swap-format"
|
||||
"--swap-error"
|
||||
"--disk-key"
|
||||
"--disk-format"
|
||||
"--disk-key"
|
||||
"--battery-format"
|
||||
"--disk-error"
|
||||
"--battery-key"
|
||||
"--locale-format"
|
||||
"--battery-format"
|
||||
"--battery-error"
|
||||
"--poweradapter-key"
|
||||
"--poweradapter-format"
|
||||
"--poweradapter-error"
|
||||
"--locale-key"
|
||||
"--disk-folders"
|
||||
"--disk-key"
|
||||
"--local-ip-format"
|
||||
"--locale-format"
|
||||
"--locale-error"
|
||||
"--local-ip-key"
|
||||
"--public-ip-format"
|
||||
"--local-ip-format"
|
||||
"--local-ip-error"
|
||||
"--public-ip-key"
|
||||
"--player-format"
|
||||
"--public-ip-format"
|
||||
"--public-ip-error"
|
||||
"--weather-key"
|
||||
"--weather-format"
|
||||
"--weather-error"
|
||||
"--player-key"
|
||||
"--song-format"
|
||||
"--song-key"
|
||||
"--player-format"
|
||||
"--player-error"
|
||||
"--media-key"
|
||||
"--media-format"
|
||||
"--media-error"
|
||||
"--datetime-key"
|
||||
"--datetime-format"
|
||||
"--date-format"
|
||||
"--datetime-error"
|
||||
"--date-key"
|
||||
"--time-format"
|
||||
"--date-format"
|
||||
"--date-error"
|
||||
"--time-key"
|
||||
"--time-format"
|
||||
"--time-error"
|
||||
"--vulkan-key"
|
||||
"--vulkan-format"
|
||||
"--vulkan-error"
|
||||
"--opengl-key"
|
||||
"--opengl-format"
|
||||
"--opengl-error"
|
||||
"--opencl-key"
|
||||
"--opencl-format"
|
||||
"--os-error"
|
||||
"--host-error"
|
||||
"--kernel-error"
|
||||
"--uptime-error"
|
||||
"--processes-error"
|
||||
"--packages-error"
|
||||
"--shell-error"
|
||||
"--resolution-error"
|
||||
"--de-error"
|
||||
"--wm-error"
|
||||
"--wm-theme-error"
|
||||
"--theme-error"
|
||||
"--icons-error"
|
||||
"--font-error"
|
||||
"--cursor-error"
|
||||
"--terminal-error"
|
||||
"--terminal-font-error"
|
||||
"--cpu-error"
|
||||
"--cpu-usage-error"
|
||||
"--gpu-error"
|
||||
"--memory-error"
|
||||
"--disk-error"
|
||||
"--battery-error"
|
||||
"--locale-error"
|
||||
"--disk-error"
|
||||
"--local-ip-error"
|
||||
"--public-ip-error"
|
||||
"--player-error"
|
||||
"--song-error"
|
||||
"--datetime-error"
|
||||
"--date-error"
|
||||
"--time-error"
|
||||
"--vulkan-error"
|
||||
"--opengl-error"
|
||||
"--opencl-error"
|
||||
"--users-key"
|
||||
"--users-format"
|
||||
"--users-error"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_PATH=(
|
||||
"--load-config"
|
||||
"--os-file"
|
||||
"--lib-PCI"
|
||||
"--lib-pci"
|
||||
"--lib-vulkan"
|
||||
"--lib-wayland"
|
||||
"--lib-xcb-randr"
|
||||
"--lib-xcb"
|
||||
"--lib-Xrandr"
|
||||
"--lib-xrandr"
|
||||
"--lib-X11"
|
||||
"--lib-gio"
|
||||
"--lib-DConf"
|
||||
"--lib-DBus"
|
||||
"--lib-XFConf"
|
||||
"--lib-dconf"
|
||||
"--lib-dbus"
|
||||
"--lib-xfconf"
|
||||
"--lib-sqlite3"
|
||||
"--lib-rpm"
|
||||
"--lib-imagemagick"
|
||||
@@ -287,7 +360,6 @@ __fastfetch_completion()
|
||||
"--lib-osmesa"
|
||||
"--lib-opencl"
|
||||
"--battery-dir"
|
||||
"--load-config"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_LOGO=(
|
||||
@@ -295,6 +367,18 @@ __fastfetch_completion()
|
||||
"--logo"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_LOGO_TYPE=(
|
||||
"--logo-type"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_BINARY_PREFIX=(
|
||||
"--binary-prefix"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_GL=(
|
||||
"--gl"
|
||||
)
|
||||
|
||||
if __fastfetch_previous_matches "${FF_OPTIONS_SINGLE[@]}"; then
|
||||
return
|
||||
elif [[ $WORD_COUND -gt 3 && ( ${COMP_WORDS[$COMP_CWORD - 2]} == "--help" || ${COMP_WORDS[$COMP_CWORD - 2]} == "-h" ) ]]; then
|
||||
@@ -311,6 +395,12 @@ __fastfetch_completion()
|
||||
__fastfetch_complete_path
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_LOGO[@]}"; then
|
||||
__fastfetch_complete_logo
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_LOGO_TYPE[@]}"; then
|
||||
__fastfetch_complete_logo_type
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_BINARY_PREFIX[@]}"; then
|
||||
__fastfetch_complete_binary_prefix
|
||||
elif __fastfetch_previous_matches "${FF_OPTIONS_GL[@]}"; then
|
||||
__fastfetch_complete_gl
|
||||
else
|
||||
__fastfetch_complete_option
|
||||
fi
|
||||
|
||||
@@ -1 +1 @@
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Break:Colors
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--disable-linewrap false
|
||||
--multithreading false
|
||||
--show-errors true
|
||||
--show-errors
|
||||
--recache
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
--load-config verbose
|
||||
--load-config devinfo
|
||||
--load-config all
|
||||
--load-config verbose
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# Load with --load-config examples/1
|
||||
@@ -0,0 +1,24 @@
|
||||
# Load with --load-config examples/2
|
||||
# Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
--kitty /home/linus/Bilder/Gentoo.png
|
||||
--logo-width 28
|
||||
|
||||
--separator " "
|
||||
|
||||
--set-keyless HardwareStart=┌───────── \e[1mHardware Information\e[0m ─────────┐
|
||||
--set-keyless SoftwareStart=├───────── \e[1mSoftware Information\e[0m ─────────┤
|
||||
--set-keyless InformationEnd=└────────────────────────────────────────┘
|
||||
--set-keyless Colors= \e[38m \e[37m \e[36m \e[35m \e[34m \e[33m \e[32m \e[31m
|
||||
--structure HardwareStart:Host:CPU:GPU:SoftwareStart:OS:Kernel:WM:Shell:Terminal:TerminalFont:Packages:InformationEnd:Colors
|
||||
|
||||
--host-key " "
|
||||
--cpu-key " "
|
||||
--gpu-key " "
|
||||
--os-key " "
|
||||
--kernel-key " "
|
||||
--wm-key " "
|
||||
--shell-key " "
|
||||
--terminal-key " "
|
||||
--terminal-font-key " "
|
||||
--packages-key " "
|
||||
@@ -0,0 +1,7 @@
|
||||
# Load with --load-config example/3
|
||||
|
||||
--logo debian_small
|
||||
--structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP
|
||||
--binary-prefix si
|
||||
--localip-show-loop false
|
||||
--disk-folders /:/home:/boot:/efi
|
||||
@@ -0,0 +1,7 @@
|
||||
# Load with --load-config examples/4
|
||||
|
||||
--color blue
|
||||
--logo arch_small
|
||||
--logo-padding-right 1
|
||||
--separator " "
|
||||
--structure Date:Time:Break:Player:Media
|
||||
@@ -0,0 +1,11 @@
|
||||
# Load with --load-config examples/5
|
||||
|
||||
--logo none
|
||||
--color reset_magenta
|
||||
--structure Theme:Icons:Font:Cursor
|
||||
--theme-key T
|
||||
--theme-format {7}
|
||||
--icons-key I
|
||||
--icons-format {5}
|
||||
--font-key F
|
||||
--cursor-key C
|
||||
@@ -1,4 +1,4 @@
|
||||
--structure Host:Resolution:CPU:GPU:Memory:Disk:Battery
|
||||
--memory-format "{?2}{2}MiB{?}"
|
||||
--disk-format "{?2}{2}GB{?}"
|
||||
--memory-format "{?2}{2}{?}"
|
||||
--disk-format "{?2}{2}{?}"
|
||||
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
--de-format "{2} {3}"
|
||||
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
--terminal-font-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{}MiB / {}MiB"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
||||
--gpu-key "GPU"
|
||||
--resolution-key "Resolution"
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
--load-config all
|
||||
|
||||
--os-format "System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}"
|
||||
--host-format "Family: "product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {}"
|
||||
--kernel-format "Sysname: {}; Release: {}; Version: {}"
|
||||
--uptime-format "Days: {}; Hours: {}; Minutes: {}; Seconds: {}"
|
||||
--processes-format "Count: {}"
|
||||
--packages-format "All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; flatpak: {}; snap: {}"
|
||||
--shell-format "Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}"
|
||||
--resolution-format "Width: {}; Height: {}; Refresh rate: {}"
|
||||
--de-format "Process name: {}; Pretty name: {}; Version: {}"
|
||||
--wm-format "Process name: {}; Pretty name: {}; Protocol: {}"
|
||||
--wm-theme-format "Name: {}"
|
||||
--theme-format "Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}"
|
||||
--icons-format "Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}"
|
||||
--font-format "Plasma raw: {}; Plasma name: {}; Plasma size: {}; Plasma styles: {}; Plasma pretty: {}; GTK2 raw: {}; GTK2 name: {}; GTK2 size: {}; GTK2 styles: {}; GTK2 pretty: {}; GTK3 raw: {}; GTK3 name: {}; GTK3 size: {}; GTK3 styles: {}; GTK3 pretty: {}; GTK4 raw: {}; GTK4 name: {}; GTK4 size: {}; GTK4 styles: {}; GTK4 pretty: {}; GTK: {}"
|
||||
--cursor-format "Theme: {}; Size: {}"
|
||||
--terminal-format "Process: {}; Path: {}; Exe: {}"
|
||||
--terminal-font-format "Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}"
|
||||
--cpu-format "Name: {}; Pretty: {}; Vendor: {}; Logical online: {}; Logical configured: {}; Physical: {}; Cores: {}; temperature: {}; bios: {}; scaling max: {}; scaling min: {}; info max: {}; info min: {}; cpuinfo: {}; frequency: {}"
|
||||
--cpu-usage-format "Percentage: {}"
|
||||
--gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}; Temperature: {}"
|
||||
--memory-format "Used: {}; Total: {}; Percentage: {}"
|
||||
--disk-format "Used: {}; Total: {}; Files: {}; Percentage: {}"
|
||||
--battery-format "Manufactor: {}; Model: {}; Technology: {}; Capacaty: {}; Status: {}"
|
||||
--player-format "Name: {}"
|
||||
--song-format "Song: {}; Artist: {}; Album: {}"
|
||||
--datetime-format "year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}"
|
||||
--vulkan-format "driver: {}; Api Version: {}; Conformance Version: {}"
|
||||
--opengl-format "version: {}; renderer: {}; vendor: {}"
|
||||
--opencl-format "version: {}; device: {}; vendor: {}"
|
||||
--os-format System: {}; Name: {}; Pretty name: {}; ID: {}; ID like: {}; Variant: {}; Variant ID: {}; Version: {}; Version ID: {}; Version codename: {}; Build ID: {}; Architecture: {}
|
||||
--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; bios_date: {}; bios_release: {}; bios_vendor: {}; bios_version: {}; board_name: {}; board_vendor: {}; board_version: {}; chassis_type: {}; chassis_vendor: {}; chassis_version: {}; sys_vendor: {}
|
||||
--kernel-format Sysname: {}; Release: {}; Version: {}
|
||||
--uptime-format Days: {}; Hours: {}; Minutes: {}; Seconds: {}
|
||||
--processes-format Count: {}
|
||||
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}
|
||||
--shell-format Process name: {}; Process path: {}; Process exe: {}; Process version: {}; User path: {}; User exe: {}; User version: {}
|
||||
--resolution-format Width: {}; Height: {}; Refresh rate: {}
|
||||
--de-format Process name: {}; Pretty name: {}; Version: {}
|
||||
--wm-format Process name: {}; Pretty name: {}; Protocol: {}
|
||||
--wm-theme-format Name: {}
|
||||
--theme-format Plasma: {}; Plasma colors: {}; Plasma colors pretty: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--icons-format Plasma: {}; GTK2: {}; GTK3: {}; GTK4: {}; GTK: {}
|
||||
--font-format Font1: {}; Font2: {}; Font3: {}; Font4: {}
|
||||
--cursor-format Theme: {}; Size: {}
|
||||
--terminal-format Process: {}; Path: {}; Exe: {}
|
||||
--terminal-font-format Pretty: {}; Name: {}; Size: {}; Styles: {}
|
||||
--cpu-format Name: {}, Vendor: {}, CoresPhysical: {}, CoresLogical: {}, CoresOnline: {}, FrequencyMin: {}, FrequencyMax: {}, Temperature: {}
|
||||
--cpu-usage-format Percentage: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
|
||||
--memory-format Used: {}; Total: {}; Percentage: {}
|
||||
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
|
||||
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
|
||||
--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {}
|
||||
--player-format Pretty: {}; Name: {}; Bus: {}; Url: {}
|
||||
--media-format Pretty: {}; Name: {}; Artist: {}; Album: {}
|
||||
--datetime-format year: {}; yearShort: {}; month: {}; monthPretty: {}; monthName: {}; monthNameShort: {}; weekNumber: {}; weekday: {}; weekdayShort: {}; dayInYear: {}; dayInMonth: {}; dayInWeek: {}; hour: {}; hourPretty: {}; hour12: {}; hour12Pretty: {}; minute: {}; minutePretty: {}; second: {}; secondPretty: {}
|
||||
--vulkan-format driver: {}; Api Version: {}; Conformance Version: {}
|
||||
--opengl-format version: {}; renderer: {}; vendor: {}
|
||||
--opencl-format version: {}; device: {}; vendor: {}
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
#!/bin/env sh
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# make the script exit if any of the commands fail,
|
||||
# making fastfetch not run if the build failed.
|
||||
set -e
|
||||
|
||||
mkdir -p build/
|
||||
cd build/
|
||||
cmake ..
|
||||
cmake --build . --target fastfetch -j$(nproc)
|
||||
|
||||
if [ -z "${CMAKE_BUILD_TYPE}" ]; then
|
||||
CMAKE_BUILD_TYPE=Release
|
||||
fi
|
||||
cmake "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ..
|
||||
|
||||
if [ -z "$OSTYPE" ] || [ "$OSTYPE" = "linux-gnu" ]; then
|
||||
cmake_build_args="-j$(nproc)"
|
||||
elif [ "$OSTYPE" = "darwin" ]; then
|
||||
cmake_build_args="-j$(sysctl -n hw.ncpu)"
|
||||
else
|
||||
cmake_build_args=""
|
||||
fi
|
||||
cmake --build . --target fastfetch ${cmake_build_args}
|
||||
|
||||
./fastfetch "$@"
|
||||
|
||||
|
Before Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 133 KiB |
@@ -4,11 +4,15 @@
|
||||
#include "common/printing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FF_CACHE_VERSION_NAME "cacheversion"
|
||||
#define FF_CACHE_VERSION_EXTENSION "ffv"
|
||||
|
||||
#define FF_CACHE_VALUE_EXTENSION "ffcv"
|
||||
#define FF_CACHE_SPLIT_EXTENSION "ffcs"
|
||||
|
||||
#define FF_CACHE_EXTENSION_DATA "ffcd"
|
||||
#define FF_CACHE_EXTENSION_V1 "ffc1"
|
||||
|
||||
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
@@ -44,9 +48,11 @@ void ffCacheValidate(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInit(&content);
|
||||
readCacheFile(instance, "cacheversion", "ffv", &content);
|
||||
readCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &content);
|
||||
|
||||
bool isSameVersion = ffStrbufCompS(&content, FASTFETCH_PROJECT_VERSION) == 0;
|
||||
const char exactVersion[] = FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK;
|
||||
|
||||
bool isSameVersion = ffStrbufCompS(&content, exactVersion) == 0;
|
||||
ffStrbufDestroy(&content);
|
||||
if(isSameVersion)
|
||||
return;
|
||||
@@ -54,9 +60,9 @@ void ffCacheValidate(FFinstance* instance)
|
||||
instance->config.recache = true;
|
||||
|
||||
FFstrbuf version;
|
||||
ffStrbufInitA(&version, sizeof(FASTFETCH_PROJECT_VERSION));
|
||||
ffStrbufAppendS(&version, FASTFETCH_PROJECT_VERSION);
|
||||
writeCacheFile(instance, "cacheversion", "ffv", &version);
|
||||
ffStrbufInitA(&version, sizeof(exactVersion));
|
||||
ffStrbufAppendS(&version, exactVersion);
|
||||
writeCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &version);
|
||||
ffStrbufDestroy(&version);
|
||||
}
|
||||
|
||||
@@ -93,7 +99,10 @@ static bool printCachedValue(FFinstance* instance, const char* moduleName, const
|
||||
ffStrbufTrimRight(&content, '\0'); //Strbuf always appends a '\0' at the end. We want the last null byte to be at the position of the length
|
||||
|
||||
if(content.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&content);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t moduleCounter = 1;
|
||||
|
||||
@@ -206,24 +215,113 @@ void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const
|
||||
ffCacheClose(&cache);
|
||||
}
|
||||
|
||||
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data)
|
||||
typedef struct FFCacheRead
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
|
||||
ffWriteFileData(path.chars, dataSize, data);
|
||||
ffStrbufDestroy(&path);
|
||||
FFstrbuf data;
|
||||
uint32_t position;
|
||||
} FFCacheRead;
|
||||
|
||||
static bool cacheReadStrbuf(FFCacheRead* cacheRead, FFstrbuf* strbuf)
|
||||
{
|
||||
if(cacheRead->position >= cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(strbuf, cacheRead->data.chars + cacheRead->position);
|
||||
cacheRead->position += strbuf->length + 1; // skip the null byte too
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data)
|
||||
static bool cacheReadData(FFCacheRead* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
if(cacheRead->position + dataSize > cacheRead->data.length)
|
||||
return false;
|
||||
|
||||
memcpy(data, cacheRead->data.chars + cacheRead->position, dataSize);
|
||||
cacheRead->position += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetStrbuf(FFCache* cache, FFstrbuf* strbuf)
|
||||
{
|
||||
FF_UNUSED(cache);
|
||||
ffStrbufClear(strbuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheResetData(FFCache* cacheRead, size_t dataSize, void* data)
|
||||
{
|
||||
FF_UNUSED(cacheRead, dataSize, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(instance->config.recache)
|
||||
return false;
|
||||
|
||||
FFCacheRead cache;
|
||||
bool result;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_EXTENSION_DATA, &path);
|
||||
ssize_t result = ffReadFileData(path.chars, dataSize, data);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
cache.position = 0;
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
result = ffAppendFileBuffer(path.chars, &cache.data);
|
||||
|
||||
if(result)
|
||||
result = callback(obj, &cache, (FFCacheMethodStrbuf) cacheReadStrbuf, (FFCacheMethodData) cacheReadData);
|
||||
|
||||
if(result)
|
||||
result = cache.position == cache.data.length;
|
||||
|
||||
if(!result)
|
||||
callback(obj, NULL, (FFCacheMethodStrbuf) cacheResetStrbuf, (FFCacheMethodData) cacheResetData);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct FFCacheWrite
|
||||
{
|
||||
FFstrbuf data;
|
||||
} FFCacheWrite;
|
||||
|
||||
static bool cacheWriteStrbuf(FFCacheWrite* cacheWrite, FFstrbuf* strbuf)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, strbuf->length);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, strbuf->chars, strbuf->length +1); //Copy the nullbyte too
|
||||
cacheWrite->data.length += strbuf->length + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cacheWriteData(FFCacheWrite* cacheWrite, size_t dataSize, const void* data)
|
||||
{
|
||||
ffStrbufEnsureFree(&cacheWrite->data, (uint32_t) dataSize);
|
||||
memcpy(cacheWrite->data.chars + cacheWrite->data.length, data, dataSize);
|
||||
cacheWrite->data.length += (uint32_t) dataSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback)
|
||||
{
|
||||
if(!instance->config.cacheSave)
|
||||
return;
|
||||
|
||||
FFCacheWrite cache;
|
||||
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 128);
|
||||
getCacheFilePath(instance, cacheName, FF_CACHE_EXTENSION_V1, &path);
|
||||
|
||||
ffStrbufInitA(&cache.data, 256);
|
||||
callback(obj, &cache, (FFCacheMethodStrbuf) cacheWriteStrbuf, (FFCacheMethodData) cacheWriteData);
|
||||
ffWriteFileBuffer(path.chars, &cache.data);
|
||||
|
||||
ffStrbufDestroy(&cache.data);
|
||||
ffStrbufDestroy(&path);
|
||||
return result > 0 && (size_t) result == dataSize;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,13 @@ bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModu
|
||||
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
void ffCachingWriteData(const FFinstance* instance, const char* moduleName, size_t dataSize, const void* data);
|
||||
bool ffCachingReadData(const FFinstance* instance, const char* moduleName, size_t dataSize, void* data);
|
||||
typedef void FFCache;
|
||||
|
||||
typedef bool(*FFCacheMethodStrbuf)(FFCache* cache, FFstrbuf* strbuf);
|
||||
typedef bool(*FFCacheMethodData)(FFCache* cache, size_t dataSize, void* data);
|
||||
typedef bool(*FFCacheMethodCallback)(void* data, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod);
|
||||
|
||||
bool ffCacheRead(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
void ffCacheWrite(const FFinstance* instance, void* obj, const char* cacheName, FFCacheMethodCallback callback);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -204,6 +204,23 @@ void ffFontInitCopy(FFfont* font, const char* name)
|
||||
ffFontInitValues(font, name, NULL);
|
||||
}
|
||||
|
||||
void ffFontInitWithSpace(FFfont* font, const char* rawName)
|
||||
{
|
||||
const char* pspace = strrchr(rawName, ' ');
|
||||
if(pspace == NULL)
|
||||
{
|
||||
ffFontInitCopy(font, rawName);
|
||||
return;
|
||||
}
|
||||
|
||||
fontInit(font);
|
||||
|
||||
ffStrbufAppendNS(&font->name, (uint32_t)(pspace - rawName), rawName);
|
||||
ffStrbufAppendS(&font->size, pspace + 1);
|
||||
|
||||
fontInitPretty(font);
|
||||
}
|
||||
|
||||
void ffFontDestroy(FFfont* font)
|
||||
{
|
||||
ffStrbufDestroy(&font->pretty);
|
||||
|
||||
@@ -18,6 +18,7 @@ void ffFontInitQt(FFfont* font, const char* data);
|
||||
void ffFontInitPango(FFfont* font, const char* data);
|
||||
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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
#include "common/parsing.h"
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
{
|
||||
@@ -54,20 +55,21 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
|
||||
|
||||
static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placeholder, uint32_t* argCounter, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(*argCounter > numArgs)
|
||||
if(*argCounter >= numArgs)
|
||||
ffStrbufAppendS(buffer, placeholder);
|
||||
else
|
||||
ffFormatAppendFormatArg(buffer, &arguments[(*argCounter)++]);
|
||||
ffFormatAppendFormatArg(buffer, arguments + *argCounter);
|
||||
|
||||
(*argCounter)++;
|
||||
}
|
||||
|
||||
static inline bool formatArgSet(const FFformatarg* arg)
|
||||
{
|
||||
return arg->value != NULL && (
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value == *(double*)arg->value) || //NaN
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) || //Also is false for NaN
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_INT && *(int*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && *(const char*)arg->value != '\0') ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "common/parsing.h"
|
||||
#include "detection/qt.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "detection/displayserver.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -31,7 +31,10 @@ static void initConfigDirs(FFstate* state)
|
||||
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \
|
||||
--state->configDirs.length;
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
|
||||
--state->configDirs.length; \
|
||||
}
|
||||
|
||||
FFstrbuf* userConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(userConfigHome, 64);
|
||||
@@ -69,15 +72,16 @@ static void initConfigDirs(FFstate* state)
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
ffStrbufDestroy(&xdgConfigDirs);
|
||||
|
||||
FFstrbuf* systemConfigHome = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfigHome, 64);
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ROOT"/etc/xdg/");
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome)
|
||||
|
||||
FFstrbuf* systemConfig = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfig, 64);
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ROOT"/etc/");
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfig)
|
||||
|
||||
#undef FF_ENSURE_ONLY_ONCE_IN_LIST
|
||||
@@ -110,7 +114,10 @@ static void initState(FFstate* state)
|
||||
state->keysHeight = 0;
|
||||
state->passwd = getpwuid(getuid());
|
||||
uname(&state->utsname);
|
||||
sysinfo(&state->sysinfo);
|
||||
|
||||
#if FF_HAVE_SYSINFO_H
|
||||
sysinfo(&state->sysinfo);
|
||||
#endif
|
||||
|
||||
initConfigDirs(state);
|
||||
initCacheDir(state);
|
||||
@@ -125,7 +132,7 @@ static void initModuleArg(FFModuleArgs* args)
|
||||
|
||||
static void defaultConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufInit(&instance->config.logo.source);
|
||||
ffStrbufInitA(&instance->config.logo.source, 0);
|
||||
instance->config.logo.type = FF_LOGO_TYPE_AUTO;
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufInit(&instance->config.logo.colors[i]);
|
||||
@@ -135,7 +142,9 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.logo.paddingRight = 4;
|
||||
instance->config.logo.printRemaining = true;
|
||||
|
||||
ffStrbufInit(&instance->config.mainColor);
|
||||
ffStrbufInit(&instance->config.colorKeys);
|
||||
ffStrbufInit(&instance->config.colorTitle);
|
||||
|
||||
ffStrbufInit(&instance->config.separator);
|
||||
ffStrbufAppendS(&instance->config.separator, ": ");
|
||||
|
||||
@@ -146,12 +155,15 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.disableLinewrap = true;
|
||||
instance->config.hideCursor = true;
|
||||
instance->config.escapeBedrock = true;
|
||||
instance->config.binaryPrefixType = FF_BINARY_PREFIX_TYPE_IEC;
|
||||
instance->config.glType = FF_GL_TYPE_AUTO;
|
||||
instance->config.pipe = false;
|
||||
instance->config.multithreading = true;
|
||||
|
||||
initModuleArg(&instance->config.os);
|
||||
initModuleArg(&instance->config.host);
|
||||
initModuleArg(&instance->config.bios);
|
||||
initModuleArg(&instance->config.board);
|
||||
initModuleArg(&instance->config.kernel);
|
||||
initModuleArg(&instance->config.uptime);
|
||||
initModuleArg(&instance->config.processes);
|
||||
@@ -171,11 +183,14 @@ static void defaultConfig(FFinstance* instance)
|
||||
initModuleArg(&instance->config.cpuUsage);
|
||||
initModuleArg(&instance->config.gpu);
|
||||
initModuleArg(&instance->config.memory);
|
||||
initModuleArg(&instance->config.swap);
|
||||
initModuleArg(&instance->config.disk);
|
||||
initModuleArg(&instance->config.battery);
|
||||
initModuleArg(&instance->config.powerAdapter);
|
||||
initModuleArg(&instance->config.locale);
|
||||
initModuleArg(&instance->config.localIP);
|
||||
initModuleArg(&instance->config.publicIP);
|
||||
initModuleArg(&instance->config.weather);
|
||||
initModuleArg(&instance->config.player);
|
||||
initModuleArg(&instance->config.song);
|
||||
initModuleArg(&instance->config.dateTime);
|
||||
@@ -184,6 +199,7 @@ static void defaultConfig(FFinstance* instance)
|
||||
initModuleArg(&instance->config.vulkan);
|
||||
initModuleArg(&instance->config.openGL);
|
||||
initModuleArg(&instance->config.openCL);
|
||||
initModuleArg(&instance->config.users);
|
||||
|
||||
ffStrbufInitA(&instance->config.libPCI, 0);
|
||||
ffStrbufInitA(&instance->config.libVulkan, 0);
|
||||
@@ -205,10 +221,17 @@ static void defaultConfig(FFinstance* instance)
|
||||
ffStrbufInitA(&instance->config.libGLX, 0);
|
||||
ffStrbufInitA(&instance->config.libOSMesa, 0);
|
||||
ffStrbufInitA(&instance->config.libOpenCL, 0);
|
||||
ffStrbufInitA(&instance->config.libcJSON, 0);
|
||||
ffStrbufInitA(&instance->config.libfreetype, 0);
|
||||
|
||||
instance->config.cpuTemp = false;
|
||||
instance->config.gpuTemp = false;
|
||||
instance->config.batteryTemp = false;
|
||||
|
||||
instance->config.titleFQDN = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.diskFolders, 0);
|
||||
instance->config.diskRemovable = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.batteryDir, 0);
|
||||
|
||||
@@ -217,8 +240,13 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.localIpShowIpV4 = true;
|
||||
instance->config.localIpShowIpV6 = false;
|
||||
instance->config.localIpShowLoop = false;
|
||||
ffStrbufInit(&instance->config.localIpNamePrefix);
|
||||
|
||||
instance->config.publicIpTimeout = 0;
|
||||
ffStrbufInit(&instance->config.publicIpUrl);
|
||||
|
||||
instance->config.weatherTimeout = 0;
|
||||
ffStrbufInitS(&instance->config.weatherOutputFormat, "%t+-+%C+(%l)");
|
||||
|
||||
ffStrbufInitA(&instance->config.osFile, 0);
|
||||
|
||||
@@ -231,37 +259,41 @@ void ffInitInstance(FFinstance* instance)
|
||||
defaultConfig(instance);
|
||||
}
|
||||
|
||||
static inline void* detectPlasmaThreadMain(void* instance)
|
||||
{
|
||||
ffDetectQt((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__)
|
||||
|
||||
static inline void* detectGTK2ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK2((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void* detectGTK3ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK3((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void* detectGTK4ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK4((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void* connectDisplayServerThreadMain(void* instance)
|
||||
static void* connectDisplayServerThreadMain(void* instance)
|
||||
{
|
||||
ffConnectDisplayServer((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void* startThreadsThreadMain(void* instance)
|
||||
#if !defined(__APPLE__)
|
||||
|
||||
static void* detectPlasmaThreadMain(void* instance)
|
||||
{
|
||||
ffDetectQt((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK2ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK2((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK3ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK3((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* detectGTK4ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK4((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* startThreadsThreadMain(void* instance)
|
||||
{
|
||||
pthread_t dsThread;
|
||||
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
@@ -288,18 +320,27 @@ static inline void* startThreadsThreadMain(void* instance)
|
||||
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
//Android needs none of the things that are detected here
|
||||
//And using gsettings sometimes hangs the program in android for some unknown reason,
|
||||
//and since we don't need it we just never call it.
|
||||
#ifdef __ANDROID__
|
||||
return;
|
||||
#endif
|
||||
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
|
||||
#else // !__APPLE__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
#else // !__ANDROID__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
}
|
||||
#endif // __ANDROID__
|
||||
|
||||
static volatile bool ffDisableLinewrap = true;
|
||||
static volatile bool ffHideCursor = true;
|
||||
|
||||
@@ -359,6 +400,111 @@ void ffFinish(FFinstance* instance)
|
||||
resetConsole();
|
||||
}
|
||||
|
||||
static void destroyModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufDestroy(&args->key);
|
||||
ffStrbufDestroy(&args->outputFormat);
|
||||
ffStrbufDestroy(&args->errorFormat);
|
||||
}
|
||||
|
||||
static void destroyConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufDestroy(&instance->config.logo.source);
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufDestroy(&instance->config.logo.colors[i]);
|
||||
ffStrbufDestroy(&instance->config.colorKeys);
|
||||
ffStrbufDestroy(&instance->config.colorTitle);
|
||||
ffStrbufDestroy(&instance->config.separator);
|
||||
|
||||
destroyModuleArg(&instance->config.os);
|
||||
destroyModuleArg(&instance->config.host);
|
||||
destroyModuleArg(&instance->config.bios);
|
||||
destroyModuleArg(&instance->config.board);
|
||||
destroyModuleArg(&instance->config.kernel);
|
||||
destroyModuleArg(&instance->config.uptime);
|
||||
destroyModuleArg(&instance->config.processes);
|
||||
destroyModuleArg(&instance->config.packages);
|
||||
destroyModuleArg(&instance->config.shell);
|
||||
destroyModuleArg(&instance->config.resolution);
|
||||
destroyModuleArg(&instance->config.de);
|
||||
destroyModuleArg(&instance->config.wm);
|
||||
destroyModuleArg(&instance->config.wmTheme);
|
||||
destroyModuleArg(&instance->config.theme);
|
||||
destroyModuleArg(&instance->config.icons);
|
||||
destroyModuleArg(&instance->config.font);
|
||||
destroyModuleArg(&instance->config.cursor);
|
||||
destroyModuleArg(&instance->config.terminal);
|
||||
destroyModuleArg(&instance->config.terminalFont);
|
||||
destroyModuleArg(&instance->config.cpu);
|
||||
destroyModuleArg(&instance->config.cpuUsage);
|
||||
destroyModuleArg(&instance->config.gpu);
|
||||
destroyModuleArg(&instance->config.memory);
|
||||
destroyModuleArg(&instance->config.swap);
|
||||
destroyModuleArg(&instance->config.disk);
|
||||
destroyModuleArg(&instance->config.battery);
|
||||
destroyModuleArg(&instance->config.powerAdapter);
|
||||
destroyModuleArg(&instance->config.locale);
|
||||
destroyModuleArg(&instance->config.localIP);
|
||||
destroyModuleArg(&instance->config.publicIP);
|
||||
destroyModuleArg(&instance->config.weather);
|
||||
destroyModuleArg(&instance->config.player);
|
||||
destroyModuleArg(&instance->config.song);
|
||||
destroyModuleArg(&instance->config.dateTime);
|
||||
destroyModuleArg(&instance->config.date);
|
||||
destroyModuleArg(&instance->config.time);
|
||||
destroyModuleArg(&instance->config.vulkan);
|
||||
destroyModuleArg(&instance->config.openGL);
|
||||
destroyModuleArg(&instance->config.openCL);
|
||||
destroyModuleArg(&instance->config.users);
|
||||
|
||||
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.libcJSON);
|
||||
ffStrbufDestroy(&instance->config.libfreetype);
|
||||
|
||||
ffStrbufDestroy(&instance->config.diskFolders);
|
||||
ffStrbufDestroy(&instance->config.batteryDir);
|
||||
ffStrbufDestroy(&instance->config.separatorString);
|
||||
ffStrbufDestroy(&instance->config.localIpNamePrefix);
|
||||
ffStrbufDestroy(&instance->config.publicIpUrl);
|
||||
ffStrbufDestroy(&instance->config.weatherOutputFormat);
|
||||
ffStrbufDestroy(&instance->config.osFile);
|
||||
ffStrbufDestroy(&instance->config.playerName);
|
||||
}
|
||||
|
||||
static void destroyState(FFinstance* instance)
|
||||
{
|
||||
for(uint32_t i = 0; i < instance->state.configDirs.length; ++i)
|
||||
ffStrbufDestroy((FFstrbuf*)ffListGet(&instance->state.configDirs, i));
|
||||
ffListDestroy(&instance->state.configDirs);
|
||||
|
||||
ffStrbufDestroy(&instance->state.cacheDir);
|
||||
}
|
||||
|
||||
void ffDestroyInstance(FFinstance* instance)
|
||||
{
|
||||
destroyConfig(instance);
|
||||
destroyState(instance);
|
||||
}
|
||||
|
||||
//Must be in a file compiled with the libfastfetch target, because the FF_HAVE* macros are not defined for the executable targets
|
||||
void ffListFeatures()
|
||||
{
|
||||
@@ -426,6 +572,12 @@ void ffListFeatures()
|
||||
#ifdef FF_HAVE_OPENCL
|
||||
"opencl\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_LIBCJSON
|
||||
"libcjson\n"
|
||||
#endif
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
"freetype"
|
||||
#endif
|
||||
""
|
||||
, stdout);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ static void createSubfolders(const char* fileName)
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
|
||||
bool ffWriteFDBuffer(int fd, const FFstrbuf* content)
|
||||
{
|
||||
return write(fd, content->chars, content->length) != -1;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#ifndef FF_INCLUDED_common_io
|
||||
#define FF_INCLUDED_common_io
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <sys/types.h> //mode_t
|
||||
|
||||
bool ffWriteFDBuffer(int fd, const FFstrbuf* content);
|
||||
@@ -19,6 +21,6 @@ bool ffFileExists(const char* fileName, mode_t mode);
|
||||
// Not thread safe!
|
||||
void ffSuppressIO(bool suppress);
|
||||
|
||||
void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
FF_C_SCANF(2, 3) void ffGetTerminalResponse(const char* request, const char* format, ...);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,10 +3,31 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
//Clang doesn't define __SANITIZE_ADDRESS__ but defines __has_feature(address_sanitizer)
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#define __SANITIZE_ADDRESS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#endif
|
||||
|
||||
static void* libraryLoad(const char* path, int maxVersion)
|
||||
{
|
||||
void* result = dlopen(path, RTLD_LAZY);
|
||||
if(result != NULL)
|
||||
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
|
||||
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
|
||||
FF_UNUSED(maxVersion)
|
||||
|
||||
#else
|
||||
|
||||
if(result != NULL || maxVersion < 0)
|
||||
return result;
|
||||
|
||||
FFstrbuf pathbuf;
|
||||
@@ -19,7 +40,7 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
uint32_t originalLength = pathbuf.length;
|
||||
ffStrbufAppendF(&pathbuf, "%i", i);
|
||||
|
||||
result = dlopen(pathbuf.chars, RTLD_LAZY);
|
||||
result = dlopen(pathbuf.chars, FF_DLOPEN_FLAGS);
|
||||
if(result != NULL)
|
||||
break;
|
||||
|
||||
@@ -27,13 +48,16 @@ static void* libraryLoad(const char* path, int maxVersion)
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&pathbuf);
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...)
|
||||
{
|
||||
if(userProvidedName->length > 0)
|
||||
return dlopen(userProvidedName->chars, RTLD_LAZY);
|
||||
if(userProvidedName != NULL && userProvidedName->length > 0)
|
||||
return dlopen(userProvidedName->chars, FF_DLOPEN_FLAGS);
|
||||
|
||||
va_list defaultNames;
|
||||
va_start(defaultNames, userProvidedName);
|
||||
|
||||
@@ -5,15 +5,23 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#define FF_LIBRARY_EXTENSION ".dll"
|
||||
#elif defined(__APPLE__)
|
||||
#define FF_LIBRARY_EXTENSION ".dylib"
|
||||
#else
|
||||
#define FF_LIBRARY_EXTENSION ".so"
|
||||
#endif
|
||||
|
||||
#define FF_LIBRARY_SYMBOL(symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName;
|
||||
|
||||
#define FF_LIBRARY_LOAD(libraryObjectName, userLibraryName, returnValue, ...) \
|
||||
void* libraryObjectName = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL);\
|
||||
void* libraryObjectName = ffLibraryLoad(userLibraryName, __VA_ARGS__, NULL);\
|
||||
if(libraryObjectName == NULL) \
|
||||
return returnValue;
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, symbolMapping, symbolName, returnValue) \
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
|
||||
symbolMapping = dlsym(library, #symbolName); \
|
||||
if(symbolMapping == NULL) \
|
||||
{ \
|
||||
@@ -22,7 +30,19 @@
|
||||
}
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADRESS(library, ff ## symbolName, symbolName, returnValue);
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_VAR(library, varName, symbolName, returnValue) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(library, varName, symbolName) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName.ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_PTR(library, varName, symbolName, returnValue) \
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, varName->ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
void* ffLibraryLoad(const FFstrbuf* userProvidedName, ...);
|
||||
|
||||
|
||||
@@ -6,38 +6,38 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer)
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
|
||||
{
|
||||
struct addrinfo hints = {0};
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = 0;
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return;
|
||||
return -1;
|
||||
|
||||
int sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sock == -1)
|
||||
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = timeout * 1000; //milliseconds to microseconds
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
if(connect(sock, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(sock);
|
||||
close(sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
@@ -48,16 +48,23 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n\r\n");
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(sock, command.chars, command.length, 0) == -1)
|
||||
if(send(sockfd, command.chars, command.length, 0) == -1)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
close(sock);
|
||||
return;
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
ssize_t received = recv(sock, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
@@ -65,6 +72,14 @@ void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, F
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&command);
|
||||
close(sock);
|
||||
close(sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
int sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
|
||||
if(sockfd > 0)
|
||||
return ffNetworkingRecvHttpResponse(sockfd, buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
void ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, FFstrbuf* buffer);
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
|
||||
bool ffNetworkingRecvHttpResponse(int sock, FFstrbuf* buffer);
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/parsing.h"
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool ffStrSet(const char* str)
|
||||
{
|
||||
if(str == NULL)
|
||||
return false;
|
||||
|
||||
while(*str != '\0')
|
||||
{
|
||||
if(*str != ' ' && *str != '\t' && *str != '\n' && *str != '\r')
|
||||
return true;
|
||||
}
|
||||
while(isspace(*str))
|
||||
str++;
|
||||
|
||||
return false;
|
||||
return *str != '\0';
|
||||
}
|
||||
|
||||
void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch)
|
||||
@@ -66,6 +65,37 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty)
|
||||
ffStrbufAppendF(pretty, ".%u", version->patch);
|
||||
}
|
||||
|
||||
static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, uint8_t prefixesLength, const char** prefixes)
|
||||
{
|
||||
long double size = (long double) bytes;
|
||||
uint8_t counter = 0;
|
||||
|
||||
while(size > base && counter < prefixesLength - 1)
|
||||
{
|
||||
size /= base;
|
||||
counter++;
|
||||
}
|
||||
|
||||
if(counter == 0)
|
||||
ffStrbufAppendF(result, "%"PRIu64" %s", bytes, prefixes[0]);
|
||||
else if(counter < 3 || (counter == 3 && size < 100.0))
|
||||
ffStrbufAppendF(result, "%.2Lf %s", size, prefixes[counter]);
|
||||
else
|
||||
ffStrbufAppendF(result, "%.0Lf %s", size, prefixes[counter]);
|
||||
}
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result)
|
||||
{
|
||||
if(binaryPrefix == FF_BINARY_PREFIX_TYPE_IEC)
|
||||
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB"});
|
||||
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_SI)
|
||||
parseSize(result, bytes, 1000, 5, (const char*[]) {"B", "kB", "MB", "GB", "TB"});
|
||||
else if(binaryPrefix == FF_BINARY_PREFIX_TYPE_JEDEC)
|
||||
parseSize(result, bytes, 1024, 5, (const char*[]) {"B", "KB", "MB", "GB", "TB"});
|
||||
else
|
||||
parseSize(result, bytes, 1024, 1, (const char*[]) {"B"});
|
||||
}
|
||||
|
||||
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
|
||||
{
|
||||
if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
|
||||
|
||||
@@ -21,4 +21,6 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
|
||||
void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty);
|
||||
int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
|
||||
|
||||
void ffParseSize(uint64_t bytes, FFBinaryPrefixType binaryPrefix, FFstrbuf* result);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,10 +5,14 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod
|
||||
{
|
||||
ffLogoPrintLine(instance);
|
||||
|
||||
//This is used by --set-keyless, in this case we wan't neither the module name nor the separator
|
||||
if(moduleName == NULL)
|
||||
return;
|
||||
|
||||
if(!instance->config.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
|
||||
ffPrintColor(&instance->config.mainColor);
|
||||
ffPrintColor(&instance->config.colorKeys);
|
||||
}
|
||||
|
||||
//NULL check is required for modules with custom keys, e.g. disk with the folder path
|
||||
@@ -26,7 +30,7 @@ void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t mod
|
||||
ffParseFormatString(&key, customKeyFormat, 1, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex}
|
||||
});
|
||||
ffStrbufWriteTo(&key, stdout);
|
||||
ffPrintUserString(key.chars);
|
||||
ffStrbufDestroy(&key);
|
||||
}
|
||||
|
||||
@@ -49,7 +53,8 @@ void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t m
|
||||
if(buffer.length > 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, customKeyFormat);
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
ffPrintUserString(buffer.chars);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&buffer);
|
||||
@@ -125,3 +130,34 @@ void ffPrintCharTimes(char c, uint32_t times)
|
||||
for(uint32_t i = 0; i < times; i++)
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
void ffPrintUserString(const char* value)
|
||||
{
|
||||
while(*value != '\0')
|
||||
{
|
||||
if(*value != '\\')
|
||||
{
|
||||
putchar(*value);
|
||||
++value;
|
||||
continue;
|
||||
}
|
||||
|
||||
++value;
|
||||
|
||||
if(*value == 'n')
|
||||
putchar('\n');
|
||||
else if(*value == 't')
|
||||
putchar('\t');
|
||||
else if(*value == 'e')
|
||||
putchar('\e');
|
||||
else if(*value == '\\')
|
||||
putchar('\\');
|
||||
else
|
||||
{
|
||||
putchar('\\');
|
||||
putchar(*value);
|
||||
}
|
||||
|
||||
++value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat);
|
||||
void ffPrintFormatString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* format, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintFormat(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, uint32_t numArgs, const FFformatarg* arguments);
|
||||
void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
FF_C_PRINTF(6, 7) void ffPrintErrorString(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat, const FFstrbuf* customErrorFormat, const char* message, ...);
|
||||
FF_C_PRINTF(5, 6) void ffPrintError(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, const char* message, ...);
|
||||
void ffPrintColor(const FFstrbuf* colorValue);
|
||||
void ffPrintCharTimes(char c, uint32_t times);
|
||||
void ffPrintUserString(const char* str);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
int pipes[2];
|
||||
|
||||
if(pipe(pipes) == -1)
|
||||
return;
|
||||
return "pipe() failed";
|
||||
|
||||
pid_t childPid = fork();
|
||||
if(childPid == -1)
|
||||
return;
|
||||
return "fork() failed";
|
||||
|
||||
//Child
|
||||
if(childPid == 0)
|
||||
@@ -33,4 +33,6 @@ void ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
waitpid(childPid, NULL, 0);
|
||||
ffAppendFDBuffer(pipes[0], buffer);
|
||||
close(pipes[0]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/processing.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
//We can't use this native version yet because we still use POSIX path ( eg /usr/bin/fish ) at a lot of places.
|
||||
const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
{
|
||||
SECURITY_ATTRIBUTES saAttr = {
|
||||
.nLength = sizeof(SECURITY_ATTRIBUTES),
|
||||
.lpSecurityDescriptor = NULL,
|
||||
.bInheritHandle = TRUE,
|
||||
};
|
||||
|
||||
HANDLE hChildStdoutRead, hChildStdoutWrite;
|
||||
if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0))
|
||||
return "CreatePipe() failed";
|
||||
|
||||
if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0))
|
||||
return "SetHandleInformation(hChildStdoutRead) failed";
|
||||
|
||||
PROCESS_INFORMATION piProcInfo = {0};
|
||||
STARTUPINFOA siStartInfo = {
|
||||
.cb = sizeof(siStartInfo),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
.hStdOutput = hChildStdoutWrite,
|
||||
};
|
||||
|
||||
FFstrbuf cmdline;
|
||||
ffStrbufInit(&cmdline);
|
||||
for(char* const* parg = argv; *parg; ++parg)
|
||||
{
|
||||
if(cmdline.length > 0)
|
||||
ffStrbufAppendC(&cmdline, ' ');
|
||||
ffStrbufAppendF(&cmdline, "\"%s\"", * parg);
|
||||
}
|
||||
|
||||
BOOL success = CreateProcessA(
|
||||
NULL, // application name
|
||||
cmdline.chars, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
TRUE, // handles are inherited
|
||||
0, // creation flags
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
|
||||
CloseHandle(hChildStdoutWrite);
|
||||
if(!success)
|
||||
{
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return "CreateProcessA() failed";
|
||||
}
|
||||
|
||||
char str[128];
|
||||
DWORD nRead;
|
||||
while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0)
|
||||
{
|
||||
ffStrbufAppendNS(buffer, nRead, str);
|
||||
if(nRead < sizeof(str))
|
||||
break;
|
||||
}
|
||||
|
||||
CloseHandle(hChildStdoutRead);
|
||||
return NULL;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ typedef struct GSettingsData
|
||||
GVariantGetters variantGetters;
|
||||
} GSettingsData;
|
||||
|
||||
static const GSettingsData* getGSettingsData(FFinstance* instance)
|
||||
static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1);
|
||||
|
||||
@@ -114,7 +114,7 @@ static const GSettingsData* getGSettingsData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
const GSettingsData* data = getGSettingsData(instance);
|
||||
if(data == NULL)
|
||||
@@ -143,7 +143,7 @@ FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, c
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_GIO
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, schemaName, path, key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
@@ -161,7 +161,7 @@ typedef struct DConfData
|
||||
DConfClient* client;
|
||||
} DConfData;
|
||||
|
||||
static const DConfData* getDConfData(FFinstance* instance)
|
||||
static const DConfData* getDConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2);
|
||||
|
||||
@@ -181,7 +181,7 @@ static const DConfData* getDConfData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
{
|
||||
const DConfData* data = getDConfData(instance);
|
||||
if(data == NULL)
|
||||
@@ -199,14 +199,14 @@ FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttyp
|
||||
return getGVariantValue(variant, type, &data->variantGetters);
|
||||
}
|
||||
#else //FF_HAVE_DCONF
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type)
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, key, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_DCONF
|
||||
|
||||
FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
{
|
||||
FFvariant gsettings = ffSettingsGetGSettings(instance, gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
|
||||
|
||||
@@ -231,7 +231,7 @@ typedef struct XFConfData
|
||||
FF_LIBRARY_SYMBOL(xfconf_init)
|
||||
} XFConfData;
|
||||
|
||||
static const XFConfData* getXFConfData(FFinstance* instance)
|
||||
static const XFConfData* getXFConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4);
|
||||
|
||||
@@ -248,7 +248,7 @@ static const XFConfData* getXFConfData(FFinstance* instance)
|
||||
FF_LIBRARY_DATA_LOAD_RETURN
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
const XFConfData* data = getXFConfData(instance);
|
||||
if(data == NULL)
|
||||
@@ -271,7 +271,7 @@ FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, con
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#else //FF_HAVE_XFCONF
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(instance, channelName, propertyName, type)
|
||||
return FF_VARIANT_NULL;
|
||||
@@ -352,10 +352,9 @@ int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, cons
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <sys/system_properties.h>
|
||||
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
|
||||
uint32_t originalLength = result->length;
|
||||
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {
|
||||
ffStrbufEnsureFree(result, PROP_VALUE_MAX);
|
||||
result->length += (uint32_t) __system_property_get(propName, result->chars + result->length);
|
||||
return result->length > originalLength;
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
#endif
|
||||
#endif //__ANDROID__
|
||||
|
||||
@@ -25,15 +25,15 @@ typedef union FFvariant
|
||||
|
||||
#define FF_VARIANT_NULL ((FFvariant){.strValue = NULL})
|
||||
|
||||
FFvariant ffSettingsGetDConf(FFinstance* instance, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
FFvariant ffSettingsGetDConf(const FFinstance* instance, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(const FFinstance* instance, const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(const FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
|
||||
int ffSettingsGetSQLite3Int(const FFinstance* instance, const char* dbPath, const char* query);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
void ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "sysctl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
{
|
||||
size_t neededLength;
|
||||
if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
|
||||
return;
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
if(sysctlbyname(propName, result->chars + result->length, &neededLength, NULL, 0) == 0)
|
||||
result->length += (uint32_t) neededLength - 1;
|
||||
|
||||
result->chars[result->length] = '\0';
|
||||
}
|
||||
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue)
|
||||
{
|
||||
int result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue)
|
||||
{
|
||||
int64_t result;
|
||||
size_t neededLength = sizeof(result);
|
||||
if(sysctlbyname(propName, &result, &neededLength, NULL, 0) != 0)
|
||||
return defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength)
|
||||
{
|
||||
if(sysctl(request, requestLength, NULL, resultLength, NULL, 0) != 0)
|
||||
return NULL;
|
||||
|
||||
void* data = malloc(*resultLength);
|
||||
if(data == NULL)
|
||||
return NULL;
|
||||
|
||||
if(sysctl(request, requestLength, data, resultLength, NULL, 0) != 0)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_sysctl
|
||||
#define FF_INCLUDED_common_sysctl
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_time
|
||||
#define FF_INCLUDED_common_time
|
||||
|
||||
#include <stdint.h>
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#include <synchapi.h>
|
||||
#include <sysinfoapi.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static inline uint64_t ffTimeGetTick() //In msec
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
return GetTickCount64();
|
||||
#else
|
||||
struct timeval timeNow;
|
||||
gettimeofday(&timeNow, NULL);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ffTimeSleep(uint32_t msec)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
SleepEx(msec, TRUE);
|
||||
#else
|
||||
nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,12 +1,12 @@
|
||||
# Fastfetch system configuration
|
||||
# This file sets the defaults for all users of the system.
|
||||
# This file sets the default config for all users of the system.
|
||||
|
||||
# For more information about configuration files work,
|
||||
# see the file ~/.config/fastfetch/config.conf, generated during first
|
||||
# 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.
|
||||
|
||||
# This file was shipped with $"FASTFETCH_PROJECT_VERSION$".
|
||||
# Use fastfetch --print-config-system > /etc/fastfetch/config.conf to overwrite this file with the current defaults
|
||||
# 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.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# 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$".
|
||||
# This file was shipped with $" FASTFETCH_PROJECT_VERSION $".
|
||||
# Use fastfetch --print-config-user > ~/.config/fastfetch/config.conf to overwrite this file with the current defaults
|
||||
|
||||
# Below some often usefull options are listed. Uncomment and modify them so they take affect.
|
||||
@@ -25,7 +25,7 @@
|
||||
# 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$"
|
||||
#--structure $" FASTFETCH_DATATEXT_STRUCTURE $"
|
||||
|
||||
# Multithreading option:
|
||||
# Sets if fastfetch should use multiple threads to detect the values.
|
||||
@@ -113,12 +113,25 @@
|
||||
# Default is true.
|
||||
#--logo-print-remaining true
|
||||
|
||||
# Color option:
|
||||
# Color keys option:
|
||||
# Sets the color of the keys.
|
||||
# Must be linux console color codes or the name of a color.
|
||||
# Default is the primary color of the logo.
|
||||
# Default is the key color of the logo.
|
||||
# Use "fastfetch --help color" to learn more and see examples.
|
||||
#--color magenta
|
||||
#--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
|
||||
|
||||
# Title FQDN option:
|
||||
# Sets if the title should use the fully qualified domain name.
|
||||
@@ -138,12 +151,30 @@
|
||||
# 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".
|
||||
#--public-ip-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).
|
||||
#--public-ip-timeout 0
|
||||
|
||||
# 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.
|
||||
@@ -193,17 +224,21 @@
|
||||
#--cpu-usage-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}
|
||||
#--locale-key Locale
|
||||
#--local-ip-key Local IP ({1})
|
||||
#--public-ip-key Public IP
|
||||
#--weather-key Weather
|
||||
#--player-key Media Player
|
||||
#--song-key Song
|
||||
#--datetime-key Date Time
|
||||
#--vulkan-key Vulkan
|
||||
#--opengl-key OpenGL
|
||||
#--opencl-key OpenCL
|
||||
#--users-key Users
|
||||
|
||||
# Format options:
|
||||
# Sets the format string for module values.
|
||||
@@ -231,17 +266,21 @@
|
||||
#--cpu-usage-format
|
||||
#--gpu-format
|
||||
#--memory-format
|
||||
#--swap-format
|
||||
#--disk-format
|
||||
#--battery-format
|
||||
#--poweradapter-format
|
||||
#--locale-format
|
||||
#--local-ip-format
|
||||
#--public-ip-format
|
||||
#--weather-format
|
||||
#--player-format
|
||||
#--song-format
|
||||
#--datetime-format
|
||||
#--vulkan-format
|
||||
#--opengl-format
|
||||
#--opencl-format
|
||||
#--users-format
|
||||
|
||||
# Error options:
|
||||
# Sets the format string to use if an error occured
|
||||
@@ -269,17 +308,21 @@
|
||||
#--cpu-usage-error
|
||||
#--gpu-error
|
||||
#--memory-error
|
||||
#--swap-error
|
||||
#--disk-error
|
||||
#--battery-error
|
||||
#--poweradapter-error
|
||||
#--locale-error
|
||||
#--local-ip-error
|
||||
#--public-ip-error
|
||||
#--weather-error
|
||||
#--player-error
|
||||
#--song-error
|
||||
#--datetime-error
|
||||
#--vulkan-error
|
||||
#--opengl-error
|
||||
#--opencl-error
|
||||
#--users-error
|
||||
|
||||
# Library options:
|
||||
# Sets an user specific path to a library to load.
|
||||
@@ -303,4 +346,6 @@
|
||||
#--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-opencl /usr/lib/libOpenCL.so
|
||||
#--lib-cjson /usr/lib/libcjson.so
|
||||
#--lib-freetype /data/data/com.termux/files/usr/lib
|
||||
|
||||
@@ -40,12 +40,16 @@ Logo options:
|
||||
|
||||
Display options:
|
||||
-s,--structure <structure>: sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
|
||||
-c,--color <color>: sets the color of the keys. Must be a linux console color code or the name of a color (+)
|
||||
--color-keys <color>: sers the color of the keys
|
||||
--color-title <color>: sets the color of the title
|
||||
-c,--color <color>: sets the color of both the keys and the title
|
||||
--separator <str>: sets 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 occuring errors
|
||||
--disable-linewrap <?value>: weather to disable linewrap during the run
|
||||
--hide-cursor <?value>: weather to hide the cursor during the run
|
||||
--binary-prefix <value>: sets the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC
|
||||
|
||||
General module options:
|
||||
--<module>-format <format>: Sets the format string to use for each specific module.
|
||||
@@ -80,17 +84,26 @@ Library options: Set the path of a library to load
|
||||
--lib-glx <path>
|
||||
--lib-osmesa <path>
|
||||
--lib-opencl <path>
|
||||
--lib-cjson <path>
|
||||
|
||||
Module specific options:
|
||||
--title-fqdn <?value>: sets if the title should use fully qualified domain name. Default is false.
|
||||
--title-fqdn <?value>: Sets if the title should use fully qualified domain name. Default is false.
|
||||
--separator-string <str>: Set the string printed by the separator module
|
||||
--os-file <path>: Set the path to the file containing OS informations
|
||||
--disk-folders <folders>: A colon separated list of folder paths for the disk output. Default is "/:/home"
|
||||
--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-removable <?value>: Sets if removable volume should be printed. Default is false
|
||||
--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
|
||||
--gpu-temp <?value>: Detect and display GPU temperature if supported. Default is false
|
||||
--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-loop <?value>: Show loop back addresses (127.0.0.1) in local ip module. Default is false
|
||||
--localip-name-prefix <str>: Show ips with given name prefix only. Default is empty
|
||||
--public-ip-timeout: Time in milliseconds to wait for the public ip server to respond. Default is disabled (0)
|
||||
--public-ip-url: The URL of public IP detection server to be used.
|
||||
--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
|
||||
--gl <value>: Sets the opengl context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ Icons
|
||||
Kernel
|
||||
Locale
|
||||
LocalIP
|
||||
Media
|
||||
Memory
|
||||
OS
|
||||
OpenCL
|
||||
@@ -23,10 +24,11 @@ Packages
|
||||
Player
|
||||
Processes
|
||||
PublicIP
|
||||
PowerAdapter
|
||||
Resolution
|
||||
Separator
|
||||
Shell
|
||||
Song
|
||||
Swap
|
||||
Terminal
|
||||
TerminalFont
|
||||
Theme
|
||||
|
||||
@@ -1 +1 @@
|
||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Locale:Break:Colors
|
||||
Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:PowerAdapter:Locale:Break:Colors
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#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)
|
||||
|
||||
typedef struct BatteryResult
|
||||
{
|
||||
FFstrbuf manufacturer;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf technology;
|
||||
FFstrbuf capacity;
|
||||
FFstrbuf status;
|
||||
double temperature;
|
||||
} BatteryResult;
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "fastfetch.h"
|
||||
#include "battery.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "detection/temps/temps_apple.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
static double detectBatteryTemp()
|
||||
{
|
||||
FFlist temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
ffDetectCoreTemps(FF_TEMP_BATTERY, &temps);
|
||||
|
||||
if(temps.length == 0)
|
||||
return FF_BATTERY_TEMP_UNSET;
|
||||
|
||||
double result = 0;
|
||||
for(uint32_t i = 0; i < temps.length; ++i)
|
||||
{
|
||||
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
|
||||
result += tempValue->value;
|
||||
//TODO: do we really need this?
|
||||
ffStrbufDestroy(&tempValue->name);
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSmartBattery");
|
||||
if (matchDict == NULL)
|
||||
return "IOServiceMatching(\"AppleSmartBattery\") failed";
|
||||
|
||||
io_iterator_t iterator;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, matchDict, &iterator) != kIOReturnSuccess)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool boolValue;
|
||||
const char* error;
|
||||
|
||||
BatteryResult* battery = ffListAdd(results);
|
||||
ffStrbufInit(&battery->capacity);
|
||||
int currentCapacity, maxCapacity;
|
||||
|
||||
if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity)))
|
||||
return error;
|
||||
if (maxCapacity <= 0)
|
||||
return "Querying MaxCapacity failed";
|
||||
|
||||
if ((error = ffCfDictGetInt(properties, CFSTR("CurrentCapacity"), ¤tCapacity)))
|
||||
return error;
|
||||
if(currentCapacity <= 0)
|
||||
return "Querying CurrentCapacity failed";
|
||||
|
||||
ffStrbufAppendF(&battery->capacity, "%.0f", currentCapacity * 100.0 / maxCapacity);
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->technology);
|
||||
if (!ffCfDictGetBool(properties, CFSTR("built-in"), &boolValue) && boolValue)
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Apple Inc.");
|
||||
ffStrbufAppendS(&battery->modelName, "Builtin");
|
||||
ffStrbufAppendS(&battery->technology, "Lithium");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&battery->manufacturer, "Unknown");
|
||||
ffStrbufAppendS(&battery->modelName, "Unknown");
|
||||
ffStrbufAppendS(&battery->technology, "Unknown");
|
||||
}
|
||||
|
||||
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, "");
|
||||
|
||||
if(instance->config.batteryTemp)
|
||||
battery->temperature = detectBatteryTemp();
|
||||
else
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
IOObjectRelease(iterator);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
#include "battery.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
{
|
||||
uint32_t dirLength = dir->length;
|
||||
|
||||
FFstrbuf testBatteryBuffer;
|
||||
ffStrbufInit(&testBatteryBuffer);
|
||||
|
||||
//type must exist and be "Battery"
|
||||
ffStrbufAppendS(dir, "/type");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Battery") != 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
//scope may not exist or must not be "Device"
|
||||
ffStrbufAppendS(dir, "/scope");
|
||||
ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&testBatteryBuffer, "Device") == 0)
|
||||
{
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
BatteryResult* result = ffListAdd(results);
|
||||
|
||||
//capacity must exist and be not empty
|
||||
ffStrbufInit(&result->capacity);
|
||||
ffStrbufAppendS(dir, "/capacity");
|
||||
ffReadFileBuffer(dir->chars, &result->capacity);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(result->capacity.length == 0)
|
||||
{
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
--results->length;
|
||||
return;
|
||||
}
|
||||
|
||||
//At this point, we have a battery. Try to get as much values as possible.
|
||||
|
||||
ffStrbufInit(&result->manufacturer);
|
||||
ffStrbufAppendS(dir, "/manufacturer");
|
||||
ffReadFileBuffer(dir->chars, &result->manufacturer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->modelName);
|
||||
ffStrbufAppendS(dir, "/model_name");
|
||||
ffReadFileBuffer(dir->chars, &result->modelName);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->technology);
|
||||
ffStrbufAppendS(dir, "/technology");
|
||||
ffReadFileBuffer(dir->chars, &result->technology);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
ffStrbufInit(&result->status);
|
||||
ffStrbufAppendS(dir, "/status");
|
||||
ffReadFileBuffer(dir->chars, &result->status);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
result->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results) {
|
||||
FFstrbuf baseDir;
|
||||
ffStrbufInitA(&baseDir, 64);
|
||||
if(instance->config.batteryDir.length > 0)
|
||||
{
|
||||
ffStrbufAppend(&baseDir, &instance->config.batteryDir);
|
||||
ffStrbufEnsureEndsWithC(&baseDir, '/');
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, "/sys/class/power_supply/");
|
||||
}
|
||||
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
|
||||
DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "opendir(batteryDir) == NULL";
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
parseBattery(&baseDir, results);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
if(results->length == 0) {
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return "batteryDir doesn't contain any battery folder";
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&baseDir);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "fastfetch.h"
|
||||
#include "battery.h"
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance, results)
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
extern "C" {
|
||||
#include "battery.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
//https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT SystemName, Name, Chemistry, EstimatedChargeRemaining, BatteryStatus FROM Win32_Battery", nullptr);
|
||||
|
||||
if(!pEnumerator)
|
||||
return "Query WMI service failed";
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
|
||||
{
|
||||
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffGetWmiObjString(pclsObj, L"SystemName", &battery->manufacturer);
|
||||
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffGetWmiObjString(pclsObj, L"Name", &battery->modelName);
|
||||
|
||||
uint64_t chemistry;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"Chemistry", &chemistry);
|
||||
switch(chemistry)
|
||||
{
|
||||
case 1: ffStrbufInitS(&battery->technology, "Other"); break;
|
||||
case 2: ffStrbufInitS(&battery->technology, "Unknown"); break;
|
||||
case 3: ffStrbufInitS(&battery->technology, "Lead Acid"); break;
|
||||
case 4: ffStrbufInitS(&battery->technology, "Nickel Cadmium"); break;
|
||||
case 5: ffStrbufInitS(&battery->technology, "Nickel Metal Hydride"); break;
|
||||
case 6: ffStrbufInitS(&battery->technology, "Lithium-ion"); break;
|
||||
case 7: ffStrbufInitS(&battery->technology, "Zinc air"); break;
|
||||
case 8: ffStrbufInitS(&battery->technology, "Lithium Polymer"); break;
|
||||
}
|
||||
|
||||
uint64_t capacity;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"EstimatedChargeRemaining", &capacity);
|
||||
ffStrbufInitF(&battery->capacity, "%d", (int)capacity);
|
||||
|
||||
uint64_t batteryStatus;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"BatteryStatus", &batteryStatus);
|
||||
switch(batteryStatus)
|
||||
{
|
||||
case 1: ffStrbufInitS(&battery->status, "Discharging"); break;
|
||||
case 2: ffStrbufInitS(&battery->status, "AC Connected"); break;
|
||||
case 3: ffStrbufInitS(&battery->status, "Fully Charged"); break;
|
||||
case 4: ffStrbufInitS(&battery->status, "Low"); break;
|
||||
case 5: ffStrbufInitS(&battery->status, "Critical"); break;
|
||||
case 6: ffStrbufInitS(&battery->status, "Charging"); break;
|
||||
case 7: ffStrbufInitS(&battery->status, "Charging and High"); break;
|
||||
case 8: ffStrbufInitS(&battery->status, "Charging and Low"); break;
|
||||
case 9: ffStrbufInitS(&battery->status, "Charging and Critical"); break;
|
||||
case 10: ffStrbufInitS(&battery->status, "Undefined"); break;
|
||||
case 11: ffStrbufInitS(&battery->status, "Partially Charged"); break;
|
||||
}
|
||||
|
||||
battery->temperature = FF_BATTERY_TEMP_UNSET;
|
||||
}
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_bios_bios
|
||||
#define FF_INCLUDED_detection_bios_bios
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBiosResult
|
||||
{
|
||||
FFstrbuf biosDate;
|
||||
FFstrbuf biosRelease;
|
||||
FFstrbuf biosVendor;
|
||||
FFstrbuf biosVersion;
|
||||
FFstrbuf error;
|
||||
} FFBiosResult;
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "bios.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool hostValueSet(FFstrbuf* value)
|
||||
{
|
||||
return
|
||||
value->length > 0 &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "To be filled") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "To be set") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "OEM") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true &&
|
||||
ffStrbufIgnCaseCompS(value, "None") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product Name") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product Version") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Name") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Version") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Default string") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Undefined") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Not Specified") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "INVALID") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "All Series") != 0
|
||||
;
|
||||
}
|
||||
|
||||
static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
|
||||
{
|
||||
ffReadFileBuffer(devicesPath, buffer);
|
||||
if(hostValueSet(buffer))
|
||||
return;
|
||||
|
||||
ffReadFileBuffer(classPath, buffer);
|
||||
if(hostValueSet(buffer))
|
||||
return;
|
||||
|
||||
ffStrbufClear(buffer);
|
||||
}
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/bios_date", "/sys/class/dmi/id/bios_date", &bios->biosDate);
|
||||
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/bios_release", "/sys/class/dmi/id/bios_release", &bios->biosRelease);
|
||||
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/bios_vendor", "/sys/class/dmi/id/bios_vendor", &bios->biosVendor);
|
||||
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/bios_version", "/sys/class/dmi/id/bios_version", &bios->biosVersion);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "bios.h"
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInitS(&bios->error, "Not supported on this platform");
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
extern "C" {
|
||||
#include "bios.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, ReleaseDate, Version, Manufacturer FROM Win32_BIOS", &bios->error);
|
||||
if(!pEnumerator)
|
||||
return;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
|
||||
|
||||
if(uReturn == 0)
|
||||
{
|
||||
ffStrbufInitS(&bios->error, "No Wmi result returned");
|
||||
pEnumerator->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
ffGetWmiObjString(pclsObj, L"Name", &bios->biosRelease);
|
||||
ffGetWmiObjString(pclsObj, L"ReleaseDate", &bios->biosDate);
|
||||
ffGetWmiObjString(pclsObj, L"Version", &bios->biosVersion);
|
||||
ffGetWmiObjString(pclsObj, L"Manufacturer", &bios->biosVendor);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_board_board
|
||||
#define FF_INCLUDED_detection_board_board
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFBoardResult
|
||||
{
|
||||
FFstrbuf boardName;
|
||||
FFstrbuf boardVendor;
|
||||
FFstrbuf boardVersion;
|
||||
FFstrbuf error;
|
||||
} FFBoardResult;
|
||||
|
||||
void ffDetectBoard(FFBoardResult* result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "board.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool hostValueSet(FFstrbuf* value)
|
||||
{
|
||||
return
|
||||
value->length > 0 &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "To be filled") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "To be set") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "OEM") != true &&
|
||||
ffStrbufStartsWithIgnCaseS(value, "O.E.M.") != true &&
|
||||
ffStrbufIgnCaseCompS(value, "None") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product Name") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Product Version") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Name") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "System Version") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Default string") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Undefined") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Not Specified") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Not Applicable") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "INVALID") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "Type1ProductConfigId") != 0 &&
|
||||
ffStrbufIgnCaseCompS(value, "All Series") != 0
|
||||
;
|
||||
}
|
||||
|
||||
static void getHostValue(const char* devicesPath, const char* classPath, FFstrbuf* buffer)
|
||||
{
|
||||
ffReadFileBuffer(devicesPath, buffer);
|
||||
if(hostValueSet(buffer))
|
||||
return;
|
||||
|
||||
ffReadFileBuffer(classPath, buffer);
|
||||
if(hostValueSet(buffer))
|
||||
return;
|
||||
|
||||
ffStrbufClear(buffer);
|
||||
}
|
||||
|
||||
void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInit(&board->error);
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/board_name", "/sys/class/dmi/id/board_name", &board->boardName);
|
||||
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/board_vendor", "/sys/class/dmi/id/board_vendor", &board->boardVendor);
|
||||
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/board_version", "/sys/class/dmi/id/board_version", &board->boardVersion);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "board.h"
|
||||
|
||||
void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInitS(&board->error, "Not supported on this platform");
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
extern "C" {
|
||||
#include "board.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInit(&board->error);
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Product, Version, Manufacturer FROM Win32_BaseBoard", &board->error);
|
||||
if(!pEnumerator)
|
||||
return;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
|
||||
|
||||
if(uReturn == 0)
|
||||
{
|
||||
ffStrbufInitS(&board->error, "No Wmi result returned");
|
||||
pEnumerator->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
ffGetWmiObjString(pclsObj, L"Product", &board->boardName);
|
||||
ffGetWmiObjString(pclsObj, L"Manufacturer", &board->boardVendor);
|
||||
ffGetWmiObjString(pclsObj, L"Version", &board->boardVersion);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "cpu.h"
|
||||
#include "common/caching.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
#define FF_CPU_CACHE_NAME "cpu"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached);
|
||||
|
||||
static bool cacheCallback(FFCPUResult* cpu, FFCache* cache, FFCacheMethodStrbuf strbufMethod, FFCacheMethodData dataMethod)
|
||||
{
|
||||
return
|
||||
strbufMethod(cache, &cpu->vendor) &&
|
||||
strbufMethod(cache, &cpu->name) &&
|
||||
dataMethod(cache, sizeof(cpu->coresPhysical), &cpu->coresPhysical) &&
|
||||
dataMethod(cache, sizeof(cpu->coresLogical), &cpu->coresLogical) &&
|
||||
dataMethod(cache, sizeof(cpu->coresOnline), &cpu->coresOnline) &&
|
||||
dataMethod(cache, sizeof(cpu->frequencyMin), &cpu->frequencyMin) &&
|
||||
dataMethod(cache, sizeof(cpu->frequencyMax), &cpu->frequencyMax);
|
||||
}
|
||||
|
||||
static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
bool cached = ffCacheRead(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
|
||||
|
||||
ffDetectCPUImpl(instance, cpu, cached);
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
const char* removeStrings[] = {
|
||||
"(R)", "(r)", "(TM)", "(tm)",
|
||||
" CPU", " FPU", " APU", " Processor",
|
||||
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
|
||||
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core",
|
||||
" with Radeon Graphics"
|
||||
};
|
||||
ffStrbufRemoveStringsA(&cpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
|
||||
ffStrbufSubstrBeforeFirstC(&cpu->name, '@'); //Cut the speed output in the name as we append our own
|
||||
ffStrbufTrimRight(&cpu->name, ' '); //If we removed the @ in previous step there was most likely a space before it
|
||||
|
||||
ffCacheWrite(instance, cpu, FF_CPU_CACHE_NAME, (FFCacheMethodCallback) cacheCallback);
|
||||
}
|
||||
|
||||
const FFCPUResult* ffDetectCPU(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFCPUResult,
|
||||
detectCPU(instance, &result);
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#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)
|
||||
|
||||
typedef struct FFCPUResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf vendor;
|
||||
|
||||
uint16_t coresPhysical;
|
||||
uint16_t coresLogical;
|
||||
uint16_t coresOnline;
|
||||
|
||||
double frequencyMin;
|
||||
double frequencyMax;
|
||||
|
||||
double temperature;
|
||||
} FFCPUResult;
|
||||
|
||||
const FFCPUResult* ffDetectCPU(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "detection/temps/temps_apple.h"
|
||||
|
||||
static double getFrequency(const char* propName)
|
||||
{
|
||||
double herz = (double) ffSysctlGetInt64(propName, 0);
|
||||
if(herz <= 0.0)
|
||||
return herz;
|
||||
|
||||
herz /= 1000.0; //to KHz
|
||||
herz /= 1000.0; //to MHz
|
||||
return herz / 1000.0; //to GHz
|
||||
}
|
||||
|
||||
static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
{
|
||||
FFlist temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_M1X, &temps);
|
||||
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_M2X, &temps);
|
||||
else //TODO: PPC?
|
||||
ffDetectCoreTemps(FF_TEMP_CPU_X64, &temps);
|
||||
|
||||
if(temps.length == 0)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
|
||||
double result = 0;
|
||||
for(uint32_t i = 0; i < temps.length; ++i)
|
||||
{
|
||||
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
|
||||
result += tempValue->value;
|
||||
//TODO: do we really need this?
|
||||
ffStrbufDestroy(&tempValue->name);
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
if(!cached)
|
||||
{
|
||||
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
|
||||
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu_max", 1);
|
||||
if(cpu->coresPhysical == 1)
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.physicalcpu", 1);
|
||||
|
||||
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.logicalcpu_max", 1);
|
||||
if(cpu->coresLogical == 1)
|
||||
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.logicalcpu", 1);
|
||||
if(cpu->coresOnline == 1)
|
||||
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.activecpu", 1);
|
||||
|
||||
cpu->frequencyMin = getFrequency("hw.cpufrequency_min");
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency_max");
|
||||
if(cpu->frequencyMax == 0.0)
|
||||
cpu->frequencyMax = getFrequency("hw.cpufrequency");
|
||||
}
|
||||
|
||||
if (instance->config.cpuTemp)
|
||||
cpu->temperature = detectCpuTemp(&cpu->name);
|
||||
else
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
ffSysctlGetString("hw.model", &cpu->name);
|
||||
|
||||
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
||||
cpu->coresLogical = cpu->coresPhysical;
|
||||
cpu->coresOnline = cpu->coresPhysical;
|
||||
|
||||
cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0;
|
||||
cpu->frequencyMax = cpu->frequencyMin;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "cpu.h"
|
||||
#include "common/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer)
|
||||
{
|
||||
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
return;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while(getline(&line, &len, cpuinfo) != -1)
|
||||
{
|
||||
//Stop after the first CPU
|
||||
if(cpu->name.length > 0 && (*line == '\0' || *line == '\n'))
|
||||
break;
|
||||
|
||||
(void)(
|
||||
ffParsePropLine(line, "model name :", &cpu->name) ||
|
||||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
|
||||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) //For Android devices
|
||||
);
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(cpuinfo);
|
||||
}
|
||||
|
||||
static double getGHz(const char* file)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInit(&content);
|
||||
ffReadFileBuffer(file, &content);
|
||||
double herz = ffStrbufToDouble(&content);
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
//ffStrbufToDouble failed
|
||||
if(herz != herz)
|
||||
return 0;
|
||||
|
||||
herz /= 1000.0; //to MHz
|
||||
return herz / 1000.0; //to GHz
|
||||
}
|
||||
|
||||
static double getFrequency(const char* info, const char* scaling)
|
||||
{
|
||||
double frequency = getGHz(info);
|
||||
if(frequency > 0.0)
|
||||
return frequency;
|
||||
|
||||
return getGHz(scaling);
|
||||
}
|
||||
|
||||
static double detectCPUTemp(const FFinstance* instance)
|
||||
{
|
||||
const FFTempsResult* temps = ffDetectTemps(instance);
|
||||
|
||||
for(uint32_t i = 0; i < temps->values.length; i++)
|
||||
{
|
||||
FFTempValue* value = ffListGet(&temps->values, i);
|
||||
|
||||
if(
|
||||
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
|
||||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
|
||||
ffStrbufCompS(&value->name, "coretemp") == 0
|
||||
) return value->value;
|
||||
}
|
||||
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
if(instance->config.cpuTemp)
|
||||
cpu->temperature = detectCPUTemp(instance);
|
||||
else
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
FFstrbuf physicalCoresBuffer;
|
||||
ffStrbufInit(&physicalCoresBuffer);
|
||||
|
||||
parseCpuInfo(cpu, &physicalCoresBuffer);
|
||||
|
||||
cpu->coresPhysical = ffStrbufToUInt16(&physicalCoresBuffer, 1);
|
||||
|
||||
#ifdef FF_HAVE_SYSINFO_H
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
#else
|
||||
cpu->coresLogical = 1;
|
||||
cpu->coresOnline = 1;
|
||||
#endif
|
||||
|
||||
#define BP "/sys/devices/system/cpu/cpufreq/policy0/"
|
||||
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
|
||||
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
|
||||
|
||||
ffStrbufDestroy(&physicalCoresBuffer);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
extern "C" {
|
||||
#include "cpu.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
|
||||
cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0;
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Manufacturer, NumberOfCores, NumberOfLogicalProcessors, ThreadCount, CurrentClockSpeed, MaxClockSpeed FROM Win32_Processor WHERE ProcessorType = 3", nullptr);
|
||||
if(!pEnumerator)
|
||||
return;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
|
||||
{
|
||||
pEnumerator->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
ffGetWmiObjString(pclsObj, L"Name", &cpu->name);
|
||||
ffGetWmiObjString(pclsObj, L"Manufacturer", &cpu->vendor);
|
||||
|
||||
uint64_t value;
|
||||
|
||||
ffGetWmiObjUnsigned(pclsObj, L"NumberOfCores", &value);
|
||||
cpu->coresPhysical = (uint16_t)value;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"NumberOfLogicalProcessors", &value);
|
||||
cpu->coresLogical = (uint16_t)value;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"ThreadCount", &value);
|
||||
cpu->coresOnline = (uint16_t)value;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"CurrentClockSpeed", &value); //There's no MinClockSpeed in Win32_Processor
|
||||
cpu->frequencyMin = (double)value / 1000.0;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"MaxClockSpeed", &value);
|
||||
cpu->frequencyMax = (double)value / 1000.0;
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#if FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
|
||||
const char* ffGetCpuUsageResultNoWait(double* result);
|
||||
|
||||
void ffPrepareCPUUsage() {}
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result) {
|
||||
return ffGetCpuUsageResultNoWait(result);
|
||||
}
|
||||
|
||||
#else //FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
|
||||
#include "common/time.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// We need to use uint64_t because sizeof(long) == 4 on Windows
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll);
|
||||
|
||||
static uint64_t inUseAll1, totalAll1, startTime;
|
||||
|
||||
void ffPrepareCPUUsage()
|
||||
{
|
||||
startTime = ffTimeGetTick();
|
||||
ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result)
|
||||
{
|
||||
const char* error = NULL;
|
||||
if(startTime == 0)
|
||||
{
|
||||
error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
|
||||
if(error)
|
||||
return error;
|
||||
ffTimeSleep(1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t duration = ffTimeGetTick() - startTime;
|
||||
if(duration < 1000)
|
||||
ffTimeSleep(1000 - (uint32_t) duration);
|
||||
}
|
||||
|
||||
uint64_t inUseAll2, totalAll2;
|
||||
error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
*result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif //FF_DETECTION_CPUUSAGE_NOWAIT
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cpu_cpuUsage
|
||||
#define FF_INCLUDED_detection_cpu_cpuUsage
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
// Disabled by default because the result does need some time to generate
|
||||
#define FF_DETECTION_CPUUSAGE_NOWAIT 0
|
||||
#endif
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#include <mach/processor_info.h>
|
||||
#include <mach/mach_host.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
natural_t numCPUs = 0U;
|
||||
processor_info_array_t cpuInfo;
|
||||
mach_msg_type_number_t numCpuInfo;
|
||||
*inUseAll = *totalAll = 0;
|
||||
|
||||
if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numCPUs, &cpuInfo, &numCpuInfo) != KERN_SUCCESS)
|
||||
return "host_processor_info() failed";
|
||||
if (numCPUs * CPU_STATE_MAX != numCpuInfo)
|
||||
return "Unexpected host_processor_info() result";
|
||||
|
||||
for (natural_t i = 0U; i < numCPUs; ++i) {
|
||||
integer_t inUse = cpuInfo[CPU_STATE_MAX * i + CPU_STATE_USER]
|
||||
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM]
|
||||
+ cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE];
|
||||
integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE];
|
||||
*inUseAll += (uint64_t)inUse;
|
||||
*totalAll += (uint64_t)total;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0;
|
||||
|
||||
FILE* procStat = fopen("/proc/stat", "r");
|
||||
if(procStat == NULL)
|
||||
return "fopen(\"""/proc/stat\", \"r\") == NULL";
|
||||
|
||||
if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0)
|
||||
{
|
||||
fclose(procStat);
|
||||
return "fscanf() failed";
|
||||
}
|
||||
*inUseAll = user + nice + system;
|
||||
*totalAll = *inUseAll + idle + iowait + irq + softirq;
|
||||
|
||||
fclose(procStat);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
extern "C" {
|
||||
#include "cpuUsage.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" const char* ffGetCpuUsageResultNoWait(double* result)
|
||||
{
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT LoadPercentage FROM Win32_Processor", nullptr);
|
||||
if(!pEnumerator)
|
||||
return "Query WMI service failed";
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
if(FAILED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) || uReturn == 0)
|
||||
{
|
||||
pEnumerator->Release();
|
||||
return "No WMI result returned";
|
||||
}
|
||||
|
||||
ffGetWmiObjReal(pclsObj, L"LoadPercentage", result);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
|
||||
return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime);
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
FILETIME idleTime, kernelTime, userTime;
|
||||
if(GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0)
|
||||
return "GetSystemTimes() failed";
|
||||
|
||||
*inUseAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
|
||||
*totalAll = *inUseAll + fileTimeToUint64(&idleTime);
|
||||
return NULL;
|
||||
}
|
||||
@@ -27,21 +27,21 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
result.yearShort = (uint8_t) (result.year % 100);
|
||||
result.month = (uint8_t) (tm->tm_mon + 1);
|
||||
|
||||
ffStrbufInit(&result.monthPretty);
|
||||
ffStrbufInitA(&result.monthPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthPretty.length = (uint32_t) strftime(result.monthPretty.chars, ffStrbufGetFree(&result.monthPretty), "%m", tm);
|
||||
|
||||
ffStrbufInit(&result.monthName);
|
||||
ffStrbufInitA(&result.monthName, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthName.length = (uint32_t) strftime(result.monthName.chars, ffStrbufGetFree(&result.monthName), "%B", tm);
|
||||
|
||||
ffStrbufInit(&result.monthNameShort);
|
||||
ffStrbufInitA(&result.monthNameShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.monthNameShort.length = (uint32_t) strftime(result.monthNameShort.chars, ffStrbufGetFree(&result.monthNameShort), "%b", tm);
|
||||
|
||||
result.week = (uint8_t) (tm->tm_yday / 7 + 1);
|
||||
|
||||
ffStrbufInit(&result.weekday);
|
||||
ffStrbufInitA(&result.weekday, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.weekday.length = (uint32_t) strftime(result.weekday.chars, ffStrbufGetFree(&result.weekday), "%A", tm);
|
||||
|
||||
ffStrbufInit(&result.weekdayShort);
|
||||
ffStrbufInitA(&result.weekdayShort, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.weekdayShort.length = (uint32_t) strftime(result.weekdayShort.chars, ffStrbufGetFree(&result.weekdayShort), "%a", tm);
|
||||
|
||||
result.dayInYear = (uint8_t) (tm->tm_yday + 1);
|
||||
@@ -50,22 +50,22 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
|
||||
result.hour = (uint8_t) tm->tm_hour;
|
||||
|
||||
ffStrbufInit(&result.hourPretty);
|
||||
ffStrbufInitA(&result.hourPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.hourPretty.length = (uint32_t) strftime(result.hourPretty.chars, ffStrbufGetFree(&result.hourPretty), "%H", tm);
|
||||
|
||||
result.hour12 = (uint8_t) (result.hour % 12);
|
||||
|
||||
ffStrbufInit(&result.hour12Pretty);
|
||||
ffStrbufInitA(&result.hour12Pretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.hour12Pretty.length = (uint32_t) strftime(result.hour12Pretty.chars, ffStrbufGetFree(&result.hour12Pretty), "%I", tm);
|
||||
|
||||
result.minute = (uint8_t) tm->tm_min;
|
||||
|
||||
ffStrbufInit(&result.minutePretty);
|
||||
ffStrbufInitA(&result.minutePretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.minutePretty.length = (uint32_t) strftime(result.minutePretty.chars, ffStrbufGetFree(&result.minutePretty), "%M", tm);
|
||||
|
||||
result.second = (uint8_t) tm->tm_sec;
|
||||
|
||||
ffStrbufInit(&result.secondPretty);
|
||||
ffStrbufInitA(&result.secondPretty, FASTFETCH_STRBUF_DEFAULT_ALLOC);
|
||||
result.secondPretty.length = (uint32_t) strftime(result.secondPretty.chars, ffStrbufGetFree(&result.secondPretty), "%S", tm);
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "fastfetch.h"
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result)
|
||||
{
|
||||
ffStrbufInitS(&result->path, folderPath);
|
||||
result->used = result->total = 0;
|
||||
ffStrbufInit(&result->error);
|
||||
|
||||
struct statvfs newFs;
|
||||
|
||||
if(fs == NULL)
|
||||
{
|
||||
fs = &newFs;
|
||||
int ret = statvfs(folderPath, fs);
|
||||
if(ret != 0)
|
||||
{
|
||||
ffStrbufAppendF(&result->error, "statvfs(\"%s\", &fs) != 0 (%i)", folderPath, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result->total = fs->f_blocks * fs->f_frsize;
|
||||
|
||||
if(result->total == 0)
|
||||
{
|
||||
ffStrbufAppendF(&result->error, "statvfs for %s returned size 0", folderPath);
|
||||
return;
|
||||
}
|
||||
|
||||
result->used = result->total - (fs->f_bavail * fs->f_frsize);
|
||||
result->files = (uint32_t) (fs->f_files - fs->f_ffree);
|
||||
result->removable = false; //To be set at other place
|
||||
}
|
||||
|
||||
bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
ffStrbufTrim(&instance->config.diskFolders, ':');
|
||||
if(instance->config.diskFolders.length == 0)
|
||||
return false;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < instance->config.diskFolders.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':');
|
||||
instance->config.diskFolders.chars[colonIndex] = '\0';
|
||||
|
||||
ffDetectDiskWithStatvfs(instance->config.diskFolders.chars + startIndex, NULL, (FFDiskResult*)ffListAdd(folders));
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_disk_disk
|
||||
#define FF_INCLUDED_detection_disk_disk
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFDiskResult
|
||||
{
|
||||
FFstrbuf path;
|
||||
uint64_t used;
|
||||
uint64_t total;
|
||||
uint32_t files;
|
||||
bool removable;
|
||||
FFstrbuf error;
|
||||
} FFDiskResult;
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders);
|
||||
bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "disk.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result);
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil];
|
||||
NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys
|
||||
options:NSVolumeEnumerationSkipHiddenVolumes];
|
||||
if(urls == nil)
|
||||
return "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed";
|
||||
|
||||
for (NSURL *url in urls) {
|
||||
NSError *error;
|
||||
NSNumber* removable;
|
||||
if([url getResourceValue:&removable forKey:NSURLVolumeIsRemovableKey error:&error] == NO)
|
||||
continue;
|
||||
if(removable.boolValue && !instance->config.diskRemovable)
|
||||
continue;
|
||||
|
||||
FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders);
|
||||
ffDetectDiskWithStatvfs([url.relativePath cStringUsingEncoding:NSUTF8StringEncoding], NULL, folder);
|
||||
folder->removable = removable.boolValue;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result);
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
struct statvfs fsRoot;
|
||||
int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot);
|
||||
if(rootRet != 0)
|
||||
return "statvfs(\"/\") failed";
|
||||
|
||||
ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot, (FFDiskResult*)ffListAdd(folders));
|
||||
|
||||
struct statvfs fsHome;
|
||||
int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome);
|
||||
if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid))
|
||||
ffDetectDiskWithStatvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome, (FFDiskResult*)ffListAdd(folders));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "disk.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
|
||||
static void detectDrive(const char* folderPath, uint32_t pathLen, FFDiskResult* result)
|
||||
{
|
||||
ffStrbufInitNS(&result->path, pathLen, folderPath);
|
||||
result->removable = false; //To be set at other place
|
||||
result->files = 0; //Unsupported
|
||||
|
||||
//According to https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa
|
||||
//GetDiskFreeSpaceExA does not have to specify the root directory on a disk. The function accepts any directory on a disk.
|
||||
uint64_t freeBytes;
|
||||
if(GetDiskFreeSpaceExA(folderPath, NULL, (PULARGE_INTEGER)&result->total, (PULARGE_INTEGER)&freeBytes)) {
|
||||
result->used = result->total - freeBytes;
|
||||
ffStrbufInit(&result->error);
|
||||
}
|
||||
else
|
||||
ffStrbufInitS(&result->error, "GetDiskFreeSpaceExA() failed");
|
||||
}
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
char buf[128]; // "C:\\\0D:\\\0"
|
||||
uint32_t length = GetLogicalDriveStringsA(sizeof(buf) / sizeof(*buf), buf);
|
||||
|
||||
for(size_t i = 0; i < length;)
|
||||
{
|
||||
const char* drive = buf + i;
|
||||
uint32_t driveLen = (uint32_t) strlen(drive);
|
||||
i += driveLen + 1;
|
||||
|
||||
bool removable = GetDriveTypeA(drive) == DRIVE_REMOVABLE;
|
||||
if(removable && !instance->config.diskRemovable)
|
||||
continue;
|
||||
|
||||
FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders);
|
||||
detectDrive(drive, driveLen, folder);
|
||||
folder->removable = removable;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
ffStrbufTrim(&instance->config.diskFolders, ';');
|
||||
if(instance->config.diskFolders.length == 0)
|
||||
return false;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < instance->config.diskFolders.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ';');
|
||||
instance->config.diskFolders.chars[colonIndex] = '\0';
|
||||
|
||||
detectDrive(instance->config.diskFolders.chars + startIndex, colonIndex - startIndex, (FFDiskResult*)ffListAdd(folders));
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
#include "displayServer.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
|
||||
uint32_t ffdsParseRefreshRate(int32_t refreshRate)
|
||||
{
|
||||
if(refreshRate <= 0)
|
||||
return 0;
|
||||
|
||||
int remainder = refreshRate % 5;
|
||||
if(remainder >= 3)
|
||||
refreshRate += (5 - remainder);
|
||||
else
|
||||
refreshRate -= remainder;
|
||||
|
||||
//All other typicall refresh rates are dividable by 5
|
||||
if(refreshRate == 145)
|
||||
refreshRate = 144;
|
||||
|
||||
return (uint32_t) refreshRate;
|
||||
}
|
||||
|
||||
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate)
|
||||
{
|
||||
if(width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
|
||||
resolution->width = width;
|
||||
resolution->height = height;
|
||||
resolution->refreshRate = refreshRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void parseDRM(FFDisplayServerResult* result)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return;
|
||||
|
||||
FFstrbuf drmDir;
|
||||
ffStrbufInitA(&drmDir, 64);
|
||||
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||
|
||||
uint32_t drmDirLength = drmDir.length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
ffStrbufAppendS(&drmDir, "/modes");
|
||||
|
||||
FILE* modeFile = fopen(drmDir.chars, "r");
|
||||
if(modeFile == NULL)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
|
||||
resolution->width = 0;
|
||||
resolution->height = 0;
|
||||
resolution->refreshRate = 0;
|
||||
|
||||
int scanned = fscanf(modeFile, "%ix%i", &resolution->width, &resolution->height);
|
||||
if(scanned < 2 || resolution->width == 0 || resolution->height == 0)
|
||||
--result->resolutions.length;
|
||||
|
||||
fclose(modeFile);
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
ffStrbufDestroy(&drmDir);
|
||||
}
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance)
|
||||
{
|
||||
static FFDisplayServerResult result;
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static bool init = false;
|
||||
pthread_mutex_lock(&mutex);
|
||||
if(init)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.wmProcessName);
|
||||
ffStrbufInit(&result.wmPrettyName);
|
||||
ffStrbufInit(&result.wmProtocolName);
|
||||
ffStrbufInit(&result.deProcessName);
|
||||
ffStrbufInit(&result.dePrettyName);
|
||||
ffStrbufInit(&result.deVersion);
|
||||
ffListInitA(&result.resolutions, sizeof(FFResolutionResult), 4);
|
||||
|
||||
//We try wayland as our prefered display server, as it supports the most features.
|
||||
//This method can't detect the name of our WM / DE
|
||||
ffdsConnectWayland(instance, &result);
|
||||
|
||||
//Try the x11 libs, from most feature rich to least.
|
||||
//We use the resolution list to detect if a connection is needed.
|
||||
//They respect wmProtocolName, and only detect resolution if it is set.
|
||||
|
||||
if(result.resolutions.length == 0)
|
||||
ffdsConnectXcbRandr(instance, &result);
|
||||
|
||||
if(result.resolutions.length == 0)
|
||||
ffdsConnectXrandr(instance, &result);
|
||||
|
||||
if(result.resolutions.length == 0)
|
||||
ffdsConnectXcb(instance, &result);
|
||||
|
||||
if(result.resolutions.length == 0)
|
||||
ffdsConnectXlib(instance, &result);
|
||||
|
||||
//This resolution detection method is display server independent.
|
||||
//Use it if all connections failed
|
||||
if(result.resolutions.length == 0)
|
||||
parseDRM(&result);
|
||||
|
||||
//This fills in missing information about WM / DE by using env vars and iterating processes
|
||||
ffdsDetectWMDE(instance, &result);
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "displayserver.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
uint32_t ffdsParseRefreshRate(int32_t refreshRate)
|
||||
{
|
||||
if(refreshRate <= 0)
|
||||
return 0;
|
||||
|
||||
int remainder = refreshRate % 5;
|
||||
if(remainder >= 3)
|
||||
refreshRate += (5 - remainder);
|
||||
else
|
||||
refreshRate -= remainder;
|
||||
|
||||
//All other typicall refresh rates are dividable by 5
|
||||
if(refreshRate == 145)
|
||||
refreshRate = 144;
|
||||
|
||||
return (uint32_t) refreshRate;
|
||||
}
|
||||
|
||||
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate)
|
||||
{
|
||||
if(width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
|
||||
resolution->width = width;
|
||||
resolution->height = height;
|
||||
resolution->refreshRate = refreshRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance);
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance)
|
||||
{
|
||||
FF_DETECTION_INTERNAL_GUARD(FFDisplayServerResult,
|
||||
ffConnectDisplayServerImpl(&result, instance);
|
||||
);
|
||||
}
|
||||
@@ -25,5 +25,8 @@ typedef struct FFDisplayServerResult
|
||||
|
||||
const FFDisplayServerResult* ffConnectDisplayServer(const FFinstance* instance);
|
||||
|
||||
#endif
|
||||
//Used internal
|
||||
uint32_t ffdsParseRefreshRate(int32_t refreshRate);
|
||||
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "displayserver.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
//Resolution code heavily inspired by displayplacer <3
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t rawData[0xDC];
|
||||
struct
|
||||
{
|
||||
uint32_t mode;
|
||||
uint32_t flags; // 0x4
|
||||
uint32_t width; // 0x8
|
||||
uint32_t height; // 0xC
|
||||
uint32_t depth; // 0x10
|
||||
uint32_t dc2[42];
|
||||
uint16_t dc3;
|
||||
uint16_t freq; // 0xBC
|
||||
uint32_t dc4[4];
|
||||
float density; // 0xD0
|
||||
} derived;
|
||||
} modes_D4;
|
||||
|
||||
void CGSGetCurrentDisplayMode(CGDirectDisplayID display, int* modeNum);
|
||||
void CGSGetDisplayModeDescriptionOfLength(CGDirectDisplayID display, int idx, modes_D4* mode, int length);
|
||||
|
||||
static void detectResolution(FFDisplayServerResult* ds)
|
||||
{
|
||||
CGDisplayCount screenCount;
|
||||
CGGetOnlineDisplayList(INT_MAX, NULL, &screenCount);
|
||||
if(screenCount == 0)
|
||||
return;
|
||||
|
||||
CGDirectDisplayID* screens = malloc(screenCount * sizeof(CGDirectDisplayID));
|
||||
CGGetOnlineDisplayList(INT_MAX, screens, &screenCount);
|
||||
|
||||
for(uint32_t i = 0; i < screenCount; i++)
|
||||
{
|
||||
int modeID;
|
||||
CGSGetCurrentDisplayMode(screens[i], &modeID);
|
||||
modes_D4 mode;
|
||||
CGSGetDisplayModeDescriptionOfLength(screens[i], modeID, &mode, 0xD4);
|
||||
|
||||
uint32_t refreshRate = ffdsParseRefreshRate(mode.derived.freq);
|
||||
ffdsAppendResolution(ds, mode.derived.width, mode.derived.height, refreshRate);
|
||||
}
|
||||
|
||||
free(screens);
|
||||
}
|
||||
|
||||
static void detectWM(FFDisplayServerResult* ds)
|
||||
{
|
||||
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
|
||||
u_int requestLength = sizeof(request) / sizeof(*request);
|
||||
|
||||
size_t length = 0;
|
||||
struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length);
|
||||
if(processes == NULL)
|
||||
return;
|
||||
|
||||
for(size_t i = 0; i < length / sizeof(struct kinfo_proc); i++)
|
||||
{
|
||||
const char* comm = processes[i].kp_proc.p_comm;
|
||||
|
||||
if(
|
||||
strcasecmp(comm, "spectacle") != 0 &&
|
||||
strcasecmp(comm, "amethyst") != 0 &&
|
||||
strcasecmp(comm, "kwm") != 0 &&
|
||||
strcasecmp(comm, "chunkwm") != 0 &&
|
||||
strcasecmp(comm, "yabai") != 0 &&
|
||||
strcasecmp(comm, "rectangle") != 0
|
||||
) continue;
|
||||
|
||||
ffStrbufAppendS(&ds->wmProcessName, comm);
|
||||
ffStrbufAppendS(&ds->wmPrettyName, comm);
|
||||
ds->wmPrettyName.chars[0] = (char) toupper(ds->wmPrettyName.chars[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
free(processes);
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ffStrbufInit(&ds->wmProcessName);
|
||||
ffStrbufInit(&ds->wmPrettyName);
|
||||
ffStrbufInitA(&ds->wmProtocolName, 0);
|
||||
detectWM(ds);
|
||||
if(ds->wmProcessName.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&ds->wmProcessName, "quartz");
|
||||
ffStrbufAppendS(&ds->wmPrettyName, "Quartz Compositor");
|
||||
}
|
||||
|
||||
ffStrbufInit(&ds->deProcessName);
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffStrbufInitA(&ds->deVersion, 0);
|
||||
ffStrbufAppendS(&ds->deProcessName, "aqua");
|
||||
ffStrbufAppendS(&ds->dePrettyName, "Aqua");
|
||||
|
||||
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 4);
|
||||
detectResolution(ds);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "displayserver.h"
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ffStrbufInitA(&ds->wmProcessName, 0);
|
||||
ffStrbufInitA(&ds->wmPrettyName, 0);
|
||||
ffStrbufInitA(&ds->wmProtocolName, 0);
|
||||
ffStrbufInitA(&ds->deProcessName, 0);
|
||||
ffStrbufInitA(&ds->dePrettyName, 0);
|
||||
ffStrbufInitA(&ds->deVersion, 0);
|
||||
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 0);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "displayserver.h"
|
||||
#include "detection/os/os.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <WinUser.h>
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
BOOL enabled;
|
||||
if(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled == TRUE)
|
||||
{
|
||||
ffStrbufInitS(&ds->wmProcessName, "dwm.exe");
|
||||
ffStrbufInitS(&ds->wmPrettyName, "Desktop Window Manager");
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufInitS(&ds->wmProcessName, "internal");
|
||||
ffStrbufInitS(&ds->wmPrettyName, "internal");
|
||||
}
|
||||
ffStrbufInit(&ds->wmProtocolName);
|
||||
ffStrbufInit(&ds->deProcessName);
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffStrbufInit(&ds->deVersion);
|
||||
ffListInit(&ds->resolutions, sizeof(FFResolutionResult));
|
||||
|
||||
DISPLAY_DEVICEW displayDevice = { .cb = sizeof(DISPLAY_DEVICEW) };
|
||||
for(DWORD devNum = 0; EnumDisplayDevicesW(NULL, devNum, &displayDevice, 0) != 0; ++devNum)
|
||||
{
|
||||
if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||
continue;
|
||||
DEVMODEW devMode = { .dmSize = sizeof(DEVMODEW) };
|
||||
if(EnumDisplaySettingsW(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode) == 0)
|
||||
continue;
|
||||
|
||||
ffdsAppendResolution(ds, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency);
|
||||
}
|
||||
|
||||
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L2067
|
||||
const FFOSResult* os = ffDetectOS(instance);
|
||||
if(ffStrbufCompS(&os->version, "11") == 0 || ffStrbufCompS(&os->version, "10") == 0)
|
||||
ffStrbufSetS(&ds->dePrettyName, "Fluent");
|
||||
else if(ffStrbufCompS(&os->version, "8") == 0 || ffStrbufStartsWithS(&os->version, "8."))
|
||||
ffStrbufSetS(&ds->dePrettyName, "Metro");
|
||||
else
|
||||
ffStrbufSetS(&ds->dePrettyName, "Aero");
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "displayserver_linux.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
static void parseDRM(FFDisplayServerResult* result)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return;
|
||||
|
||||
FFstrbuf drmDir;
|
||||
ffStrbufInitA(&drmDir, 64);
|
||||
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||
|
||||
uint32_t drmDirLength = drmDir.length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
ffStrbufAppendS(&drmDir, "/modes");
|
||||
|
||||
FILE* modeFile = fopen(drmDir.chars, "r");
|
||||
if(modeFile == NULL)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFResolutionResult* resolution = ffListAdd(&result->resolutions);
|
||||
resolution->width = 0;
|
||||
resolution->height = 0;
|
||||
resolution->refreshRate = 0;
|
||||
|
||||
int scanned = fscanf(modeFile, "%ux%u", &resolution->width, &resolution->height);
|
||||
if(scanned < 2 || resolution->width == 0 || resolution->height == 0)
|
||||
--result->resolutions.length;
|
||||
|
||||
fclose(modeFile);
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
ffStrbufDestroy(&drmDir);
|
||||
}
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* instance)
|
||||
{
|
||||
ffStrbufInit(&ds->wmProcessName);
|
||||
ffStrbufInit(&ds->wmPrettyName);
|
||||
ffStrbufInit(&ds->wmProtocolName);
|
||||
ffStrbufInit(&ds->deProcessName);
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffStrbufInit(&ds->deVersion);
|
||||
ffListInitA(&ds->resolutions, sizeof(FFResolutionResult), 4);
|
||||
|
||||
//We try wayland as our prefered display server, as it supports the most features.
|
||||
//This method can't detect the name of our WM / DE
|
||||
ffdsConnectWayland(instance, ds);
|
||||
|
||||
//Try the x11 libs, from most feature rich to least.
|
||||
//We use the resolution list to detect if a connection is needed.
|
||||
//They respect wmProtocolName, and only detect resolution if it is set.
|
||||
|
||||
if(ds->resolutions.length == 0)
|
||||
ffdsConnectXcbRandr(instance, ds);
|
||||
|
||||
if(ds->resolutions.length == 0)
|
||||
ffdsConnectXrandr(instance, ds);
|
||||
|
||||
if(ds->resolutions.length == 0)
|
||||
ffdsConnectXcb(instance, ds);
|
||||
|
||||
if(ds->resolutions.length == 0)
|
||||
ffdsConnectXlib(instance, ds);
|
||||
|
||||
//This resolution detection method is display server independent.
|
||||
//Use it if all connections failed
|
||||
if(ds->resolutions.length == 0)
|
||||
parseDRM(ds);
|
||||
|
||||
//This fills in missing information about WM / DE by using env vars and iterating processes
|
||||
ffdsDetectWMDE(instance, ds);
|
||||
}
|
||||
@@ -3,16 +3,12 @@
|
||||
#ifndef FASTFETCH_INCLUDED_DISPLAYSERVER
|
||||
#define FASTFETCH_INCLUDED_DISPLAYSERVER
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "detection/displayserver.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#define FF_DISPLAYSERVER_PROTOCOL_WAYLAND "Wayland"
|
||||
#define FF_DISPLAYSERVER_PROTOCOL_X11 "X11"
|
||||
#define FF_DISPLAYSERVER_PROTOCOL_TTY "TTY"
|
||||
|
||||
uint32_t ffdsParseRefreshRate(int32_t refreshRate);
|
||||
bool ffdsAppendResolution(FFDisplayServerResult* result, uint32_t width, uint32_t height, uint32_t refreshRate);
|
||||
|
||||
void ffdsConnectWayland(const FFinstance* instance, FFDisplayServerResult* result);
|
||||
|
||||
void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result);
|
||||
@@ -1,6 +1,4 @@
|
||||
#define _GNU_SOURCE //required for struct ucred
|
||||
|
||||
#include "displayServer.h"
|
||||
#include "displayserver_linux.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -17,9 +15,11 @@ typedef struct WaylandData
|
||||
FFlist* results;
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_marshal_constructor_versioned)
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_add_listener)
|
||||
FF_LIBRARY_SYMBOL(wl_proxy_destroy)
|
||||
const struct wl_interface* ffwl_output_interface;
|
||||
} WaylandData;
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
struct ucred ucred;
|
||||
@@ -35,6 +35,12 @@ static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
|
||||
ffStrbufDestroy(&procPath);
|
||||
}
|
||||
#else
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_UNUSED(fd, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void stubListener(void* data, ...)
|
||||
{
|
||||
@@ -43,10 +49,10 @@ static void stubListener(void* data, ...)
|
||||
|
||||
static void waylandOutputModeListener(void* data, struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
|
||||
{
|
||||
FF_UNUSED(output);
|
||||
|
||||
WaylandData* wldata = data;
|
||||
|
||||
wldata->ffwl_proxy_destroy((struct wl_proxy*) output);
|
||||
|
||||
if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
@@ -96,7 +102,7 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
||||
|
||||
bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(wayland, instance->config.libWayland, false, "libwayland-client.so", 1)
|
||||
FF_LIBRARY_LOAD(wayland, &instance->config.libWayland, false, "libwayland-client.so", 1)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
|
||||
@@ -108,9 +114,10 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
|
||||
WaylandData data;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, wl_proxy_marshal_constructor_versioned, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_add_listener, wl_proxy_add_listener, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_output_interface, wl_output_interface, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_marshal_constructor_versioned, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_add_listener, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_proxy_destroy, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(wayland, data, wl_output_interface, false)
|
||||
|
||||
struct wl_display* display = ffwl_display_connect(NULL);
|
||||
if(display == NULL)
|
||||
@@ -140,7 +147,8 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
ffwl_display_dispatch(display);
|
||||
ffwl_display_roundtrip(display);
|
||||
|
||||
ffwl_display_disconnect(display); //This will also destroy our wl_registry and wl_output proxies
|
||||
data.ffwl_proxy_destroy(registry);
|
||||
ffwl_display_disconnect(display);
|
||||
dlclose(wayland);
|
||||
|
||||
//We successfully connected to wayland and detected the resolution.
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "displayServer.h"
|
||||
#include "displayserver_linux.h"
|
||||
#include "common/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
@@ -129,6 +129,10 @@ static void getKDE(FFDisplayServerResult* result)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/wayland-sessions/plasmawayland5.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/local/share/xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
if(result->deVersion.length == 0)
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/local/share/wayland-sessions/plasmawayland.desktop", "X-KDE-PluginInfo-Version =", &result->deVersion);
|
||||
|
||||
applyBetterWM(result, getenv("KDEWM"));
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "displayServer.h"
|
||||
#include "displayserver_linux.h"
|
||||
|
||||
#ifdef FF_HAVE_XCB
|
||||
#include "common/library.h"
|
||||
@@ -18,12 +18,12 @@ typedef struct XcbPropertyData
|
||||
|
||||
static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyData)
|
||||
{
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_intern_atom, xcb_intern_atom, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_intern_atom_reply, xcb_intern_atom_reply, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_get_property, xcb_get_property, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_get_property_reply, xcb_get_property_reply, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_get_property_value, xcb_get_property_value, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(libraryHandle, propertyData->ffxcb_get_property_value_length, xcb_get_property_value_length, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_intern_atom_reply, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_reply, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_value, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, xcb_get_property_value_length, false)
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
|
||||
|
||||
void ffdsConnectXcb(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcb, instance->config.libXcb, , "libxcb.so", 2)
|
||||
FF_LIBRARY_LOAD(xcb, &instance->config.libXcb, , "libxcb.so", 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcb, xcb_setup_roots_iterator,)
|
||||
@@ -326,7 +326,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
|
||||
void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xcbRandr, instance->config.libXcbRandr, , "libxcb-randr.so", 1)
|
||||
FF_LIBRARY_LOAD(xcbRandr, &instance->config.libXcbRandr, , "libxcb-randr.so", 1)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_connect,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_get_setup,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xcbRandr, xcb_setup_roots_iterator,)
|
||||
@@ -335,23 +335,23 @@ void ffdsConnectXcbRandr(const FFinstance* instance, FFDisplayServerResult* resu
|
||||
|
||||
XcbRandrData data;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_screen_resources, xcb_randr_get_screen_resources,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_screen_resources_reply, xcb_randr_get_screen_resources_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_screen_resources_modes_iterator, xcb_randr_get_screen_resources_modes_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_screen_info, xcb_randr_get_screen_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_screen_info_reply, xcb_randr_get_screen_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_mode_info_next, xcb_randr_mode_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_monitors, xcb_randr_get_monitors,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_monitors_reply, xcb_randr_get_monitors_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_monitors_monitors_iterator, xcb_randr_get_monitors_monitors_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_monitor_info_next, xcb_randr_monitor_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_monitor_info_outputs_length, xcb_randr_monitor_info_outputs_length,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_monitor_info_outputs, xcb_randr_monitor_info_outputs,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_output_next, xcb_randr_output_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_output_info, xcb_randr_get_output_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_output_info_reply, xcb_randr_get_output_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_crtc_info, xcb_randr_get_crtc_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xcbRandr, data.ffxcb_randr_get_crtc_info_reply, xcb_randr_get_crtc_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_resources_modes_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_screen_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_mode_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_monitors_monitors_iterator,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs_length,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_monitor_info_outputs,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_output_next,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_output_info_reply,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info,)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(xcbRandr, data, xcb_randr_get_crtc_info_reply,)
|
||||
|
||||
XcbPropertyData propertyData;
|
||||
bool propertyDataInitialized = xcbInitPropertyData(xcbRandr, &propertyData);
|
||||