mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
336 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f92524ada | |||
| b2ff1501aa | |||
| fbb4ab590f | |||
| e2cadf85f8 | |||
| b5c2c9ee7a | |||
| 1dabac9782 | |||
| 50983f83f5 | |||
| 5026be2d28 | |||
| 70aad5c320 | |||
| e74d21c0e5 | |||
| 90d8677b7a | |||
| 7a5d88270e | |||
| 5599335965 | |||
| e829589875 | |||
| 98acd516b8 | |||
| 584d792f5a | |||
| e6db860861 | |||
| f0ec3cb9ec | |||
| 0801e22dce | |||
| 5efd7b9ac4 | |||
| f2bae200d3 | |||
| fd14513aef | |||
| 6becc8f334 | |||
| 90359d227e | |||
| 6ff67e87eb | |||
| 0a83423731 | |||
| 5160644016 | |||
| d956bd2643 | |||
| 7a6a2ad530 | |||
| 21c76f31c4 | |||
| cb48c1277a | |||
| 3c18fd8920 | |||
| 83c6e809c6 | |||
| dc35fedd74 | |||
| 947923567f | |||
| 3d19388086 | |||
| 051f6643a6 | |||
| 47e01a7157 | |||
| a336145ed9 | |||
| ecc6b477dc | |||
| e0c6c462a6 | |||
| 3e607680e2 | |||
| 89347b7bee | |||
| c45ef08926 | |||
| 8d40b2cd0e | |||
| 14e318c273 | |||
| f50b478966 | |||
| 0cacedfc5d | |||
| 5283f10189 | |||
| c9c2526f08 | |||
| fba4bca46e | |||
| a95eb65faa | |||
| bcc7b630ae | |||
| a247a8d6ba | |||
| 620adc0ec6 | |||
| d5b3ae9056 | |||
| afe56a36c9 | |||
| 265b98311a | |||
| 89983a28b4 | |||
| c9918035ed | |||
| 225d1dd4d2 | |||
| 985fc991e8 | |||
| 8f3900a9df | |||
| d21ce9b10f | |||
| 1153d29099 | |||
| 75341e8172 | |||
| 2f5cbfb03a | |||
| 01d2d77efd | |||
| 1b2a61ed49 | |||
| 10584eb01a | |||
| d4ec500b1b | |||
| c7bec3d0c9 | |||
| ff6e982050 | |||
| 6a49ae60a1 | |||
| 27fb0c6c06 | |||
| 047b32e7d9 | |||
| eeb008f505 | |||
| 704834b370 | |||
| a3cb6608ce | |||
| 7640042905 | |||
| d601cc823c | |||
| 338cc1db40 | |||
| 6710967d19 | |||
| e4a5194115 | |||
| d151901049 | |||
| c9e9ec3a80 | |||
| 54912df237 | |||
| b09aa3240a | |||
| c9bc1f8306 | |||
| 7e98fa8626 | |||
| 3b2c189083 | |||
| c242001a77 | |||
| b21cfc127a | |||
| 3a5af1bbb3 | |||
| 68b98c1bd2 | |||
| 24ae7ec6e0 | |||
| e3590bc673 | |||
| 72dcc5223d | |||
| 4558af2e43 | |||
| ed259fad9c | |||
| b4e2997389 | |||
| d946a46d3f | |||
| 983bd50a09 | |||
| 4f0be4f72c | |||
| 58aa3e94e4 | |||
| 19ec59cca5 | |||
| 911780ba3c | |||
| 8b0d034a94 | |||
| 2a8235ae38 | |||
| 15a98a83cd | |||
| 1dc578badb | |||
| be698bd806 | |||
| 0cad657ce2 | |||
| 7991abab0b | |||
| b3e635a923 | |||
| 57b794cbd9 | |||
| 974dc96259 | |||
| db33d246cb | |||
| 5e5442426c | |||
| a55add190c | |||
| 5c381460ce | |||
| 4cf1d5bf94 | |||
| 4316ba988b | |||
| c6a9217c74 | |||
| 34d3021b80 | |||
| c57417e834 | |||
| 00f86c6346 | |||
| 0ab38bb4d7 | |||
| 7da45d6c2c | |||
| 3c7f02bee3 | |||
| 686a66e5f1 | |||
| c50d7bf974 | |||
| d70b3100f2 | |||
| d500bdff96 | |||
| 8de88adc0b | |||
| 4b3ed67877 | |||
| 11258c0d8d | |||
| 325aa536c4 | |||
| 31863baee2 | |||
| 0f08233581 | |||
| b28da1057c | |||
| 4fa3ca98a2 | |||
| 66f8a8cdd0 | |||
| 051423e75e | |||
| ae562ac962 | |||
| 772dd1e294 | |||
| 27212e8b98 | |||
| 629c2de253 | |||
| 9ef95e43a3 | |||
| 6a304dbb4d | |||
| 4355039329 | |||
| 5aebb400da | |||
| fbd8c0237f | |||
| 04c9d16c16 | |||
| 308408a962 | |||
| 19c5904561 | |||
| c0037c99e4 | |||
| b85c1c44b8 | |||
| 1c69d6c788 | |||
| b6b95581cd | |||
| 55c6374949 | |||
| 0a65867937 | |||
| 859f645fe5 | |||
| f1cc94207e | |||
| 70847857f7 | |||
| 2a34978487 | |||
| fde9379bb2 | |||
| e8e586ce7c | |||
| fb78d9bbb9 | |||
| a498e9e142 | |||
| d0d6f48751 | |||
| 0361a30c40 | |||
| d0c18c4679 | |||
| 8aca8a2229 | |||
| 0bbecb3b33 | |||
| 3f008c4b6d | |||
| 227eb707d2 | |||
| a5306d60ee | |||
| e3de39d3ab | |||
| f4666fcb0a | |||
| 85a554b60d | |||
| 1ea44417d0 | |||
| 0605cb754b | |||
| f889d919f8 | |||
| d670a9a584 | |||
| e51b8276cd | |||
| 67feba6171 | |||
| 922de3755b | |||
| 9da7bb3f30 | |||
| 46ebb52afa | |||
| 4f97692245 | |||
| 25a833207e | |||
| 8224f8c4c6 | |||
| c455718ada | |||
| 37b1d24575 | |||
| 449d121f19 | |||
| 9a51d203de | |||
| 0e92fc2289 | |||
| 54c649e76e | |||
| 45f8b86f13 | |||
| a8a1f98a8f | |||
| b8f14c964a | |||
| de964d3e77 | |||
| 4634606a36 | |||
| 5d306ed9f3 | |||
| ba1fc7a03e | |||
| 8b43605abf | |||
| 2ee5b3b7a5 | |||
| 302a588812 | |||
| 2a1330dea3 | |||
| 5472621ac0 | |||
| 9ad7ba7144 | |||
| 895d151e2e | |||
| 3ee15d0401 | |||
| 60ad6792ba | |||
| b878d3ccf6 | |||
| f93bd9e28b | |||
| 9c73f6b787 | |||
| 64b9f69fb1 | |||
| aca2c01c9e | |||
| 470d160346 | |||
| e225b496b1 | |||
| f470744e44 | |||
| 42fec6e61f | |||
| 883a535441 | |||
| 65b342cac7 | |||
| 1395abcf09 | |||
| e59d64513f | |||
| ed85b8249a | |||
| bddf1c67bf | |||
| 62ab091350 | |||
| 1588f58726 | |||
| 688a16c941 | |||
| 69b3a6871f | |||
| 0aac358e33 | |||
| 7f82f8d679 | |||
| 5fb96223a8 | |||
| e13c88cea6 | |||
| fbc76714f5 | |||
| c7adbc1309 | |||
| b27453d275 | |||
| aa0501b853 | |||
| 596c776463 | |||
| eb1738b1c6 | |||
| 0505926c75 | |||
| 581c6f547d | |||
| 3d5ef186ba | |||
| e3ea39afaa | |||
| 7f9269cff2 | |||
| bbcc040dc4 | |||
| 727a6988c2 | |||
| 7bbd2aee94 | |||
| b812f1dcb4 | |||
| fb2dca2eaf | |||
| a03eaed4e2 | |||
| ee705363c1 | |||
| c1fec9b411 | |||
| 19a9b18c69 | |||
| 38b3aae1e3 | |||
| 5d5663e2a7 | |||
| 973eb8127e | |||
| 2499cbdab8 | |||
| ec80a41871 | |||
| a829e85ef5 | |||
| a090bed6c0 | |||
| 76684e49ca | |||
| c1fc6e2762 | |||
| 437431a821 | |||
| 5749a8f7c1 | |||
| 54e271c985 | |||
| b042b90d9b | |||
| a99ca9a1a1 | |||
| f05d036023 | |||
| 5a55691358 | |||
| 4f0dd51761 | |||
| 0ca6f76e88 | |||
| 869f544bab | |||
| 4f67ed2b77 | |||
| 3f4926cbd5 | |||
| af93157a76 | |||
| 220a7d24bc | |||
| 3b541d3670 | |||
| 4bd6f2da89 | |||
| d5e00c3517 | |||
| 1b7a2c2ed5 | |||
| 11ad7a8a3d | |||
| 622f84c971 | |||
| 779a33349a | |||
| 135ca1eeba | |||
| 2dee7f5982 | |||
| 1513b8c0db | |||
| 693cc1e730 | |||
| e18980be9f | |||
| cf048bc723 | |||
| 3004d8c9dc | |||
| 6f66b87262 | |||
| 79cfa96616 | |||
| 952cacf3ff | |||
| 3cc6611614 | |||
| 457c2da67d | |||
| 13769e0e52 | |||
| b33e042cd4 | |||
| 2689a20889 | |||
| d769fd32f0 | |||
| 2c82c9a6dc | |||
| 3850130583 | |||
| 06262c078d | |||
| b64a234f8a | |||
| dfed3812ce | |||
| 1b594d9ed1 | |||
| d0f589bb3e | |||
| bc72f3cd64 | |||
| de8f1a86c6 | |||
| 4bae08c159 | |||
| 34cd81b4d9 | |||
| 8c127a175c | |||
| 5e3e2b6137 | |||
| 88a16d4c7d | |||
| 296674cfd6 | |||
| 875174e2e0 | |||
| 4393fa1a47 | |||
| 5ae2031bcf | |||
| 779266e61e | |||
| 8e8d283959 | |||
| 2cb7be67bd | |||
| 9bc5c99fc8 | |||
| 424fbfc9c9 | |||
| 3d2497f963 | |||
| 2e42bbb1a2 | |||
| 9879a95570 | |||
| d54f14a14c | |||
| cdcac06dbf | |||
| 6b81223002 | |||
| df986d36a2 | |||
| 173c9043e3 | |||
| 488986e42e |
+1
-1
@@ -10,7 +10,7 @@ trim_trailing_whitespace = true
|
||||
[*.{md,fflogo}]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{txt,fflogo}]
|
||||
[*.{fflogo}]
|
||||
insert_final_newline = false
|
||||
|
||||
[*.yml]
|
||||
|
||||
@@ -39,5 +39,5 @@ Output of `fastfetch --list-features`:
|
||||
|
||||
<!--
|
||||
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
|
||||
If this isn't possible (or too much work) for you, post the output of `fastfetch --show-errors --recache --multithreading false --disable-linewrap false`.
|
||||
If this isn't possible (or too much work) for you, post the output of `fastfetch --show-errors --multithreading false --disable-linewrap false`.
|
||||
-->
|
||||
|
||||
+162
-13
@@ -35,17 +35,17 @@ jobs:
|
||||
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
|
||||
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: get fastfetch version
|
||||
id: ffversion
|
||||
run: echo "::set-output name=ffversion::$(./fastfetch --version-raw)"
|
||||
run: echo "ffversion=$(./fastfetch --version-raw)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install required packages
|
||||
run: brew install vulkan-loader molten-vk
|
||||
run: brew install vulkan-loader molten-vk imagemagick chafa
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
@@ -81,10 +81,10 @@ jobs:
|
||||
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
|
||||
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: ./flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
@@ -95,8 +95,8 @@ jobs:
|
||||
name: fastfetch-macos
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
bsd:
|
||||
name: BSD
|
||||
freebsd:
|
||||
name: FreeBSD
|
||||
runs-on: macos-12
|
||||
permissions:
|
||||
security-events: write
|
||||
@@ -113,16 +113,164 @@ jobs:
|
||||
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
|
||||
time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
time ./flashfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-bsd
|
||||
name: fastfetch-freebsd
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
# https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785
|
||||
- name: create OpenCL.pc
|
||||
run: |
|
||||
cat > /clang64/lib/pkgconfig/OpenCL.pc << EOF
|
||||
prefix=/clang64
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: OpenCL
|
||||
Description: Open Computing Language generic Installable Client Driver Loader
|
||||
Version: 2022.09.30-1
|
||||
Libs: -L${libdir} -lOpenCL.dll
|
||||
Cflags: -I${includedir}
|
||||
EOF
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c, cpp
|
||||
|
||||
- name: configure project
|
||||
run: env PKG_CONFIG_PATH=/clang64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{libcjson,libOpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: zip fastfetch-windows.zip *.dll fastfetch.exe flashfetch.exe
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-windows
|
||||
path: ./fastfetch-windows.zip
|
||||
|
||||
windows-old:
|
||||
name: Windows-old
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: setup-msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: git zip mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-cjson mingw-w64-x86_64-vulkan-loader mingw-w64-x86_64-opencl-icd
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
|
||||
# https://github.com/msys2/MINGW-packages/issues/13524#event-7555720785
|
||||
- name: create OpenCL.pc
|
||||
run: |
|
||||
cat > /mingw64/lib/pkgconfig/OpenCL.pc << EOF
|
||||
prefix=/mingw64
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: OpenCL
|
||||
Description: Open Computing Language generic Installable Client Driver Loader
|
||||
Version: 2022.09.30-1
|
||||
Libs: -L${libdir} -lOpenCL.dll
|
||||
Cflags: -I${includedir}
|
||||
EOF
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: c, cpp
|
||||
|
||||
- name: configure project
|
||||
run: env PKG_CONFIG_PATH=/mingw64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_BUFFER=Off .
|
||||
|
||||
- name: build project
|
||||
run: cmake --build .
|
||||
|
||||
- name: perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
- name: copy necessary dlls
|
||||
run: cp /mingw64/bin/{libcjson,libOpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch --disable-linewrap false --hide-cursor false --show-errors true --load-config presets/all
|
||||
|
||||
- name: run flashfetch
|
||||
run: time ./flashfetch
|
||||
|
||||
- name: run tests
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: zip fastfetch-windows-old.zip *.dll fastfetch.exe flashfetch.exe
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: fastfetch-windows-old
|
||||
path: ./fastfetch-windows-old.zip
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'LinusDierheimer/fastfetch'
|
||||
name: Release
|
||||
@@ -130,7 +278,8 @@ jobs:
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- bsd
|
||||
- freebsd
|
||||
- windows
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
@@ -150,4 +299,4 @@ jobs:
|
||||
tag: ${{ needs.linux.outputs.ffversion }}
|
||||
commit: ${{ github.sha }}
|
||||
artifactErrorsFailBuild: true
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-bsd/*
|
||||
artifacts: fastfetch-linux/*,fastfetch-macos/*,fastfetch-freebsd/*,fastfetch-windows/*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
**/.cache/
|
||||
**/.kdev4/
|
||||
**/.DS_Store
|
||||
/.vs
|
||||
cscope.*
|
||||
tags
|
||||
fastfetch.kdev4
|
||||
|
||||
+107
@@ -1,3 +1,110 @@
|
||||
# 1.8.1
|
||||
|
||||
Notable Changes:
|
||||
|
||||
* `Song` was used as an alias to `Media` module. It's removed to avoid confusion. All song related flags (`--song-key`, etc) should change to media (`--media-key`, etc). (@CarterLi)
|
||||
|
||||
Bugfixes:
|
||||
|
||||
* Mountpoint paths on linux get decoded correctly (#364)
|
||||
* Color parsing once again works (@IanManske, #365)
|
||||
* Using a custom key with a placeholder for the local ip module now does work correctly if multiple interfaces are present (#368)
|
||||
|
||||
# 1.8.0
|
||||
|
||||
This release introduces Windows support! Fastfetch now fully support all major desktop OSes (Linux, macOS, Windows and FreeBSD)
|
||||
|
||||
Notable Changes:
|
||||
* Bios / Board / Chassis modules are splitted against Host module for performance reasons
|
||||
* Caching is removed. Option `--nocache` is removed accordingly
|
||||
|
||||
Features:
|
||||
* Windows (7 and newer) is officially and fully supported
|
||||
* FreeBSD support is improved greatly (Bios, Cpu Temp, Cpu Usage, Disk, Host, Processes, Swap, Terminal / Shell, Uptime)
|
||||
* Adds a new flag `--stat`, which prints time usage for individual modules
|
||||
* Adds Wifi module which supports Windows and macOS
|
||||
* Adds data source option for logo printing
|
||||
* Detects Homebrew Cellar and Cask seperately
|
||||
* Detects WSL version
|
||||
* Detects disk based on mount point
|
||||
* Exposes more chafa configs
|
||||
* Improves performance for Cpu Usage, Public IP, Weather modules
|
||||
* Improves performance for Kitty image protocol when both image width / height specified
|
||||
* Improves performance for large file loading
|
||||
* Improves performance for macOS WM and Host detection
|
||||
* Improves shell and terminal detection on macOS
|
||||
* Supports Deepin Terminal terminal font
|
||||
* Supports GPU detection on Android
|
||||
* Supports Kitty Terminal terminal font
|
||||
* Supports bar output for percentage values
|
||||
* Supports Bios module on macOS
|
||||
* Supports eopkg package manager detection
|
||||
* Supports iTerm image logo protocol
|
||||
* Supports image logo printing on macOS
|
||||
* Supports tcsh version detection
|
||||
* Vulkan module on macOS no longer requires vulkan-loader to work
|
||||
|
||||
Logos:
|
||||
* Alpine
|
||||
* CRUX
|
||||
* EndeavourOS
|
||||
* Enso
|
||||
* Garuda small
|
||||
* Nobara
|
||||
* OpenMandriva
|
||||
* Parabola GNU/Linux-libre
|
||||
* Rocky
|
||||
* Rosa
|
||||
* Solus
|
||||
* Univalent
|
||||
* Vanilla OS
|
||||
|
||||
Bugfixes:
|
||||
* Fixes disk size detection on 32bit Linux (#337)
|
||||
* Fixes cpu freq detection in WSL
|
||||
* Fixes internal bug of FFstrbuf
|
||||
* Fixes some memory leaks
|
||||
* Fixes segfault if 0 is given as argument index
|
||||
* Lots of code refactors
|
||||
|
||||
# 1.7.5
|
||||
|
||||
Fixes a crash on linux that could happen when getting zsh version (#285)
|
||||
|
||||
# 1.7.4
|
||||
|
||||
The last element in the default structure (currently the color blocks) is now printed again (#283)
|
||||
|
||||
# 1.7.3
|
||||
|
||||
A lot of small improvements for MacOS & BSD platforms.
|
||||
|
||||
Features:
|
||||
* BSD is now officially supported (#228)
|
||||
* MacPorts package manager support (@SladeGetz, #234)
|
||||
* Battery support for MacOS (@CarterLi, #235)
|
||||
* Processes, swap & terminal font support for MacOS(@CarterLi, #237)
|
||||
* Media support for MacOS (@CarterLi, #242)
|
||||
* Player support for MacOS (@CarterLi, #245)
|
||||
* WM theme support for MacOS (@CarterLi, #246)
|
||||
* CPU usage support for MacOS (@CarterLi, #247)
|
||||
* Power Adapter module (@CarterLi, #249)
|
||||
* Windows terminal font for WSL (@CarterLi, #254)
|
||||
* Temps & Font support for MacOS (@CarterLi, #258)
|
||||
* Terminal font support for Termux (@CarterLi, #263)
|
||||
* Weather module (@CarterLi, #266)
|
||||
|
||||
Logos
|
||||
* Crystal linux (@AloneER0, #239)
|
||||
* FreeBSD (@draumaz, #244)
|
||||
* New Ubuntu (@AloneER0, #259)
|
||||
|
||||
Bugfixes:
|
||||
* Don't segfault in GPU code on Intel Macs (@CarterLi, #236)
|
||||
* Don't use hardcoded size units in presets (@dr460nf1r3, #255)
|
||||
* Don't crash with some format strings (#252)
|
||||
* --logo-none keeps key color now (#264)
|
||||
|
||||
# 1.7.2
|
||||
|
||||
Fixes the bash completions
|
||||
|
||||
+447
-259
@@ -1,28 +1,45 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 1.7.2
|
||||
VERSION 1.8.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast system information tool"
|
||||
HOMEPAGE_URL "https://github.com/LinusDierheimer/fastfetch"
|
||||
)
|
||||
|
||||
set(PROJECT_LICENSE "MIT license")
|
||||
|
||||
###################
|
||||
# Target Platform #
|
||||
###################
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES ".*[Ll]inux.*")
|
||||
if(ANDROID)
|
||||
set(LINUX FALSE)
|
||||
elseif("${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)
|
||||
elseif(NOT APPLE AND NOT WIN32)
|
||||
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
|
||||
if(MSYS)
|
||||
if(WIN32)
|
||||
enable_language(CXX)
|
||||
endif()
|
||||
|
||||
#############################
|
||||
# Compile time dependencies #
|
||||
#############################
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG NOT WIN32)
|
||||
find_package(Threads)
|
||||
|
||||
find_package(PkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
message(WARNING "pkg-config not found, library detection might be limited")
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
|
||||
#####################
|
||||
# Configure options #
|
||||
#####################
|
||||
@@ -30,7 +47,7 @@ endif()
|
||||
include(CMakeDependentOption)
|
||||
|
||||
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_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" 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)
|
||||
@@ -42,31 +59,24 @@ 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_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE OR WIN32" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE" 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_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBCJSON "Enable libcjson" ON "LINUX OR WIN32" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND AND NOT ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_BUFFER "Enable stdout buffer" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
|
||||
cmake_dependent_option(USE_WIN_NTAPI "Allow using internal NTAPI" ON "WIN32" OFF)
|
||||
cmake_dependent_option(USE_WIN_GPU_DXGI "Use DXGI to detect GPUs instead of WMI. Faster, but may ignore GPUs that only support DX9" ON "WIN32" 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 #
|
||||
#############################
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
include(CheckIncludeFile)
|
||||
|
||||
####################
|
||||
# Compiler options #
|
||||
####################
|
||||
@@ -76,11 +86,20 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
if(ENABLE_THREADS)
|
||||
if(CMAKE_USE_WIN32_THREADS_INIT)
|
||||
message(STATUS "Threads type: Win32 thread")
|
||||
elseif(CMAKE_USE_PTHREADS_INIT)
|
||||
message(STATUS "Threads type: pthread")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Threads type: disabled")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion")
|
||||
|
||||
if(MSYS)
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti")
|
||||
endif()
|
||||
@@ -92,16 +111,18 @@ if(APPLE AND DEFINED ENV{HOMEBREW_PREFIX})
|
||||
endif()
|
||||
|
||||
set(FASTFETCH_FLAGS_DEBUG "-fno-omit-frame-pointer")
|
||||
if(NOT MSYS)
|
||||
if(NOT WIN32)
|
||||
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)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
if(IPO_SUPPORTED)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#######################
|
||||
@@ -160,6 +181,11 @@ if (SET_TWEAK AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
)
|
||||
string(REGEX MATCH "-[0-9]+" PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}")
|
||||
endif()
|
||||
if(PROJECT_VERSION_TWEAK)
|
||||
string(REGEX MATCH "[0-9]+" PROJECT_VERSION_TWEAK_NUM "${PROJECT_VERSION_TWEAK}")
|
||||
else()
|
||||
set(PROJECT_VERSION_TWEAK_NUM 0)
|
||||
endif()
|
||||
|
||||
#############
|
||||
# Text data #
|
||||
@@ -167,9 +193,10 @@ endif()
|
||||
|
||||
function(fastfetch_load_text FILENAME OUTVAR)
|
||||
file(READ "${FILENAME}" TEMP)
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}")
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}")
|
||||
string(REPLACE "$\\" "" TEMP "${TEMP}")
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${TEMP}") # Remove trailing newline
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||
string(REPLACE "$\\" "" TEMP "${TEMP}") # Remove $\, so we can unescape some things
|
||||
set("${OUTVAR}" "${TEMP}" PARENT_SCOPE)
|
||||
endfunction(fastfetch_load_text)
|
||||
|
||||
@@ -193,225 +220,274 @@ configure_file(src/fastfetch_config.h.in fastfetch_config.h)
|
||||
#######################
|
||||
|
||||
set(LIBFASTFETCH_SRC
|
||||
src/util/FFstrbuf.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFvaluestore.c
|
||||
src/common/init.c
|
||||
src/common/io.c
|
||||
src/common/printing.c
|
||||
src/common/caching.c
|
||||
src/common/properties.c
|
||||
src/common/bar.c
|
||||
src/common/font.c
|
||||
src/common/format.c
|
||||
src/common/parsing.c
|
||||
src/common/settings.c
|
||||
src/common/init.c
|
||||
src/common/io.c
|
||||
src/common/library.c
|
||||
src/common/networking.c
|
||||
src/logo/logo.c
|
||||
src/logo/builtin.c
|
||||
src/logo/image/image.c
|
||||
src/logo/image/im7.c
|
||||
src/logo/image/im6.c
|
||||
src/detection/vulkan.c
|
||||
src/detection/datetime.c
|
||||
src/detection/title.c
|
||||
src/detection/host/host.c
|
||||
src/detection/os/os.c
|
||||
src/common/parsing.c
|
||||
src/common/printing.c
|
||||
src/common/properties.c
|
||||
src/common/settings.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/datetime.c
|
||||
src/detection/disk/disk.c
|
||||
src/detection/displayserver/displayserver.c
|
||||
src/detection/terminalfont/terminalfont.c
|
||||
src/detection/font/font.c
|
||||
src/detection/gpu/gpu.c
|
||||
src/detection/host/host.c
|
||||
src/detection/locale/locale.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/detection/os/os.c
|
||||
src/detection/packages/packages.c
|
||||
src/detection/terminalfont/terminalfont.c
|
||||
src/detection/terminalshell/terminalshell.c
|
||||
src/detection/title.c
|
||||
src/detection/vulkan.c
|
||||
src/logo/builtin.c
|
||||
src/logo/image/im6.c
|
||||
src/logo/image/im7.c
|
||||
src/logo/image/image.c
|
||||
src/logo/logo.c
|
||||
src/modules/battery.c
|
||||
src/modules/bios.c
|
||||
src/modules/board.c
|
||||
src/modules/kernel.c
|
||||
src/modules/uptime.c
|
||||
src/modules/processes.c
|
||||
src/modules/packages.c
|
||||
src/modules/shell.c
|
||||
src/modules/resolution.c
|
||||
src/modules/de.c
|
||||
src/modules/wm.c
|
||||
src/modules/wmtheme.c
|
||||
src/modules/theme.c
|
||||
src/modules/icons.c
|
||||
src/modules/font.c
|
||||
src/modules/cursor.c
|
||||
src/modules/terminal.c
|
||||
src/modules/terminalfont.c
|
||||
src/modules/break.c
|
||||
src/modules/chassis.c
|
||||
src/modules/colors.c
|
||||
src/modules/cpu.c
|
||||
src/modules/cpuUsage.c
|
||||
src/modules/gpu.c
|
||||
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
|
||||
src/modules/cursor.c
|
||||
src/modules/custom.c
|
||||
src/modules/date.c
|
||||
src/modules/time.c
|
||||
src/modules/colors.c
|
||||
src/modules/opengl.c
|
||||
src/modules/datetime.c
|
||||
src/modules/de.c
|
||||
src/modules/disk.c
|
||||
src/modules/font.c
|
||||
src/modules/gpu.c
|
||||
src/modules/host.c
|
||||
src/modules/icons.c
|
||||
src/modules/kernel.c
|
||||
src/modules/locale.c
|
||||
src/modules/localip.c
|
||||
src/modules/memory.c
|
||||
src/modules/opencl.c
|
||||
src/modules/opengl.c
|
||||
src/modules/os.c
|
||||
src/modules/packages.c
|
||||
src/modules/player.c
|
||||
src/modules/poweradapter.c
|
||||
src/modules/processes.c
|
||||
src/modules/publicip.c
|
||||
src/modules/resolution.c
|
||||
src/modules/separator.c
|
||||
src/modules/shell.c
|
||||
src/modules/media.c
|
||||
src/modules/terminal.c
|
||||
src/modules/terminalfont.c
|
||||
src/modules/theme.c
|
||||
src/modules/time.c
|
||||
src/modules/title.c
|
||||
src/modules/uptime.c
|
||||
src/modules/users.c
|
||||
src/modules/vulkan.c
|
||||
src/modules/weather.c
|
||||
src/modules/wifi.c
|
||||
src/modules/wm.c
|
||||
src/modules/wmtheme.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFstrbuf.c
|
||||
src/util/FFvaluestore.c
|
||||
)
|
||||
|
||||
if(LINUX OR APPLE OR ANDROID OR BSD)
|
||||
if(LINUX)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/users/users_linux.c
|
||||
src/common/networking_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(BSD OR APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/sysctl.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LINUX OR ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
)
|
||||
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(LINUX OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/host/host_linux.c
|
||||
src/detection/battery/battery_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/chassis/chassis_linux.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/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/gpu/gpu_linux.c
|
||||
src/detection/gtk.c
|
||||
)
|
||||
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/host/host_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_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
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/qt.c
|
||||
src/detection/swap/swap_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/uptime/uptime_linux.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wifi/wifi_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/bios/bios_nosupport.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/displayserver/displayserver_nosupport.c
|
||||
src/detection/font/font_nosupport.c
|
||||
src/detection/gpu/gpu_nosupport.c
|
||||
src/detection/host/host_android.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_android.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/swap/swap_linux.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/uptime/uptime_linux.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wifi/wifi_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
)
|
||||
elseif(BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/bios/bios_bsd.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/cpuUsage/cpuUsage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/wayland.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/gpu/gpu_linux.c
|
||||
src/detection/gtk.c
|
||||
src/detection/host/host_bsd.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_bsd.c
|
||||
src/detection/qt.c
|
||||
src/detection/swap/swap_bsd.c
|
||||
src/detection/temps/temps_linux.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/uptime/uptime_bsd.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wifi/wifi_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
)
|
||||
elseif(APPLE)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/common/sysctl.c
|
||||
src/detection/battery/battery_apple.c
|
||||
src/detection/bios/bios_apple.c
|
||||
src/detection/board/board_nosupport.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_apple.c
|
||||
src/detection/cpuUsage/cpuUsage_apple.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/disk/disk_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
src/detection/gpu/gpu_apple.c
|
||||
src/detection/host/host_apple.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/memory/memory_apple.c
|
||||
src/detection/opengl/opengl_apple.c
|
||||
src/detection/os/os_apple.m
|
||||
src/detection/packages/packages_apple.c
|
||||
src/detection/poweradapter/poweradapter_apple.c
|
||||
src/detection/processes/processes_bsd.c
|
||||
src/detection/swap/swap_apple.c
|
||||
src/detection/temps/temps_apple.c
|
||||
src/detection/terminalfont/terminalfont_apple.m
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/uptime/uptime_bsd.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wifi/wifi_apple.m
|
||||
src/detection/wmtheme/wmtheme_apple.m
|
||||
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(BSD)
|
||||
elseif(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/memory/memory_bsd.c
|
||||
)
|
||||
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/common/networking_windows.c
|
||||
src/common/processing_windows.c
|
||||
src/detection/battery/battery_windows.c
|
||||
src/detection/bios/bios_windows.c
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_windows.c
|
||||
src/detection/cpuUsage/cpuUsage_windows.c
|
||||
src/detection/cursor/cursor_windows.c
|
||||
src/detection/disk/disk_windows.c
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.cpp
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/localip/localip_windows.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/memory/memory_windows.c
|
||||
src/detection/opengl/opengl_windows.c
|
||||
src/detection/os/os_windows.cpp
|
||||
src/detection/packages/packages_windows.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_windows.cpp
|
||||
src/detection/swap/swap_windows.cpp
|
||||
src/detection/terminalfont/terminalfont_windows.c
|
||||
src/detection/terminalshell/terminalshell_windows.cpp
|
||||
src/detection/uptime/uptime_windows.c
|
||||
src/detection/users/users_windows.c
|
||||
src/detection/wifi/wifi_windows.c
|
||||
src/detection/wmtheme/wmtheme_windows.c
|
||||
src/util/windows/getline.c
|
||||
src/util/windows/pwd.c
|
||||
src/util/windows/registry.c
|
||||
src/util/windows/unicode.c
|
||||
src/util/windows/utsname.c
|
||||
src/util/windows/wmi.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -421,31 +497,38 @@ add_library(libfastfetch OBJECT
|
||||
|
||||
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()
|
||||
|
||||
CHECK_INCLUDE_FILE("utmpx.h" HAVE_UTMPX_H)
|
||||
if(HAVE_UTMPX_H)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_UTMPX_H)
|
||||
endif()
|
||||
|
||||
function(ff_lib_enable VARNAME)
|
||||
function(ff_lib_enable VARNAME PKGCONFIG_NAMES CMAKE_NAME)
|
||||
if(NOT ENABLE_${VARNAME})
|
||||
return()
|
||||
endif()
|
||||
|
||||
pkg_search_module(${VARNAME} ${ARGN})
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_search_module(${VARNAME} QUIET ${PKGCONFIG_NAMES})
|
||||
endif()
|
||||
|
||||
if(NOT ${VARNAME}_FOUND)
|
||||
message(WARNING "Package ${ARGV1} not found, building without support.")
|
||||
find_package(${CMAKE_NAME} QUIET)
|
||||
|
||||
set(${VARNAME}_FOUND ${${CMAKE_NAME}_FOUND})
|
||||
set(${VARNAME}_INCLUDE_DIRS ${${CMAKE_NAME}_INCLUDE_DIRS})
|
||||
set(${VARNAME}_LIBRARIES ${${CMAKE_NAME}_LIBRARIES})
|
||||
set(${VARNAME}_CFLAGS_OTHER ${${CMAKE_NAME}_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if(NOT ${VARNAME}_FOUND)
|
||||
message(STATUS "Library: missing: ${VARNAME}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
message(STATUS "Library: found ${VARNAME}")
|
||||
|
||||
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})
|
||||
|
||||
foreach(FLAG ${${VARNAME}_CFLAGS_OTHER})
|
||||
if(FLAG MATCHES "-D.*")
|
||||
@@ -455,50 +538,144 @@ function(ff_lib_enable VARNAME)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
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)
|
||||
ff_lib_enable(LIBPCI
|
||||
"libpci"
|
||||
"Pci"
|
||||
)
|
||||
ff_lib_enable(VULKAN
|
||||
"vulkan"
|
||||
"Vulkan"
|
||||
)
|
||||
ff_lib_enable(WAYLAND
|
||||
"wayland-client"
|
||||
"WaylandClient"
|
||||
)
|
||||
ff_lib_enable(XCB_RANDR
|
||||
"xcb-randr"
|
||||
"XcbRandr"
|
||||
)
|
||||
ff_lib_enable(XCB
|
||||
"xcb"
|
||||
"Xcb"
|
||||
)
|
||||
ff_lib_enable(XRANDR
|
||||
"xrandr"
|
||||
"XRandr"
|
||||
)
|
||||
ff_lib_enable(X11
|
||||
"x11"
|
||||
"X11"
|
||||
)
|
||||
ff_lib_enable(GIO
|
||||
"gio-2.0"
|
||||
"GIO"
|
||||
)
|
||||
ff_lib_enable(DCONF
|
||||
"dconf"
|
||||
"DConf"
|
||||
)
|
||||
ff_lib_enable(DBUS
|
||||
"dbus-1"
|
||||
"DBus"
|
||||
)
|
||||
ff_lib_enable(XFCONF
|
||||
"libxfconf-0"
|
||||
"XFConf"
|
||||
)
|
||||
ff_lib_enable(SQLITE3
|
||||
"sqlite3"
|
||||
"SQLite3"
|
||||
)
|
||||
ff_lib_enable(RPM
|
||||
"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"
|
||||
"ImageMagick7"
|
||||
)
|
||||
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"
|
||||
"ImageMagick6"
|
||||
)
|
||||
ff_lib_enable(ZLIB
|
||||
"zlib"
|
||||
"ZLIB"
|
||||
)
|
||||
ff_lib_enable(CHAFA
|
||||
"chafa>=1.10"
|
||||
"Chafa"
|
||||
)
|
||||
ff_lib_enable(EGL
|
||||
"egl"
|
||||
"EGL"
|
||||
)
|
||||
ff_lib_enable(GLX
|
||||
"glx"
|
||||
"GLX"
|
||||
)
|
||||
ff_lib_enable(OSMESA
|
||||
"osmesa"
|
||||
"OSMesa"
|
||||
)
|
||||
ff_lib_enable(OPENCL
|
||||
"OpenCL"
|
||||
"OpenCL"
|
||||
)
|
||||
ff_lib_enable(LIBCJSON
|
||||
"libcjson"
|
||||
"CJson"
|
||||
)
|
||||
ff_lib_enable(FREETYPE
|
||||
"freetype2"
|
||||
"FreeType2"
|
||||
)
|
||||
|
||||
if(ENABLE_THREADS)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
|
||||
if(CMAKE_USE_PTHREADS_INIT) #Threads::Threads is not set for WIN32
|
||||
target_link_libraries(libfastfetch PRIVATE Threads::Threads)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(ENABLE_BUFFER)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_ENABLE_BUFFER)
|
||||
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 "-framework CoreWLAN"
|
||||
PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks"
|
||||
)
|
||||
elseif(MSYS)
|
||||
elseif(WIN32)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "wbemuuid"
|
||||
PRIVATE "ole32"
|
||||
PRIVATE "oleaut32"
|
||||
PRIVATE "dwmapi"
|
||||
PRIVATE "opengl32"
|
||||
PRIVATE "gdi32"
|
||||
PRIVATE "iphlpapi"
|
||||
PRIVATE "ole32"
|
||||
PRIVATE "oleaut32"
|
||||
PRIVATE "opengl32"
|
||||
PRIVATE "wbemuuid"
|
||||
PRIVATE "ws2_32"
|
||||
PRIVATE "ntdll"
|
||||
PRIVATE "version"
|
||||
PRIVATE "setupapi"
|
||||
PRIVATE "dxgi"
|
||||
PRIVATE "wtsapi32"
|
||||
PRIVATE "powrprof"
|
||||
)
|
||||
if(USE_WIN_NTAPI)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_NTAPI)
|
||||
endif()
|
||||
if(USE_WIN_GPU_DXGI)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_WIN_GPU_DXGI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(libfastfetch
|
||||
@@ -508,7 +685,6 @@ target_include_directories(libfastfetch
|
||||
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE ${CMAKE_DL_LIBS}
|
||||
PRIVATE Threads::Threads
|
||||
)
|
||||
|
||||
######################
|
||||
@@ -518,6 +694,9 @@ target_link_libraries(libfastfetch
|
||||
add_executable(fastfetch
|
||||
src/fastfetch.c
|
||||
)
|
||||
target_compile_definitions(fastfetch
|
||||
PRIVATE FASTFETCH_TARGET_BINARY_NAME=fastfetch
|
||||
)
|
||||
target_link_libraries(fastfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
@@ -525,10 +704,25 @@ target_link_libraries(fastfetch
|
||||
add_executable(flashfetch
|
||||
src/flashfetch.c
|
||||
)
|
||||
target_compile_definitions(flashfetch
|
||||
PRIVATE FASTFETCH_TARGET_BINARY_NAME=flashfetch
|
||||
)
|
||||
target_link_libraries(flashfetch
|
||||
PRIVATE libfastfetch
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(TARGET_NAME fastfetch)
|
||||
target_sources(fastfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
|
||||
set(TARGET_NAME flashfetch)
|
||||
target_sources(flashfetch
|
||||
PRIVATE src/util/windows/version.rc
|
||||
)
|
||||
endif()
|
||||
|
||||
###################
|
||||
# Testing targets #
|
||||
###################
|
||||
@@ -600,12 +794,6 @@ if(LINUX)
|
||||
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)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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 pure c, with performance and customizability in mind. Currently Linux, Android, BSD, MacOS and Windows on [MSYS2](https://www.msys2.org/) are supported.
|
||||
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, FreeBSD, MacOS and Windows 7+ 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" />
|
||||
@@ -21,9 +21,13 @@ There are some premade config files in [`presets`](presets), including the ones
|
||||
|
||||
## Dependencies
|
||||
|
||||
Fastfetch dynamically loads needed libraries if they are available. Therefore its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and `libpthread`. They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions, so you probably don't have to worry about it.
|
||||
Fastfetch dynamically loads needed libraries if they are available. On Linux, its only hard dependencies are `libc` (any implementation of the c standard library), `libdl` and [`libpthread`](https://man7.org/linux/man-pages/man7/pthreads.7.html) (if built with multithreading support). They are all shipped with [`glibc`](https://www.gnu.org/software/libc/), which is already installed on most linux distributions.
|
||||
|
||||
|
||||
The following libraries are used if present at runtime:
|
||||
|
||||
### Linux and FreeBSD
|
||||
|
||||
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
|
||||
* [`libxcb-randr`](https://xcb.freedesktop.org/),
|
||||
@@ -44,30 +48,57 @@ The following libraries are used if present at runtime:
|
||||
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
|
||||
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
|
||||
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ).
|
||||
* [`freetype`](https://www.freetype.org/): Needed for Termux font detection ( Android ).
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ).
|
||||
|
||||
### macOS
|
||||
|
||||
* [`MediaRemote`](https://iphonedev.wiki/index.php/MediaRemote.framework): Need for Media detection. It's a private framework provided by newer macOS system.
|
||||
* [`MoltenVK`](https://github.com/KhronosGroup/MoltenVK): Vulkan driver for macOS. [`molten-vk`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/molten-vk.rb)
|
||||
* [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel graphics protocol. [`imagemagick`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/imagemagick.rb)
|
||||
* [`libchafa`](https://github.com/hpjansson/chafa): Image output as ascii art. [`chafa`](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/chafa.rb)
|
||||
|
||||
For the image logo, iTerm with iterm image protocol should work. Apple Terminal is not supported.
|
||||
|
||||
### Windows
|
||||
|
||||
* [`wlanapi`](https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/): A system dll which isn't supported by Windows Server by default. Used for Wifi info detection.
|
||||
* [`libcJSON`](https://github.com/DaveGamble/cJSON): Used for Windows Terminal font detection. [`cjson`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-cjson)
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module. Usually has been provided by GPU drivers. [`vulkan-loader`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-loader) [`vulkan-headers`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-vulkan-headers)
|
||||
* [`libOpenCL`](https://www.khronos.org/opencl/): OpenCL module. [`opencl-icd`](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-opencl-icd)
|
||||
|
||||
Note: In Windows 7, 8 and 8.1, [ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html) is required to run fastfetch due to [the lack of ASCII escape code native support](https://en.wikipedia.org/wiki/ANSI_escape_code#DOS,_OS/2,_and_Windows). In addition, special build `fastfetch-windows-old` in [Github Actions](https://github.com/LinusDierheimer/fastfetch/actions) is provided to support these old systems, which
|
||||
|
||||
1. Build with the ancient MSVCRT C runtime library, instead of the modern [UCRT](https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment) C runtime library
|
||||
2. Disable stdout application buffer, which seems to problematic for ConEmu.
|
||||
|
||||
For the image logo, only chafa is supported due to [the design flaw of ConPTY](https://github.com/microsoft/terminal/issues/1173). In addition, chafa support is not built by default due to the massive dependencies of imagemagick. You must built it yourself.
|
||||
|
||||
### Android
|
||||
|
||||
* [`freetype`](https://www.freetype.org/): Used for Termux font detection. [`freetype`](https://github.com/termux/termux-packages/tree/master/packages/freetype)
|
||||
* [`libvulkan`](https://www.vulkan.org/): Vulkan module, also used for GPU detection. Usually has been provided by Android system. [`vulkan-loader-android`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-loader-android) [`vulkan-headers`](https://github.com/termux/termux-packages/tree/master/packages/vulkan-headers)
|
||||
|
||||
## Support status
|
||||
All categories not listed here should work without needing a specific implementation.
|
||||
|
||||
##### Available Modules
|
||||
```
|
||||
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
|
||||
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, Wifi, DateTime, Date, Time, Locale, Colors, Break, Custom
|
||||
```
|
||||
|
||||
##### Logos
|
||||
```
|
||||
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
|
||||
AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, CRUX, Crystal, Debian, Devuan, Deepin, Endeavour, Enso, Fedora, FreeBSD, Garuda, Gentoo, KDE Neon, KISS, Kubuntu, LangitKetujuh, Linux, MacOS, Manjaro, Mint, MSYS2, NixOS, Nobara, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Parabola, Pop!_OS, RebornOS, RedstarOS, Rocky, Rosa, Slackware, Solus, Ubuntu, Vanilla, 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.
|
||||
* 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 / Kitty graphics protocol or chafas image to text conversion.
|
||||
* Printing images as logo is supported using Sixel / Kitty / iTerm graphics protocol or chafas image to text conversion.
|
||||
|
||||
##### Package managers
|
||||
```
|
||||
Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop
|
||||
Pacman, dpkg, rpm, emerge, eopkg, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop, Chocolatey
|
||||
```
|
||||
|
||||
##### WM themes
|
||||
@@ -82,12 +113,12 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt
|
||||
|
||||
##### Terminal fonts
|
||||
```
|
||||
Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, LXTerminal, iTerm2, Apple Terminal, TTY, Windows Terminal, Termux, mintty
|
||||
Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, Kitty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
fastfetch uses [`cmake`](https://cmake.org/) and [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) for building. The simplest steps to build the fastfetch and flashfetch binaries are:
|
||||
fastfetch uses [`cmake`](https://cmake.org/) for building. [`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) is recommended for better library detection. The simplest steps to build the fastfetch and flashfetch binaries are:
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
@@ -95,13 +126,19 @@ cmake ..
|
||||
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.
|
||||
If the build process fails to find the headers for a library listed in [dependencies](#dependencies), fastfetch will simply build without support for that specific feature. This means, it won't look for it at runtime and just act like it isn't available.
|
||||
|
||||
### Building on Windows
|
||||
|
||||
Currently [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.
|
||||
Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 subsystem (or CLANGARM64 if needed) is suggested (and tested) to build fastfetch. If you need Windows 7 / 8.x support, using MINGW64 is suggested.
|
||||
|
||||
Full native Windows executable is planned.
|
||||
1. Install [MSYS2](https://www.msys2.org/#installation)
|
||||
1. Open `MSYS2 CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime)
|
||||
1. Install dependencies
|
||||
```bash
|
||||
pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
|
||||
```
|
||||
1. Follow building instructions of Linux
|
||||
|
||||
## Packaging
|
||||
|
||||
@@ -117,7 +154,7 @@ Full native Windows executable is planned.
|
||||
## FAQ
|
||||
|
||||
Q: Why do you need a very performant version of neofetch?
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever i use the terminal, but the slow speed annoyed me, so i created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
> I like putting neofetch in my ~/.bashrc to have a system overwiew whenever I use the terminal, but the slow speed annoyed me, so I created this. Also neofetch didn't output everything correctly (e.g Font is displayed as "[Plasma], Noto Sans, 10 [GTK2/3]") and writing my own tool gave me the possibility to fine tune it to run perfectly on at least my configuration.
|
||||
|
||||
Q: It does not display [*] correctly for me, what can i do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment i am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
Q: It does not display [*] correctly for me, what can I do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
|
||||
+7
-2
@@ -169,11 +169,10 @@ __fastfetch_completion()
|
||||
|
||||
local FF_OPTIONS_BOOL=(
|
||||
"-r"
|
||||
"--recache"
|
||||
"--nocache"
|
||||
"--show-errors"
|
||||
"--logo-print-remaining"
|
||||
"--multithreading"
|
||||
"--stat"
|
||||
"--allow-slow-operations"
|
||||
"--disable-linewrap"
|
||||
"--hide-cursor"
|
||||
@@ -188,6 +187,8 @@ __fastfetch_completion()
|
||||
"--pipe"
|
||||
"--title-fqdn"
|
||||
"--escape-bedrock"
|
||||
"--disk-show-removable"
|
||||
"--disk-show-hidden"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_STRING=(
|
||||
@@ -216,6 +217,7 @@ __fastfetch_completion()
|
||||
"--set"
|
||||
"--set-keyless"
|
||||
"--player-name"
|
||||
"--percent-type"
|
||||
"--public-ip-url"
|
||||
"--public-ip-timeout"
|
||||
"--weather-output-format"
|
||||
@@ -304,6 +306,9 @@ __fastfetch_completion()
|
||||
"--public-ip-key"
|
||||
"--public-ip-format"
|
||||
"--public-ip-error"
|
||||
"--wifi-key"
|
||||
"--wifi-format"
|
||||
"--wifi-error"
|
||||
"--weather-key"
|
||||
"--weather-format"
|
||||
"--weather-error"
|
||||
|
||||
+1
-1
@@ -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:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
|
||||
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
--disable-linewrap false
|
||||
--multithreading false
|
||||
--show-errors
|
||||
--recache
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
--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: {}
|
||||
--host-format Family: product_family: {}; product_name: {}; product_version: {}; product_sku: {}; 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: {}
|
||||
--packages-format All: {}; pacman: {}; pacman branch: {}; dpkg: {}; rpm: {}; emerge: {}; eopkg: {}; xbps: {}; apk: {}; flatpak: {}; snap: {}; brew: {}; brew-cask: {}; port: {}; scoop: {}; choco: {}
|
||||
--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: {}
|
||||
@@ -19,7 +19,7 @@
|
||||
--cpu-usage-format Percentage: {}
|
||||
--gpu-format Vendor: {}; Name: {}; Driver: {}; Temperature: {}; CoreCount: {}
|
||||
--memory-format Used: {}; Total: {}; Percentage: {}
|
||||
--disk-format Used: {}; Total: {}; Files: {}; Percentage: {}
|
||||
--disk-format SizeUsed: {}; SizeTotal: {}; SizePercentage: {}; FilesUsed: {}; FilesTotal: {}; FilesPercentage: {}; Removable: {}; Hidden: {}; Filesystem: {}; Name: {}
|
||||
--battery-format Manufactor: {}; Model: {}; Technology: {}; Capacity: {}; Status: {}
|
||||
--poweradapter-format Watts: {}; Name: {}; Manufactor: {}; Model: {}; Description: {}
|
||||
--player-format Pretty: {}; Name: {}; Bus: {}; Url: {}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "util/textModifier.h"
|
||||
#include "bar.h"
|
||||
|
||||
// green, yellow, red: print the color on nth (0~9) block
|
||||
// set its value == 10 means the color will not be printed
|
||||
void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red)
|
||||
{
|
||||
assert(green <= 10 && yellow <= 10 && red <= 10);
|
||||
|
||||
// [ 0%, 5%) prints 0 blocks
|
||||
// [ 5%, 15%) prints 1 block;
|
||||
// ...
|
||||
// [85%, 95%) prints 9 blocks;
|
||||
// [95%,100%] prints 10 blocks
|
||||
percent = (uint8_t)(percent + 5) / 10;
|
||||
assert(percent <= 10);
|
||||
|
||||
if(!instance->config.pipe)
|
||||
ffStrbufAppendS(buffer, "\033[97m[ ");
|
||||
else
|
||||
ffStrbufAppendS(buffer, "[ ");
|
||||
|
||||
for (uint8_t i = 0; i < percent; ++i)
|
||||
{
|
||||
if(!instance->config.pipe)
|
||||
{
|
||||
if (i == green)
|
||||
ffStrbufAppendS(buffer, "\033[32m");
|
||||
else if (i == yellow)
|
||||
ffStrbufAppendS(buffer, "\033[93m");
|
||||
else if (i == red)
|
||||
ffStrbufAppendS(buffer, "\033[91m");
|
||||
}
|
||||
ffStrbufAppendS(buffer, "■");
|
||||
}
|
||||
|
||||
if (percent < 10)
|
||||
{
|
||||
if(!instance->config.pipe)
|
||||
ffStrbufAppendS(buffer, "\033[97m");
|
||||
for (uint8_t i = percent; i < 10; ++i)
|
||||
ffStrbufAppendS(buffer, "-");
|
||||
}
|
||||
|
||||
if(!instance->config.pipe)
|
||||
ffStrbufAppendS(buffer, "\033[97m ]" FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
else
|
||||
ffStrbufAppendS(buffer, " ]");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_bar
|
||||
#define FF_INCLUDED_common_bar
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
enum
|
||||
{
|
||||
FF_PERCENTAGE_TYPE_NUM_BIT = 1,
|
||||
FF_PERCENTAGE_TYPE_BAR_BIT = 2,
|
||||
};
|
||||
|
||||
void ffAppendPercentBar(FFinstance* instance, FFstrbuf* buffer, uint8_t percent, uint8_t green, uint8_t yellow, uint8_t red);
|
||||
|
||||
#endif
|
||||
@@ -1,327 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/caching.h"
|
||||
#include "common/io.h"
|
||||
#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_V1 "ffc1"
|
||||
|
||||
static void getCacheFilePath(const FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
ffStrbufAppend(buffer, &instance->state.cacheDir);
|
||||
ffStrbufAppendS(buffer, moduleName);
|
||||
|
||||
if(extension != NULL)
|
||||
{
|
||||
ffStrbufAppendC(buffer, '.');
|
||||
ffStrbufAppendS(buffer, extension);
|
||||
}
|
||||
}
|
||||
|
||||
static void readCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* buffer)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 64);
|
||||
getCacheFilePath(instance, moduleName, extension, &path);
|
||||
ffAppendFileBuffer(path.chars, buffer);
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
static void writeCacheFile(FFinstance* instance, const char* moduleName, const char* extension, FFstrbuf* content)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitA(&path, 64);
|
||||
getCacheFilePath(instance, moduleName, extension, &path);
|
||||
ffWriteFileBuffer(path.chars, content);
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
void ffCacheValidate(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInit(&content);
|
||||
readCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &content);
|
||||
|
||||
const char exactVersion[] = FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK;
|
||||
|
||||
bool isSameVersion = ffStrbufCompS(&content, exactVersion) == 0;
|
||||
ffStrbufDestroy(&content);
|
||||
if(isSameVersion)
|
||||
return;
|
||||
|
||||
instance->config.recache = true;
|
||||
|
||||
FFstrbuf version;
|
||||
ffStrbufInitA(&version, sizeof(exactVersion));
|
||||
ffStrbufAppendS(&version, exactVersion);
|
||||
writeCacheFile(instance, FF_CACHE_VERSION_NAME, FF_CACHE_VERSION_EXTENSION, &version);
|
||||
ffStrbufDestroy(&version);
|
||||
}
|
||||
|
||||
void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache)
|
||||
{
|
||||
FFstrbuf cacheFileValue;
|
||||
ffStrbufInitA(&cacheFileValue, 64);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &cacheFileValue);
|
||||
cache->value = fopen(cacheFileValue.chars, "w");
|
||||
ffStrbufDestroy(&cacheFileValue);
|
||||
|
||||
FFstrbuf cacheFileSplit;
|
||||
ffStrbufInitA(&cacheFileSplit, 64);
|
||||
getCacheFilePath(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &cacheFileSplit);
|
||||
cache->split = fopen(cacheFileSplit.chars, "w");
|
||||
ffStrbufDestroy(&cacheFileSplit);
|
||||
}
|
||||
|
||||
void ffCacheClose(FFcache* cache)
|
||||
{
|
||||
if(cache->value != NULL)
|
||||
fclose(cache->value);
|
||||
|
||||
if(cache->split != NULL)
|
||||
fclose(cache->split);
|
||||
}
|
||||
|
||||
static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInitA(&content, 512);
|
||||
readCacheFile(instance, moduleName, FF_CACHE_VALUE_EXTENSION, &content);
|
||||
|
||||
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;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < content.length)
|
||||
{
|
||||
uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0');
|
||||
uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter;
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key);
|
||||
puts(content.chars + startIndex);
|
||||
startIndex = nullByteIndex + 1;
|
||||
++moduleCounter;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
return moduleCounter > 1;
|
||||
}
|
||||
|
||||
static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInitA(&content, 512);
|
||||
readCacheFile(instance, moduleName, FF_CACHE_SPLIT_EXTENSION, &content);
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
||||
uint8_t moduleCounter = 1;
|
||||
|
||||
FFformatarg* arguments = calloc(numArgs, sizeof(FFformatarg));
|
||||
uint32_t argumentCounter = 0;
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < content.length)
|
||||
{
|
||||
arguments[argumentCounter].type = FF_FORMAT_ARG_TYPE_STRING;
|
||||
arguments[argumentCounter].value = &content.chars[startIndex];
|
||||
++argumentCounter;
|
||||
|
||||
uint32_t nullByteIndex = ffStrbufNextIndexC(&content, startIndex, '\0');
|
||||
|
||||
if(argumentCounter == numArgs)
|
||||
{
|
||||
uint8_t moduleIndex = (moduleCounter == 1 && nullByteIndex == content.length) ? 0 : moduleCounter;
|
||||
ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments);
|
||||
++moduleCounter;
|
||||
argumentCounter = 0;
|
||||
}
|
||||
|
||||
startIndex = nullByteIndex + 1;
|
||||
}
|
||||
|
||||
free(arguments);
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
return moduleCounter > 1;
|
||||
}
|
||||
|
||||
bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs)
|
||||
{
|
||||
if(instance->config.recache)
|
||||
return false;
|
||||
|
||||
if(moduleArgs->outputFormat.length == 0)
|
||||
return printCachedValue(instance, moduleName, moduleArgs);
|
||||
else
|
||||
return printCachedFormat(instance, moduleName, moduleArgs, numArgs);
|
||||
}
|
||||
|
||||
void ffPrintAndAppendToCache(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFcache* cache, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(moduleArgs->outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, moduleName, moduleIndex, &moduleArgs->key);
|
||||
ffStrbufPutTo(value, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintFormat(instance, moduleName, moduleIndex, moduleArgs, numArgs, arguments);
|
||||
}
|
||||
|
||||
if(cache->value != NULL)
|
||||
{
|
||||
ffStrbufWriteTo(value, cache->value);
|
||||
fputc('\0', cache->value);
|
||||
}
|
||||
|
||||
if(cache->split == NULL)
|
||||
return;
|
||||
|
||||
for(uint32_t i = 0; i < numArgs; i++)
|
||||
{
|
||||
FFstrbuf buffer;
|
||||
ffStrbufInitA(&buffer, 64);
|
||||
ffFormatAppendFormatArg(&buffer, &arguments[i]);
|
||||
ffStrbufWriteTo(&buffer, cache->split);
|
||||
ffStrbufDestroy(&buffer);
|
||||
fputc('\0', cache->split);
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintAndWriteToCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, const FFstrbuf* value, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
FFcache cache;
|
||||
ffCacheOpenWrite(instance, moduleName, &cache);
|
||||
ffPrintAndAppendToCache(instance, moduleName, 0, moduleArgs, &cache, value, numArgs, arguments);
|
||||
ffCacheClose(&cache);
|
||||
}
|
||||
|
||||
typedef struct FFCacheRead
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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, 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);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_caching
|
||||
#define FF_INCLUDED_common_caching
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
|
||||
typedef struct FFcache
|
||||
{
|
||||
FILE* value;
|
||||
FILE* split;
|
||||
} FFcache;
|
||||
|
||||
void ffCacheValidate(FFinstance* instance);
|
||||
|
||||
void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache);
|
||||
void ffCacheClose(FFcache* cache);
|
||||
|
||||
bool ffPrintFromCache(FFinstance* instance, const char* moduleName, const FFModuleArgs* moduleArgs, uint32_t numArgs);
|
||||
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);
|
||||
|
||||
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
|
||||
+19
-5
@@ -1,23 +1,28 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/format.h"
|
||||
#include "common/parsing.h"
|
||||
#include "util/textModifier.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
{
|
||||
if(formatarg->type == FF_FORMAT_ARG_TYPE_INT)
|
||||
ffStrbufAppendF(buffer, "%i", *(int*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT)
|
||||
ffStrbufAppendF(buffer, "%u", *(uint32_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu32, *(uint32_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT16)
|
||||
ffStrbufAppendF(buffer, "%hu", *(uint16_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu16, *(uint16_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_UINT8)
|
||||
ffStrbufAppendF(buffer, "%hhu", *(uint8_t*)formatarg->value);
|
||||
ffStrbufAppendF(buffer, "%" PRIu8, *(uint8_t*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRING)
|
||||
ffStrbufAppendS(buffer, (const char*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_STRBUF)
|
||||
ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE)
|
||||
ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value);
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_BOOL)
|
||||
ffStrbufAppendS(buffer, formatarg->value != NULL ? "true" : "false");
|
||||
else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST)
|
||||
{
|
||||
const FFlist* list = formatarg->value;
|
||||
@@ -34,6 +39,14 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parses a string to a uint32_t
|
||||
*
|
||||
* If the string can't be parsed, or is < 1, uint32_t max is returned.
|
||||
*
|
||||
* @param placeholderValue the string to parse
|
||||
* @return uint32_t the parsed value
|
||||
*/
|
||||
static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue)
|
||||
{
|
||||
uint32_t result = UINT32_MAX;
|
||||
@@ -41,7 +54,7 @@ static inline uint32_t getArgumentIndex(const FFstrbuf* placeholderValue)
|
||||
if(placeholderValue->chars[0] != '-')
|
||||
sscanf(placeholderValue->chars, "%u", &result);
|
||||
|
||||
return result;
|
||||
return result == 0 ? UINT32_MAX : result;
|
||||
}
|
||||
|
||||
static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start, const FFstrbuf* placeholderValue, uint32_t index, uint32_t formatStringLength)
|
||||
@@ -72,7 +85,8 @@ static inline bool formatArgSet(const FFformatarg* arg)
|
||||
(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)
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) ||
|
||||
(arg->type == FF_FORMAT_ARG_TYPE_BOOL && arg->value != NULL)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -13,7 +13,8 @@ typedef enum FFformatargtype
|
||||
FF_FORMAT_ARG_TYPE_STRING,
|
||||
FF_FORMAT_ARG_TYPE_STRBUF,
|
||||
FF_FORMAT_ARG_TYPE_DOUBLE,
|
||||
FF_FORMAT_ARG_TYPE_LIST
|
||||
FF_FORMAT_ARG_TYPE_LIST,
|
||||
FF_FORMAT_ARG_TYPE_BOOL
|
||||
} FFformatargtype;
|
||||
|
||||
typedef struct FFformatarg
|
||||
@@ -25,4 +26,6 @@ typedef struct FFformatarg
|
||||
void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg);
|
||||
void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t numArgs, const FFformatarg* arguments);
|
||||
|
||||
#define FF_FORMAT_ARG_VALUE_BOOL(xpr) ((xpr) ? (const void*) 1 : NULL)
|
||||
|
||||
#endif
|
||||
|
||||
+95
-119
@@ -1,25 +1,27 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/caching.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/thread.h"
|
||||
#include "detection/qt.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
#include "util/textModifier.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static bool strbufEqualsAdapter(const void* first, const void* second)
|
||||
{
|
||||
return ffStrbufComp(second, first) == 0;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
#include <wincon.h>
|
||||
#include <locale.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
static void initConfigDirs(FFstate* state)
|
||||
{
|
||||
ffListInit(&state->configDirs, sizeof(FFstrbuf));
|
||||
|
||||
#if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__))
|
||||
|
||||
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
if(ffStrSet(xdgConfigHome))
|
||||
{
|
||||
@@ -29,8 +31,10 @@ static void initConfigDirs(FFstate* state)
|
||||
ffStrbufEnsureEndsWithC(buffer, '/');
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define FF_ENSURE_ONLY_ONCE_IN_LIST(element) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, strbufEqualsAdapter) < state->configDirs.length - 1) \
|
||||
if(ffListFirstIndexComp(&state->configDirs, element, (bool(*)(const void*, const void*))ffStrbufEqual) < state->configDirs.length - 1) \
|
||||
{ \
|
||||
ffStrbufDestroy(ffListGet(&state->configDirs, state->configDirs.length - 1)); \
|
||||
--state->configDirs.length; \
|
||||
@@ -48,6 +52,8 @@ static void initConfigDirs(FFstate* state)
|
||||
ffStrbufEnsureEndsWithC(userHome, '/');
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(userHome)
|
||||
|
||||
#if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__))
|
||||
|
||||
FFstrbuf xdgConfigDirs;
|
||||
ffStrbufInitA(&xdgConfigDirs, 64);
|
||||
ffStrbufAppendS(&xdgConfigDirs, getenv("XDG_CONFIG_DIRS"));
|
||||
@@ -79,6 +85,8 @@ static void initConfigDirs(FFstate* state)
|
||||
ffStrbufAppendS(systemConfigHome, FASTFETCH_TARGET_DIR_ETC"/xdg/");
|
||||
FF_ENSURE_ONLY_ONCE_IN_LIST(systemConfigHome)
|
||||
|
||||
#endif
|
||||
|
||||
FFstrbuf* systemConfig = ffListAdd(&state->configDirs);
|
||||
ffStrbufInitA(systemConfig, 64);
|
||||
ffStrbufAppendS(systemConfig, FASTFETCH_TARGET_DIR_ETC"/");
|
||||
@@ -87,47 +95,31 @@ static void initConfigDirs(FFstate* state)
|
||||
#undef FF_ENSURE_ONLY_ONCE_IN_LIST
|
||||
}
|
||||
|
||||
static void initCacheDir(FFstate* state)
|
||||
{
|
||||
ffStrbufInitA(&state->cacheDir, 64);
|
||||
|
||||
ffStrbufAppendS(&state->cacheDir, getenv("XDG_CACHE_HOME"));
|
||||
|
||||
if(state->cacheDir.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&state->cacheDir, state->passwd->pw_dir);
|
||||
ffStrbufAppendS(&state->cacheDir, "/.cache/");
|
||||
}
|
||||
else
|
||||
ffStrbufEnsureEndsWithC(&state->cacheDir, '/');
|
||||
|
||||
mkdir(state->cacheDir.chars, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder, but who knows
|
||||
|
||||
ffStrbufAppendS(&state->cacheDir, "fastfetch/");
|
||||
mkdir(state->cacheDir.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
}
|
||||
|
||||
static void initState(FFstate* state)
|
||||
{
|
||||
#ifdef WIN32
|
||||
//https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support
|
||||
setlocale(LC_ALL, ".UTF8");
|
||||
#endif
|
||||
|
||||
state->logoWidth = 0;
|
||||
state->logoHeight = 0;
|
||||
state->keysHeight = 0;
|
||||
state->passwd = getpwuid(getuid());
|
||||
#ifndef WIN32
|
||||
state->passwd = getpwuid(getuid());
|
||||
#else
|
||||
state->passwd = ffGetPasswd();
|
||||
#endif
|
||||
uname(&state->utsname);
|
||||
|
||||
#if FF_HAVE_SYSINFO_H
|
||||
sysinfo(&state->sysinfo);
|
||||
#endif
|
||||
|
||||
initConfigDirs(state);
|
||||
initCacheDir(state);
|
||||
}
|
||||
|
||||
static void initModuleArg(FFModuleArgs* args)
|
||||
{
|
||||
ffStrbufInitA(&args->key, 0);
|
||||
ffStrbufInitA(&args->outputFormat, 0);
|
||||
ffStrbufInitA(&args->errorFormat, 0);
|
||||
ffStrbufInit(&args->key);
|
||||
ffStrbufInit(&args->outputFormat);
|
||||
ffStrbufInit(&args->errorFormat);
|
||||
}
|
||||
|
||||
static void defaultConfig(FFinstance* instance)
|
||||
@@ -141,6 +133,13 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.logo.paddingLeft = 0;
|
||||
instance->config.logo.paddingRight = 4;
|
||||
instance->config.logo.printRemaining = true;
|
||||
instance->config.logo.preserveAspectRadio = false;
|
||||
|
||||
instance->config.logo.chafaFgOnly = false;
|
||||
ffStrbufInitS(&instance->config.logo.chafaSymbols, "block+border+space-wide-inverted"); // Chafa default
|
||||
instance->config.logo.chafaCanvasMode = UINT32_MAX;
|
||||
instance->config.logo.chafaColorSpace = UINT32_MAX;
|
||||
instance->config.logo.chafaDitherMode = UINT32_MAX;
|
||||
|
||||
ffStrbufInit(&instance->config.colorKeys);
|
||||
ffStrbufInit(&instance->config.colorTitle);
|
||||
@@ -150,7 +149,6 @@ static void defaultConfig(FFinstance* instance)
|
||||
|
||||
instance->config.showErrors = false;
|
||||
instance->config.recache = false;
|
||||
instance->config.cacheSave = true;
|
||||
instance->config.allowSlowOperations = false;
|
||||
instance->config.disableLinewrap = true;
|
||||
instance->config.hideCursor = true;
|
||||
@@ -159,11 +157,13 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.glType = FF_GL_TYPE_AUTO;
|
||||
instance->config.pipe = false;
|
||||
instance->config.multithreading = true;
|
||||
instance->config.stat = false;
|
||||
|
||||
initModuleArg(&instance->config.os);
|
||||
initModuleArg(&instance->config.host);
|
||||
initModuleArg(&instance->config.bios);
|
||||
initModuleArg(&instance->config.board);
|
||||
initModuleArg(&instance->config.chassis);
|
||||
initModuleArg(&instance->config.kernel);
|
||||
initModuleArg(&instance->config.uptime);
|
||||
initModuleArg(&instance->config.processes);
|
||||
@@ -191,8 +191,9 @@ static void defaultConfig(FFinstance* instance)
|
||||
initModuleArg(&instance->config.localIP);
|
||||
initModuleArg(&instance->config.publicIP);
|
||||
initModuleArg(&instance->config.weather);
|
||||
initModuleArg(&instance->config.wifi);
|
||||
initModuleArg(&instance->config.player);
|
||||
initModuleArg(&instance->config.song);
|
||||
initModuleArg(&instance->config.media);
|
||||
initModuleArg(&instance->config.dateTime);
|
||||
initModuleArg(&instance->config.date);
|
||||
initModuleArg(&instance->config.time);
|
||||
@@ -223,6 +224,7 @@ static void defaultConfig(FFinstance* instance)
|
||||
ffStrbufInitA(&instance->config.libOpenCL, 0);
|
||||
ffStrbufInitA(&instance->config.libcJSON, 0);
|
||||
ffStrbufInitA(&instance->config.libfreetype, 0);
|
||||
ffStrbufInit(&instance->config.libwlanapi);
|
||||
|
||||
instance->config.cpuTemp = false;
|
||||
instance->config.gpuTemp = false;
|
||||
@@ -231,7 +233,8 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.titleFQDN = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.diskFolders, 0);
|
||||
instance->config.diskRemovable = false;
|
||||
instance->config.diskShowRemovable = true;
|
||||
instance->config.diskShowHidden = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.batteryDir, 0);
|
||||
|
||||
@@ -251,6 +254,8 @@ static void defaultConfig(FFinstance* instance)
|
||||
ffStrbufInitA(&instance->config.osFile, 0);
|
||||
|
||||
ffStrbufInitA(&instance->config.playerName, 0);
|
||||
|
||||
instance->config.percentType = 1;
|
||||
}
|
||||
|
||||
void ffInitInstance(FFinstance* instance)
|
||||
@@ -259,87 +264,39 @@ void ffInitInstance(FFinstance* instance)
|
||||
defaultConfig(instance);
|
||||
}
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(_WIN32) && !defined(__MSYS__)
|
||||
#ifdef FF_HAVE_THREADS
|
||||
|
||||
static void* connectDisplayServerThreadMain(void* instance)
|
||||
{
|
||||
ffConnectDisplayServer((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(ffConnectDisplayServer, FFinstance*)
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
#if !(defined(__APPLE__) || defined(_WIN32))
|
||||
|
||||
static void* detectPlasmaThreadMain(void* instance)
|
||||
{
|
||||
ffDetectQt((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
#define FF_DETECT_QT_GTK 1
|
||||
|
||||
static void* detectGTK2ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK2((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectQt, FFinstance*)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK2, FFinstance*)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK3, FFinstance*)
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*)
|
||||
|
||||
static void* detectGTK3ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK3((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
#endif //!(defined(__APPLE__) || defined(_WIN32))
|
||||
|
||||
static void* detectGTK4ThreadMain(void* instance)
|
||||
{
|
||||
ffDetectGTK4((FFinstance*)instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* startThreadsThreadMain(void* instance)
|
||||
{
|
||||
pthread_t dsThread;
|
||||
pthread_create(&dsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
pthread_detach(dsThread);
|
||||
|
||||
pthread_t gtk2Thread;
|
||||
pthread_create(>k2Thread, NULL, detectGTK2ThreadMain, instance);
|
||||
pthread_detach(gtk2Thread);
|
||||
|
||||
pthread_t gtk3Thread;
|
||||
pthread_create(>k3Thread, NULL, detectGTK3ThreadMain, instance);
|
||||
pthread_detach(gtk3Thread);
|
||||
|
||||
pthread_t gtk4Thread;
|
||||
pthread_create(>k4Thread, NULL, detectGTK4ThreadMain, instance);
|
||||
pthread_detach(gtk4Thread);
|
||||
|
||||
pthread_t plasmaThread;
|
||||
pthread_create(&plasmaThread, NULL, detectPlasmaThreadMain, instance);
|
||||
pthread_detach(plasmaThread);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif //FF_HAVE_THREADS
|
||||
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, startThreadsThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
#ifdef FF_HAVE_THREADS
|
||||
ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, instance));
|
||||
|
||||
#else // !__APPLE__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
pthread_t startThreadsThread;
|
||||
pthread_create(&startThreadsThread, NULL, connectDisplayServerThreadMain, instance);
|
||||
pthread_detach(startThreadsThread);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
#ifdef FF_DETECT_QT_GTK
|
||||
ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, instance));
|
||||
#endif
|
||||
|
||||
#else // !__ANDROID__
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
#else
|
||||
FF_UNUSED(instance);
|
||||
#endif
|
||||
}
|
||||
#endif // __ANDROID__
|
||||
|
||||
static volatile bool ffDisableLinewrap = true;
|
||||
static volatile bool ffHideCursor = true;
|
||||
@@ -353,12 +310,21 @@ static void resetConsole()
|
||||
fputs("\033[?25h", stdout);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI consoleHandler(DWORD signal)
|
||||
{
|
||||
FF_UNUSED(signal);
|
||||
resetConsole();
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
static void exitSignalHandler(int signal)
|
||||
{
|
||||
FF_UNUSED(signal);
|
||||
resetConsole();
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ffStart(FFinstance* instance)
|
||||
{
|
||||
@@ -368,16 +334,25 @@ void ffStart(FFinstance* instance)
|
||||
ffDisableLinewrap = instance->config.disableLinewrap && !instance->config.pipe;
|
||||
ffHideCursor = instance->config.hideCursor && !instance->config.pipe;
|
||||
|
||||
struct sigaction action = {};
|
||||
action.sa_handler = exitSignalHandler;
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef FF_ENABLE_BUFFER
|
||||
setvbuf(stdout, NULL, _IOFBF, 4096);
|
||||
#endif
|
||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
GetConsoleMode(hStdout, &mode);
|
||||
SetConsoleMode(hStdout, mode | ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#else
|
||||
#ifndef FF_ENABLE_BUFFER
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
#endif
|
||||
struct sigaction action = { .sa_handler = exitSignalHandler };
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
sigaction(SIGQUIT, &action, NULL);
|
||||
|
||||
//We do the cache validation here, so we can skip it if --recache is given
|
||||
if(!instance->config.recache)
|
||||
ffCacheValidate(instance);
|
||||
#endif
|
||||
|
||||
//reset everything to default before we start printing
|
||||
if(!instance->config.pipe)
|
||||
@@ -410,6 +385,7 @@ static void destroyModuleArg(FFModuleArgs* args)
|
||||
static void destroyConfig(FFinstance* instance)
|
||||
{
|
||||
ffStrbufDestroy(&instance->config.logo.source);
|
||||
ffStrbufDestroy(&instance->config.logo.chafaSymbols);
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufDestroy(&instance->config.logo.colors[i]);
|
||||
ffStrbufDestroy(&instance->config.colorKeys);
|
||||
@@ -447,8 +423,9 @@ static void destroyConfig(FFinstance* instance)
|
||||
destroyModuleArg(&instance->config.localIP);
|
||||
destroyModuleArg(&instance->config.publicIP);
|
||||
destroyModuleArg(&instance->config.weather);
|
||||
destroyModuleArg(&instance->config.wifi);
|
||||
destroyModuleArg(&instance->config.player);
|
||||
destroyModuleArg(&instance->config.song);
|
||||
destroyModuleArg(&instance->config.media);
|
||||
destroyModuleArg(&instance->config.dateTime);
|
||||
destroyModuleArg(&instance->config.date);
|
||||
destroyModuleArg(&instance->config.time);
|
||||
@@ -479,6 +456,7 @@ static void destroyConfig(FFinstance* instance)
|
||||
ffStrbufDestroy(&instance->config.libOpenCL);
|
||||
ffStrbufDestroy(&instance->config.libcJSON);
|
||||
ffStrbufDestroy(&instance->config.libfreetype);
|
||||
ffStrbufDestroy(&instance->config.libwlanapi);
|
||||
|
||||
ffStrbufDestroy(&instance->config.diskFolders);
|
||||
ffStrbufDestroy(&instance->config.batteryDir);
|
||||
@@ -495,8 +473,6 @@ 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)
|
||||
|
||||
+98
-5
@@ -1,11 +1,15 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fileapi.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
static void createSubfolders(const char* fileName)
|
||||
{
|
||||
@@ -16,7 +20,13 @@ static void createSubfolders(const char* fileName)
|
||||
{
|
||||
ffStrbufAppendC(&path, *fileName);
|
||||
if(*fileName == '/')
|
||||
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
|
||||
{
|
||||
mkdir(path.chars
|
||||
#ifndef WIN32
|
||||
, S_IRWXU | S_IRGRP | S_IROTH
|
||||
#endif
|
||||
);
|
||||
}
|
||||
++fileName;
|
||||
}
|
||||
|
||||
@@ -30,6 +40,21 @@ bool ffWriteFDBuffer(int fd, const FFstrbuf* content)
|
||||
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
bool ret = !!WriteFile(handle, data, (DWORD)dataSize, &written, NULL);
|
||||
|
||||
CloseHandle(handle);
|
||||
#else
|
||||
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
@@ -45,6 +70,7 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
bool ret = write(fd, data, dataSize) != -1;
|
||||
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -54,11 +80,51 @@ bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer)
|
||||
return ffWriteFileData(fileName, buffer->length, buffer->chars);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
bool ffAppendHandleBuffer(HANDLE handle, FFstrbuf* buffer)
|
||||
{
|
||||
DWORD readed = 0;
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if(!GetFileSizeEx(handle, &fileSize))
|
||||
fileSize.QuadPart = 0;
|
||||
|
||||
ffStrbufEnsureFree(buffer, fileSize.QuadPart > 0 ? (uint32_t)fileSize.QuadPart : 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
|
||||
bool success;
|
||||
while(
|
||||
(success = !!ReadFile(handle, buffer->chars + buffer->length, free, &readed, NULL)) &&
|
||||
(uint32_t) readed == free
|
||||
) {
|
||||
buffer->length += (uint32_t) readed;
|
||||
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
|
||||
free = ffStrbufGetFree(buffer);
|
||||
}
|
||||
|
||||
if(readed > 0)
|
||||
buffer->length += (uint32_t) readed;
|
||||
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
|
||||
ffStrbufTrimRight(buffer, '\n');
|
||||
ffStrbufTrimRight(buffer, ' ');
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t readed = 0;
|
||||
|
||||
ffStrbufEnsureFree(buffer, 31); // 32 - 1 for the null terminator
|
||||
struct stat fileInfo;
|
||||
if(fstat(fd, &fileInfo) != 0)
|
||||
return false;
|
||||
|
||||
ffStrbufEnsureFree(buffer, fileInfo.st_size > 0 ? (uint32_t)fileInfo.st_size : 31);
|
||||
uint32_t free = ffStrbufGetFree(buffer);
|
||||
|
||||
while(
|
||||
@@ -84,6 +150,17 @@ bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
|
||||
|
||||
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
DWORD readed;
|
||||
if(!ReadFile(handle, data, (DWORD)dataSize, &readed, NULL))
|
||||
return -1;
|
||||
|
||||
return (ssize_t)readed;
|
||||
#else
|
||||
int fd = open(fileName, O_RDONLY);
|
||||
if(fd == -1)
|
||||
return -1;
|
||||
@@ -93,10 +170,20 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
|
||||
close(fd);
|
||||
|
||||
return readed;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE handle = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
bool ret = ffAppendHandleBuffer(handle, buffer);
|
||||
|
||||
CloseHandle(handle);
|
||||
#else
|
||||
int fd = open(fileName, O_RDONLY);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
@@ -104,6 +191,7 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
bool ret = ffAppendFDBuffer(fd, buffer);
|
||||
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -151,6 +239,7 @@ bool ffFileExists(const char* fileName, mode_t mode)
|
||||
|
||||
void ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
#ifndef WIN32
|
||||
struct termios oldTerm, newTerm;
|
||||
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
|
||||
return;
|
||||
@@ -189,4 +278,8 @@ void ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
va_start(args, format);
|
||||
vsscanf(buffer, format, args);
|
||||
va_end(args);
|
||||
#else
|
||||
//Unimplemented
|
||||
FF_UNUSED(request, format);
|
||||
#endif
|
||||
}
|
||||
|
||||
+5
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <sys/types.h> //mode_t
|
||||
#include <sys/stat.h> //mode_t, fstat, stat
|
||||
|
||||
bool ffWriteFDBuffer(int fd, const FFstrbuf* content);
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data);
|
||||
@@ -16,6 +16,10 @@ ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data);
|
||||
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer);
|
||||
|
||||
#ifdef _WIN32
|
||||
bool ffAppendHandleBuffer(HANDLE handle, FFstrbuf* buffer);
|
||||
#endif
|
||||
|
||||
bool ffFileExists(const char* fileName, mode_t mode);
|
||||
|
||||
// Not thread safe!
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#ifndef FF_DLOPEN_FLAGS
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY | RTLD_NODELETE
|
||||
#else
|
||||
#define FF_DLOPEN_FLAGS RTLD_LAZY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void* libraryLoad(const char* path, int maxVersion)
|
||||
{
|
||||
void* result = dlopen(path, FF_DLOPEN_FLAGS);
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
|
||||
// libX.dll.1 never exists on Windows, while libX-1.dll may exist
|
||||
FF_UNUSED(maxVersion)
|
||||
|
||||
+16
-2
@@ -3,9 +3,20 @@
|
||||
#ifndef FF_INCLUDED_common_library
|
||||
#define FF_INCLUDED_common_library
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#if defined(_WIN32) //We don't force MSYS using LoadLibrary because dlopen also searches $LD_LIBRARY_PATH
|
||||
#include <libloaderapi.h>
|
||||
#define FF_DLOPEN_FLAGS 0
|
||||
FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); }
|
||||
FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return GetProcAddress((HMODULE)handle, symbol); }
|
||||
static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); }
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FF_LIBRARY_EXTENSION ".dll"
|
||||
#elif defined(__APPLE__)
|
||||
#define FF_LIBRARY_EXTENSION ".dylib"
|
||||
@@ -32,6 +43,9 @@
|
||||
#define FF_LIBRARY_LOAD_SYMBOL(library, symbolName, returnValue) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, returnValue);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_LAZY(library, symbolName) \
|
||||
__typeof__(&symbolName) ff ## symbolName = dlsym(library, #symbolName);
|
||||
|
||||
#define FF_LIBRARY_LOAD_SYMBOL_MESSAGE(library, symbolName) \
|
||||
__typeof__(&symbolName) FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, ff ## symbolName, symbolName, "dlsym " #symbolName " failed");
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
int ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return -1;
|
||||
|
||||
int sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
FFstrbuf command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(sockfd, command.chars, command.length, 0) == -1)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(int sockfd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
+30
-3
@@ -3,10 +3,37 @@
|
||||
#ifndef FF_INCLUDED_common_networking
|
||||
#define FF_INCLUDED_common_networking
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
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);
|
||||
#ifdef _WIN32
|
||||
#include <minwindef.h>
|
||||
#endif
|
||||
|
||||
typedef struct FFNetworkingState {
|
||||
#ifdef _WIN32
|
||||
uintptr_t sockfd;
|
||||
OVERLAPPED overlapped;
|
||||
#else
|
||||
int sockfd;
|
||||
FFstrbuf host;
|
||||
FFstrbuf command;
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
FFThreadType thread;
|
||||
#endif
|
||||
#endif
|
||||
} FFNetworkingState;
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
|
||||
|
||||
static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
FFNetworkingState state;
|
||||
if(ffNetworkingSendHttpRequest(&state, host, path, headers))
|
||||
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
static void connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
|
||||
goto error;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||
{
|
||||
close(state->sockfd);
|
||||
goto error;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
state->sockfd = -1;
|
||||
|
||||
exit:
|
||||
ffStrbufDestroy(&state->host);
|
||||
ffStrbufDestroy(&state->command);
|
||||
}
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
ffStrbufInitS(&state->host, host);
|
||||
|
||||
ffStrbufInitA(&state->command, 64);
|
||||
ffStrbufAppendS(&state->command, "GET ");
|
||||
ffStrbufAppendS(&state->command, path);
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&state->command, host);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
ffStrbufAppendS(&state->command, headers);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||
return !!state->thread;
|
||||
#else
|
||||
connectAndSend(state);
|
||||
return state->sockfd != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
ffThreadJoin(state->thread);
|
||||
#endif
|
||||
if(state->sockfd == -1)
|
||||
return false;
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
close(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
//Must be included after <mswsock.h>
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
static LPFN_CONNECTEX ConnectEx;
|
||||
|
||||
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
|
||||
{
|
||||
(void)once;
|
||||
(void)param;
|
||||
static WSADATA wsaData;
|
||||
*context = &wsaData;
|
||||
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
return FALSE;
|
||||
|
||||
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
|
||||
return FALSE;
|
||||
|
||||
//Dummy socket needed for WSAIoctl
|
||||
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
return FALSE;
|
||||
|
||||
DWORD dwBytes;
|
||||
GUID guid = WSAID_CONNECTEX;
|
||||
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||
&guid, sizeof(guid),
|
||||
&ConnectEx, sizeof(ConnectEx),
|
||||
&dwBytes, NULL, NULL) != 0)
|
||||
return FALSE;
|
||||
|
||||
return closesocket(sockfd) == 0;
|
||||
}
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
|
||||
WSADATA* pData;
|
||||
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
|
||||
return false;
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return false;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
//ConnectEx requires the socket to be initially bound
|
||||
struct sockaddr_in addr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
.sin_port = 0,
|
||||
};
|
||||
if(bind(state->sockfd, (SOCKADDR *)&addr, sizeof(addr)) != 0)
|
||||
{
|
||||
printf("bind %d\n", WSAGetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped);
|
||||
freeaddrinfo(addr);
|
||||
|
||||
if(!result && WSAGetLastError() != WSA_IO_PENDING)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
DWORD transfer, flags;
|
||||
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
closesocket(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
+11
-3
@@ -1,5 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "util/textModifier.h"
|
||||
|
||||
void ffPrintLogoAndKey(FFinstance* instance, const char* moduleName, uint8_t moduleIndex, const FFstrbuf* customKeyFormat)
|
||||
{
|
||||
@@ -93,7 +94,9 @@ static void printError(FFinstance* instance, const char* moduleName, uint8_t mod
|
||||
vprintf(message, arguments);
|
||||
|
||||
if(!instance->config.pipe)
|
||||
puts(FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,8 +130,13 @@ void ffPrintColor(const FFstrbuf* colorValue)
|
||||
|
||||
void ffPrintCharTimes(char c, uint32_t times)
|
||||
{
|
||||
for(uint32_t i = 0; i < times; i++)
|
||||
putchar(c);
|
||||
char str[32];
|
||||
memset(str, c, sizeof(str)); //2 instructions when compiling with AVX2 enabled
|
||||
for(uint32_t i = sizeof(str); i <= times; i += sizeof(str))
|
||||
fwrite(str, 1, sizeof(str), stdout);
|
||||
uint32_t remaining = times % sizeof(str);
|
||||
if(remaining > 0)
|
||||
fwrite(str, 1, remaining, stdout);
|
||||
}
|
||||
|
||||
void ffPrintUserString(const char* value)
|
||||
|
||||
@@ -27,26 +27,30 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
.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;
|
||||
|
||||
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
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cmdline;
|
||||
ffStrbufInitF(&cmdline, "\"%s\"", argv[0]);
|
||||
for(char* const* parg = &argv[1]; *parg; ++parg)
|
||||
{
|
||||
ffStrbufAppendC(&cmdline, ' ');
|
||||
ffStrbufAppendS(&cmdline, *parg);
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -55,14 +59,10 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[])
|
||||
return "CreateProcessA() failed";
|
||||
}
|
||||
|
||||
char str[128];
|
||||
char str[1024];
|
||||
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;
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "common/properties.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef _WIN32
|
||||
#include "util/windows/getline.h"
|
||||
#endif
|
||||
|
||||
static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef FF_INCLUDED_common_properties
|
||||
#define FF_INCLUDED_common_properties
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFpropquery
|
||||
{
|
||||
|
||||
+12
-13
@@ -1,9 +1,9 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/library.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/io.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum FFInitState
|
||||
@@ -15,18 +15,18 @@ typedef enum FFInitState
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
|
||||
static dataObject data; \
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
||||
static FFInitState initState = FF_INITSTATE_UNINITIALIZED; \
|
||||
pthread_mutex_lock(&mutex); \
|
||||
ffThreadMutexLock(&mutex); \
|
||||
if(initState != FF_INITSTATE_UNINITIALIZED) {\
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return initState == FF_INITSTATE_SUCCESSFUL ? &data : NULL; \
|
||||
} \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
void* libraryHandle = ffLibraryLoad(&userLibraryName, __VA_ARGS__, NULL); \
|
||||
if(libraryHandle == NULL) { \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
} \
|
||||
|
||||
@@ -35,20 +35,20 @@ typedef enum FFInitState
|
||||
if(data.ff ## symbolName == NULL) { \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_RETURN \
|
||||
initState = FF_INITSTATE_SUCCESSFUL; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return &data;
|
||||
|
||||
#define FF_LIBRARY_DATA_LOAD_ERROR \
|
||||
{ \
|
||||
dlclose(libraryHandle); \
|
||||
initState = FF_INITSTATE_FAILED; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ typedef struct GSettingsData
|
||||
|
||||
static const GSettingsData* getGSettingsData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0.so", 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(GSettingsData, instance->config.libGIO, "libgio-2.0" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_source_lookup)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(g_settings_schema_has_key)
|
||||
@@ -163,7 +163,7 @@ typedef struct DConfData
|
||||
|
||||
static const DConfData* getDConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf.so", 2);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(DConfData, instance->config.libDConf, "libdconf" FF_LIBRARY_EXTENSION, 2);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_read_full)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(dconf_client_new)
|
||||
@@ -233,7 +233,7 @@ typedef struct XFConfData
|
||||
|
||||
static const XFConfData* getXFConfData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0.so", 4);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(XFConfData, instance->config.libXFConf, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_get)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(xfconf_channel_has_property)
|
||||
@@ -280,7 +280,6 @@ FFvariant ffSettingsGetXFConf(const FFinstance* instance, const char* channelNam
|
||||
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef struct SQLiteData
|
||||
{
|
||||
@@ -295,7 +294,7 @@ typedef struct SQLiteData
|
||||
|
||||
static const SQLiteData* getSQLiteData(const FFinstance* instance)
|
||||
{
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3.so", 1);
|
||||
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3" FF_LIBRARY_EXTENSION, 1);
|
||||
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
|
||||
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
|
||||
|
||||
+4
-2
@@ -2,11 +2,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
const char* 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;
|
||||
return "sysctlbyname() failed";
|
||||
|
||||
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
|
||||
|
||||
@@ -14,6 +14,8 @@ void ffSysctlGetString(const char* propName, FFstrbuf* result)
|
||||
result->length += (uint32_t) neededLength - 1;
|
||||
|
||||
result->chars[result->length] = '\0';
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ffSysctlGetInt(const char* propName, int defaultValue)
|
||||
|
||||
+6
-4
@@ -4,12 +4,14 @@
|
||||
#define FF_INCLUDED_common_sysctl
|
||||
|
||||
#include "fastfetch.h"
|
||||
#include "util/FFcheckmacros.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);
|
||||
const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
|
||||
FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
|
||||
FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
|
||||
FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_common_thread
|
||||
#define FF_INCLUDED_common_thread
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
#if defined(_WIN32)
|
||||
#include <handleapi.h>
|
||||
#include <synchapi.h>
|
||||
#include <process.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
typedef SRWLOCK FFThreadMutex;
|
||||
typedef HANDLE FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); }
|
||||
static inline FFThreadType ffThreadCreate(unsigned (__stdcall* func)(void*), void* data) {
|
||||
return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL);
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); }
|
||||
static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, INFINITE); }
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t FFThreadMutex;
|
||||
typedef pthread_t FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
|
||||
static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
|
||||
FFThreadType newThread = 0;
|
||||
pthread_create(&newThread, NULL, func, data);
|
||||
return newThread;
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
|
||||
static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); }
|
||||
#endif
|
||||
#else //FF_HAVE_THREADS
|
||||
#define FF_THREAD_MUTEX_INITIALIZER 0
|
||||
typedef char FFThreadMutex;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType)
|
||||
#endif //FF_HAVE_THREADS
|
||||
|
||||
#endif
|
||||
+12
-9
@@ -4,28 +4,31 @@
|
||||
#define FF_INCLUDED_common_time
|
||||
|
||||
#include <stdint.h>
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
#include <synchapi.h>
|
||||
#include <sysinfoapi.h>
|
||||
#include <profileapi.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static inline uint64_t ffTimeGetTick() //In msec
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
return GetTickCount64();
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
LARGE_INTEGER start;
|
||||
QueryPerformanceCounter(&start);
|
||||
return (uint64_t)(start.QuadPart * 1000 / frequency.QuadPart);
|
||||
#else
|
||||
struct timeval timeNow;
|
||||
gettimeofday(&timeNow, NULL);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000));
|
||||
struct timespec timeNow;
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeNow);
|
||||
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ffTimeSleep(uint32_t msec)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__MSYS__)
|
||||
#ifdef _WIN32
|
||||
SleepEx(msec, TRUE);
|
||||
#else
|
||||
nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL);
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
# Default is true.
|
||||
#--multithreading true
|
||||
|
||||
# Print stat option:
|
||||
# Sets if fastfetch should print time usage (in ms) for individual modules
|
||||
# If true, it will also enable --show-errors
|
||||
# Must be true or false.
|
||||
# Default is false.
|
||||
#--stat true
|
||||
|
||||
# Slow operations option:
|
||||
# Sets if fastfetch is allowed to use known slow operations to detect more / better values.
|
||||
# Must be true or false.
|
||||
@@ -61,7 +68,7 @@
|
||||
|
||||
# Logo type option:
|
||||
# Sets the logo type to use.
|
||||
# Must be auto, builtin, file, raw, sixel, kitty or chafa.
|
||||
# Must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty or chafa.
|
||||
# Default is auto.
|
||||
#--logo-type auto
|
||||
|
||||
@@ -178,7 +185,6 @@
|
||||
# OS file option
|
||||
# Sets the path to the file containing the operating system information.
|
||||
# Should be a valid path to an existing file.
|
||||
# Note that you might need to run fastfetch with --recache once for it to take affect.
|
||||
# Default is /etc/os-release.
|
||||
#--os-file /etc/os-release
|
||||
|
||||
@@ -200,11 +206,18 @@
|
||||
# Default is auto.
|
||||
#--gl auto
|
||||
|
||||
# Percentage output type option
|
||||
# Applies to all modules that prints percentage values. Currently memory, swap, disk, battery and CPU usage are supported.
|
||||
# Only works with default format ( without --module-format option ).
|
||||
# 0: prints none; 1: prints percent number only; 2: prints bar only; 3: prints both percent number and bar
|
||||
#--percent-type 1
|
||||
|
||||
# Key options:
|
||||
# Sets the displayed key of a module
|
||||
# Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help.
|
||||
#--os-key OS
|
||||
#--host-key Host
|
||||
#--chassis-key Chassis
|
||||
#--kernel-key Kernel
|
||||
#--uptime-key Uptime
|
||||
#--processes-key Processes
|
||||
@@ -231,9 +244,10 @@
|
||||
#--locale-key Locale
|
||||
#--local-ip-key Local IP ({1})
|
||||
#--public-ip-key Public IP
|
||||
#--wifi-key Wifi
|
||||
#--weather-key Weather
|
||||
#--player-key Media Player
|
||||
#--song-key Song
|
||||
#--media-key Media
|
||||
#--datetime-key Date Time
|
||||
#--vulkan-key Vulkan
|
||||
#--opengl-key OpenGL
|
||||
@@ -247,6 +261,7 @@
|
||||
# An empty format string (As they are currently below) will behave as if it was not set.
|
||||
#--os-format
|
||||
#--host-format
|
||||
#--chassis-format
|
||||
#--kernel-format
|
||||
#--uptime-format
|
||||
#--processes-format
|
||||
@@ -275,7 +290,7 @@
|
||||
#--public-ip-format
|
||||
#--weather-format
|
||||
#--player-format
|
||||
#--song-format
|
||||
#--media-format
|
||||
#--datetime-format
|
||||
#--vulkan-format
|
||||
#--opengl-format
|
||||
@@ -289,6 +304,7 @@
|
||||
# If one of them is set, the module will appear, even if --show-errors is not given.
|
||||
#--os-error
|
||||
#--host-error
|
||||
#--chassis-error
|
||||
#--kernel-error
|
||||
#--uptime-error
|
||||
#--processes-error
|
||||
@@ -317,7 +333,7 @@
|
||||
#--public-ip-error
|
||||
#--weather-error
|
||||
#--player-error
|
||||
#--song-error
|
||||
#--media-error
|
||||
#--datetime-error
|
||||
#--vulkan-error
|
||||
#--opengl-error
|
||||
@@ -328,7 +344,7 @@
|
||||
# Sets an user specific path to a library to load.
|
||||
# Must be a valid path to a library.
|
||||
#--lib-PCI /usr/lib/libpci.so
|
||||
#--lib-vulkan /usr/lib/libvulkan.so
|
||||
#--lib-vulkan /usr/lib/libvulkan.so (libMoltenVK.dylib on macOS)
|
||||
#--lib-wayland /usr/lib/libwayland-client.so
|
||||
#--lib-xcb-randr /usr/lib/libxcb-randr.so
|
||||
#--lib-xcb /usr/lib/libxcb.so
|
||||
|
||||
+75
-65
@@ -1,65 +1,73 @@
|
||||
Usage: fastfetch <options>
|
||||
|
||||
Informative options:
|
||||
-h,--help: shows this message and exits
|
||||
-h,--help <command>: shows help for a specific command and exits
|
||||
-v,--version: prints the version of fastfetch and exits
|
||||
--list-logos: list available logos and exits
|
||||
--list-modules: lists available modules and exits
|
||||
--list-presets: list presets fastfetch knows about and exits. They can be loaded with --load-config. (+)
|
||||
--list-features: list the supported features fastfetch was compiled with and exits. Mainly for development.
|
||||
--print-logos: show available logos and exits
|
||||
--print-config-system: prints the default system config and exits
|
||||
--print-config-user: prints the default user config and exits
|
||||
--print-structure: prints the default stucture and exits
|
||||
-h,--help: Show this message
|
||||
-h,--help <command>: Show help for a specific command
|
||||
-v,--version: Show the version of fastfetch
|
||||
--list-logos: List available logos
|
||||
--list-modules: List available modules
|
||||
--list-presets: List presets fastfetch knows about; they can be loaded with --load-config (+)
|
||||
--list-features: List the supported features fastfetch was compiled with (mainly for development)
|
||||
--print-logos: Print available logos
|
||||
--print-config-system: Print the default system config
|
||||
--print-config-user: Print the default user config
|
||||
--print-structure: Print the default structure
|
||||
|
||||
General options:
|
||||
-r,--recache <?value>: generate new cached values
|
||||
--nocache <?value>: don't use cached values, but also don't overwrite existing ones
|
||||
--load-config <file>: load a config file or a preset (+)
|
||||
--multithreading <?value>: use multiple threads to detect values
|
||||
--allow-slow-operations <?value>: allow operations that are usually very slow for more detailed output
|
||||
--escape-bedrock <?value>: on bedrock linux, sets if it should escape the bedrock jail or not
|
||||
--pipe <?value>: disable logo and all escape sequences
|
||||
--load-config <file>: Load a config file or preset (+)
|
||||
--multithreading <?value>: Use multiple threads to detect values
|
||||
--stat <?value>: Show time usage (in ms) for individual modules
|
||||
--allow-slow-operations <?value>: Allow operations that are usually very slow for more detailed output
|
||||
--escape-bedrock <?value>: On Bedrock Linux, whether to escape the bedrock jail
|
||||
--pipe <?value>: Disable logo and all escape sequences
|
||||
|
||||
Logo options:
|
||||
-l,--logo <logo>: set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file
|
||||
--logo-type <type>: set the type of the logo given. Must be auto, builtin, file, raw, sixel, kitty or chafa.
|
||||
--logo-width <width>: set the width of the logo (in characters), if it is an image
|
||||
--logo-height <height>: set the height of the logo (in characters), if it is an image
|
||||
--logo-color-[1-9] <color>: overwrite a color in the logo
|
||||
--logo-padding <padding>: set the padding on the left and the right of the logo
|
||||
--logo-padding-left <padding>: set the padding on the left of the logo
|
||||
--logo-padding-right <padding>: set the padding on the right of the logo
|
||||
--logo-print-remaining <?value>: weather to print the remaining logo, if it has more lines than modules to display
|
||||
--sixel <file>: short for --logo-type sixel --logo <file>
|
||||
--kitty <file>: short for --logo-type kitty --logo <file>
|
||||
--chafa <file>: short for --logo-type chafa --logo <file>
|
||||
--file <file>: short for --logo-type file --logo <file>
|
||||
--raw <file>: short for --logo-type raw --logo <file>
|
||||
-l,--logo <logo>: Set the logo; if default, the name of a builtin logo or a path to a file
|
||||
--logo-type <type>: Set the type of the logo given; must be auto, builtin, file, file-raw, data, data-raw, sixel, kitty, iterm or chafa
|
||||
--logo-width <width>: Set the width of the logo (in characters), if it is an image. Required for iTerm image protocol
|
||||
--logo-height <height>: Set the height of the logo (in characters), if it is an image. Required for iTerm image protocol
|
||||
--logo-preserve-aspect-radio <?value>: Set if the logo should fill the specified width and height as much as possible without stretching. Supported by iTerm image protocol
|
||||
--logo-color-[1-9] <color>: Overwrite a color in the logo
|
||||
--logo-padding <padding>: Set the padding on the left and the right of the logo
|
||||
--logo-padding-left <padding>: Set the padding on the left of the logo
|
||||
--logo-padding-right <padding>: Set the padding on the right of the logo
|
||||
--logo-print-remaining <?value>: Whether to print the remaining logo, if it has more lines than modules to display
|
||||
--file <file>: Short for --logo-type file --logo <file>
|
||||
--file-raw <file>: Short for --logo-type file-raw --logo <file>
|
||||
--data <data>: Short for --logo-type data --logo <data>
|
||||
--data-raw <data>: Short for --logo-type data-raw --logo <data>
|
||||
--sixel <file>: Short for --logo-type sixel --logo <file>
|
||||
--kitty <file>: Short for --logo-type kitty --logo <file>
|
||||
--iterm <file>: Short for --logo-type iterm --logo <file>
|
||||
--chafa <file>: Short for --logo-type chafa --logo <file>
|
||||
--chafa-fg-only <?value>: Produce character-cell output using foreground colors only. See chafa document for detail
|
||||
--chafa-symbols <str>: Specify character symbols to employ in final output. See chafa document for detail
|
||||
--chafa-canvas-mode <value>: Determine how colors are used in the output. This value maps the int value of enum ChafaCanvasMode. See chafa document for detail
|
||||
--chafa-color-space <value>: Set color space used for quantization. 0 for RGB; 1 for DIN99d. See chafa document for detail
|
||||
--chafa-dither-mode <value>: Set output dither mode (No effect with 24-bit color). This value maps the int value of enum ChafaDitherMode. See chafa document for detail
|
||||
|
||||
Display options:
|
||||
-s,--structure <structure>: sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
|
||||
--color-keys <color>: 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
|
||||
-s,--structure <structure>: Set the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
|
||||
--color-keys <color>: Set the color of the keys
|
||||
--color-title <color>: Set the color of the title
|
||||
-c,--color <color>: Set the color of both the keys and title
|
||||
--separator <str>: Set the separator between key and value. Default is a colon with a space
|
||||
--set <key=value>: Hard set the value of a key
|
||||
--set-keyless <key=value>: Hard set the value of a key, but don't print the key or the separator
|
||||
--show-errors <?value>: Print occurring errors
|
||||
--disable-linewrap <?value>: Whether to disable line wrap during the run
|
||||
--hide-cursor <?value>: Whether to hide the cursor during the run
|
||||
--binary-prefix <value>: Set the binary prefix to used. Must be IEC, SI or JEDEC. Default is IEC.
|
||||
|
||||
General module options:
|
||||
--<module>-format <format>: Sets the format string to use for each specific module.
|
||||
--<module>-format <format>: Set the format string to use for each specific module.
|
||||
To see how a format string works, use fastfetch --help format.
|
||||
To see help about a specific format string, use fastfetch --help <module>-format.
|
||||
|
||||
--<module>-key <key>: Sets the key to use for each specific module.
|
||||
--<module>-key <key>: Set the key to use for each specific module.
|
||||
For modules which print multiple lines, the string is parsed as a format string with the index as first character.
|
||||
|
||||
--<module>-error <format>: Sets the error format string to use for each specific module.
|
||||
--<module>-error <format>: Set the error format string to use for each specific module.
|
||||
The error is given as the first and only argument.
|
||||
Setting this for a module will cause it to appear, even if --show-errors is not given.
|
||||
|
||||
@@ -87,25 +95,27 @@ Library options: Set the path of a library to load
|
||||
--lib-cjson <path>
|
||||
|
||||
Module specific options:
|
||||
--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 (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
|
||||
--title-fqdn <?value>: Set 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 information
|
||||
--disk-folders <folders>: A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows)
|
||||
--disk-show-removable <?value>: Set if removable volume should be printed. Default is true
|
||||
--disk-show-hidden <?value>: Set if hidden volumes 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>: Set the OpenGL context creation library to use. Must be auto, egl, glx or osmesa. Default is auto
|
||||
--percent-type <value>: Set the percentage output type. 1 for percentage number, 2 for bar, 3 for both. Default is 1
|
||||
|
||||
Parsing is not case sensitive. E.g. "--lib-PCI" is equal to "--Lib-Pci"
|
||||
If a value starts with a ?, it is optional. "true" will be used if not set.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
Battery
|
||||
Bios
|
||||
Board
|
||||
Break
|
||||
Chassis
|
||||
Colors
|
||||
CPU
|
||||
CPUUsage
|
||||
@@ -17,14 +20,13 @@ Locale
|
||||
LocalIP
|
||||
Media
|
||||
Memory
|
||||
OS
|
||||
OpenCL
|
||||
OpenGL
|
||||
OS
|
||||
Packages
|
||||
Player
|
||||
PowerAdapter
|
||||
Processes
|
||||
PublicIP
|
||||
PowerAdapter
|
||||
Resolution
|
||||
Separator
|
||||
Shell
|
||||
@@ -36,5 +38,7 @@ Time
|
||||
Title
|
||||
Uptime
|
||||
Vulkan
|
||||
Weather
|
||||
Wifi
|
||||
WM
|
||||
WMTheme
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef struct BatteryResult
|
||||
FFstrbuf manufacturer;
|
||||
FFstrbuf modelName;
|
||||
FFstrbuf technology;
|
||||
FFstrbuf capacity;
|
||||
double capacity;
|
||||
FFstrbuf status;
|
||||
double temperature;
|
||||
} BatteryResult;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
static double detectBatteryTemp()
|
||||
{
|
||||
FFlist temps;
|
||||
FF_LIST_AUTO_DESTROY temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
ffDetectCoreTemps(FF_TEMP_BATTERY, &temps);
|
||||
@@ -25,7 +25,6 @@ static double detectBatteryTemp()
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -55,7 +54,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
const char* error;
|
||||
|
||||
BatteryResult* battery = ffListAdd(results);
|
||||
ffStrbufInit(&battery->capacity);
|
||||
battery->capacity = 0.0/0.0;
|
||||
int currentCapacity, maxCapacity;
|
||||
|
||||
if ((error = ffCfDictGetInt(properties, CFSTR("MaxCapacity"), &maxCapacity)))
|
||||
@@ -68,7 +67,7 @@ const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
if(currentCapacity <= 0)
|
||||
return "Querying CurrentCapacity failed";
|
||||
|
||||
ffStrbufAppendF(&battery->capacity, "%.0f", currentCapacity * 100.0 / maxCapacity);
|
||||
battery->capacity = currentCapacity * 100.0 / maxCapacity;
|
||||
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
|
||||
@@ -33,18 +33,18 @@ static void parseBattery(FFstrbuf* dir, FFlist* results)
|
||||
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);
|
||||
bool available = ffReadFileBuffer(dir->chars, &testBatteryBuffer);
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if(result->capacity.length == 0)
|
||||
if(available)
|
||||
result->capacity = ffStrbufToDouble(&testBatteryBuffer);
|
||||
ffStrbufDestroy(&testBatteryBuffer);
|
||||
if(!available)
|
||||
{
|
||||
ffStrbufDestroy(&result->capacity);
|
||||
result->capacity = 0.0/0.0;
|
||||
--results->length;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
#include "battery.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <setupapi.h>
|
||||
#include <batclass.h>
|
||||
#include <devguid.h>
|
||||
#include <winternl.h>
|
||||
#include <powrprof.h>
|
||||
|
||||
static inline void wrapCloseHandle(HANDLE* handle)
|
||||
{
|
||||
if(*handle)
|
||||
CloseHandle(*handle);
|
||||
}
|
||||
static inline void wrapSetupDiDestroyDeviceInfoList(HDEVINFO* hdev)
|
||||
{
|
||||
if(*hdev)
|
||||
SetupDiDestroyDeviceInfoList(*hdev);
|
||||
}
|
||||
|
||||
const char* ffDetectBatteryImpl(FFinstance* instance, FFlist* results)
|
||||
{
|
||||
if(instance->config.allowSlowOperations)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/power/enumerating-battery-devices
|
||||
HDEVINFO hdev __attribute__((__cleanup__(wrapSetupDiDestroyDeviceInfoList))) =
|
||||
SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
if(hdev == INVALID_HANDLE_VALUE)
|
||||
return "SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY) failed";
|
||||
|
||||
for(DWORD idev = 0;; idev++)
|
||||
{
|
||||
SP_DEVICE_INTERFACE_DATA did = { .cbSize = sizeof(did) };
|
||||
if(!SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did))
|
||||
break;
|
||||
|
||||
DWORD cbRequired = 0;
|
||||
SetupDiGetDeviceInterfaceDetailW(hdev, &did, NULL, 0, &cbRequired, NULL); //Fail with not enough buffer
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA_W* FF_AUTO_FREE pdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA_W*)malloc(cbRequired);
|
||||
if(!pdidd)
|
||||
break; //Out of memory
|
||||
|
||||
pdidd->cbSize = sizeof(*pdidd);
|
||||
if(!SetupDiGetDeviceInterfaceDetailW(hdev, &did, pdidd, cbRequired, &cbRequired, NULL))
|
||||
continue;
|
||||
|
||||
HANDLE __attribute__((__cleanup__(wrapCloseHandle))) hBattery =
|
||||
CreateFileW(pdidd->DevicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if(hBattery == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
BATTERY_QUERY_INFORMATION bqi = { .InformationLevel = BatteryInformation };
|
||||
|
||||
DWORD dwWait = 0;
|
||||
DWORD dwOut;
|
||||
|
||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag, sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
|
||||
continue;
|
||||
|
||||
BATTERY_INFORMATION bi = {0};
|
||||
if(!DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi, sizeof(bi), &dwOut, NULL))
|
||||
continue;
|
||||
|
||||
if(!(bi.Capabilities & BATTERY_SYSTEM_BATTERY))
|
||||
continue;
|
||||
|
||||
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
|
||||
|
||||
if(memcmp(bi.Chemistry, "PbAc", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Lead Acid");
|
||||
else if(memcmp(bi.Chemistry, "LION", 4) == 0 || memcmp(bi.Chemistry, "Li-I", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Lithium Ion");
|
||||
else if(memcmp(bi.Chemistry, "NiCd", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Cadmium");
|
||||
else if(memcmp(bi.Chemistry, "NiMH", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Metal Hydride");
|
||||
else if(memcmp(bi.Chemistry, "NiZn", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Nickel Zinc");
|
||||
else if(memcmp(bi.Chemistry, "RAM\0", 4) == 0)
|
||||
ffStrbufInitS(&battery->technology, "Rechargeable Alkaline-Manganese");
|
||||
else
|
||||
ffStrbufInitS(&battery->technology, "Unknown");
|
||||
|
||||
{
|
||||
ffStrbufInit(&battery->modelName);
|
||||
bqi.InformationLevel = BatteryDeviceName;
|
||||
wchar_t name[64];
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||
ffStrbufSetWS(&battery->modelName, name);
|
||||
}
|
||||
|
||||
{
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
bqi.InformationLevel = BatteryManufactureName;
|
||||
wchar_t name[64];
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), name, sizeof(name), &dwOut, NULL))
|
||||
ffStrbufSetWS(&battery->manufacturer, name);
|
||||
}
|
||||
|
||||
battery->temperature = 0.0/0.0;
|
||||
if(instance->config.batteryTemp)
|
||||
{
|
||||
bqi.InformationLevel = BatteryTemperature;
|
||||
ULONG temp;
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &temp, sizeof(temp), &dwOut, NULL))
|
||||
battery->temperature = temp;
|
||||
}
|
||||
|
||||
{
|
||||
BATTERY_STATUS bs;
|
||||
BATTERY_WAIT_STATUS bws = { .BatteryTag = bqi.BatteryTag };
|
||||
if(DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws), &bs, sizeof(bs), &dwOut, NULL) && bs.Capacity != BATTERY_UNKNOWN_CAPACITY)
|
||||
battery->capacity = bs.Capacity * 100.0 / bi.FullChargedCapacity;
|
||||
else
|
||||
battery->capacity = 0;
|
||||
|
||||
ffStrbufInit(&battery->status);
|
||||
if(bs.PowerState & BATTERY_POWER_ON_LINE)
|
||||
ffStrbufAppendS(&battery->status, "AC Connected, ");
|
||||
if(bs.PowerState & BATTERY_DISCHARGING)
|
||||
ffStrbufAppendS(&battery->status, "Discharging, ");
|
||||
if(bs.PowerState & BATTERY_CHARGING)
|
||||
ffStrbufAppendS(&battery->status, "Charging");
|
||||
if(bs.PowerState & BATTERY_CRITICAL)
|
||||
ffStrbufAppendS(&battery->status, "Critical, ");
|
||||
ffStrbufTrimRight(&battery->status, ' ');
|
||||
ffStrbufTrimRight(&battery->status, ',');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SYSTEM_BATTERY_STATE info;
|
||||
if (NT_SUCCESS(CallNtPowerInformation(SystemBatteryState, NULL, 0, &info, sizeof(info))) && info.BatteryPresent)
|
||||
{
|
||||
BatteryResult* battery = (BatteryResult*)ffListAdd(results);
|
||||
ffStrbufInit(&battery->modelName);
|
||||
ffStrbufInit(&battery->manufacturer);
|
||||
ffStrbufInit(&battery->technology);
|
||||
ffStrbufInit(&battery->status);
|
||||
battery->temperature = 0.0/0.0;
|
||||
|
||||
battery->capacity = info.RemainingCapacity * 100.0 / info.MaxCapacity;
|
||||
if(info.AcOnLine)
|
||||
{
|
||||
ffStrbufAppendS(&battery->status, "AC Connected");
|
||||
if(info.Charging)
|
||||
ffStrbufAppendS(&battery->status, ", Charging");
|
||||
}
|
||||
else if(info.Discharging)
|
||||
ffStrbufAppendS(&battery->status, "Discharging");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
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,70 @@
|
||||
#include "bios.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
|
||||
#ifndef __aarch64__
|
||||
|
||||
//https://github.com/osquery/osquery/blob/master/osquery/tables/system/darwin/smbios_tables.cpp
|
||||
//For Intel
|
||||
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/rom")))
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
|
||||
{
|
||||
IOObjectRelease(registryEntry);
|
||||
ffStrbufAppendS(&bios->error, "IORegistryEntryCreateCFProperties(registryEntry) failed");
|
||||
return;
|
||||
}
|
||||
|
||||
ffCfDictGetString(properties, CFSTR("vendor"), &bios->biosVendor);
|
||||
ffCfDictGetString(properties, CFSTR("version"), &bios->biosVersion);
|
||||
ffCfDictGetString(properties, CFSTR("release-date"), &bios->biosDate);
|
||||
if(!ffStrbufContainC(&bios->biosDate, '-'))
|
||||
ffStrbufAppendS(&bios->biosRelease, "Efi-");
|
||||
ffStrbufAppend(&bios->biosRelease, &bios->biosVersion);
|
||||
|
||||
CFRelease(properties);
|
||||
IOObjectRelease(registryEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//For arm64
|
||||
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/")))
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess)
|
||||
{
|
||||
ffCfDictGetString(properties, CFSTR("manufacturer"), &bios->biosVendor);
|
||||
CFRelease(properties);
|
||||
}
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
if((registryEntry = IORegistryEntryFromPath(MACH_PORT_NULL, "IODeviceTree:/chosen")))
|
||||
{
|
||||
CFMutableDictionaryRef properties;
|
||||
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) == kIOReturnSuccess)
|
||||
{
|
||||
ffCfDictGetString(properties, CFSTR("system-firmware-version"), &bios->biosRelease);
|
||||
ffStrbufAppend(&bios->biosVersion, &bios->biosRelease);
|
||||
ffStrbufSubstrAfterFirstC(&bios->biosVersion, '-');
|
||||
CFRelease(properties);
|
||||
}
|
||||
IOObjectRelease(registryEntry);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "bios.h"
|
||||
|
||||
#include <kenv.h>
|
||||
|
||||
static void kenvLookup(const char* name, FFstrbuf* result)
|
||||
{
|
||||
ffStrbufEnsureFree(result, 255);
|
||||
int len = kenv(KENV_GET, name, result->chars, 256);
|
||||
if(len > 0)
|
||||
result->length = (uint32_t) len;
|
||||
}
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
//https://wiki.ghostbsd.org/index.php/Kenv
|
||||
kenvLookup("smbios.bios.reldate", &bios->biosDate);
|
||||
kenvLookup("smbios.system.product", &bios->biosRelease);
|
||||
kenvLookup("smbios.bios.vendor", &bios->biosVendor);
|
||||
kenvLookup("smbios.bios.version", &bios->biosVersion);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "bios.h"
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
void ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
ffStrbufInit(&bios->error);
|
||||
|
||||
ffStrbufInit(&bios->biosDate);
|
||||
ffStrbufInit(&bios->biosRelease);
|
||||
ffStrbufInit(&bios->biosVendor);
|
||||
ffStrbufInit(&bios->biosVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &bios->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, L"BIOSVersion", &bios->biosRelease, &bios->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, L"BIOSVendor", &bios->biosVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BIOSReleaseDate", &bios->biosDate, NULL);
|
||||
|
||||
uint32_t major, minor;
|
||||
if(
|
||||
ffRegReadUint(hKey, L"BiosMajorRelease", &major, NULL) &&
|
||||
ffRegReadUint(hKey, L"BiosMinorRelease", &minor, NULL)
|
||||
)
|
||||
ffStrbufAppendF(&bios->biosVersion, "%u.%u", (unsigned)major, (unsigned)minor);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
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,21 @@
|
||||
#include "board.h"
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
void ffDetectBoard(FFBoardResult* board)
|
||||
{
|
||||
ffStrbufInit(&board->error);
|
||||
|
||||
ffStrbufInit(&board->boardName);
|
||||
ffStrbufInit(&board->boardVendor);
|
||||
ffStrbufInit(&board->boardVersion);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &board->error))
|
||||
return;
|
||||
|
||||
if(!ffRegReadStrbuf(hKey, L"BaseBoardProduct", &board->boardName, &board->error))
|
||||
return;
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardManufacturer", &board->boardVendor, NULL);
|
||||
ffRegReadStrbuf(hKey, L"BaseBoardVersion", &board->boardVersion, NULL);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
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,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_chassis_chassis
|
||||
#define FF_INCLUDED_detection_chassis_chassis
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFChassisResult
|
||||
{
|
||||
FFstrbuf chassisType;
|
||||
FFstrbuf chassisVendor;
|
||||
FFstrbuf chassisVersion;
|
||||
FFstrbuf error;
|
||||
} FFChassisResult;
|
||||
|
||||
void ffDetectChassis(FFChassisResult* result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "chassis.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 ffDetectChassis(FFChassisResult* result)
|
||||
{
|
||||
ffStrbufInit(&result->error);
|
||||
|
||||
ffStrbufInit(&result->chassisType);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &result->chassisType);
|
||||
|
||||
ffStrbufInit(&result->chassisVendor);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &result->chassisVendor);
|
||||
|
||||
ffStrbufInit(&result->chassisVersion);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &result->chassisVersion);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "chassis.h"
|
||||
|
||||
void ffDetectChassis(FFChassisResult* result)
|
||||
{
|
||||
ffStrbufInitS(&result->error, "Not supported on this platform");
|
||||
|
||||
ffStrbufInit(&result->chassisType);
|
||||
ffStrbufInit(&result->chassisVendor);
|
||||
ffStrbufInit(&result->chassisVersion);
|
||||
}
|
||||
+2
-26
@@ -1,37 +1,15 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu);
|
||||
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;
|
||||
ffDetectCPUImpl(instance, cpu);
|
||||
|
||||
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",
|
||||
@@ -40,8 +18,6 @@ static void detectCPU(const FFinstance* instance, FFCPUResult* cpu)
|
||||
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)
|
||||
|
||||
@@ -15,7 +15,7 @@ static double getFrequency(const char* propName)
|
||||
|
||||
static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
{
|
||||
FFlist temps;
|
||||
FF_LIST_AUTO_DESTROY temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
|
||||
@@ -38,36 +38,32 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
if(!cached)
|
||||
{
|
||||
ffSysctlGetString("machdep.cpu.brand_string", &cpu->name);
|
||||
ffSysctlGetString("machdep.cpu.vendor", &cpu->vendor);
|
||||
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->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->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->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");
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
#include "cpu.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
if(cached)
|
||||
return;
|
||||
if (instance->config.cpuTemp)
|
||||
{
|
||||
FFstrbuf cpuTemp;
|
||||
ffStrbufInit(&cpuTemp);
|
||||
if(ffSysctlGetString("temperature", &cpuTemp))
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
else
|
||||
cpu->temperature = ffStrbufToDouble(&cpuTemp);
|
||||
}
|
||||
else
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
|
||||
ffSysctlGetString("hw.model", &cpu->name);
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
#include "common/properties.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer)
|
||||
static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz)
|
||||
{
|
||||
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||
if(cpuinfo == NULL)
|
||||
@@ -25,6 +26,7 @@ static void parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer)
|
||||
ffParsePropLine(line, "model name :", &cpu->name) ||
|
||||
ffParsePropLine(line, "vendor_id :", &cpu->vendor) ||
|
||||
ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) ||
|
||||
ffParsePropLine(line, "cpu MHz :", cpuMHz) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) //For Android devices
|
||||
);
|
||||
}
|
||||
@@ -39,16 +41,19 @@ static double getGHz(const char* file)
|
||||
{
|
||||
FFstrbuf content;
|
||||
ffStrbufInit(&content);
|
||||
ffReadFileBuffer(file, &content);
|
||||
double herz = ffStrbufToDouble(&content);
|
||||
ffStrbufDestroy(&content);
|
||||
if(ffAppendFileBuffer(file, &content))
|
||||
{
|
||||
double herz = ffStrbufToDouble(&content);
|
||||
ffStrbufDestroy(&content);
|
||||
|
||||
//ffStrbufToDouble failed
|
||||
if(herz != herz)
|
||||
return 0;
|
||||
//ffStrbufToDouble failed
|
||||
if(herz != herz)
|
||||
return 0;
|
||||
|
||||
herz /= 1000.0; //to MHz
|
||||
return herz / 1000.0; //to GHz
|
||||
herz /= 1000.0; //to MHz
|
||||
return herz / 1000.0; //to GHz
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double getFrequency(const char* info, const char* scaling)
|
||||
@@ -78,34 +83,37 @@ static double detectCPUTemp(const FFinstance* instance)
|
||||
return FF_CPU_TEMP_UNSET;
|
||||
}
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
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);
|
||||
FFstrbuf cpuMHz;
|
||||
ffStrbufInit(&cpuMHz);
|
||||
|
||||
parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz);
|
||||
|
||||
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
|
||||
cpu->coresLogical = (uint16_t) get_nprocs_conf();
|
||||
cpu->coresOnline = (uint16_t) get_nprocs();
|
||||
|
||||
#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");
|
||||
if(ffFileExists(BP, S_IFDIR))
|
||||
{
|
||||
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
|
||||
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->frequencyMin = cpu->frequencyMax = ffStrbufToDouble(&cpuMHz) / 1000;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&physicalCoresBuffer);
|
||||
ffStrbufDestroy(&cpuMHz);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "cpu.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
cpu->temperature = FF_CPU_TEMP_UNSET;
|
||||
cpu->coresPhysical = cpu->coresLogical = cpu->coresOnline = 0;
|
||||
cpu->frequencyMax = cpu->frequencyMin = 0;
|
||||
ffStrbufInit(&cpu->name);
|
||||
ffStrbufInit(&cpu->vendor);
|
||||
|
||||
{
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformationEx(RelationProcessorCore, NULL, &length);
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
|
||||
pLogicalInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
|
||||
|
||||
if(pLogicalInfo && GetLogicalProcessorInformationEx(RelationProcessorCore, pLogicalInfo, &length))
|
||||
{
|
||||
for(
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pLogicalInfo;
|
||||
(uint8_t*)ptr < ((uint8_t*)pLogicalInfo) + length;
|
||||
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
|
||||
)
|
||||
{
|
||||
if(ptr->Relationship == RelationProcessorCore)
|
||||
++cpu->coresPhysical;
|
||||
}
|
||||
}
|
||||
}
|
||||
cpu->coresOnline = (uint16_t)GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
cpu->coresLogical = (uint16_t)GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
|
||||
return;
|
||||
|
||||
{
|
||||
uint32_t mhz;
|
||||
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
|
||||
cpu->frequencyMax = mhz / 1000.0;
|
||||
}
|
||||
|
||||
ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL);
|
||||
ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
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();
|
||||
}
|
||||
@@ -1,18 +1,6 @@
|
||||
#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>
|
||||
@@ -20,39 +8,37 @@ const char* ffGetCpuUsageResult(double* result) {
|
||||
// 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;
|
||||
static uint64_t inUseAll1, totalAll1;
|
||||
|
||||
void ffPrepareCPUUsage()
|
||||
{
|
||||
startTime = ffTimeGetTick();
|
||||
ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageResult(double* result)
|
||||
{
|
||||
const char* error = NULL;
|
||||
if(startTime == 0)
|
||||
if(inUseAll1 == 0 && totalAll1 == 0)
|
||||
{
|
||||
error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1);
|
||||
if(error)
|
||||
return error;
|
||||
ffTimeSleep(1000);
|
||||
ffTimeSleep(200);
|
||||
}
|
||||
else
|
||||
|
||||
while(true)
|
||||
{
|
||||
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;
|
||||
|
||||
if(inUseAll2 != inUseAll1)
|
||||
{
|
||||
*result = (double)(inUseAll2 - inUseAll1) / (double)(totalAll2 - totalAll1) * 100;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
ffTimeSleep(200);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
#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,19 @@
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
// interrupt processing, user processes, system processing, lock spinning, and idling
|
||||
uint64_t cpTime[5];
|
||||
size_t neededLength = sizeof(cpTime);
|
||||
if(sysctlbyname("kern.cp_time", cpTime, &neededLength, NULL, 0) != 0)
|
||||
return "sysctlbyname(kern.cp_time) failed";
|
||||
|
||||
*inUseAll = cpTime[0] + cpTime[1] + cpTime[2] + cpTime[3];
|
||||
*totalAll = *inUseAll + cpTime[4];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -10,7 +10,13 @@ const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
|
||||
FILE* procStat = fopen("/proc/stat", "r");
|
||||
if(procStat == NULL)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
return "Accessing \"/proc/stat\" is restricted on Android O+";
|
||||
#else
|
||||
return "fopen(\"""/proc/stat\", \"r\") == NULL";
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0)
|
||||
{
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
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;
|
||||
}
|
||||
@@ -1,8 +1,46 @@
|
||||
#include "fastfetch.h"
|
||||
#include "cpuUsage.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
#ifdef FF_USE_WIN_NTAPI
|
||||
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <ntstatus.h>
|
||||
#include <winternl.h>
|
||||
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
ULONG size = 0;
|
||||
if(NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL, 0, &size) != STATUS_INFO_LENGTH_MISMATCH)
|
||||
return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, NULL) failed";
|
||||
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* FF_AUTO_FREE pinfo = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)malloc(size);
|
||||
if(!NT_SUCCESS(NtQuerySystemInformation(SystemProcessorPerformanceInformation, pinfo, size, &size)))
|
||||
return "NtQuerySystemInformation(SystemProcessorPerformanceInformation, size) failed";
|
||||
|
||||
*inUseAll = *totalAll = 0;
|
||||
|
||||
for (uint32_t i = 0; i < size / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); ++i)
|
||||
{
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* coreInfo = pinfo + i;
|
||||
|
||||
// KernelTime includes idle time.
|
||||
LONGLONG dpcTime = coreInfo->Reserved1[0].QuadPart;
|
||||
LONGLONG interruptTime = coreInfo->Reserved1[1].QuadPart;
|
||||
coreInfo->KernelTime.QuadPart -= coreInfo->IdleTime.QuadPart;
|
||||
coreInfo->KernelTime.QuadPart += dpcTime + interruptTime;
|
||||
|
||||
LONGLONG inUse = coreInfo->UserTime.QuadPart + coreInfo->KernelTime.QuadPart;
|
||||
*inUseAll += (uint64_t)inUse;
|
||||
*totalAll += (uint64_t)(inUse + coreInfo->IdleTime.QuadPart);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <processthreadsapi.h>
|
||||
|
||||
static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
|
||||
return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime);
|
||||
@@ -11,10 +49,14 @@ static inline uint64_t fileTimeToUint64(const FILETIME* ft) {
|
||||
const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
|
||||
{
|
||||
FILETIME idleTime, kernelTime, userTime;
|
||||
if(GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0)
|
||||
if(!GetSystemTimes(&idleTime, &kernelTime, &userTime))
|
||||
return "GetSystemTimes() failed";
|
||||
|
||||
*inUseAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
|
||||
*totalAll = *inUseAll + fileTimeToUint64(&idleTime);
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getsystemtimes
|
||||
// `kernelTime` also includes the amount of time the system has been idle.
|
||||
*totalAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime);
|
||||
*inUseAll = *totalAll - fileTimeToUint64(&idleTime);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_cursor_cursor
|
||||
#define FF_INCLUDED_detection_cursor_cursor
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFCursorResult
|
||||
{
|
||||
FFstrbuf theme;
|
||||
FFstrbuf size;
|
||||
FFstrbuf error;
|
||||
} FFCursorResult;
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "cursor.h"
|
||||
|
||||
#include "common/properties.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/settings.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void detectCursorGTK(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
const FFGTKResult* gtk = ffDetectGTK4(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK3(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
gtk = ffDetectGTK2(instance);
|
||||
|
||||
if(gtk->cursor.length == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "Couldn't detect GTK Cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufAppend(&result->theme, >k->cursor);
|
||||
ffStrbufAppend(&result->size, >k->cursorSize);
|
||||
}
|
||||
|
||||
static void detectCursorXFCE(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
ffStrbufAppendS(&result->theme, ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue);
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendS(&result->error, "Couldn't find xfce cursor in xfconf (xsettings::/Gtk/CursorThemeName)");
|
||||
|
||||
int cursorSizeVal = ffSettingsGetXFConf(instance, "xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
|
||||
if(cursorSizeVal > 0)
|
||||
ffStrbufAppendF(&result->size, "%i", cursorSizeVal);
|
||||
}
|
||||
|
||||
static void detectCursorFromConfigFile(const FFinstance* instance, const char* relativeFilePath, const char* themeStart, const char* themeDefault, const char* sizeStart, const char* sizeDefault, FFCursorResult* result)
|
||||
{
|
||||
if(ffParsePropFileConfigValues(instance, relativeFilePath, 2, (FFpropquery[]) {
|
||||
{themeStart, &result->theme},
|
||||
{sizeStart, &result->size}
|
||||
})) {
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendS(&result->theme, themeDefault);
|
||||
|
||||
if(result->size.length == 0)
|
||||
ffStrbufAppendS(&result->size, sizeDefault);
|
||||
}
|
||||
|
||||
if(result->theme.length == 0)
|
||||
ffStrbufAppendF(&result->error, "Couldn't find cursor in %s", relativeFilePath);
|
||||
}
|
||||
|
||||
static bool detectCursorFromXResources(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
ffParsePropFileHomeValues(instance, ".Xresources", 2, (FFpropquery[]) {
|
||||
{"Xcursor.theme :", &result->theme},
|
||||
{"Xcursor.size :", &result->size}
|
||||
});
|
||||
|
||||
return result->theme.length > 0;
|
||||
}
|
||||
|
||||
static bool detectCursorFromXDG(const FFinstance* instance, bool user, FFCursorResult* result)
|
||||
{
|
||||
if(user)
|
||||
ffParsePropFileHome(instance, ".icons/default/index.theme", "Inherits =", &result->theme);
|
||||
else
|
||||
ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/icons/default/index.theme", "Inherits =", &result->theme);
|
||||
|
||||
return result->theme.length > 0;
|
||||
}
|
||||
|
||||
static bool detectCursorFromEnv(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
const char* xcursor_theme = getenv("XCURSOR_THEME");
|
||||
|
||||
if(!ffStrSet(xcursor_theme))
|
||||
return false;
|
||||
|
||||
ffStrbufAppendS(&result->theme, xcursor_theme);
|
||||
ffStrbufAppendS(&result->size, getenv("XCURSOR_SIZE"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer(instance);
|
||||
|
||||
if(ffStrbufCompS(&wmde->wmPrettyName, "WSLg") == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "WSLg uses native windows cursor");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, "TTY") == 0)
|
||||
{
|
||||
ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY");
|
||||
return;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "KDE Plasma") == 0)
|
||||
return detectCursorFromConfigFile(instance, "kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "XFCE"))
|
||||
return detectCursorXFCE(instance, result);
|
||||
|
||||
if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, "LXQt"))
|
||||
return detectCursorFromConfigFile(instance, "lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Gnome") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Cinnamon") == 0 || ffStrbufIgnCaseCompS(&wmde->dePrettyName, "Mate") == 0)
|
||||
return detectCursorGTK(instance, result);
|
||||
|
||||
if(
|
||||
detectCursorFromEnv(instance, result) ||
|
||||
detectCursorFromXDG(instance, true, result) ||
|
||||
detectCursorFromXResources(instance, result) ||
|
||||
detectCursorFromXDG(instance, false, result)
|
||||
) return;
|
||||
|
||||
detectCursorGTK(instance, result);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "cursor.h"
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
FF_UNUSED(instance, result);
|
||||
ffStrbufInitS(&result->error, "Not supported on this platform");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "cursor.h"
|
||||
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
void ffDetectCursor(const FFinstance* instance, FFCursorResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey;
|
||||
if(ffRegOpenKeyForRead(HKEY_CURRENT_USER, L"Control Panel\\Cursors", &hKey, &result->error))
|
||||
ffRegReadStrbuf(hKey, NULL, &result->theme, &result->error);
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/datetime.h"
|
||||
#include "common/thread.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance); //We may need it later for additional configuration
|
||||
|
||||
static FFDateTimeResult result;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
||||
static bool init = false;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
ffThreadMutexLock(&mutex);
|
||||
if (init)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
init = true;
|
||||
@@ -68,6 +68,6 @@ const FFDateTimeResult* ffDetectDateTime(const FFinstance* instance)
|
||||
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);
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
|
||||
+17
-45
@@ -1,56 +1,28 @@
|
||||
#include "fastfetch.h"
|
||||
#include "disk.h"
|
||||
#include "detection/internal.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
void ffDetectDisksImpl(FFDiskResult* disks);
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result)
|
||||
static int compareDisks(const void* disk1, const void* disk2)
|
||||
{
|
||||
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
|
||||
return ffStrbufCompAlphabetically(&((const FFDisk*) disk1)->mountpoint, &((const FFDisk*) disk2)->mountpoint);
|
||||
}
|
||||
|
||||
bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders)
|
||||
const FFDiskResult* ffDetectDisks()
|
||||
{
|
||||
ffStrbufTrim(&instance->config.diskFolders, ':');
|
||||
if(instance->config.diskFolders.length == 0)
|
||||
return false;
|
||||
FF_DETECTION_INTERNAL_GUARD(FFDiskResult,
|
||||
ffStrbufInit(&result.error);
|
||||
ffListInitA(&result.disks, sizeof(FFDisk), 4);
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < instance->config.diskFolders.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':');
|
||||
instance->config.diskFolders.chars[colonIndex] = '\0';
|
||||
ffDetectDisksImpl(&result);
|
||||
|
||||
ffDetectDiskWithStatvfs(instance->config.diskFolders.chars + startIndex, NULL, (FFDiskResult*)ffListAdd(folders));
|
||||
if(result.disks.length == 0 && result.error.length == 0)
|
||||
ffStrbufAppendS(&result.error, "No disks found");
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
//We need to sort the disks, so that we can detect, which disk a path resides on
|
||||
// For example for /boot/efi/bootmgr we need to check /boot/efi before /boot
|
||||
//Note that we sort alphabetically here for a better ordering when printing the list,
|
||||
// so the check must be done in reverse order
|
||||
ffListSort(&result.disks, compareDisks);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,17 +5,39 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef enum FFDiskType
|
||||
{
|
||||
FF_DISK_TYPE_REGULAR,
|
||||
FF_DISK_TYPE_HIDDEN,
|
||||
FF_DISK_TYPE_EXTERNAL
|
||||
} FFDiskType;
|
||||
|
||||
typedef struct FFDisk
|
||||
{
|
||||
FFstrbuf mountpoint;
|
||||
FFstrbuf filesystem;
|
||||
FFstrbuf name;
|
||||
FFDiskType type;
|
||||
|
||||
uint64_t bytesUsed;
|
||||
uint64_t bytesTotal;
|
||||
|
||||
uint32_t filesUsed;
|
||||
uint32_t filesTotal;
|
||||
} FFDisk;
|
||||
|
||||
typedef struct FFDiskResult
|
||||
{
|
||||
FFstrbuf path;
|
||||
uint64_t used;
|
||||
uint64_t total;
|
||||
uint32_t files;
|
||||
bool removable;
|
||||
FFstrbuf error;
|
||||
FFlist disks; //List of FFDisk
|
||||
} FFDiskResult;
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders);
|
||||
bool ffDiskDetectDiskFolders(FFinstance* instance, FFlist* folders);
|
||||
/**
|
||||
* Returns a List of FFDisk, sorted alphabetically by mountpoint.
|
||||
* If error is not set, disks contains at least one disk.
|
||||
*
|
||||
* @return const FFDiskResult*
|
||||
*/
|
||||
const FFDiskResult* ffDetectDisks();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,29 +1,17 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/mount.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result);
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil];
|
||||
NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys
|
||||
options:NSVolumeEnumerationSkipHiddenVolumes];
|
||||
if(urls == nil)
|
||||
return "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed";
|
||||
// FreeBSD doesn't support these flags
|
||||
if(fs->f_flags & MNT_DONTBROWSE)
|
||||
disk->type = FF_DISK_TYPE_HIDDEN;
|
||||
else if(fs->f_flags & MNT_REMOVABLE)
|
||||
disk->type = FF_DISK_TYPE_EXTERNAL;
|
||||
else
|
||||
disk->type = FF_DISK_TYPE_REGULAR;
|
||||
|
||||
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;
|
||||
ffStrbufInitS(&disk->name, [NSFileManager.defaultManager displayNameAtPath:@(fs->f_mntonname)].UTF8String);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/mount.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
if(
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/boot") ||
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/dev") ||
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/var") ||
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/tmp") ||
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/proc") ||
|
||||
ffStrbufStartsWithS(&disk->mountpoint, "/zroot")
|
||||
)
|
||||
disk->type = FF_DISK_TYPE_HIDDEN;
|
||||
else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL))
|
||||
disk->type = FF_DISK_TYPE_EXTERNAL;
|
||||
else
|
||||
disk->type = FF_DISK_TYPE_REGULAR;
|
||||
|
||||
ffStrbufInit(&disk->name);
|
||||
}
|
||||
#else
|
||||
void detectFsInfo(struct statfs* fs, FFDisk* disk);
|
||||
#endif
|
||||
|
||||
void ffDetectDisksImpl(FFDiskResult* disks)
|
||||
{
|
||||
struct statfs* buf;
|
||||
|
||||
int size = getmntinfo(&buf, MNT_WAIT);
|
||||
if(size <= 0)
|
||||
ffStrbufAppendS(&disks->error, "getmntinfo() failed");
|
||||
|
||||
for(struct statfs* fs = buf; fs < buf + size; ++fs)
|
||||
{
|
||||
FFDisk* disk = ffListAdd(&disks->disks);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
// f_bavail and f_ffree are signed on FreeBSD...
|
||||
if(fs->f_bavail < 0) fs->f_bavail = 0;
|
||||
if(fs->f_ffree < 0) fs->f_ffree = 0;
|
||||
#endif
|
||||
|
||||
disk->bytesTotal = fs->f_blocks * fs->f_bsize;
|
||||
disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bavail * fs->f_bsize);
|
||||
|
||||
disk->filesTotal = (uint32_t) fs->f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree);
|
||||
|
||||
ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
|
||||
ffStrbufInitS(&disk->filesystem, fs->f_fstypename);
|
||||
detectFsInfo(fs, disk);
|
||||
}
|
||||
}
|
||||
+116
-16
@@ -1,24 +1,124 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
void ffDetectDiskWithStatvfs(const char* folderPath, struct statvfs* fs, FFDiskResult* result);
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
static void strbufAppendMountPoint(FFstrbuf* mountpoint, const char* source)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
while(*source != '\0' && !isspace(*source))
|
||||
{
|
||||
//After a backslash the next 3 characters are octal ascii codes
|
||||
if(*source == '\\' && strnlen(source, 4) == 4)
|
||||
{
|
||||
char octal[4] = {0};
|
||||
strncpy(octal, source + 1, 3);
|
||||
|
||||
struct statvfs fsRoot;
|
||||
int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot);
|
||||
if(rootRet != 0)
|
||||
return "statvfs(\"/\") failed";
|
||||
long value = strtol(octal, NULL, 8); //Returns 0 on error, so no need to check endptr
|
||||
if(value > 0 && value < CHAR_MAX)
|
||||
{
|
||||
ffStrbufAppendC(mountpoint, (char) value);
|
||||
source += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
ffStrbufAppendC(mountpoint, *source);
|
||||
++source;
|
||||
}
|
||||
}
|
||||
|
||||
void ffDetectDisksImpl(FFDiskResult* disks)
|
||||
{
|
||||
FILE* mountsFile = fopen("/proc/mounts", "r");
|
||||
if(mountsFile == NULL)
|
||||
{
|
||||
ffStrbufAppendS(&disks->error, "fopen(\"/proc/mounts\", \"r\") == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while(getline(&line, &len, mountsFile) != EOF)
|
||||
{
|
||||
//Format of the file: "<device> <mountpoint> <filesystem> <options> ..." (Same as fstab)
|
||||
char* currentPos = line;
|
||||
|
||||
//Non pseudo filesystems have their device in /dev/
|
||||
//DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem.
|
||||
if(strncmp(currentPos, "/dev/", 5) != 0 && strncmp(currentPos, "drvfs", 5) != 0)
|
||||
continue;
|
||||
|
||||
//Skip /dev/ or drvfs
|
||||
currentPos += 5;
|
||||
|
||||
//Don't show loop file systems
|
||||
if(strncasecmp(currentPos, "loop", 4) == 0)
|
||||
continue;
|
||||
|
||||
FFDisk* disk = ffListAdd(&disks->disks);
|
||||
|
||||
//Go to mountpoint
|
||||
while(!isspace(*currentPos) && *currentPos != '\0')
|
||||
++currentPos;
|
||||
while(isspace(*currentPos))
|
||||
++currentPos;
|
||||
|
||||
ffStrbufInitA(&disk->mountpoint, 16);
|
||||
strbufAppendMountPoint(&disk->mountpoint, currentPos);
|
||||
|
||||
//Go to filesystem
|
||||
currentPos += disk->mountpoint.length;
|
||||
while(isspace(*currentPos))
|
||||
++currentPos;
|
||||
|
||||
ffStrbufInitA(&disk->filesystem, 16);
|
||||
ffStrbufAppendSUntilC(&disk->filesystem, currentPos, ' ');
|
||||
|
||||
//Go to options, detect type
|
||||
currentPos += disk->filesystem.length;
|
||||
while(isspace(*currentPos))
|
||||
++currentPos;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if(ffStrbufEqualS(&disk->mountpoint, "/") || ffStrbufEqualS(&disk->mountpoint, "/storage/emulated"))
|
||||
disk->type = FF_DISK_TYPE_REGULAR;
|
||||
else if(ffStrbufStartsWithS(&disk->mountpoint, "/mnt/media_rw/"))
|
||||
disk->type = FF_DISK_TYPE_EXTERNAL;
|
||||
else
|
||||
disk->type = FF_DISK_TYPE_HIDDEN;
|
||||
#else
|
||||
if(strstr(currentPos, "nosuid") != NULL || strstr(currentPos, "nodev") != NULL)
|
||||
disk->type = FF_DISK_TYPE_EXTERNAL;
|
||||
else if(ffStrbufStartsWithS(&disk->mountpoint, "/boot") || ffStrbufStartsWithS(&disk->mountpoint, "/efi"))
|
||||
disk->type = FF_DISK_TYPE_HIDDEN;
|
||||
else
|
||||
disk->type = FF_DISK_TYPE_REGULAR;
|
||||
#endif
|
||||
|
||||
//Detects stats
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct statvfs64 fs;
|
||||
if(statvfs64(disk->mountpoint.chars, &fs) != 0)
|
||||
memset(&fs, 0, sizeof(struct statvfs64)); //Set all values to 0, so our values get initialized to 0 too
|
||||
#else
|
||||
struct statvfs fs;
|
||||
if(statvfs(disk->mountpoint.chars, &fs) != 0)
|
||||
memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
|
||||
#endif
|
||||
|
||||
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
|
||||
disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize);
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
|
||||
ffStrbufInit(&disk->name); //TODO: implement this
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(mountsFile);
|
||||
}
|
||||
|
||||
@@ -1,66 +1,70 @@
|
||||
#include "disk.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <Windows.h>
|
||||
#include <windows.h>
|
||||
|
||||
static void detectDrive(const char* folderPath, uint32_t pathLen, FFDiskResult* result)
|
||||
void ffDetectDisksImpl(FFDiskResult* disks)
|
||||
{
|
||||
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;)
|
||||
uint32_t length = GetLogicalDriveStringsA(0, NULL);
|
||||
if(length == 0)
|
||||
{
|
||||
const char* drive = buf + i;
|
||||
uint32_t driveLen = (uint32_t) strlen(drive);
|
||||
i += driveLen + 1;
|
||||
ffStrbufAppendS(&disks->error, "GetLogicalDriveStringsA failed");
|
||||
return;
|
||||
}
|
||||
|
||||
bool removable = GetDriveTypeA(drive) == DRIVE_REMOVABLE;
|
||||
if(removable && !instance->config.diskRemovable)
|
||||
char* buf = malloc(length + 1);
|
||||
GetLogicalDriveStringsA(length, buf);
|
||||
|
||||
for(uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
const char* mountpoint = buf + i;
|
||||
|
||||
UINT driveType = GetDriveTypeA(mountpoint);
|
||||
if(driveType == DRIVE_NO_ROOT_DIR)
|
||||
{
|
||||
i += (uint32_t)strlen(mountpoint);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFDiskResult* folder = (FFDiskResult*)ffListAdd(folders);
|
||||
detectDrive(drive, driveLen, folder);
|
||||
folder->removable = removable;
|
||||
FFDisk* disk = ffListAdd(&disks->disks);
|
||||
ffStrbufInitS(&disk->mountpoint, mountpoint);
|
||||
|
||||
uint64_t bytesFree;
|
||||
if(!GetDiskFreeSpaceExA(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree))
|
||||
{
|
||||
disk->bytesTotal = 0;
|
||||
bytesFree = 0;
|
||||
}
|
||||
disk->bytesUsed = disk->bytesTotal - bytesFree;
|
||||
|
||||
if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM)
|
||||
disk->type = FF_DISK_TYPE_EXTERNAL;
|
||||
else if(driveType == DRIVE_FIXED)
|
||||
disk->type = FF_DISK_TYPE_REGULAR;
|
||||
else
|
||||
disk->type = FF_DISK_TYPE_HIDDEN;
|
||||
|
||||
ffStrbufInitA(&disk->filesystem, MAX_PATH + 1);
|
||||
ffStrbufInitA(&disk->name, MAX_PATH + 1);
|
||||
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationa#remarks
|
||||
UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
GetVolumeInformationA(mountpoint,
|
||||
disk->name.chars, disk->name.allocated, //Volume name
|
||||
NULL, //Serial number
|
||||
NULL, //Max component length
|
||||
NULL, //File system flags
|
||||
disk->filesystem.chars, disk->filesystem.allocated
|
||||
);
|
||||
SetErrorMode(errorMode);
|
||||
ffStrbufRecalculateLength(&disk->name);
|
||||
ffStrbufRecalculateLength(&disk->filesystem);
|
||||
|
||||
//TODO: implement
|
||||
disk->filesUsed = 0;
|
||||
disk->filesTotal = 0;
|
||||
|
||||
i += disk->mountpoint.length;
|
||||
}
|
||||
|
||||
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;
|
||||
free(buf);
|
||||
}
|
||||
|
||||
@@ -4,56 +4,34 @@
|
||||
#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);
|
||||
#include <assert.h>
|
||||
#include <CoreGraphics/CGDirectDisplay.h>
|
||||
|
||||
static void detectResolution(FFDisplayServerResult* ds)
|
||||
{
|
||||
CGDisplayCount screenCount;
|
||||
CGGetOnlineDisplayList(INT_MAX, NULL, &screenCount);
|
||||
if(screenCount == 0)
|
||||
CGDirectDisplayID screens[128];
|
||||
uint32_t screenCount;
|
||||
if(CGGetOnlineDisplayList(sizeof(screens) / sizeof(screens[0]), screens, &screenCount) != kCGErrorSuccess)
|
||||
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);
|
||||
CGDirectDisplayID screen = screens[i];
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(screen);
|
||||
if(mode)
|
||||
{
|
||||
ffdsAppendResolution(ds,
|
||||
(uint32_t)CGDisplayModeGetWidth(mode),
|
||||
(uint32_t)CGDisplayModeGetHeight(mode),
|
||||
(uint32_t)CGDisplayModeGetRefreshRate(mode)
|
||||
);
|
||||
CGDisplayModeRelease(mode);
|
||||
}
|
||||
CGDisplayRelease(screen);
|
||||
}
|
||||
|
||||
free(screens);
|
||||
}
|
||||
|
||||
static void detectWM(FFDisplayServerResult* ds)
|
||||
static void detectWMPlugin(FFstrbuf* name)
|
||||
{
|
||||
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
|
||||
u_int requestLength = sizeof(request) / sizeof(*request);
|
||||
@@ -76,9 +54,8 @@ static void detectWM(FFDisplayServerResult* ds)
|
||||
strcasecmp(comm, "rectangle") != 0
|
||||
) continue;
|
||||
|
||||
ffStrbufAppendS(&ds->wmProcessName, comm);
|
||||
ffStrbufAppendS(&ds->wmPrettyName, comm);
|
||||
ds->wmPrettyName.chars[0] = (char) toupper(ds->wmPrettyName.chars[0]);
|
||||
ffStrbufAppendS(name, comm);
|
||||
name->chars[0] = (char) toupper(name->chars[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -89,19 +66,21 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
ffStrbufInit(&ds->wmProcessName);
|
||||
ffStrbufInit(&ds->wmPrettyName);
|
||||
ffStrbufInitA(&ds->wmProtocolName, 0);
|
||||
detectWM(ds);
|
||||
if(ds->wmProcessName.length == 0)
|
||||
ffStrbufInitS(&ds->wmProcessName, "quartz");
|
||||
ffStrbufInitS(&ds->wmPrettyName, "Quartz Compositor");
|
||||
ffStrbufInit(&ds->wmProtocolName);
|
||||
|
||||
if(instance->config.allowSlowOperations)
|
||||
{
|
||||
ffStrbufAppendS(&ds->wmProcessName, "quartz");
|
||||
ffStrbufAppendS(&ds->wmPrettyName, "Quartz Compositor");
|
||||
FF_STRBUF_AUTO_DESTROY name;
|
||||
detectWMPlugin(&name);
|
||||
if(name.length)
|
||||
ffStrbufAppendF(&ds->wmPrettyName, " (with %s)", name.chars);
|
||||
}
|
||||
|
||||
ffStrbufInit(&ds->deProcessName);
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffStrbufInitA(&ds->deVersion, 0);
|
||||
ffStrbufInit(&ds->deVersion);
|
||||
ffStrbufAppendS(&ds->deProcessName, "aqua");
|
||||
ffStrbufAppendS(&ds->dePrettyName, "Aqua");
|
||||
|
||||
|
||||
@@ -39,10 +39,19 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds, const FFinstance* ins
|
||||
|
||||
//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");
|
||||
if(
|
||||
ffStrbufEqualS(&os->version, "11") ||
|
||||
ffStrbufEqualS(&os->version, "10") ||
|
||||
ffStrbufEqualS(&os->version, "2022") ||
|
||||
ffStrbufEqualS(&os->version, "2019") ||
|
||||
ffStrbufEqualS(&os->version, "2016")
|
||||
) ffStrbufSetS(&ds->dePrettyName, "Fluent");
|
||||
else if(
|
||||
ffStrbufEqualS(&os->version, "8") ||
|
||||
ffStrbufEqualS(&os->version, "81.") ||
|
||||
ffStrbufEqualS(&os->version, "2012 R2") ||
|
||||
ffStrbufEqualS(&os->version, "2012")
|
||||
) ffStrbufSetS(&ds->dePrettyName, "Metro");
|
||||
else
|
||||
ffStrbufSetS(&ds->dePrettyName, "Aero");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
#include "common/library.h"
|
||||
#include "common/io.h"
|
||||
#include <pthread.h>
|
||||
#include "common/thread.h"
|
||||
#include <wayland-client.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -56,12 +56,12 @@ static void waylandOutputModeListener(void* data, struct wl_output* output, uint
|
||||
if(!(flags & WL_OUTPUT_MODE_CURRENT) || width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_mutex_lock(&mutex);
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
||||
ffThreadMutexLock(&mutex);
|
||||
|
||||
FFResolutionResult* result = ffListAdd(wldata->results);
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
|
||||
result->width = (uint32_t) width;
|
||||
result->height = (uint32_t) height;
|
||||
@@ -102,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" FF_LIBRARY_EXTENSION, 1)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static const char* parseEnv()
|
||||
{
|
||||
|
||||
@@ -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" FF_LIBRARY_EXTENSION, 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" FF_LIBRARY_EXTENSION, 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,)
|
||||
|
||||
@@ -9,12 +9,14 @@ typedef struct X11PropertyData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(XInternAtom)
|
||||
FF_LIBRARY_SYMBOL(XGetWindowProperty)
|
||||
FF_LIBRARY_SYMBOL(XFree)
|
||||
} X11PropertyData;
|
||||
|
||||
static bool x11InitPropertyData(void* libraryHandle, X11PropertyData* propertyData)
|
||||
{
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XInternAtom, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XGetWindowProperty, false)
|
||||
FF_LIBRARY_LOAD_SYMBOL_PTR(libraryHandle, propertyData, XFree, false)
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -29,7 +31,8 @@ static unsigned char* x11GetProperty(X11PropertyData* data, Display* display, Wi
|
||||
unsigned long unused;
|
||||
unsigned char* result = NULL;
|
||||
|
||||
data->ffXGetWindowProperty(display, window, requestAtom, 0, 64, False, AnyPropertyType, &actualType, (int*) &unused, &unused, &unused, &result);
|
||||
if(data->ffXGetWindowProperty(display, window, requestAtom, 0, 64, False, AnyPropertyType, &actualType, (int*) &unused, &unused, &unused, &result) != Success)
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -43,19 +46,20 @@ static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDispl
|
||||
if(wmWindow == NULL)
|
||||
return;
|
||||
|
||||
const char* wmName = (const char*) x11GetProperty(data, display, *wmWindow, "_NET_WM_NAME");
|
||||
char* wmName = (char*) x11GetProperty(data, display, *wmWindow, "_NET_WM_NAME");
|
||||
if(wmName == NULL)
|
||||
wmName = (const char*) x11GetProperty(data, display, *wmWindow, "WM_NAME");
|
||||
wmName = (char*) x11GetProperty(data, display, *wmWindow, "WM_NAME");
|
||||
|
||||
if(!ffStrSet(wmName))
|
||||
return;
|
||||
if(ffStrSet(wmName))
|
||||
ffStrbufSetS(&result->wmProcessName, wmName);
|
||||
|
||||
ffStrbufSetS(&result->wmProcessName, wmName);
|
||||
data->ffXFree(wmName);
|
||||
data->ffXFree(wmWindow);
|
||||
}
|
||||
|
||||
void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11.so", 7, "libX11-xcb.so", 2)
|
||||
FF_LIBRARY_LOAD(x11, &instance->config.libX11, , "libX11" FF_LIBRARY_EXTENSION, 7, "libX11-xcb" FF_LIBRARY_EXTENSION, 2)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
|
||||
|
||||
@@ -259,7 +263,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
|
||||
void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr.so", 3)
|
||||
FF_LIBRARY_LOAD(xrandr, &instance->config.libXrandr, , "libXrandr" FF_LIBRARY_EXTENSION, 3)
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XOpenDisplay,)
|
||||
FF_LIBRARY_LOAD_SYMBOL(xrandr, XCloseDisplay,)
|
||||
|
||||
@@ -12,10 +12,10 @@ typedef struct FFFontResult
|
||||
FFstrbuf error;
|
||||
|
||||
/**
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, Monospace, Application
|
||||
* Windows: Desktop, Unset, Unset, Unset
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, System Mono, User Mono
|
||||
* Windows: Caption, Menu, Message, Status
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
*/
|
||||
FFstrbuf fonts[FF_DETECT_FONT_NUM_FONTS];
|
||||
} FFFontResult;
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
#include "common/font.h"
|
||||
#include "common/io.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
#include "font.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
static void detectFontForType(CTFontUIFontType uiType, FFstrbuf* font)
|
||||
{
|
||||
CTFontRef ctFont = CTFontCreateUIFontForLanguage(uiType, 12, NULL);
|
||||
ffCfStrGetString(CTFontCopyFamilyName(ctFont), font);
|
||||
}
|
||||
#import <AppKit/NSFont.h>
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
ffSuppressIO(true);
|
||||
detectFontForType(kCTFontUIFontSystem, &result->fonts[0]);
|
||||
detectFontForType(kCTFontUIFontUser, &result->fonts[1]);
|
||||
detectFontForType(kCTFontUIFontUserFixedPitch, &result->fonts[2]);
|
||||
detectFontForType(kCTFontUIFontApplication, &result->fonts[3]);
|
||||
ffSuppressIO(false);
|
||||
ffStrbufAppendS(&result->fonts[0], [NSFont systemFontOfSize:12].familyName.UTF8String);
|
||||
ffStrbufAppendS(&result->fonts[1], [NSFont userFontOfSize:12].familyName.UTF8String);
|
||||
ffStrbufAppendS(&result->fonts[2], [NSFont monospacedSystemFontOfSize:12 weight:400].familyName.UTF8String);
|
||||
ffStrbufAppendS(&result->fonts[3], [NSFont userFixedPitchFontOfSize:12].familyName.UTF8String);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "font.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <winuser.h>
|
||||
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
NONCLIENTMETRICSW info = { .cbSize = sizeof(info) };
|
||||
if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0))
|
||||
ffStrbufAppendS(&result->error, "SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed");
|
||||
|
||||
LOGFONTW* fonts[4] = { &info.lfCaptionFont, &info.lfMenuFont, &info.lfMessageFont, &info.lfStatusFont };
|
||||
|
||||
for(uint32_t i = 0; i < sizeof(fonts) / sizeof(fonts[0]); ++i)
|
||||
{
|
||||
ffStrbufSetWS(&result->fonts[i], fonts[i]->lfFaceName);
|
||||
if(fonts[i]->lfHeight < 0)
|
||||
ffStrbufAppendF(&result->fonts[i], " (%dpt)", (int)-fonts[i]->lfHeight);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
extern "C" {
|
||||
#include "font.h"
|
||||
#include "common/font.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
extern "C"
|
||||
void ffDetectFontImpl(const FFinstance* instance, FFFontResult* result)
|
||||
{
|
||||
wchar_t query[256] = {};
|
||||
swprintf(query, 256, L"SELECT IconTitleFaceName, IconTitleSize FROM Win32_Desktop WHERE Name LIKE '%%\\\\%s'", instance->state.passwd->pw_name);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(query, &result->error);
|
||||
if(!pEnumerator)
|
||||
return;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
|
||||
|
||||
if(uReturn == 0)
|
||||
{
|
||||
ffStrbufInitS(&result->error, "No WMI result returned");
|
||||
pEnumerator->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
FFstrbuf fontName;
|
||||
ffStrbufInit(&fontName);
|
||||
ffGetWmiObjString(pclsObj, L"IconTitleFaceName", &fontName);
|
||||
|
||||
uint64_t fontSize;
|
||||
ffGetWmiObjUnsigned(pclsObj, L"IconTitleSize", &fontSize);
|
||||
|
||||
ffStrbufAppendF(&result->fonts[0], "%*s (%upt)", fontName.length, fontName.chars, (unsigned)fontSize);
|
||||
|
||||
ffStrbufDestroy(&fontName);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
}
|
||||
@@ -8,6 +8,10 @@
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
|
||||
#define FF_GPU_VENDOR_NAME_AMD "AMD"
|
||||
#define FF_GPU_VENDOR_NAME_INTEL "Intel"
|
||||
#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA"
|
||||
|
||||
typedef struct FFGPUResult
|
||||
{
|
||||
FFstrbuf vendor;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
{
|
||||
FFlist temps;
|
||||
FF_LIST_AUTO_DESTROY temps;
|
||||
ffListInit(&temps, sizeof(FFTempValue));
|
||||
|
||||
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
|
||||
@@ -35,7 +35,6 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
ffStrbufDestroy(&tempValue->deviceClass);
|
||||
}
|
||||
result /= temps.length;
|
||||
ffListDestroy(&temps);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/vulkan.h"
|
||||
|
||||
#define FF_GPU_VENDOR_NAME_AMD "AMD"
|
||||
#define FF_GPU_VENDOR_NAME_INTEL "Intel"
|
||||
#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA"
|
||||
|
||||
#ifdef FF_HAVE_LIBPCI
|
||||
#include "common/library.h"
|
||||
#include "common/properties.h"
|
||||
@@ -208,7 +204,7 @@ static const char* pciDetectGPUs(const FFinstance* instance, FFlist* gpus)
|
||||
{
|
||||
PCIData pci;
|
||||
|
||||
FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci.so", 4);
|
||||
FF_LIBRARY_LOAD(libpci, &instance->config.libPCI, "dlopen libpci.so failed", "libpci" FF_LIBRARY_EXTENSION, 4);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_alloc);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_init);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libpci, pci_scan_bus);
|
||||
|
||||
@@ -1,27 +1,72 @@
|
||||
extern "C" {
|
||||
#include "gpu.h"
|
||||
#include "util/windows/unicode.h"
|
||||
}
|
||||
|
||||
#ifdef FF_USE_WIN_GPU_DXGI
|
||||
|
||||
#include <dxgi.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static const char* detectWithDxgi(FFlist* gpus)
|
||||
{
|
||||
IDXGIFactory1* pFactory;
|
||||
if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory))))
|
||||
return "CreateDXGIFactory1() failed";
|
||||
|
||||
for(unsigned iAdapter = 0;; ++iAdapter)
|
||||
{
|
||||
IDXGIAdapter1* adapter;
|
||||
if(FAILED(pFactory->EnumAdapters1(iAdapter, &adapter)))
|
||||
break;
|
||||
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
if(FAILED(adapter->GetDesc1(&desc)) || (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE))
|
||||
continue;
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
|
||||
if(wmemchr((const wchar_t[]) {0x1002, 0x1022}, (wchar_t)desc.VendorId, 2))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD);
|
||||
else if(wmemchr((const wchar_t[]) {0x03e7, 0x8086, 0x8087}, (wchar_t)desc.VendorId, 3))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
else if(wmemchr((const wchar_t[]) {0x0955, 0x10de, 0x12d2}, (wchar_t)desc.VendorId, 3))
|
||||
ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA);
|
||||
else
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufSetWS(&gpu->name, desc.Description);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
|
||||
adapter->Release();
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
}
|
||||
|
||||
pFactory->Release();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
static const char* detectWithWmi(FFlist* gpus)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
|
||||
|
||||
if(!pEnumerator)
|
||||
FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
while(SUCCEEDED(pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn)) && uReturn != 0)
|
||||
while(FFWmiRecord record = query.next())
|
||||
{
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffGetWmiObjString(pclsObj, L"AdapterCompatibility", &gpu->vendor);
|
||||
record.getString(L"AdapterCompatibility", &gpu->vendor);
|
||||
if(ffStrbufStartsWithS(&gpu->vendor, "Intel "))
|
||||
{
|
||||
//Intel returns "Intel Corporation", not sure about AMD
|
||||
@@ -29,16 +74,28 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
}
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffGetWmiObjString(pclsObj, L"Name", &gpu->name);
|
||||
record.getString(L"Name", &gpu->name);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffGetWmiObjString(pclsObj, L"DriverVersion", &gpu->driver);
|
||||
record.getString(L"DriverVersion", &gpu->driver);
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
}
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
#ifdef FF_USE_WIN_GPU_DXGI
|
||||
return detectWithDxgi(gpus);
|
||||
#else
|
||||
return detectWithWmi(gpus);
|
||||
#endif
|
||||
}
|
||||
|
||||
+9
-10
@@ -1,11 +1,10 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/gtk.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/settings.h"
|
||||
#include "detection/displayserver/displayserver.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static inline bool allPropertiesSet(FFGTKResult* result)
|
||||
{
|
||||
return
|
||||
@@ -34,7 +33,7 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
|
||||
|
||||
static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* result)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static const char* themeName = NULL;
|
||||
static const char* iconsName = NULL;
|
||||
@@ -44,11 +43,11 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
|
||||
|
||||
static bool init = false;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
ffThreadMutexLock(&mutex);
|
||||
|
||||
if(init)
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
|
||||
return;
|
||||
}
|
||||
@@ -90,7 +89,7 @@ static void detectGTKFromSettings(const FFinstance* instance, FFGTKResult* resul
|
||||
cursorSize = ffSettingsGet(instance, "/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
ffThreadMutexUnlock(&mutex);
|
||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize);
|
||||
}
|
||||
|
||||
@@ -168,12 +167,12 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu
|
||||
}
|
||||
|
||||
#define FF_DETECT_GTK_IMPL(version) \
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
||||
static FFGTKResult result; \
|
||||
static bool init = false; \
|
||||
pthread_mutex_lock(&mutex); \
|
||||
ffThreadMutexLock(&mutex); \
|
||||
if(init){ \
|
||||
pthread_mutex_unlock(&mutex);\
|
||||
ffThreadMutexUnlock(&mutex);\
|
||||
return &result; \
|
||||
} \
|
||||
init = true; \
|
||||
@@ -183,7 +182,7 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu
|
||||
ffStrbufInit(&result.cursor); \
|
||||
ffStrbufInit(&result.cursorSize); \
|
||||
detectGTK(instance, #version, &result); \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return &result;
|
||||
|
||||
const FFGTKResult* ffDetectGTK2(const FFinstance* instance)
|
||||
|
||||
@@ -5,18 +5,12 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_HOST_PRODUCT_NAME_WSL "Windows Subsystem for Linux"
|
||||
#define FF_HOST_PRODUCT_NAME_MSYS "Windows on MSYS"
|
||||
|
||||
typedef struct FFHostResult
|
||||
{
|
||||
FFstrbuf productFamily;
|
||||
FFstrbuf productName;
|
||||
FFstrbuf productVersion;
|
||||
FFstrbuf productSku;
|
||||
FFstrbuf chassisType;
|
||||
FFstrbuf chassisVendor;
|
||||
FFstrbuf chassisVersion;
|
||||
FFstrbuf sysVendor;
|
||||
FFstrbuf error;
|
||||
} FFHostResult;
|
||||
|
||||
@@ -34,7 +34,4 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
|
||||
ffStrbufInitA(&host->productVersion, 0);
|
||||
ffStrbufInitA(&host->productSku, 0);
|
||||
ffStrbufInitA(&host->chassisType, 0);
|
||||
ffStrbufInitA(&host->chassisVendor, 0);
|
||||
ffStrbufInitA(&host->chassisVersion, 0);
|
||||
}
|
||||
|
||||
+140
-110
@@ -1,112 +1,145 @@
|
||||
#include "host.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
static inline bool strEqual(const char* a, const char* b)
|
||||
{
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
|
||||
static const char* getProductName(const FFstrbuf* hwModel)
|
||||
{
|
||||
//https://github.com/hykilpikonna/hyfetch/blob/master/neofetch#L1386
|
||||
if(ffStrbufCompS(hwModel, "Mac14,7") == 0) return "MacBook Pro (13-inch, M2, 2022)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro18,3") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro18,4") == 0) return "MacBook Pro (14-inch, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro18,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro18,2") == 0) return "MacBook Pro (16-inch, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro17,1") == 0) return "MacBook Pro (13-inch, M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,4") == 0) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,3") == 0) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,2") == 0) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro16,1") == 0) return "MacBook Pro (16-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,4") == 0) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,3") == 0) return "MacBook Pro (15-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,2") == 0) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro15,1") == 0) return "MacBook Pro (15-inch, 2018/2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,3") == 0) return "MacBook Pro (15-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,2") == 0) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro14,1") == 0) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,3") == 0) return "MacBook Pro (15-inch, 2016)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,2") == 0) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro13,1") == 0) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro12,1") == 0) return "MacBook Pro (Retina, 13-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,4") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro11,5") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,2") == 0 ||
|
||||
ffStrbufCompS(hwModel, "MacBookPro11,3") == 0) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro11,1") == 0) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro10,2") == 0) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro10,1") == 0) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro9,2") == 0) return "MacBook Pro (13-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro9,1") == 0) return "MacBook Pro (15-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,3") == 0) return "MacBook Pro (17-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,2") == 0) return "MacBook Pro (15-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro8,1") == 0) return "MacBook Pro (13-inch, 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro7,1") == 0) return "MacBook Pro (13-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro6,2") == 0) return "MacBook Pro (15-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro6,1") == 0) return "MacBook Pro (17-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,5") == 0) return "MacBook Pro (13-inch, Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,3") == 0) return "MacBook Pro (15-inch, Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,2") == 0) return "MacBook Pro (17-inch, Mid/Early 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro5,1") == 0) return "MacBook Pro (15-inch, Late 2008)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookPro4,1") == 0) return "MacBook Pro (17/15-inch, Early 2008)";
|
||||
if(ffStrbufCompS(hwModel, "Mac14,2") == 0) return "MacBook Air (M2, 2022)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir10,1") == 0) return "MacBook Air (M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir9,1") == 0) return "MacBook Air (Retina, 13-inch, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir8,2") == 0) return "MacBook Air (Retina, 13-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir8,1") == 0) return "MacBook Air (Retina, 13-inch, 2018)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir7,2") == 0) return "MacBook Air (13-inch, Early 2015/2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir7,1") == 0) return "MacBook Air (11-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir6,2") == 0) return "MacBook Air (13-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir6,1") == 0) return "MacBook Air (11-inch, Mid 2013/Early 2014)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir5,2") == 0) return "MacBook Air (13-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir5,1") == 0) return "MacBook Air (11-inch, Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir4,2") == 0) return "MacBook Air (13-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir4,1") == 0) return "MacBook Air (11-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir3,2") == 0) return "MacBook Air (13-inch, Late 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir3,1") == 0) return "MacBook Air (11-inch, Late 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBookAir2,1") == 0) return "MacBook Air (Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook10,1") == 0) return "MacBook (Retina, 12-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook9,1") == 0) return "MacBook (Retina, 12-inch, Early 2016)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook8,1") == 0) return "MacBook (Retina, 12-inch, Early 2015)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook7,1") == 0) return "MacBook (13-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook6,1") == 0) return "MacBook (13-inch, Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacBook5,2") == 0) return "MacBook (13-inch, Early/Mid 2009)";
|
||||
if(ffStrbufCompS(hwModel, "Mac13,1") == 0) return "Mac Studio (2022, Two USB-C front ports)";
|
||||
if(ffStrbufCompS(hwModel, "Mac13,2") == 0) return "Mac Studio (2022, Two Thunderbolt 4 front ports)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini9,1") == 0) return "Mac mini (M1, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini8,1") == 0) return "Mac mini (2018)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini7,1") == 0) return "Mac mini (Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini6,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "Macmini6,2") == 0) return "Mac mini (Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini5,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "Macmini5,2") == 0) return "Mac mini (Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini4,1") == 0) return "Mac mini (Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "Macmini3,1") == 0) return "Mac mini (Early/Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro7,1") == 0) return "Mac Pro (2019)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro6,1") == 0) return "Mac Pro (Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro5,1") == 0) return "Mac Pro (Mid 2010 - Mid 2012)";
|
||||
if(ffStrbufCompS(hwModel, "MacPro4,1") == 0) return "Mac Pro (Early 2009)";
|
||||
if(ffStrbufCompS(hwModel, "iMac21,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac21,2") == 0) return "iMac (24-inch, M1, 2021)";
|
||||
if(ffStrbufCompS(hwModel, "iMac20,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac20,2") == 0) return "iMac (Retina 5K, 27-inch, 2020)";
|
||||
if(ffStrbufCompS(hwModel, "iMac19,1") == 0 ||
|
||||
ffStrbufCompS(hwModel, "iMac19,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2019)";
|
||||
if(ffStrbufCompS(hwModel, "iMacPro1,1") == 0) return "iMac Pro (2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,3") == 0) return "iMac (Retina 5K, 27-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,2") == 0) return "iMac (Retina 4K, 21.5-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac18,1") == 0) return "iMac (21.5-inch, 2017)";
|
||||
if(ffStrbufCompS(hwModel, "iMac17,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac16,2") == 0) return "iMac (Retina 4K, 21.5-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac16,1") == 0) return "iMac (21.5-inch, Late 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac15,1") == 0) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,4") == 0) return "iMac (21.5-inch, Mid 2014)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,2") == 0) return "iMac (27-inch, Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "iMac14,1") == 0) return "iMac (21.5-inch, Late 2013)";
|
||||
if(ffStrbufCompS(hwModel, "iMac13,2") == 0) return "iMac (27-inch, Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "iMac13,1") == 0) return "iMac (21.5-inch, Late 2012)";
|
||||
if(ffStrbufCompS(hwModel, "iMac12,2") == 0) return "iMac (27-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "iMac12,1") == 0) return "iMac (21.5-inch, Mid 2011)";
|
||||
if(ffStrbufCompS(hwModel, "iMac11,3") == 0) return "iMac (27-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "iMac11,2") == 0) return "iMac (21.5-inch, Mid 2010)";
|
||||
if(ffStrbufCompS(hwModel, "iMac10,1") == 0) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(ffStrbufCompS(hwModel, "iMac9,1") == 0) return "iMac (24/20-inch, Early 2009)";
|
||||
if(ffStrbufStartsWithS(hwModel, "MacBookPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookPro");
|
||||
if(strEqual(version, "18,3") ||
|
||||
strEqual(version, "18,4")) return "MacBook Pro (14-inch, 2021)";
|
||||
if(strEqual(version, "18,1") ||
|
||||
strEqual(version, "18,2")) return "MacBook Pro (16-inch, 2021)";
|
||||
if(strEqual(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)";
|
||||
if(strEqual(version, "16,4")) return "MacBook Pro (16-inch, 2019)";
|
||||
if(strEqual(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "16,1")) return "MacBook Pro (16-inch, 2019)";
|
||||
if(strEqual(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "15,3")) return "MacBook Pro (15-inch, 2019)";
|
||||
if(strEqual(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "15,1")) return "MacBook Pro (15-inch, 2018/2019)";
|
||||
if(strEqual(version, "14,3")) return "MacBook Pro (15-inch, 2017)";
|
||||
if(strEqual(version, "14,2")) return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "14,1")) return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "13,3")) return "MacBook Pro (15-inch, 2016)";
|
||||
if(strEqual(version, "13,2")) return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "13,1")) return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
|
||||
if(strEqual(version, "12,1")) return "MacBook Pro (Retina, 13-inch, Early 2015)";
|
||||
if(strEqual(version, "11,4") ||
|
||||
strEqual(version, "11,5")) return "MacBook Pro (Retina, 15-inch, Mid 2015)";
|
||||
if(strEqual(version, "11,2") ||
|
||||
strEqual(version, "11,3")) return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
|
||||
if(strEqual(version, "11,1")) return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
|
||||
if(strEqual(version, "10,2")) return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
|
||||
if(strEqual(version, "10,1")) return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
|
||||
if(strEqual(version, "9,2")) return "MacBook Pro (13-inch, Mid 2012)";
|
||||
if(strEqual(version, "9,1")) return "MacBook Pro (15-inch, Mid 2012)";
|
||||
if(strEqual(version, "8,3")) return "MacBook Pro (17-inch, 2011)";
|
||||
if(strEqual(version, "8,2")) return "MacBook Pro (15-inch, 2011)";
|
||||
if(strEqual(version, "8,1")) return "MacBook Pro (13-inch, 2011)";
|
||||
if(strEqual(version, "7,1")) return "MacBook Pro (13-inch, Mid 2010)";
|
||||
if(strEqual(version, "6,2")) return "MacBook Pro (15-inch, Mid 2010)";
|
||||
if(strEqual(version, "6,1")) return "MacBook Pro (17-inch, Mid 2010)";
|
||||
if(strEqual(version, "5,5")) return "MacBook Pro (13-inch, Mid 2009)";
|
||||
if(strEqual(version, "5,3")) return "MacBook Pro (15-inch, Mid 2009)";
|
||||
if(strEqual(version, "5,2")) return "MacBook Pro (17-inch, Mid/Early 2009)";
|
||||
if(strEqual(version, "5,1")) return "MacBook Pro (15-inch, Late 2008)";
|
||||
if(strEqual(version, "4,1")) return "MacBook Pro (17/15-inch, Early 2008)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBookAir"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBookAir");
|
||||
if(strEqual(version, "10,1")) return "MacBook Air (M1, 2020)";
|
||||
if(strEqual(version, "9,1")) return "MacBook Air (Retina, 13-inch, 2020)";
|
||||
if(strEqual(version, "8,2")) return "MacBook Air (Retina, 13-inch, 2019)";
|
||||
if(strEqual(version, "8,1")) return "MacBook Air (Retina, 13-inch, 2018)";
|
||||
if(strEqual(version, "7,2")) return "MacBook Air (13-inch, Early 2015/2017)";
|
||||
if(strEqual(version, "7,1")) return "MacBook Air (11-inch, Early 2015)";
|
||||
if(strEqual(version, "6,2")) return "MacBook Air (13-inch, Mid 2013/Early 2014)";
|
||||
if(strEqual(version, "6,1")) return "MacBook Air (11-inch, Mid 2013/Early 2014)";
|
||||
if(strEqual(version, "5,2")) return "MacBook Air (13-inch, Mid 2012)";
|
||||
if(strEqual(version, "5,1")) return "MacBook Air (11-inch, Mid 2012)";
|
||||
if(strEqual(version, "4,2")) return "MacBook Air (13-inch, Mid 2011)";
|
||||
if(strEqual(version, "4,1")) return "MacBook Air (11-inch, Mid 2011)";
|
||||
if(strEqual(version, "3,2")) return "MacBook Air (13-inch, Late 2010)";
|
||||
if(strEqual(version, "3,1")) return "MacBook Air (11-inch, Late 2010)";
|
||||
if(strEqual(version, "2,1")) return "MacBook Air (Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Macmini"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Macmini");
|
||||
if(strEqual(version, "9,1")) return "Mac mini (M1, 2020)";
|
||||
if(strEqual(version, "8,1")) return "Mac mini (2018)";
|
||||
if(strEqual(version, "7,1")) return "Mac mini (Mid 2014)";
|
||||
if(strEqual(version, "6,1") ||
|
||||
strEqual(version, "6,2")) return "Mac mini (Late 2012)";
|
||||
if(strEqual(version, "5,1") ||
|
||||
strEqual(version, "5,2")) return "Mac mini (Mid 2011)";
|
||||
if(strEqual(version, "4,1")) return "Mac mini (Mid 2010)";
|
||||
if(strEqual(version, "3,1")) return "Mac mini (Early/Late 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacBook"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacBook");
|
||||
if(strEqual(version, "10,1")) return "MacBook (Retina, 12-inch, 2017)";
|
||||
if(strEqual(version, "9,1")) return "MacBook (Retina, 12-inch, Early 2016)";
|
||||
if(strEqual(version, "8,1")) return "MacBook (Retina, 12-inch, Early 2015)";
|
||||
if(strEqual(version, "7,1")) return "MacBook (13-inch, Mid 2010)";
|
||||
if(strEqual(version, "6,1")) return "MacBook (13-inch, Late 2009)";
|
||||
if(strEqual(version, "5,2")) return "MacBook (13-inch, Early/Mid 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "MacPro"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("MacPro");
|
||||
if(strEqual(version, "7,1")) return "Mac Pro (2019)";
|
||||
if(strEqual(version, "6,1")) return "Mac Pro (Late 2013)";
|
||||
if(strEqual(version, "5,1")) return "Mac Pro (Mid 2010 - Mid 2012)";
|
||||
if(strEqual(version, "4,1")) return "Mac Pro (Early 2009)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "Mac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("Mac");
|
||||
if(strEqual(version, "14,7")) return "MacBook Pro (13-inch, M2, 2022)";
|
||||
if(strEqual(version, "14,2")) return "MacBook Air (M2, 2022)";
|
||||
if(strEqual(version, "13,1")) return "Mac Studio (2022, Two USB-C front ports)";
|
||||
if(strEqual(version, "13,2")) return "Mac Studio (2022, Two Thunderbolt 4 front ports)";
|
||||
}
|
||||
else if(ffStrbufStartsWithS(hwModel, "iMac"))
|
||||
{
|
||||
const char* version = hwModel->chars + strlen("iMac");
|
||||
if(strEqual(version, "21,1") ||
|
||||
strEqual(version, "21,2")) return "iMac (24-inch, M1, 2021)";
|
||||
if(strEqual(version, "20,1") ||
|
||||
strEqual(version, "20,2")) return "iMac (Retina 5K, 27-inch, 2020)";
|
||||
if(strEqual(version, "19,1") ||
|
||||
strEqual(version, "19,2")) return "iMac (Retina 4K, 21.5-inch, 2019)";
|
||||
if(strEqual(version, "Pro1,1")) return "iMac Pro (2017)";
|
||||
if(strEqual(version, "18,3")) return "iMac (Retina 5K, 27-inch, 2017)";
|
||||
if(strEqual(version, "18,2")) return "iMac (Retina 4K, 21.5-inch, 2017)";
|
||||
if(strEqual(version, "18,1")) return "iMac (21.5-inch, 2017)";
|
||||
if(strEqual(version, "17,1")) return "iMac (Retina 5K, 27-inch, Late 2015)";
|
||||
if(strEqual(version, "16,2")) return "iMac (Retina 4K, 21.5-inch, Late 2015)";
|
||||
if(strEqual(version, "16,1")) return "iMac (21.5-inch, Late 2015)";
|
||||
if(strEqual(version, "15,1")) return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
|
||||
if(strEqual(version, "14,4")) return "iMac (21.5-inch, Mid 2014)";
|
||||
if(strEqual(version, "14,2")) return "iMac (27-inch, Late 2013)";
|
||||
if(strEqual(version, "14,1")) return "iMac (21.5-inch, Late 2013)";
|
||||
if(strEqual(version, "13,2")) return "iMac (27-inch, Late 2012)";
|
||||
if(strEqual(version, "13,1")) return "iMac (21.5-inch, Late 2012)";
|
||||
if(strEqual(version, "12,2")) return "iMac (27-inch, Mid 2011)";
|
||||
if(strEqual(version, "12,1")) return "iMac (21.5-inch, Mid 2011)";
|
||||
if(strEqual(version, "11,3")) return "iMac (27-inch, Mid 2010)";
|
||||
if(strEqual(version, "11,2")) return "iMac (21.5-inch, Mid 2010)";
|
||||
if(strEqual(version, "10,1")) return "iMac (27/21.5-inch, Late 2009)";
|
||||
if(strEqual(version, "9,1")) return "iMac (24/20-inch, Early 2009)";
|
||||
}
|
||||
return hwModel->chars;
|
||||
}
|
||||
|
||||
@@ -118,12 +151,9 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInitS(&host->sysVendor, "Apple");
|
||||
|
||||
ffStrbufInitA(&host->sysVendor, 0);
|
||||
ffStrbufInitA(&host->chassisType, 0);
|
||||
ffStrbufInitA(&host->chassisVendor, 0);
|
||||
ffStrbufInitA(&host->chassisVersion, 0);
|
||||
|
||||
ffSysctlGetString("hw.model", &host->productFamily);
|
||||
ffStrbufAppendS(&host->productName, getProductName(&host->productFamily));
|
||||
ffStrbufAppendS(&host->error, ffSysctlGetString("hw.model", &host->productFamily));
|
||||
if(host->error.length == 0)
|
||||
ffStrbufAppendS(&host->productName, getProductName(&host->productFamily));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "host.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->error);
|
||||
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
|
||||
ffStrbufAppendS(&host->error, ffSysctlGetString("hw.fdt.model", &host->productName));
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "host.h"
|
||||
#include "common/io.h"
|
||||
#include "common/processing.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -74,15 +75,6 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
ffStrbufInit(&host->productSku);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->productSku);
|
||||
|
||||
ffStrbufInit(&host->chassisType);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_type", "/sys/class/dmi/id/chassis_type", &host->chassisType);
|
||||
|
||||
ffStrbufInit(&host->chassisVendor);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_vendor", "/sys/class/dmi/id/chassis_vendor", &host->chassisVendor);
|
||||
|
||||
ffStrbufInit(&host->chassisVersion);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/chassis_version", "/sys/class/dmi/id/chassis_version", &host->chassisVersion);
|
||||
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
getHostValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->sysVendor);
|
||||
|
||||
@@ -94,6 +86,27 @@ void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
//On WSL, the real host can't be detected. Instead use WSL as host.
|
||||
if(getenv("WSL_DISTRO") != NULL || getenv("WSL_INTEROP") != NULL)
|
||||
ffStrbufAppendS(&host->productName, FF_HOST_PRODUCT_NAME_WSL);
|
||||
{
|
||||
ffStrbufAppendS(&host->productName, "Windows Subsystem for Linux");
|
||||
|
||||
FFstrbuf wslVer; //Wide charactors
|
||||
ffStrbufInit(&wslVer);
|
||||
if(!ffProcessAppendStdOut(&wslVer, (char* const[]){
|
||||
"wsl.exe",
|
||||
"--version",
|
||||
NULL
|
||||
}) && wslVer.length > 0)
|
||||
{
|
||||
ffStrbufSubstrBeforeFirstC(&wslVer, '\r'); //CRLF
|
||||
ffStrbufSubstrAfterLastC(&wslVer, ' ');
|
||||
ffStrbufAppendS(&host->productName, " (");
|
||||
for(uint32_t i = 0; i < wslVer.length; ++i) {
|
||||
if(wslVer.chars[i]) //don't append \0
|
||||
ffStrbufAppendC(&host->productName, wslVer.chars[i]);
|
||||
}
|
||||
ffStrbufAppendC(&host->productName, ')');
|
||||
}
|
||||
ffStrbufDestroy(&wslVer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "host.h"
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->error);
|
||||
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
|
||||
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", &hKey, &host->error))
|
||||
return;
|
||||
|
||||
ffRegReadStrbuf(hKey, L"SystemProductName", &host->productName, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemFamily", &host->productFamily, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemVersion", &host->productVersion, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemSKU", &host->productSku, NULL);
|
||||
ffRegReadStrbuf(hKey, L"SystemManufacturer", &host->sysVendor, NULL);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
extern "C" {
|
||||
#include "host.h"
|
||||
}
|
||||
#include "util/windows/wmi.hpp"
|
||||
|
||||
extern "C" void ffDetectHostImpl(FFHostResult* host)
|
||||
{
|
||||
ffStrbufInit(&host->error);
|
||||
|
||||
ffStrbufInit(&host->productName);
|
||||
ffStrbufInit(&host->productFamily);
|
||||
ffStrbufInit(&host->productVersion);
|
||||
ffStrbufInit(&host->productSku);
|
||||
ffStrbufInit(&host->sysVendor);
|
||||
ffStrbufInit(&host->chassisType);
|
||||
ffStrbufInit(&host->chassisVendor);
|
||||
ffStrbufInit(&host->chassisVersion);
|
||||
|
||||
IEnumWbemClassObject* pEnumerator = ffQueryWmi(L"SELECT Name, Version, SKUNumber, Vendor FROM Win32_ComputerSystemProduct", &host->error);
|
||||
if(!pEnumerator)
|
||||
return;
|
||||
|
||||
IWbemClassObject *pclsObj = NULL;
|
||||
ULONG uReturn = 0;
|
||||
|
||||
pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
|
||||
|
||||
if(uReturn == 0)
|
||||
{
|
||||
ffStrbufInitS(&host->error, "No Wmi result returned");
|
||||
pEnumerator->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
ffGetWmiObjString(pclsObj, L"Name", &host->productName);
|
||||
ffGetWmiObjString(pclsObj, L"Version", &host->productVersion);
|
||||
ffGetWmiObjString(pclsObj, L"SKUNumber", &host->productSku);
|
||||
ffGetWmiObjString(pclsObj, L"Vendor", &host->sysVendor);
|
||||
|
||||
pclsObj->Release();
|
||||
pEnumerator->Release();
|
||||
}
|
||||
@@ -3,21 +3,21 @@
|
||||
#ifndef FF_INCLUDED_detection_internal
|
||||
#define FF_INCLUDED_detection_internal
|
||||
|
||||
#include "pthread.h"
|
||||
#include "common/thread.h"
|
||||
|
||||
#define FF_DETECTION_INTERNAL_GUARD(ResultType, ...) \
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; \
|
||||
static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; \
|
||||
static ResultType result; \
|
||||
static bool init = false; \
|
||||
pthread_mutex_lock(&mutex); \
|
||||
ffThreadMutexLock(&mutex); \
|
||||
if(init) \
|
||||
{ \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return &result; \
|
||||
} \
|
||||
init = true; \
|
||||
__VA_ARGS__; \
|
||||
pthread_mutex_unlock(&mutex); \
|
||||
ffThreadMutexUnlock(&mutex); \
|
||||
return &result; \
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_kernel_kernel
|
||||
#define FF_INCLUDED_detection_kernel_kernel
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef struct FFKernelResult
|
||||
{
|
||||
FFstrbuf sysname;
|
||||
FFstrbuf release;
|
||||
FFstrbuf version;
|
||||
FFstrbuf error;
|
||||
} FFKernelResult;
|
||||
|
||||
void ffDetectKernel(FFinstance* instance, FFKernelResult* result);
|
||||
|
||||
#endif
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "kernel.h"
|
||||
|
||||
void ffDetectKernel(FFinstance* instance, FFKernelResult* result)
|
||||
{
|
||||
ffStrbufInit(&result->error);
|
||||
ffStrbufInitS(&result->sysname, instance->state.utsname.sysname);
|
||||
ffStrbufInitS(&result->release, instance->state.utsname.release);
|
||||
ffStrbufInitS(&result->version, instance->state.utsname.version);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user