Compare commits

...

147 Commits

Author SHA1 Message Date
Carter Li 8e5017aa3a Merge pull request #1123 from fastfetch-cli/dev
Release: v2.20.0
2024-07-26 10:27:31 +08:00
李通洲 dc89336fc1 Release: v2.20.0 2024-07-26 09:51:51 +08:00
李通洲 952152edf0 Global (macOS): always check NULL after IORegistryEntryCreateCFProperty 2024-07-26 08:46:34 +08:00
李通洲 6862747c48 GPU (macOS): fix possible segfault when detecting GPU frequency (M1 Air)
Fix #1122
2024-07-26 08:46:34 +08:00
李通洲 f91be6442d Android (Linux): detect MTK CPU part name 2024-07-26 08:46:34 +08:00
Carter Li bdce8ea3a1 Logo (Image): fix paddingTop doesn't work with position: right 2024-07-25 21:41:15 +08:00
Carter Li 44c8fa0470 Logo (Image): fix padding* not working correctly
Fix #1121
2024-07-25 21:27:53 +08:00
李通洲 9f9a5ba39a Android (Linux): report Snapdragon SOC marketing name 2024-07-25 10:33:06 +08:00
李通洲 7c37d719e5 Doc: update help message 2024-07-24 16:41:22 +08:00
李通洲 cc78d6b16c Presets: update some presets 2024-07-24 16:37:35 +08:00
李通洲 e7b7645f08 Presets: remove meaningless presets 2024-07-24 16:25:33 +08:00
李通洲 6a17ef6a54 Presets: update examples 2024-07-24 16:25:16 +08:00
李通洲 5b687727c0 Global: update icon 2024-07-24 15:46:41 +08:00
李通洲 9b038dc848 Global: fix JSON option modules.keyIcon doesn't work 2024-07-24 15:38:54 +08:00
李通洲 597dd32caf Presets: simplify examples/2.jsonc with builtin icon feature 2024-07-24 15:32:20 +08:00
李通洲 8d08a65611 Sound: update icon 2024-07-24 15:31:37 +08:00
李通洲 263c54a81e Global: add option display.key.paddingLeft
Also rename `display.keyWidth` to `display.key.width`
2024-07-24 15:12:25 +08:00
李通洲 cba5560068 LM: change icon 2024-07-24 14:36:13 +08:00
李通洲 0703b2b88f NetIO: don't use the same icon as DiskIO 2024-07-24 14:34:50 +08:00
李通洲 86e5572a7e Custom: fix using icon as key 2024-07-24 14:32:03 +08:00
李通洲 3b3c1a9f63 Global: support display predefined icon in custom key format 2024-07-24 14:27:46 +08:00
李通洲 14b9e88a82 Editor: fix printing editor type 2024-07-24 14:17:47 +08:00
李通洲 bee7c62000 Global: add option --<module>-key-icon 2024-07-24 14:05:46 +08:00
李通洲 8fa4d7ae6e Fastfetch: add option --key-type <enum> 2024-07-24 11:13:37 +08:00
李通洲 640d0666fc Logo (Image): don't require logo height when using position right
Fix #1119
2024-07-24 09:59:23 +08:00
李通洲 165b0b0a69 TerminalFont (Linux): remove Windows Terminal support for WSL
Fix #1113
2024-07-24 09:33:17 +08:00
李通洲 dc216362d5 TerminalFont (Linux): detect system mono font 2024-07-24 09:21:16 +08:00
李通洲 57ffe3bad2 Fastfetch: add icons 2024-07-23 23:02:35 +08:00
Carter Li cdee6e2997 Display (Linux): don't wake up suspended GPU 2024-07-23 19:06:04 +08:00
Carter Li fb03c95d68 LM (Linux): improve ssh version detection code 2024-07-23 18:38:07 +08:00
Carter Li 5b76a0b45a Packaging: update debian stuff [ci skip] 2024-07-23 10:27:33 +08:00
Carter Li fa5a74c746 Merge pull request #1115 from fastfetch-cli/dev
Release: v2.19.1
2024-07-23 10:10:49 +08:00
李通洲 4c6e14bcc2 Release: v2.19.1 2024-07-23 09:56:17 +08:00
李通洲 deacecdc11 Fastfetch: print error when invalid freq option is found 2024-07-23 09:55:48 +08:00
李通洲 83dcdaa726 GPU: fix frequency printing when using custom formation 2024-07-23 09:50:51 +08:00
李通洲 2c29465f69 Doc: update README [ci skip] 2024-07-23 09:39:22 +08:00
李通洲 f3e48a00a0 Display (Android): fix MiUI
560 is density dpi, not physical dpi
2024-07-23 09:27:07 +08:00
李通洲 9559db556d Display: print [HDR] if enabled 2024-07-23 09:27:07 +08:00
Carter Li b89eeaa954 CPU: fix double frequency value when using custom formation
Fix #1111
2024-07-22 22:14:43 +08:00
Carter Li 7c15d0ce88 Merge pull request #1105 from fastfetch-cli/dev
Release: v2.19.0
2024-07-22 13:46:40 +08:00
李通洲 036d407708 Doc: update README [ci skip] 2024-07-22 13:44:29 +08:00
李通洲 52715a0ec5 Fastfetch: rename binaryPrefixType to sizeBinaryPrefix 2024-07-22 10:59:23 +08:00
李通洲 4a6209e0e3 JsonConfig: rename display.binaryPrefix to display.size.binaryPrefix 2024-07-22 10:54:24 +08:00
李通洲 93bdaf10c4 Release: v2.19.0 2024-07-22 10:17:23 +08:00
李通洲 4a75123eb1 Host (macOS): tidy 2024-07-22 09:23:06 +08:00
李通洲 7f2ab7310a Terminal: fix possible buffer overflow 2024-07-22 09:22:01 +08:00
Carter Li 3c9d9b3c67 Brightness (Linux): use brightness instead of actual_brightness
`actual_brightness` are above `max_brightness` on asahi. See also https://bugzilla.kernel.org/show_bug.cgi?id=203905
2024-07-21 12:44:31 +08:00
李通洲 7a1b214ffe Monitor (Windows): if current refresh rate is higher than preferred refresh rate, use it.
No better methods. I have tried EnumDisplaySettings and winrt DisplayPath::GetModes but none of them work.
2024-07-20 23:29:40 +08:00
李通洲 4fe1bb0b7e Display: detect if WCG enabled 2024-07-20 11:52:07 +08:00
李通洲 2f26045d30 Common: fix compiler warnings 2024-07-19 23:57:44 +08:00
李通洲 40e67a1d93 Doc: fix typo [ci skip] 2024-07-19 23:56:18 +08:00
李通洲 d7018c2fd3 DateTime: try fixing 32bit linux
Fix #1108
2024-07-19 22:53:10 +08:00
XhmikosR 9e1ba0d104 Doc: README.md: link to issue (#1107) [ci skip] 2024-07-19 22:22:36 +08:00
Carter Li 9f23ce93bd Doc: update changelog [ci skip] 2024-07-19 16:42:15 +08:00
李通洲 f89cbf6bc8 Monitor: enable module on FreeBSD and SunOS
Fix #1101
2024-07-19 16:04:46 +08:00
李通洲 e12c6e6fd7 Colors: fix bug with --pipe enabled 2024-07-19 15:02:17 +08:00
Carter Li 7ba1e3d3d9 Monitor (Linux): detect by Xrandr if EDID is not available 2024-07-19 05:43:15 +00:00
李通洲 672bf0ef54 Display: update JSON output structure 2024-07-18 22:51:46 +08:00
Carter Li 96ec2b662c Display (Linux): support HDR detection for KDE; fix build 2024-07-18 18:51:33 +08:00
李通洲 c3de293450 Display: print more information 2024-07-18 16:43:19 +08:00
李通洲 f11b07ba8a DisplayServer (macOS): detect bit depth 2024-07-18 16:41:57 +08:00
李通洲 4e84153e9d Display (Windows): check for hdr enabled & bit depth 2024-07-18 16:40:45 +08:00
李通洲 121cbde661 Monitor (Windows): detect maximum refresh rate 2024-07-18 15:10:15 +08:00
李通洲 0d71ae7f97 Monitor (macOS): detect maximum refresh rate 2024-07-18 13:52:12 +08:00
mhkdepauw 2a49f1d0eb Doc: Small typo corrected in man page (#1102) 2024-07-17 22:55:31 +08:00
李通洲 6b7403281b JsonSchema: fix typo [ci skip] 2024-07-17 16:01:12 +08:00
李通洲 63a0faa1d9 GPU (macOS): support GPU frequency detection for Apple Silicon
Also refactor CPU freq detection code
2024-07-17 15:51:15 +08:00
李通洲 408a2d731a GPU: support printing frequency in MHz 2024-07-17 15:49:12 +08:00
李通洲 46abc4f5f7 CPU: move option freqNdigits into display section 2024-07-17 15:49:12 +08:00
李通洲 7393bcdf05 CI: disable --stat which messes output 2024-07-17 14:11:52 +08:00
李通洲 d282050130 CPU: support display frequency in MHz 2024-07-17 14:09:06 +08:00
Carter Li c0de618177 CPU: remove support of min freq detection 2024-07-17 10:19:12 +08:00
Carter Li d1609ea96b Separator: add option --separator-length 2024-07-17 09:16:35 +08:00
李通洲 d869164d6b Display: show inches instead of full size
Which is shorter
2024-07-16 22:10:05 +08:00
李通洲 3b361c663d Logo (Builtin): add ALT Linux 2024-07-16 21:56:37 +08:00
Carter Li 5bc9a5dc4e Display: rotate physical demensions 2024-07-16 16:36:19 +08:00
李通洲 c0781dd5f8 Display: print physical size 2024-07-16 16:11:26 +08:00
李通洲 c795c20723 FFstrbuf: improve ffStrbufSubstr* 2024-07-16 15:39:06 +08:00
李通洲 0776dac95b TerminalFont: improve wezterm detection 2024-07-16 15:06:25 +08:00
李通洲 3433043604 Terminal: support zed version detection 2024-07-16 14:53:14 +08:00
李通洲 bd0b108c04 Colors: don't disable color if --color-symbol background is set in --pipe mode 2024-07-16 14:32:51 +08:00
李通洲 2a9f9d5a34 Colors: add and default to --colors-symbol background 2024-07-16 11:07:26 +08:00
李通洲 4f3649e96e Doc: update README [ci skip] 2024-07-16 10:03:01 +08:00
Carter Li e4f0efd58c Logo (Builtin): update void logo 2024-07-16 09:13:44 +08:00
李通洲 25577a6e58 Disk (Android): ignore /apex/* 2024-07-15 22:56:14 +08:00
Carter Li 801bd7c879 GPU: fix --gpu-hide-type doesn't work
Fix #1098
2024-07-15 18:34:43 +08:00
李通洲 89ce598800 Revert "TerminalFont (Linux): improve detection for xterm"
Committed by accident

This reverts commit 64c53e2cdc.
2024-07-15 16:19:39 +08:00
李通洲 9268d8449e IO (Windows): remove debug output
Fix #1097
2024-07-15 16:01:19 +08:00
李通洲 179341c30c Presets: clean up examples 2024-07-15 14:01:35 +08:00
李通洲 1947aa2b0e Formating: support specifying costant strings 2024-07-15 13:35:59 +08:00
李通洲 64c53e2cdc TerminalFont (Linux): improve detection for xterm
Fix #1095
2024-07-15 10:24:32 +08:00
李通洲 7eaefe163a TerminalFont (Linux): improve detection for xterm
Fix #1095
2024-07-15 10:21:30 +08:00
Carter Li beabaa90f1 InitSystem (Android): fix detection 2024-07-12 20:24:59 +08:00
Carter Li 2f42d64dc9 GPU (Linux): support intel xe driver 2024-07-12 19:24:55 +08:00
Carter Li 7d452cc460 Presets: fix examples/19.jsonc
Fix #1090
2024-07-12 18:47:00 +08:00
Carter Li 5b064f2e7b Display (Linux); improve display type detection
1. assume `DP-x` is external (false possitive alert);
2. detect display type for X11
2024-07-12 15:29:12 +08:00
Carter Li e786cd5d33 Display: detect physical width and height 2024-07-11 20:33:25 +08:00
Carter Li 6c7efea2fd Packaging: update debian stuff [ci skip] 2024-07-11 14:33:46 +08:00
Carter Li efd9e94138 Merge pull request #1086 from fastfetch-cli/dev
Release: v2.18.1
2024-07-11 10:43:24 +08:00
Carter Li 0707b29326 Release: v2.18.1 2024-07-11 10:19:20 +08:00
Carter Li 560e061c25 CI: upgrade freebsd version 2024-07-11 10:11:48 +08:00
Carter Li 1d83743259 GPU (Linux): detect more GPU driver versions 2024-07-11 10:04:23 +08:00
Carter Li 48bb38ca85 GPU (Linux): fix GPU driver detection
Regression of e5a04ee814

Fix #1084
2024-07-11 08:59:07 +08:00
李通洲 d9f084894e General: support more module for --detect-version 2024-07-10 22:09:28 +08:00
Carter Li 765c7b42b6 General: rename --ts-version to --detect-version
And use it in more modules
2024-07-10 21:55:37 +08:00
Carter Li 5060c265a9 Merge pull request #1083 from fastfetch-cli/dev
Release: v2.18.0
2024-07-10 15:39:24 +08:00
李通洲 fca4b3eee8 CI: remove freebsd-aarch64
It's unstable and I don't think anyone uses it
2024-07-10 14:41:52 +08:00
Carter Li eefed2be9c Release: v2.18.0 2024-07-10 13:57:57 +08:00
Carter Li 6a33027892 Fastfetch: use the official function instead of our local copy 2024-07-10 13:37:11 +08:00
Carter Li 5e9c0d03ff 3rdparty: upgrade yyjson to 0.10.0 2024-07-10 13:36:23 +08:00
Carter Li ab84c2ca76 Doc: update json schema and help message 2024-07-10 11:13:28 +08:00
李通洲 4777f7bec3 OpenGL (Windows): support EGL via ANGLE 2024-07-10 11:01:37 +08:00
李通洲 1038668db9 OpenGL: detect library version 2024-07-09 20:39:15 +08:00
Carter Li 49639b6719 OpenGL (Linux): fix flag --opengl-library doesn't work 2024-07-09 14:27:25 +08:00
Carter Li e5a04ee814 GPU (Linux): ignore disabled PCI devices 2024-07-09 06:06:46 +00:00
李通洲 fea2d80743 Doc: update changelog 2024-07-09 11:10:39 +08:00
Carter Li 39eccf189c Presets: add missing modules to all & ci
Fix #1081
2024-07-08 18:29:39 +08:00
Carter Li 1652ec3512 Display (Linux): remove debug output 2024-07-08 18:27:42 +08:00
李通洲 5a39b69d1d Wifi: print signal quality 2024-07-08 16:08:20 +08:00
Carter Li fa872d7c9b Display: fix build on FreeBSD 2024-07-08 15:32:09 +08:00
李通洲 545267bb7e Percentage: support percent bar in custom formatting
Fix #1075
2024-07-08 15:21:12 +08:00
李通洲 789f1e34ef Fastfetch: don't mess output with --stat in --pipe mode 2024-07-08 15:05:42 +08:00
李通洲 9c095967fc Separator: don't print color in --pipe mode 2024-07-08 15:04:28 +08:00
李通洲 ddc910e924 Base64: silence warnings 2024-07-08 14:21:10 +08:00
Carter Li d628bdea5a Display (Linux): support primary display detection for GNOME & Cinnamon 2024-07-08 14:11:45 +08:00
Carter Li f9ce2fae0e Display (Linux): improve id generation for wayland 2024-07-08 11:04:27 +08:00
Carter Li 4f70c16d63 Editor: don't print () 2024-07-08 09:12:18 +08:00
Carter Li f8d5f56dee GPU (Linux): remove possible overhead 2024-07-08 09:11:53 +08:00
Carter Li 4d1c62947b GPU (Linux): don't detect frequency for AMD cards
It's current frequency and may hang for some reason
2024-07-08 08:54:51 +08:00
Carter Li 8402dba0d9 Util (Base64): silence compiler warnings 2024-07-08 08:32:47 +08:00
David Adam 94b6f0fbd1 fish completion: pipe straight to Python (#1076)
In https://github.com/fish-shell/fish-shell/issues/10599, a user of an older version of fish has run into an issue with the fastfetch completion requiring a relatively new version.

Rewrite the (really quite clever) embedded Python into a straight pipe, dropping the string transformation entirely. Does require some escaping of quotes to support Python < 3.12.
2024-07-07 22:36:52 +08:00
李通洲 3b1b81437e Battery (Linux): add comments [ci skip] 2024-07-06 09:04:23 +08:00
李通洲 a61765c8b1 Display (Linux): try fix building for old wayland version 2024-07-06 00:10:59 +08:00
李通洲 065b44ff59 Display (Linux): better zxdg manager handling 2024-07-06 00:03:14 +08:00
李通洲 b0e51ba91d Global: fix memleaks 2024-07-05 23:27:13 +08:00
李通洲 b6fff0c946 Display (Wayland): code refactor 2024-07-05 23:13:28 +08:00
李通洲 c16373a7d7 Display (Linux): support primary display detection for GNOME 2024-07-05 23:11:27 +08:00
李通洲 73875de6a1 LocalIP: don't print * if defaultRouteOnly is set 2024-07-05 23:11:27 +08:00
Carter Li 5f1cb16534 Display (Linux): support primary display detection for KDE 2024-07-05 23:11:27 +08:00
Carter Li 013320bcde Display (Wayland): support fractional scale for KDE 2024-07-05 19:13:09 +08:00
李通洲 3415d8197c PhysicalMemory: don't print (null) in property locator 2024-07-05 11:01:04 +08:00
李通洲 c5fdcc5cfc PhysicalDisk (Linux): detect revision of USB devices 2024-07-05 02:40:15 +00:00
Carter Li f894856407 Disk: update module description 2024-07-05 10:16:25 +08:00
Dennis ten Hoove 313bb02188 Fix Arkane Linux color code (#1072) 2024-07-05 00:14:13 +08:00
李通洲 4dc0bd583c Logo (Builtin): add Opak
Fix #1070
2024-07-04 21:21:26 +08:00
Dennis ten Hoove 0ae1bd57bd Add Arkane Linux logo (#1071) 2024-07-04 20:58:16 +08:00
Carter Li 02f3789eaa Packaging: update debian stuff [ci skip] 2024-07-04 10:24:23 +08:00
209 changed files with 5643 additions and 2173 deletions
+12 -50
View File
@@ -44,7 +44,7 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
@@ -99,7 +99,7 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
@@ -146,7 +146,7 @@ jobs:
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 --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
@@ -185,7 +185,7 @@ jobs:
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 --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
@@ -220,7 +220,7 @@ jobs:
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 --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
@@ -259,7 +259,7 @@ jobs:
- name: run
run: |
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
@@ -300,7 +300,7 @@ jobs:
- name: run
run: |
./fastfetch --list-features
time ./fastfetch -c presets/ci.jsonc
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
@@ -348,7 +348,7 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
@@ -416,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
@@ -438,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
@@ -514,7 +477,7 @@ jobs:
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
@@ -584,7 +547,7 @@ jobs:
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
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
@@ -623,7 +586,6 @@ jobs:
- musl-aarch64
- macos-universal
- freebsd-amd64
- freebsd-aarch64
- sunos-amd64
- windows-amd64
- windows-i686
+144
View File
@@ -1,3 +1,147 @@
# 2.20.0
This release fixes regression of `2.19.0` on M1 MacBook Air. It also introduces a new option `--key-type icon` to display predefined icons in keys (requires newest nerd font). See `fastfetch -h key-type` for detail.
Changes:
* JSON option `display.keyWidth` has been renamed to `display.key.width`
* Previously: `{ "display": { "keyWidth": 3 } }`
* Now: `{ "display": { "key": { "width": 3 } } }`
* Windows Terminal font detection **in WSL** has been removed due to [issue #1113](https://github.com/fastfetch/fastfetch/issues/1113)
Features:
* Add option `display.key.type: <enum>` to print icons in keys
* Supported value `string`, `icon` and `both`. Default to `string` (don't display icons)
* Example: `{ "display": { "key": { "type": "icon" } } }`
* Add option `display.key.paddingLeft: <num>` to print left padding (whitespaces) in keys
* Example: `{ "display": { "key": { "paddingLeft": 2 } } }`
* Add option `modules.keyIcon` to set icon for specified module
* Example: `{ "modules": { "type": "command", "keyIcon": "🔑" } }`
* Report system mono font name for Terminator if used (TerminalFont, Linux)
* Don't require logo height to be set when using `--logo-position right`
* Report Snapdragon SOC marketing name for newer Android phones (CPU, Android)
* Detect MTK SOC part name (CPU, Android)
Bugfixes:
* Don't wake up suspended GPUs when using `--ds-force-drm` (Display, Linux)
* Fix printing editor type in JSON result (Editor)
* Fix `--logo-padding-*` not working correctly (#1121, Logo)
* Fix possible segfault when detecting GPU frequency (#1121, macOS, GPU)
# 2.19.1
Bugfixes
* Fix frequency value printing when using custom format (#1111, CPU / GPU)
* Fix display detection for XiaoMi Android phone (Display, Android)
Features:
* Display if HDR mode is enabled for screens (Display)
* Supported in Windows and Linux (KDE) correctly
# 2.19.0
Changes:
* JSON option `modules.cpu.freqNdigits` has been renamed and moved to `display.freq.ndigits`
* Previously: `{ "modules": { "type": "cpu", "freqNdigits": 2 } }`
* Now: `{ "display": { "freq": { "ndigits": 2 } } }`
* This option now affects GPU frequency too
* By default, frequencies are displayed in *GHz*. Set `display.freq.ndigits` to `-1` to display them in *MHz*
* JSON option `display.binaryPrefix` has been moved to `display.size.binaryPrefix`
* Previously: `{ "display": { "binaryPrefix": "IEC" } }`
* Now: `{ "display": { "size": { "binaryPrefix": "IEC" } } }`
Features:
* Print physical diagonal length if supported (Display)
* Detect display type in X11 mode (Display)
* Assume displays connected via DisplayPort are external monitors (Display, Linux)
* Support GPU frequency detection for Intel XE driver (GPU, Linux)
* Detect init system on Android (InitSystem, Android)
* Use background to display color blocks (Colors)
* To fix weird vertical black lines in some terminals and match the behavior of neofetch (#1094)
* Can be reverted to old behavior with `--colors-symbol block`
* Support Zed terminal version detection (Terminal)
* Improve wezterm font detection (TerminalFont)
* Add option `--separator-length`
* Support GPU frequency detection for Apple Silicon (GPU, macOS)
* Detect maximum refresh rate (#1101, Monitor)
* Detect if HDR mode is supported and enabled (Windows, Display / Monitor)
* Support physical monitor info detection for FreeBSD and SunOS (Monitor)
* Support defining constant strings in JSON config file, which can be used to dedupe formattion strings
```jsonc
{
"display": {
"constants": [
"Hello", // {$1}
"world" // {$2}
]
},
"modules": [
{
"type": "custom",
"format": "{$1} {$2}!" // print "Hello world!"
},
{
"type": "custom",
"format": "{$2} {$1}" // print "world Hello"
}
]
}
```
Bugfixes:
* Fix some presets
* Better detection for XTerm terminal fonts (#1095, TerminalFont, Linux)
* Remove debug output (#1097, Windows)
* Fix command line option `--gpu-hide-type` doesn't work (#1098, GPU)
* Fix wrong date on Raspbian 10 (#1108, DateTime, Linux)
* Use `brightness` instead of `actuall_brightness` when detecting current brightness level (Brightness, Linux)
* Ref: https://bugzilla.kernel.org/show_bug.cgi?id=203905
* Fix buffer overflow with long font family names when detecting kitty term font (TerminalFont)
* Fix some typos
Logos:
* Update void_small
* Add ALT Linux
# 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:
+18 -4
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.17.2
VERSION 2.20.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -61,7 +61,7 @@ cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR B
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 OR SunOS" 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)
@@ -307,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
@@ -395,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
@@ -429,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
@@ -562,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
@@ -581,7 +591,7 @@ elseif(BSD)
src/detection/gamepad/gamepad_bsd.c
src/detection/media/media_linux.c
src/detection/memory/memory_bsd.c
src/detection/monitor/monitor_nosupport.c
src/detection/monitor/monitor_linux.c
src/detection/netio/netio_bsd.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_linux.c
@@ -763,7 +773,11 @@ elseif(SunOS)
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
@@ -782,7 +796,7 @@ elseif(SunOS)
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/monitor/monitor_linux.c
src/detection/netio/netio_sunos.c
src/detection/opengl/opengl_linux.c
src/detection/os/os_sunos.c
+10
View File
@@ -126,6 +126,12 @@ Fastfetch uses JSON (with comments) for configuration. I suggest you use an IDE
Alternatively, you can refer to the presets in [`presets` directory](https://github.com/fastfetch-cli/fastfetch/tree/dev/presets).
The **correct** way to edit the configuration:
This is an example that [changes size prefix from MiB / GiB to MB / GB](https://github.com/fastfetch-cli/fastfetch/discussions/1014). Editor used: [helix](https://github.com/helix-editor/helix)
[![asciicast](https://asciinema.org/a/1uF6sTPGKrHKI1MVaFcikINSQ.svg)](https://asciinema.org/a/1uF6sTPGKrHKI1MVaFcikINSQ)
### Q: I WANT THE DOCUMENTATION!
[Here is the documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Json-Schema). It is generated from [JSON schema](https://github.com/fastfetch-cli/fastfetch/blob/dev/doc/json_schema.json) but you won't like it.
@@ -169,6 +175,10 @@ The p10k doc clearly states that you should NOT print anything to stdout after `
You can always use `fastfetch --pipe false` to force fastfetch running in colorful mode.
### Q: Why do fastfetch and neofetch show different memory usage result?
See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096).
### Q: I want feature A / B / C. Will fastfetch support it?
Fastfetch is a system information tool. We only accept hardware or system level software feature requests. For most personal uses, I recommend using `Command` module to detect it yourself, which can be used to grab output from a custom shell script:
+2 -3
View File
@@ -83,12 +83,12 @@ __fastfetch_complete_logo_type()
__fastfetch_complete_binary_prefix()
{
local __ff_binary_prefixes=(
local __ff_size_binary_prefixes=(
"iec"
"si"
"jedec"
)
COMPREPLY=($(compgen -W "${__ff_binary_prefixes[*]}" -- "$CURRENT_WORD"))
COMPREPLY=($(compgen -W "${__ff_size_binary_prefixes[*]}" -- "$CURRENT_WORD"))
}
__fastfetch_complete_gl()
@@ -356,7 +356,6 @@ __fastfetch_completion()
local FF_OPTIONS_PATH=(
"-c"
"--config"
"--lib-pci"
"--lib-vulkan"
"--lib-wayland"
"--lib-xcb-randr"
+44 -47
View File
@@ -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
+30
View File
@@ -1,3 +1,33 @@
fastfetch (2.19.1) jammy; urgency=medium
* Update to 2.19.1
-- Carter Li <zhangsongcui@live.cn> Tue, 23 Jul 2024 10:25:14 +0800
fastfetch (2.19.0) jammy; urgency=medium
* Update to 2.19.0
-- Carter Li <zhangsongcui@live.cn> Mon, 22 Jul 2024 14:17:55 +0800
fastfetch (2.18.1) jammy; urgency=medium
* Update to 2.18.1
-- Carter Li <zhangsongcui@live.cn> Thu, 11 Jul 2024 14:32:15 +0800
fastfetch (2.18.0) jammy; urgency=medium
* Update to 2.18.0
-- Carter Li <zhangsongcui@live.cn> Wed, 10 Jul 2024 16:46:32 +0800
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
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.17.1_source.buildinfo universe/utils optional
fastfetch_2.19.1_source.buildinfo universe/utils optional
+1 -1
View File
@@ -98,7 +98,7 @@ config files, see the CONFIGURATION section
.B \-\-gen\-config \fI[file]
Generate a config file with options specified on the command line.
If \fIfile\fR is specified, the configuration will written to the
If \fIfile\fR is specified, the configuration will be written to the
file, otherwise it will be written to stdout.
.TP
+258 -115
View File
@@ -22,6 +22,10 @@
"minimum": 0,
"default": 0
},
"keyIcon": {
"description": "Set the icon to be displayed by `display.keyType: \"icon\"`",
"type": "string"
},
"format": {
"description": "Output format of the module. See `-h <module>-format` for detail. I.e: fastfetch -h disk-format",
"type": "string"
@@ -339,6 +343,11 @@
"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
}
}
},
@@ -413,35 +422,59 @@
"type": "boolean",
"default": true
},
"keyWidth": {
"description": "Align the width of keys to number of characters, 0 to disable",
"type": "integer",
"minimum": 0,
"default": 0
},
"binaryPrefix": {
"type": "string",
"description": "Set the binary prefix to used when printing bytes",
"oneOf": [
{
"const": "iec",
"description": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)"
"key": {
"type": "object",
"additionalProperties": false,
"description": "Set how module keys should be displayed",
"properties": {
"width": {
"description": "Align the width of keys to number of characters, 0 to disable",
"type": "integer",
"minimum": 0,
"default": 0
},
{
"const": "si",
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
"type": {
"type": "string",
"description": "Set whether to show icon before string keys",
"enum": [
"none",
"string",
"icon",
"both"
],
"default": "string"
},
{
"const": "jedec",
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
"paddingLeft": {
"type": "integer",
"description": "Set the left padding of keys",
"minimum": 0,
"default": 0
}
]
}
},
"size": {
"type": "object",
"additionalProperties": false,
"description": "Set how a size value should be displayed",
"properties": {
"binaryPrefix": {
"type": "string",
"description": "Set the binary prefix to used when formatting sizes",
"oneOf": [
{
"const": "iec",
"description": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ... (standard)"
},
{
"const": "si",
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
},
{
"const": "jedec",
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
}
]
},
"maxPrefix": {
"type": "string",
"description": "Set the largest binary prefix to use when formatting sizes",
@@ -569,15 +602,31 @@
}
}
},
"freq": {
"type": "object",
"additionalProperties": false,
"description": "Set how frequency values should be displayed",
"properties": {
"ndigits": {
"type": "integer",
"description": "Set the number of digits to keep after the decimal point when formatting frequency values\nA positive value will show the frequency in GHz of decimal\n-1 will show the frequency in MHz",
"minimum": -1,
"maximum": 9,
"default": 2
}
}
},
"noBuffer": {
"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, shell and editor. Mainly for benchmarking",
"default": true
"constants": {
"type": "array",
"description": "List of strings to be used in custom format of modules",
"items": {
"type": "string"
}
}
}
},
@@ -586,10 +635,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"
@@ -604,39 +649,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",
@@ -648,34 +693,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": {
@@ -944,12 +989,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -981,12 +1029,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1015,12 +1066,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1051,12 +1105,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1077,12 +1134,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1100,13 +1160,6 @@
"temp": {
"$ref": "#/$defs/temperature"
},
"freqNdigits": {
"description": "Set the number of digits to keep after the decimal point when printing CPU frequency",
"type": "integer",
"minimum": 0,
"maximum": 9,
"default": 2
},
"showPeCoreCount": {
"description": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
"type": "boolean",
@@ -1118,12 +1171,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1152,12 +1208,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1177,13 +1236,14 @@
"type": "string",
"enum": [
"block",
"background",
"circle",
"diamond",
"triangle",
"square",
"star"
],
"default": "block"
"default": "background"
},
"paddingLeft": {
"description": "Set the number of white spaces to print before the symbol",
@@ -1217,6 +1277,9 @@
},
"key": {
"$ref": "#/$defs/key"
},
"keyIcon": {
"$ref": "#/$defs/keyIcon"
}
}
},
@@ -1243,12 +1306,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1270,12 +1336,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"description": "Text to print",
"type": "string"
@@ -1322,12 +1391,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1385,12 +1457,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1420,12 +1495,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1451,12 +1529,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1486,12 +1567,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1515,12 +1599,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1570,12 +1657,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1640,12 +1730,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1669,12 +1762,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1710,12 +1806,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1750,12 +1849,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1771,7 +1873,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",
@@ -1786,12 +1888,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1820,6 +1925,9 @@
"emerge",
"eopkg",
"flatpak",
"guix",
"lpkg",
"lpkgbuild",
"macports",
"nix",
"opkg",
@@ -1830,6 +1938,7 @@
"rpm",
"scoop",
"snap",
"sorcery",
"winget",
"xbps"
],
@@ -1843,12 +1952,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1876,12 +1988,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1919,12 +2034,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -1940,12 +2058,19 @@
"const": "separator"
},
"string": {
"description": "Set the string to be printed",
"description": "Set the string to be printed by the separator line",
"type": "string",
"default": "-"
},
"outputColor": {
"description": "Set the color of the separator line",
"$ref": "#/$defs/outputColor"
},
"length": {
"description": "Set the length of the separator line, or 0 to auto-detect",
"type": "integer",
"minimum": 0,
"default": 0
}
}
},
@@ -1977,12 +2102,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -2006,12 +2134,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -2056,12 +2187,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -2092,12 +2226,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -2133,12 +2270,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
@@ -2164,12 +2304,15 @@
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
"keyIcon": {
"$ref": "#/$defs/keyIcon"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"format": {
"$ref": "#/$defs/format"
}
+2
View File
@@ -47,6 +47,7 @@
"cpuusage",
{
"type": "gpu",
"driverSpecific": true,
"temp": true
},
"memory",
@@ -63,6 +64,7 @@
"showIpv6": true,
"showMac": true
},
"dns",
"wifi",
"datetime",
"locale",
+9 -12
View File
@@ -4,12 +4,12 @@
{
"type": "title",
"key": "User",
"format": "{1}"
"format": "{user-name}"
},
{
"type": "title",
"key": "Hostname",
"format": "{2}"
"format": "{host-name}"
},
{
"type": "host",
@@ -17,7 +17,7 @@
},
{
"type": "os",
"format": "{3} {9} {12}"
"format": "{pretty-name} {version-id} {arch}"
},
"kernel",
"uptime",
@@ -34,32 +34,29 @@
"type": "de",
"key": "Desktop Environment"
},
{
"type": "shell",
"format": "{7}"
},
"shell",
{
"type": "terminal",
"format": "{5} {6} {#37}█{#97}█ {#36}█{#96}█ {#35}█{#95}█ {#34}█{#94}█ {#33}█{#93}█ {#32}█{#92}█ {#31}█{#91}█ {#30}█{#90}█"
"format": "{pretty-name} {version} {#37}█{#97}█ {#36}█{#96}█ {#35}█{#95}█ {#34}█{#94}█ {#33}█{#93}█ {#32}█{#92}█ {#31}█{#91}█ {#30}█{#90}█"
},
{
"type": "packages",
"format": "{1}"
"format": "{all}"
},
{
"type": "cpu",
"key": "Temperature",
"temp": true,
"format": "{8}"
"format": "{temperature}"
},
{
"type": "cpu",
"key": "CPU",
"format": "{4} x {1}"
"format": "{cores-logical} x {name}"
},
{
"type": "gpu",
"format": "{2}"
"format": "{name}"
},
{
"type": "memory",
-42
View File
@@ -1,42 +0,0 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "builtin",
"source": "arch"
},
"modules": [
"title",
"separator",
{
"type": "os",
"format": "Arch Linux ({12})"
},
"host",
"kernel",
"uptime",
{
"type": "packages",
"format": "{} (pacman)"
},
"shell",
"display",
"de",
"wm",
"wmtheme",
"theme",
"icons",
"font",
"cursor",
"terminal",
"terminalfont",
"cpu",
"gpu",
"memory",
"disk",
"battery",
"poweradapter",
"locale",
"break",
"colors"
]
}
+2
View File
@@ -49,6 +49,7 @@
"cpuusage",
{
"type": "gpu",
"driverSpecific": true,
"temp": true
},
"memory",
@@ -65,6 +66,7 @@
"showIpv6": true,
"showMac": true
},
"dns",
"wifi",
"datetime",
"locale",
+9 -6
View File
@@ -9,12 +9,15 @@
}
},
"display": {
"separator": " -> "
"separator": " -> ",
"constants": [
"──────────────────────────────"
]
},
"modules": [
{
"type": "custom",
"format": "┌────────────────────────────────────────────────────────────┐",
"format": "┌{$1}{$1}┐",
"outputColor": "90"
},
{
@@ -23,7 +26,7 @@
},
{
"type": "custom",
"format": "└────────────────────────────────────────────────────────────┘",
"format": "└{$1}{$1}┘",
"outputColor": "90"
},
{
@@ -32,12 +35,12 @@
},
{
"type": "custom",
"format": "┌────────────────────────────────────────────────────────────┐",
"format": "┌{$1}{$1}┐",
"outputColor": "90"
},
{
"type": "os",
"key": " OS",
"key": "{icon} OS",
"keyColor": "yellow"
},
{
@@ -142,7 +145,7 @@
},
{
"type": "custom",
"format": "└────────────────────────────────────────────────────────────┘",
"format": "└{$1}{$1}┘",
"outputColor": "90"
},
"break",
+25 -18
View File
@@ -6,96 +6,103 @@
"display": {
"separator": "-> ",
"color": {
"separator": "1"
"separator": "1" // Bold
},
"constants": [
"───────────────────────────"
],
"key": {
"type": "both",
"paddingLeft": 4
}
},
"modules": [
{
"type": "title",
"format": " {6}{7}{8}"
"format": " {user-name-colored}{at-symbol-colored}{host-name-colored}"
},
"break",
{
"type": "custom",
"format": "┌───────────────────────────── {#1}System Information{#} ─────────────────────────────┐"
"format": "┌{$1} {#1}System Information{#} {$1}┐"
},
"break",
{
"key": "OS ",
"key": "OS ",
"keyColor": "red",
"type": "os"
},
{
"key": " 󰌢 Machine ",
"key": "Machine ",
"keyColor": "green",
"type": "host"
},
{
"key": "Kernel ",
"key": "Kernel ",
"keyColor": "magenta",
"type": "kernel"
},
{
"key": " 󰅐 Uptime ",
"key": "Uptime ",
"keyColor": "red",
"type": "uptime"
},
{
"key": " 󰍹 Resolution ",
"key": "Resolution ",
"keyColor": "yellow",
"type": "display",
"compactType": "original-with-refresh-rate"
},
{
"key": "WM ",
"key": "WM ",
"keyColor": "blue",
"type": "wm"
},
{
"key": "DE ",
"key": "DE ",
"keyColor": "green",
"type": "de"
},
{
"key": "Shell ",
"key": "Shell ",
"keyColor": "cyan",
"type": "shell"
},
{
"key": "Terminal ",
"key": "Terminal ",
"keyColor": "red",
"type": "terminal"
},
{
"key": " 󰻠 CPU ",
"key": "CPU ",
"keyColor": "yellow",
"type": "cpu"
},
{
"key": " 󰍛 GPU ",
"key": "GPU ",
"keyColor": "blue",
"type": "gpu"
},
{
"key": " 󰑭 Memory ",
"key": "Memory ",
"keyColor": "magenta",
"type": "memory"
},
{
"key": " 󰩟 Local IP ",
"key": "Local IP ",
"keyColor": "red",
"type": "localip",
"compact": true
},
{
"key": " 󰩠 Public IP ",
"key": "Public IP ",
"keyColor": "cyan",
"type": "publicip"
},
"break",
{
"type": "custom",
"format": "└──────────────────────────────────────────────────────────────────────────────┘"
"format": "└{$1}────────────────────{$1}┘"
},
"break",
{
+17 -19
View File
@@ -8,8 +8,7 @@
}
},
"display": {
"separator": "",
"keyWidth": 15
"separator": " "
},
"modules": [
{
@@ -17,65 +16,64 @@
"type": "custom"
},
{
// draw borders first to make colors of left and right border consistant
"key": "│ │\u001b[11D{#31} user",
"key": "│ {#31} user {#keys}│",
"type": "title",
"format": "{1}"
"format": "{user-name}"
},
{
"key": "│ │\u001b[11D{#32}󰇅 hname",
"key": "│ {#32}󰇅 hname {#keys}│",
"type": "title",
"format": "{2}"
"format": "{host-name}"
},
{
"key": "│ │\u001b[11D{#33}󰅐 uptime",
"key": "│ {#33}󰅐 uptime {#keys}│",
"type": "uptime"
},
{
"key": "│ │\u001b[11D{#34}󰟾 distro",
"key": "│ {#34}{icon} distro {#keys}│",
"type": "os"
},
{
"key": "│ │\u001b[11D{#35} kernel",
"key": "│ {#35} kernel {#keys}│",
"type": "kernel"
},
{
"key": "│ │\u001b[11D{#36}󰇄 desktop",
"key": "│ {#36}󰇄 desktop {#keys}│",
"type": "de"
},
{
"key": "│ │\u001b[11D{#31} term",
"key": "│ {#31} term {#keys}│",
"type": "terminal"
},
{
"key": "│ │\u001b[11D{#32} shell",
"key": "│ {#32} shell {#keys}│",
"type": "shell"
},
{
"key": "│ │\u001b[11D{#33}󰍛 cpu",
"key": "│ {#33}󰍛 cpu {#keys}│",
"type": "cpu",
"showPeCoreCount": true
},
{
"key": "│ │\u001b[11D{#34}󰉉 disk",
"key": "│ {#34}󰉉 disk {#keys}│",
"type": "disk",
"folders": "/"
},
{
"key": "│ │\u001b[11D{#35} memory",
"key": "│ {#35} memory {#keys}│",
"type": "memory"
},
{
"key": "│ │\u001b[11D{#36}󰩟 network",
"key": "│ {#36}󰩟 network {#keys}│",
"type": "localip",
"format": "{1} ({4})"
"format": "{ipv4} ({ifname})"
},
{
"key": "├───────────┤",
"type": "custom"
},
{
"key": "│ │\u001b[11D{#39} colors",
"key": "│ {#39} colors {#keys}│",
"type": "colors",
"symbol": "circle"
},
+7 -5
View File
@@ -6,20 +6,22 @@
},
"display": {
"separator": "",
"keyWidth": 12
"key": {
"width": 15
}
},
"modules": [
{
// draw borders first to make colors of left and right border consistant
"key": " user",
"type": "title",
"format": "{1}",
"format": "{user-name}",
"keyColor": "31"
},
{
"key": "󰇅 hname",
"type": "title",
"format": "{2}",
"format": "{host-name}",
"keyColor": "32"
},
@@ -29,7 +31,7 @@
"keyColor": "33"
},
{
"key": "󰟾 distro",
"key": "{icon} distro",
"type": "os",
"keyColor": "34"
},
@@ -73,7 +75,7 @@
{
"key": "󰩟 network",
"type": "localip",
"format": "{1} ({4})",
"format": "{ipv4} ({ifname})",
"keyColor": "36"
},
{
+17 -19
View File
@@ -8,8 +8,7 @@
}
},
"display": {
"separator": "",
"keyWidth": 15
"separator": " "
},
"modules": [
{
@@ -17,65 +16,64 @@
"type": "custom"
},
{
// draw borders first to make colors of left and right border consistant
"key": "• •\u001b[11D{#31} user",
"key": "• {#31} user {#keys}•",
"type": "title",
"format": "{1}"
"format": "{user-name}"
},
{
"key": "• •\u001b[11D{#32}󰇅 hname",
"key": "• {#32}󰇅 hname {#keys}•",
"type": "title",
"format": "{2}"
"format": "{host-name}"
},
{
"key": "• •\u001b[11D{#33}󰅐 uptime",
"key": "• {#33}󰅐 uptime {#keys}•",
"type": "uptime"
},
{
"key": "• •\u001b[11D{#34}󰟾 distro",
"key": "• {#34}{icon} distro {#keys}•",
"type": "os"
},
{
"key": "• •\u001b[11D{#35} kernel",
"key": "• {#35} kernel {#keys}•",
"type": "kernel"
},
{
"key": "• •\u001b[11D{#36}󰇄 desktop",
"key": "• {#36}󰇄 desktop {#keys}•",
"type": "de"
},
{
"key": "• •\u001b[11D{#31} term",
"key": "• {#31} term {#keys}•",
"type": "terminal"
},
{
"key": "• •\u001b[11D{#32} shell",
"key": "• {#32} shell {#keys}•",
"type": "shell"
},
{
"key": "• •\u001b[11D{#33}󰍛 cpu",
"key": "• {#33}󰍛 cpu {#keys}•",
"type": "cpu",
"showPeCoreCount": true
},
{
"key": "• •\u001b[11D{#34}󰉉 disk",
"key": "• {#34}󰉉 disk {#keys}•",
"type": "disk",
"folders": "/"
},
{
"key": "• •\u001b[11D{#35} memory",
"key": "• {#35} memory {#keys}•",
"type": "memory"
},
{
"key": "• •\u001b[11D{#36}󰩟 network",
"key": "• {#36}󰩟 network {#keys}•",
"type": "localip",
"format": "{1} ({4})"
"format": "{ipv4} ({ifname})"
},
{
"key": "•••••••••••••",
"type": "custom"
},
{
"key": "• •\u001b[11D{#39} colors",
"key": "• {#39} colors {#keys}•",
"type": "colors",
"symbol": "circle"
},
+4 -4
View File
@@ -18,19 +18,19 @@
{
"key": "║ {#31} user {#keys}║",
"type": "title",
"format": "{1}"
"format": "{user-name}"
},
{
"key": "║ {#32}󰇅 hname {#keys}║",
"type": "title",
"format": "{2}"
"format": "{host-name}"
},
{
"key": "║ {#33}󰅐 uptime {#keys}║",
"type": "uptime"
},
{
"key": "║ {#34}󰟾 distro {#keys}║",
"key": "║ {#34}{icon} distro {#keys}║",
"type": "os"
},
{
@@ -66,7 +66,7 @@
{
"key": "║ {#36}󰩟 network {#keys}║",
"type": "localip",
"format": "{1} ({4})"
"format": "{ipv4} ({ifname})"
},
{
"key": "╠═══════════╣",
+21 -17
View File
@@ -11,72 +11,76 @@
"separator": "> ",
"color": {
"separator": "red"
}
},
"constants": [
"───────────────────────────────────────────────────────────────────────────",
"│\u001b[75C│\u001b[75D"
]
},
"modules": [
{
"format": "{#1}{#keys}╭───────────────────────────────────────────────────────────────────────────╮\u001b[76D {6}{7}{8} 🖥 ",
"format": "{#1}{#keys}╭{$1}╮\u001b[76D {user-name-colored}{at-symbol-colored}{host-name-colored} 🖥 ",
"type": "title"
},
{
"key": "│\u001b[75C│\u001b[75D{#31} kernel ",
"key": "{$2}{#31} kernel ",
"type": "kernel"
},
{
"key": "│\u001b[75C│\u001b[75D{#32}󰅐 uptime ",
"key": "{$2}{#32}󰅐 uptime ",
"type": "uptime"
},
{
"key": "│\u001b[75C│\u001b[75D{#33}󰟾 distro ",
"key": "{$2}{#33}{icon} distro ",
"type": "os"
},
{
"key": "│\u001b[75C│\u001b[75D{#34}󰇄 desktop ",
"key": "{$2}{#34}󰇄 desktop ",
"type": "de"
},
{
"key": "│\u001b[75C│\u001b[75D{#35} term ",
"key": "{$2}{#35} term ",
"type": "terminal"
},
{
"key": "│\u001b[75C│\u001b[75D{#36} shell ",
"key": "{$2}{#36} shell ",
"type": "shell"
},
{
"key": "│\u001b[75C│\u001b[75D{#35}󰍛 cpu ",
"key": "{$2}{#35}󰍛 cpu ",
"type": "cpu",
"showPeCoreCount": true,
"temp": true
},
{
"key": "│\u001b[75C│\u001b[75D{#34}󰍛 gpu ",
"key": "{$2}{#34}󰍛 gpu ",
"type": "gpu"
},
{
"key": "│\u001b[75C│\u001b[75D{#33}󰉉 disk ",
"key": "{$2}{#33}󰉉 disk ",
"type": "disk",
"folders": "/"
},
{
"key": "│\u001b[75C│\u001b[75D{#32} memory ",
"key": "{$2}{#32} memory ",
"type": "memory"
},
{
"key": "│\u001b[75C│\u001b[75D{#31}󰩟 network ",
"key": "{$2}{#31}󰩟 network ",
"type": "localip",
"format": "{1} ({4})"
"format": "{ipv4} ({ifname})"
},
{
"format": "{#1}{#keys}├───────────────────────────────────────────────────────────────────────────┤",
"format": "{#1}{#keys}├{$1}┤",
"type": "custom"
},
{
"key": "│\u001b[75C│\u001b[75D{#39} colors ",
"key": "{$2}{#39} colors ",
"type": "colors",
"symbol": "circle"
},
{
"format": "{#1}{#keys}╰───────────────────────────────────────────────────────────────────────────╯",
"format": "{#1}{#keys}╰{$1}╯",
"type": "custom"
}
]
+21 -17
View File
@@ -11,72 +11,76 @@
"separator": "> ",
"color": {
"separator": "red"
}
},
"constants": [
"═══════════════════════════════════════════════════════════════════════════",
"║\u001b[75C║\u001b[75D"
]
},
"modules": [
{
"format": "{#1}{#keys}╔═══════════════════════════════════════════════════════════════════════════╗\u001b[76D {6}{7}{8} 💻 ",
"format": "{#1}{#keys}╔{$1}╗\u001b[76D {user-name-colored}{at-symbol-colored}{host-name-colored} 💻 ",
"type": "title"
},
{
"key": "║\u001b[75C║\u001b[75D{#31} kernel ",
"key": "{$2}{#31} kernel ",
"type": "kernel"
},
{
"key": "║\u001b[75C║\u001b[75D{#32}󰅐 uptime ",
"key": "{$2}{#32}󰅐 uptime ",
"type": "uptime"
},
{
"key": "║\u001b[75C║\u001b[75D{#33}󰟾 distro ",
"key": "{$2}{#33}{icon} distro ",
"type": "os"
},
{
"key": "║\u001b[75C║\u001b[75D{#34}󰇄 desktop ",
"key": "{$2}{#34}󰇄 desktop ",
"type": "de"
},
{
"key": "║\u001b[75C║\u001b[75D{#35} term ",
"key": "{$2}{#35} term ",
"type": "terminal"
},
{
"key": "║\u001b[75C║\u001b[75D{#36} shell ",
"key": "{$2}{#36} shell ",
"type": "shell"
},
{
"key": "║\u001b[75C║\u001b[75D{#35}󰍛 cpu ",
"key": "{$2}{#35}󰍛 cpu ",
"type": "cpu",
"showPeCoreCount": true,
"temp": true
},
{
"key": "║\u001b[75C║\u001b[75D{#34}󰍛 gpu ",
"key": "{$2}{#34}󰍛 gpu ",
"type": "gpu"
},
{
"key": "║\u001b[75C║\u001b[75D{#33}󰉉 disk ",
"key": "{$2}{#33}󰉉 disk ",
"type": "disk",
"folders": "/"
},
{
"key": "║\u001b[75C║\u001b[75D{#32} memory ",
"key": "{$2}{#32} memory ",
"type": "memory"
},
{
"key": "║\u001b[75C║\u001b[75D{#31}󰩟 network ",
"key": "{$2}{#31}󰩟 network ",
"type": "localip",
"format": "{1} ({4})"
"format": "{ipv4} ({ifname})"
},
{
"format": "{#1}{#keys}╠═══════════════════════════════════════════════════════════════════════════╣",
"format": "{#1}{#keys}╠{$1}╣",
"type": "custom"
},
{
"key": "║\u001b[75C║\u001b[75D{#39} colors ",
"key": "{$2}{#39} colors ",
"type": "colors",
"symbol": "circle"
},
{
"format": "{#1}{#keys}╚═══════════════════════════════════════════════════════════════════════════╝",
"format": "{#1}{#keys}╚{$1}╝",
"type": "custom"
}
]
+1 -1
View File
@@ -12,7 +12,7 @@
"logo": {
"source": " _____ _____ _____ _____ _____ _____ _____ _____ _____\n| __| _ | __|_ _| __| __|_ _| | | |\n| __| |__ | | | | __| __| | | | --| |\n|__| |__|__|_____| |_| |__| |_____| |_| |_____|__|__|",
"type": "data",
"separate": true,
"position": "top",
"padding": {
"right": 2
}
+44 -126
View File
@@ -10,153 +10,71 @@
// "height": 12
// },
"display": {
"separator": "  "
"separator": "  ",
"constants": [
"─────────────────" // {$1}, used in Custom module
],
"key": {
"type": "icon",
"paddingLeft": 2
}
},
"modules": [
{
"type": "custom", // HardwareStart
// {#1} is equivalent to `\u001b[1m`. {#} is equivalent to `\u001b[m`
"format": "┌─────────── {#1}Hardware Information{#} ───────────┐"
},
{
"type": "host",
"key": " 󰌢"
},
{
"type": "cpu",
"key": " 󰻠"
},
{
"type": "gpu",
"key": " 󰍛"
},
{
"type": "disk",
"key": " "
},
{
"type": "memory",
"key": " 󰑭"
},
{
"type": "swap",
"key": " 󰓡"
},
{
"type": "display",
"key": " 󰍹"
},
{
"type": "brightness",
"key": " 󰃞"
},
{
"type": "battery",
"key": " "
},
{
"type": "poweradapter",
"key": " "
},
{
"type": "bluetooth",
"key": " "
},
{
"type": "sound",
"key": " "
},
{
"type": "gamepad",
"key": " "
"format": "┌{$1} {#1}Hardware Information{#} {$1}┐"
},
"host",
"cpu",
"gpu",
"disk",
"memory",
"swap",
"display",
"brightness",
"battery",
"poweradapter",
"bluetooth",
"sound",
"gamepad",
{
"type": "custom", // SoftwareStart
"format": "├─────────── {#1}Software Information{#} ───────────┤"
"format": "├{$1} {#1}Software Information{#} {$1}┤"
},
{
"type": "title",
"key": " ",
"format": "{1}@{2}"
},
{
"type": "os",
"key": " " // Just get your distro's logo off nerdfonts.com
},
{
"type": "kernel",
"key": " ",
"format": "{1} {2}"
},
{
"type": "lm",
"key": " 󰧨"
},
{
"type": "de",
"key": " "
},
{
"type": "wm",
"key": " "
},
{
"type": "shell",
"key": " "
},
{
"type": "terminal",
"key": " "
},
{
"type": "terminalfont",
"key": " "
},
{
"type": "theme",
"key": " 󰉼"
},
{
"type": "icons",
"key": " 󰀻"
},
{
"type": "wallpaper",
"key": " 󰸉"
},
{
"type": "packages",
"key": " 󰏖"
},
{
"type": "uptime",
"key": " 󰅐"
},
{
"type": "media",
"key": " 󰝚"
"keyIcon": "",
"key": "Title", // Title module has no key by default, so that icon is not displayed
"format": "{user-name}@{host-name}"
},
"os",
"kernel",
"lm",
"de",
"wm",
"shell",
"terminal",
"terminalfont",
"theme",
"icons",
"wallpaper",
"packages",
"uptime",
"media",
{
"type": "localip",
"key": " 󰩟",
"compact": true
},
{
"type": "publicip",
"key": " 󰩠"
},
"publicip",
{
"type": "wifi",
"key": " ",
"format": "{4}" // ssid
},
{
"type": "locale",
"key": " "
"format": "{ssid}"
},
"locale",
{
"type": "custom", // InformationEnd
"format": "└────────────────────────────────────────────┘"
"format": "└{$1}──────────────────────{$1}┘"
},
{
"type": "colors",
+25 -20
View File
@@ -4,7 +4,9 @@
"logo": null,
"display": {
"pipe": true,
"keyWidth": 16,
"key": {
"width": 16
},
"separator": "│ ",
"percent": {
"type": 6
@@ -15,7 +17,10 @@
"charElapsed": "█",
"charTotal": "░",
"width": 40
}
},
"constants": [
"\u001b[42C"
]
},
"modules": [
{
@@ -41,11 +46,11 @@
},
{
"type": "os",
"key": "│ OS │\u001b[42C"
"key": "│ OS │{$1}"
},
{
"type": "kernel",
"key": "│ KERNEL │\u001b[42C"
"key": "│ KERNEL │{$1}"
},
{
"type": "custom",
@@ -53,34 +58,34 @@
},
{
"type": "title",
"key": "│ HOSTNAME │\u001b[42C",
"key": "│ HOSTNAME │{$1}",
"format": "{host-name}"
},
{
"type": "localip",
"key": "│ CLIENT IP │\u001b[42C",
"key": "│ CLIENT IP │{$1}",
"format": "{ipv4}"
},
{
"type": "localip",
"key": "│ MAC ADDR │\u001b[42C",
"key": "│ MAC ADDR │{$1}",
"format": "{mac} ({ifname})",
"showIPv4": false,
"showMac": true
},
{
"type": "dns",
"key": "│ DNS │\u001b[42C",
"key": "│ DNS │{$1}",
"showType": "ipv4"
},
{
"type": "title",
"key": "│ USER │\u001b[42C",
"key": "│ USER │{$1}",
"format": "{user-name}"
},
{
"type": "host",
"key": "│ MACHINE │\u001b[42C",
"key": "│ MACHINE │{$1}",
"format": "{name}"
},
{
@@ -89,25 +94,25 @@
},
{
"type": "cpu",
"key": "│ PROCESSOR │\u001b[42C",
"key": "│ PROCESSOR │{$1}",
"format": "{name}"
},
{
"type": "cpu",
"key": "│ CORES │\u001b[42C",
"key": "│ CORES │{$1}",
"format": "{cores-physical} PHYSICAL CORES / {cores-logical} THREADS",
"showPeCoreCount": false
},
{
"type": "cpu",
"key": "│ CPU FREQ │\u001b[42C",
"key": "│ CPU FREQ │{$1}",
"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"
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
},
{
"type": "custom",
@@ -115,12 +120,12 @@
},
{
"type": "memory",
"key": "│ MEMORY │\u001b[42C",
"key": "│ MEMORY │{$1}",
"format": "{used} / {total} [{percentage}]"
},
{
"type": "memory",
"key": "│ USAGE │\u001b[42C",
"key": "│ USAGE │{$1}",
"format": ""
},
{
@@ -129,13 +134,13 @@
},
{
"type": "disk",
"key": "│ VOLUME │\u001b[42C",
"key": "│ VOLUME │{$1}",
"format": "{size-used} / {size-total} [{size-percentage}]",
"folders": "/"
},
{
"type": "disk",
"key": "│ DISK USAGE │\u001b[42C",
"key": "│ DISK USAGE │{$1}",
"format": ""
},
{
@@ -144,13 +149,13 @@
},
{
"type": "users",
"key": "│ LAST LOGIN │\u001b[42C",
"key": "│ LAST LOGIN │{$1}",
"format": "{login-time}{?client-ip} ({client-ip})",
"myselfOnly": true
},
{
"type": "uptime",
"key": "│ UPTIME │\u001b[42C"
"key": "│ UPTIME │{$1}"
},
{
"type": "custom",
+12 -7
View File
@@ -3,39 +3,44 @@
"logo": {
"type": "small"
},
"display": {
"constants": [
"██ "
]
},
"modules": [
{
"key": "██ Distro",
"key": "{$1}Distro",
"keyColor": "38;5;210",
"type": "os"
},
{
"key": "██ Kernel",
"key": "{$1}Kernel",
"keyColor": "38;5;84",
"type": "kernel"
},
{
"key": "██ Shell",
"key": "{$1}Shell",
"keyColor": "38;5;147",
"type": "shell"
},
{
"key": "██ Packages",
"key": "{$1}Packages",
"keyColor": "38;5;200",
"type": "packages"
},
{
"key": "██ WM",
"key": "{$1}WM",
"keyColor": "38;5;44",
"type": "wm"
},
{
"key": "██ CPU",
"key": "{$1}CPU",
"keyColor": "38;5;75",
"type": "cpu"
},
{
"key": "██ Memory",
"key": "{$1}Memory",
"keyColor": "38;5;123",
"type": "memory"
}
+8 -4
View File
@@ -1,3 +1,4 @@
// Designed for Arch Linux
// 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",
@@ -12,7 +13,10 @@
"color": {
"separator": "blue"
},
"separator": " | "
"separator": " | ",
"constants": [
">-----------<+>---------------------------------------------<"
]
},
"modules": [
{
@@ -22,7 +26,7 @@
},
{
"type": "custom",
"format": ">-----------<+>------------------------------------------<",
"format": "{$1}",
"outputColor": "separator"
},
{
@@ -57,7 +61,7 @@
},
{
"type": "custom",
"format": ">-----------<+>------------------------------------------<",
"format": "{$1}",
"outputColor": "separator"
},
{
@@ -97,7 +101,7 @@
},
{
"type": "custom",
"format": ">-----------<+>------------------------------------------<",
"format": "{$1}",
"outputColor": "separator"
},
"break",
+6 -2
View File
@@ -2,9 +2,13 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": "debian_small",
"logo": {
"type": "small"
},
"display": {
"binaryPrefix": "si"
"size": {
"binaryPrefix": "si"
}
},
"modules": [
"vulkan",
+4 -2
View File
@@ -3,13 +3,15 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"source": "arch_small",
"type": "small",
"padding": {
"right": 1
}
},
"display": {
"binaryPrefix": "si",
"size": {
"binaryPrefix": "si"
},
"color": "blue",
"separator": "  "
},
+1 -1
View File
@@ -4,7 +4,7 @@
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": null,
"display": {
"color": "reset_magenta"
"color": "magenta"
},
"modules": [
{
+4 -11
View File
@@ -3,12 +3,6 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
// "logo": {
// "type": "iterm",
// "source": "/Users/carter/Desktop/apple1.png",
// "width": 28,
// "height": 12
// },
"display": {
"separator": " "
},
@@ -125,23 +119,22 @@
"key": "╰─󰸉",
"keyColor": "yellow"
},
"break",
{
"type": "title",
"key": "╭─",
"format": "{1}@{2}",
"format": "{user-name}@{host-name}",
"keyColor": "blue"
},
{
"type": "os",
"key": "├─", // Just get your distro's logo off nerdfonts.com
"key": "├─{icon}", // Just get your distro's logo off nerdfonts.com
"keyColor": "blue"
},
{
"type": "kernel",
"key": "├─",
"format": "{1} {2}",
"keyColor": "blue"
},
{
@@ -173,7 +166,7 @@
{
"type": "wifi",
"key": "├─",
"format": "{4}", // ssid
"format": "{ssid}",
"keyColor": "blue"
},
{
+6 -7
View File
@@ -22,9 +22,8 @@
},
{
"type": "os",
"key": "├", // Just get your distro's logo off nerdfonts.com
"keyColor": "yellow",
"format": "{6}{?6} {?}{10}{?10} {?}{8}{?8} {?}{11}"
"key": "├{icon}", // Just get your distro's logo off nerdfonts.com
"keyColor": "yellow"
},
{
"type": "kernel",
@@ -106,13 +105,13 @@
"keyColor": "green"
},
{
"type": "uptime",
"key": "├󰅐",
"type": "display",
"key": "├󰍹",
"keyColor": "green"
},
{
"type": "display",
"key": "└󰍹",
"type": "uptime",
"key": "└󰅐",
"keyColor": "green"
},
+13 -24
View File
@@ -11,6 +11,9 @@
"size": {
"ndigits": 0,
"maxPrefix": "MB"
},
"key": {
"type": "icon"
}
},
"modules": [
@@ -22,31 +25,17 @@
"host": "blue"
}
},
"os",
"kernel",
"memory",
"packages",
"uptime",
{
"type": "os",
"key": "",
"format": "{2} {8}"
},
{
"type": "kernel",
"key": ""
},
{
"type": "memory",
"key": ""
},
{
"type": "packages",
"key": "󰏖"
},
{
"type": "uptime",
"key": "󰅐"
},
{
"type": "custom",
"key": "",
"format": "{#31}███{#32}███{#33}███{#34}███{#35}███{#36}███"
"type": "colors",
"key": "Colors", // For printing icon
"block": {
"range": [1, 6]
}
}
]
}
+3 -1
View File
@@ -4,7 +4,9 @@
"type": "small"
},
"display": {
"keyWidth": 11,
"key": {
"width": 11
},
"bar": {
"charElapsed": "=",
"charTotal": "-",
-37
View File
@@ -1,37 +0,0 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
{
"type": "host",
"format": "{?2}{2}{?}{?5} ({5}){?}"
},
"chassis",
{
"type": "board",
"format": "{?1}{1}{?}{?2} ({2}){?}"
},
"cpu",
{
"type": "memory",
"format": "{?2}{2}{?}"
},
"physicaldisk",
"gpu",
"display",
"monitor",
{
"type": "wifi",
"format": "{?1}{1}{?}{?6} - {6}{?}"
},
{
"type": "sound",
"format": "{?2}{2}{?}"
},
"camera",
{
"type": "battery",
"format": "{?1}{1}{?}{?2} {2}{?}{?3} ({3}){?}"
},
"poweradapter"
]
}
+6 -3
View File
@@ -11,7 +11,10 @@
"separator",
"os",
"host",
"kernel",
{
"type": "kernel",
"format": "{release}"
},
"uptime",
"packages",
"shell",
@@ -28,7 +31,7 @@
"terminal",
{
"type": "terminalfont",
"format": "{/2}{-}{/}{2}{?3} {3}{?}"
"format": "{/name}{-}{/}{name}{?size} {size}{?}"
},
"cpu",
{
@@ -37,7 +40,7 @@
},
{
"type": "memory",
"format": "{/1}{-}{/}{/2}{-}{/}{} / {}"
"format": "{} / {}"
},
"break",
"colors"
-17
View File
@@ -1,17 +0,0 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
"os",
"kernel",
"shell",
"de",
"wm",
"wmtheme",
"theme",
"icons",
"font",
"cursor",
"terminal",
"terminalfont"
]
}
+1 -1
View File
@@ -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"
}
+152 -57
View File
@@ -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;
+21 -3
View File
@@ -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);
/**
+1 -4
View File
@@ -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
}
}
+21
View File
@@ -244,6 +244,27 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
//test for constant, if so evaluate it
if (firstChar == '$')
{
char* pend = NULL;
int32_t indexSigned = (int32_t) strtol(placeholderValue.chars + 1, &pend, 10);
uint32_t index = (uint32_t) indexSigned;
bool backward = indexSigned < 0;
if (indexSigned == 0 || *pend != '\0' || instance.config.display.constants.length < index)
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
FFstrbuf* item = FF_LIST_GET(FFstrbuf, instance.config.display.constants, backward
? instance.config.display.constants.length - index
: index - 1);
ffStrbufAppend(buffer, item);
continue;
}
int32_t truncLength = INT32_MAX;
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pColon != NULL)
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include "util/FFstrbuf.h"
typedef enum FFformatargtype
{
FF_FORMAT_ARG_TYPE_NULL = 0,
+16 -8
View File
@@ -101,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
-1
View File
@@ -229,7 +229,6 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
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);
}
+8 -4
View File
@@ -37,6 +37,11 @@ bool ffJsonConfigParseModuleArgs(const char* key, yyjson_val* val, FFModuleArgs*
moduleArgs->keyWidth = (uint32_t) yyjson_get_uint(val);
return true;
}
else if(ffStrEqualsIgnCase(key, "keyIcon"))
{
ffStrbufSetS(&moduleArgs->keyIcon, yyjson_get_str(val));
return true;
}
return false;
}
@@ -50,6 +55,8 @@ void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* m
yyjson_mut_obj_add_strbuf(doc, module, "keyColor", &moduleArgs->keyColor);
if (moduleArgs->keyWidth != defaultModuleArgs->keyWidth)
yyjson_mut_obj_add_uint(doc, module, "keyWidth", moduleArgs->keyWidth);
if (!ffStrbufEqual(&defaultModuleArgs->keyIcon, &moduleArgs->keyIcon))
yyjson_mut_obj_add_strbuf(doc, module, "keyIcon", &moduleArgs->keyIcon);
}
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[])
@@ -213,10 +220,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
}
}
+20 -28
View File
@@ -50,20 +50,29 @@ bool ffOptionParseModuleArgs(const char* argumentKey, const char* subKey, const
ffOptionParseColor(value, &result->outputColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "key-color"))
else if(ffStrStartsWithIgnCase(subKey, "key-"))
{
if(value == NULL)
const char* subKey2 = subKey + strlen("key-");
if(ffStrEqualsIgnCase(subKey2, "color"))
{
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
exit(477);
if(value == NULL)
{
fprintf(stderr, "Error: usage: %s <str>\n", argumentKey);
exit(477);
}
ffOptionParseColor(value, &result->keyColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey2, "width"))
{
result->keyWidth = ffOptionParseUInt32(argumentKey, value);
return true;
}
else if(ffStrEqualsIgnCase(subKey2, "icon"))
{
ffOptionParseString(argumentKey, value, &result->keyIcon);
return true;
}
ffOptionParseColor(value, &result->keyColor);
return true;
}
else if(ffStrEqualsIgnCase(subKey, "key-width"))
{
result->keyWidth = ffOptionParseUInt32(argumentKey, value);
return true;
}
return false;
}
@@ -205,20 +214,3 @@ void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
#undef FF_APPEND_COLOR_PROP_COND
}
}
void ffOptionInitModuleArg(FFModuleArgs* args)
{
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInit(&args->outputFormat);
ffStrbufInit(&args->outputColor);
args->keyWidth = 0;
}
void ffOptionDestroyModuleArg(FFModuleArgs* args)
{
ffStrbufDestroy(&args->key);
ffStrbufDestroy(&args->keyColor);
ffStrbufDestroy(&args->outputFormat);
ffStrbufDestroy(&args->outputColor);
}
+28 -2
View File
@@ -45,10 +45,19 @@ static inline void ffOptionInitModuleBaseInfo(
baseInfo->generateJsonConfig = (__typeof__(baseInfo->generateJsonConfig)) generateJsonConfig;
}
typedef enum FFModuleKeyType
{
FF_MODULE_KEY_TYPE_NONE = 0,
FF_MODULE_KEY_TYPE_STRING = 1 << 0,
FF_MODULE_KEY_TYPE_ICON = 1 << 1,
FF_MODULE_KEY_TYPE_BOTH = FF_MODULE_KEY_TYPE_STRING | FF_MODULE_KEY_TYPE_ICON,
} FFModuleKeyType;
typedef struct FFModuleArgs
{
FFstrbuf key;
FFstrbuf keyColor;
FFstrbuf keyIcon;
FFstrbuf outputFormat;
FFstrbuf outputColor;
uint32_t keyWidth;
@@ -73,5 +82,22 @@ static inline void ffOptionParseColor(const char* value, FFstrbuf* buffer)
ffStrbufClear(buffer);
ffOptionParseColorNoClear(value, buffer);
}
void ffOptionInitModuleArg(FFModuleArgs* args);
void ffOptionDestroyModuleArg(FFModuleArgs* args);
static inline void ffOptionInitModuleArg(FFModuleArgs* args, const char* icon)
{
ffStrbufInit(&args->key);
ffStrbufInit(&args->keyColor);
ffStrbufInitStatic(&args->keyIcon, icon);
ffStrbufInit(&args->outputFormat);
ffStrbufInit(&args->outputColor);
args->keyWidth = 0;
}
static inline void ffOptionDestroyModuleArg(FFModuleArgs* args)
{
ffStrbufDestroy(&args->key);
ffStrbufDestroy(&args->keyColor);
ffStrbufDestroy(&args->keyIcon);
ffStrbufDestroy(&args->outputFormat);
ffStrbufDestroy(&args->outputColor);
}
+18 -4
View File
@@ -79,15 +79,15 @@ static void parseSize(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
void ffParseSize(uint64_t bytes, FFstrbuf* result)
{
switch (instance.config.display.binaryPrefixType)
switch (instance.config.display.sizeBinaryPrefix)
{
case FF_BINARY_PREFIX_TYPE_IEC:
case FF_SIZE_BINARY_PREFIX_TYPE_IEC:
parseSize(result, bytes, 1024, (const char*[]) {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", NULL});
break;
case FF_BINARY_PREFIX_TYPE_SI:
case FF_SIZE_BINARY_PREFIX_TYPE_SI:
parseSize(result, bytes, 1000, (const char*[]) {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL});
break;
case FF_BINARY_PREFIX_TYPE_JEDEC:
case FF_SIZE_BINARY_PREFIX_TYPE_JEDEC:
parseSize(result, bytes, 1024, (const char*[]) {"B", "KB", "MB", "GB", "TB", NULL});
break;
default:
@@ -96,6 +96,20 @@ void ffParseSize(uint64_t bytes, FFstrbuf* result)
}
}
bool ffParseFrequency(uint32_t mhz, FFstrbuf* result)
{
if (mhz == 0)
return false;
int8_t ndigits = instance.config.display.freqNdigits;
if (ndigits >= 0)
ffStrbufAppendF(result, "%.*f GHz", ndigits, mhz / 1000.);
else
ffStrbufAppendF(result, "%u MHz", (unsigned) mhz);
return true;
}
void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4)
{
if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
+1
View File
@@ -26,3 +26,4 @@ void ffVersionToPretty(const FFVersion* version, FFstrbuf* pretty);
int8_t ffVersionCompare(const FFVersion* version1, const FFVersion* version2);
void ffParseSize(uint64_t bytes, FFstrbuf* result);
bool ffParseFrequency(uint32_t mhz, FFstrbuf* result);
+29 -13
View File
@@ -11,8 +11,10 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
return;
//This is used as a magic value for hiding keys
if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")))
if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")) && instance.config.display.keyType != FF_MODULE_KEY_TYPE_NONE)
{
ffPrintCharTimes(' ', instance.config.display.keyPaddingLeft);
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
@@ -25,21 +27,35 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
ffPrintColor(&instance.config.display.colorKeys);
}
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
bool hasIcon = false;
if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_ICON && moduleArgs && moduleArgs->keyIcon.length > 0)
{
fputs(moduleName, stdout);
if(moduleIndex > 0)
printf(" %hhu", moduleIndex);
ffStrbufWriteTo(&moduleArgs->keyIcon, stdout);
hasIcon = true;
}
else
if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_STRING)
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 1, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex, "index"},
}));
ffStrbufWriteTo(&key, stdout);
if(hasIcon)
putchar(' ');
//NULL check is required for modules with custom keys, e.g. disk with the folder path
if((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0)
{
fputs(moduleName, stdout);
if(moduleIndex > 0)
printf(" %hhu", moduleIndex);
}
else
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &moduleIndex, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &moduleArgs->keyIcon, "icon"},
}));
ffStrbufWriteTo(&key, stdout);
}
}
if(!instance.config.display.pipe)
+4 -8
View File
@@ -4,11 +4,12 @@
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <ctype.h>
#ifdef _WIN32
#include "util/windows/getline.h"
#endif
static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer)
{
if(**line == '\0')
return false;
@@ -32,7 +33,7 @@ static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf*
}
//Line doesn't match start, skip it
if(**line != *start || **line == '\0')
if(tolower(**line) != tolower(*start) || **line == '\0')
return false;
//Line and start match, continue testing
@@ -69,14 +70,9 @@ static bool parsePropLinePointer(const char** line, const char* start, FFstrbuf*
return true;
}
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer)
{
return parsePropLinePointer(&line, start, buffer);
}
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer)
{
while(!parsePropLinePointer(&lines, start, buffer))
while(!ffParsePropLinePointer(&lines, start, buffer))
{
while(*lines != '\0' && *lines != '\n')
++lines;
+7 -1
View File
@@ -8,12 +8,18 @@ typedef struct FFpropquery
FFstrbuf* buffer;
} FFpropquery;
bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer);
bool ffParsePropLines(const char* lines, const char* start, FFstrbuf* buffer);
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropFileHomeValues(const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropFileListValues(const FFlist* list, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
bool ffParsePropLinePointer(const char** line, const char* start, FFstrbuf* buffer);
static inline bool ffParsePropLine(const char* line, const char* start, FFstrbuf* buffer)
{
return ffParsePropLinePointer(&line, start, buffer);
}
static inline bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer)
{
return ffParsePropFileValues(filename, 1, (FFpropquery[]){{start, buffer}});
+2 -2
View File
@@ -20,7 +20,7 @@ static inline uint64_t ffTimeGetTick() //In msec
#else
struct timespec timeNow;
clock_gettime(CLOCK_MONOTONIC, &timeNow);
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
#endif
}
@@ -33,7 +33,7 @@ static inline uint64_t ffTimeGetNow()
#else
struct timespec timeNow;
clock_gettime(CLOCK_REALTIME, &timeNow);
return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_nsec / 1000000));
return (uint64_t)(((uint64_t) timeNow.tv_sec * 1000u) + ((uint64_t) timeNow.tv_nsec / 1000000u));
#endif
}
+73 -41
View File
@@ -148,6 +148,16 @@
"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": [
@@ -495,6 +505,27 @@
"type": "num"
}
},
{
"long": "key-padding-left",
"desc": "Set the left padding of keys to <num> characters",
"arg": {
"type": "num"
}
},
{
"long": "key-type",
"desc": "Set whether to show icon before string keys",
"arg": {
"type": "enum",
"enum": {
"none": "Disable keys",
"string": "Show string",
"icon": "Show icon (requires newest nerd font)",
"both": "Show both icon and string"
},
"default": "string"
}
},
{
"long": "bright-color",
"desc": "Set if the keys, title and ASCII logo should be printed in bright color",
@@ -539,19 +570,6 @@
"default": false
}
},
{
"long": "binary-prefix",
"desc": "Set the binary prefix to used",
"arg": {
"type": "enum",
"enum": {
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
"SI": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ...",
"JEDEC": "1024 Bytes = 1 kB, 1024 kB = 1 MB, ..."
},
"default": "IEC"
}
},
{
"long": "percent-type",
"desc": "Set the percentage output type",
@@ -659,6 +677,19 @@
"type": "num"
}
},
{
"long": "size-binary-prefix",
"desc": "Set the binary prefix to used when formatting sizes",
"arg": {
"type": "enum",
"enum": {
"IEC": "1024 Bytes = 1 KiB, 1024 KiB = 1 MiB, ...",
"SI": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ...",
"JEDEC": "1024 Bytes = 1 kB, 1024 kB = 1 MB, ..."
},
"default": "IEC"
}
},
{
"long": "size-max-prefix",
"desc": "Set the largest binary prefix to use when formatting sizes",
@@ -678,6 +709,14 @@
"default": "YB"
}
},
{
"long": "freq-ndigits",
"desc": "Set the number of digits to keep after the decimal point when printing CPU / GPU frequency in GHz",
"arg": {
"type": "num",
"default": 2
}
},
{
"long": "temp-unit",
"desc": "Set the unit of the temperature",
@@ -725,26 +764,9 @@
"type": "color",
"default": "light_red"
}
},
{
"long": "ts-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
}
}
],
"Library path": [
{
"long": "lib-pci",
"desc": "Pciutils. Used for GPU output",
"arg": {
"type": "path"
}
},
{
"long": "lib-vulkan",
"desc": "Vulkan module & fallback for GPU output",
@@ -954,7 +976,7 @@
},
{
"long": "separator-string",
"desc": "Set the string printed by the separator module",
"desc": "Set the string to be printed by the separator line",
"arg": {
"type": "str",
"default": "-"
@@ -962,12 +984,21 @@
},
{
"long": "separator-output-color",
"desc": "Set the color of the separator module",
"desc": "Set the color of the separator line",
"arg": {
"type": "color",
"default": "default"
}
},
{
"long": "separator-length",
"desc": "Set the length of the separator line",
"remark": "Set to 0 to automatically calculate it with the title length",
"arg": {
"type": "num",
"default": "0"
}
},
{
"long": "disk-folders",
"desc": "A colon (semicolon on Windows) separated list of folder paths to be detected",
@@ -1175,14 +1206,6 @@
"default": false
}
},
{
"long": "cpu-freq-ndigits",
"desc": "Set the number of digits to keep after the decimal point when printing CPU frequency",
"arg": {
"type": "num",
"default": 2
}
},
{
"long": "cpu-show-pe-core-count",
"desc": "Detect and display CPU frequency of different core types (eg. Pcore and Ecore) if supported",
@@ -1545,13 +1568,14 @@
"type": "enum",
"enum": {
"block": "\u2588\u2588\u2588",
"background": "(whitespaces with background)",
"circle": "\u25cf",
"diamond": "\u25c6",
"triangle": "\u25b2",
"square": "\u25a0",
"star": "\u2605"
},
"default": "block"
"default": "background"
}
},
{
@@ -1634,6 +1658,14 @@
},
"pseudo": true
},
{
"long": "<module>-key-icon",
"desc": "Set the icon to be displayed by \"--key-type icon\"",
"arg": {
"type": "string"
},
"pseudo": true
},
{
"long": "<module>-output-color",
"desc": "Override the global \"--color-output\" option for each specific module",
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -29,7 +29,7 @@ static const char* detectWithBacklight(FFlist* result)
continue;
ffStrbufAppendS(&backlightDir, entry->d_name);
ffStrbufAppendS(&backlightDir, "/actual_brightness");
ffStrbufAppendS(&backlightDir, "/brightness");
if(ffReadFileBuffer(backlightDir.chars, &buffer))
{
double actualBrightness = ffStrbufToDouble(&buffer);
+3 -4
View File
@@ -19,10 +19,9 @@ typedef struct FFCPUResult
uint16_t coresLogical;
uint16_t coresOnline;
double frequencyBase; // GHz
double frequencyMax; // GHz
double frequencyMin; // GHz
double frequencyBiosLimit; // GHz
uint32_t frequencyBase; // GHz
uint32_t frequencyMax; // GHz
uint32_t frequencyBiosLimit; // GHz
FFCPUCore coreTypes[16]; // number of P cores, E cores, etc.
+18 -19
View File
@@ -43,38 +43,37 @@ static const char* detectFrequency(FFCPUResult* cpu)
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
FF_CFTYPE_AUTO_RELEASE CFMutableDictionaryRef properties = NULL;
if (IORegistryEntryCreateCFProperties(entryDevice, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
return "IORegistryEntryCreateCFProperties() failed";
uint32_t pMin, eMin, aMax, pCoreLength;
if (ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), 0, 4, (uint8_t*) &pMin, &pCoreLength) != NULL) // pCore
FF_CFTYPE_AUTO_RELEASE CFDataRef freqProperty = (CFDataRef) IORegistryEntryCreateCFProperty(entryDevice, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, kNilOptions);
if (!freqProperty || CFGetTypeID(freqProperty) != CFDataGetTypeID())
return "\"voltage-states5-sram\" in \"pmgr\" is not found";
if (ffCfDictGetData(properties, CFSTR("voltage-states1-sram"), 0, 4, (uint8_t*) &eMin, NULL) != NULL) // eCore
return "\"voltage-states1-sram\" in \"pmgr\" is not found";
cpu->frequencyMin = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000);
// voltage-states5-sram stores supported <frequency / voltage> pairs of pcores from the lowest to the highest
// voltage-states1-sram stores ecores'
CFIndex propLength = CFDataGetLength(freqProperty);
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0)
return "Invalid \"voltage-states5-sram\" length";
if (pCoreLength >= 8)
{
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL);
cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000);
}
uint32_t* pStart = (uint32_t*) CFDataGetBytePtr(freqProperty);
uint32_t pMax = *pStart;
for (CFIndex i = 2; i < propLength / (CFIndex) sizeof(uint32_t) && pStart[i] > 0; i += 2 /* skip voltage */)
pMax = pMax > pStart[i] ? pMax : pStart[i];
if (pMax > 0)
cpu->frequencyMax = pMax / 1000 / 1000;
return NULL;
}
#else
static const char* detectFrequency(FFCPUResult* cpu)
{
cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000.0 / 1000.0 / 1000.0;
if(cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = (uint32_t) (ffSysctlGetInt64("hw.cpufrequency", 0) / 1000 / 1000);
cpu->frequencyMax = (uint32_t) (ffSysctlGetInt64("hw.cpufrequency_max", 0) / 1000 / 1000);
if(cpu->frequencyBase == 0)
{
unsigned current = 0;
size_t size = sizeof(current);
if (sysctl((int[]){ CTL_HW, HW_CPU_FREQ }, 2, &current, &size, NULL, 0) == 0)
cpu->frequencyBase = (double) current / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyBase = (uint32_t) (current / 1000 / 1000);
}
return NULL;
}
+7 -11
View File
@@ -44,16 +44,13 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
ffStrbufClear(&buffer);
char key[32];
snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i);
if (ffSysctlGetString(key, &buffer) == NULL && buffer.length > 0)
if (ffSysctlGetString(key, &buffer) == NULL)
{
if (buffer.length == 0) continue;
// MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000
uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10);
uint32_t fmin = fmax;
uint32_t i = ffStrbufLastIndexC(&buffer, ' ');
if (i < buffer.length)
fmin = (uint32_t) strtoul(buffer.chars + i + 1, NULL, 10);
if (!(cpu->frequencyMin <= fmin)) cpu->frequencyMin = fmin; // Counting for NaN
if (!(cpu->frequencyMax >= fmax)) cpu->frequencyMax = fmax;
if (cpu->frequencyMax < fmax) cpu->frequencyMax = fmax;
if (options->showPeCoreCount)
{
@@ -65,12 +62,11 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coreTypes[ifreq].count++;
}
}
else
break;
}
cpu->frequencyMin /= 1000;
cpu->frequencyMax /= 1000;
int clockRate = ffSysctlGetInt("hw.clockrate", 0);
cpu->frequencyBase = clockRate <= 0 ? 0.0/0.0 : clockRate / 1000.0;
cpu->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
+55 -36
View File
@@ -13,18 +13,62 @@
#ifdef __ANDROID__
#include "common/settings.h"
static void detectQualcomm(FFCPUResult* cpu)
{
if (ffStrbufEqualS(&cpu->name, "SM8635"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8s Gen 3 [SM8635]");
else if (ffStrbufEqualS(&cpu->name, "SM8650-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 3 for Galaxy [SM8650-AC]");
else if (ffStrbufEqualS(&cpu->name, "SM8650"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 3 [SM8650]");
else if (ffStrbufEqualS(&cpu->name, "SM8550-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 2 for Galaxy [SM8550-AC]");
else if (ffStrbufEqualS(&cpu->name, "SM8550"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 2 [SM8550]");
else if (ffStrbufEqualS(&cpu->name, "SM8475"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8+ Gen 1 [SM8475]");
else if (ffStrbufEqualS(&cpu->name, "SM8450"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 8 Gen 1 [SM8450]");
else if (ffStrbufEqualS(&cpu->name, "SM7675"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7+ Gen 3 [SM7675]");
else if (ffStrbufEqualS(&cpu->name, "SM7550"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7 Gen 3 [SM7550]");
else if (ffStrbufEqualS(&cpu->name, "SM7475"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7+ Gen 2 [SM7550]");
else if (ffStrbufEqualS(&cpu->name, "SM7435"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7s Gen 2 [SM7435]");
else if (ffStrbufEqualS(&cpu->name, "SM7450"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 7 Gen 1 [SM7450]");
else if (ffStrbufEqualS(&cpu->name, "SM6375-AC"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6s Gen 3 [SM6375-AC]");
else if (ffStrbufEqualS(&cpu->name, "SM6450"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 6 Gen 1 [SM6450]");
else if (ffStrbufEqualS(&cpu->name, "SM4450"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 4 Gen 2 [SM4450]");
else if (ffStrbufEqualS(&cpu->name, "SM4375"))
ffStrbufSetStatic(&cpu->name, "Qualcomm Snapdragon 4 Gen 1 [SM4375]");
}
static void detectAndroid(FFCPUResult* cpu)
{
if (cpu->name.length == 0)
{
ffSettingsGetAndroidProperty("ro.soc.model", &cpu->name);
ffStrbufClear(&cpu->vendor); // We usually detect the vendor of CPU core as ARM, but instead we want the vendor of SOC
if (ffSettingsGetAndroidProperty("ro.soc.model", &cpu->name))
ffStrbufClear(&cpu->vendor); // We usually detect the vendor of CPU core as ARM, but instead we want the vendor of SOC
else if(ffSettingsGetAndroidProperty("ro.mediatek.platform", &cpu->name))
ffStrbufSetStatic(&cpu->vendor, "MTK");
}
if (cpu->vendor.length == 0)
{
if (!ffSettingsGetAndroidProperty("ro.soc.manufacturer", &cpu->vendor))
ffSettingsGetAndroidProperty("ro.product.product.manufacturer", &cpu->vendor);
}
if (ffStrbufEqualS(&cpu->vendor, "QTI") && ffStrbufStartsWithS(&cpu->name, "SM"))
detectQualcomm(cpu);
}
#endif
@@ -94,7 +138,7 @@ static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, co
bool ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return (uint32_t) ffStrbufToUInt(buffer, 0);
return (uint32_t) (ffStrbufToUInt(buffer, 0) / 1000);
if (scalingFileName)
{
@@ -102,7 +146,7 @@ static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, co
ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return (uint32_t) ffStrbufToUInt(buffer, 0);
return (uint32_t) (ffStrbufToUInt(buffer, 0) / 1000);
}
return 0;
@@ -143,36 +187,15 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
ffStrbufAppendS(&path, entry->d_name);
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase > 0)
{
if (cpu->frequencyBase == cpu->frequencyBase)
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
else
cpu->frequencyBase = fbase;
}
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
uint32_t fbioslimit = getFrequency(&path, "/bios_limit", NULL, &buffer);
if (fbioslimit > 0)
{
if (cpu->frequencyBiosLimit == cpu->frequencyBiosLimit)
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
else
cpu->frequencyBiosLimit = fbioslimit;
}
cpu->frequencyBiosLimit = cpu->frequencyBiosLimit > fbioslimit ? cpu->frequencyBiosLimit : fbioslimit;
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax > 0)
{
if (cpu->frequencyMax == cpu->frequencyMax)
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
else
cpu->frequencyMax = fmax;
}
uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
if (fmin > 0)
{
if (cpu->frequencyMin == cpu->frequencyMin)
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
else
cpu->frequencyMin = fmin;
}
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
if (options->showPeCoreCount)
{
@@ -187,10 +210,6 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
ffStrbufSubstrBefore(&path, baseLen);
}
}
cpu->frequencyBase /= 1e6;
cpu->frequencyMax /= 1e6;
cpu->frequencyMin /= 1e6;
cpu->frequencyBiosLimit /= 1e6;
return true;
}
@@ -272,8 +291,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
if (!detectFrequency(cpu, options) || cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = ffStrbufToDouble(&cpuMHz) / 1000;
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
if(cpuUarch.length > 0)
{
+1 -1
View File
@@ -31,7 +31,7 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe
}
{
kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz");
cpu->frequencyBase = kn->value.ui32 / 1000.;
cpu->frequencyBase = kn->value.ui32;
}
ks = kstat_lookup(kc, "unix", -1, "system_misc");
+7 -7
View File
@@ -65,8 +65,8 @@ inline static const char* detectSpeedByCpuid(FFCPUResult* cpu)
return "Unsupported instruction";
// cpuid returns 0 MHz when hyper-v is enabled
if (base) cpu->frequencyBase = base / 1000.0;
if (max) cpu->frequencyMax = max / 1000.0;
if (base) cpu->frequencyBase = base;
if (max) cpu->frequencyMax = max;
return NULL;
}
@@ -97,7 +97,7 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
return "No active CPU is found in SMBIOS data";
}
double speed = data->MaxSpeed / 1000.0;
uint32_t speed = data->MaxSpeed;
// Sometimes SMBIOS reports invalid value. We assume that max speed is small than 2x of base
if (speed < cpu->frequencyBase || speed > cpu->frequencyBase * 2)
return "Possible invalid CPU max speed in SMBIOS data. See #800";
@@ -159,7 +159,7 @@ static const char* detectByRegistry(FFCPUResult* cpu)
uint32_t mhz;
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
cpu->frequencyBase = mhz / 1000.0;
cpu->frequencyBase = mhz;
return NULL;
}
@@ -180,8 +180,8 @@ static const char* detectCoreTypes(FFCPUResult* cpu)
++cpu->coreTypes[ifreq].count;
}
if (cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = pinfo->MaxMhz / 1000.0;
if (cpu->frequencyBase == 0)
cpu->frequencyBase = pinfo->MaxMhz;
return NULL;
}
@@ -196,7 +196,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectSpeedByCpuid(cpu);
if (options->showPeCoreCount) detectCoreTypes(cpu);
if (cpu->frequencyMax != cpu->frequencyMax)
if (cpu->frequencyMax == 0)
detectMaxSpeedBySmbios(cpu);
if(options->temp)
+2
View File
@@ -180,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))
+4
View File
@@ -71,6 +71,10 @@ static bool isPhysicalDevice(const struct mntent* device)
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
) return false;
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
return false;
#endif // __ANDROID__
return true;
+13 -5
View File
@@ -1,6 +1,6 @@
#include "displayserver.h"
bool ffdsAppendDisplay(
FFDisplayResult* ffdsAppendDisplay(
FFDisplayServerResult* result,
uint32_t width,
uint32_t height,
@@ -11,10 +11,12 @@ bool ffdsAppendDisplay(
FFstrbuf* name,
FFDisplayType type,
bool primary,
uint64_t id)
uint64_t id,
uint32_t physicalWidth,
uint32_t physicalHeight)
{
if(width == 0 || height == 0)
return false;
return NULL;
FFDisplayResult* display = ffListAdd(&result->displays);
display->width = width;
@@ -25,10 +27,16 @@ bool ffdsAppendDisplay(
display->rotation = rotation;
ffStrbufInitMove(&display->name, name);
display->type = type;
display->primary = primary;
display->id = id;
display->physicalWidth = physicalWidth;
display->physicalHeight = physicalHeight;
display->primary = primary;
return true;
display->bitDepth = 0;
display->hdrEnabled = false;
display->wcgEnabled = false;
return display;
}
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds);
+10 -3
View File
@@ -58,8 +58,13 @@ typedef struct FFDisplayResult
FFstrbuf name;
FFDisplayType type;
uint32_t rotation;
bool primary;
uint64_t id; // platform dependent
uint32_t physicalWidth;
uint32_t physicalHeight;
bool primary;
uint8_t bitDepth;
bool hdrEnabled;
bool wcgEnabled;
} FFDisplayResult;
typedef struct FFDisplayServerResult
@@ -74,7 +79,7 @@ typedef struct FFDisplayServerResult
const FFDisplayServerResult* ffConnectDisplayServer();
bool ffdsAppendDisplay(
FFDisplayResult* ffdsAppendDisplay(
FFDisplayServerResult* result,
uint32_t width,
uint32_t height,
@@ -85,4 +90,6 @@ bool ffdsAppendDisplay(
FFstrbuf* name,
FFDisplayType type,
bool primary,
uint64_t id);
uint64_t id,
uint32_t physicalWidth,
uint32_t physicalHeight);
@@ -1,8 +1,9 @@
#include "displayserver.h"
#include "common/settings.h"
#include "common/processing.h"
#include <math.h>
static void detectWithDumpsys(FFDisplayServerResult* ds)
{
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
@@ -63,6 +64,8 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
&name,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0,
0,
0
);
}
@@ -79,20 +82,24 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
if (ffSettingsGetAndroidProperty("persist.sys.miui_resolution", &buffer) &&
ffStrbufContainC(&buffer, ','))
{
// 1440,3200,560 => width,height,ppi
// 1440,3200,560 => width,height,densityDpi
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
return ffdsAppendDisplay(ds,
width,
height,
0,
0,
0,
(uint32_t) (width / scaleFactor + .5),
(uint32_t) (height / scaleFactor + .5),
0,
0,
FF_DISPLAY_TYPE_BUILTIN,
false,
0,
0,
0
);
}
@@ -1,5 +1,6 @@
#include "displayserver.h"
#include "util/apple/cf_helpers.h"
#include "util/stringUtils.h"
#include <stdlib.h>
#include <string.h>
@@ -57,7 +58,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
if(CoreDisplay_IODisplayCreateInfoDictionary)
{
io_service_t servicePort = CGDisplayIOServicePort(screen);
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
CFDictionaryRef FF_CFTYPE_AUTO_RELEASE displayInfo = CoreDisplay_IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
if(displayInfo)
{
CFDictionaryRef productNames;
@@ -67,7 +68,9 @@ static void detectDisplays(FFDisplayServerResult* ds)
}
#endif
ffdsAppendDisplay(ds,
CGSize size = CGDisplayScreenSize(screen);
FFDisplayResult* display = ffdsAppendDisplay(ds,
(uint32_t)CGDisplayModeGetPixelWidth(mode),
(uint32_t)CGDisplayModeGetPixelHeight(mode),
refreshRate,
@@ -77,8 +80,28 @@ static void detectDisplays(FFDisplayServerResult* ds)
&name,
CGDisplayIsBuiltin(screen) ? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
CGDisplayIsMain(screen),
(uint64_t)screen
(uint64_t)screen,
(uint32_t) (size.width + 0.5),
(uint32_t) (size.height + 0.5)
);
if (display)
{
// Shitty code
uint8_t bitDepth = 0;
FF_CFTYPE_AUTO_RELEASE CFStringRef desc = CFCopyDescription(mode);
CFRange start = CFStringFind(desc, CFSTR("BitsPerSample = "), 0);
if (start.location != kCFNotFound)
{
for (CFIndex idx = start.location + start.length; idx < CFStringGetLength(desc); ++idx)
{
UniChar ch = CFStringGetCharacterAtIndex(desc, idx);
if (!ffCharIsDigit((char) ch))
break;
bitDepth = (uint8_t) (bitDepth * 10 + (ch - '0'));
}
}
display->bitDepth = bitDepth;
}
CGDisplayModeRelease(mode);
}
CGDisplayRelease(screen);
@@ -1,6 +1,9 @@
#include "displayserver.h"
#include "detection/os/os.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
#include "util/mallocHelper.h"
#include "util/edidHelper.h"
#include <dwmapi.h>
#include <WinUser.h>
@@ -73,6 +76,7 @@ static void detectDisplays(FFDisplayServerResult* ds)
if (!monitorInfo) continue;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
uint32_t physicalWidth = 0, physicalHeight = 0;
DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {
.header = {
@@ -84,13 +88,39 @@ static void detectDisplays(FFDisplayServerResult* ds)
};
if(DisplayConfigGetDeviceInfo(&targetName.header) == ERROR_SUCCESS)
{
if (targetName.flags.friendlyNameFromEdid)
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
wchar_t regPath[256] = L"SYSTEM\\CurrentControlSet\\Enum";
wchar_t* pRegPath = regPath + strlen("SYSTEM\\CurrentControlSet\\Enum");
wchar_t* pDevPath = targetName.monitorDevicePath + strlen("\\\\?");
while (*pDevPath && *pDevPath != L'{')
{
if (*pDevPath == L'#')
*pRegPath = L'\\';
else
*pRegPath = *pDevPath;
++pRegPath;
++pDevPath;
assert(pRegPath < regPath + sizeof(regPath) / sizeof(wchar_t) + strlen("Device Parameters"));
}
wcscpy(pRegPath, L"Device Parameters");
uint8_t edidData[1024];
DWORD edidLength = sizeof(edidData);
if (RegGetValueW(HKEY_LOCAL_MACHINE, regPath, L"EDID", RRF_RT_REG_BINARY, NULL, edidData, &edidLength) == ERROR_SUCCESS &&
edidLength > 0 && edidLength % 128 == 0)
{
ffEdidGetName(edidData, &name);
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
}
else
{
ffStrbufSetWS(&name, targetName.monitorDevicePath);
ffStrbufSubstrAfterFirstC(&name, '#');
ffStrbufSubstrBeforeFirstC(&name, '#');
if (targetName.flags.friendlyNameFromEdid)
ffStrbufSetWS(&name, targetName.monitorFriendlyDeviceName);
else
{
ffStrbufSetWS(&name, targetName.monitorDevicePath);
ffStrbufSubstrAfterFirstC(&name, '#');
ffStrbufSubstrBeforeFirstC(&name, '#');
}
}
}
@@ -102,26 +132,21 @@ static void detectDisplays(FFDisplayServerResult* ds)
uint32_t temp = width;
width = height;
height = temp;
temp = physicalWidth;
physicalWidth = physicalHeight;
physicalHeight = temp;
}
uint32_t rotation;
switch (path->targetInfo.rotation)
{
case DISPLAYCONFIG_ROTATION_ROTATE90:
rotation = 90;
break;
case DISPLAYCONFIG_ROTATION_ROTATE180:
rotation = 180;
break;
case DISPLAYCONFIG_ROTATION_ROTATE270:
rotation = 270;
break;
default:
rotation = 0;
break;
case DISPLAYCONFIG_ROTATION_ROTATE90: rotation = 90; break;
case DISPLAYCONFIG_ROTATION_ROTATE180: rotation = 180; break;
case DISPLAYCONFIG_ROTATION_ROTATE270: rotation = 270; break;
default: rotation = 0; break;
}
ffdsAppendDisplay(ds,
FFDisplayResult* display = ffdsAppendDisplay(ds,
width,
height,
path->targetInfo.refreshRate.Numerator / (double) path->targetInfo.refreshRate.Denominator,
@@ -135,8 +160,28 @@ static void detectDisplays(FFDisplayServerResult* ds)
path->targetInfo.outputTechnology == DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED
? FF_DISPLAY_TYPE_BUILTIN : FF_DISPLAY_TYPE_EXTERNAL,
!!(monitorInfo->info.dwFlags & MONITORINFOF_PRIMARY),
(uint64_t)(uintptr_t) monitorInfo->handle
(uint64_t)(uintptr_t) monitorInfo->handle,
physicalWidth,
physicalHeight
);
if (display)
{
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {
.header = {
.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO,
.size = sizeof(advColorInfo),
.adapterId = path->targetInfo.adapterId,
.id = path->targetInfo.id,
}
};
if (DisplayConfigGetDeviceInfo(&advColorInfo.header) == ERROR_SUCCESS)
{
display->hdrEnabled = !!advColorInfo.advancedColorEnabled;
display->wcgEnabled = !!advColorInfo.wideColorEnforced;
display->bitDepth = (uint8_t) advColorInfo.bitsPerColorChannel;
}
}
}
}
}
@@ -50,7 +50,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
if (ffSettingsGetFreeBSDKenv("screen.height", &buf))
{
uint32_t height = (uint32_t) ffStrbufToUInt(&buf, 0);
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0);
ffdsAppendDisplay(ds, width, height, 0, 0, 0, 0, NULL, FF_DISPLAY_TYPE_UNKNOWN, false, 0, 0, 0);
}
}
}
@@ -68,7 +68,7 @@ bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName)
// However I can't find a better method to get the edid data
const char* drmDirPath = "/sys/class/drm/";
DIR* dirp = opendir(drmDirPath);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
if(dirp == NULL)
return false;
@@ -90,13 +90,25 @@ bool ffdsMatchDrmConnector(const char* connName, FFstrbuf* edidName)
{
ffStrbufClear(edidName);
ffEdidGetName(edidData, edidName);
closedir(dirp);
return true;
}
break;
}
}
ffStrbufClear(edidName);
closedir(dirp);
return false;
}
FFDisplayType ffdsGetDisplayType(const char* name)
{
if(ffStrStartsWith(name, "eDP-") || ffStrStartsWith(name, "LVDS-"))
return FF_DISPLAY_TYPE_BUILTIN;
else if(ffStrStartsWith(name, "HDMI-") ||
ffStrStartsWith(name, "DP-") ||
ffStrStartsWith(name, "DisplayPort-") ||
ffStrStartsWith(name, "DVI-") ||
ffStrStartsWith(name, "VGA-"))
return FF_DISPLAY_TYPE_EXTERNAL;
return FF_DISPLAY_TYPE_UNKNOWN;
}
@@ -20,4 +20,6 @@ void ffdsConnectDrm(FFDisplayServerResult* result);
void ffdsDetectWMDE(FFDisplayServerResult* result);
FFDisplayType ffdsGetDisplayType(const char* drmConnectorName);
#endif
+21 -6
View File
@@ -37,7 +37,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
continue;
}
unsigned width = 0, height = 0;
unsigned width = 0, height = 0, physicalWidth = 0, physicalHeight = 0;
double refreshRate = 0;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
@@ -49,6 +49,7 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
{
ffEdidGetName(edidData, &name);
ffEdidGetPreferredResolutionAndRefreshRate(edidData, &width, &height, &refreshRate);
ffEdidGetPhysicalSize(edidData, &physicalWidth, &physicalHeight);
}
else
{
@@ -78,7 +79,9 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
&name,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0
0,
physicalWidth,
physicalHeight
);
ffStrbufSubstrBefore(&drmDir, drmDirLength);
@@ -217,6 +220,8 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
if (nDevices < 0)
return "drmGetDevices() failed";
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
for (int iDev = 0; iDev < nDevices; ++iDev)
{
drmDevice* dev = devices[iDev];
@@ -225,6 +230,13 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
continue;
const char* path = dev->nodes[DRM_NODE_PRIMARY];
ffStrbufSetF(&name, "/sys/class/drm/%s/device/power/runtime_status", strrchr(path, '/') + 1);
char buffer[8] = "";
if (ffReadFileData(name.chars, strlen("suspend"), buffer) > 0 && ffStrStartsWith(buffer, "suspend"))
continue;
FF_AUTO_CLOSE_FD int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
continue;
@@ -289,7 +301,8 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
}
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
ffStrbufClear(&name);
for (int iProp = 0; iProp < conn->count_props; ++iProp)
{
@@ -339,12 +352,14 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
0,
0,
&name,
conn->connector_type == DRM_MODE_CONNECTOR_eDP
conn->connector_type == DRM_MODE_CONNECTOR_eDP || conn->connector_type == DRM_MODE_CONNECTOR_LVDS
? FF_DISPLAY_TYPE_BUILTIN
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB || conn->connector_type == DRM_MODE_CONNECTOR_DisplayPort
? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
false,
conn->connector_id
conn->connector_id,
conn->mmWidth,
conn->mmHeight
);
}
@@ -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)
{
@@ -24,17 +25,52 @@ static void waylandOutputGeometryListener(void *data,
FF_MAYBE_UNUSED struct wl_output *output,
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,
int32_t physical_width,
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->physicalWidth = physical_width;
display->physicalHeight = physical_height;
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,60 +90,27 @@ 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)
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;
}
uint32_t rotation = ffWaylandHandleRotation(&display);
ffdsAppendDisplay(wldata->result,
(uint32_t) display.width,
@@ -124,7 +127,9 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist
: &display.name,
display.type,
false,
0
display.id,
(uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight
);
ffStrbufDestroy(&display.description);
@@ -132,4 +137,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,237 @@
#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,
int32_t physical_width,
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->physicalWidth = physical_width;
display->physicalHeight = physical_height;
display->transform = (enum wl_output_transform) transform;
}
static void waylandKdeNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* kde_output_device_v2, const char *name)
{
WaylandDisplay* display = data;
display->type = ffdsGetDisplayType(name);
strncpy((char*) &display->id, name, sizeof(display->id));
ffStrbufAppendS(&display->name, name);
}
static void waylandKdeHdrListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t hdr_enabled)
{
WaylandDisplay* display = data;
display->hdrEnabled = !!hdr_enabled;
}
static void waylandKdeWcgListener(void *data, FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, uint32_t wcg_enabled)
{
WaylandDisplay* display = data;
display->wcgEnabled = !!wcg_enabled;
}
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 = waylandKdeNameListener,
.high_dynamic_range = waylandKdeHdrListener,
.sdr_brightness = (void*) stubListener,
.wide_color_gamut = waylandKdeWcgListener,
.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 = ffWaylandHandleRotation(&display);
FFDisplayResult* item = 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,
(uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight
);
if (item)
{
item->hdrEnabled = display.hdrEnabled;
item->wcgEnabled = display.wcgEnabled;
}
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,27 +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);
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
@@ -47,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)
@@ -90,9 +110,85 @@ bool detectWayland(FFDisplayServerResult* result)
data.ffwl_proxy_add_listener(registry, (void(**)(void)) &registry_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.
@@ -103,21 +199,65 @@ bool detectWayland(FFDisplayServerResult* result)
void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* 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;
ffdsMatchDrmConnector(name, &display->edidName);
if (display->id) return;
display->type = ffdsGetDisplayType(name);
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);
}
uint32_t ffWaylandHandleRotation(WaylandDisplay* display)
{
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;
temp = display->physicalWidth;
display->physicalWidth = display->physicalHeight;
display->physicalHeight = temp;
break;
}
default:
break;
}
return rotation;
}
#endif
void ffdsConnectWayland(FFDisplayServerResult* result)
@@ -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
@@ -33,6 +36,8 @@ typedef struct WaylandDisplay
WaylandData* parent;
int32_t width;
int32_t height;
int32_t physicalWidth;
int32_t physicalHeight;
int32_t refreshRate;
double scale;
enum wl_output_transform transform;
@@ -40,6 +45,9 @@ typedef struct WaylandDisplay
FFstrbuf name;
FFstrbuf description;
FFstrbuf edidName;
uint64_t id;
bool hdrEnabled;
bool wcgEnabled;
void* internal;
} WaylandDisplay;
@@ -48,10 +56,26 @@ 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);
// Modifies content of display. Don't call this function when calling ffdsAppendDisplay
uint32_t ffWaylandHandleRotation(WaylandDisplay* display);
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,34 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw
wldata->refreshRate = current->refreshRate;
}
static void waylandZwlrPhysicalSizeListener(void* data, FF_MAYBE_UNUSED struct zwlr_output_head_v1 *zwlr_output_head_v1, int32_t width, int32_t height)
{
WaylandDisplay* wldata = (WaylandDisplay*) data;
wldata->physicalWidth = width;
wldata->physicalHeight = height;
}
static const struct zwlr_output_head_v1_listener headListener = {
.name = (void*) ffWaylandOutputNameListener,
.description = (void*) ffWaylandOutputDescriptionListener,
.physical_size = waylandZwlrPhysicalSizeListener,
.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,
@@ -113,38 +120,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
if(display.width <= 0 || display.height <= 0)
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;
}
uint32_t rotation = ffWaylandHandleRotation(&display);
ffdsAppendDisplay(wldata->result,
(uint32_t) display.width,
@@ -160,7 +136,9 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output
: &display.name,
display.type,
false,
0
display.id,
(uint32_t) display.physicalWidth,
(uint32_t) display.physicalHeight
);
ffStrbufDestroy(&display.description);
+41 -49
View File
@@ -41,32 +41,25 @@ static bool xcbInitPropertyData(void* libraryHandle, XcbPropertyData* propertyDa
static void* xcbGetProperty(XcbPropertyData* data, xcb_connection_t* connection, xcb_window_t window, const char* request)
{
xcb_intern_atom_cookie_t requestAtomCookie = data->ffxcb_intern_atom(connection, true, (uint16_t) strlen(request), request);
xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL);
FF_AUTO_FREE xcb_intern_atom_reply_t* requestAtomReply = data->ffxcb_intern_atom_reply(connection, requestAtomCookie, NULL);
if(requestAtomReply == NULL)
return NULL;
xcb_get_property_cookie_t propertyCookie = data->ffxcb_get_property(connection, false, window, requestAtomReply->atom, XCB_ATOM_ANY, 0, 64);
free(requestAtomReply);
xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL);
FF_AUTO_FREE xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL);
if(propertyReply == NULL)
return NULL;
int length = data->ffxcb_get_property_value_length(propertyReply);
if(length <= 0)
{
free(propertyReply);
return NULL;
}
//Why are xcb property strings not null terminated???
void* replyValue = malloc((size_t)length + 1);
memcpy(replyValue, data->ffxcb_get_property_value(propertyReply), (size_t) length);
((char*) replyValue)[length] = '\0';
free(propertyReply);
return replyValue;
}
@@ -75,28 +68,18 @@ static void xcbDetectWMfromEWMH(XcbPropertyData* data, xcb_connection_t* connect
if(result->wmProcessName.length > 0 || ffStrbufCompS(&result->wmProtocolName, FF_WM_PROTOCOL_WAYLAND) == 0)
return;
xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK");
FF_AUTO_FREE xcb_window_t* wmWindow = (xcb_window_t*) xcbGetProperty(data, connection, rootWindow, "_NET_SUPPORTING_WM_CHECK");
if(wmWindow == NULL)
return;
char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME");
FF_AUTO_FREE char* wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "_NET_WM_NAME");
if(wmName == NULL)
wmName = (char*) xcbGetProperty(data, connection, *wmWindow, "WM_NAME");
free(wmWindow);
if(wmName == NULL)
if(wmName == NULL || *wmName == '\0')
return;
if(*wmName == '\0')
{
free(wmName);
return;
}
ffStrbufSetS(&result->wmProcessName, wmName);
free(wmName);
}
void ffdsConnectXcb(FFDisplayServerResult* result)
@@ -122,17 +105,20 @@ void ffdsConnectXcb(FFDisplayServerResult* result)
while(iterator.rem > 0)
{
xcb_screen_t* screen = iterator.data;
ffdsAppendDisplay(result,
(uint32_t) iterator.data->width_in_pixels,
(uint32_t) iterator.data->height_in_pixels,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
0,
(uint32_t) iterator.data->width_in_pixels,
(uint32_t) iterator.data->height_in_pixels,
(uint32_t) screen->width_in_pixels,
(uint32_t) screen->height_in_pixels,
0,
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0
0,
(uint32_t) screen->width_in_millimeters,
(uint32_t) screen->height_in_millimeters
);
ffxcb_screen_next(&iterator);
}
@@ -191,7 +177,7 @@ typedef struct XcbRandrData
xcb_randr_get_screen_resources_current_reply_t* screenResources;
} XcbRandrData;
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary)
static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* modeInfo, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
{
double refreshRate = (double) modeInfo->dot_clock / (double) (modeInfo->htotal * modeInfo->vtotal);
@@ -204,13 +190,15 @@ static bool xcbRandrHandleModeInfo(XcbRandrData* data, xcb_randr_mode_info_t* mo
(uint32_t) modeInfo->height,
rotation,
name,
FF_DISPLAY_TYPE_UNKNOWN,
displayType,
primary,
0
0,
(uint32_t) output->mm_width,
(uint32_t) output->mm_height
);
}
static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary)
static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrbuf* name, uint32_t rotation, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
{
//We do the check here, because we want the best fallback display if this call failed
if(data->screenResources == NULL)
@@ -221,7 +209,7 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
while(modesIterator.rem > 0)
{
if(modesIterator.data->id == mode)
return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary);
return xcbRandrHandleModeInfo(data, modesIterator.data, name, rotation, primary, output, displayType);
data->ffxcb_randr_mode_info_next(&modesIterator);
}
@@ -229,10 +217,10 @@ static bool xcbRandrHandleMode(XcbRandrData* data, xcb_randr_mode_t mode, FFstrb
return false;
}
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary)
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType)
{
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME);
xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
FF_AUTO_FREE xcb_randr_get_crtc_info_reply_t* crtcInfoReply = data->ffxcb_randr_get_crtc_info_reply(data->connection, crtcInfoCookie, NULL);
if(crtcInfoReply == NULL)
return false;
@@ -252,8 +240,8 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
rotation = 0;
break;
}
bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary);
res = res ? true : ffdsAppendDisplay(
bool res = xcbRandrHandleMode(data, crtcInfoReply->mode, name, rotation, primary, output, displayType);
res = res ? true : !!ffdsAppendDisplay(
data->result,
(uint32_t) crtcInfoReply->width,
(uint32_t) crtcInfoReply->height,
@@ -262,16 +250,17 @@ static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrb
(uint32_t) crtcInfoReply->height,
rotation,
name,
FF_DISPLAY_TYPE_UNKNOWN,
displayType,
primary,
0
0,
(uint32_t) output->mm_width,
(uint32_t) output->mm_height
);
free(crtcInfoReply);
return res;
}
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary)
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType)
{
xcb_randr_get_output_info_cookie_t outputInfoCookie = data->ffxcb_randr_get_output_info(data->connection, output, XCB_CURRENT_TIME);
FF_AUTO_FREE xcb_randr_get_output_info_reply_t* outputInfoReply = data->ffxcb_randr_get_output_info_reply(data->connection, outputInfoCookie, NULL);
@@ -294,7 +283,7 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
}
}
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary);
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply, displayType);
return res;
}
@@ -317,17 +306,18 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
(uint32_t) data->propData.ffxcb_get_atom_name_name_length(nameReply),
data->propData.ffxcb_get_atom_name_name(nameReply)
);
const FFDisplayType displayType = ffdsGetDisplayType(name.chars);
bool foundOutput = false;
while(outputIterator.rem > 0)
{
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary))
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType))
foundOutput = true;
data->ffxcb_randr_output_next(&outputIterator);
};
return foundOutput ? true : ffdsAppendDisplay(
return foundOutput ? true : !!ffdsAppendDisplay(
data->result,
(uint32_t) monitor->width,
(uint32_t) monitor->height,
@@ -336,16 +326,18 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
(uint32_t) monitor->height,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
displayType,
!!monitor->primary,
0
0,
(uint32_t) monitor->width_in_millimeters,
(uint32_t) monitor->height_in_millimeters
);
}
static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
{
xcb_randr_get_monitors_cookie_t monitorsCookie = data->ffxcb_randr_get_monitors(data->connection, screen->root, true);
xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL);
FF_AUTO_FREE xcb_randr_get_monitors_reply_t* monitorsReply = data->ffxcb_randr_get_monitors_reply(data->connection, monitorsCookie, NULL);
if(monitorsReply == NULL)
return false;
@@ -360,8 +352,6 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
data->ffxcb_randr_monitor_info_next(&monitorInfoIterator);
}
free(monitorsReply);
return foundMonitor;
}
@@ -392,7 +382,9 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0
0,
(uint32_t) screen->width_in_millimeters,
(uint32_t) screen->height_in_millimeters
);
}
+20 -13
View File
@@ -87,7 +87,9 @@ void ffdsConnectXlib(FFDisplayServerResult* result)
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0
0,
(uint32_t) WidthMMOfScreen(screen),
(uint32_t) HeightMMOfScreen(screen)
);
}
@@ -117,7 +119,6 @@ typedef struct XrandrData
FF_LIBRARY_SYMBOL(XInternAtom)
FF_LIBRARY_SYMBOL(XGetAtomName);
FF_LIBRARY_SYMBOL(XFree);
FF_LIBRARY_SYMBOL(XRRConfigCurrentRate)
FF_LIBRARY_SYMBOL(XRRGetMonitors)
FF_LIBRARY_SYMBOL(XRRGetScreenResourcesCurrent)
FF_LIBRARY_SYMBOL(XRRGetOutputInfo)
@@ -149,7 +150,7 @@ static double xrandrHandleMode(XrandrData* data, RRMode mode)
return 0;
}
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary)
static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool primary, XRROutputInfo* output, FFDisplayType displayType)
{
//We do the check here, because we want the best fallback display if this call failed
if(data->screenResources == NULL)
@@ -185,16 +186,18 @@ static bool xrandrHandleCrtc(XrandrData* data, RRCrtc crtc, FFstrbuf* name, bool
(uint32_t) crtcInfo->height,
rotation,
name,
FF_DISPLAY_TYPE_UNKNOWN,
displayType,
primary,
0
0,
(uint32_t) output->mm_width,
(uint32_t) output->mm_height
);
data->ffXRRFreeCrtcInfo(crtcInfo);
return res;
}
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary)
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType)
{
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output);
if(outputInfo == NULL)
@@ -218,7 +221,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
if (edidData)
data->ffXFree(edidData);
}
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary);
bool res = xrandrHandleCrtc(data, outputInfo->crtc, name, primary, outputInfo, displayType);
data->ffXRRFreeOutputInfo(outputInfo);
@@ -231,13 +234,14 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
char* xname = data->ffXGetAtomName(data->display, monitorInfo->name);
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(xname);
data->ffXFree(xname);
FFDisplayType displayType = ffdsGetDisplayType(name.chars);
for(int i = 0; i < monitorInfo->noutput; i++)
{
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary))
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType))
foundOutput = true;
}
return foundOutput ? true : ffdsAppendDisplay(
return foundOutput ? true : !!ffdsAppendDisplay(
data->result,
(uint32_t) monitorInfo->width,
(uint32_t) monitorInfo->height,
@@ -246,9 +250,11 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
(uint32_t) monitorInfo->height,
0,
&name,
FF_DISPLAY_TYPE_UNKNOWN,
displayType,
!!monitorInfo->primary,
0
0,
(uint32_t) monitorInfo->mwidth,
(uint32_t) monitorInfo->mheight
);
}
@@ -296,7 +302,9 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
NULL,
FF_DISPLAY_TYPE_UNKNOWN,
false,
0
0,
(uint32_t) WidthMMOfScreen(screen),
(uint32_t) HeightMMOfScreen(screen)
);
}
@@ -312,7 +320,6 @@ void ffdsConnectXrandr(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XInternAtom,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XGetAtomName,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XFree,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRConfigCurrentRate,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetMonitors,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetScreenResourcesCurrent,);
FF_LIBRARY_LOAD_SYMBOL_VAR(xrandr, data, XRRGetOutputInfo,);
+1 -1
View File
@@ -26,7 +26,7 @@ const char* ffDetectEditor(FFEditorResult* result)
return "$VISUAL or $EDITOR not set";
}
if (!instance.config.display.tsVersion) return NULL;
if (!instance.config.general.detectVersion) return NULL;
#ifndef _WIN32
if (result->name.chars[0] != '/')
+3
View File
@@ -42,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)
{
@@ -75,6 +77,7 @@ const char* detectByOpenGL(FFlist* gpus)
ffStrbufDestroy(&result.renderer);
ffStrbufDestroy(&result.vendor);
ffStrbufDestroy(&result.slv);
ffStrbufDestroy(&result.library);
return error;
}
+2 -2
View File
@@ -5,7 +5,7 @@
#define FF_GPU_TEMP_UNSET (0/0.0)
#define FF_GPU_CORE_COUNT_UNSET -1
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t)-1)
#define FF_GPU_FREQUENCY_UNSET (0/0.0)
#define FF_GPU_FREQUENCY_UNSET 0
extern const char* FF_GPU_VENDOR_NAME_APPLE;
extern const char* FF_GPU_VENDOR_NAME_AMD;
@@ -32,7 +32,7 @@ typedef struct FFGPUResult
FFstrbuf platformApi;
double temperature;
int32_t coreCount;
double frequency; // Real time clock frequency in GHz
uint32_t frequency; // Maximum time clock frequency in MHz
FFGPUMemory dedicated;
FFGPUMemory shared;
uint64_t deviceId; // Used internally, may be uninitialized
+1 -1
View File
@@ -60,7 +60,7 @@ const char* ffDetectAmdGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResu
}
if (result.frequency)
*result.frequency = device->coreClock / 1000.; // Maximum frequency
*result.frequency = (uint32_t) device->coreClock; // Maximum frequency
if (result.type)
*result.type = device->isAPU ? FF_GPU_TYPE_INTEGRATED : FF_GPU_TYPE_DISCRETE;
+42
View File
@@ -36,6 +36,43 @@ static double detectGpuTemp(const FFstrbuf* gpuName)
return result;
}
#ifdef __aarch64__
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
static const char* detectFrequency(FFGPUResult* gpu)
{
// https://github.com/giampaolo/psutil/pull/2222/files
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDevice = IOServiceGetMatchingService(MACH_PORT_NULL, IOServiceNameMatching("pmgr"));
if (!entryDevice)
return "IOServiceGetMatchingServices() failed";
if (!IOObjectConformsTo(entryDevice, "AppleARMIODevice"))
return "\"pmgr\" should conform to \"AppleARMIODevice\"";
FF_CFTYPE_AUTO_RELEASE CFDataRef freqProperty = (CFDataRef) IORegistryEntryCreateCFProperty(entryDevice, CFSTR("voltage-states9-sram"), kCFAllocatorDefault, kNilOptions);
if (!freqProperty || CFGetTypeID(freqProperty) != CFDataGetTypeID())
return "\"voltage-states9-sram\" in \"pmgr\" is not found";
// voltage-states5-sram stores supported <frequency / voltage> pairs of gpu from the lowest to the highest
CFIndex propLength = CFDataGetLength(freqProperty);
if (propLength == 0 || propLength % (CFIndex) sizeof(uint32_t) * 2 != 0)
return "Invalid \"voltage-states9-sram\" length";
uint32_t* pStart = (uint32_t*) CFDataGetBytePtr(freqProperty);
uint32_t pMax = *pStart;
for (CFIndex i = 2; i < propLength / (CFIndex) sizeof(uint32_t) && pStart[i] > 0; i += 2 /* skip voltage */)
pMax = pMax > pStart[i] ? pMax : pStart[i];
if (pMax > 0)
gpu->frequency = pMax / 1000 / 1000;
return NULL;
}
#endif
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = IO_OBJECT_NULL;
@@ -94,6 +131,11 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
gpu->type = FF_GPU_TYPE_INTEGRATED;
else if (vendorStr == FF_GPU_VENDOR_NAME_NVIDIA || vendorStr == FF_GPU_VENDOR_NAME_AMD)
gpu->type = FF_GPU_TYPE_DISCRETE;
#ifdef __aarch64__
if (vendorStr == FF_GPU_VENDOR_NAME_APPLE)
detectFrequency(gpu);
#endif
}
gpu->temperature = options->temp ? detectGpuTemp(&gpu->name) : FF_GPU_TEMP_UNSET;
+1 -1
View File
@@ -41,7 +41,7 @@ typedef struct FFGpuDriverResult
FFGPUMemory* memory;
uint32_t* coreCount;
FFGPUType* type;
double* frequency;
uint32_t* frequency;
} FFGpuDriverResult;
const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName);
+1 -1
View File
@@ -191,7 +191,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
maxValue = props.max;
}
}
*result.frequency = maxValue / 1000;
*result.frequency = (uint32_t) (maxValue + 0.5);
}
}
+50 -27
View File
@@ -32,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)
@@ -78,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;
@@ -92,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);
@@ -125,19 +133,26 @@ static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf*
ffStrbufSubstrAfter(&gpu->name, (uint32_t) strlen("Intel "));
gpu->type = ffStrbufStartsWithIgnCaseS(&gpu->name, "Arc ") ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
ffStrbufAppendS(pciDir, "/drm/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
if (ffStrbufEqualS(&gpu->driver, "xe"))
{
if (ffStrStartsWith(entry->d_name, "card")) break;
ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq");
}
else
{
ffStrbufAppendS(pciDir, "/drm/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (!dirp) return;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (ffStrStartsWith(entry->d_name, "card")) break;
}
if (!entry) return;
ffStrbufAppendS(pciDir, entry->d_name);
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
}
if (!entry) return;
ffStrbufAppendS(pciDir, entry->d_name);
ffStrbufAppendS(pciDir, "/gt_max_freq_mhz");
if (ffReadFileBuffer(pciDir->chars, buffer))
gpu->frequency = ffStrbufToDouble(buffer) / 1000.0;
gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0);
}
static bool loadPciIds(FFstrbuf* pciids)
@@ -197,6 +212,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);
@@ -323,7 +346,7 @@ FF_MAYBE_UNUSED static const char* detectAsahi(FFlist* gpus, FFstrbuf* buffer, F
}) >= 0)
{
gpu->coreCount = (int) paramsGlobal.num_cores_total_active;
gpu->frequency = paramsGlobal.max_frequency_khz / 1e6;
gpu->frequency = paramsGlobal.max_frequency_khz / 1000;
gpu->deviceId = paramsGlobal.chip_id;
}
}
+1 -5
View File
@@ -122,11 +122,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR
nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount);
if (result.frequency)
{
uint32_t clockMHz;
if (nvmlData.ffnvmlDeviceGetMaxClockInfo(device, NVML_CLOCK_GRAPHICS, &clockMHz) == NVML_SUCCESS)
*result.frequency = clockMHz / 1000.;
}
nvmlData.ffnvmlDeviceGetMaxClockInfo(device, NVML_CLOCK_GRAPHICS, result.frequency);
return NULL;
+2 -2
View File
@@ -22,10 +22,10 @@ static const char* getProductNameWithHwModel(const FFstrbuf* hwModel)
if(ffStrEquals(version, "18,1") ||
ffStrEquals(version, "18,2")) return "MacBook Pro (16-inch, 2021)";
if(ffStrEquals(version, "17,1")) return "MacBook Pro (13-inch, M1, 2020)";
if(ffStrEquals(version, "16,4")) return "MacBook Pro (16-inch, 2019)";
if(ffStrEquals(version, "16,3")) return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
if(ffStrEquals(version, "16,2")) return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
if(ffStrEquals(version, "16,1")) return "MacBook Pro (16-inch, 2019)";
if(ffStrEquals(version, "16,4") ||
ffStrEquals(version, "16,1")) return "MacBook Pro (16-inch, 2019)";
if(ffStrEquals(version, "15,4")) return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
if(ffStrEquals(version, "15,3")) return "MacBook Pro (15-inch, 2019)";
if(ffStrEquals(version, "15,2")) return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
+9 -6
View File
@@ -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
}
}
}
+41 -26
View File
@@ -1,10 +1,22 @@
#include "initsystem.h"
#include "common/processing.h"
#include <unistd.h>
const char* ffDetectInitSystem(FFInitSystemResult* result)
{
const char* error = ffProcessGetBasicInfoLinux((int) result->pid, &result->name, NULL, NULL);
if (error) return error;
if (error)
{
#ifdef __ANDROID__
if (access("/system/bin/init", F_OK) == 0)
{
ffStrbufSetStatic(&result->exe, "/system/bin/init");
ffStrbufSetStatic(&result->name, "init");
return NULL;
}
#endif
return error;
}
const char* _;
// In linux /proc/1/exe is not readable
@@ -17,38 +29,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);
}
}
}
}
+14 -12
View File
@@ -35,13 +35,12 @@ static const char* getSshdVersion(FFstrbuf* version)
{
const char* error = ffProcessAppendStdErr(version, (char* const[]) {
"sshd",
"-qv",
"-V",
NULL
});
if (error)
return error;
// unknown option -- v
// OpenSSH_9.0p1, OpenSSL 3.0.9 30 May 2023...
ffStrbufSubstrBeforeFirstC(version, ',');
ffStrbufSubstrAfterFirstC(version, '_');
@@ -163,16 +162,19 @@ const char* ffDetectLM(FFLMResult* result)
}))
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))
+1
View File
@@ -5,6 +5,7 @@ typedef struct FFMonitorResult
FFstrbuf name;
uint32_t width; // native / maximum resolution, in pixels
uint32_t height; // native / maximum resolution, in pixels
double refreshRate;// maximum refresh rate in native resolution, in Hz
uint32_t physicalWidth; // in mm
uint32_t physicalHeight; // in mm
bool hdrCompatible;

Some files were not shown because too many files have changed in this diff Show More