mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
220 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| efd9e94138 | |||
| 0707b29326 | |||
| 560e061c25 | |||
| 1d83743259 | |||
| 48bb38ca85 | |||
| d9f084894e | |||
| 765c7b42b6 | |||
| 5060c265a9 | |||
| fca4b3eee8 | |||
| eefed2be9c | |||
| 6a33027892 | |||
| 5e9c0d03ff | |||
| ab84c2ca76 | |||
| 4777f7bec3 | |||
| 1038668db9 | |||
| 49639b6719 | |||
| e5a04ee814 | |||
| fea2d80743 | |||
| 39eccf189c | |||
| 1652ec3512 | |||
| 5a39b69d1d | |||
| fa872d7c9b | |||
| 545267bb7e | |||
| 789f1e34ef | |||
| 9c095967fc | |||
| ddc910e924 | |||
| d628bdea5a | |||
| f9ce2fae0e | |||
| 4f70c16d63 | |||
| f8d5f56dee | |||
| 4d1c62947b | |||
| 8402dba0d9 | |||
| 94b6f0fbd1 | |||
| 3b1b81437e | |||
| a61765c8b1 | |||
| 065b44ff59 | |||
| b0e51ba91d | |||
| b6fff0c946 | |||
| c16373a7d7 | |||
| 73875de6a1 | |||
| 5f1cb16534 | |||
| 013320bcde | |||
| 3415d8197c | |||
| c5fdcc5cfc | |||
| f894856407 | |||
| 313bb02188 | |||
| 4dc0bd583c | |||
| 0ae1bd57bd | |||
| 02f3789eaa | |||
| cec38b9501 | |||
| 3453b72f0c | |||
| 060544b899 | |||
| 14c6b6d7e2 | |||
| 9df394bba3 | |||
| b25ffda90b | |||
| db9cf4ef29 | |||
| 7b2d4b7a0d | |||
| 64cdb3f058 | |||
| 66e7924fa3 | |||
| 84540250f7 | |||
| 96e7f65902 | |||
| 321d3e5574 | |||
| 2bba2eaa16 | |||
| 58ebde422a | |||
| 06f3b9a96d | |||
| fa5aaa692f | |||
| 9d2c4f52d2 | |||
| 9946a5d758 | |||
| a749014e7c | |||
| 2cd421fc2e | |||
| 4db6aebcc9 | |||
| 3b156e819b | |||
| 7ffed9e911 | |||
| 9042950ee8 | |||
| 7aad0dc32f | |||
| 01d04a8fa2 | |||
| d3e50fe595 | |||
| ecd69370ab | |||
| abd2522268 | |||
| 2e1261bc21 | |||
| 0e597a2ded | |||
| 2781a0ab93 | |||
| 02d7f2693b | |||
| b001ea409b | |||
| f97a9fdfc0 | |||
| 2c8d5292d7 | |||
| 88e4579f1e | |||
| 8f97e61f67 | |||
| 0b943bb25e | |||
| 19590003e1 | |||
| 27a1d9f8c6 | |||
| d50ebc86c7 | |||
| 74616c79f5 | |||
| 0c1462898b | |||
| b94a322dfc | |||
| adb6dc537c | |||
| debcc3ca7f | |||
| 3d7d02b5c5 | |||
| 3f0ae13505 | |||
| 4370c0944b | |||
| a9df048d49 | |||
| 09782d67e5 | |||
| 165aa93fd3 | |||
| d979f55c8e | |||
| 4f261509a0 | |||
| 6413656cea | |||
| a334b805fd | |||
| f940ef0592 | |||
| 963b5c6c4e | |||
| 4a74f69c96 | |||
| 18d36c5054 | |||
| a4614ec412 | |||
| e257f876ae | |||
| e9031171c0 | |||
| 47a9cf0450 | |||
| 1704dc62e0 | |||
| abf6c403d4 | |||
| 0606cde061 | |||
| 0bc9149a23 | |||
| 071be4794f | |||
| b5e199d2b2 | |||
| a210128592 | |||
| 63a28cc8f4 | |||
| a6c006221d | |||
| 42b84161d9 | |||
| 88e075ad9d | |||
| e37ad26729 | |||
| b500e9c09b | |||
| 77fbfd3fbd | |||
| 63cdc47d18 | |||
| edf24d9820 | |||
| becd9b7f26 | |||
| 672604081a | |||
| 3185969974 | |||
| ddbafd1cca | |||
| 16d70eed03 | |||
| bf15adf57a | |||
| dbd1f96353 | |||
| 8b3cff33da | |||
| 146c9b2bc6 | |||
| 3c7cb339e2 | |||
| 6318668d0b | |||
| 6737896038 | |||
| 96fc1db85e | |||
| 03e6b47eda | |||
| 067396d3a0 | |||
| a8c3979696 | |||
| 786b23ef52 | |||
| ca6e889a63 | |||
| 439ed07660 | |||
| d435ef6a77 | |||
| e7e5e89207 | |||
| eb1f378a6e | |||
| e2ce06dda2 | |||
| e9bc312b38 | |||
| 9351c48d57 | |||
| 07b3cf325b | |||
| 616c99a05d | |||
| e554ff6e4f | |||
| f013a60cf5 | |||
| bb1586e9a2 | |||
| edba2492e1 | |||
| 57b3c3951e | |||
| cd2a6e0906 | |||
| c180ddab28 | |||
| 77ab00a4f4 | |||
| 4e5c93315a | |||
| 935bea962f | |||
| 1b29f5b3a5 | |||
| d296e53213 | |||
| 5926c259ed | |||
| 2a19067ce7 | |||
| 06aaf0f3fd | |||
| 1d6a48e49a | |||
| 72d332772d | |||
| 255c6a09ac | |||
| 74a364e3f2 | |||
| 76b8446d15 | |||
| 94fb7eabfd | |||
| 6473db86a3 | |||
| 804c61b7c1 | |||
| 898bf1edd9 | |||
| 507caa7b49 | |||
| d05b6a25c3 | |||
| a11f99cce5 | |||
| 1841e1a99d | |||
| d727547b1c | |||
| d35490aeef | |||
| 5539fecb99 | |||
| cff2a18466 | |||
| 8a923835ad | |||
| 2bd507c890 | |||
| 19690656a2 | |||
| 36dc3c7263 | |||
| b38eb705f9 | |||
| 0a899e1e80 | |||
| 218c553841 | |||
| e284fee4aa | |||
| 124823e643 | |||
| dafc4ed3fb | |||
| 1c05e65bc0 | |||
| e0910777af | |||
| df0fb93542 | |||
| 30135570c7 | |||
| 20cef09c73 | |||
| 5bb4dabaec | |||
| ebfcd7195e | |||
| 671f5e2cec | |||
| cf4ed9d9dc | |||
| c4751eb834 | |||
| ff3ddc774e | |||
| 9104db0d21 | |||
| 7eb86b4e95 | |||
| 06fa6033f0 | |||
| f058d70d89 | |||
| 58f7d6fed4 | |||
| 95f8eccebb | |||
| e1245fe2e5 | |||
| 4332b09c8c | |||
| 13b488a33c |
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- keepalive
|
||||
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
+84
-46
@@ -197,6 +197,41 @@ jobs:
|
||||
name: fastfetch-linux-armv7
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
linux-riscv64:
|
||||
name: Linux-riscv64
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: uraimo/run-on-arch-action@v2
|
||||
id: runcmd
|
||||
with:
|
||||
arch: riscv64
|
||||
distro: ubuntu22.04
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev libosmesa6-dev ocl-icd-opencl-dev libnm-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-linux-riscv64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
musl-amd64:
|
||||
name: Musl-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -333,6 +368,39 @@ jobs:
|
||||
name: fastfetch-macos-universal
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
sunos-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
name: SunOS-amd64
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: vmactions/omnios-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
prepare: |
|
||||
uname -a
|
||||
pkg update --accept
|
||||
pkg install gcc13 cmake git pkg-config glib2 dbus sqlite-3 imagemagick
|
||||
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
cpack
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-sunos-amd64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
freebsd-amd64:
|
||||
name: FreeBSD-amd64
|
||||
runs-on: ubuntu-latest
|
||||
@@ -348,9 +416,9 @@ jobs:
|
||||
with:
|
||||
operating_system: freebsd
|
||||
architecture: x86-64
|
||||
cpu_count: 3
|
||||
cpu_count: 4
|
||||
shell: bash
|
||||
version: '13.2'
|
||||
version: '14.1'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
@@ -370,43 +438,6 @@ jobs:
|
||||
name: fastfetch-freebsd-amd64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
freebsd-aarch64:
|
||||
name: FreeBSD-aarch64
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: run VM
|
||||
uses: cross-platform-actions/action@master
|
||||
with:
|
||||
operating_system: freebsd
|
||||
architecture: arm64
|
||||
cpu_count: 3
|
||||
shell: bash
|
||||
version: '13.2'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg update
|
||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd v4l_compat
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fastfetch-freebsd-aarch64
|
||||
path: ./fastfetch-*.*
|
||||
|
||||
windows-amd64:
|
||||
name: Windows-amd64
|
||||
runs-on: windows-latest
|
||||
@@ -425,7 +456,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG64
|
||||
update: true
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd
|
||||
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd mingw-w64-clang-x86_64-opencl-headers mingw-w64-clang-x86_64-cppwinrt
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -439,6 +470,9 @@ jobs:
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang64/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: download amd_ags
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x64.dll
|
||||
|
||||
- name: list features
|
||||
run: ./fastfetch --list-features
|
||||
|
||||
@@ -458,10 +492,10 @@ jobs:
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-amd64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-amd64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -487,7 +521,7 @@ jobs:
|
||||
with:
|
||||
msystem: CLANG32
|
||||
update: true
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
|
||||
install: git p7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd mingw-w64-clang-i686-opencl-headers
|
||||
|
||||
- name: print msys version
|
||||
run: uname -a
|
||||
@@ -509,6 +543,9 @@ jobs:
|
||||
- name: copy necessary dlls
|
||||
run: cp /clang32/bin/{OpenCL,vulkan-1}.dll .
|
||||
|
||||
- name: download amd_ags
|
||||
run: curl -LO https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK/raw/master/ags_lib/lib/amd_ags_x86.dll
|
||||
|
||||
- name: run fastfetch
|
||||
run: time ./fastfetch -c presets/ci.jsonc
|
||||
|
||||
@@ -525,10 +562,10 @@ jobs:
|
||||
run: ctest
|
||||
|
||||
- name: create zip archive
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-i686.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: create 7z archive
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z *.dll fastfetch.exe flashfetch.exe presets
|
||||
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-i686.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
|
||||
|
||||
- name: upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -544,11 +581,12 @@ jobs:
|
||||
- linux-amd64
|
||||
- linux-aarch64
|
||||
- linux-armv7
|
||||
- linux-riscv64
|
||||
- musl-amd64
|
||||
- musl-aarch64
|
||||
- macos-universal
|
||||
- freebsd-amd64
|
||||
- freebsd-aarch64
|
||||
- sunos-amd64
|
||||
- windows-amd64
|
||||
- windows-i686
|
||||
permissions:
|
||||
|
||||
+151
-3
@@ -1,3 +1,151 @@
|
||||
# 2.18.1
|
||||
|
||||
Fix a regression introduced in v2.18.0
|
||||
|
||||
Changes:
|
||||
* `--ts-version` has been renamed to `--detect-version`
|
||||
* `general.detectVersion` in JSON config file
|
||||
|
||||
Bugfixes:
|
||||
* Fix and improve GPU driver detection (#1084, GPU, Linux)
|
||||
|
||||
# 2.18.0
|
||||
|
||||
Changes:
|
||||
* `yyjson 0.10.0` is required
|
||||
* Fastfetch no longer prints `*` (which means it's the default route) if `defaultRouteOnly` is set (LocalIP)
|
||||
|
||||
Bugfixes:
|
||||
* Fix some memory leaks
|
||||
* Fix compatibility with old Python versions
|
||||
* Don't detect frequency for AMD cards (GPU, Linux)
|
||||
* Fix possible hang with discrete AMD cards (#1077)
|
||||
* Don't print colors in `--pipe` mode (Separator)
|
||||
* Don't print `(null)` in property `locator` (PhysicalMemory)
|
||||
* Ignore disabled PCI devices (GPU)
|
||||
* Fix flag `--opengl-library` doesn't work (OpenGL)
|
||||
|
||||
Features:
|
||||
* Detect revision of USB drives (#1048, Disk)
|
||||
* Support fractional scale factor detection (Display, Linux)
|
||||
* Support primary display detection for KDE and GNOME (Display, Linux)
|
||||
* Support percent bar in custom formatting
|
||||
* Print signal quality by default (Wifi)
|
||||
* Detect used OpenGL library version (OpenGL)
|
||||
* Support detecting OpenGL version by `EGL` (ANGLE) on Windows (OpenGL)
|
||||
|
||||
Logos:
|
||||
* Add Arkane Linux
|
||||
* Add Opak
|
||||
|
||||
# 2.17.2
|
||||
|
||||
Changes:
|
||||
* Flatpak package count no longer takes runtime packages into account (Packages, Linux)
|
||||
|
||||
Bugfixes:
|
||||
* Fix formattion with multiple batteries (Battery)
|
||||
* Fix incorrect size value for large memory sticks (PhysicalMemory)
|
||||
* Fix spelling of `Qt` and `LXQt`
|
||||
* Fix building on SunOS if imagemagick support is enabled (Logo, SunOS)
|
||||
* Fix typos
|
||||
|
||||
Features:
|
||||
* Support Ptyxis terminal version and font detection (Terminal / TerminalFont, Linux)
|
||||
* Improve Cinnamon version detection (DE)
|
||||
* Support `cinnamon-wayland` (WMTheme)
|
||||
* `--ts-version false` will disable editor version detection (Editor)
|
||||
|
||||
# 2.17.1
|
||||
|
||||
Hotfix for a regression that breaks Qt font detection
|
||||
|
||||
Bugfixes:
|
||||
* Don't generate and install `libffwinrt.dll.a` on MinGW (Windows)
|
||||
* Fix building on Windows when imagemagick support is enabled (Logo, Windows)
|
||||
* Don't print GPU frequency with `--gpu-temp` for Nvidia cards (#1052, GPU)
|
||||
* `--gpu-driver-specific` needs to be specified
|
||||
* Print formatted size when `--gpu-format` is used (#1052, GPU)
|
||||
* Ignore QVariant format; fix unreadable Qt font (#1053, Theme, Linux)
|
||||
* Fix segfaults with `--show-errors` and an invalid module (#1055)
|
||||
|
||||
# 2.17.0
|
||||
|
||||
Changes:
|
||||
* CMake option `ENABLE_PROPRIETARY_GPU_DRIVER_API` is removed. The GPU driver APIs are now enabled by default.
|
||||
* The option was introduced to reduce the license concerns. Since all non MIT proprietary code has been rewritten manually from scratch, it is no longer necessary.
|
||||
* See <https://github.com/fastfetch-cli/fastfetch/issues/533#issuecomment-2122830958> for detail
|
||||
* Option `--logo-separate true` is changed to `--logo-position top` for better readability
|
||||
* Builtin ascii logos can be positioned on the right side now with`--logo-position right`
|
||||
|
||||
Features:
|
||||
* Add support for `--gpu-detection-method opencl` which uses OpenCL to detect GPUs.
|
||||
* Support detecting CPU cache size by using SMBIOS as fallback (CPUCache)
|
||||
* Support GPU detection (SunOS)
|
||||
* Support GPU type detection with AMD GPU driver (GPU, Windows)
|
||||
* Add fast path of version and font detection for kitty (Terminal / TerminalFont)
|
||||
* Make sure `stdin` and `stdout` are TTYs when querying terminal
|
||||
* So modules like `TerminalSize` should work when `stdin` or `stdout` is redirected
|
||||
* Support argument truncation in `--<module>-format` (#1043)
|
||||
* See `fastfetch --help format` for detail
|
||||
* Improve Qt theme detection (#1047, Theme, Linux)
|
||||
* Add new JSON config option `general.preRun`, which is executed before fastfetch prints output.
|
||||
* It can be used to generate a temp logo file. For example
|
||||
```jsonc
|
||||
{
|
||||
"general": {
|
||||
"preRun": "kitten icat --align=left /path/to/image > /tmp/logo.kitty"
|
||||
},
|
||||
"logo": {
|
||||
"source": "/tmp/logo.kitty",
|
||||
"type": "raw"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Bugfixes:
|
||||
* Fix invalid path (#1031, LM, Linux)
|
||||
* Fix VMEM detection for Nvidia GPU (requires `--gpu-driver-specific`) (GPU)
|
||||
* Fix AMD `--gpu-driver-specific` for AMD cards (#1032, GPU, Windows)
|
||||
* Use Coordinated Universal Time rather than timezone-varying local date (#1046)
|
||||
|
||||
Logo:
|
||||
* Fix colors of Asahi Linux
|
||||
|
||||
# 2.16.0
|
||||
|
||||
This release added basic support for SunOS (Solaris, illumos). The binaries provided in the release lack a few useful features (such as Display detection). People who use SunOS should consider building fastfetch themselves.
|
||||
|
||||
Changes:
|
||||
* Fastfetch now prefers `/etc/os-release` over `/etc/lsb-release` when detecting distro info.
|
||||
* This may break some distros (notably some debian based distros). File a bug with the content of `os-release` and `lsb-release` if it breaks your distro.
|
||||
|
||||
Features:
|
||||
* Support Media detection in Windows (Media / Player, Windows)
|
||||
* Requires Windows 10 and later
|
||||
* Add new option `--users-myself-only` to display current login user only (Users)
|
||||
* Add code name of macOS Sequoia (OS, macOS)
|
||||
* Add new module `DNS` to show active DNS servers (DNS)
|
||||
* Add new option `--loadavg-compact`. Defaults to true (Loadavg)
|
||||
* Use `--loadavg-compact false` to display load averages in different lines
|
||||
* Detect MTU size (LocalIP)
|
||||
* Support version detection of pluma, which is the default editor of OpenIndiana (Editor)
|
||||
* Print used OGL library, eg EGL, GLX or OSMesa (OpenGL)
|
||||
|
||||
Bugfixes:
|
||||
* Report error if cache size is unavailable (CPUCache, Android)
|
||||
* Trim white spaces in device name (Sound, Linux, #1005)
|
||||
* Fix `display.bar.border{Left,Right}` doesn't work in JSON config files (Config)
|
||||
* Fix invalid call to `realpath(3)` (Platform, Linux)
|
||||
* Fix result calculation (CPUUsage, FreeBSD)
|
||||
|
||||
Logos:
|
||||
* Add Mauna
|
||||
* Add Tuxdeo
|
||||
* Add Manjaro ARM
|
||||
* Add RedOS
|
||||
* Add Arch3
|
||||
|
||||
# 2.15.0
|
||||
|
||||
Changes:
|
||||
@@ -971,7 +1119,7 @@ Bugfixes:
|
||||
This release backports some changes from dev branch, and fixes 2 crashing issues
|
||||
|
||||
Features:
|
||||
* Support KDE / LXQT / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
|
||||
* Support KDE / LXQt / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
|
||||
* Support QTerminal version & terminal font detection
|
||||
* Support MATE Terminal version & terminal font detection
|
||||
* Set `--pipe true` automatically if stdout is not a tty
|
||||
@@ -1017,7 +1165,7 @@ Bugfixes:
|
||||
* Fix Windows drives detection in WSL (Disk)
|
||||
|
||||
Changes:
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
|
||||
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / Qt icon params.
|
||||
* `--theme-format` no longer supports individual GTK / plasma theme params.
|
||||
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
|
||||
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
|
||||
@@ -1391,7 +1539,7 @@ Fixes build on android (#205)
|
||||
# 1.6.0
|
||||
|
||||
Features:
|
||||
* Detect QT on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [QT]
|
||||
* Detect Qt on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [Qt]
|
||||
* Alacritty font detection
|
||||
* Load `/etc/fastfetch/config.conf` before user config
|
||||
* Disk: print one decimal point if size < 100GB
|
||||
|
||||
+167
-44
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.15.0
|
||||
VERSION 2.18.1
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -18,6 +18,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
set(LINUX TRUE CACHE BOOL "..." FORCE) # LINUX means GNU/Linux, not just the kernel
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
|
||||
set(BSD TRUE CACHE BOOL "..." FORCE)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")
|
||||
set(SunOS TRUE CACHE BOOL "..." FORCE)
|
||||
elseif(NOT APPLE AND NOT WIN32)
|
||||
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
@@ -42,37 +44,37 @@ include(CheckIncludeFile)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR BSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD OR APPLE" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB "Enable xcb" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_X11 "Enable x11" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR BSD OR APPLE OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX" 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_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR BSD OR APPLE OR WIN32 OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE OR SunOS" 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 WIN32" OFF)
|
||||
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD OR WIN32 OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR ANDROID OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBNM "Enable libnm" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
|
||||
|
||||
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
|
||||
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
|
||||
option(ENABLE_PROPRIETARY_GPU_DRIVER_API "Enable proprietary GPU driver API (NVML, IGCL and AGS)" ON)
|
||||
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
|
||||
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
|
||||
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
|
||||
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
|
||||
@@ -118,7 +120,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointe
|
||||
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
@@ -138,7 +140,7 @@ if(NOT WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -rdynamic")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
if(ENABLE_LTO AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(STATUS "Enabling LTO")
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
@@ -254,7 +256,7 @@ if(APPLE)
|
||||
configure_file(src/util/apple/Info.plist.in Info.plist @ONLY)
|
||||
endif()
|
||||
|
||||
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y")
|
||||
string(TIMESTAMP FASTFETCH_BUILD_DATE "%d %B %Y" UTC)
|
||||
configure_file(doc/fastfetch.1.in fastfetch.1 @ONLY)
|
||||
|
||||
####################
|
||||
@@ -305,6 +307,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/detection/media/media.c
|
||||
src/detection/netio/netio.c
|
||||
src/detection/opencl/opencl.c
|
||||
src/detection/opengl/opengl_shared.c
|
||||
src/detection/os/os.c
|
||||
src/detection/packages/packages.c
|
||||
src/detection/physicalmemory/physicalmemory.c
|
||||
@@ -340,6 +343,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/de/de.c
|
||||
src/modules/disk/disk.c
|
||||
src/modules/diskio/diskio.c
|
||||
src/modules/dns/dns.c
|
||||
src/modules/editor/editor.c
|
||||
src/modules/font/font.c
|
||||
src/modules/gpu/gpu.c
|
||||
@@ -392,6 +396,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/options/general.c
|
||||
src/options/library.c
|
||||
src/util/edidHelper.c
|
||||
src/util/base64.c
|
||||
src/util/FFlist.c
|
||||
src/util/FFstrbuf.c
|
||||
src/util/platform/FFPlatform.c
|
||||
@@ -417,6 +422,7 @@ if(LINUX)
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
@@ -425,7 +431,11 @@ if(LINUX)
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
src/detection/displayserver/linux/wayland/zwlr-output.c
|
||||
src/detection/displayserver/linux/wayland/kde-output.c
|
||||
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
@@ -487,6 +497,7 @@ elseif(ANDROID)
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/cpuusage/cpuusage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
@@ -544,10 +555,11 @@ elseif(BSD)
|
||||
src/detection/brightness/brightness_bsd.c
|
||||
src/detection/chassis/chassis_bsd.c
|
||||
src/detection/cpu/cpu_bsd.c
|
||||
src/detection/cpucache/cpucache_nosupport.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
src/detection/cpuusage/cpuusage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_bsd.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_bsd.c
|
||||
@@ -556,7 +568,11 @@ elseif(BSD)
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
src/detection/displayserver/linux/wayland/zwlr-output.c
|
||||
src/detection/displayserver/linux/wayland/kde-output.c
|
||||
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
@@ -619,6 +635,7 @@ elseif(APPLE)
|
||||
src/detection/cpuusage/cpuusage_apple.c
|
||||
src/detection/cursor/cursor_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_apple.c
|
||||
src/detection/physicalmemory/physicalmemory_apple.m
|
||||
src/detection/diskio/diskio_apple.c
|
||||
@@ -684,6 +701,7 @@ elseif(WIN32)
|
||||
src/detection/physicaldisk/physicaldisk_windows.c
|
||||
src/detection/diskio/diskio_windows.c
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/dns/dns_windows.c
|
||||
src/detection/font/font_windows.c
|
||||
src/detection/gpu/gpu_windows.c
|
||||
src/detection/host/host_windows.c
|
||||
@@ -695,7 +713,7 @@ elseif(WIN32)
|
||||
src/detection/locale/locale_windows.c
|
||||
src/detection/localip/localip_windows.c
|
||||
src/detection/gamepad/gamepad_windows.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/media/media_windows.c
|
||||
src/detection/memory/memory_windows.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/monitor/monitor_windows.c
|
||||
@@ -727,6 +745,81 @@ elseif(WIN32)
|
||||
src/util/windows/wmi.cpp
|
||||
src/util/platform/FFPlatform_windows.c
|
||||
)
|
||||
elseif(SunOS)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/dbus.c
|
||||
src/common/io/io_unix.c
|
||||
src/common/netif/netif_bsd.c
|
||||
src/common/networking_linux.c
|
||||
src/common/processing_linux.c
|
||||
src/detection/battery/battery_nosupport.c
|
||||
src/detection/bios/bios_windows.c
|
||||
src/detection/board/board_windows.c
|
||||
src/detection/bootmgr/bootmgr_nosupport.c
|
||||
src/detection/brightness/brightness_nosupport.c
|
||||
src/detection/chassis/chassis_windows.c
|
||||
src/detection/cpu/cpu_sunos.c
|
||||
src/detection/cpucache/cpucache_shared.c
|
||||
src/detection/cpuusage/cpuusage_sunos.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/bluetooth/bluetooth_nosupport.c
|
||||
src/detection/disk/disk_sunos.c
|
||||
src/detection/dns/dns_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_nosupport.c
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_sunos.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
src/detection/displayserver/linux/wayland/zwlr-output.c
|
||||
src/detection/displayserver/linux/wayland/kde-output.c
|
||||
src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c
|
||||
src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c
|
||||
src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.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_sunos.c
|
||||
src/detection/gpu/gpu_pci.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/host/host_windows.c
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/initsystem/initsystem_linux.c
|
||||
src/detection/libc/libc_nosupport.c
|
||||
src/detection/lm/lm_nosupport.c
|
||||
src/detection/loadavg/loadavg_sunos.c
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_sunos.c
|
||||
src/detection/monitor/monitor_nosupport.c
|
||||
src/detection/netio/netio_sunos.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_sunos.c
|
||||
src/detection/packages/packages_sunos.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/sound/sound_linux.c
|
||||
src/detection/swap/swap_sunos.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/terminalsize/terminalsize_linux.c
|
||||
src/detection/theme/theme_linux.c
|
||||
src/detection/uptime/uptime_sunos.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_nosupport.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DIRECTX_HEADERS)
|
||||
@@ -734,15 +827,13 @@ if(ENABLE_DIRECTX_HEADERS)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_wsl.cpp)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
|
||||
message(STATUS "Enabling proprietary GPU driver API")
|
||||
if(LINUX OR BSD OR WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
|
||||
endif()
|
||||
# Proprietary GPU driver APIs
|
||||
if(LINUX OR BSD OR WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_nvidia.c)
|
||||
endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_intel.c)
|
||||
list(APPEND LIBFASTFETCH_SRC src/detection/gpu/gpu_amd.c)
|
||||
endif()
|
||||
|
||||
include(CheckFunctionExists)
|
||||
@@ -771,10 +862,6 @@ add_library(libfastfetch OBJECT
|
||||
${LIBFASTFETCH_SRC}
|
||||
)
|
||||
|
||||
if(ENABLE_PROPRIETARY_GPU_DRIVER_API AND (LINUX OR BSD OR WIN32))
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_PROPRIETARY_GPU_DRIVER_API)
|
||||
endif()
|
||||
|
||||
if(yyjson_FOUND)
|
||||
target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON)
|
||||
target_link_libraries(libfastfetch PRIVATE yyjson::yyjson)
|
||||
@@ -814,6 +901,8 @@ if(WIN32)
|
||||
target_compile_definitions(libfastfetch PUBLIC WIN32_LEAN_AND_MEAN=1)
|
||||
elseif(APPLE)
|
||||
target_compile_definitions(libfastfetch PUBLIC _DARWIN_C_SOURCE)
|
||||
elseif(SunOS)
|
||||
target_compile_definitions(libfastfetch PUBLIC __EXTENSIONS__ _POSIX_C_SOURCE=1)
|
||||
endif()
|
||||
|
||||
if(HAVE_STATX)
|
||||
@@ -1042,6 +1131,13 @@ elseif(BSD)
|
||||
PRIVATE "usbhid"
|
||||
PRIVATE "geom"
|
||||
)
|
||||
elseif(SunOS)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
PRIVATE "socket"
|
||||
PRIVATE "kstat"
|
||||
PRIVATE "proc"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
if(HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
@@ -1067,6 +1163,24 @@ target_link_libraries(libfastfetch
|
||||
PRIVATE ${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
||||
target_compile_options(libfastfetch PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions -fno-rtti>)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
include(CheckIncludeFileCXX)
|
||||
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Foundation.h" HAVE_WINRT)
|
||||
if(HAVE_WINRT)
|
||||
add_library(ffwinrt MODULE src/detection/media/media_windows.dll.cpp)
|
||||
target_link_libraries(ffwinrt PRIVATE "RuntimeObject")
|
||||
target_compile_definitions(ffwinrt PRIVATE WIN32_LEAN_AND_MEAN=1 WINRT_LEAN_AND_MEAN=1)
|
||||
target_link_options(ffwinrt
|
||||
PRIVATE "-static" # stdc++, winpthread, gcc_s, etc.
|
||||
)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
######################
|
||||
# Executable targets #
|
||||
######################
|
||||
@@ -1105,12 +1219,9 @@ if(yyjson_FOUND)
|
||||
endif()
|
||||
|
||||
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
|
||||
)
|
||||
@@ -1163,6 +1274,13 @@ install(
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
|
||||
if (TARGET ffwinrt)
|
||||
install(
|
||||
TARGETS ffwinrt
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.bash"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/bash-completion/completions"
|
||||
@@ -1219,12 +1337,17 @@ if(LINUX)
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
|
||||
if(NOT IS_MUSL)
|
||||
EXECUTE_PROCESS (
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND getconf GNU_LIBC_VERSION
|
||||
OUTPUT_VARIABLE GLIBC_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
STRING (REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
|
||||
if(GLIBC_VERSION)
|
||||
STRING(REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
|
||||
message(STATUS "found glibc ${GLIBC_VERSION}")
|
||||
else()
|
||||
message(WARNING "Could not determine glibc version. If `musl` is used, `-DIS_MUSL=ON` should be set")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Linus Dierheimer
|
||||
Copyright (c) 2021-2023 Linus Dierheimer
|
||||
Copyright (c) 2022-2024 Carter Li
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
[](https://repology.org/project/fastfetch/versions)
|
||||
|
||||
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 mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported.
|
||||
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS 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,15 +21,16 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
|
||||
<img src="screenshots/example3.png" width="48%" align="top" />
|
||||
<img src="screenshots/example5.png" height="15%" align="top" />
|
||||
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
|
||||
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki).
|
||||
|
||||
## Installation
|
||||
|
||||
### Linux
|
||||
|
||||
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
|
||||
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
|
||||
|
||||
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
|
||||
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
|
||||
* Debian / Ubuntu: Download `fastfetch-linux-<proper architecture>.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer).
|
||||
* Arch Linux: `sudo pacman -S fastfetch`
|
||||
* Fedora: `sudo dnf install fastfetch`
|
||||
@@ -56,7 +57,7 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
|
||||
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
|
||||
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
|
||||
|
||||
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
|
||||
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
|
||||
|
||||
### FreeBSD
|
||||
|
||||
@@ -80,7 +81,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
|
||||
|
||||
## Customization
|
||||
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
|
||||
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. Those files can serve as examples of the configuration syntax.
|
||||
|
||||
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
|
||||
|
||||
@@ -102,10 +103,10 @@ Logos can be heavily customized too; see the [logo documentation](https://github
|
||||
|
||||
1. Fastfetch is actively maintained.
|
||||
2. Fastfetch is faster. As the name suggests.
|
||||
3. Fastfetch is more feature-rich. By default fastfetch only has a few modules enabled. Use `fastfetch -c all` to find what you want.
|
||||
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module (notibily the difference of `MiB` and `G`), while fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
6. Fastfetch is more accurate. For example, [neofetch never actually supports Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
|
||||
3. Fastfetch has a greater number of features, though by default fastfetch only has a few modules enabled; use `fastfetch -c all` to find what you want.
|
||||
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>.
|
||||
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
|
||||
6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
|
||||
|
||||
### Q: Fastfetch shows my local IP address. It leaks my privacy!
|
||||
|
||||
@@ -117,7 +118,7 @@ If you really don't like it, you can disable the `Local IP` module in `config.js
|
||||
|
||||
### Q: Where is the config file? I can't find it.
|
||||
|
||||
`Fastfetch` don't generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
|
||||
`Fastfetch` does not generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
|
||||
|
||||
### Q: The configuration is so complex. Where is the documentation?
|
||||
|
||||
@@ -131,7 +132,7 @@ Alternatively, you can refer to the presets in [`presets` directory](https://git
|
||||
|
||||
### Q: How can I customize the module output?
|
||||
|
||||
Fastfetch uses `format` to generate output. For example to make `GPU` module show GPU name only and ignore other information, you can use
|
||||
Fastfetch uses `format` to generate output. For example, to make the `GPU` module show only the GPU name (leaving other information undisplayed), you can use
|
||||
|
||||
```jsonc
|
||||
{
|
||||
@@ -144,15 +145,15 @@ Fastfetch uses `format` to generate output. For example to make `GPU` module sho
|
||||
}
|
||||
```
|
||||
|
||||
which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
|
||||
. . which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
|
||||
|
||||
See `fastfetch -h format` for basic usage. For module specific formattion, see `fastfetch -h <module>-format`
|
||||
See `fastfetch -h format` for information on basic usage. For module specific formattion, see `fastfetch -h <module>-format`
|
||||
|
||||
### Q: I have my own ascii-art / image file. How can I show it with fastfetch?
|
||||
|
||||
Try `fastfetch -l /path/to/logo`. See [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for detail.
|
||||
|
||||
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet)
|
||||
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet):
|
||||
|
||||
```bash
|
||||
# install pyfiglet and jq first
|
||||
|
||||
@@ -347,6 +347,7 @@ __fastfetch_completion()
|
||||
"--users-key"
|
||||
"--users-format"
|
||||
"--users-key-color"
|
||||
"--users-myself-only"
|
||||
"--bluetooth-key"
|
||||
"--bluetooth-format"
|
||||
"--bluetooth-key-color"
|
||||
@@ -355,7 +356,6 @@ __fastfetch_completion()
|
||||
local FF_OPTIONS_PATH=(
|
||||
"-c"
|
||||
"--config"
|
||||
"--lib-pci"
|
||||
"--lib-vulkan"
|
||||
"--lib-wayland"
|
||||
"--lib-xcb-randr"
|
||||
|
||||
+44
-47
@@ -54,51 +54,48 @@ function __fastfetch_complete_structure
|
||||
end
|
||||
end
|
||||
|
||||
string match -r -a -g "^###> ?(.*)" < (status -f) | string collect | python3 | source
|
||||
echo '
|
||||
import json, subprocess, sys
|
||||
|
||||
###> #!/usr/bin/env python3
|
||||
###>
|
||||
###> import json, subprocess, sys
|
||||
###>
|
||||
###> def main():
|
||||
###> data: dict[str, list[dict]] = json.loads(subprocess.check_output(['fastfetch', '--help-raw']))
|
||||
###>
|
||||
###> for key in data:
|
||||
###> for flag in data[key]:
|
||||
###> if flag.get('pseudo', False):
|
||||
###> continue
|
||||
###>
|
||||
###> command_prefix: str = f'complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}"';
|
||||
###> if 'short' in flag:
|
||||
###> command_prefix += f' -o "{flag["short"]}"'
|
||||
###>
|
||||
###> if 'arg' in flag:
|
||||
###> type: str = flag['arg']['type'];
|
||||
###> if type == 'bool':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_bool)"')
|
||||
###> elif type == 'color':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_color)"')
|
||||
###> elif type == 'command':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_command)"')
|
||||
###> elif type == 'config':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_config)"')
|
||||
###> elif type == 'enum':
|
||||
###> temp: str = ' '.join(flag["arg"]["enum"])
|
||||
###> print(f'{command_prefix} -x -a "{temp}"')
|
||||
###> elif type == 'logo':
|
||||
###> print(f'{command_prefix} -x -a "(__fastfetch_complete_logo)"')
|
||||
###> elif type == 'structure':
|
||||
###> print(f'{command_prefix} -x -a "(__fish_complete_list : __fastfetch_complete_structure)"')
|
||||
###> elif type == 'path':
|
||||
###> print(f'{command_prefix} -r -F')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -x')
|
||||
###> else:
|
||||
###> print(f'{command_prefix} -f')
|
||||
###>
|
||||
###> if __name__ == "__main__":
|
||||
###> try:
|
||||
###> main()
|
||||
###> except:
|
||||
###> sys.exit(1)
|
||||
###>
|
||||
def main():
|
||||
data: dict[str, list[dict]] = json.loads(subprocess.check_output(["fastfetch", "--help-raw"]))
|
||||
|
||||
for key in data:
|
||||
for flag in data[key]:
|
||||
if flag.get("pseudo", False):
|
||||
continue
|
||||
|
||||
command_prefix = f"""complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}\""""
|
||||
if "short" in flag:
|
||||
command_prefix += f""" -o {flag["short"]}"""
|
||||
|
||||
if "arg" in flag:
|
||||
type: str = flag["arg"]["type"];
|
||||
if type == "bool":
|
||||
print(f"{command_prefix} -x -a \"(__fastfetch_complete_bool)\"")
|
||||
elif type == "color":
|
||||
print(f"{command_prefix} -x -a \"(__fastfetch_complete_color)\"")
|
||||
elif type == "command":
|
||||
print(f"{command_prefix} -x -a \"(__fastfetch_complete_command)\"")
|
||||
elif type == "config":
|
||||
print(f"{command_prefix} -x -a \"(__fastfetch_complete_config)\"")
|
||||
elif type == "enum":
|
||||
temp: str = " ".join(flag["arg"]["enum"])
|
||||
print(f"{command_prefix} -x -a \"{temp}\"")
|
||||
elif type == "logo":
|
||||
print(f"{command_prefix} -x -a \"(__fastfetch_complete_logo)\"")
|
||||
elif type == "structure":
|
||||
print(f"{command_prefix} -x -a \"(__fish_complete_list : __fastfetch_complete_structure)\"")
|
||||
elif type == "path":
|
||||
print(f"{command_prefix} -r -F")
|
||||
else:
|
||||
print(f"{command_prefix} -x")
|
||||
else:
|
||||
print(f"{command_prefix} -f")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except:
|
||||
sys.exit(1)
|
||||
' | python3 | source
|
||||
|
||||
Vendored
+36
@@ -1,3 +1,39 @@
|
||||
fastfetch (2.17.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.2
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 04 Jul 2024 10:22:44 +0800
|
||||
|
||||
fastfetch (2.17.1) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.1
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Mon, 01 Jul 2024 08:56:29 +0800
|
||||
|
||||
fastfetch (2.17.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.17.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 28 Jun 2024 13:43:18 +0800
|
||||
|
||||
fastfetch (2.16.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.16.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Wed, 19 Jun 2024 14:53:43 +0800
|
||||
|
||||
fastfetch (2.15.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.15.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 07 Jun 2024 13:52:43 +0800
|
||||
|
||||
fastfetch (2.14.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.14.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Thu, 30 May 2024 14:27:54 +0800
|
||||
|
||||
fastfetch (2.13.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.13.2
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.13.2_source.buildinfo universe/utils optional
|
||||
fastfetch_2.17.2_source.buildinfo universe/utils optional
|
||||
|
||||
+141
-37
@@ -23,7 +23,7 @@
|
||||
"default": 0
|
||||
},
|
||||
"format": {
|
||||
"description": "Output format of the module. See `-h <module>-format` for detail",
|
||||
"description": "Output format of the module. See `-h <module>-format` for detail. I.e: fastfetch -h disk-format",
|
||||
"type": "string"
|
||||
},
|
||||
"outputColor": {
|
||||
@@ -89,10 +89,12 @@
|
||||
"default": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"
|
||||
},
|
||||
"logo": {
|
||||
"description": "Fastfetch logo configurations\nSee also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Disable logo",
|
||||
"type": "null"
|
||||
"type": "null",
|
||||
"const": null
|
||||
},
|
||||
{
|
||||
"description": "Set the source file of the logo",
|
||||
@@ -217,10 +219,15 @@
|
||||
"description": "If true, regenerate image logo cache",
|
||||
"default": false
|
||||
},
|
||||
"separate": {
|
||||
"type": "boolean",
|
||||
"description": "If true, print modules at bottom of the logo",
|
||||
"default": false
|
||||
"position": {
|
||||
"type": "string",
|
||||
"description": "Set the position of the logo should be displayed",
|
||||
"enum": [
|
||||
"left",
|
||||
"top",
|
||||
"right"
|
||||
],
|
||||
"default": "left"
|
||||
},
|
||||
"chafa": {
|
||||
"type": "object",
|
||||
@@ -327,6 +334,16 @@
|
||||
"type": "integer",
|
||||
"description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout",
|
||||
"default": 1000
|
||||
},
|
||||
"preRun": {
|
||||
"type": "string",
|
||||
"description": "Set the command to be executed before printing logos",
|
||||
"default": ""
|
||||
},
|
||||
"showVersion": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to detect and display component versions. Mainly for benchmarking",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -561,11 +578,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Whether to disable the stdout application buffer",
|
||||
"default": false
|
||||
},
|
||||
"tsVersion": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to detect and display the version of terminal and shell. Mainly for benchmarking",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -574,10 +586,6 @@
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"pci": {
|
||||
"type": "string",
|
||||
"description": "GPU output (Linux and FreeBSD)"
|
||||
},
|
||||
"vulkan": {
|
||||
"type": "string",
|
||||
"description": "Vulkan module & fallback for GPU output"
|
||||
@@ -592,39 +600,39 @@
|
||||
},
|
||||
"xcbRandr": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)"
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xcb": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)"
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xrandr": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)"
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"x11": {
|
||||
"type": "string",
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)"
|
||||
"description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"drm": {
|
||||
"type": "string",
|
||||
"description": "Used for fast resolution and refresh rate detection (Linux)"
|
||||
"description": "Used for fast resolution and refresh rate detection (Linux, FreeBSD)"
|
||||
},
|
||||
"gio": {
|
||||
"type": "string",
|
||||
"description": "Needed for values that are only stored GSettings (Linux, FreeBSD)"
|
||||
"description": "Needed for values that are only stored GSettings (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"dconf": {
|
||||
"type": "string",
|
||||
"description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD)"
|
||||
"description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"dbus": {
|
||||
"type": "string",
|
||||
"description": "Bluetooth, Player & Media detection (Linux, FreeBSD)"
|
||||
"description": "Bluetooth, Player & Media detection (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"xfconf": {
|
||||
"type": "string",
|
||||
"description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD)"
|
||||
"description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"sqlite3": {
|
||||
"type": "string",
|
||||
@@ -636,34 +644,34 @@
|
||||
},
|
||||
"imagemagick": {
|
||||
"type": "string",
|
||||
"description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, macOS)"
|
||||
"description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)"
|
||||
},
|
||||
"z": {
|
||||
"description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, macOS)",
|
||||
"description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)",
|
||||
"type": "string"
|
||||
},
|
||||
"chafa": {
|
||||
"type": "string",
|
||||
"description": "Image output as ascii art (Linux, FreeBSD, macOS)"
|
||||
"description": "Image output as ascii art (Linux, FreeBSD, SunOS, macOS)"
|
||||
},
|
||||
"egl": {
|
||||
"type": "string",
|
||||
"description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)"
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS, Windows)"
|
||||
},
|
||||
"glx": {
|
||||
"type": "string",
|
||||
"description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)"
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"osmesa": {
|
||||
"type": "string",
|
||||
"description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)"
|
||||
"description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)"
|
||||
},
|
||||
"opencl": {
|
||||
"type": "string",
|
||||
"description": "OpenCL module (Linux, FreeBSD, Windows)"
|
||||
"description": "OpenCL module (Linux, FreeBSD, SunOS, Windows)"
|
||||
},
|
||||
"pulse": {
|
||||
"description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD)",
|
||||
"description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD, SunOS)",
|
||||
"type": "string"
|
||||
},
|
||||
"nm": {
|
||||
@@ -705,6 +713,7 @@
|
||||
"disk",
|
||||
"diskio",
|
||||
"de",
|
||||
"dns",
|
||||
"editor",
|
||||
"font",
|
||||
"gamepad",
|
||||
@@ -903,10 +912,6 @@
|
||||
"const": "uptime",
|
||||
"description": "Print how long system has been running"
|
||||
},
|
||||
{
|
||||
"const": "users",
|
||||
"description": "Print users currently logged in"
|
||||
},
|
||||
{
|
||||
"const": "version",
|
||||
"description": "Print Fastfetch version"
|
||||
@@ -1136,6 +1141,21 @@
|
||||
"type": "boolean",
|
||||
"description": "Display CPU usage per CPU logical core, instead of an average result",
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1438,6 +1458,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "DNS",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "dns",
|
||||
"description": "Print DNS servers"
|
||||
},
|
||||
"showType": {
|
||||
"enum": [
|
||||
"ipv4",
|
||||
"ipv6",
|
||||
"both"
|
||||
],
|
||||
"default": "both",
|
||||
"description": "Specify the type of DNS servers should be detected"
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Gamepad",
|
||||
"type": "object",
|
||||
@@ -1491,6 +1546,7 @@
|
||||
"auto",
|
||||
"pci",
|
||||
"vulkan",
|
||||
"opencl",
|
||||
"opengl"
|
||||
],
|
||||
"default": "auto"
|
||||
@@ -1636,6 +1692,14 @@
|
||||
"maximum": 9,
|
||||
"default": 2
|
||||
},
|
||||
"compact": {
|
||||
"type": "boolean",
|
||||
"description": "Show values in one line",
|
||||
"default": true
|
||||
},
|
||||
"percent": {
|
||||
"$ref": "#/$defs/percent"
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
@@ -1703,7 +1767,7 @@
|
||||
"const": "opengl"
|
||||
},
|
||||
"library": {
|
||||
"description": "Set the OpenGL context creation library to use. Linux only",
|
||||
"description": "Set the OpenGL context creation library to use",
|
||||
"enum": [
|
||||
"auto",
|
||||
"egl",
|
||||
@@ -1752,6 +1816,9 @@
|
||||
"emerge",
|
||||
"eopkg",
|
||||
"flatpak",
|
||||
"guix",
|
||||
"lpkg",
|
||||
"lpkgbuild",
|
||||
"macports",
|
||||
"nix",
|
||||
"opkg",
|
||||
@@ -1762,6 +1829,7 @@
|
||||
"rpm",
|
||||
"scoop",
|
||||
"snap",
|
||||
"sorcery",
|
||||
"winget",
|
||||
"xbps"
|
||||
],
|
||||
@@ -1999,6 +2067,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Users",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "users",
|
||||
"description": "Print users currently logged in"
|
||||
},
|
||||
"compact": {
|
||||
"type": "boolean",
|
||||
"description": "Show all active users in one line",
|
||||
"default": false
|
||||
},
|
||||
"myselfOnly": {
|
||||
"type": "boolean",
|
||||
"description": "Show only the current user",
|
||||
"default": false
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"outputColor": {
|
||||
"$ref": "#/$defs/outputColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Weather",
|
||||
"type": "object",
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"cpuusage",
|
||||
{
|
||||
"type": "gpu",
|
||||
"driverSpecific": true,
|
||||
"temp": true
|
||||
},
|
||||
"memory",
|
||||
@@ -63,6 +64,7 @@
|
||||
"showIpv6": true,
|
||||
"showMac": true
|
||||
},
|
||||
"dns",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
"cpuusage",
|
||||
{
|
||||
"type": "gpu",
|
||||
"driverSpecific": true,
|
||||
"temp": true
|
||||
},
|
||||
"memory",
|
||||
@@ -65,6 +66,7 @@
|
||||
"showIpv6": true,
|
||||
"showMac": true
|
||||
},
|
||||
"dns",
|
||||
"wifi",
|
||||
"datetime",
|
||||
"locale",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Inspired by Catnap
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Inspired by Catnap
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Inspired by Catnap
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Inspired by Catnap
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
// _____ _____ _____ _____ _____ _____ _____ _____ _____
|
||||
// | __| _ | __|_ _| __| __|_ _| | | |
|
||||
// | __| |__ | | | | __| __| | | | --| |
|
||||
// |__| |__|__|_____| |_| |__| |_____| |_| |_____|__|__|
|
||||
//
|
||||
// By CarterLi - https://github.com/CarterLi
|
||||
// Homepage - https://github.com/fastfetch-cli/fastfetch
|
||||
// config.jsonc - ニリ @niri-san
|
||||
// pokemon-colorscripts - https://gitlab.com/phoneybadger/pokemon-colorscripts
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"source": " _____ _____ _____ _____ _____ _____ _____ _____ _____\n| __| _ | __|_ _| __| __|_ _| | | |\n| __| |__ | | | | __| __| | | | --| |\n|__| |__|__|_____| |_| |__| |_____| |_| |_____|__|__|",
|
||||
"type": "data",
|
||||
"separate": true,
|
||||
"padding": {
|
||||
"right": 2
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"separator": " - "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom", // HardwareInfo
|
||||
"format": "• {#green}SYSTEM INFORMATION"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "HOST",
|
||||
"format": "{name}{?vendor} ({vendor}){?}",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "chassis",
|
||||
"key": "COMPUTER TYPE",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "CPU",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": "GPU",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "MEMORY USED",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": "SWAP USED",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "DISK",
|
||||
"folders": "/",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "custom", // SoftwareInfo
|
||||
"format": "• {#red}SOFTWARE INFORMATION"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "DISTRO",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"folders": "/", // Use "/System/Volumes/VM" or something else on macOS
|
||||
"format": "{create-time}",
|
||||
"key": "INSTALLED DATE",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "KERNEL",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": "PACKAGES",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "UPTIME",
|
||||
"keyColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "custom", // DisplayInfo
|
||||
"format": "• {#blue}DISPLAY INFORMATION"
|
||||
},
|
||||
{
|
||||
"type": "de",
|
||||
"key": "DESKTOP ENVIRONMENT",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "lm",
|
||||
"key": "LOGIN MANAGER",
|
||||
"format": "{type}",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wm",
|
||||
"key": "WM",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "wmtheme",
|
||||
"key": "WM THEME",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "monitor",
|
||||
"key": "MONITOR ({name})",
|
||||
"keyColor": "blue"
|
||||
},
|
||||
{
|
||||
"type": "custom", // DesignInfo
|
||||
"format": "• {#yellow}DESIGN INFORMATION"
|
||||
},
|
||||
{
|
||||
"type": "wallpaper",
|
||||
"key": "WALLPAPER",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "theme",
|
||||
"key": "KDE THEME",
|
||||
"format": "{1}",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "icons",
|
||||
"key": "ICON THEME",
|
||||
"format": "{1}",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "font",
|
||||
"key": "FONT",
|
||||
"format": "{?1}{1} [Qt]{?}{/1}Unknown", // Remove "[Qt]" if not using Qt
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": "TERMINAL FONT",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "cursor",
|
||||
"key": "CURSOR",
|
||||
"keyColor": "yellow"
|
||||
},
|
||||
{
|
||||
"type": "custom", // OtherInfo
|
||||
"format": "• {#cyan}VARIOUS INFORMATION"
|
||||
},
|
||||
{
|
||||
"type": "media",
|
||||
"key": "NOW PLAYING",
|
||||
"format": "{?artist}{artist} - {?}{title}",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "weather",
|
||||
"key": "WEATHER",
|
||||
"timeout": 1000,
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "version",
|
||||
"key": "INFO",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
"break",
|
||||
"colors",
|
||||
"break"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// Inspired by https://github.com/usgraphics/TR-100
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": null,
|
||||
"display": {
|
||||
"pipe": true,
|
||||
"keyWidth": 16,
|
||||
"separator": "│ ",
|
||||
"percent": {
|
||||
"type": 6
|
||||
},
|
||||
"bar": {
|
||||
"borderLeft": "",
|
||||
"borderRight": "",
|
||||
"charElapsed": "█",
|
||||
"charTotal": "░",
|
||||
"width": 40
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┤"
|
||||
},
|
||||
{
|
||||
"type": "version",
|
||||
"key": " ",
|
||||
"format": "│ FASTFETCH v{version} │"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "│ TR-100 MACHINE REPORT │"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┬──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "os",
|
||||
"key": "│ OS │\u001b[42C"
|
||||
},
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": "│ KERNEL │\u001b[42C"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┼──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "│ HOSTNAME │\u001b[42C",
|
||||
"format": "{host-name}"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "│ CLIENT IP │\u001b[42C",
|
||||
"format": "{ipv4}"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": "│ MAC ADDR │\u001b[42C",
|
||||
"format": "{mac} ({ifname})",
|
||||
"showIPv4": false,
|
||||
"showMac": true
|
||||
},
|
||||
{
|
||||
"type": "dns",
|
||||
"key": "│ DNS │\u001b[42C",
|
||||
"showType": "ipv4"
|
||||
},
|
||||
{
|
||||
"type": "title",
|
||||
"key": "│ USER │\u001b[42C",
|
||||
"format": "{user-name}"
|
||||
},
|
||||
{
|
||||
"type": "host",
|
||||
"key": "│ MACHINE │\u001b[42C",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┼──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ PROCESSOR │\u001b[42C",
|
||||
"format": "{name}"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ CORES │\u001b[42C",
|
||||
"format": "{cores-physical} PHYSICAL CORES / {cores-logical} THREADS",
|
||||
"showPeCoreCount": false
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": "│ CPU FREQ │\u001b[42C",
|
||||
"format": "{freq-max}{/freq-max}{freq-base}{/} GHz"
|
||||
},
|
||||
{
|
||||
"type": "loadavg",
|
||||
"compact": false,
|
||||
// {duration} is not fixed length, hack it
|
||||
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│\u001b[42C"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┼──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ MEMORY │\u001b[42C",
|
||||
"format": "{used} / {total} [{percentage}]"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": "│ USAGE │\u001b[42C",
|
||||
"format": ""
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┼──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ VOLUME │\u001b[42C",
|
||||
"format": "{size-used} / {size-total} [{size-percentage}]",
|
||||
"folders": "/"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": "│ DISK USAGE │\u001b[42C",
|
||||
"format": ""
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "├────────────┼──────────────────────────────────────────┤"
|
||||
},
|
||||
{
|
||||
"type": "users",
|
||||
"key": "│ LAST LOGIN │\u001b[42C",
|
||||
"format": "{login-time}{?client-ip} ({client-ip})",
|
||||
"myselfOnly": true
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": "│ UPTIME │\u001b[42C"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": "└────────────┴──────────────────────────────────────────┘"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"type": "small"
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"key": "██ Distro",
|
||||
"keyColor": "38;5;210",
|
||||
"type": "os"
|
||||
},
|
||||
{
|
||||
"key": "██ Kernel",
|
||||
"keyColor": "38;5;84",
|
||||
"type": "kernel"
|
||||
},
|
||||
{
|
||||
"key": "██ Shell",
|
||||
"keyColor": "38;5;147",
|
||||
"type": "shell"
|
||||
},
|
||||
{
|
||||
"key": "██ Packages",
|
||||
"keyColor": "38;5;200",
|
||||
"type": "packages"
|
||||
},
|
||||
{
|
||||
"key": "██ WM",
|
||||
"keyColor": "38;5;44",
|
||||
"type": "wm"
|
||||
},
|
||||
{
|
||||
"key": "██ CPU",
|
||||
"keyColor": "38;5;75",
|
||||
"type": "cpu"
|
||||
},
|
||||
{
|
||||
"key": "██ Memory",
|
||||
"keyColor": "38;5;123",
|
||||
"type": "memory"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// Modified from: https://github.com/fastfetch-cli/fastfetch/pull/1025#issuecomment-2177566138
|
||||
{
|
||||
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||
"logo": {
|
||||
"source": "arch3",
|
||||
"color": {
|
||||
"1": "red",
|
||||
"2": "yellow"
|
||||
}
|
||||
},
|
||||
"display": {
|
||||
"color": {
|
||||
"separator": "blue"
|
||||
},
|
||||
"separator": " | "
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"type": "kernel",
|
||||
"key": " /\\rch Linux",
|
||||
"keyColor": "magenta"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
{
|
||||
"type": "uptime",
|
||||
"key": " Uptime ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"key": " Shell ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "terminal",
|
||||
"key": " Terminal ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "terminalfont",
|
||||
"key": " Font ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "packages",
|
||||
"key": " Packages ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "localip",
|
||||
"key": " Local IP ",
|
||||
"keyColor": "green"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
{
|
||||
"type": "display",
|
||||
"key": " Display ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "cpu",
|
||||
"key": " CPU ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "gpu",
|
||||
"key": " GPU ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "memory",
|
||||
"key": " RAM ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "swap",
|
||||
"key": " SWAP ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "disk",
|
||||
"key": " Disk ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "battery",
|
||||
"key": " Battery ",
|
||||
"keyColor": "cyan"
|
||||
},
|
||||
{
|
||||
"type": "custom",
|
||||
"format": ">-----------<+>------------------------------------------<",
|
||||
"outputColor": "separator"
|
||||
},
|
||||
"break",
|
||||
{
|
||||
"type": "colors",
|
||||
"paddingLeft": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"home": "https://github.com/ibireme/yyjson",
|
||||
"license": "MIT ( embed in source )",
|
||||
"version": "0.9.0",
|
||||
"version": "0.10.0",
|
||||
"author": "ibireme"
|
||||
}
|
||||
|
||||
Vendored
+152
-57
@@ -1831,6 +1831,42 @@ bool unsafe_yyjson_mut_equals(yyjson_mut_val *lhs, yyjson_mut_val *rhs) {
|
||||
}
|
||||
}
|
||||
|
||||
bool yyjson_locate_pos(const char *str, size_t len, size_t pos,
|
||||
size_t *line, size_t *col, size_t *chr) {
|
||||
usize line_sum = 0, line_pos = 0, chr_sum = 0;
|
||||
const u8 *cur = (const u8 *)str;
|
||||
const u8 *end = cur + pos;
|
||||
|
||||
if (!str || pos > len) {
|
||||
if (line) *line = 0;
|
||||
if (col) *col = 0;
|
||||
if (chr) *chr = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (cur < end) {
|
||||
u8 c = *cur;
|
||||
chr_sum += 1;
|
||||
if (likely(c < 0x80)) { /* 0xxxxxxx (0x00-0x7F) ASCII */
|
||||
if (c == '\n') {
|
||||
line_sum += 1;
|
||||
line_pos = chr_sum;
|
||||
}
|
||||
cur += 1;
|
||||
}
|
||||
else if (c < 0xC0) cur += 1; /* 10xxxxxx (0x80-0xBF) Invalid */
|
||||
else if (c < 0xE0) cur += 2; /* 110xxxxx (0xC0-0xDF) 2-byte UTF-8 */
|
||||
else if (c < 0xF0) cur += 3; /* 1110xxxx (0xE0-0xEF) 3-byte UTF-8 */
|
||||
else if (c < 0xF8) cur += 4; /* 11110xxx (0xF0-0xF7) 4-byte UTF-8 */
|
||||
else cur += 1; /* 11111xxx (0xF8-0xFF) Invalid */
|
||||
}
|
||||
|
||||
if (line) *line = line_sum + 1;
|
||||
if (col) *col = chr_sum - line_pos + 1;
|
||||
if (chr) *chr = chr_sum;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !YYJSON_DISABLE_UTILS
|
||||
@@ -4434,7 +4470,7 @@ static_inline bool read_number(u8 **ptr,
|
||||
bool sign;
|
||||
|
||||
/* read number as raw string if has `YYJSON_READ_NUMBER_AS_RAW` flag */
|
||||
if (unlikely(pre && !has_read_flag(BIGNUM_AS_RAW))) {
|
||||
if (has_read_flag(NUMBER_AS_RAW)) {
|
||||
return read_number_raw(ptr, pre, flg, val, msg);
|
||||
}
|
||||
|
||||
@@ -5036,7 +5072,7 @@ static_inline bool read_number(u8 **ptr,
|
||||
bool sign;
|
||||
|
||||
/* read number as raw string if has `YYJSON_READ_NUMBER_AS_RAW` flag */
|
||||
if (unlikely(pre && !has_read_flag(BIGNUM_AS_RAW))) {
|
||||
if (has_read_flag(NUMBER_AS_RAW)) {
|
||||
return read_number_raw(ptr, pre, flg, val, msg);
|
||||
}
|
||||
|
||||
@@ -5744,18 +5780,18 @@ static_noinline yyjson_doc *read_root_single(u8 *hdr,
|
||||
}
|
||||
if (*cur == 't') {
|
||||
if (likely(read_true(&cur, val))) goto doc_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_true;
|
||||
}
|
||||
if (*cur == 'f') {
|
||||
if (likely(read_false(&cur, val))) goto doc_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_false;
|
||||
}
|
||||
if (*cur == 'n') {
|
||||
if (likely(read_null(&cur, val))) goto doc_end;
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_nan(false, &cur, pre, val)) goto doc_end;
|
||||
}
|
||||
goto fail_literal;
|
||||
goto fail_literal_null;
|
||||
}
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_inf_or_nan(false, &cur, pre, val)) goto doc_end;
|
||||
@@ -5789,15 +5825,26 @@ fail_string:
|
||||
fail_number:
|
||||
return_err(cur, INVALID_NUMBER, msg);
|
||||
fail_alloc:
|
||||
return_err(cur, MEMORY_ALLOCATION, "memory allocation failed");
|
||||
fail_literal:
|
||||
return_err(cur, LITERAL, "invalid literal");
|
||||
fail_comment:
|
||||
return_err(cur, INVALID_COMMENT, "unclosed multiline comment");
|
||||
return_err(cur, MEMORY_ALLOCATION,
|
||||
"memory allocation failed");
|
||||
fail_literal_true:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'true'");
|
||||
fail_literal_false:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'false'");
|
||||
fail_literal_null:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'null'");
|
||||
fail_character:
|
||||
return_err(cur, UNEXPECTED_CHARACTER, "unexpected character");
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a valid root value");
|
||||
fail_comment:
|
||||
return_err(cur, INVALID_COMMENT,
|
||||
"unclosed multiline comment");
|
||||
fail_garbage:
|
||||
return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document");
|
||||
return_err(cur, UNEXPECTED_CONTENT,
|
||||
"unexpected content after document");
|
||||
|
||||
#undef return_err
|
||||
}
|
||||
@@ -5927,13 +5974,13 @@ arr_val_begin:
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (likely(read_true(&cur, val))) goto arr_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_true;
|
||||
}
|
||||
if (*cur == 'f') {
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (likely(read_false(&cur, val))) goto arr_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_false;
|
||||
}
|
||||
if (*cur == 'n') {
|
||||
val_incr();
|
||||
@@ -5942,7 +5989,7 @@ arr_val_begin:
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_nan(false, &cur, pre, val)) goto arr_val_end;
|
||||
}
|
||||
goto fail_literal;
|
||||
goto fail_literal_null;
|
||||
}
|
||||
if (*cur == ']') {
|
||||
cur++;
|
||||
@@ -5960,13 +6007,13 @@ arr_val_begin:
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (read_inf_or_nan(false, &cur, pre, val)) goto arr_val_end;
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
}
|
||||
if (has_read_flag(ALLOW_COMMENTS)) {
|
||||
if (skip_spaces_and_comments(&cur)) goto arr_val_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
|
||||
arr_val_end:
|
||||
if (*cur == ',') {
|
||||
@@ -5985,7 +6032,7 @@ arr_val_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto arr_val_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_arr_end;
|
||||
|
||||
arr_end:
|
||||
/* get parent container */
|
||||
@@ -6038,7 +6085,7 @@ obj_key_begin:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_key_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_key;
|
||||
|
||||
obj_key_end:
|
||||
if (*cur == ':') {
|
||||
@@ -6053,7 +6100,7 @@ obj_key_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_key_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_sep;
|
||||
|
||||
obj_val_begin:
|
||||
if (*cur == '"') {
|
||||
@@ -6080,13 +6127,13 @@ obj_val_begin:
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (likely(read_true(&cur, val))) goto obj_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_true;
|
||||
}
|
||||
if (*cur == 'f') {
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (likely(read_false(&cur, val))) goto obj_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_false;
|
||||
}
|
||||
if (*cur == 'n') {
|
||||
val++;
|
||||
@@ -6095,7 +6142,7 @@ obj_val_begin:
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_nan(false, &cur, pre, val)) goto obj_val_end;
|
||||
}
|
||||
goto fail_literal;
|
||||
goto fail_literal_null;
|
||||
}
|
||||
if (char_is_space(*cur)) {
|
||||
while (char_is_space(*++cur));
|
||||
@@ -6106,13 +6153,13 @@ obj_val_begin:
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (read_inf_or_nan(false, &cur, pre, val)) goto obj_val_end;
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
}
|
||||
if (has_read_flag(ALLOW_COMMENTS)) {
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_val_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
|
||||
obj_val_end:
|
||||
if (likely(*cur == ',')) {
|
||||
@@ -6131,7 +6178,7 @@ obj_val_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_val_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_end;
|
||||
|
||||
obj_end:
|
||||
/* pop container */
|
||||
@@ -6174,17 +6221,41 @@ fail_string:
|
||||
fail_number:
|
||||
return_err(cur, INVALID_NUMBER, msg);
|
||||
fail_alloc:
|
||||
return_err(cur, MEMORY_ALLOCATION, "memory allocation failed");
|
||||
return_err(cur, MEMORY_ALLOCATION,
|
||||
"memory allocation failed");
|
||||
fail_trailing_comma:
|
||||
return_err(cur, JSON_STRUCTURE, "trailing comma is not allowed");
|
||||
fail_literal:
|
||||
return_err(cur, LITERAL, "invalid literal");
|
||||
return_err(cur, JSON_STRUCTURE,
|
||||
"trailing comma is not allowed");
|
||||
fail_literal_true:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'true'");
|
||||
fail_literal_false:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'false'");
|
||||
fail_literal_null:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'null'");
|
||||
fail_character_val:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a valid JSON value");
|
||||
fail_character_arr_end:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a comma or a closing bracket");
|
||||
fail_character_obj_key:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a string for object key");
|
||||
fail_character_obj_sep:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a colon after object key");
|
||||
fail_character_obj_end:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a comma or a closing brace");
|
||||
fail_comment:
|
||||
return_err(cur, INVALID_COMMENT, "unclosed multiline comment");
|
||||
fail_character:
|
||||
return_err(cur, UNEXPECTED_CHARACTER, "unexpected character");
|
||||
return_err(cur, INVALID_COMMENT,
|
||||
"unclosed multiline comment");
|
||||
fail_garbage:
|
||||
return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document");
|
||||
return_err(cur, UNEXPECTED_CONTENT,
|
||||
"unexpected content after document");
|
||||
|
||||
#undef val_incr
|
||||
#undef return_err
|
||||
@@ -6330,13 +6401,13 @@ arr_val_begin:
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (likely(read_true(&cur, val))) goto arr_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_true;
|
||||
}
|
||||
if (*cur == 'f') {
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (likely(read_false(&cur, val))) goto arr_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_false;
|
||||
}
|
||||
if (*cur == 'n') {
|
||||
val_incr();
|
||||
@@ -6345,7 +6416,7 @@ arr_val_begin:
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_nan(false, &cur, pre, val)) goto arr_val_end;
|
||||
}
|
||||
goto fail_literal;
|
||||
goto fail_literal_null;
|
||||
}
|
||||
if (*cur == ']') {
|
||||
cur++;
|
||||
@@ -6363,13 +6434,13 @@ arr_val_begin:
|
||||
val_incr();
|
||||
ctn_len++;
|
||||
if (read_inf_or_nan(false, &cur, pre, val)) goto arr_val_end;
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
}
|
||||
if (has_read_flag(ALLOW_COMMENTS)) {
|
||||
if (skip_spaces_and_comments(&cur)) goto arr_val_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
|
||||
arr_val_end:
|
||||
if (byte_match_2(cur, ",\n")) {
|
||||
@@ -6392,7 +6463,7 @@ arr_val_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto arr_val_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_arr_end;
|
||||
|
||||
arr_end:
|
||||
/* get parent container */
|
||||
@@ -6458,7 +6529,7 @@ obj_key_begin:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_key_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_key;
|
||||
|
||||
obj_key_end:
|
||||
if (byte_match_2(cur, ": ")) {
|
||||
@@ -6477,7 +6548,7 @@ obj_key_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_key_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_sep;
|
||||
|
||||
obj_val_begin:
|
||||
if (*cur == '"') {
|
||||
@@ -6504,13 +6575,13 @@ obj_val_begin:
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (likely(read_true(&cur, val))) goto obj_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_true;
|
||||
}
|
||||
if (*cur == 'f') {
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (likely(read_false(&cur, val))) goto obj_val_end;
|
||||
goto fail_literal;
|
||||
goto fail_literal_false;
|
||||
}
|
||||
if (*cur == 'n') {
|
||||
val++;
|
||||
@@ -6519,7 +6590,7 @@ obj_val_begin:
|
||||
if (has_read_flag(ALLOW_INF_AND_NAN)) {
|
||||
if (read_nan(false, &cur, pre, val)) goto obj_val_end;
|
||||
}
|
||||
goto fail_literal;
|
||||
goto fail_literal_null;
|
||||
}
|
||||
if (char_is_space(*cur)) {
|
||||
while (char_is_space(*++cur));
|
||||
@@ -6530,13 +6601,13 @@ obj_val_begin:
|
||||
val++;
|
||||
ctn_len++;
|
||||
if (read_inf_or_nan(false, &cur, pre, val)) goto obj_val_end;
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
}
|
||||
if (has_read_flag(ALLOW_COMMENTS)) {
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_val_begin;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_val;
|
||||
|
||||
obj_val_end:
|
||||
if (byte_match_2(cur, ",\n")) {
|
||||
@@ -6559,7 +6630,7 @@ obj_val_end:
|
||||
if (skip_spaces_and_comments(&cur)) goto obj_val_end;
|
||||
if (byte_match_2(cur, "/*")) goto fail_comment;
|
||||
}
|
||||
goto fail_character;
|
||||
goto fail_character_obj_end;
|
||||
|
||||
obj_end:
|
||||
/* pop container */
|
||||
@@ -6603,17 +6674,41 @@ fail_string:
|
||||
fail_number:
|
||||
return_err(cur, INVALID_NUMBER, msg);
|
||||
fail_alloc:
|
||||
return_err(cur, MEMORY_ALLOCATION, "memory allocation failed");
|
||||
return_err(cur, MEMORY_ALLOCATION,
|
||||
"memory allocation failed");
|
||||
fail_trailing_comma:
|
||||
return_err(cur, JSON_STRUCTURE, "trailing comma is not allowed");
|
||||
fail_literal:
|
||||
return_err(cur, LITERAL, "invalid literal");
|
||||
return_err(cur, JSON_STRUCTURE,
|
||||
"trailing comma is not allowed");
|
||||
fail_literal_true:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'true'");
|
||||
fail_literal_false:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'false'");
|
||||
fail_literal_null:
|
||||
return_err(cur, LITERAL,
|
||||
"invalid literal, expected a valid literal such as 'null'");
|
||||
fail_character_val:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a valid JSON value");
|
||||
fail_character_arr_end:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a comma or a closing bracket");
|
||||
fail_character_obj_key:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a string for object key");
|
||||
fail_character_obj_sep:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a colon after object key");
|
||||
fail_character_obj_end:
|
||||
return_err(cur, UNEXPECTED_CHARACTER,
|
||||
"unexpected character, expected a comma or a closing brace");
|
||||
fail_comment:
|
||||
return_err(cur, INVALID_COMMENT, "unclosed multiline comment");
|
||||
fail_character:
|
||||
return_err(cur, UNEXPECTED_CHARACTER, "unexpected character");
|
||||
return_err(cur, INVALID_COMMENT,
|
||||
"unclosed multiline comment");
|
||||
fail_garbage:
|
||||
return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document");
|
||||
return_err(cur, UNEXPECTED_CONTENT,
|
||||
"unexpected content after document");
|
||||
|
||||
#undef val_incr
|
||||
#undef return_err
|
||||
@@ -7835,7 +7930,7 @@ static const u8 esc_single_char_table[512] = {
|
||||
|
||||
/** Returns the encode table with options. */
|
||||
static_inline const char_enc_type *get_enc_table_with_flag(
|
||||
yyjson_read_flag flg) {
|
||||
yyjson_write_flag flg) {
|
||||
if (has_write_flag(ESCAPE_UNICODE)) {
|
||||
if (has_write_flag(ESCAPE_SLASHES)) {
|
||||
return enc_table_esc_slash;
|
||||
|
||||
Vendored
+21
-3
@@ -527,16 +527,16 @@ extern "C" {
|
||||
#define YYJSON_VERSION_MAJOR 0
|
||||
|
||||
/** The minor version of yyjson. */
|
||||
#define YYJSON_VERSION_MINOR 9
|
||||
#define YYJSON_VERSION_MINOR 10
|
||||
|
||||
/** The patch version of yyjson. */
|
||||
#define YYJSON_VERSION_PATCH 0
|
||||
|
||||
/** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */
|
||||
#define YYJSON_VERSION_HEX 0x000900
|
||||
#define YYJSON_VERSION_HEX 0x000A00
|
||||
|
||||
/** The version string of yyjson. */
|
||||
#define YYJSON_VERSION_STRING "0.9.0"
|
||||
#define YYJSON_VERSION_STRING "0.10.0"
|
||||
|
||||
/** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */
|
||||
yyjson_api uint32_t yyjson_version(void);
|
||||
@@ -841,6 +841,24 @@ typedef struct yyjson_read_err {
|
||||
size_t pos;
|
||||
} yyjson_read_err;
|
||||
|
||||
/**
|
||||
Locate the line and column number for a byte position in a string.
|
||||
This can be used to get better description for error position.
|
||||
|
||||
@param str The input string.
|
||||
@param len The byte length of the input string.
|
||||
@param pos The byte position within the input string.
|
||||
@param line A pointer to receive the line number, starting from 1.
|
||||
@param col A pointer to receive the column number, starting from 1.
|
||||
@param chr A pointer to receive the character index, starting from 0.
|
||||
@return true on success, false if `str` is NULL or `pos` is out of bounds.
|
||||
@note Line/column/character are calculated based on Unicode characters for
|
||||
compatibility with text editors. For multi-byte UTF-8 characters,
|
||||
the returned value may not directly correspond to the byte position.
|
||||
*/
|
||||
yyjson_api bool yyjson_locate_pos(const char *str, size_t len, size_t pos,
|
||||
size_t *line, size_t *col, size_t *chr);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -130,10 +130,7 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+47
-34
@@ -52,24 +52,28 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
* @param placeholderValue the string to parse
|
||||
* @return uint32_t the parsed value
|
||||
*/
|
||||
static uint32_t getArgumentIndex(const FFstrbuf* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
|
||||
static uint32_t getArgumentIndex(const char* placeholderValue, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
char firstChar = placeholderValue->chars[0];
|
||||
char firstChar = placeholderValue[0];
|
||||
if (firstChar == '\0')
|
||||
return 0; // use arg counter
|
||||
|
||||
if(firstChar >= '1' && firstChar <= '9')
|
||||
if (firstChar >= '0' && firstChar <= '9')
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
unsigned long result = strtoul(placeholderValue->chars, &pEnd, 10);
|
||||
if (pEnd != placeholderValue->chars + placeholderValue->length || result > numArgs)
|
||||
uint32_t result = (uint32_t) strtoul(placeholderValue, &pEnd, 10);
|
||||
if (result > numArgs)
|
||||
return UINT32_MAX;
|
||||
return (uint32_t) result;
|
||||
if (*pEnd != '\0')
|
||||
return UINT32_MAX;
|
||||
return result;
|
||||
}
|
||||
else if (ffCharIsEnglishAlphabet(firstChar))
|
||||
{
|
||||
for (uint32_t i = 0; i < numArgs; ++i)
|
||||
{
|
||||
const FFformatarg* arg = &arguments[i];
|
||||
if(arg->name && ffStrbufIgnCaseEqualS(placeholderValue, arg->name))
|
||||
if (arg->name && strcasecmp(placeholderValue, arg->name) == 0)
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
@@ -86,16 +90,6 @@ static inline void appendInvalidPlaceholder(FFstrbuf* buffer, const char* start,
|
||||
ffStrbufAppendC(buffer, '}');
|
||||
}
|
||||
|
||||
static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placeholder, uint32_t* argCounter, uint32_t numArgs, const FFformatarg* arguments)
|
||||
{
|
||||
if(*argCounter >= numArgs)
|
||||
ffStrbufAppendS(buffer, placeholder);
|
||||
else
|
||||
ffFormatAppendFormatArg(buffer, arguments + *argCounter);
|
||||
|
||||
(*argCounter)++;
|
||||
}
|
||||
|
||||
static inline bool formatArgSet(const FFformatarg* arg)
|
||||
{
|
||||
return arg->value != NULL && (
|
||||
@@ -128,13 +122,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have an { at the end handle it as {}
|
||||
if(i == formatstr->length - 1)
|
||||
{
|
||||
appendEmptyPlaceholder(buffer, "{", &argCounter, numArgs, arguments);
|
||||
continue;
|
||||
}
|
||||
|
||||
// jump to next char, the start of the placeholder value
|
||||
++i;
|
||||
|
||||
@@ -145,13 +132,6 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
// placeholder is {}
|
||||
if(formatstr->chars[i] == '}')
|
||||
{
|
||||
appendEmptyPlaceholder(buffer, "{}", &argCounter, numArgs, arguments);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufClear(&placeholderValue);
|
||||
|
||||
{
|
||||
@@ -205,7 +185,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
{
|
||||
ffStrbufSubstrAfter(&placeholderValue, 0);
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// testing for an invalid index
|
||||
if (index > numArgs)
|
||||
@@ -231,7 +211,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
{
|
||||
ffStrbufSubstrAfter(&placeholderValue, 0);
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// testing for an invalid index
|
||||
if (index > numArgs)
|
||||
@@ -264,16 +244,49 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(&placeholderValue, numArgs, arguments);
|
||||
int32_t truncLength = INT32_MAX;
|
||||
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
|
||||
if (pColon != NULL)
|
||||
{
|
||||
char* pEnd = NULL;
|
||||
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
|
||||
if (*pEnd != '\0')
|
||||
{
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
*pColon = '\0';
|
||||
}
|
||||
|
||||
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
|
||||
|
||||
// test for invalid index
|
||||
if (index == 0)
|
||||
index = ++argCounter;
|
||||
|
||||
if (index > numArgs)
|
||||
{
|
||||
if (pColon) *pColon = ':';
|
||||
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ellipsis = false;
|
||||
if (truncLength < 0)
|
||||
{
|
||||
ellipsis = true;
|
||||
truncLength = -truncLength;
|
||||
}
|
||||
|
||||
uint32_t oldLength = buffer->length;
|
||||
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
|
||||
if (buffer->length - oldLength > (uint32_t) truncLength)
|
||||
{
|
||||
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
if (ellipsis)
|
||||
ffStrbufAppendS(buffer, "…");
|
||||
}
|
||||
}
|
||||
|
||||
if (!instance.config.display.pipe)
|
||||
|
||||
@@ -254,9 +254,6 @@ void ffListFeatures(void)
|
||||
#ifdef FF_HAVE_DIRECTX_HEADERS
|
||||
"Directx Headers\n"
|
||||
#endif
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
"Proprietary GPU driver API\n"
|
||||
#endif
|
||||
#ifdef FF_USE_SYSTEM_YYJSON
|
||||
"System yyjson\n"
|
||||
#endif
|
||||
|
||||
+18
-8
@@ -8,11 +8,13 @@
|
||||
#include <handleapi.h>
|
||||
#include <io.h>
|
||||
typedef HANDLE FFNativeFD;
|
||||
#define FF_INVALID_FD INVALID_HANDLE_VALUE
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
typedef int FFNativeFD;
|
||||
#define FF_INVALID_FD (-1)
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
|
||||
@@ -99,17 +101,25 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
|
||||
|
||||
#else
|
||||
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
if (pathType == FF_PATHTYPE_ANY)
|
||||
{
|
||||
// Zero overhead
|
||||
return access(path, F_OK) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
|
||||
if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
|
||||
return true;
|
||||
if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
|
||||
return true;
|
||||
|
||||
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+46
-16
@@ -133,32 +133,44 @@ bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* o
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
if (instance.config.display.pipe)
|
||||
return "Not supported in --pipe mode";
|
||||
int fin = STDIN_FILENO, fout = STDOUT_FILENO;
|
||||
FF_AUTO_CLOSE_FD int ftty = -1;
|
||||
|
||||
struct termios oldTerm, newTerm;
|
||||
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
|
||||
if (!isatty(STDIN_FILENO))
|
||||
{
|
||||
if (ftty < 0)
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
fin = ftty;
|
||||
}
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
{
|
||||
if (ftty < 0)
|
||||
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
fout = ftty;
|
||||
}
|
||||
|
||||
struct termios oldTerm;
|
||||
if(tcgetattr(fin, &oldTerm) == -1)
|
||||
return "tcgetattr(STDIN_FILENO, &oldTerm) failed";
|
||||
|
||||
newTerm = oldTerm;
|
||||
struct termios newTerm = oldTerm;
|
||||
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
|
||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
|
||||
return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)";
|
||||
if(tcsetattr(fin, TCSAFLUSH, &newTerm) == -1)
|
||||
return "tcsetattr(STDIN_FILENO, TCSAFLUSH, &newTerm)";
|
||||
|
||||
fputs(request, stdout);
|
||||
fflush(stdout);
|
||||
ffWriteFDData(fout, strlen(request), request);
|
||||
|
||||
//Give the terminal 35ms to respond
|
||||
if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
//Give the terminal some time to respond
|
||||
if(poll(&(struct pollfd) { .fd = fin, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
tcsetattr(fin, TCSANOW, &oldTerm);
|
||||
return "poll() timeout or failed";
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
|
||||
ssize_t bytesRead = read(fin, buffer, sizeof(buffer) - 1);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
|
||||
tcsetattr(fin, TCSANOW, &oldTerm);
|
||||
|
||||
if(bytesRead <= 0)
|
||||
return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";
|
||||
@@ -204,7 +216,11 @@ bool ffSuppressIO(bool suppress)
|
||||
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
{
|
||||
DIR* dir = opendir(folder->chars);
|
||||
FF_AUTO_CLOSE_FD int dfd = open(folder->chars, O_RDONLY);
|
||||
if (dfd < 0)
|
||||
return;
|
||||
|
||||
DIR* dir = fdopendir(dfd);
|
||||
if(dir == NULL)
|
||||
return;
|
||||
|
||||
@@ -221,7 +237,21 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
|
||||
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(entry->d_type == DT_DIR)
|
||||
bool isDir = false;
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
|
||||
isDir = entry->d_type == DT_DIR;
|
||||
else
|
||||
#else
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
|
||||
isDir = false;
|
||||
else
|
||||
isDir = S_ISDIR(stbuf.st_mode);
|
||||
}
|
||||
#endif
|
||||
if (isDir)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
+57
-12
@@ -114,8 +114,40 @@ bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||
|
||||
bool ffSuppressIO(bool suppress)
|
||||
{
|
||||
(void) suppress; //Not implemented.
|
||||
return false;
|
||||
static bool init = false;
|
||||
static HANDLE hOrigOut = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hOrigErr = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hNullFile = INVALID_HANDLE_VALUE;
|
||||
static int fOrigOut = -1;
|
||||
static int fOrigErr = -1;
|
||||
static int fNullFile = -1;
|
||||
|
||||
if (!init)
|
||||
{
|
||||
if(!suppress)
|
||||
return true;
|
||||
|
||||
hOrigOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hOrigErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
hNullFile = CreateFileW(L"NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
fOrigOut = _dup(STDOUT_FILENO);
|
||||
fOrigErr = _dup(STDERR_FILENO);
|
||||
fNullFile = _open_osfhandle((intptr_t) hNullFile, 0);
|
||||
|
||||
init = true;
|
||||
}
|
||||
if (hNullFile == INVALID_HANDLE_VALUE || fNullFile == -1)
|
||||
return false;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, suppress ? hNullFile : hOrigOut);
|
||||
SetStdHandle(STD_ERROR_HANDLE, suppress ? hNullFile : hOrigErr);
|
||||
_dup2(suppress ? fNullFile : fOrigOut, STDOUT_FILENO);
|
||||
_dup2(suppress ? fNullFile : fOrigErr, STDERR_FILENO);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indentation, const char* folderName, bool pretty)
|
||||
@@ -175,24 +207,37 @@ void ffListFilesRecursively(const char* path, bool pretty)
|
||||
|
||||
const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
{
|
||||
if (instance.config.display.pipe)
|
||||
return "Not supported in --pipe mode";
|
||||
|
||||
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD prev_mode;
|
||||
GetConsoleMode(hInput, &prev_mode);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConin = INVALID_HANDLE_VALUE;
|
||||
DWORD inputMode;
|
||||
if (!GetConsoleMode(hInput, &inputMode))
|
||||
{
|
||||
hConin = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, NULL);
|
||||
hInput = hConin;
|
||||
}
|
||||
SetConsoleMode(hInput, 0);
|
||||
|
||||
FlushConsoleInputBuffer(hInput);
|
||||
|
||||
DWORD bytes = 0;
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), request, (DWORD) strlen(request), &bytes, NULL);
|
||||
{
|
||||
DWORD bytes = 0;
|
||||
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
||||
DWORD outputMode;
|
||||
if (!GetConsoleMode(hOutput, &outputMode))
|
||||
{
|
||||
hConout = CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
||||
hOutput = hConout;
|
||||
}
|
||||
WriteFile(hOutput, "TEST\n", 5, &bytes, NULL);
|
||||
WriteFile(hOutput, request, (DWORD) strlen(request), &bytes, NULL);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (WaitForSingleObjectEx(hInput, FF_IO_TERM_RESP_WAIT_MS, TRUE) != WAIT_OBJECT_0)
|
||||
{
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
SetConsoleMode(hInput, inputMode);
|
||||
return "WaitForSingleObject() failed or timeout";
|
||||
}
|
||||
|
||||
@@ -213,10 +258,10 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
|
||||
}
|
||||
|
||||
char buffer[512];
|
||||
bytes = 0;
|
||||
DWORD bytes = 0;
|
||||
ReadFile(hInput, buffer, sizeof(buffer) - 1, &bytes, NULL);
|
||||
|
||||
SetConsoleMode(hInput, prev_mode);
|
||||
SetConsoleMode(hInput, inputMode);
|
||||
|
||||
if(bytes <= 0)
|
||||
return "ReadFile() failed";
|
||||
|
||||
@@ -213,10 +213,7 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
|
||||
{
|
||||
char str[32];
|
||||
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
|
||||
if(instance.config.display.pipe)
|
||||
puts(str);
|
||||
else
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ static FFModuleBaseInfo* D[] = {
|
||||
(void*) &instance.config.modules.display,
|
||||
(void*) &instance.config.modules.disk,
|
||||
(void*) &instance.config.modules.diskIo,
|
||||
(void*) &instance.config.modules.dns,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||
#elif defined(__OpenBSD__)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), sizeof(int))
|
||||
#elif defined(__sun)
|
||||
# define ROUNDUP(a) ROUNDUP2((a), _SS_ALIGNSIZE)
|
||||
#else
|
||||
# error unknown platform
|
||||
#endif
|
||||
@@ -31,9 +33,13 @@ get_rt_address(struct rt_msghdr *rtm, int desired)
|
||||
{
|
||||
if (rtm->rtm_addrs & (1 << i))
|
||||
{
|
||||
if ((1 <<i ) == desired)
|
||||
if ((1 << i) == desired)
|
||||
return sa;
|
||||
#ifdef __sun
|
||||
sa = (struct sockaddr *)(ROUNDUP(sizeof(struct sockaddr)) + (char *)sa);
|
||||
#else
|
||||
sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -71,7 +77,9 @@ bool ffNetifGetDefaultRouteImpl(char iface[IF_NAMESIZE + 1], uint32_t* ifIndex)
|
||||
},
|
||||
.dst = {
|
||||
.sin_family = AF_INET,
|
||||
#ifndef __sun
|
||||
.sin_len = sizeof(rtmsg.dst),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -148,6 +148,14 @@ bool ffOptionParseBoolean(const char* str)
|
||||
|
||||
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
|
||||
{
|
||||
// If value is already an ANSI escape code, use it
|
||||
if (value[0] == '\e' && value[1] == '[')
|
||||
{
|
||||
ffStrbufAppendS(buffer, value + 2);
|
||||
ffStrbufTrimRight(buffer, 'm');
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufEnsureFree(buffer, 63);
|
||||
|
||||
while(*value != '\0')
|
||||
|
||||
@@ -64,7 +64,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
if(!instance.config.display.pipe)
|
||||
{
|
||||
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
|
||||
if (moduleArgs->outputColor.length)
|
||||
if (moduleArgs && moduleArgs->outputColor.length)
|
||||
ffPrintColor(&moduleArgs->outputColor);
|
||||
else if (instance.config.display.colorOutput.length)
|
||||
ffPrintColor(&instance.config.display.colorOutput);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
typedef enum FFPrintType {
|
||||
FF_PRINT_TYPE_DEFAULT = 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY = 1 << 0, // key has been formatted outside
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR = 1 << 1,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH = 1 << 2,
|
||||
FF_PRINT_TYPE_NO_CUSTOM_OUTPUT_FORMAT = 1 << 3, // reserved
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
#include <sys/user.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__)
|
||||
#include <libproc.h>
|
||||
#elif defined(__sun)
|
||||
#include <procfs.h>
|
||||
#endif
|
||||
|
||||
enum { FF_PIPE_BUFSIZ = 8192 };
|
||||
@@ -234,6 +236,29 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
|
||||
ffStrbufSetS(exe, arg0);
|
||||
}
|
||||
|
||||
#elif defined(__sun)
|
||||
|
||||
char filePath[PATH_MAX];
|
||||
snprintf(filePath, sizeof(filePath), "/proc/%d/psinfo", (int) pid);
|
||||
psinfo_t proc;
|
||||
if (ffReadFileData(filePath, sizeof(proc), &proc) == sizeof(proc))
|
||||
{
|
||||
ffStrbufSetS(exe, proc.pr_psargs);
|
||||
ffStrbufSubstrBeforeFirstC(exe, ' ');
|
||||
}
|
||||
|
||||
if (exePath)
|
||||
{
|
||||
snprintf(filePath, sizeof(filePath), "/proc/%d/path/a.out", (int) pid);
|
||||
ffStrbufEnsureFixedLengthFree(exePath, PATH_MAX);
|
||||
ssize_t length = readlink(filePath, exePath->chars, exePath->allocated - 1);
|
||||
if (length > 0) // doesn't contain trailing NUL
|
||||
{
|
||||
exePath->chars[length] = '\0';
|
||||
exePath->length = (uint32_t) length;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(exe->length == 0)
|
||||
@@ -335,6 +360,19 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
|
||||
*tty = -1;
|
||||
}
|
||||
|
||||
#elif defined(__sun)
|
||||
char path[128];
|
||||
snprintf(path, sizeof(path), "/proc/%d/psinfo", (int) pid);
|
||||
psinfo_t proc;
|
||||
if (ffReadFileData(path, sizeof(proc), &proc) != sizeof(proc))
|
||||
return "ffReadFileData(psinfo) failed";
|
||||
|
||||
ffStrbufSetS(name, proc.pr_fname);
|
||||
if (ppid)
|
||||
*ppid = proc.pr_ppid;
|
||||
if (tty)
|
||||
*tty = (int) proc.pr_ttydev;
|
||||
|
||||
#else
|
||||
|
||||
return "Unsupported platform";
|
||||
|
||||
+62
-25
@@ -148,13 +148,23 @@
|
||||
"false": "Try `wayland`, then `x11`, then `drm`"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "detect-version",
|
||||
"desc": "Whether to detect and display the version of terminal, shell and editor",
|
||||
"remark": "Mainly for benchmarking",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Logo": [
|
||||
{
|
||||
"short": "l",
|
||||
"long": "logo",
|
||||
"desc": "Set the logo source",
|
||||
"desc": "Set the logo source. Use \"none\" to disable the logo",
|
||||
"remark": "Should be the name of a builtin logo, or a path to an image file. See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
|
||||
"arg": {
|
||||
"type": "logo"
|
||||
@@ -257,12 +267,15 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "logo-separate",
|
||||
"desc": "If true, print modules at bottom of the logo",
|
||||
"long": "logo-position",
|
||||
"desc": "Set the position of the logo should be displayed",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": false
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"left": "Left",
|
||||
"top": "Top",
|
||||
"right": "Right"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -438,7 +451,7 @@
|
||||
},
|
||||
{
|
||||
"long": "pipe",
|
||||
"desc": "Disable logo and all escape sequences",
|
||||
"desc": "Disable colors",
|
||||
"remark": "Auto detection based on isatty(1)",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
@@ -722,26 +735,9 @@
|
||||
"type": "color",
|
||||
"default": "light_red"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "ts-version",
|
||||
"desc": "Whether to detect and display the version of terminal and shell",
|
||||
"remark": "Mainly for benchmarking",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"Library path": [
|
||||
{
|
||||
"long": "lib-pci",
|
||||
"desc": "Pciutils. Used for GPU output",
|
||||
"arg": {
|
||||
"type": "path"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "lib-vulkan",
|
||||
"desc": "Vulkan module & fallback for GPU output",
|
||||
@@ -1251,7 +1247,8 @@
|
||||
"enum": {
|
||||
"auto": "Query platform specific graphic APIs. Requires proper GPU drivers installed. Not supported on FreeBSD",
|
||||
"pci": "Search PCI devices, which do not requires GPU driver installed. Not supported on Windows and macOS",
|
||||
"vulkan": "Use Vulkan API. Slow and requires vulkan driver installed. Used for Android",
|
||||
"vulkan": "Use Vulkan API. Slow and requires proper vulkan driver installed. Used for Android",
|
||||
"opencl": "Use OpenCL API. Slow and requires proper OpenCL driver installed",
|
||||
"opengl": "Use OpenGL API. Slow and only detects one GPU"
|
||||
},
|
||||
"default": "auto"
|
||||
@@ -1287,6 +1284,15 @@
|
||||
"default": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "loadavg-compact",
|
||||
"desc": "Show load average values in one line",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "localip-show-ipv4",
|
||||
"desc": "Show IPv4 addresses in local ip module",
|
||||
@@ -1367,6 +1373,19 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "dns-show-type",
|
||||
"desc": "Specify the type of DNS servers should be detected",
|
||||
"arg": {
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"ipv4": "Show IPv4 addresses only",
|
||||
"ipv6": "Show IPv6 addresses only",
|
||||
"both": "Show both IPv4 and IPv6 addresses"
|
||||
},
|
||||
"default": "both"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "netio-name-prefix",
|
||||
"desc": "Show interfaces with given name prefix only",
|
||||
@@ -1450,6 +1469,24 @@
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "users-compact",
|
||||
"desc": "Show all active users in one line",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "users-myself-only",
|
||||
"desc": "Show only current user",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "player-name",
|
||||
"desc": "The name of the player to use for module Media and Player",
|
||||
|
||||
@@ -8,6 +8,11 @@ In 2.14.0 or newer, the value indices can be meaningful named tags.
|
||||
For example: "--title-format '{user-name-colored}{at-symbol-colored}{host-name-colored}'" is equivalent to "--title-format '{6}{7}{8}'"
|
||||
See "fastfetch -h title-format" for all supported tags.
|
||||
|
||||
In 2.17.0 or newer, a truncation length can be specified using syntax '<arg>:<trunc-length>`
|
||||
For example: "--title-format '{user-name:5}'" will truncate user name into 5-length string.
|
||||
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
|
||||
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
|
||||
|
||||
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
|
||||
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
|
||||
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
|
||||
|
||||
@@ -33,7 +33,7 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option
|
||||
|
||||
//capacity must exist and be not empty
|
||||
ffStrbufAppendS(dir, "/capacity");
|
||||
bool available = ffReadFileBuffer(dir->chars, &tmpBuffer);
|
||||
bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); // This is expensive in my laptop
|
||||
ffStrbufSubstrBefore(dir, dirLength);
|
||||
|
||||
if (!available)
|
||||
|
||||
@@ -172,7 +172,7 @@ typedef struct FFSmbiosPortableBattery
|
||||
static_assert(offsetof(FFSmbiosPortableBattery, OEMSpecific) == 0x16,
|
||||
"FFSmbiosPortableBattery: Wrong struct alignment");
|
||||
|
||||
const char* detectBySmbios(FFBatteryResult* battery)
|
||||
static const char* detectBySmbios(FFBatteryResult* battery)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "bios.h"
|
||||
|
||||
const char* ffDetectBios(FFBiosResult* bios)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "bios.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
#include <ntstatus.h>
|
||||
@@ -25,7 +27,7 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
||||
};
|
||||
};
|
||||
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct FFSmbiosBios
|
||||
{
|
||||
@@ -74,6 +76,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
if (data->Header.Length > offsetof(FFSmbiosBios, SystemBiosMajorRelease))
|
||||
ffStrbufSetF(&bios->release, "%u.%u", data->SystemBiosMajorRelease, data->SystemBiosMinorRelease);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Same as GetFirmwareType, but support (?) Windows 7
|
||||
// https://ntdoc.m417z.com/system_information_class
|
||||
SYSTEM_BOOT_ENVIRONMENT_INFORMATION sbei;
|
||||
@@ -86,6 +89,7 @@ const char* ffDetectBios(FFBiosResult* bios)
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "camera.h"
|
||||
|
||||
const char* ffDetectCamera(FF_MAYBE_UNUSED FFlist* result)
|
||||
{
|
||||
return "Not support on this platform";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "cpu.h"
|
||||
|
||||
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "cpu.h"
|
||||
#include <kstat.h>
|
||||
|
||||
static inline void kstatFreeWrap(kstat_ctl_t** pkc)
|
||||
{
|
||||
assert(pkc);
|
||||
if (*pkc)
|
||||
kstat_close(*pkc);
|
||||
}
|
||||
|
||||
const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
{
|
||||
__attribute__((__cleanup__(kstatFreeWrap))) kstat_ctl_t* kc = kstat_open();
|
||||
if (!kc)
|
||||
return "kstat_open() failed";
|
||||
|
||||
kstat_t* ks = kstat_lookup(kc, "cpu_info", -1, NULL);
|
||||
if (!ks)
|
||||
return "kstat_lookup() failed";
|
||||
|
||||
if (kstat_read(kc, ks, NULL) < 0)
|
||||
return "kstat_read() failed";
|
||||
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "brand");
|
||||
ffStrbufSetNS(&cpu->name, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id");
|
||||
ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn));
|
||||
}
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
|
||||
cpu->frequencyBase = kn->value.ui32 / 1000.;
|
||||
}
|
||||
|
||||
ks = kstat_lookup(kc, "unix", -1, "system_misc");
|
||||
if (ks && kstat_read(kc, ks, NULL) >= 0)
|
||||
{
|
||||
kstat_named_t* kn = kstat_data_lookup(ks, "ncpus");
|
||||
cpu->coresLogical = cpu->coresPhysical = cpu->coresOnline = (uint16_t) kn->value.ui32;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ static const char* parseCpuCacheIndex(FFstrbuf* path, FFCPUCacheResult* result,
|
||||
|
||||
// deduplicate shared caches
|
||||
ffStrbufAppendF(buffer, "_%u_%u_%u_%u\n", level, sizeKb, lineSize, cacheType);
|
||||
if (ffStrbufContain(added, buffer)) return "cache already added";
|
||||
if (ffStrbufContain(added, buffer)) return NULL;
|
||||
ffStrbufAppend(added, buffer);
|
||||
ffCPUCacheAddItem(result, level, sizeKb * 1024, lineSize, cacheType);
|
||||
return NULL;
|
||||
@@ -71,7 +71,8 @@ static const char* parseCpuCache(FFstrbuf* path, FFCPUCacheResult* result, FFstr
|
||||
|| !ffCharIsDigit(pathCacheEntry->d_name[strlen("index")])) continue;
|
||||
|
||||
ffStrbufAppendS(path, pathCacheEntry->d_name);
|
||||
parseCpuCacheIndex(path, result, buffer, added);
|
||||
const char* error = parseCpuCacheIndex(path, result, buffer, added);
|
||||
if (error) return error;
|
||||
ffStrbufSubstrBefore(path, baseLen);
|
||||
}
|
||||
|
||||
@@ -97,7 +98,8 @@ const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
||||
!ffCharIsDigit(pathCpuEntry->d_name[strlen("cpu")])) continue;
|
||||
|
||||
ffStrbufAppendS(&path, pathCpuEntry->d_name);
|
||||
parseCpuCache(&path, result, &buffer, &added);
|
||||
const char* error = parseCpuCache(&path, result, &buffer, &added);
|
||||
if (error) return error;
|
||||
ffStrbufSubstrBefore(&path, baseLen);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "cpucache.h"
|
||||
#include "common/sysctl.h"
|
||||
|
||||
const char* ffDetectCPUCache(FF_MAYBE_UNUSED FFCPUCacheResult* result)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "cpucache.h"
|
||||
#include "util/smbiosHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
typedef struct FFSmbiosCacheInfo
|
||||
{
|
||||
FFSmbiosHeader Header;
|
||||
|
||||
uint8_t SocketDesignation; // string
|
||||
uint16_t CacheConfiguration; // varies
|
||||
uint16_t MaximumCacheSize; // varies
|
||||
uint16_t InstalledSize; // varies
|
||||
uint16_t SupportedSramType; // bit field
|
||||
uint16_t CurrentSramType; // bit field
|
||||
|
||||
// 2.1+
|
||||
uint8_t CacheSpeed; // varies
|
||||
uint8_t ErrorCorrectionType; // enum
|
||||
uint8_t SystemCacheType; // enum
|
||||
uint8_t Associativity; // enum
|
||||
|
||||
// 3.1+
|
||||
uint32_t MaximumCacheSize2; // bit field
|
||||
uint32_t InstalledCacheSize2; // bit field
|
||||
} __attribute__((__packed__)) FFSmbiosCacheInfo;
|
||||
|
||||
static_assert(offsetof(FFSmbiosCacheInfo, InstalledCacheSize2) == 0x17,
|
||||
"FFSmbiosCacheInfo: Wrong struct alignment");
|
||||
|
||||
const char* ffDetectCPUCache(FFCPUCacheResult* result)
|
||||
{
|
||||
const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable();
|
||||
if (!smbiosTable)
|
||||
return "Failed to get SMBIOS data";
|
||||
|
||||
const FFSmbiosCacheInfo* data = (const FFSmbiosCacheInfo*) (*smbiosTable)[FF_SMBIOS_TYPE_CACHE_INFO];
|
||||
if (!data)
|
||||
return "Cache information is not found in SMBIOS data";
|
||||
|
||||
for (; data->Header.Type == FF_SMBIOS_TYPE_CACHE_INFO;
|
||||
data = (const FFSmbiosCacheInfo*) ffSmbiosNextEntry(&data->Header))
|
||||
{
|
||||
bool enabled = !!(data->CacheConfiguration & (1 << 7));
|
||||
if (!enabled)
|
||||
continue;
|
||||
|
||||
uint32_t size = data->InstalledSize;
|
||||
if (size == 0)
|
||||
continue;
|
||||
|
||||
if (data->InstalledSize != 0xFFFF)
|
||||
{
|
||||
size *= (size >> 15 ? 64 : 1) * 1024u;
|
||||
}
|
||||
else if (data->Header.Length > offsetof(FFSmbiosCacheInfo, InstalledCacheSize2))
|
||||
{
|
||||
size = data->InstalledCacheSize2;
|
||||
size *= (size >> 31 ? 64 : 1) * 1024u;
|
||||
}
|
||||
|
||||
uint32_t level = (data->CacheConfiguration & 0b111u) + 1;
|
||||
|
||||
FFCPUCacheType type;
|
||||
switch (data->SystemCacheType)
|
||||
{
|
||||
case 3: type = FF_CPU_CACHE_TYPE_INSTRUCTION; break;
|
||||
case 4: type = FF_CPU_CACHE_TYPE_DATA; break;
|
||||
default: type = FF_CPU_CACHE_TYPE_UNIFIED; break;
|
||||
}
|
||||
|
||||
ffCPUCacheAddItem(result, level, size, 0, type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -23,12 +23,12 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
uint64_t* cpTime = cpTimes[i];
|
||||
uint64_t inUse = cpTime[CP_USER] + cpTime[CP_NICE] + cpTime[CP_SYS];
|
||||
uint64_t total = cpTime[CP_INTR] + cpTime[CP_IDLE];
|
||||
uint64_t total = inUse + cpTime[CP_INTR] + cpTime[CP_IDLE];
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = (uint64_t)inUse,
|
||||
.totalAll = (uint64_t)total,
|
||||
.inUseAll = inUse,
|
||||
.totalAll = total,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = (uint64_t)inUse,
|
||||
.totalAll = (uint64_t)total,
|
||||
.inUseAll = inUse,
|
||||
.totalAll = total,
|
||||
};
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/cpuusage/cpuusage.h"
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
return "Not support on this platform";
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "fastfetch.h"
|
||||
#include "detection/cpuusage/cpuusage.h"
|
||||
|
||||
#include <kstat.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
static inline void kstatFreeWrap(kstat_ctl_t** pkc)
|
||||
{
|
||||
assert(pkc);
|
||||
if (*pkc)
|
||||
kstat_close(*pkc);
|
||||
}
|
||||
|
||||
const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
{
|
||||
__attribute__((__cleanup__(kstatFreeWrap))) kstat_ctl_t* kc = kstat_open();
|
||||
if (!kc)
|
||||
return "kstat_open() failed";
|
||||
|
||||
for (int i = 0;; ++i)
|
||||
{
|
||||
kstat_t* ks = kstat_lookup(kc, "cpu_stat", i, NULL);
|
||||
|
||||
cpu_stat_t cs;
|
||||
if (!ks || kstat_read(kc, ks, &cs) < 0)
|
||||
break;
|
||||
|
||||
uint64_t inUse = cs.cpu_sysinfo.cpu[CPU_USER] + cs.cpu_sysinfo.cpu[CPU_KERNEL];
|
||||
uint64_t total = inUse + cs.cpu_sysinfo.cpu[CPU_IDLE] + cs.cpu_sysinfo.cpu[CPU_WAIT];
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = inUse,
|
||||
.totalAll = total,
|
||||
};
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -31,8 +31,8 @@ const char* ffGetCpuUsageInfo(FFlist* cpuTimes)
|
||||
|
||||
FFCpuUsageInfo* info = (FFCpuUsageInfo*) ffListAdd(cpuTimes);
|
||||
*info = (FFCpuUsageInfo) {
|
||||
.inUseAll = (uint64_t)inUse,
|
||||
.totalAll = (uint64_t)total,
|
||||
.inUseAll = inUse,
|
||||
.totalAll = total,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,20 @@ static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
|
||||
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||
ffStrbufSetS(result, getenv("CINNAMON_VERSION"));
|
||||
|
||||
if (result->length == 0)
|
||||
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
|
||||
|
||||
if (result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
"cinnamon",
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL) // Cinnamon 6.2.2
|
||||
ffStrbufSubstrAfterLastC(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
static void getMate(FFstrbuf* result, FFDEOptions* options)
|
||||
@@ -167,6 +180,8 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
|
||||
|
||||
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
if (!instance.config.general.detectVersion) return "Disabled by config";
|
||||
|
||||
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
|
||||
getKDE(result, options);
|
||||
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "disk.h"
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "disk.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mnttab.h>
|
||||
|
||||
static bool isPhysicalDevice(const struct mnttab* device)
|
||||
{
|
||||
//Always show the root path
|
||||
if(ffStrEquals(device->mnt_mountp, "/"))
|
||||
return true;
|
||||
|
||||
if(ffStrEquals(device->mnt_special, "none"))
|
||||
return false;
|
||||
|
||||
//ZFS pool
|
||||
if(ffStrEquals(device->mnt_fstype, "zfs"))
|
||||
return true;
|
||||
|
||||
//Pseudo filesystems don't have a device in /dev
|
||||
if(!ffStrStartsWith(device->mnt_special, "/dev/"))
|
||||
return false;
|
||||
|
||||
struct stat deviceStat;
|
||||
if(stat(device->mnt_special, &deviceStat) != 0)
|
||||
return false;
|
||||
|
||||
//Ignore all devices that are not block devices
|
||||
if(!S_ISBLK(deviceStat.st_mode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
|
||||
{
|
||||
if(ffStrbufEqualS(¤tDisk->filesystem, "zfs"))
|
||||
{
|
||||
//ZFS subvolumes
|
||||
uint32_t index = ffStrbufFirstIndexC(¤tDisk->mountFrom, '/');
|
||||
if (index == currentDisk->mountFrom.length)
|
||||
return false;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
const FFDisk* otherDevice = ffListGet(disks, i);
|
||||
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Filter all disks which device was already found. This catches BTRFS subvolumes.
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
const FFDisk* otherDevice = ffListGet(disks, i);
|
||||
|
||||
if(ffStrbufEqual(¤tDisk->mountFrom, &otherDevice->mountFrom))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mnttab* device)
|
||||
{
|
||||
if(ffStrContains(device->mnt_mntopts, MNTOPT_NOBROWSE))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(isSubvolume(disks, currentDisk))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||
else
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
|
||||
static void detectStats(FFDisk* disk)
|
||||
{
|
||||
struct statvfs fs;
|
||||
if(statvfs(disk->mountpoint.chars, &fs) != 0)
|
||||
memset(&fs, 0, sizeof(struct statvfs));
|
||||
|
||||
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
|
||||
disk->bytesFree = fs.f_bfree * fs.f_frsize;
|
||||
disk->bytesAvailable = fs.f_bavail * fs.f_frsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
|
||||
if(fs.f_flag & ST_RDONLY)
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
|
||||
ffStrbufSetS(&disk->name, fs.f_fstr);
|
||||
|
||||
disk->createTime = 0;
|
||||
struct stat deviceStat;
|
||||
if(stat(disk->mountpoint.chars, &deviceStat) == 0)
|
||||
disk->createTime = (uint64_t) deviceStat.st_ctim.tv_sec * 1000 + (uint64_t) deviceStat.st_ctim.tv_nsec / 1000000000;
|
||||
}
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* mountsFile = fopen(MNTTAB, "r");
|
||||
if(mountsFile == NULL)
|
||||
return "fopen(\"" MNTTAB "\", \"r\") == NULL";
|
||||
|
||||
struct mnttab device;
|
||||
|
||||
while (getmntent(mountsFile, &device) == 0)
|
||||
{
|
||||
if (__builtin_expect(options->folders.length, 0))
|
||||
{
|
||||
if (!ffDiskMatchMountpoint(options, device.mnt_mountp))
|
||||
continue;
|
||||
}
|
||||
else if(!isPhysicalDevice(&device))
|
||||
continue;
|
||||
|
||||
//We have a valid device, add it to the list
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
disk->type = FF_DISK_VOLUME_TYPE_NONE;
|
||||
ffStrbufInitS(&disk->mountFrom, device.mnt_special);
|
||||
ffStrbufInitS(&disk->mountpoint, device.mnt_mountp);
|
||||
ffStrbufInitS(&disk->filesystem, device.mnt_fstype);
|
||||
ffStrbufInit(&disk->name);
|
||||
detectType(disks, disk, &device);
|
||||
detectStats(disk);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "diskio.h"
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "diskio.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include <kstat.h>
|
||||
|
||||
static inline void kstatFreeWrap(kstat_ctl_t** pkc)
|
||||
{
|
||||
assert(pkc);
|
||||
if (*pkc)
|
||||
kstat_close(*pkc);
|
||||
}
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
__attribute__((__cleanup__(kstatFreeWrap))) kstat_ctl_t* kc = kstat_open();
|
||||
if (!kc)
|
||||
return "kstat_open() failed";
|
||||
|
||||
for (kstat_t* ks = kc->kc_chain; ks; ks = ks->ks_next)
|
||||
{
|
||||
if (ks->ks_type != KSTAT_TYPE_IO || !ffStrEquals(ks->ks_class, "disk")) continue;
|
||||
|
||||
if (options->namePrefix.length && strncmp(ks->ks_name, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||
continue;
|
||||
|
||||
kstat_io_t kio;
|
||||
if (kstat_read(kc, ks, &kio) < 0)
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitS(&device->devPath, ks->ks_name);
|
||||
device->bytesRead = kio.nread;
|
||||
device->readCount = kio.reads;
|
||||
device->bytesWritten = kio.nwritten;
|
||||
device->writeCount = kio.writes;
|
||||
ffStrbufInitS(&device->name, ks->ks_name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
#define FF_DE_PRETTY_CINNAMON "Cinnamon"
|
||||
#define FF_DE_PRETTY_MATE "Mate"
|
||||
#define FF_DE_PRETTY_LXDE "LXDE"
|
||||
#define FF_DE_PRETTY_LXQT "LXQT"
|
||||
#define FF_DE_PRETTY_LXQT "LXQt"
|
||||
#define FF_DE_PRETTY_BUDGIE "Budgie"
|
||||
#define FF_DE_PRETTY_CDE "CDE"
|
||||
#define FF_DE_PRETTY_UNITY "Unity"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <dirent.h>
|
||||
|
||||
static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
@@ -85,6 +86,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FF_HAVE_DRM
|
||||
|
||||
@@ -369,5 +371,7 @@ void ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
drmParseSysfs(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "wayland.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate)
|
||||
{
|
||||
@@ -35,6 +36,39 @@ static void waylandOutputGeometryListener(void *data,
|
||||
display->transform = (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
static void handleXdgLogicalSize(void *data, FF_MAYBE_UNUSED struct zxdg_output_v1 *_, int32_t width, FF_MAYBE_UNUSED int32_t height)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
// Seems the values are only useful when ractional scale is enabled
|
||||
if (width < display->width)
|
||||
{
|
||||
display->scale = (double) display->width / width;
|
||||
}
|
||||
}
|
||||
|
||||
// Dirty hack for #477
|
||||
// The order of these callbacks MUST follow `struct wl_output_listener`
|
||||
static void* outputListener[] = {
|
||||
waylandOutputGeometryListener, // geometry
|
||||
waylandOutputModeListener, // mode
|
||||
stubListener, // done
|
||||
waylandOutputScaleListener, // scale
|
||||
ffWaylandOutputNameListener, // name
|
||||
ffWaylandOutputDescriptionListener, // description
|
||||
};
|
||||
static_assert(
|
||||
sizeof(outputListener) >= sizeof(struct wl_output_listener),
|
||||
"sizeof(outputListener) is too small. Please report it to fastfetch github issue"
|
||||
);
|
||||
|
||||
static struct zxdg_output_v1_listener zxdgOutputListener = {
|
||||
.logical_position = (void*) stubListener,
|
||||
.logical_size = handleXdgLogicalSize,
|
||||
.done = (void*) stubListener,
|
||||
.name = (void*) ffWaylandOutputNameListener,
|
||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||
};
|
||||
|
||||
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, wldata->ffwl_output_interface, version, name, wldata->ffwl_output_interface->name, version, NULL);
|
||||
@@ -54,23 +88,21 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
.edidName = ffStrbufCreate(),
|
||||
};
|
||||
|
||||
// Dirty hack for #477
|
||||
// The order of these callbacks MUST follow `struct wl_output_listener`
|
||||
void* outputListener[] = {
|
||||
waylandOutputGeometryListener, // geometry
|
||||
waylandOutputModeListener, // mode
|
||||
stubListener, // done
|
||||
waylandOutputScaleListener, // scale
|
||||
ffWaylandOutputNameListener, // name
|
||||
ffWaylandOutputDescriptionListener, // description
|
||||
};
|
||||
static_assert(
|
||||
sizeof(outputListener) >= sizeof(struct wl_output_listener),
|
||||
"sizeof(outputListener) is too small. Please report it to fastfetch github issue"
|
||||
);
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
|
||||
if (wldata->zxdgOutputManager)
|
||||
{
|
||||
struct wl_proxy* zxdgOutput = wldata->ffwl_proxy_marshal_constructor_versioned(wldata->zxdgOutputManager, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, version, NULL, output);
|
||||
|
||||
if (zxdgOutput)
|
||||
{
|
||||
wldata->ffwl_proxy_add_listener(zxdgOutput, (void(**)(void)) &zxdgOutputListener, &display);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
wldata->ffwl_proxy_destroy(zxdgOutput);
|
||||
}
|
||||
}
|
||||
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
if(display.width <= 0 || display.height <= 0)
|
||||
@@ -124,7 +156,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
0
|
||||
display.id
|
||||
);
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
@@ -132,4 +164,13 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
|
||||
ffStrbufDestroy(&display.edidName);
|
||||
}
|
||||
|
||||
void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL);
|
||||
if(manager == NULL)
|
||||
return;
|
||||
|
||||
wldata->zxdgOutputManager = manager;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,845 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
|
||||
#define KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_kde_output_device_v2 The kde_output_device_v2 protocol
|
||||
* @section page_ifaces_kde_output_device_v2 Interfaces
|
||||
* - @subpage page_iface_kde_output_device_v2 - output configuration representation
|
||||
* - @subpage page_iface_kde_output_device_mode_v2 - output mode
|
||||
* @section page_copyright_kde_output_device_v2 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
|
||||
* SPDX-FileCopyrightText: 2010-2011 Intel Corporation
|
||||
* SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd.
|
||||
* SPDX-FileCopyrightText: 2015 Sebastian Kügler <sebas@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Méven Car <meven.car@enioka.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT-CMU
|
||||
* </pre>
|
||||
*/
|
||||
struct kde_output_device_mode_v2;
|
||||
struct kde_output_device_v2;
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_INTERFACE
|
||||
#define KDE_OUTPUT_DEVICE_V2_INTERFACE
|
||||
/**
|
||||
* @page page_iface_kde_output_device_v2 kde_output_device_v2
|
||||
* @section page_iface_kde_output_device_v2_desc Description
|
||||
*
|
||||
* An output device describes a display device available to the compositor.
|
||||
* output_device is similar to wl_output, but focuses on output
|
||||
* configuration management.
|
||||
*
|
||||
* A client can query all global output_device objects to enlist all
|
||||
* available display devices, even those that may currently not be
|
||||
* represented by the compositor as a wl_output.
|
||||
*
|
||||
* The client sends configuration changes to the server through the
|
||||
* outputconfiguration interface, and the server applies the configuration
|
||||
* changes to the hardware and signals changes to the output devices
|
||||
* accordingly.
|
||||
*
|
||||
* This object is published as global during start up for every available
|
||||
* display devices, or when one later becomes available, for example by
|
||||
* being hotplugged via a physical connector.
|
||||
* @section page_iface_kde_output_device_v2_api API
|
||||
* See @ref iface_kde_output_device_v2.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_kde_output_device_v2 The kde_output_device_v2 interface
|
||||
*
|
||||
* An output device describes a display device available to the compositor.
|
||||
* output_device is similar to wl_output, but focuses on output
|
||||
* configuration management.
|
||||
*
|
||||
* A client can query all global output_device objects to enlist all
|
||||
* available display devices, even those that may currently not be
|
||||
* represented by the compositor as a wl_output.
|
||||
*
|
||||
* The client sends configuration changes to the server through the
|
||||
* outputconfiguration interface, and the server applies the configuration
|
||||
* changes to the hardware and signals changes to the output devices
|
||||
* accordingly.
|
||||
*
|
||||
* This object is published as global during start up for every available
|
||||
* display devices, or when one later becomes available, for example by
|
||||
* being hotplugged via a physical connector.
|
||||
*/
|
||||
extern const struct wl_interface kde_output_device_v2_interface;
|
||||
#endif
|
||||
#ifndef KDE_OUTPUT_DEVICE_MODE_V2_INTERFACE
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_INTERFACE
|
||||
/**
|
||||
* @page page_iface_kde_output_device_mode_v2 kde_output_device_mode_v2
|
||||
* @section page_iface_kde_output_device_mode_v2_desc Description
|
||||
*
|
||||
* This object describes an output mode.
|
||||
*
|
||||
* Some heads don't support output modes, in which case modes won't be
|
||||
* advertised.
|
||||
*
|
||||
* Properties sent via this interface are applied atomically via the
|
||||
* kde_output_device.done event. No guarantees are made regarding the order
|
||||
* in which properties are sent.
|
||||
* @section page_iface_kde_output_device_mode_v2_api API
|
||||
* See @ref iface_kde_output_device_mode_v2.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_kde_output_device_mode_v2 The kde_output_device_mode_v2 interface
|
||||
*
|
||||
* This object describes an output mode.
|
||||
*
|
||||
* Some heads don't support output modes, in which case modes won't be
|
||||
* advertised.
|
||||
*
|
||||
* Properties sent via this interface are applied atomically via the
|
||||
* kde_output_device.done event. No guarantees are made regarding the order
|
||||
* in which properties are sent.
|
||||
*/
|
||||
extern const struct wl_interface kde_output_device_mode_v2_interface;
|
||||
#endif
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* subpixel geometry information
|
||||
*
|
||||
* This enumeration describes how the physical pixels on an output are
|
||||
* laid out.
|
||||
*/
|
||||
enum kde_output_device_v2_subpixel {
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_UNKNOWN = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_NONE = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_HORIZONTAL_RGB = 2,
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_HORIZONTAL_BGR = 3,
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_VERTICAL_RGB = 4,
|
||||
KDE_OUTPUT_DEVICE_V2_SUBPIXEL_VERTICAL_BGR = 5,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* transform from framebuffer to output
|
||||
*
|
||||
* This describes the transform, that a compositor will apply to a
|
||||
* surface to compensate for the rotation or mirroring of an
|
||||
* output device.
|
||||
*
|
||||
* The flipped values correspond to an initial flip around a
|
||||
* vertical axis followed by rotation.
|
||||
*
|
||||
* The purpose is mainly to allow clients to render accordingly and
|
||||
* tell the compositor, so that for fullscreen surfaces, the
|
||||
* compositor is still able to scan out directly client surfaces.
|
||||
*/
|
||||
enum kde_output_device_v2_transform {
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_NORMAL = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_90 = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_180 = 2,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_270 = 3,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED = 4,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_90 = 5,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_180 = 6,
|
||||
KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_270 = 7,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* describes capabilities of the outputdevice
|
||||
*
|
||||
* Describes what capabilities this device has.
|
||||
*/
|
||||
enum kde_output_device_v2_capability {
|
||||
/**
|
||||
* if this output_device can use overscan
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_OVERSCAN = 0x1,
|
||||
/**
|
||||
* if this outputdevice supports variable refresh rate
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_VRR = 0x2,
|
||||
/**
|
||||
* if setting the rgb range is possible
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_RGB_RANGE = 0x4,
|
||||
/**
|
||||
* if this outputdevice supports high dynamic range
|
||||
* @since 3
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_HIGH_DYNAMIC_RANGE = 0x8,
|
||||
/**
|
||||
* if this outputdevice supports a wide color gamut
|
||||
* @since 3
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_WIDE_COLOR_GAMUT = 0x10,
|
||||
/**
|
||||
* if this outputdevice supports autorotation
|
||||
* @since 4
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_AUTO_ROTATE = 0x20,
|
||||
/**
|
||||
* if this outputdevice supports icc profiles
|
||||
* @since 5
|
||||
*/
|
||||
KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE = 0x40,
|
||||
};
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_HIGH_DYNAMIC_RANGE_SINCE_VERSION 3
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_WIDE_COLOR_GAMUT_SINCE_VERSION 3
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_AUTO_ROTATE_SINCE_VERSION 4
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE_SINCE_VERSION 5
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* describes vrr policy
|
||||
*
|
||||
* Describes when the compositor may employ variable refresh rate
|
||||
*/
|
||||
enum kde_output_device_v2_vrr_policy {
|
||||
KDE_OUTPUT_DEVICE_V2_VRR_POLICY_NEVER = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ALWAYS = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_VRR_POLICY_AUTOMATIC = 2,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* describes RGB range policy
|
||||
*
|
||||
* Whether full or limited color range should be used
|
||||
*/
|
||||
enum kde_output_device_v2_rgb_range {
|
||||
KDE_OUTPUT_DEVICE_V2_RGB_RANGE_AUTOMATIC = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_RGB_RANGE_FULL = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_RGB_RANGE_LIMITED = 2,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* describes when auto rotate should be used
|
||||
*/
|
||||
enum kde_output_device_v2_auto_rotate_policy {
|
||||
KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_NEVER = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_IN_TABLET_MODE = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ALWAYS = 2,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM */
|
||||
|
||||
#ifndef KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM
|
||||
#define KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* which source the compositor should use for the color profile on an output
|
||||
*/
|
||||
enum kde_output_device_v2_color_profile_source {
|
||||
KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_SRGB = 0,
|
||||
KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ICC = 1,
|
||||
KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_EDID = 2,
|
||||
};
|
||||
#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
* @struct kde_output_device_v2_listener
|
||||
*/
|
||||
struct kde_output_device_v2_listener {
|
||||
/**
|
||||
* geometric properties of the output
|
||||
*
|
||||
* The geometry event describes geometric properties of the
|
||||
* output. The event is sent when binding to the output object and
|
||||
* whenever any of the properties change.
|
||||
* @param x x position within the global compositor space
|
||||
* @param y y position within the global compositor space
|
||||
* @param physical_width width in millimeters of the output
|
||||
* @param physical_height height in millimeters of the output
|
||||
* @param subpixel subpixel orientation of the output
|
||||
* @param make textual description of the manufacturer
|
||||
* @param model textual description of the model
|
||||
* @param transform transform that maps framebuffer to output
|
||||
*/
|
||||
void (*geometry)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physical_width,
|
||||
int32_t physical_height,
|
||||
int32_t subpixel,
|
||||
const char *make,
|
||||
const char *model,
|
||||
int32_t transform);
|
||||
/**
|
||||
* current mode
|
||||
*
|
||||
* This event describes the mode currently in use for this head.
|
||||
* It is only sent if the output is enabled.
|
||||
*/
|
||||
void (*current_mode)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
struct kde_output_device_mode_v2 *mode);
|
||||
/**
|
||||
* advertise available output modes and current one
|
||||
*
|
||||
* The mode event describes an available mode for the output.
|
||||
*
|
||||
* When the client binds to the output_device object, the server
|
||||
* sends this event once for every available mode the output_device
|
||||
* can be operated by.
|
||||
*
|
||||
* There will always be at least one event sent out on initial
|
||||
* binding, which represents the current mode.
|
||||
*
|
||||
* Later if an output changes, its mode event is sent again for the
|
||||
* eventual added modes and lastly the current mode. In other
|
||||
* words, the current mode is always represented by the latest
|
||||
* event sent with the current flag set.
|
||||
*
|
||||
* The size of a mode is given in physical hardware units of the
|
||||
* output device. This is not necessarily the same as the output
|
||||
* size in the global compositor space. For instance, the output
|
||||
* may be scaled, as described in kde_output_device_v2.scale, or
|
||||
* transformed, as described in kde_output_device_v2.transform.
|
||||
*/
|
||||
void (*mode)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
struct kde_output_device_mode_v2 *mode);
|
||||
/**
|
||||
* sent all information about output
|
||||
*
|
||||
* This event is sent after all other properties have been sent
|
||||
* on binding to the output object as well as after any other
|
||||
* output property change have been applied later on. This allows
|
||||
* to see changes to the output properties as atomic, even if
|
||||
* multiple events successively announce them.
|
||||
*/
|
||||
void (*done)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2);
|
||||
/**
|
||||
* output scaling properties
|
||||
*
|
||||
* This event contains scaling geometry information that is not
|
||||
* in the geometry event. It may be sent after binding the output
|
||||
* object or if the output scale changes later. If it is not sent,
|
||||
* the client should assume a scale of 1.
|
||||
*
|
||||
* A scale larger than 1 means that the compositor will
|
||||
* automatically scale surface buffers by this amount when
|
||||
* rendering. This is used for high resolution displays where
|
||||
* applications rendering at the native resolution would be too
|
||||
* small to be legible.
|
||||
*
|
||||
* It is intended that scaling aware clients track the current
|
||||
* output of a surface, and if it is on a scaled output it should
|
||||
* use wl_surface.set_buffer_scale with the scale of the output.
|
||||
* That way the compositor can avoid scaling the surface, and the
|
||||
* client can supply a higher detail image.
|
||||
* @param factor scaling factor of output
|
||||
*/
|
||||
void (*scale)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
wl_fixed_t factor);
|
||||
/**
|
||||
* advertise EDID data for the output
|
||||
*
|
||||
* The edid event encapsulates the EDID data for the
|
||||
* outputdevice.
|
||||
*
|
||||
* The event is sent when binding to the output object. The EDID
|
||||
* data may be empty, in which case this event is sent anyway. If
|
||||
* the EDID information is empty, you can fall back to the name et
|
||||
* al. properties of the outputdevice.
|
||||
* @param raw base64-encoded EDID string
|
||||
*/
|
||||
void (*edid)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *raw);
|
||||
/**
|
||||
* output is enabled or disabled
|
||||
*
|
||||
* The enabled event notifies whether this output is currently
|
||||
* enabled and used for displaying content by the server. The event
|
||||
* is sent when binding to the output object and whenever later on
|
||||
* an output changes its state by becoming enabled or disabled.
|
||||
* @param enabled output enabled state
|
||||
*/
|
||||
void (*enabled)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
int32_t enabled);
|
||||
/**
|
||||
* A unique id for this outputdevice
|
||||
*
|
||||
* The uuid can be used to identify the output. It's controlled
|
||||
* by the server entirely. The server should make sure the uuid is
|
||||
* persistent across restarts. An empty uuid is considered invalid.
|
||||
* @param uuid output devices ID
|
||||
*/
|
||||
void (*uuid)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *uuid);
|
||||
/**
|
||||
* Serial Number
|
||||
*
|
||||
* Serial ID of the monitor, sent on startup before the first
|
||||
* done event.
|
||||
* @param serialNumber textual representation of serial number
|
||||
*/
|
||||
void (*serial_number)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *serialNumber);
|
||||
/**
|
||||
* EISA ID
|
||||
*
|
||||
* EISA ID of the monitor, sent on startup before the first done
|
||||
* event.
|
||||
* @param eisaId textual representation of EISA identifier
|
||||
*/
|
||||
void (*eisa_id)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *eisaId);
|
||||
/**
|
||||
* capability flags
|
||||
*
|
||||
* What capabilities this device has, sent on startup before the
|
||||
* first done event.
|
||||
*/
|
||||
void (*capabilities)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t flags);
|
||||
/**
|
||||
* overscan
|
||||
*
|
||||
* Overscan value of the monitor in percent, sent on startup
|
||||
* before the first done event.
|
||||
* @param overscan amount of overscan of the monitor
|
||||
*/
|
||||
void (*overscan)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t overscan);
|
||||
/**
|
||||
* Variable Refresh Rate Policy
|
||||
*
|
||||
* What policy the compositor will employ regarding its use of
|
||||
* variable refresh rate.
|
||||
*/
|
||||
void (*vrr_policy)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t vrr_policy);
|
||||
/**
|
||||
* RGB range
|
||||
*
|
||||
* What rgb range the compositor is using for this output
|
||||
*/
|
||||
void (*rgb_range)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t rgb_range);
|
||||
/**
|
||||
* Output's name
|
||||
*
|
||||
* Name of the output, it's useful to cross-reference to an
|
||||
* zxdg_output_v1 and ultimately QScreen
|
||||
* @since 2
|
||||
*/
|
||||
void (*name)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *name);
|
||||
/**
|
||||
* if HDR is enabled
|
||||
*
|
||||
* Whether or not high dynamic range is enabled for this output
|
||||
* @param hdr_enabled 1 if enabled, 0 if disabled
|
||||
* @since 3
|
||||
*/
|
||||
void (*high_dynamic_range)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t hdr_enabled);
|
||||
/**
|
||||
* the brightness of sdr if hdr is enabled
|
||||
*
|
||||
* If high dynamic range is used, this value defines the
|
||||
* brightness in nits for content that's in standard dynamic range
|
||||
* format. Note that while the value is in nits, that doesn't
|
||||
* necessarily translate to the same brightness on the screen.
|
||||
* @since 3
|
||||
*/
|
||||
void (*sdr_brightness)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t sdr_brightness);
|
||||
/**
|
||||
* if WCG is enabled
|
||||
*
|
||||
* Whether or not the use of a wide color gamut is enabled for
|
||||
* this output
|
||||
* @param wcg_enabled 1 if enabled, 0 if disabled
|
||||
* @since 3
|
||||
*/
|
||||
void (*wide_color_gamut)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t wcg_enabled);
|
||||
/**
|
||||
* describes when auto rotate is used
|
||||
*
|
||||
*
|
||||
* @since 4
|
||||
*/
|
||||
void (*auto_rotate_policy)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t policy);
|
||||
/**
|
||||
* describes when auto rotate is used
|
||||
*
|
||||
*
|
||||
* @since 5
|
||||
*/
|
||||
void (*icc_profile_path)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const char *profile_path);
|
||||
/**
|
||||
* metadata about the screen's brightness limits
|
||||
*
|
||||
*
|
||||
* @param max_peak_brightness in nits
|
||||
* @param max_frame_average_brightness in nits
|
||||
* @param min_brightness in 0.0001 nits
|
||||
* @since 6
|
||||
*/
|
||||
void (*brightness_metadata)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t max_peak_brightness,
|
||||
uint32_t max_frame_average_brightness,
|
||||
uint32_t min_brightness);
|
||||
/**
|
||||
* overrides for the screen's brightness limits
|
||||
*
|
||||
*
|
||||
* @param max_peak_brightness -1 for no override, positive values are the brightness in nits
|
||||
* @param max_average_brightness -1 for no override, positive values are the brightness in nits
|
||||
* @param min_brightness -1 for no override, positive values are the brightness in 0.0001 nits
|
||||
* @since 6
|
||||
*/
|
||||
void (*brightness_overrides)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
int32_t max_peak_brightness,
|
||||
int32_t max_average_brightness,
|
||||
int32_t min_brightness);
|
||||
/**
|
||||
* describes which gamut is assumed for sRGB applications
|
||||
*
|
||||
* This can be used to provide the colors users assume sRGB
|
||||
* applications should have based on the default experience on many
|
||||
* modern sRGB screens.
|
||||
* @param gamut_wideness 0 means rec.709 primaries, 10000 means native primaries
|
||||
* @since 6
|
||||
*/
|
||||
void (*sdr_gamut_wideness)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t gamut_wideness);
|
||||
/**
|
||||
* describes which source the compositor uses for the color profile on an output
|
||||
*
|
||||
*
|
||||
* @since 7
|
||||
*/
|
||||
void (*color_profile_source)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t source);
|
||||
/**
|
||||
* brightness multiplier
|
||||
*
|
||||
* This is the brightness modifier of the output. It doesn't
|
||||
* specify any absolute values, but is merely a multiplier on top
|
||||
* of other brightness values, like sdr_brightness and
|
||||
* brightness_metadata. 0 is the minimum brightness (not completely
|
||||
* dark) and 10000 is the maximum brightness. This is currently
|
||||
* only supported / meaningful while HDR is active.
|
||||
* @param brightness brightness in 0-10000
|
||||
* @since 8
|
||||
*/
|
||||
void (*brightness)(void *data,
|
||||
struct kde_output_device_v2 *kde_output_device_v2,
|
||||
uint32_t brightness);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
static inline int
|
||||
kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device_v2,
|
||||
const struct kde_output_device_v2_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) kde_output_device_v2,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_GEOMETRY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CURRENT_MODE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_MODE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_DONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_SCALE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_EDID_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_ENABLED_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_UUID_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_SERIAL_NUMBER_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_EISA_ID_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_CAPABILITIES_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_OVERSCAN_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_VRR_POLICY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_RGB_RANGE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_NAME_SINCE_VERSION 2
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_HIGH_DYNAMIC_RANGE_SINCE_VERSION 3
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_SDR_BRIGHTNESS_SINCE_VERSION 3
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_WIDE_COLOR_GAMUT_SINCE_VERSION 3
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_SINCE_VERSION 4
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_ICC_PROFILE_PATH_SINCE_VERSION 5
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_METADATA_SINCE_VERSION 6
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_OVERRIDES_SINCE_VERSION 6
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_SDR_GAMUT_WIDENESS_SINCE_VERSION 6
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_SINCE_VERSION 7
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_SINCE_VERSION 8
|
||||
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void *
|
||||
// kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
|
||||
// static inline uint32_t
|
||||
// kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_kde_output_device_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2)
|
||||
// {
|
||||
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2);
|
||||
// }
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
* @struct kde_output_device_mode_v2_listener
|
||||
*/
|
||||
struct kde_output_device_mode_v2_listener {
|
||||
/**
|
||||
* mode size
|
||||
*
|
||||
* This event describes the mode size. The size is given in
|
||||
* physical hardware units of the output device. This is not
|
||||
* necessarily the same as the output size in the global compositor
|
||||
* space. For instance, the output may be scaled or transformed.
|
||||
* @param width width of the mode in hardware units
|
||||
* @param height height of the mode in hardware units
|
||||
*/
|
||||
void (*size)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* mode refresh rate
|
||||
*
|
||||
* This event describes the mode's fixed vertical refresh rate.
|
||||
* It is only sent if the mode has a fixed refresh rate.
|
||||
* @param refresh vertical refresh rate in mHz
|
||||
*/
|
||||
void (*refresh)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2,
|
||||
int32_t refresh);
|
||||
/**
|
||||
* mode is preferred
|
||||
*
|
||||
* This event advertises this mode as preferred.
|
||||
*/
|
||||
void (*preferred)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2);
|
||||
/**
|
||||
* the mode has been destroyed
|
||||
*
|
||||
* The compositor will destroy the object immediately after
|
||||
* sending this event, so it will become invalid and the client
|
||||
* should release any resources associated with it.
|
||||
*/
|
||||
void (*removed)(void *data,
|
||||
struct kde_output_device_mode_v2 *kde_output_device_mode_v2);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
static inline int
|
||||
kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_output_device_mode_v2,
|
||||
const struct kde_output_device_mode_v2_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) kde_output_device_mode_v2,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_REFRESH_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_PREFERRED_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_device_mode_v2
|
||||
*/
|
||||
#define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1
|
||||
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void *
|
||||
// kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
|
||||
// static inline uint32_t
|
||||
// kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_kde_output_device_mode_v2 */
|
||||
// static inline void
|
||||
// kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2)
|
||||
// {
|
||||
// wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2);
|
||||
// }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
|
||||
* SPDX-FileCopyrightText: 2010-2011 Intel Corporation
|
||||
* SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd.
|
||||
* SPDX-FileCopyrightText: 2015 Sebastian Kügler <sebas@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Méven Car <meven.car@enioka.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT-CMU
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
extern const struct wl_interface kde_output_device_mode_v2_interface;
|
||||
|
||||
static const struct wl_interface *kde_output_device_v2_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&kde_output_device_mode_v2_interface,
|
||||
&kde_output_device_mode_v2_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_device_v2_events[] = {
|
||||
{ "geometry", "iiiiissi", kde_output_device_v2_types + 0 },
|
||||
{ "current_mode", "o", kde_output_device_v2_types + 8 },
|
||||
{ "mode", "n", kde_output_device_v2_types + 9 },
|
||||
{ "done", "", kde_output_device_v2_types + 0 },
|
||||
{ "scale", "f", kde_output_device_v2_types + 0 },
|
||||
{ "edid", "s", kde_output_device_v2_types + 0 },
|
||||
{ "enabled", "i", kde_output_device_v2_types + 0 },
|
||||
{ "uuid", "s", kde_output_device_v2_types + 0 },
|
||||
{ "serial_number", "s", kde_output_device_v2_types + 0 },
|
||||
{ "eisa_id", "s", kde_output_device_v2_types + 0 },
|
||||
{ "capabilities", "u", kde_output_device_v2_types + 0 },
|
||||
{ "overscan", "u", kde_output_device_v2_types + 0 },
|
||||
{ "vrr_policy", "u", kde_output_device_v2_types + 0 },
|
||||
{ "rgb_range", "u", kde_output_device_v2_types + 0 },
|
||||
{ "name", "2s", kde_output_device_v2_types + 0 },
|
||||
{ "high_dynamic_range", "3u", kde_output_device_v2_types + 0 },
|
||||
{ "sdr_brightness", "3u", kde_output_device_v2_types + 0 },
|
||||
{ "wide_color_gamut", "3u", kde_output_device_v2_types + 0 },
|
||||
{ "auto_rotate_policy", "4u", kde_output_device_v2_types + 0 },
|
||||
{ "icc_profile_path", "5s", kde_output_device_v2_types + 0 },
|
||||
{ "brightness_metadata", "6uuu", kde_output_device_v2_types + 0 },
|
||||
{ "brightness_overrides", "6iii", kde_output_device_v2_types + 0 },
|
||||
{ "sdr_gamut_wideness", "6u", kde_output_device_v2_types + 0 },
|
||||
{ "color_profile_source", "7u", kde_output_device_v2_types + 0 },
|
||||
{ "brightness", "8u", kde_output_device_v2_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_device_v2_interface = {
|
||||
"kde_output_device_v2", 8,
|
||||
0, NULL,
|
||||
25, kde_output_device_v2_events,
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_device_mode_v2_events[] = {
|
||||
{ "size", "ii", kde_output_device_v2_types + 0 },
|
||||
{ "refresh", "i", kde_output_device_v2_types + 0 },
|
||||
{ "preferred", "", kde_output_device_v2_types + 0 },
|
||||
{ "removed", "", kde_output_device_v2_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_device_mode_v2_interface = {
|
||||
"kde_output_device_mode_v2", 1,
|
||||
0, NULL,
|
||||
4, kde_output_device_mode_v2_events,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
#ifndef KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H
|
||||
#define KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_kde_output_order_v1 The kde_output_order_v1 protocol
|
||||
* @section page_ifaces_kde_output_order_v1 Interfaces
|
||||
* - @subpage page_iface_kde_output_order_v1 - announce order of outputs
|
||||
* @section page_copyright_kde_output_order_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT-CMU
|
||||
* </pre>
|
||||
*/
|
||||
struct kde_output_order_v1;
|
||||
|
||||
#ifndef KDE_OUTPUT_ORDER_V1_INTERFACE
|
||||
#define KDE_OUTPUT_ORDER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_kde_output_order_v1 kde_output_order_v1
|
||||
* @section page_iface_kde_output_order_v1_desc Description
|
||||
*
|
||||
* Announce the order in which desktop environment components should be placed on outputs.
|
||||
* The compositor will send the list of outputs when the global is bound and whenever there is a change.
|
||||
* @section page_iface_kde_output_order_v1_api API
|
||||
* See @ref iface_kde_output_order_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_kde_output_order_v1 The kde_output_order_v1 interface
|
||||
*
|
||||
* Announce the order in which desktop environment components should be placed on outputs.
|
||||
* The compositor will send the list of outputs when the global is bound and whenever there is a change.
|
||||
*/
|
||||
extern const struct wl_interface kde_output_order_v1_interface;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_order_v1
|
||||
* @struct kde_output_order_v1_listener
|
||||
*/
|
||||
struct kde_output_order_v1_listener {
|
||||
/**
|
||||
* output name
|
||||
*
|
||||
* Specifies the output identified by their wl_output.name.
|
||||
* @param output_name the name of the output
|
||||
*/
|
||||
void (*output)(void *data,
|
||||
struct kde_output_order_v1 *kde_output_order_v1,
|
||||
const char *output_name);
|
||||
/**
|
||||
* done
|
||||
*
|
||||
* Specifies that the output list is complete. On the next output
|
||||
* event, a new list begins.
|
||||
*/
|
||||
void (*done)(void *data,
|
||||
struct kde_output_order_v1 *kde_output_order_v1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_order_v1
|
||||
*/
|
||||
static inline int
|
||||
kde_output_order_v1_add_listener(struct kde_output_order_v1 *kde_output_order_v1,
|
||||
const struct kde_output_order_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) kde_output_order_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define KDE_OUTPUT_ORDER_V1_DESTROY 0
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_order_v1
|
||||
*/
|
||||
#define KDE_OUTPUT_ORDER_V1_OUTPUT_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_kde_output_order_v1
|
||||
*/
|
||||
#define KDE_OUTPUT_ORDER_V1_DONE_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_kde_output_order_v1
|
||||
*/
|
||||
#define KDE_OUTPUT_ORDER_V1_DESTROY_SINCE_VERSION 1
|
||||
|
||||
// /** @ingroup iface_kde_output_order_v1 */
|
||||
// static inline void
|
||||
// kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_kde_output_order_v1 */
|
||||
// static inline void *
|
||||
// kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1);
|
||||
// }
|
||||
|
||||
// static inline uint32_t
|
||||
// kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @ingroup iface_kde_output_order_v1
|
||||
// */
|
||||
// static inline void
|
||||
// kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1)
|
||||
// {
|
||||
// wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1,
|
||||
// KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
// }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT-CMU
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
|
||||
static const struct wl_interface *kde_output_order_v1_types[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_order_v1_requests[] = {
|
||||
{ "destroy", "", kde_output_order_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message kde_output_order_v1_events[] = {
|
||||
{ "output", "s", kde_output_order_v1_types + 0 },
|
||||
{ "done", "", kde_output_order_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface kde_output_order_v1_interface = {
|
||||
"kde_output_order_v1", 1,
|
||||
1, kde_output_order_v1_requests,
|
||||
2, kde_output_order_v1_events,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,250 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
|
||||
#include "wayland.h"
|
||||
#include "kde-output-device-v2-client-protocol.h"
|
||||
#include "kde-output-order-v1-client-protocol.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/base64.h"
|
||||
|
||||
typedef struct WaylandKdeMode
|
||||
{
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t refreshRate;
|
||||
struct kde_output_device_mode_v2* pMode;
|
||||
} WaylandKdeMode;
|
||||
|
||||
static void waylandKdeSizeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t width, int32_t height)
|
||||
{
|
||||
WaylandKdeMode* mode = (WaylandKdeMode*) data;
|
||||
mode->width = width;
|
||||
mode->height = height;
|
||||
}
|
||||
|
||||
static void waylandKdeRefreshListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t rate)
|
||||
{
|
||||
WaylandKdeMode* mode = (WaylandKdeMode*) data;
|
||||
mode->refreshRate = rate;
|
||||
}
|
||||
|
||||
static const struct kde_output_device_mode_v2_listener modeListener = {
|
||||
.size = waylandKdeSizeListener,
|
||||
.refresh = waylandKdeRefreshListener,
|
||||
.preferred = (void*) stubListener,
|
||||
.removed = (void*) stubListener,
|
||||
};
|
||||
|
||||
static void waylandKdeModeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, struct kde_output_device_mode_v2 *mode)
|
||||
{
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
if (!wldata->internal) return;
|
||||
|
||||
WaylandKdeMode* newMode = ffListAdd((FFlist*) wldata->internal);
|
||||
newMode->pMode = mode;
|
||||
|
||||
// Strangely, the listener is called only in this function, but not in `waylandKdeCurrentModeListener`
|
||||
wldata->parent->ffwl_proxy_add_listener((struct wl_proxy *) mode, (void (**)(void)) &modeListener, newMode);
|
||||
}
|
||||
|
||||
static void waylandKdeCurrentModeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2 *_, struct kde_output_device_mode_v2 *mode)
|
||||
{
|
||||
// waylandKdeModeListener is always run before this
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
if (!wldata->internal) return;
|
||||
|
||||
WaylandKdeMode* current = NULL;
|
||||
FF_LIST_FOR_EACH(WaylandKdeMode, m, *(FFlist*) wldata->internal)
|
||||
{
|
||||
if (m->pMode == mode)
|
||||
{
|
||||
current = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
wldata->width = current->width;
|
||||
wldata->height = current->height;
|
||||
wldata->refreshRate = current->refreshRate;
|
||||
}
|
||||
|
||||
static void waylandKdeScaleListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, wl_fixed_t scale)
|
||||
{
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
wldata->scale = wl_fixed_to_double(scale);
|
||||
}
|
||||
|
||||
static void waylandKdeEdidListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, const char* raw)
|
||||
{
|
||||
if (!*raw) return;
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
FF_STRBUF_AUTO_DESTROY b64 = ffStrbufCreateStatic(raw);
|
||||
FF_STRBUF_AUTO_DESTROY edid = ffBase64DecodeStrbuf(&b64);
|
||||
if (edid.length < 128) return;
|
||||
ffEdidGetName((const uint8_t*) edid.chars, &wldata->edidName);
|
||||
}
|
||||
|
||||
static void waylandKdeEnabledListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, int32_t enabled)
|
||||
{
|
||||
WaylandDisplay* wldata = (WaylandDisplay*) data;
|
||||
if (!enabled) wldata->internal = NULL;
|
||||
}
|
||||
|
||||
static void waylandKdeGeometryListener(void *data,
|
||||
FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2,
|
||||
FF_MAYBE_UNUSED int32_t x,
|
||||
FF_MAYBE_UNUSED int32_t y,
|
||||
FF_MAYBE_UNUSED int32_t physical_width,
|
||||
FF_MAYBE_UNUSED int32_t physical_height,
|
||||
FF_MAYBE_UNUSED int32_t subpixel,
|
||||
FF_MAYBE_UNUSED const char *make,
|
||||
FF_MAYBE_UNUSED const char *model,
|
||||
int32_t transform)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
display->transform = (enum wl_output_transform) transform;
|
||||
}
|
||||
|
||||
void waylandOutputNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* output, const char *name)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
if(ffStrStartsWith(name, "eDP-"))
|
||||
display->type = FF_DISPLAY_TYPE_BUILTIN;
|
||||
else if(ffStrStartsWith(name, "HDMI-"))
|
||||
display->type = FF_DISPLAY_TYPE_EXTERNAL;
|
||||
strncpy((char*) &display->id, name, sizeof(display->id));
|
||||
ffStrbufAppendS(&display->name, name);
|
||||
}
|
||||
|
||||
static struct kde_output_device_v2_listener outputListener = {
|
||||
.geometry = waylandKdeGeometryListener,
|
||||
.current_mode = waylandKdeCurrentModeListener,
|
||||
.mode = waylandKdeModeListener,
|
||||
.done = (void*) stubListener,
|
||||
.scale = waylandKdeScaleListener,
|
||||
.edid = waylandKdeEdidListener,
|
||||
.enabled = waylandKdeEnabledListener,
|
||||
.uuid = (void*) stubListener,
|
||||
.serial_number = (void*) stubListener,
|
||||
.eisa_id = (void*) stubListener,
|
||||
.capabilities = (void*) stubListener,
|
||||
.overscan = (void*) stubListener,
|
||||
.vrr_policy = (void*) stubListener,
|
||||
.rgb_range = (void*) stubListener,
|
||||
.name = waylandOutputNameListener,
|
||||
.high_dynamic_range = (void*) stubListener,
|
||||
.sdr_brightness = (void*) stubListener,
|
||||
.wide_color_gamut = (void*) stubListener,
|
||||
.auto_rotate_policy = (void*) stubListener,
|
||||
.icc_profile_path = (void*) stubListener,
|
||||
.brightness_metadata = (void*) stubListener,
|
||||
.brightness_overrides = (void*) stubListener,
|
||||
.sdr_gamut_wideness = (void*) stubListener,
|
||||
.color_profile_source = (void*) stubListener,
|
||||
.brightness = (void*) stubListener,
|
||||
};
|
||||
|
||||
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_device_v2_interface, version, name, kde_output_device_v2_interface.name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
|
||||
FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode));
|
||||
WaylandDisplay display = {
|
||||
.parent = wldata,
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.refreshRate = 0,
|
||||
.scale = 1,
|
||||
.transform = WL_OUTPUT_TRANSFORM_NORMAL,
|
||||
.type = FF_DISPLAY_TYPE_UNKNOWN,
|
||||
.name = ffStrbufCreate(),
|
||||
.description = ffStrbufCreate(),
|
||||
.edidName = ffStrbufCreate(),
|
||||
.internal = &modes,
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
|
||||
if(display.width <= 0 || display.height <= 0 || !display.internal)
|
||||
return;
|
||||
|
||||
uint32_t rotation;
|
||||
switch(display.transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case 90:
|
||||
case 270: {
|
||||
int32_t temp = display.width;
|
||||
display.width = display.height;
|
||||
display.height = temp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(wldata->result,
|
||||
(uint32_t) display.width,
|
||||
(uint32_t) display.height,
|
||||
display.refreshRate / 1000.0,
|
||||
(uint32_t) (display.width / display.scale),
|
||||
(uint32_t) (display.height / display.scale),
|
||||
rotation,
|
||||
display.edidName.length
|
||||
? &display.edidName
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
display.id
|
||||
);
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
ffStrbufDestroy(&display.name);
|
||||
ffStrbufDestroy(&display.edidName);
|
||||
}
|
||||
|
||||
|
||||
static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde_output_order_v1 *_, const char *output_name)
|
||||
{
|
||||
uint64_t* id = (uint64_t*) data;
|
||||
if (*id == 0)
|
||||
*id = ffWaylandGenerateIdFromName(output_name);
|
||||
}
|
||||
|
||||
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version)
|
||||
{
|
||||
struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, version, name, kde_output_order_v1_interface.name, version, NULL);
|
||||
if(output == NULL)
|
||||
return;
|
||||
|
||||
struct kde_output_order_v1_listener orderListener = {
|
||||
.output = waylandKdeOutputOrderListener,
|
||||
.done = (void*) stubListener,
|
||||
};
|
||||
|
||||
wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId);
|
||||
wldata->ffwl_display_roundtrip(wldata->display);
|
||||
wldata->ffwl_proxy_destroy(output);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -9,28 +9,34 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "common/properties.h"
|
||||
|
||||
#include "wayland.h"
|
||||
#include "wlr-output-management-unstable-v1-client-protocol.h"
|
||||
#include "kde-output-device-v2-client-protocol.h"
|
||||
#include "kde-output-order-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
#ifdef __linux__
|
||||
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
struct ucred ucred;
|
||||
socklen_t len = sizeof(struct ucred);
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1)
|
||||
return;
|
||||
return false;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate();
|
||||
ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed.
|
||||
ffReadFileBuffer(procPath.chars, &result->wmProcessName);
|
||||
ffStrbufTrimRightSpace(&result->wmProcessName);
|
||||
ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments
|
||||
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
|
||||
{
|
||||
FF_UNUSED(fd, result);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,6 +54,19 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_ZWLR;
|
||||
ffWaylandHandleZwlrOutput(wldata, registry, name, version);
|
||||
}
|
||||
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_KDE) && ffStrEquals(interface, kde_output_device_v2_interface.name))
|
||||
{
|
||||
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE;
|
||||
ffWaylandHandleKdeOutput(wldata, registry, name, version);
|
||||
}
|
||||
else if(ffStrEquals(interface, kde_output_order_v1_interface.name))
|
||||
{
|
||||
ffWaylandHandleKdeOutputOrder(wldata, registry, name, version);
|
||||
}
|
||||
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE) && ffStrEquals(interface, zxdg_output_manager_v1_interface.name))
|
||||
{
|
||||
ffWaylandHandleZxdgOutput(wldata, registry, name, version);
|
||||
}
|
||||
}
|
||||
|
||||
bool detectWayland(FFDisplayServerResult* result)
|
||||
@@ -91,9 +110,85 @@ bool detectWayland(FFDisplayServerResult* result)
|
||||
data.ffwl_proxy_add_listener(registry, (void(**)(void)) ®istry_listener, &data);
|
||||
data.ffwl_display_roundtrip(data.display);
|
||||
|
||||
if (data.zxdgOutputManager)
|
||||
data.ffwl_proxy_destroy(data.zxdgOutputManager);
|
||||
|
||||
data.ffwl_proxy_destroy(registry);
|
||||
ffwl_display_disconnect(data.display);
|
||||
|
||||
if(data.primaryDisplayId == 0 && result->wmProcessName.length > 0)
|
||||
{
|
||||
const char* fileName = ffStrbufEqualS(&result->wmProcessName, "gnome-shell")
|
||||
? "monitors.xml"
|
||||
: ffStrbufEqualS(&result->wmProcessName, "cinnamon")
|
||||
? "cinnamon-monitors.xml"
|
||||
: NULL;
|
||||
if (fileName)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY monitorsXml = ffStrbufCreate();
|
||||
FF_LIST_FOR_EACH(FFstrbuf, basePath, instance.state.platform.configDirs)
|
||||
{
|
||||
char path[1024];
|
||||
snprintf(path, sizeof(path) - 1, "%s%s", basePath->chars, fileName);
|
||||
if (ffReadFileBuffer(path, &monitorsXml))
|
||||
break;
|
||||
}
|
||||
if (monitorsXml.length)
|
||||
{
|
||||
// <monitors version="2">
|
||||
// <configuration>
|
||||
// <logicalmonitor>
|
||||
// <x>0</x>
|
||||
// <y>0</y>
|
||||
// <scale>1.7489879131317139</scale>
|
||||
// <primary>yes</primary>
|
||||
// <monitor>
|
||||
// <monitorspec>
|
||||
// <connector>Virtual-1</connector>
|
||||
// <vendor>unknown</vendor>
|
||||
// <product>unknown</product>
|
||||
// <serial>unknown</serial>
|
||||
// </monitorspec>
|
||||
// <mode>
|
||||
// <width>3456</width>
|
||||
// <height>2160</height>
|
||||
// <rate>60.000068664550781</rate>
|
||||
// </mode>
|
||||
// </monitor>
|
||||
// </logicalmonitor>
|
||||
// </configuration>
|
||||
// </monitors>
|
||||
uint32_t start = ffStrbufFirstIndexS(&monitorsXml, "<primary>yes</primary>");
|
||||
if (start < monitorsXml.length)
|
||||
{
|
||||
start = ffStrbufNextIndexS(&monitorsXml, start, "<connector>");
|
||||
if (start < monitorsXml.length)
|
||||
{
|
||||
uint32_t end = ffStrbufNextIndexS(&monitorsXml, start, "</connector>");
|
||||
if (end < monitorsXml.length)
|
||||
{
|
||||
ffStrbufSubstrBefore(&monitorsXml, end);
|
||||
const char* name = monitorsXml.chars + start + strlen("<connector>");
|
||||
data.primaryDisplayId = ffWaylandGenerateIdFromName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(data.primaryDisplayId)
|
||||
{
|
||||
FF_LIST_FOR_EACH(FFDisplayResult, d, data.result->displays)
|
||||
{
|
||||
if(d->id == data.primaryDisplayId)
|
||||
{
|
||||
d->primary = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//We successfully connected to wayland and detected the display.
|
||||
//So we can set set the session type to wayland.
|
||||
//This is used as an indicator that we are running wayland by the x11 backends.
|
||||
@@ -104,17 +199,23 @@ bool detectWayland(FFDisplayServerResult* result)
|
||||
void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
if (display->id) return;
|
||||
|
||||
if(ffStrStartsWith(name, "eDP-"))
|
||||
display->type = FF_DISPLAY_TYPE_BUILTIN;
|
||||
else if(ffStrStartsWith(name, "HDMI-"))
|
||||
display->type = FF_DISPLAY_TYPE_EXTERNAL;
|
||||
ffdsMatchDrmConnector(name, &display->edidName);
|
||||
if (!display->edidName.length)
|
||||
ffdsMatchDrmConnector(name, &display->edidName);
|
||||
display->id = ffWaylandGenerateIdFromName(name);
|
||||
ffStrbufAppendS(&display->name, name);
|
||||
}
|
||||
|
||||
void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output, const char* description)
|
||||
{
|
||||
WaylandDisplay* display = data;
|
||||
if (display->description.length) return;
|
||||
|
||||
while (*description == ' ') ++description;
|
||||
if (!ffStrEquals(description, "Unknown Display") && !ffStrContains(description, "(null)"))
|
||||
ffStrbufAppendS(&display->description, description);
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef enum WaylandProtocolType
|
||||
FF_WAYLAND_PROTOCOL_TYPE_NONE,
|
||||
FF_WAYLAND_PROTOCOL_TYPE_GLOBAL,
|
||||
FF_WAYLAND_PROTOCOL_TYPE_ZWLR,
|
||||
FF_WAYLAND_PROTOCOL_TYPE_KDE,
|
||||
} WaylandProtocolType;
|
||||
|
||||
typedef struct WaylandData
|
||||
@@ -26,6 +27,8 @@ typedef struct WaylandData
|
||||
struct wl_display* display;
|
||||
const struct wl_interface* ffwl_output_interface;
|
||||
WaylandProtocolType protocolType;
|
||||
uint64_t primaryDisplayId;
|
||||
struct wl_proxy* zxdgOutputManager;
|
||||
} WaylandData;
|
||||
|
||||
typedef struct WaylandDisplay
|
||||
@@ -40,6 +43,7 @@ typedef struct WaylandDisplay
|
||||
FFstrbuf name;
|
||||
FFstrbuf description;
|
||||
FFstrbuf edidName;
|
||||
uint64_t id;
|
||||
void* internal;
|
||||
} WaylandDisplay;
|
||||
|
||||
@@ -48,10 +52,24 @@ inline static void stubListener(void* data, ...)
|
||||
(void) data;
|
||||
}
|
||||
|
||||
inline static uint64_t ffWaylandGenerateIdFromName(const char* name)
|
||||
{
|
||||
uint64_t id = 0;
|
||||
size_t len = strlen(name);
|
||||
if (len > sizeof(id))
|
||||
memcpy(&id, name + (len - sizeof(id)), sizeof(id)); // copy the last 8 bytes
|
||||
else if (len > 0)
|
||||
memcpy(&id, name, len);
|
||||
return id;
|
||||
}
|
||||
|
||||
void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name);
|
||||
void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output, const char* description);
|
||||
|
||||
void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,414 @@
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol
|
||||
* Protocol to describe output regions
|
||||
*
|
||||
* @section page_desc_xdg_output_unstable_v1 Description
|
||||
*
|
||||
* This protocol aims at describing outputs in a way which is more in line
|
||||
* with the concept of an output on desktop oriented systems.
|
||||
*
|
||||
* Some information are more specific to the concept of an output for
|
||||
* a desktop oriented system and may not make sense in other applications,
|
||||
* such as IVI systems for example.
|
||||
*
|
||||
* Typically, the global compositor space on a desktop system is made of
|
||||
* a contiguous or overlapping set of rectangular regions.
|
||||
*
|
||||
* The logical_position and logical_size events defined in this protocol
|
||||
* might provide information identical to their counterparts already
|
||||
* available from wl_output, in which case the information provided by this
|
||||
* protocol should be preferred to their equivalent in wl_output. The goal is
|
||||
* to move the desktop specific concepts (such as output location within the
|
||||
* global compositor space, etc.) out of the core wl_output protocol.
|
||||
*
|
||||
* Warning! The protocol described in this file is experimental and
|
||||
* backward incompatible changes may be made. Backward compatible
|
||||
* changes may be added together with the corresponding interface
|
||||
* version bump.
|
||||
* Backward incompatible changes are done by bumping the version
|
||||
* number in the protocol and interface names and resetting the
|
||||
* interface version. Once the protocol is to be declared stable,
|
||||
* the 'z' prefix and the version number in the protocol and
|
||||
* interface names are removed and the interface version number is
|
||||
* reset.
|
||||
*
|
||||
* @section page_ifaces_xdg_output_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects
|
||||
* - @subpage page_iface_zxdg_output_v1 - compositor logical output region
|
||||
* @section page_copyright_xdg_output_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
* </pre>
|
||||
*/
|
||||
struct wl_output;
|
||||
struct zxdg_output_manager_v1;
|
||||
struct zxdg_output_v1;
|
||||
|
||||
#ifndef ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1
|
||||
* @section page_iface_zxdg_output_manager_v1_desc Description
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
* @section page_iface_zxdg_output_manager_v1_api API
|
||||
* See @ref iface_zxdg_output_manager_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_manager_v1_interface;
|
||||
#endif
|
||||
#ifndef ZXDG_OUTPUT_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_v1 zxdg_output_v1
|
||||
* @section page_iface_zxdg_output_v1_desc Description
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
* @section page_iface_zxdg_output_v1_api API
|
||||
* See @ref iface_zxdg_output_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
#endif
|
||||
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1
|
||||
|
||||
// /** @ingroup iface_zxdg_output_manager_v1 */
|
||||
// static inline void
|
||||
// zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_zxdg_output_manager_v1 */
|
||||
// static inline void *
|
||||
// zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
// }
|
||||
|
||||
// static inline uint32_t
|
||||
// zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @ingroup iface_zxdg_output_manager_v1
|
||||
// *
|
||||
// * Using this request a client can tell the server that it is not
|
||||
// * going to use the xdg_output_manager object anymore.
|
||||
// *
|
||||
// * Any objects already created through this instance are not affected.
|
||||
// */
|
||||
// static inline void
|
||||
// zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
// {
|
||||
// wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
// ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @ingroup iface_zxdg_output_manager_v1
|
||||
// *
|
||||
// * This creates a new xdg_output object for the given wl_output.
|
||||
// */
|
||||
// static inline struct zxdg_output_v1 *
|
||||
// zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output)
|
||||
// {
|
||||
// struct wl_proxy *id;
|
||||
|
||||
// id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
// ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output);
|
||||
|
||||
// return (struct zxdg_output_v1 *) id;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
* @struct zxdg_output_v1_listener
|
||||
*/
|
||||
struct zxdg_output_v1_listener {
|
||||
/**
|
||||
* position of the output within the global compositor space
|
||||
*
|
||||
* The position event describes the location of the wl_output
|
||||
* within the global compositor space.
|
||||
*
|
||||
* The logical_position event is sent after creating an xdg_output
|
||||
* (see xdg_output_manager.get_xdg_output) and whenever the
|
||||
* location of the output changes within the global compositor
|
||||
* space.
|
||||
* @param x x position within the global compositor space
|
||||
* @param y y position within the global compositor space
|
||||
*/
|
||||
void (*logical_position)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
/**
|
||||
* size of the output in the global compositor space
|
||||
*
|
||||
* The logical_size event describes the size of the output in the
|
||||
* global compositor space.
|
||||
*
|
||||
* Most regular Wayland clients should not pay attention to the
|
||||
* logical size and would rather rely on xdg_shell interfaces.
|
||||
*
|
||||
* Some clients such as Xwayland, however, need this to configure
|
||||
* their surfaces in the global compositor space as the compositor
|
||||
* may apply a different scale from what is advertised by the
|
||||
* output scaling property (to achieve fractional scaling, for
|
||||
* example).
|
||||
*
|
||||
* For example, for a wl_output mode 3840×2160 and a scale factor
|
||||
* 2:
|
||||
*
|
||||
* - A compositor not scaling the monitor viewport in its
|
||||
* compositing space will advertise a logical size of 3840×2160,
|
||||
*
|
||||
* - A compositor scaling the monitor viewport with scale factor 2
|
||||
* will advertise a logical size of 1920×1080,
|
||||
*
|
||||
* - A compositor scaling the monitor viewport using a fractional
|
||||
* scale of 1.5 will advertise a logical size of 2560×1440.
|
||||
*
|
||||
* For example, for a wl_output mode 1920×1080 and a 90 degree
|
||||
* rotation, the compositor will advertise a logical size of
|
||||
* 1080x1920.
|
||||
*
|
||||
* The logical_size event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the logical size
|
||||
* of the output changes, either as a result of a change in the
|
||||
* applied scale or because of a change in the corresponding output
|
||||
* mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||
* @param width width in global compositor space
|
||||
* @param height height in global compositor space
|
||||
*/
|
||||
void (*logical_size)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* all information about the output have been sent
|
||||
*
|
||||
* This event is sent after all other properties of an xdg_output
|
||||
* have been sent.
|
||||
*
|
||||
* This allows changes to the xdg_output properties to be seen as
|
||||
* atomic, even if they happen via multiple events.
|
||||
*
|
||||
* For objects version 3 onwards, this event is deprecated.
|
||||
* Compositors are not required to send it anymore and must send
|
||||
* wl_output.done instead.
|
||||
*/
|
||||
void (*done)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1);
|
||||
/**
|
||||
* name of this output
|
||||
*
|
||||
* Many compositors will assign names to their outputs, show them
|
||||
* to the user, allow them to be configured by name, etc. The
|
||||
* client may wish to know this name as well to offer the user
|
||||
* similar behaviors.
|
||||
*
|
||||
* The naming convention is compositor defined, but limited to
|
||||
* alphanumeric characters and dashes (-). Each name is unique
|
||||
* among all wl_output globals, but if a wl_output global is
|
||||
* destroyed the same name may be reused later. The names will also
|
||||
* remain consistent across sessions with the same hardware and
|
||||
* software configuration.
|
||||
*
|
||||
* Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc.
|
||||
* However, do not assume that the name is a reflection of an
|
||||
* underlying DRM connector, X11 connection, etc.
|
||||
*
|
||||
* The name event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output). This event is only sent once
|
||||
* per xdg_output, and the name does not change over the lifetime
|
||||
* of the wl_output global.
|
||||
*
|
||||
* This event is deprecated, instead clients should use
|
||||
* wl_output.name. Compositors must still support this event.
|
||||
* @param name output name
|
||||
* @since 2
|
||||
*/
|
||||
void (*name)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *name);
|
||||
/**
|
||||
* human-readable description of this output
|
||||
*
|
||||
* Many compositors can produce human-readable descriptions of
|
||||
* their outputs. The client may wish to know this description as
|
||||
* well, to communicate the user for various purposes.
|
||||
*
|
||||
* The description is a UTF-8 string with no convention defined for
|
||||
* its contents. Examples might include 'Foocorp 11" Display' or
|
||||
* 'Virtual X11 output via :1'.
|
||||
*
|
||||
* The description event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the description
|
||||
* changes. The description is optional, and may not be sent at
|
||||
* all.
|
||||
*
|
||||
* For objects of version 2 and lower, this event is only sent once
|
||||
* per xdg_output, and the description does not change over the
|
||||
* lifetime of the wl_output global.
|
||||
*
|
||||
* This event is deprecated, instead clients should use
|
||||
* wl_output.description. Compositors must still support this
|
||||
* event.
|
||||
* @param description output description
|
||||
* @since 2
|
||||
*/
|
||||
void (*description)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *description);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
static inline int
|
||||
zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const struct zxdg_output_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZXDG_OUTPUT_V1_DESTROY 0
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1
|
||||
|
||||
// /** @ingroup iface_zxdg_output_v1 */
|
||||
// static inline void
|
||||
// zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data)
|
||||
// {
|
||||
// wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data);
|
||||
// }
|
||||
|
||||
// /** @ingroup iface_zxdg_output_v1 */
|
||||
// static inline void *
|
||||
// zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
// {
|
||||
// return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1);
|
||||
// }
|
||||
|
||||
// static inline uint32_t
|
||||
// zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
// {
|
||||
// return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @ingroup iface_zxdg_output_v1
|
||||
// *
|
||||
// * Using this request a client can tell the server that it is not
|
||||
// * going to use the xdg_output object anymore.
|
||||
// */
|
||||
// static inline void
|
||||
// zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
// {
|
||||
// wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1,
|
||||
// ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
// }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
#ifdef FF_HAVE_WAYLAND
|
||||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
|
||||
static const struct wl_interface *xdg_output_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
&zxdg_output_v1_interface,
|
||||
NULL, // &wl_output_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_manager_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zxdg_output_manager_v1_interface = {
|
||||
"zxdg_output_manager_v1", 3,
|
||||
2, zxdg_output_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_events[] = {
|
||||
{ "logical_position", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "logical_size", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "done", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "name", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
{ "description", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zxdg_output_v1_interface = {
|
||||
"zxdg_output_v1", 3,
|
||||
1, zxdg_output_v1_requests,
|
||||
5, zxdg_output_v1_events,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -71,27 +71,27 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw
|
||||
wldata->refreshRate = current->refreshRate;
|
||||
}
|
||||
|
||||
static const struct zwlr_output_head_v1_listener headListener = {
|
||||
.name = (void*) ffWaylandOutputNameListener,
|
||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||
.physical_size = (void*) stubListener,
|
||||
.mode = waylandZwlrModeListener,
|
||||
.enabled = (void*) stubListener,
|
||||
.current_mode = waylandZwlrCurrentModeListener,
|
||||
.position = (void*) stubListener,
|
||||
.transform = waylandZwlrTransformListener,
|
||||
.scale = waylandZwlrScaleListener,
|
||||
.finished = (void*) stubListener,
|
||||
.make = (void*) stubListener,
|
||||
.model = (void*) stubListener,
|
||||
.serial_number = (void*) stubListener,
|
||||
.adaptive_sync = (void*) stubListener,
|
||||
};
|
||||
|
||||
static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output_manager_v1 *zwlr_output_manager_v1, struct zwlr_output_head_v1 *head)
|
||||
{
|
||||
WaylandData* wldata = data;
|
||||
|
||||
const struct zwlr_output_head_v1_listener headListener = {
|
||||
.name = (void*) ffWaylandOutputNameListener,
|
||||
.description = (void*) ffWaylandOutputDescriptionListener,
|
||||
.physical_size = (void*) stubListener,
|
||||
.mode = waylandZwlrModeListener,
|
||||
.enabled = (void*) stubListener,
|
||||
.current_mode = waylandZwlrCurrentModeListener,
|
||||
.position = (void*) stubListener,
|
||||
.transform = waylandZwlrTransformListener,
|
||||
.scale = waylandZwlrScaleListener,
|
||||
.finished = (void*) stubListener,
|
||||
.make = (void*) stubListener,
|
||||
.model = (void*) stubListener,
|
||||
.serial_number = (void*) stubListener,
|
||||
.adaptive_sync = (void*) stubListener,
|
||||
};
|
||||
|
||||
FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandZwlrMode));
|
||||
WaylandDisplay display = {
|
||||
.parent = wldata,
|
||||
@@ -160,7 +160,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
|
||||
: &display.name,
|
||||
display.type,
|
||||
false,
|
||||
0
|
||||
display.id
|
||||
);
|
||||
|
||||
ffStrbufDestroy(&display.description);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/mallocHelper.h"
|
||||
@@ -11,8 +12,8 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/user.h>
|
||||
#else
|
||||
#include "common/io/io.h"
|
||||
#elif defined(__sun)
|
||||
#include <procfs.h>
|
||||
#endif
|
||||
|
||||
static const char* parseEnv(void)
|
||||
@@ -70,11 +71,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
return;
|
||||
|
||||
if(
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin") ||
|
||||
ffStrStartsWithIgnCase(name, "kwin_") ||
|
||||
ffStrEndsWithIgnCase(name, "-kwin_wayland") ||
|
||||
ffStrEndsWithIgnCase(name, "-kwin_x11")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
|
||||
@@ -85,7 +83,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
ffStrEqualsIgnCase(name, "Mutter")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
|
||||
else if(
|
||||
ffStrEqualsIgnCase(name, "cinnamon-session") ||
|
||||
ffStrEqualsIgnCase(name, "cinnamon") ||
|
||||
ffStrStartsWithIgnCase(name, "cinnamon-") ||
|
||||
ffStrEqualsIgnCase(name, "Muffin") ||
|
||||
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
|
||||
@@ -206,7 +205,7 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
|
||||
else if(
|
||||
ffStrEqualsIgnCase(name, "LXQt") ||
|
||||
ffStrEqualsIgnCase(name, "X-LXQT") ||
|
||||
ffStrEqualsIgnCase(name, "X-LXQt") ||
|
||||
ffStrEqualsIgnCase(name, "lxqt-session")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
||||
@@ -302,6 +301,42 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
break;
|
||||
}
|
||||
#elif defined(__sun)
|
||||
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
|
||||
if(procdir == NULL)
|
||||
return "opendir(\"/proc\") failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&procPath, "/proc/");
|
||||
|
||||
uint32_t procPathLength = procPath.length;
|
||||
|
||||
struct dirent* dirent;
|
||||
while((dirent = readdir(procdir)) != NULL)
|
||||
{
|
||||
if (!ffCharIsDigit(dirent->d_name[0]))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&procPath, dirent->d_name);
|
||||
ffStrbufAppendS(&procPath, "/psinfo");
|
||||
psinfo_t proc;
|
||||
if (ffReadFileData(procPath.chars, sizeof(proc), &proc) == sizeof(proc))
|
||||
{
|
||||
ffStrbufSubstrBefore(&procPath, procPathLength);
|
||||
|
||||
if (proc.pr_uid != userId)
|
||||
continue;
|
||||
|
||||
if(result->dePrettyName.length == 0)
|
||||
applyPrettyNameIfDE(result, proc.pr_fname);
|
||||
|
||||
if(result->wmPrettyName.length == 0)
|
||||
applyNameIfWM(result, proc.pr_fname);
|
||||
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
|
||||
if(procdir == NULL)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results /* list of FFstrbuf */);
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "detection/dns/dns.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
FF_AUTO_CLOSE_FILE FILE* file = fopen(FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf", "r");
|
||||
if (!file)
|
||||
return "fopen (" FASTFETCH_TARGET_DIR_ROOT "/etc/resolv.conf) failed";
|
||||
|
||||
FF_AUTO_FREE char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while (getline(&line, &len, file) != -1)
|
||||
{
|
||||
if (ffStrStartsWith(line, "nameserver"))
|
||||
{
|
||||
const char* nameserver = line + strlen("nameserver");
|
||||
while (*nameserver == ' ' || *nameserver == '\t')
|
||||
nameserver++;
|
||||
if (*nameserver == '\0') continue;
|
||||
|
||||
if ((ffStrContainsC(nameserver, ':') && !(options->showType & FF_DNS_TYPE_IPV6_BIT)) ||
|
||||
(ffStrContainsC(nameserver, '.') && !(options->showType & FF_DNS_TYPE_IPV4_BIT)))
|
||||
continue;
|
||||
|
||||
FFstrbuf* item = (FFstrbuf*) ffListAdd(results);
|
||||
ffStrbufInitS(item, nameserver);
|
||||
ffStrbufTrimRightSpace(item);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "detection/dns/dns.h"
|
||||
#include "common/netif/netif.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
const char* ffDetectDNS(FFDNSOptions* options, FFlist* results)
|
||||
{
|
||||
IP_ADAPTER_ADDRESSES* FF_AUTO_FREE adapter_addresses = NULL;
|
||||
|
||||
// Multiple attempts in case interfaces change while
|
||||
// we are in the middle of querying them.
|
||||
DWORD adapter_addresses_buffer_size = 0;
|
||||
for (int attempts = 0;; ++attempts)
|
||||
{
|
||||
if (adapter_addresses_buffer_size)
|
||||
{
|
||||
adapter_addresses = (IP_ADAPTER_ADDRESSES*)realloc(adapter_addresses, adapter_addresses_buffer_size);
|
||||
assert(adapter_addresses);
|
||||
}
|
||||
|
||||
DWORD error = GetAdaptersAddresses(
|
||||
options->showType & FF_DNS_TYPE_IPV4_BIT
|
||||
? options->showType & FF_DNS_TYPE_IPV6_BIT ? AF_UNSPEC : AF_INET
|
||||
: AF_INET6,
|
||||
GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME,
|
||||
NULL,
|
||||
adapter_addresses,
|
||||
&adapter_addresses_buffer_size);
|
||||
|
||||
if (error == ERROR_SUCCESS)
|
||||
break;
|
||||
else if (ERROR_BUFFER_OVERFLOW == error && attempts < 4)
|
||||
continue;
|
||||
else
|
||||
return "GetAdaptersAddresses() failed";
|
||||
}
|
||||
|
||||
uint32_t defaultRouteIfIndex = ffNetifGetDefaultRouteIfIndex();
|
||||
// Iterate through all of the adapters
|
||||
for (IP_ADAPTER_ADDRESSES* adapter = adapter_addresses; adapter; adapter = adapter->Next)
|
||||
{
|
||||
if (adapter->IfIndex != defaultRouteIfIndex) continue;
|
||||
if (adapter->OperStatus != IfOperStatusUp) continue;
|
||||
|
||||
for (IP_ADAPTER_DNS_SERVER_ADDRESS_XP * ifa = adapter->FirstDnsServerAddress; ifa; ifa = ifa->Next)
|
||||
{
|
||||
FFstrbuf* item = (FFstrbuf*) ffListAdd(results);
|
||||
if (ifa->Address.lpSockaddr->sa_family == AF_INET)
|
||||
{
|
||||
SOCKADDR_IN* ipv4 = (SOCKADDR_IN*) ifa->Address.lpSockaddr;
|
||||
ffStrbufInitA(item, INET_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, item->chars, item->allocated);
|
||||
}
|
||||
else if (ifa->Address.lpSockaddr->sa_family == AF_INET6)
|
||||
{
|
||||
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
|
||||
ffStrbufInitA(item, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, item->chars, item->allocated);
|
||||
}
|
||||
ffStrbufRecalculateLength(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -26,6 +26,8 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
return "$VISUAL or $EDITOR not set";
|
||||
}
|
||||
|
||||
if (!instance.config.general.detectVersion) return NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
if (result->name.chars[0] != '/')
|
||||
{
|
||||
@@ -90,6 +92,7 @@ const char* ffDetectEditor(FFEditorResult* result)
|
||||
ffStrbufStartsWithS(&result->exe, "emacs-") || // emacs-29.3
|
||||
ffStrbufEqualS(&result->exe, "hx") ||
|
||||
ffStrbufEqualS(&result->exe, "code") ||
|
||||
ffStrbufEqualS(&result->exe, "pluma") ||
|
||||
ffStrbufEqualS(&result->exe, "sublime_text")
|
||||
) param = "--version";
|
||||
else if (
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
typedef struct FFFontResult
|
||||
{
|
||||
/**
|
||||
* Linux / BSD: QT, GTK2, GTK3, GTK4
|
||||
* Linux / BSD: Qt, GTK2, GTK3, GTK4
|
||||
* MacOS: System, User, System Mono, User Mono
|
||||
* Windows: Caption, Menu, Message, Status
|
||||
* Other: Unset, Unset, Unset, Unset
|
||||
|
||||
@@ -9,7 +9,7 @@ static void generateString(FFFontResult* font)
|
||||
if(font->fonts[0].length > 0)
|
||||
{
|
||||
ffStrbufAppend(&font->display, &font->fonts[0]);
|
||||
ffStrbufAppendS(&font->display, " [QT]");
|
||||
ffStrbufAppendS(&font->display, " [Qt]");
|
||||
|
||||
for(uint8_t i = 1; i < sizeof(font->fonts) / sizeof(font->fonts[0]); i++)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/vulkan/vulkan.h"
|
||||
#include "detection/opencl/opencl.h"
|
||||
#include "detection/opengl/opengl.h"
|
||||
|
||||
const char* FF_GPU_VENDOR_NAME_APPLE = "Apple";
|
||||
@@ -41,6 +42,8 @@ const char* detectByOpenGL(FFlist* gpus)
|
||||
ffStrbufInit(&result.renderer);
|
||||
ffStrbufInit(&result.vendor);
|
||||
ffStrbufInit(&result.slv);
|
||||
ffStrbufInit(&result.library);
|
||||
|
||||
const char* error = ffDetectOpenGL(&instance.config.modules.openGL, &result);
|
||||
if (!error)
|
||||
{
|
||||
@@ -74,6 +77,7 @@ const char* detectByOpenGL(FFlist* gpus)
|
||||
ffStrbufDestroy(&result.renderer);
|
||||
ffStrbufDestroy(&result.vendor);
|
||||
ffStrbufDestroy(&result.slv);
|
||||
ffStrbufDestroy(&result.library);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -94,6 +98,16 @@ const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENCL)
|
||||
{
|
||||
FFOpenCLResult* opencl = ffDetectOpenCL();
|
||||
if (!opencl->error && opencl->gpus.length > 0)
|
||||
{
|
||||
ffListDestroy(result);
|
||||
ffListInitMove(result, &opencl->gpus);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (options->detectionMethod <= FF_GPU_DETECTION_METHOD_OPENGL)
|
||||
{
|
||||
if (detectByOpenGL(result) == NULL)
|
||||
|
||||
@@ -32,7 +32,7 @@ typedef struct FFGPUResult
|
||||
FFstrbuf platformApi;
|
||||
double temperature;
|
||||
int32_t coreCount;
|
||||
double frequency; // Real time clock frequency in GHz
|
||||
double frequency; // Maximum time clock frequency in GHz
|
||||
FFGPUMemory dedicated;
|
||||
FFGPUMemory shared;
|
||||
uint64_t deviceId; // Used internally, may be uninitialized
|
||||
@@ -43,6 +43,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
|
||||
|
||||
const char* ffGetGPUVendorString(unsigned vendorId);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun)
|
||||
void ffGPUParsePciIds(FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu);
|
||||
#endif
|
||||
|
||||
@@ -19,13 +19,12 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
inited = true;
|
||||
FF_LIBRARY_LOAD(libags, NULL, "dlopen amd_ags failed", soName , 1);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsInitialize)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libags, agsDeInitialize)
|
||||
|
||||
struct AGSContext* apiHandle;
|
||||
if (ffagsInitialize(AGS_CURRENT_VERSION, NULL, &apiHandle, &gpuInfo) != AGS_SUCCESS)
|
||||
return "loading ags library failed";
|
||||
|
||||
ffagsDeInitialize(apiHandle);
|
||||
// agsDeInitialize will free pointers allocated in gpuInfo. Just leak them.
|
||||
}
|
||||
|
||||
if (gpuInfo.numDevices == 0)
|
||||
@@ -63,5 +62,8 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
|
||||
if (result.frequency)
|
||||
*result.frequency = device->coreClock / 1000.; // Maximum frequency
|
||||
|
||||
if (result.type)
|
||||
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
ffGPUParsePciIds(&pciids, pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
|
||||
}
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || options->driverSpecific))
|
||||
{
|
||||
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
|
||||
@@ -98,7 +97,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
|
||||
if (gpu->dedicated.total != FF_GPU_VMEM_SIZE_UNSET)
|
||||
gpu->type = gpu->dedicated.total > (uint64_t)1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
#include "detection/vulkan/vulkan.h"
|
||||
#include "detection/temps/temps_linux.h"
|
||||
#include "detection/cpu/cpu.h"
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#endif
|
||||
|
||||
#define FF_STR_INDIR(x) #x
|
||||
#define FF_STR(x) FF_STR_INDIR(x)
|
||||
|
||||
@@ -35,29 +32,42 @@
|
||||
|
||||
static bool pciDetectDriver(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, FF_MAYBE_UNUSED const char* drmKey)
|
||||
{
|
||||
uint32_t pciDirLength = pciDir->length;
|
||||
ffStrbufAppendS(pciDir, "/driver");
|
||||
char pathBuf[PATH_MAX];
|
||||
ssize_t resultLength = readlink(pciDir->chars, pathBuf, sizeof(pathBuf));
|
||||
if(resultLength > 0)
|
||||
{
|
||||
const char* slash = memrchr(pathBuf, '/', (size_t) resultLength);
|
||||
if (slash)
|
||||
{
|
||||
slash++;
|
||||
ffStrbufSetNS(&gpu->driver, (uint32_t) (resultLength - (slash - pathBuf)), slash);
|
||||
}
|
||||
if(resultLength <= 0) return false;
|
||||
|
||||
const char* slash = memrchr(pathBuf, '/', (size_t) resultLength);
|
||||
if (slash)
|
||||
{
|
||||
slash++;
|
||||
ffStrbufSetNS(&gpu->driver, (uint32_t) (resultLength - (slash - pathBuf)), slash);
|
||||
}
|
||||
|
||||
if (instance.config.general.detectVersion)
|
||||
{
|
||||
ffStrbufAppendS(pciDir, "/module/version");
|
||||
if (ffReadFileBuffer(pciDir->chars, buffer))
|
||||
{
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
ffStrbufAppendC(&gpu->driver, ' ');
|
||||
ffStrbufAppend(&gpu->driver, buffer);
|
||||
return true;
|
||||
}
|
||||
else if (ffStrbufEqualS(&gpu->driver, "zx"))
|
||||
{
|
||||
ffStrbufSubstrBefore(pciDir, pciDirLength);
|
||||
ffStrbufAppendS(pciDir, "/zx_info/driver_version");
|
||||
if (ffReadFileBuffer(pciDir->chars, buffer))
|
||||
{
|
||||
ffStrbufTrimRightSpace(buffer);
|
||||
ffStrbufAppendC(&gpu->driver, ' ');
|
||||
ffStrbufAppend(&gpu->driver, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer)
|
||||
@@ -81,7 +91,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
|
||||
|
||||
const uint32_t hwmonLen = pciDir->length;
|
||||
ffStrbufAppendS(pciDir, "in1_input"); // Northbridge voltage in millivolts (APUs only)
|
||||
if (ffPathExists(pciDir->chars, FF_PATHTYPE_FILE))
|
||||
if (ffPathExists(pciDir->chars, FF_PATHTYPE_ANY))
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
else
|
||||
gpu->type = FF_GPU_TYPE_DISCRETE;
|
||||
@@ -95,11 +105,6 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
|
||||
gpu->temperature = (double) value / 1000;
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(pciDir, hwmonLen);
|
||||
ffStrbufAppendS(pciDir, "freq1_input"); // The gfx/compute clock in hertz
|
||||
if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0)))
|
||||
gpu->frequency = (double) value / (1000 * 1000 * 1000);
|
||||
|
||||
if (options->driverSpecific)
|
||||
{
|
||||
ffStrbufSubstrBefore(pciDir, pciDirLen);
|
||||
@@ -200,6 +205,14 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
if (sscanf(pPciPath, "%" SCNx32 ":%" SCNx32 ":%" SCNx32 ".%" SCNx32, &pciDomain, &pciBus, &pciDevice, &pciFunc) != 4)
|
||||
return "Invalid PCI device path";
|
||||
|
||||
ffStrbufAppendS(deviceDir, "/enable");
|
||||
if (ffReadFileBuffer(deviceDir->chars, buffer))
|
||||
{
|
||||
if (!ffStrbufStartsWithC(buffer, '1'))
|
||||
return "GPU disabled";
|
||||
}
|
||||
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString((uint16_t) vendorId));
|
||||
ffStrbufInit(&gpu->name);
|
||||
@@ -261,7 +274,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
}
|
||||
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
|
||||
{
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
if (options->temp || options->driverSpecific)
|
||||
{
|
||||
ffDetectNvidiaGpuInfo(&(FFGpuDriverCondition) {
|
||||
@@ -277,10 +289,9 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
}, "libnvidia-ml.so");
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
|
||||
if (gpu->type == FF_GPU_TYPE_UNKNOWN)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "gpu.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/processing.h"
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
// SunOS requires root permission to query PCI device list, except `/usr/bin/scanpci`
|
||||
// Same behavior can be observed with `cp $(which scanpci) /tmp/ && /tmp/scanpci`
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
const char* error = ffProcessAppendStdOut(&buffer, (char* const[]) {
|
||||
"scanpci",
|
||||
"-v",
|
||||
NULL,
|
||||
});
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!ffStrbufStartsWithS(&buffer, "\npci "))
|
||||
return "Invalid scanpci result";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY pciids = ffStrbufCreate();
|
||||
|
||||
// pci bus 0x0000 cardnum 0x00 function 0x00: vendor 0x1414 device 0x008e
|
||||
// Device unknown
|
||||
// CardVendor 0x0000 card 0x0000 (Card unknown)
|
||||
// STATUS 0x0010 COMMAND 0x0007
|
||||
// CLASS 0x03 0x02 0x00 REVISION 0x00
|
||||
// BIST 0x00 HEADER 0x00 LATENCY 0x00 CACHE 0x00
|
||||
// MAX_LAT 0x00 MIN_GNT 0x00 INT_PIN 0x00 INT_LINE 0x00
|
||||
|
||||
for (
|
||||
const char* pclass = strstr(buffer.chars, "\n CLASS 0x03 ");
|
||||
pclass;
|
||||
pclass = strstr(pclass, "\n CLASS 0x03 ")
|
||||
)
|
||||
{
|
||||
// find the start of device entry
|
||||
const char* pstart = memrchr(buffer.chars, '\n', (size_t) (pclass - buffer.chars));
|
||||
while (pstart[1] != 'p')
|
||||
pstart = memrchr(buffer.chars, '\n', (size_t) (pstart - buffer.chars - 1));
|
||||
++pstart;
|
||||
|
||||
uint32_t vendorId, deviceId;
|
||||
if (sscanf(pstart, "pci %*[^:]: vendor %x device %x",
|
||||
&vendorId, &deviceId) != 2)
|
||||
return "PCI info not found, invalid scanpci result";
|
||||
|
||||
pclass += strlen("\n CLASS 0x03 ");
|
||||
uint32_t subclass = (uint32_t) strtoul(pclass, NULL, 16);
|
||||
pclass += strlen("0x02 0x00 REVISION ");
|
||||
uint32_t revision = (uint32_t) strtoul(pclass, NULL, 16);
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
ffStrbufInit(&gpu->platformApi);
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->deviceId = 0;
|
||||
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
||||
|
||||
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD)
|
||||
{
|
||||
char query[32];
|
||||
snprintf(query, sizeof(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision);
|
||||
ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name);
|
||||
}
|
||||
|
||||
if (gpu->name.length == 0)
|
||||
{
|
||||
if (pciids.length == 0)
|
||||
ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids);
|
||||
ffGPUParsePciIds(&pciids, (uint8_t) subclass, (uint16_t) vendorId, (uint16_t) deviceId, gpu);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "gpu.h"
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#include "util/windows/unicode.h"
|
||||
#include "util/windows/registry.h"
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
#include "detection/gpu/gpu_driver_specific.h"
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
|
||||
@@ -13,7 +10,6 @@ static int isGpuNameEqual(const FFGPUResult* gpu, const FFstrbuf* name)
|
||||
return ffStrbufEqual(&gpu->name, name);
|
||||
}
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&ffDetectNvidiaGpuInfo)* pDetectFn, const char** pDllName)
|
||||
{
|
||||
if (vendor == FF_GPU_VENDOR_NAME_NVIDIA)
|
||||
@@ -48,7 +44,6 @@ static inline bool getDriverSpecificDetectionFn(const char* vendor, __typeof__(&
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
|
||||
const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* gpus)
|
||||
{
|
||||
@@ -144,13 +139,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
__typeof__(&ffDetectNvidiaGpuInfo) detectFn;
|
||||
const char* dllName;
|
||||
|
||||
if (getDriverSpecificDetectionFn(gpu->vendor.chars, &detectFn, &dllName) && (options->temp || options->driverSpecific))
|
||||
{
|
||||
if (vendorId && deviceId && subSystemId && revId)
|
||||
if (vendorId && deviceId && subSystemId)
|
||||
{
|
||||
detectFn(
|
||||
&(FFGpuDriverCondition) {
|
||||
@@ -168,13 +162,12 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
},
|
||||
dllName
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif // FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -104,7 +104,6 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
const char* vendorStr = ffGetGPUVendorString((unsigned) hardwareId.vendorID);
|
||||
ffStrbufSetStatic(&gpu->vendor, vendorStr);
|
||||
|
||||
#ifdef FF_USE_PROPRIETARY_GPU_DRIVER_API
|
||||
if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA && (options->driverSpecific || options->temp))
|
||||
{
|
||||
FFGpuDriverCondition cond = {
|
||||
@@ -121,10 +120,9 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
|
||||
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
|
||||
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
|
||||
.type = &gpu->type,
|
||||
.frequency = &gpu->frequency,
|
||||
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
|
||||
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ typedef struct {
|
||||
// Allocated device memory (in bytes)
|
||||
unsigned long long used;
|
||||
} nvmlMemory_v2_t;
|
||||
enum { nvmlMemory_v2 = 2 };
|
||||
// https://github.com/NVIDIA/nvidia-settings/issues/78#issuecomment-1012837988
|
||||
enum { nvmlMemory_v2 = (unsigned int)(sizeof(nvmlMemory_v2_t) | (2 << 24U)) };
|
||||
|
||||
// https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64
|
||||
// Clock types
|
||||
|
||||
@@ -135,6 +135,34 @@ static void detectLXQt(FFQtResult* result)
|
||||
ffParsePropFileConfig("pcmanfm-qt/lxqt/settings.conf", "Wallpaper=", &result->wallpaper);
|
||||
}
|
||||
|
||||
static void detectQtCt(char qver, FFQtResult* result)
|
||||
{
|
||||
// qt5ct and qt6ct are technically separate applications, but they're both
|
||||
// by the same author and qt6ct understands qt5ct in qt6 applications as well.
|
||||
char file[] = "qtXct/qtXct.conf";
|
||||
file[2] = file[8] = qver;
|
||||
ffParsePropFileConfigValues(file, 3, (FFpropquery[]) {
|
||||
{"style=", &result->widgetStyle},
|
||||
{"icon_theme=", &result->icons},
|
||||
{"general=", &result->font}
|
||||
});
|
||||
|
||||
if (ffStrbufStartsWithC(&result->font, '@'))
|
||||
{
|
||||
// See QVariant notes on https://doc.qt.io/qt-5/qsettings.html and
|
||||
// https://github.com/fastfetch-cli/fastfetch/issues/1053#issuecomment-2197254769
|
||||
// Thankfully, newer versions use the more common font encoding.
|
||||
ffStrbufSetNS(&result->font, 5, file);
|
||||
}
|
||||
}
|
||||
|
||||
static void detectKvantum(FFQtResult* result)
|
||||
{
|
||||
ffParsePropFileConfigValues("Kvantum/kvantum.kvconfig", 1, (FFpropquery[]) {
|
||||
{"theme=", &result->widgetStyle},
|
||||
});
|
||||
}
|
||||
|
||||
const FFQtResult* ffDetectQt(void)
|
||||
{
|
||||
static FFQtResult result;
|
||||
@@ -151,11 +179,20 @@ const FFQtResult* ffDetectQt(void)
|
||||
ffStrbufInit(&result.wallpaper);
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
const char *qplatformtheme = getenv("QT_QPA_PLATFORMTHEME");
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA))
|
||||
detectPlasma(&result);
|
||||
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
|
||||
detectLXQt(&result);
|
||||
else if(ffStrSet(qplatformtheme) && (ffStrEquals(qplatformtheme, "qt5ct") || ffStrEquals(qplatformtheme, "qt6ct")))
|
||||
detectQtCt(qplatformtheme[2], &result);
|
||||
|
||||
if(ffStrbufEqualS(&result.widgetStyle, "kvantum") || ffStrbufEqualS(&result.widgetStyle, "kvantum-dark"))
|
||||
{
|
||||
ffStrbufClear(&result.widgetStyle);
|
||||
detectKvantum(&result);
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
@@ -78,12 +78,15 @@ const char* ffDetectHost(FFHostResult* host)
|
||||
ffStrbufAppendF(&host->name, " - %s", wslDistroName);
|
||||
ffStrbufAppendS(&host->family, "WSL");
|
||||
|
||||
ffProcessAppendStdOut(&host->version, (char* const[]){
|
||||
"wslinfo",
|
||||
"--wsl-version",
|
||||
"-n",
|
||||
NULL,
|
||||
}); // supported in 2.2.3 and later
|
||||
if (instance.config.general.detectVersion)
|
||||
{
|
||||
ffProcessAppendStdOut(&host->version, (char* const[]){
|
||||
"wslinfo",
|
||||
"--wsl-version",
|
||||
"-n",
|
||||
NULL,
|
||||
}); // supported in 2.2.3 and later
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "host.h"
|
||||
|
||||
const char* ffDetectHost(FFHostResult* host)
|
||||
{
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
@@ -23,7 +23,7 @@ const char* ffDetectIcons(FFIconsResult* result)
|
||||
if(plasma->length > 0)
|
||||
{
|
||||
ffStrbufAppend(&result->icons1, plasma);
|
||||
ffStrbufAppendS(&result->icons1, " [QT]");
|
||||
ffStrbufAppendS(&result->icons1, " [Qt]");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -17,38 +17,41 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
|
||||
ffStrbufSetS(&result->exe, buf);
|
||||
}
|
||||
|
||||
if (ffStrbufEqualS(&result->name, "systemd"))
|
||||
if (instance.config.general.detectVersion)
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
ffStrbufEndsWithS(&result->exe, "/systemd") ? result->exe.chars : "systemctl", // use exe path in case users have another systemd installed
|
||||
"--version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
if (ffStrbufEqualS(&result->name, "systemd"))
|
||||
{
|
||||
uint32_t iStart = ffStrbufFirstIndexC(&result->version, '(');
|
||||
if (iStart < result->version.length)
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
ffStrbufEndsWithS(&result->exe, "/systemd") ? result->exe.chars : "systemctl", // use exe path in case users have another systemd installed
|
||||
"--version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
{
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ')');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
uint32_t iStart = ffStrbufFirstIndexC(&result->version, '(');
|
||||
if (iStart < result->version.length)
|
||||
{
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ')');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ffStrbufEqualS(&result->name, "launchd"))
|
||||
{
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
"/bin/launchctl",
|
||||
"version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
else if (ffStrbufEqualS(&result->name, "launchd"))
|
||||
{
|
||||
uint32_t iStart = ffStrbufFirstIndexS(&result->version, "Version ");
|
||||
if (iStart < result->version.length)
|
||||
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
|
||||
"/bin/launchctl",
|
||||
"version",
|
||||
NULL,
|
||||
}) == NULL && result->version.length)
|
||||
{
|
||||
iStart += (uint32_t) strlen("Version");
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ':');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
uint32_t iStart = ffStrbufFirstIndexS(&result->version, "Version ");
|
||||
if (iStart < result->version.length)
|
||||
{
|
||||
iStart += (uint32_t) strlen("Version");
|
||||
uint32_t iEnd = ffStrbufNextIndexC(&result->version, iStart + 1, ':');
|
||||
ffStrbufSubstrBefore(&result->version, iEnd);
|
||||
ffStrbufSubstrAfter(&result->version, iStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "libc.h"
|
||||
|
||||
const char* ffDetectLibc(FFLibcResult* result)
|
||||
{
|
||||
result->name = "Unknown";
|
||||
result->version = NULL;
|
||||
return NULL;
|
||||
}
|
||||
+17
-15
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define FF_SYSTEMD_SESSIONS_PATH "/var/run/systemd/sessions/"
|
||||
#define FF_SYSTEMD_SESSIONS_PATH "/run/systemd/sessions/"
|
||||
#define FF_SYSTEMD_USERS_PATH "/run/systemd/users/"
|
||||
|
||||
static const char* getGdmVersion(FFstrbuf* version)
|
||||
@@ -143,7 +143,7 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{
|
||||
// On some incorrectly configured systems, $XDG_SESSION_ID is not set. Try finding it ourself
|
||||
// WARNING: This is private data. Do not parse
|
||||
ffStrbufAppendF(&path, "/run/systemd/users/%d", getuid());
|
||||
ffStrbufSetF(&path, FF_SYSTEMD_USERS_PATH "%d", getuid());
|
||||
|
||||
// This is actually buggy, and assumes current user is using DE
|
||||
// `sd_pid_get_session` can be a better option, but we need to find a pid to use
|
||||
@@ -151,10 +151,9 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{"DISPLAY=", &sessionId},
|
||||
}))
|
||||
return "Failed to get $XDG_SESSION_ID";
|
||||
ffStrbufClear(&path);
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&path, "/var/run/systemd/sessions/");
|
||||
ffStrbufSetS(&path, FF_SYSTEMD_SESSIONS_PATH);
|
||||
ffStrbufAppend(&path, &sessionId);
|
||||
|
||||
// WARNING: This is private data. Do not parse
|
||||
@@ -162,18 +161,21 @@ const char* ffDetectLM(FFLMResult* result)
|
||||
{"SERVICE=", &result->service},
|
||||
{"TYPE=", &result->type},
|
||||
}))
|
||||
return "Failed to parse /run/systemd/sessions/$XDG_SESSION_ID";
|
||||
return "Failed to parse " FF_SYSTEMD_SESSIONS_PATH "$XDG_SESSION_ID";
|
||||
|
||||
if (ffStrbufStartsWithS(&result->service, "gdm"))
|
||||
getGdmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "sddm"))
|
||||
getSddmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "xfwm"))
|
||||
getXfwmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "lightdm"))
|
||||
getLightdmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "sshd"))
|
||||
getSshdVersion(&result->version);
|
||||
if (instance.config.general.detectVersion)
|
||||
{
|
||||
if (ffStrbufStartsWithS(&result->service, "gdm"))
|
||||
getGdmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "sddm"))
|
||||
getSddmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "xfwm"))
|
||||
getXfwmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "lightdm"))
|
||||
getLightdmVersion(&result->version);
|
||||
else if (ffStrbufStartsWithS(&result->service, "sshd"))
|
||||
getSshdVersion(&result->version);
|
||||
}
|
||||
|
||||
// Correct char cases
|
||||
if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_WAYLAND))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "detection/loadavg/loadavg.h"
|
||||
|
||||
#include <sys/loadavg.h>
|
||||
|
||||
const char* ffDetectLoadavg(double result[3])
|
||||
{
|
||||
return getloadavg(result, 3) == 3 ? NULL : "getloadavg() failed";
|
||||
}
|
||||
@@ -8,6 +8,7 @@ typedef struct FFLocalIpResult
|
||||
FFstrbuf ipv4;
|
||||
FFstrbuf ipv6;
|
||||
FFstrbuf mac;
|
||||
int32_t mtu;
|
||||
bool defaultRoute;
|
||||
} FFLocalIpResult;
|
||||
|
||||
|
||||
@@ -10,12 +10,16 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#include <net/if_dl.h>
|
||||
#else
|
||||
#include <netpacket/packet.h>
|
||||
#endif
|
||||
#ifdef __sun
|
||||
#include <sys/sockio.h>
|
||||
#endif
|
||||
|
||||
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool defaultRoute, bool firstOnly)
|
||||
{
|
||||
@@ -35,6 +39,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
@@ -90,7 +95,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
|
||||
char addressBuffer[INET_ADDRSTRLEN + 4];
|
||||
char addressBuffer[INET_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
@@ -100,7 +105,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 4, "/%d", cidr);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +117,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
continue;
|
||||
|
||||
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 4];
|
||||
char addressBuffer[INET6_ADDRSTRLEN + 16];
|
||||
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
|
||||
|
||||
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
|
||||
@@ -125,7 +130,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (cidr != 0)
|
||||
{
|
||||
size_t len = strlen(addressBuffer);
|
||||
snprintf(addressBuffer + len, 4, "/%d", cidr);
|
||||
snprintf(addressBuffer + len, 16, "/%d", cidr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,5 +165,26 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
|
||||
if (ifAddrStruct) freeifaddrs(ifAddrStruct);
|
||||
|
||||
FF_AUTO_CLOSE_FD int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd > 0)
|
||||
{
|
||||
FF_LIST_FOR_EACH(FFLocalIpResult, iface, *results)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1);
|
||||
if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0)
|
||||
iface->mtu = (int32_t) ifr.ifr_mtu;
|
||||
|
||||
#ifdef __sun
|
||||
if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
|
||||
{
|
||||
const uint8_t* ptr = (uint8_t*) ifr.ifr_addr.sa_data; // NOT ifr_enaddr
|
||||
ffStrbufSetF(&iface->mac, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,11 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
|
||||
ffStrbufInit(&ip->ipv6);
|
||||
ffStrbufInit(&ip->mac);
|
||||
ip->defaultRoute = defaultRoute;
|
||||
ip->mtu = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip = ffListGet(list, list->length - 1);
|
||||
ip = FF_LIST_GET(FFLocalIpResult, *list, list->length - 1);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
@@ -147,6 +148,9 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
if (typesToAdd == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newIp)
|
||||
FF_LIST_GET(FFLocalIpResult, *results, results->length - 1)->mtu = (int32_t) adapter->Mtu;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -20,6 +20,10 @@ const FFMediaResult* ffDetectMedia(void)
|
||||
|
||||
if(result.song.length == 0 && result.error.length == 0)
|
||||
ffStrbufAppendS(&result.error, "No media found");
|
||||
ffStrbufTrimRightSpace(&result.song);
|
||||
ffStrbufTrimRightSpace(&result.artist);
|
||||
ffStrbufTrimRightSpace(&result.album);
|
||||
ffStrbufTrimRightSpace(&result.player);
|
||||
}
|
||||
|
||||
return &result;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user