Compare commits

...

151 Commits

Author SHA1 Message Date
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
Carter Li cec38b9501 Merge pull request #1069 from fastfetch-cli/dev
Release: v2.17.2
2024-07-04 08:33:15 +08:00
李通洲 3453b72f0c Release: v2.17.2 2024-07-03 20:03:06 +08:00
李通洲 060544b899 Packages (Linux): detect flatpak-app only
The runtime packages detection was inaccurate. The official `flatpak
list` ignores some packages (notablily *.Locale) but the logic is
currently unknown.
2024-07-03 20:01:27 +08:00
李通洲 14c6b6d7e2 Doc: update changelog 2024-07-03 16:42:55 +08:00
李通洲 9df394bba3 Revert "OS (Linux): prioritize prettyName over name"
This reverts commit ecd69370ab.
2024-07-03 16:37:51 +08:00
李通洲 b25ffda90b PhysicalDisk: silence compiler warnings 2024-07-03 16:24:17 +08:00
李通洲 db9cf4ef29 CMake: add option ENABLE_LTO 2024-07-03 16:10:34 +08:00
李通洲 7b2d4b7a0d Wifi: silence compiler warnings 2024-07-03 15:27:06 +08:00
李通洲 64cdb3f058 LocalIP: silence compiler warnings 2024-07-03 15:26:53 +08:00
李通洲 66e7924fa3 Logo (Image): fix building on SunOS 2024-07-03 15:12:48 +08:00
李通洲 84540250f7 Editor: make --ts-version false disable version detection 2024-07-03 13:59:39 +08:00
李通洲 96e7f65902 DE (Linux): fix silly bug 2024-07-03 13:56:35 +08:00
Carter Li 321d3e5574 CMake: don't error out if we fail to detect glibc version 2024-07-03 09:54:48 +08:00
Carter Li 2bba2eaa16 WM: minor code cleanup 2024-07-03 09:54:48 +08:00
Carter Li 58ebde422a WMTheme: support cinnamon-wayland 2024-07-03 09:54:48 +08:00
Carter Li 06f3b9a96d DE (Linux): improve Cinnamon version detection
Fix #1068
2024-07-03 09:54:21 +08:00
李通洲 fa5aaa692f Doc: update copyright [ci skip] 2024-07-02 15:12:28 +08:00
李通洲 9d2c4f52d2 CI: clean up 2024-07-02 15:00:39 +08:00
李通洲 9946a5d758 CI: add stale.yml [ci skip] 2024-07-02 14:14:16 +08:00
Carter Li a749014e7c Kernel: code refactor 2024-07-02 10:47:14 +08:00
LinuxOnTheDesktop 2cd421fc2e Doc: correct various errors of English (#1065)
Including but not limited to: number agreement; punctuation
2024-07-02 10:45:36 +08:00
李通洲 4db6aebcc9 TerminalFont (Linux): support Ptyxis 2024-07-01 23:56:53 +08:00
李通洲 3b156e819b Terminal (Linux): support ptyxis version detection 2024-07-01 23:56:19 +08:00
Diego Viola 7ffed9e911 DE: Fix spelling of LXQt (#1063)
Signed-off-by: Diego Viola <diego.viola@gmail.com>
2024-07-01 16:00:35 +08:00
李通洲 9042950ee8 Color: if value is already an ANSI escape code, use it 2024-07-01 15:04:51 +08:00
Diego Viola 7aad0dc32f Theme: Fix spelling of Qt (#1062)
Signed-off-by: Diego Viola <diego.viola@gmail.com>
2024-07-01 14:38:29 +08:00
李通洲 01d04a8fa2 PhysicalMemory: remove an unused variable 2024-07-01 13:54:57 +08:00
Carter Li d3e50fe595 Packaging: update debian stuff [ci skip] 2024-07-01 13:34:28 +08:00
Carter Li ecd69370ab OS (Linux): prioritize prettyName over name 2024-07-01 08:56:00 +08:00
李通洲 abd2522268 JsonSchema: add formattion keys for CpuUsage module
Fix #1060
2024-06-30 20:01:57 +08:00
李通洲 2e1261bc21 PhysicalMemory: fix incorrect size value for large memory sticks
Fix #1061 (integer overflow)
2024-06-30 19:13:58 +08:00
李通洲 0e597a2ded Battery: fix index format with multiple batteries 2024-06-29 21:59:57 +08:00
scarf 2781a0ab93 docs: document --logo none (#1059) 2024-06-29 19:32:36 +08:00
李通洲 02d7f2693b Doc: fix document of --pipe [ci skip]
Fix #1058
2024-06-29 18:53:52 +08:00
Carter Li b001ea409b Merge pull request #1056 from fastfetch-cli/dev
Release: v2.17.1
2024-06-29 08:20:39 +08:00
李通洲 f97a9fdfc0 GPU: don't print 16 EiB 2024-06-29 07:55:01 +08:00
李通洲 2c8d5292d7 Release: v2.17.1 2024-06-29 07:29:53 +08:00
李通洲 88e4579f1e Fastfetch: fix segfaults with --show-errors and an invalid module
Fix #1055
2024-06-29 07:16:35 +08:00
Carlos & 8f97e61f67 Theme (QT): ignore QVariant format (#1054)
Closes: #1053

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-06-29 07:14:36 +08:00
李通洲 0b943bb25e GPU: print formatted size when --gpu-format is used
Fix #1052
2024-06-28 22:24:02 +08:00
李通洲 19590003e1 GPU: guard GPU frequency behind driverSpecific 2024-06-28 22:17:37 +08:00
李通洲 27a1d9f8c6 Logo (Image): fix building on Windows 2024-06-28 18:08:16 +08:00
李通洲 d50ebc86c7 CMake (Windows): don't generate libffwinrt.dll.a 2024-06-28 15:15:49 +08:00
186 changed files with 5039 additions and 1645 deletions
+21
View File
@@ -0,0 +1,21 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- keepalive
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+12 -51
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
@@ -375,7 +375,6 @@ jobs:
- name: checkout repository
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: run VM
uses: vmactions/omnios-vm@v1
with:
@@ -417,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
@@ -439,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
@@ -515,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
@@ -585,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
@@ -624,7 +586,6 @@ jobs:
- musl-aarch64
- macos-universal
- freebsd-amd64
- freebsd-aarch64
- sunos-amd64
- windows-amd64
- windows-i686
+139 -3
View File
@@ -1,3 +1,139 @@
# 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:
* Flatpak package count no longer takes runtime packages into account (Packages, Linux)
Bugfixes:
* Fix formattion with multiple batteries (Battery)
* Fix incorrect size value for large memory sticks (PhysicalMemory)
* Fix spelling of `Qt` and `LXQt`
* Fix building on SunOS if imagemagick support is enabled (Logo, SunOS)
* Fix typos
Features:
* Support Ptyxis terminal version and font detection (Terminal / TerminalFont, Linux)
* Improve Cinnamon version detection (DE)
* Support `cinnamon-wayland` (WMTheme)
* `--ts-version false` will disable editor version detection (Editor)
# 2.17.1
Hotfix for a regression that breaks Qt font detection
Bugfixes:
* Don't generate and install `libffwinrt.dll.a` on MinGW (Windows)
* Fix building on Windows when imagemagick support is enabled (Logo, Windows)
* Don't print GPU frequency with `--gpu-temp` for Nvidia cards (#1052, GPU)
* `--gpu-driver-specific` needs to be specified
* Print formatted size when `--gpu-format` is used (#1052, GPU)
* Ignore QVariant format; fix unreadable Qt font (#1053, Theme, Linux)
* Fix segfaults with `--show-errors` and an invalid module (#1055)
# 2.17.0
Changes:
@@ -1048,7 +1184,7 @@ Bugfixes:
This release backports some changes from dev branch, and fixes 2 crashing issues
Features:
* Support KDE / LXQT / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
* Support KDE / LXQt / MATE / Cinnamon wallpaper detection (Wallpaper, Linux)
* Support QTerminal version & terminal font detection
* Support MATE Terminal version & terminal font detection
* Set `--pipe true` automatically if stdout is not a tty
@@ -1094,7 +1230,7 @@ Bugfixes:
* Fix Windows drives detection in WSL (Disk)
Changes:
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / QT icon params.
* In order to make Icons module consistent between different platforms, `--icons-format` no longer supports individual GTK / Qt icon params.
* `--theme-format` no longer supports individual GTK / plasma theme params.
* `--local-ip-*` and `--public-ip-*` have been changed to `--localip-*` and `--publicip-*`
* `--localip-compact-type` is no longer supported. Fastfetch now display IPs as `--localip-compat-type multiline` by default, with `--local-compact true` can be set as an alias of `--localip-compact-type oneline`
@@ -1468,7 +1604,7 @@ Fixes build on android (#205)
# 1.6.0
Features:
* Detect QT on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [QT]
* Detect Qt on more DEs than just KDE Plasma. The [Plasma] category was therefore renamed to [Qt]
* Alacritty font detection
* Load `/etc/fastfetch/config.conf` before user config
* Disk: print one decimal point if size < 100GB
+29 -9
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.0
VERSION 2.19.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)
@@ -74,6 +74,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
option(ENABLE_LTO "Enable link-time optimization in release mode if supported" ON)
option(BUILD_TESTS "Build tests" OFF) # Also create test executables
option(SET_TWEAK "Add tweak to project version" ON) # This is set to off by github actions for release builds
option(IS_MUSL "Build with musl libc" OFF) # Used by Github Actions
@@ -139,7 +140,7 @@ if(NOT WIN32)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -rdynamic")
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
if(ENABLE_LTO AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Enabling LTO")
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORTED)
@@ -306,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
@@ -394,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
@@ -428,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
@@ -561,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
@@ -580,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
@@ -762,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
@@ -781,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
@@ -1156,7 +1171,7 @@ if(WIN32)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX("winrt/Windows.Foundation.h" HAVE_WINRT)
if(HAVE_WINRT)
add_library(ffwinrt SHARED src/detection/media/media_windows.dll.cpp)
add_library(ffwinrt MODULE src/detection/media/media_windows.dll.cpp)
target_link_libraries(ffwinrt PRIVATE "RuntimeObject")
target_compile_definitions(ffwinrt PRIVATE WIN32_LEAN_AND_MEAN=1 WINRT_LEAN_AND_MEAN=1)
target_link_options(ffwinrt
@@ -1322,12 +1337,17 @@ if(LINUX)
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
if(NOT IS_MUSL)
EXECUTE_PROCESS (
EXECUTE_PROCESS(
COMMAND getconf GNU_LIBC_VERSION
OUTPUT_VARIABLE GLIBC_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
STRING (REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
if(GLIBC_VERSION)
STRING(REPLACE "glibc " "" GLIBC_VERSION ${GLIBC_VERSION})
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= ${GLIBC_VERSION})")
message(STATUS "found glibc ${GLIBC_VERSION}")
else()
message(WARNING "Could not determine glibc version. If `musl` is used, `-DIS_MUSL=ON` should be set")
endif()
endif()
endif()
+2 -1
View File
@@ -1,6 +1,7 @@
MIT License
Copyright (c) 2021 Linus Dierheimer
Copyright (c) 2021-2023 Linus Dierheimer
Copyright (c) 2022-2024 Carter Li
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+22 -14
View File
@@ -11,7 +11,7 @@
[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions)
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.
Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, macOS, SunOS and Windows 7+ are supported.
<img src="screenshots/example1.png" width="49%" align="left" />
<img src="https://upload.wikimedia.org/wikipedia/commons/2/24/Transparent_Square_Tiles_Texture.png" width="49%" height="16px" align="left" />
@@ -21,13 +21,13 @@ Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for
<img src="screenshots/example3.png" width="48%" align="top" />
<img src="screenshots/example5.png" height="15%" align="top" />
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki)
There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki).
## Installation
### Linux
Some distros packaged an outdated fastfetch version. Older version is not supported, please always ensure that the latest version is used.
Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version.
* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer)
* Debian: `sudo apt install fastfetch` (for Debian 13 or newer)
@@ -57,7 +57,7 @@ If fastfetch is not packaged for your distro or an outdated version is packaged,
* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch`
* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-fastfetch`
You may also download it directly from [GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and extract the archive.
You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file.
### FreeBSD
@@ -81,7 +81,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building
## Customization
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. They may also serve as a good example for format arguments.
Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c <filename>`. Those files can serve as examples of the configuration syntax.
Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information.
@@ -103,10 +103,10 @@ Logos can be heavily customized too; see the [logo documentation](https://github
1. Fastfetch is actively maintained.
2. Fastfetch is faster. As the name suggests.
3. Fastfetch is more feature-rich. By default fastfetch only has a few modules enabled. Use `fastfetch -c all` to find what you want.
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module (notibily the difference of `MiB` and `G`), while fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
6. Fastfetch is more accurate. For example, [neofetch never actually supports Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
3. Fastfetch has a greater number of features, though by default fastfetch only has a few modules enabled; use `fastfetch -c all` to find what you want.
4. Fastfetch is more configurable. You can find more information in the Wiki: <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration>.
5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively.
6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395).
### Q: Fastfetch shows my local IP address. It leaks my privacy!
@@ -118,7 +118,7 @@ If you really don't like it, you can disable the `Local IP` module in `config.js
### Q: Where is the config file? I can't find it.
`Fastfetch` don't generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
`Fastfetch` does not generate config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See [Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration).
### Q: The configuration is so complex. Where is the documentation?
@@ -126,13 +126,17 @@ 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:
[![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.
### Q: How can I customize the module output?
Fastfetch uses `format` to generate output. For example to make `GPU` module show GPU name only and ignore other information, you can use
Fastfetch uses `format` to generate output. For example, to make the `GPU` module show only the GPU name (leaving other information undisplayed), you can use
```jsonc
{
@@ -145,15 +149,15 @@ Fastfetch uses `format` to generate output. For example to make `GPU` module sho
}
```
which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
. . which is equivalent to `fastfetch -s gpu --gpu-format '{2}'`
See `fastfetch -h format` for basic usage. For module specific formattion, see `fastfetch -h <module>-format`
See `fastfetch -h format` for information on basic usage. For module specific formattion, see `fastfetch -h <module>-format`
### Q: I have my own ascii-art / image file. How can I show it with fastfetch?
Try `fastfetch -l /path/to/logo`. See [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for detail.
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet)
If you just want to display distro name in [FIGlet text](https://github.com/pwaller/pyfiglet):
```bash
# install pyfiglet and jq first
@@ -169,6 +173,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.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
-- Carter Li <zhangsongcui@live.cn> Mon, 01 Jul 2024 08:56:29 +0800
fastfetch (2.17.0) jammy; urgency=medium
* Update to 2.17.0
-- Carter Li <zhangsongcui@live.cn> Fri, 28 Jun 2024 13:43:18 +0800
fastfetch (2.16.0) jammy; urgency=medium
* Update to 2.16.0
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.16.0_source.buildinfo universe/utils optional
fastfetch_2.18.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
+90 -53
View File
@@ -339,6 +339,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
}
}
},
@@ -419,29 +424,29 @@
"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)"
},
{
"const": "si",
"description": "1000 Bytes = 1 KB, 1000 KB = 1 MB, ..."
},
{
"const": "jedec",
"description": "1024 Bytes = 1 kB, 1024 K = 1 MB, ..."
}
]
},
"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 +574,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 and shell. 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 +607,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 +621,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 +665,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": {
@@ -1100,13 +1117,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",
@@ -1145,6 +1155,21 @@
"type": "boolean",
"description": "Display CPU usage per CPU logical core, instead of an average result",
"default": false
},
"key": {
"$ref": "#/$defs/key"
},
"keyColor": {
"$ref": "#/$defs/keyColor"
},
"outputColor": {
"$ref": "#/$defs/outputColor"
},
"keyWidth": {
"$ref": "#/$defs/keyWidth"
},
"format": {
"$ref": "#/$defs/format"
}
}
},
@@ -1162,13 +1187,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",
@@ -1756,7 +1782,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",
@@ -1805,6 +1831,9 @@
"emerge",
"eopkg",
"flatpak",
"guix",
"lpkg",
"lpkgbuild",
"macports",
"nix",
"opkg",
@@ -1815,6 +1844,7 @@
"rpm",
"scoop",
"snap",
"sorcery",
"winget",
"xbps"
],
@@ -1925,12 +1955,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
}
}
},
+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",
+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",
+8 -5
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,7 +35,7 @@
},
{
"type": "custom",
"format": "┌────────────────────────────────────────────────────────────┐",
"format": "┌{$1}{$1}┐",
"outputColor": "90"
},
{
@@ -142,7 +145,7 @@
},
{
"type": "custom",
"format": "└────────────────────────────────────────────────────────────┘",
"format": "└{$1}{$1}┘",
"outputColor": "90"
},
"break",
+6 -3
View File
@@ -7,7 +7,10 @@
"separator": "-> ",
"color": {
"separator": "1"
}
},
"constants": [
"─────────────────────────────"
]
},
"modules": [
{
@@ -17,7 +20,7 @@
"break",
{
"type": "custom",
"format": "┌───────────────────────────── {#1}System Information{#} ─────────────────────────────┐"
"format": "┌{$1} {#1}System Information{#} {$1}┐"
},
"break",
{
@@ -95,7 +98,7 @@
"break",
{
"type": "custom",
"format": "└──────────────────────────────────────────────────────────────────────────────┘"
"format": "└{$1}────────────────────{$1}┘"
},
"break",
{
+13 -14
View File
@@ -17,56 +17,55 @@
"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}"
},
{
"key": "│ │\u001b[11D{#32}󰇅 hname",
"key": "│ {#32}󰇅 hname {#keys}│",
"type": "title",
"format": "{2}"
},
{
"key": "│ │\u001b[11D{#33}󰅐 uptime",
"key": "│ {#33}󰅐 uptime {#keys}│",
"type": "uptime"
},
{
"key": "│ │\u001b[11D{#34}󰟾 distro",
"key": "│ {#34}󰟾 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})"
},
@@ -75,7 +74,7 @@
"type": "custom"
},
{
"key": "│ │\u001b[11D{#39} colors",
"key": "│ {#39} colors {#keys}│",
"type": "colors",
"symbol": "circle"
},
+13 -14
View File
@@ -17,56 +17,55 @@
"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}"
},
{
"key": "• •\u001b[11D{#32}󰇅 hname",
"key": "• {#32}󰇅 hname {#keys}•",
"type": "title",
"format": "{2}"
},
{
"key": "• •\u001b[11D{#33}󰅐 uptime",
"key": "• {#33}󰅐 uptime {#keys}•",
"type": "uptime"
},
{
"key": "• •\u001b[11D{#34}󰟾 distro",
"key": "• {#34}󰟾 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})"
},
@@ -75,7 +74,7 @@
"type": "custom"
},
{
"key": "• •\u001b[11D{#39} colors",
"key": "• {#39} colors {#keys}•",
"type": "colors",
"symbol": "circle"
},
+20 -16
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 {6}{7}{8} 🖥 ",
"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}󰟾 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": "{#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"
}
]
+20 -16
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 {6}{7}{8} 💻 ",
"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}󰟾 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": "{#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"
}
]
+2 -2
View File
@@ -12,7 +12,7 @@
"logo": {
"source": " _____ _____ _____ _____ _____ _____ _____ _____ _____\n| __| _ | __|_ _| __| __|_ _| | | |\n| __| |__ | | | | __| __| | | | --| |\n|__| |__|__|_____| |_| |__| |_____| |_| |_____|__|__|",
"type": "data",
"separate": true,
"position": "top",
"padding": {
"right": 2
}
@@ -147,7 +147,7 @@
{
"type": "font",
"key": "FONT",
"format": "{?1}{1} [QT]{?}{/1}Unknown", // Remove "[QT]" if not using Qt
"format": "{?1}{1} [Qt]{?}{/1}Unknown", // Remove "[Qt]" if not using Qt
"keyColor": "yellow"
},
{
+8 -5
View File
@@ -10,13 +10,16 @@
// "height": 12
// },
"display": {
"separator": "  "
"separator": "  ",
"constants": [
"───────────────"
]
},
"modules": [
{
"type": "custom", // HardwareStart
// {#1} is equivalent to `\u001b[1m`. {#} is equivalent to `\u001b[m`
"format": "┌─────────── {#1}Hardware Information{#} ───────────┐"
"format": "┌{$1} {#1}Hardware Information{#} {$1}┐"
},
{
"type": "host",
@@ -72,12 +75,12 @@
},
{
"type": "custom", // SoftwareStart
"format": "├─────────── {#1}Software Information{#} ───────────┤"
"format": "├{$1} {#1}Software Information{#} {$1}┤"
},
{
"type": "title",
"key": " ",
"format": "{1}@{2}"
"format": "{1}${2}"
},
{
"type": "os",
@@ -156,7 +159,7 @@
},
{
"type": "custom", // InformationEnd
"format": "└────────────────────────────────────────────┘"
"format": "└{$1}──────────────────────{$1}┘"
},
{
"type": "colors",
+22 -19
View File
@@ -15,7 +15,10 @@
"charElapsed": "█",
"charTotal": "░",
"width": 40
}
},
"constants": [
"\u001b[42C"
]
},
"modules": [
{
@@ -41,11 +44,11 @@
},
{
"type": "os",
"key": "│ OS │\u001b[42C"
"key": "│ OS │{$1}"
},
{
"type": "kernel",
"key": "│ KERNEL │\u001b[42C"
"key": "│ KERNEL │{$1}"
},
{
"type": "custom",
@@ -53,34 +56,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 +92,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 +118,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 +132,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 +147,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"
}
+7 -4
View File
@@ -12,7 +12,10 @@
"color": {
"separator": "blue"
},
"separator": " | "
"separator": " | ",
"constants": [
">-----------<+>---------------------------------------------<"
]
},
"modules": [
{
@@ -22,7 +25,7 @@
},
{
"type": "custom",
"format": ">-----------<+>------------------------------------------<",
"format": "{$1}",
"outputColor": "separator"
},
{
@@ -57,7 +60,7 @@
},
{
"type": "custom",
"format": ">-----------<+>------------------------------------------<",
"format": "{$1}",
"outputColor": "separator"
},
{
@@ -97,7 +100,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": [
{
+1 -7
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,8 +119,8 @@
"key": "╰─󰸉",
"keyColor": "yellow"
},
"break",
{
"type": "title",
"key": "╭─",
+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,
+18 -8
View File
@@ -8,11 +8,13 @@
#include <handleapi.h>
#include <io.h>
typedef HANDLE FFNativeFD;
#define FF_INVALID_FD INVALID_HANDLE_VALUE
#else
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
typedef int FFNativeFD;
#define FF_INVALID_FD (-1)
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
// one safe way to read correct data is reading the whole file in a single read syscall
// 8192 comes from procps-ng: https://gitlab.com/procps-ng/procps/-/blob/master/library/meminfo.c?ref_type=heads#L39
@@ -99,17 +101,25 @@ static inline bool ffPathExists(const char* path, FFPathType pathType)
#else
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
if (pathType == FF_PATHTYPE_ANY)
{
// Zero overhead
return access(path, F_OK) == 0;
}
else
{
struct stat fileStat;
if(stat(path, &fileStat) != 0)
return false;
unsigned int mode = fileStat.st_mode & S_IFMT;
unsigned int mode = fileStat.st_mode & S_IFMT;
if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
return true;
if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR)
return true;
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
return true;
}
#endif
-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);
}
+1 -4
View File
@@ -213,10 +213,7 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc)
{
char str[32];
int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms);
if(instance.config.display.pipe)
puts(str);
else
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left <len>; Print <str>; Load
}
}
+8
View File
@@ -148,6 +148,14 @@ bool ffOptionParseBoolean(const char* str)
void ffOptionParseColorNoClear(const char* value, FFstrbuf* buffer)
{
// If value is already an ANSI escape code, use it
if (value[0] == '\e' && value[1] == '[')
{
ffStrbufAppendS(buffer, value + 2);
ffStrbufTrimRight(buffer, 'm');
return;
}
ffStrbufEnsureFree(buffer, 63);
while(*value != '\0')
+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);
+1 -1
View File
@@ -64,7 +64,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
if(!instance.config.display.pipe)
{
fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
if (moduleArgs->outputColor.length)
if (moduleArgs && moduleArgs->outputColor.length)
ffPrintColor(&moduleArgs->outputColor);
else if (instance.config.display.colorOutput.length)
ffPrintColor(&instance.config.display.colorOutput);
+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
}
+46 -43
View File
@@ -148,13 +148,23 @@
"false": "Try `wayland`, then `x11`, then `drm`"
}
}
},
{
"long": "detect-version",
"desc": "Whether to detect and display the version of terminal, shell and editor",
"remark": "Mainly for benchmarking",
"arg": {
"type": "bool",
"optional": true,
"default": true
}
}
],
"Logo": [
{
"short": "l",
"long": "logo",
"desc": "Set the logo source",
"desc": "Set the logo source. Use \"none\" to disable the logo",
"remark": "Should be the name of a builtin logo, or a path to an image file. See also https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options",
"arg": {
"type": "logo"
@@ -441,7 +451,7 @@
},
{
"long": "pipe",
"desc": "Disable logo and all escape sequences",
"desc": "Disable colors",
"remark": "Auto detection based on isatty(1)",
"arg": {
"type": "bool",
@@ -539,19 +549,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 +656,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 +688,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 +743,9 @@
"type": "color",
"default": "light_red"
}
},
{
"long": "ts-version",
"desc": "Whether to detect and display the version of terminal and shell",
"remark": "Mainly for benchmarking",
"arg": {
"type": "bool",
"optional": true,
"default": true
}
}
],
"Library path": [
{
"long": "lib-pci",
"desc": "Pciutils. Used for GPU output",
"arg": {
"type": "path"
}
},
{
"long": "lib-vulkan",
"desc": "Vulkan module & fallback for GPU output",
@@ -954,7 +955,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 +963,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 +1185,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 +1547,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"
}
},
{
+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 (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)
+9 -34
View File
@@ -94,7 +94,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 +102,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 +143,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 +166,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 +247,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)
+16 -1
View File
@@ -74,7 +74,20 @@ static void getGnome(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
static void getCinnamon(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
ffStrbufSetS(result, getenv("CINNAMON_VERSION"));
if (result->length == 0)
ffParsePropFileData("applications/cinnamon.desktop", "X-GNOME-Bugzilla-Version =", result);
if (result->length == 0 && options->slowVersionDetection)
{
if (ffProcessAppendStdOut(result, (char* const[]){
"cinnamon",
"--version",
NULL
}) == NULL) // Cinnamon 6.2.2
ffStrbufSubstrAfterLastC(result, ' ');
}
}
static void getMate(FFstrbuf* result, FFDEOptions* options)
@@ -167,6 +180,8 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
{
if (!instance.config.general.detectVersion) return "Disabled by config";
if (ffStrbufEqualS(deName, FF_DE_PRETTY_PLASMA))
getKDE(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_GNOME))
+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);
+11 -4
View File
@@ -9,7 +9,7 @@
#define FF_DE_PRETTY_CINNAMON "Cinnamon"
#define FF_DE_PRETTY_MATE "Mate"
#define FF_DE_PRETTY_LXDE "LXDE"
#define FF_DE_PRETTY_LXQT "LXQT"
#define FF_DE_PRETTY_LXQT "LXQt"
#define FF_DE_PRETTY_BUDGIE "Budgie"
#define FF_DE_PRETTY_CDE "CDE"
#define FF_DE_PRETTY_UNITY "Unity"
@@ -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
);
}
@@ -83,6 +86,8 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
uint32_t width = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t height = (uint32_t) ffStrbufToUInt(&buffer, 0);
ffStrbufSubstrAfterFirstC(&buffer, ',');
uint32_t ppi = (uint32_t) ffStrbufToUInt(&buffer, 0);
return ffdsAppendDisplay(ds,
width,
height,
@@ -93,7 +98,9 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
0,
FF_DISPLAY_TYPE_BUILTIN,
false,
0
0,
(uint32_t) (width / ppi * 25.4),
(uint32_t) (height / ppi * 25.4)
);
}
@@ -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
+10 -5
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);
@@ -339,12 +342,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,28 +9,34 @@
#include <sys/socket.h>
#include "common/properties.h"
#include "wayland.h"
#include "wlr-output-management-unstable-v1-client-protocol.h"
#include "kde-output-device-v2-client-protocol.h"
#include "kde-output-order-v1-client-protocol.h"
#include "xdg-output-unstable-v1-client-protocol.h"
#ifndef __FreeBSD__
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
#ifdef __linux__
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
{
struct ucred ucred;
socklen_t len = sizeof(struct ucred);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1)
return;
return false;
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate();
ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed.
ffReadFileBuffer(procPath.chars, &result->wmProcessName);
ffStrbufTrimRightSpace(&result->wmProcessName);
ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments
ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path
return true;
}
#else
static void waylandDetectWM(int fd, FFDisplayServerResult* result)
static bool waylandDetectWM(int fd, FFDisplayServerResult* result)
{
FF_UNUSED(fd, result);
return false;
}
#endif
@@ -48,6 +54,19 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_ZWLR;
ffWaylandHandleZwlrOutput(wldata, registry, name, version);
}
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_KDE) && ffStrEquals(interface, kde_output_device_v2_interface.name))
{
wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE;
ffWaylandHandleKdeOutput(wldata, registry, name, version);
}
else if(ffStrEquals(interface, kde_output_order_v1_interface.name))
{
ffWaylandHandleKdeOutputOrder(wldata, registry, name, version);
}
else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE) && ffStrEquals(interface, zxdg_output_manager_v1_interface.name))
{
ffWaylandHandleZxdgOutput(wldata, registry, name, version);
}
}
bool detectWayland(FFDisplayServerResult* result)
@@ -91,9 +110,85 @@ bool detectWayland(FFDisplayServerResult* result)
data.ffwl_proxy_add_listener(registry, (void(**)(void)) &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.
@@ -104,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);
+4 -6
View File
@@ -71,11 +71,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
return;
if(
ffStrEqualsIgnCase(name, "kwin_wayland") ||
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
ffStrEqualsIgnCase(name, "kwin_x11") ||
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
ffStrEqualsIgnCase(name, "kwin") ||
ffStrStartsWithIgnCase(name, "kwin_") ||
ffStrEndsWithIgnCase(name, "-kwin_wayland") ||
ffStrEndsWithIgnCase(name, "-kwin_x11")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
@@ -86,7 +83,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
ffStrEqualsIgnCase(name, "Mutter")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
else if(
ffStrEqualsIgnCase(name, "cinnamon-session") ||
ffStrEqualsIgnCase(name, "cinnamon") ||
ffStrStartsWithIgnCase(name, "cinnamon-") ||
ffStrEqualsIgnCase(name, "Muffin") ||
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
@@ -207,7 +205,7 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
else if(
ffStrEqualsIgnCase(name, "LXQt") ||
ffStrEqualsIgnCase(name, "X-LXQT") ||
ffStrEqualsIgnCase(name, "X-LXQt") ||
ffStrEqualsIgnCase(name, "lxqt-session")
) {
ffStrbufSetS(&result->deProcessName, "lxqt-session");
+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,);
+2
View File
@@ -26,6 +26,8 @@ const char* ffDetectEditor(FFEditorResult* result)
return "$VISUAL or $EDITOR not set";
}
if (!instance.config.general.detectVersion) return NULL;
#ifndef _WIN32
if (result->name.chars[0] != '/')
{
+1 -1
View File
@@ -7,7 +7,7 @@
typedef struct FFFontResult
{
/**
* Linux / BSD: QT, GTK2, GTK3, GTK4
* Linux / BSD: Qt, GTK2, GTK3, GTK4
* MacOS: System, User, System Mono, User Mono
* Windows: Caption, Menu, Message, Status
* Other: Unset, Unset, Unset, Unset
+1 -1
View File
@@ -9,7 +9,7 @@ static void generateString(FFFontResult* font)
if(font->fonts[0].length > 0)
{
ffStrbufAppend(&font->display, &font->fonts[0]);
ffStrbufAppendS(&font->display, " [QT]");
ffStrbufAppendS(&font->display, " [Qt]");
for(uint8_t i = 1; i < sizeof(font->fonts) / sizeof(font->fonts[0]); i++)
{
+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 (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);
}
}
+51 -28
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);
@@ -273,7 +296,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
}, "libnvidia-ml.so");
}
@@ -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;
+1 -1
View File
@@ -162,7 +162,7 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
},
dllName
);
+1 -1
View File
@@ -120,7 +120,7 @@ const char* ffGPUDetectByDirectX(FF_MAYBE_UNUSED const FFGPUOptions* options, FF
.memory = options->driverSpecific ? &gpu->dedicated : NULL,
.coreCount = options->driverSpecific ? (uint32_t*) &gpu->coreCount : NULL,
.type = &gpu->type,
.frequency = &gpu->frequency,
.frequency = options->driverSpecific ? &gpu->frequency : NULL,
}, "/usr/lib/wsl/lib/libnvidia-ml.so");
}
}
+8 -3
View File
@@ -144,11 +144,16 @@ static void detectQtCt(char qver, FFQtResult* result)
ffParsePropFileConfigValues(file, 3, (FFpropquery[]) {
{"style=", &result->widgetStyle},
{"icon_theme=", &result->icons},
// FIXME: on older versions this was hex-encoded binary format
// (See QVariant notes on https://doc.qt.io/qt-5/qsettings.html)
// Thankfully, newer versions use the more common font encoding.
{"general=", &result->font}
});
if (ffStrbufStartsWithC(&result->font, '@'))
{
// See QVariant notes on https://doc.qt.io/qt-5/qsettings.html and
// https://github.com/fastfetch-cli/fastfetch/issues/1053#issuecomment-2197254769
// Thankfully, newer versions use the more common font encoding.
ffStrbufSetNS(&result->font, 5, file);
}
}
static void detectKvantum(FFQtResult* result)
+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
}
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ const char* ffDetectIcons(FFIconsResult* result)
if(plasma->length > 0)
{
ffStrbufAppend(&result->icons1, plasma);
ffStrbufAppendS(&result->icons1, " [QT]");
ffStrbufAppendS(&result->icons1, " [Qt]");
}
return NULL;
+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);
}
}
}
}
+13 -10
View File
@@ -163,16 +163,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))
+4 -4
View File
@@ -95,7 +95,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
continue;
struct sockaddr_in* ipv4 = (struct sockaddr_in*) ifa->ifa_addr;
char addressBuffer[INET_ADDRSTRLEN + 4];
char addressBuffer[INET_ADDRSTRLEN + 16];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
@@ -105,7 +105,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (cidr != 0)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%d", cidr);
snprintf(addressBuffer + len, 16, "/%d", cidr);
}
}
@@ -117,7 +117,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
continue;
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
char addressBuffer[INET6_ADDRSTRLEN + 4];
char addressBuffer[INET6_ADDRSTRLEN + 16];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
@@ -130,7 +130,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
if (cidr != 0)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%d", cidr);
snprintf(addressBuffer + len, 16, "/%d", cidr);
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
+ vmstat.compressor_page_count
- vmstat.purgeable_count
- vmstat.external_page_count
) * instance.state.platform.pageSize;
) * instance.state.platform.sysinfo.pageSize;
return NULL;
}
+1 -1
View File
@@ -12,7 +12,7 @@ const char* ffDetectMemory(FFMemoryResult* ram)
+ ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0)
+ ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize;
return NULL;
}

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