mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:32:10 +02:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de18a07938 | |||
| 88147f80ac | |||
| 505ff6ff65 | |||
| 390549394d | |||
| f7e7d54c16 | |||
| 5e068d22c8 | |||
| b77646f23e | |||
| aa40366a49 | |||
| a64a82f215 | |||
| 0a4d6220e9 | |||
| 6b037c595f | |||
| f628f5c382 | |||
| cf713e32e1 | |||
| 7d08f81075 | |||
| 8822653335 | |||
| 75ff054255 | |||
| c51cc8ce6b | |||
| 44e23412b5 | |||
| 59742bca00 | |||
| 303edb97ce | |||
| 37ab380a6f | |||
| a06e245c34 | |||
| 5de432b083 | |||
| 817285ac01 | |||
| 8687505505 | |||
| 34c34d25c4 | |||
| 21b15ee944 | |||
| 8e0a65126e | |||
| 54d8b0a95d | |||
| 48fc72e95c | |||
| e3d6a85888 | |||
| 7d92da8829 | |||
| 2f3a361b1f | |||
| ac71f21e6c | |||
| 8d5316f6aa | |||
| 1242fda66f | |||
| 5a2b618d27 | |||
| d836d7569f | |||
| 8a412e6823 |
+13
-13
@@ -38,7 +38,7 @@ jobs:
|
||||
run: uname -a
|
||||
|
||||
- name: configure project
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_XFCONF=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
|
||||
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_DIRECTX_HEADERS=OFF -DENABLE_THREADS=OFF
|
||||
|
||||
- name: build project
|
||||
run: cmake --build . --target package --verbose -j4
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
run: cat /proc/cpuinfo
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev
|
||||
|
||||
- name: install linuxbrew packages
|
||||
run: |
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
run: cat /proc/cpuinfo
|
||||
|
||||
- name: install required packages
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm
|
||||
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm
|
||||
|
||||
- name: install linuxbrew packages
|
||||
run: |
|
||||
@@ -216,7 +216,7 @@ jobs:
|
||||
# CMake installed by apt has bug `list sub-command REMOVE_ITEM requires two or more arguments`
|
||||
wget --no-check-certificate https://apt.kitware.com/ubuntu/pool/main/c/cmake/{cmake_3.29.2-0kitware1ubuntu20.04.1_armhf.deb,cmake-data_3.29.2-0kitware1ubuntu20.04.1_all.deb}
|
||||
dpkg -i *.deb
|
||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
apt-get install -y make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y wget
|
||||
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -287,7 +287,7 @@ jobs:
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libddcutil-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -322,7 +322,7 @@ jobs:
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -357,7 +357,7 @@ jobs:
|
||||
githubToken: ${{ github.token }}
|
||||
run: |
|
||||
uname -a
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
apt-get update && apt-get install -y cmake make g++ libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libchafa-dev libelf-dev directx-headers-dev rpm
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -386,7 +386,7 @@ jobs:
|
||||
run: |
|
||||
cat /etc/alpine-release
|
||||
uname -a
|
||||
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
|
||||
apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++
|
||||
shell: alpine.sh --root {0}
|
||||
|
||||
- name: build
|
||||
@@ -560,7 +560,7 @@ jobs:
|
||||
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 egl opencl ocl-icd v4l_compat chafa
|
||||
sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -596,7 +596,7 @@ jobs:
|
||||
version: '7.7'
|
||||
run: |
|
||||
uname -a
|
||||
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 xfconf imagemagick chafa
|
||||
sudo pkg_add -r cmake git pkgconf wayland vulkan-headers vulkan-loader glib2 dconf dbus sqlite3 imagemagick chafa
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||
cmake --build . --target package --verbose -j4
|
||||
./fastfetch --list-features
|
||||
@@ -665,7 +665,7 @@ jobs:
|
||||
prepare: |
|
||||
uname -a
|
||||
pkg update
|
||||
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa libelf
|
||||
pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl egl opencl ocl-icd v4l_compat chafa libelf
|
||||
|
||||
run: |
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On .
|
||||
@@ -875,7 +875,7 @@ jobs:
|
||||
|
||||
- name: download artifacts
|
||||
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
|
||||
- name: create release
|
||||
if: needs.linux-amd64.outputs.ffversion != steps.get_version_release.outputs.release
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
# 2.52.0
|
||||
|
||||
Changes:
|
||||
* New optional build dependencies on Android
|
||||
* main: chafa dbus glib imagemagick libelf libxcb libxrandr pulseaudio zlib
|
||||
* x11: dconf (Optional)
|
||||
* Dependency on `libxfconf` is removed. XFCE related detection now uses `libdbus` instead (Linux)
|
||||
* The default format of `Display` module is updated to `{width}x{height} @ {scale-factor}x in {inch}", {refresh-rate} Hz`
|
||||
* Replaced scaled resolution with scale factor for shorter texts and avoiding potential confusion.
|
||||
|
||||
Bugfixes:
|
||||
* Fixes linking on 32-bit Android (#1939)
|
||||
* Skips network interfaces without IPs unless MAC address is requested (#1949, LocalIP)
|
||||
* Fixes unexpected padding when setting `logo.width` with chafa logos (#1947, Logo)
|
||||
* Regression from v2.51.0
|
||||
* Improves Wallpaper detection on XFCE4 (Wallpaper, Linux)
|
||||
* Ignores process `Relay(xxx)` when detecting terminal on WSL2 (Terminal, Linux)
|
||||
|
||||
Features:
|
||||
* Enables X11-related info (i.e., WM/DE) detection on Android (Global, Android)
|
||||
* This requires many dependencies. See above.
|
||||
* Adds scale factors detection for X11 (Display, Linux)
|
||||
* X11 doesn't natively report scale factor as Wayland does. Instead, Fastfetch tries to detect `Xft.dpi` (DPI used by X FreeType for scaling fonts), which is usually set by the WM when DPI scaling is enabled.
|
||||
* It's not always accurate. For example, XFCE4 has a separate config for text scaling, which is unaffected by the global DPI scaling setting.
|
||||
* Adds `display.fraction.trailingZeros: [always|never]` option for fraction formatting
|
||||
* The default value of `display.fraction.ndigits` is changed from `-1` (unlimited) to `2` for usability.
|
||||
* Used for displaying scale factor in Display module mentioned above, alongside other places for printing raw fraction numbers.
|
||||
* Informs users that module-specific CLI options are no longer supported and provide guidance for transitioning to JSON config
|
||||
* Adds CPU name detection support for IA64 (CPU, Linux)
|
||||
* Support Btrfs allocation profile detection (#1941, Btrfs, Linux)
|
||||
|
||||
# 2.51.1
|
||||
|
||||
Bugfixes:
|
||||
* Fix building on macOS 14 or older; no functional changes (CPU, macOS)
|
||||
|
||||
# 2.51.0
|
||||
|
||||
Changes:
|
||||
|
||||
+36
-24
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.51.0
|
||||
VERSION 2.52.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -60,25 +60,23 @@ include(CMakeDependentOption)
|
||||
|
||||
cmake_dependent_option(ENABLE_VULKAN "Enable vulkan" ON "LINUX OR APPLE OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_WAYLAND "Enable wayland-client" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_XCB_RANDR "Enable xcb-randr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_XRANDR "Enable xrandr" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DRM "Enable libdrm" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DRM_AMDGPU "Enable libdrm_amdgpu" ON "LINUX OR FreeBSD OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_XFCONF "Enable libxfconf-0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_GIO "Enable gio-2.0" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DCONF "Enable dconf" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR ANDROID OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR APPLE OR SunOS OR GNU" 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 FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR ANDROID OR GNU" OFF)
|
||||
cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF)
|
||||
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku OR GNU" OFF)
|
||||
@@ -86,6 +84,7 @@ cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND"
|
||||
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
|
||||
cmake_dependent_option(ENABLE_PCIACCESS "Enable libpciaccess" ON "NetBSD OR OpenBSD" OFF)
|
||||
|
||||
option(ENABLE_ZLIB "Enable zlib" ON)
|
||||
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)
|
||||
@@ -515,6 +514,7 @@ if(LINUX)
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -575,6 +575,7 @@ if(LINUX)
|
||||
)
|
||||
elseif(ANDROID)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/dbus.c
|
||||
src/common/io/io_unix.c
|
||||
src/common/netif/netif_linux.c
|
||||
src/common/networking/networking_linux.c
|
||||
@@ -590,7 +591,7 @@ elseif(ANDROID)
|
||||
src/detection/chassis/chassis_nosupport.c
|
||||
src/detection/cpu/cpu_linux.c
|
||||
src/detection/cpucache/cpucache_linux.c
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/cpuusage/cpuusage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/dns/dns_linux.c
|
||||
@@ -598,10 +599,16 @@ elseif(ANDROID)
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
src/detection/font/font_nosupport.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/wmde.c
|
||||
src/detection/displayserver/linux/xcb.c
|
||||
src/detection/displayserver/linux/xlib.c
|
||||
src/detection/gtk_qt/gtk.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
src/detection/font/font_linux.c
|
||||
src/detection/gpu/gpu_android.c
|
||||
src/detection/host/host_android.c
|
||||
src/detection/icons/icons_nosupport.c
|
||||
src/detection/icons/icons_linux.c
|
||||
src/detection/initsystem/initsystem_linux.c
|
||||
src/detection/keyboard/keyboard_nosupport.c
|
||||
src/detection/libc/libc_android.c
|
||||
@@ -610,7 +617,7 @@ elseif(ANDROID)
|
||||
src/detection/locale/locale_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
src/detection/gamepad/gamepad_nosupport.c
|
||||
src/detection/media/media_nosupport.c
|
||||
src/detection/media/media_linux.c
|
||||
src/detection/memory/memory_linux.c
|
||||
src/detection/mouse/mouse_nosupport.c
|
||||
src/detection/netio/netio_linux.c
|
||||
@@ -620,20 +627,21 @@ elseif(ANDROID)
|
||||
src/detection/packages/packages_nix.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_linux.c
|
||||
src/detection/sound/sound_nosupport.c
|
||||
src/detection/sound/sound_linux.c
|
||||
src/detection/swap/swap_linux.c
|
||||
src/detection/terminalfont/terminalfont_android.c
|
||||
src/detection/terminalfont/terminalfont_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/terminalsize/terminalsize_linux.c
|
||||
src/detection/theme/theme_nosupport.c
|
||||
src/detection/theme/theme_linux.c
|
||||
src/detection/tpm/tpm_nosupport.c
|
||||
src/detection/uptime/uptime_linux.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/wallpaper/wallpaper_nosupport.c
|
||||
src/detection/wallpaper/wallpaper_linux.c
|
||||
src/detection/wifi/wifi_android.c
|
||||
src/detection/wm/wm_nosupport.c
|
||||
src/detection/de/de_nosupport.c
|
||||
src/detection/wmtheme/wmtheme_nosupport.c
|
||||
src/detection/wm/wm_linux.c
|
||||
src/detection/de/de_linux.c
|
||||
src/detection/wmtheme/wmtheme_linux.c
|
||||
src/detection/camera/camera_android.c
|
||||
src/detection/zpool/zpool_nosupport.c
|
||||
src/util/platform/FFPlatform_unix.c
|
||||
@@ -665,6 +673,7 @@ elseif(FreeBSD)
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -759,6 +768,7 @@ elseif(NetBSD)
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_nbsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -841,6 +851,7 @@ elseif(OpenBSD)
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_obsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -1069,6 +1080,7 @@ elseif(SunOS)
|
||||
src/detection/physicalmemory/physicalmemory_linux.c
|
||||
src/detection/diskio/diskio_sunos.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -1220,6 +1232,7 @@ elseif(GNU)
|
||||
src/detection/physicalmemory/physicalmemory_nosupport.c
|
||||
src/detection/diskio/diskio_nosupport.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/common.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
src/detection/displayserver/linux/wayland/wayland.c
|
||||
src/detection/displayserver/linux/wayland/global-output.c
|
||||
@@ -1525,10 +1538,6 @@ ff_lib_enable(DBUS
|
||||
"dbus-1"
|
||||
"DBus"
|
||||
)
|
||||
ff_lib_enable(XFCONF
|
||||
"libxfconf-0"
|
||||
"XFConf"
|
||||
)
|
||||
ff_lib_enable(SQLITE3
|
||||
"sqlite3"
|
||||
"SQLite3"
|
||||
@@ -1728,6 +1737,9 @@ elseif(GNU)
|
||||
PRIVATE "m"
|
||||
)
|
||||
elseif(ANDROID)
|
||||
target_link_libraries(libfastfetch
|
||||
PRIVATE "m"
|
||||
)
|
||||
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
if(HAVE_LIBANDROID_WORDEXP_STATIC)
|
||||
target_link_libraries(libfastfetch
|
||||
|
||||
Vendored
+6
@@ -1,3 +1,9 @@
|
||||
fastfetch (2.51.0) jammy; urgency=medium
|
||||
|
||||
* Update to 2.51.0
|
||||
|
||||
-- Carter Li <zhangsongcui@live.cn> Fri, 29 Aug 2025 08:55:03 +0800
|
||||
|
||||
fastfetch (2.50.2) jammy; urgency=medium
|
||||
|
||||
* Update to 2.50.2
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
fastfetch_2.50.2_source.buildinfo universe/utils optional
|
||||
fastfetch_2.51.0_source.buildinfo universe/utils optional
|
||||
|
||||
+35
-4
@@ -1290,10 +1290,19 @@
|
||||
"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 with decimal\n-1 will show the frequency in MHz",
|
||||
"minimum": -1,
|
||||
"maximum": 9,
|
||||
"description": "Set the number of decimal places to display when formatting frequency values",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 9,
|
||||
"description": "Integer value displays the frequency in GHz with specified decimal places"
|
||||
},
|
||||
{
|
||||
"type": "null",
|
||||
"description": "Null value display the frequency as integer MHz"
|
||||
}
|
||||
],
|
||||
"default": 2
|
||||
},
|
||||
"spaceBeforeUnit": {
|
||||
@@ -1333,6 +1342,28 @@
|
||||
"description": "The number of digits will be automatically determined based on the value"
|
||||
}
|
||||
],
|
||||
"default": 2
|
||||
},
|
||||
"trailingZeros": {
|
||||
"description": "Set when to keep trailing zeros",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "null",
|
||||
"description": "Same as `default`"
|
||||
},
|
||||
{
|
||||
"const": "default",
|
||||
"description": "Use the behavior defined internally"
|
||||
},
|
||||
{
|
||||
"const": "always",
|
||||
"description": "Always keep trailing zeros"
|
||||
},
|
||||
{
|
||||
"const": "never",
|
||||
"description": "Never keep trailing zeros"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,65 @@
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
bool ffParseModuleOptions(const char* key, const char* value)
|
||||
{
|
||||
if (!ffStrStartsWith(key, "--") || !ffCharIsEnglishAlphabet(key[2])) return false;
|
||||
if (value && !*value) value = NULL;
|
||||
for (FFModuleBaseInfo** modules = ffModuleInfos[toupper(key[2]) - 'A']; *modules; ++modules)
|
||||
{
|
||||
FFModuleBaseInfo* baseInfo = *modules;
|
||||
const char* subKey = ffOptionTestPrefix(key, baseInfo->name);
|
||||
if (subKey != NULL)
|
||||
{
|
||||
if (subKey[0] == '\0' || subKey[0] == '-') // Key is exactly the module name or has a leading '-'
|
||||
{
|
||||
fprintf(stderr, "Error: unknown module key %s\n", key);
|
||||
exit(477);
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY moduleName = ffStrbufCreateS(baseInfo->name);
|
||||
ffStrbufLowerCase(&moduleName);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY jsonKey = ffStrbufCreate();
|
||||
bool flag = false;
|
||||
for (const char* p = subKey; *p; ++p)
|
||||
{
|
||||
if (*p == '-')
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
fprintf(stderr, "Error: invalid double `-` in module key %s\n", key);
|
||||
exit(477);
|
||||
}
|
||||
flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p))
|
||||
{
|
||||
fprintf(stderr, "Error: invalid character `%c` in module key %s\n", *p, key);
|
||||
exit(477);
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
flag = false;
|
||||
ffStrbufAppendC(&jsonKey, (char) toupper((unsigned char) *p));
|
||||
}
|
||||
else
|
||||
ffStrbufAppendC(&jsonKey, *p);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Error: Unsupported module option: %s\n", key);
|
||||
fputs(" Support of module options has been removed. Please add the flag to the JSON config instead.\n", stderr);
|
||||
fprintf(stderr, " Example (demonstration only): `{ \"modules\": [ { \"type\": \"%s\", \"%s\": %s%s%s } ] }`\n", moduleName.chars, jsonKey.chars, value ? "\"" : "", value ? value : "true", value ? "\"" : "");
|
||||
fputs(" See <https://github.com/fastfetch-cli/fastfetch/wiki/Configuration> for more information.\n", stderr);
|
||||
exit(477);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffPrepareCommandOption(FFdata* data)
|
||||
{
|
||||
//If we don't have a custom structure, use the default one
|
||||
|
||||
@@ -12,3 +12,4 @@ typedef struct FFdata
|
||||
void ffPrepareCommandOption(FFdata* data);
|
||||
void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
void ffMigrateCommandOptionToJsonc(FFdata* data, yyjson_mut_doc* jsonDoc);
|
||||
bool ffParseModuleOptions(const char* key, const char* value);
|
||||
|
||||
+56
-3
@@ -162,14 +162,67 @@ bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result)
|
||||
return ffDBusGetUint(dbus, &subIter, result);
|
||||
}
|
||||
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg)
|
||||
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result)
|
||||
{
|
||||
int argType = dbus->lib->ffdbus_message_iter_get_arg_type(iter);
|
||||
|
||||
if(argType == DBUS_TYPE_INT16)
|
||||
{
|
||||
int16_t value = 0;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||
*result = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType == DBUS_TYPE_INT32)
|
||||
{
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType == DBUS_TYPE_BYTE)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||
*result = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType == DBUS_TYPE_UINT16)
|
||||
{
|
||||
uint16_t value = 0;
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, &value);
|
||||
*result = (int16_t) value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType == DBUS_TYPE_UINT32)
|
||||
{
|
||||
dbus->lib->ffdbus_message_iter_get_basic(iter, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType != DBUS_TYPE_VARIANT)
|
||||
return false;
|
||||
|
||||
DBusMessageIter subIter;
|
||||
dbus->lib->ffdbus_message_iter_recurse(iter, &subIter);
|
||||
return ffDBusGetInt(dbus, &subIter, result);
|
||||
}
|
||||
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2)
|
||||
{
|
||||
DBusMessage* message = dbus->lib->ffdbus_message_new_method_call(busName, objectPath, interface, method);
|
||||
if(message == NULL)
|
||||
return NULL;
|
||||
|
||||
if (arg)
|
||||
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID);
|
||||
if (arg1)
|
||||
{
|
||||
if (arg2)
|
||||
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_STRING, &arg2, DBUS_TYPE_INVALID);
|
||||
else
|
||||
dbus->lib->ffdbus_message_append_args(message, DBUS_TYPE_STRING, &arg1, DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
DBusMessage* reply = dbus->lib->ffdbus_connection_send_with_reply_and_block(dbus->connection, message, instance.config.general.processingTimeout, NULL);
|
||||
|
||||
|
||||
+3
-2
@@ -31,14 +31,15 @@ const char* ffDBusLoadData(DBusBusType busType, FFDBusData* data); //Returns an
|
||||
bool ffDBusGetString(FFDBusData* dbus, DBusMessageIter* iter, FFstrbuf* result);
|
||||
bool ffDBusGetBool(FFDBusData* dbus, DBusMessageIter* iter, bool* result);
|
||||
bool ffDBusGetUint(FFDBusData* dbus, DBusMessageIter* iter, uint32_t* result);
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg);
|
||||
DBusMessage* ffDBusGetMethodReply(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* method, const char* arg1, const char* arg2);
|
||||
DBusMessage* ffDBusGetProperty(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property);
|
||||
bool ffDBusGetPropertyString(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result);
|
||||
bool ffDBusGetInt(FFDBusData* dbus, DBusMessageIter* iter, int32_t* result);
|
||||
bool ffDBusGetPropertyUint(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface, const char* property, uint32_t* result);
|
||||
|
||||
static inline DBusMessage* ffDBusGetAllProperties(FFDBusData* dbus, const char* busName, const char* objectPath, const char* interface)
|
||||
{
|
||||
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface);
|
||||
return ffDBusGetMethodReply(dbus, busName, objectPath, "org.freedesktop.DBus.Properties", "GetAll", interface, NULL);
|
||||
}
|
||||
|
||||
#endif // FF_HAVE_DBUS
|
||||
|
||||
+2
-2
@@ -32,10 +32,10 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg)
|
||||
ffStrbufAppend(buffer, (const FFstrbuf*)formatarg->value);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_FLOAT:
|
||||
ffStrbufAppendDouble(buffer, *(float*)formatarg->value, instance.config.display.fractionNdigits);
|
||||
ffStrbufAppendDouble(buffer, *(float*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_DOUBLE:
|
||||
ffStrbufAppendDouble(buffer, *(double*)formatarg->value, instance.config.display.fractionNdigits);
|
||||
ffStrbufAppendDouble(buffer, *(double*)formatarg->value, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros != FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER);
|
||||
break;
|
||||
case FF_FORMAT_ARG_TYPE_BOOL:
|
||||
ffStrbufAppendS(buffer, *(bool*)formatarg->value ? "true" : "false");
|
||||
|
||||
@@ -11,7 +11,7 @@ bool ffFreqAppendNum(uint32_t mhz, FFstrbuf* result)
|
||||
|
||||
if (ndigits >= 0)
|
||||
{
|
||||
ffStrbufAppendDouble(result, mhz / 1000., ndigits);
|
||||
ffStrbufAppendDouble(result, mhz / 1000., ndigits, true);
|
||||
if (spaceBeforeUnit) ffStrbufAppendC(result, ' ');
|
||||
ffStrbufAppendS(result, "GHz");
|
||||
}
|
||||
|
||||
@@ -208,9 +208,6 @@ void ffListFeatures(void)
|
||||
#if FF_HAVE_ZLIB
|
||||
"zlib\n"
|
||||
#endif
|
||||
#if FF_HAVE_XFCONF
|
||||
"xfconf\n"
|
||||
#endif
|
||||
#if FF_HAVE_SQLITE3
|
||||
"sqlite3\n"
|
||||
#endif
|
||||
|
||||
+126
-52
@@ -184,7 +184,7 @@ FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type)
|
||||
}
|
||||
#endif //FF_HAVE_DCONF
|
||||
|
||||
FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type)
|
||||
{
|
||||
FFvariant gsettings = ffSettingsGetGSettings(gsettingsSchemaName, gsettingsPath, gsettingsKey, type);
|
||||
|
||||
@@ -196,77 +196,151 @@ FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, c
|
||||
return ffSettingsGetDConf(dconfKey, type);
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_XFCONF
|
||||
#include <xfconf/xfconf.h>
|
||||
|
||||
typedef struct XFConfData
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(xfconf_channel_get)
|
||||
FF_LIBRARY_SYMBOL(xfconf_channel_has_property)
|
||||
FF_LIBRARY_SYMBOL(xfconf_channel_get_string)
|
||||
FF_LIBRARY_SYMBOL(xfconf_channel_get_bool)
|
||||
FF_LIBRARY_SYMBOL(xfconf_channel_get_int)
|
||||
FF_LIBRARY_SYMBOL(xfconf_init)
|
||||
|
||||
bool inited;
|
||||
} XFConfData;
|
||||
|
||||
static const XFConfData* getXFConfData(void)
|
||||
{
|
||||
static XFConfData data;
|
||||
|
||||
if (!data.inited)
|
||||
{
|
||||
data.inited = true;
|
||||
FF_LIBRARY_LOAD(libxfconf, NULL, "libxfconf-0" FF_LIBRARY_EXTENSION, 4);
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_has_property, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_string, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_bool, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_channel_get_int, NULL)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR(libxfconf, data, xfconf_init, NULL)
|
||||
if(!data.ffxfconf_init(NULL))
|
||||
data.ffxfconf_init = NULL;
|
||||
else
|
||||
libxfconf = NULL;
|
||||
}
|
||||
|
||||
if(!data.ffxfconf_init)
|
||||
return NULL;
|
||||
|
||||
return &data;
|
||||
}
|
||||
#ifdef FF_HAVE_DBUS
|
||||
#include "common/dbus.h"
|
||||
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
const XFConfData* data = getXFConfData();
|
||||
if(data == NULL)
|
||||
FFDBusData dbus;
|
||||
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
XfconfChannel* channel = data->ffxfconf_channel_get(channelName); // Never fails according to documentation but rather returns an empty channel
|
||||
|
||||
if(!data->ffxfconf_channel_has_property(channel, propertyName))
|
||||
DBusMessage* reply = ffDBusGetMethodReply(&dbus, "org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "GetProperty", channelName, propertyName);
|
||||
if(!reply)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
DBusMessageIter rootIterator;
|
||||
if(!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
if(type == FF_VARIANT_TYPE_INT)
|
||||
return (FFvariant) {.intValue = data->ffxfconf_channel_get_int(channel, propertyName, 0)};
|
||||
{
|
||||
int32_t value;
|
||||
if (ffDBusGetInt(&dbus, &rootIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .intValue = value };
|
||||
}
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
if(type == FF_VARIANT_TYPE_STRING)
|
||||
return (FFvariant) {.strValue = data->ffxfconf_channel_get_string(channel, propertyName, NULL)};
|
||||
{
|
||||
FFstrbuf value = ffStrbufCreate();
|
||||
if (ffDBusGetString(&dbus, &rootIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
|
||||
}
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
if(type == FF_VARIANT_TYPE_BOOL)
|
||||
return (FFvariant) {.boolValue = data->ffxfconf_channel_get_bool(channel, propertyName, false), .boolValueSet = true};
|
||||
{
|
||||
bool value;
|
||||
if (ffDBusGetBool(&dbus, &rootIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .boolValue = value, .boolValueSet = true };
|
||||
}
|
||||
}
|
||||
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#else //FF_HAVE_XFCONF
|
||||
|
||||
#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \
|
||||
{ \
|
||||
if(!(dbus).lib->ffdbus_message_iter_next(iterator)) \
|
||||
break; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
|
||||
{
|
||||
FFDBusData dbus;
|
||||
if (ffDBusLoadData(DBUS_BUS_SESSION, &dbus) != NULL)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
DBusMessage* reply = ffDBusGetMethodReply(&dbus, "org.xfce.Xfconf", "/org/xfce/Xfconf", "org.xfce.Xfconf", "GetAllProperties", channelName, propertyPrefix);
|
||||
if(!reply)
|
||||
return FF_VARIANT_NULL;
|
||||
|
||||
DBusMessageIter rootIterator;
|
||||
if(!dbus.lib->ffdbus_message_iter_init(reply, &rootIterator))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
DBusMessageIter arrayIterator;
|
||||
dbus.lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator);
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(dbus.lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY)
|
||||
FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
|
||||
|
||||
DBusMessageIter dictIterator;
|
||||
dbus.lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator);
|
||||
|
||||
const char* key;
|
||||
dbus.lib->ffdbus_message_iter_get_basic(&dictIterator, &key);
|
||||
|
||||
if (cb(data, key)) FF_DBUS_ITER_CONTINUE(dbus, &arrayIterator)
|
||||
dbus.lib->ffdbus_message_iter_next(&dictIterator);
|
||||
|
||||
if(type == FF_VARIANT_TYPE_INT)
|
||||
{
|
||||
int32_t value;
|
||||
if (ffDBusGetInt(&dbus, &dictIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .intValue = value };
|
||||
}
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
if(type == FF_VARIANT_TYPE_STRING)
|
||||
{
|
||||
FFstrbuf value = ffStrbufCreate();
|
||||
if (ffDBusGetString(&dbus, &dictIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .strValue = value.chars }; // Leaks value.chars
|
||||
}
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
if(type == FF_VARIANT_TYPE_BOOL)
|
||||
{
|
||||
bool value;
|
||||
if (ffDBusGetBool(&dbus, &dictIterator, &value))
|
||||
{
|
||||
dbus.lib->ffdbus_message_unref(reply);
|
||||
return (FFvariant) { .boolValue = value, .boolValueSet = true };
|
||||
}
|
||||
}
|
||||
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#else //FF_HAVE_DBUS
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type)
|
||||
{
|
||||
FF_UNUSED(channelName, propertyName, type)
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_XFCONF
|
||||
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb)
|
||||
{
|
||||
FF_UNUSED(channelName, propertyPrefix, type, data, cb);
|
||||
return FF_VARIANT_NULL;
|
||||
}
|
||||
#endif //FF_HAVE_DBUS
|
||||
|
||||
#ifdef FF_HAVE_SQLITE3
|
||||
#include <sqlite3.h>
|
||||
|
||||
@@ -24,8 +24,10 @@ typedef union FFvariant
|
||||
|
||||
FFvariant ffSettingsGetDConf(const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGSettings(const char* schemaName, const char* path, const char* key, FFvarianttype type);
|
||||
FFvariant ffSettingsGet(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetGnome(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
|
||||
FFvariant ffSettingsGetXFConf(const char* channelName, const char* propertyName, FFvarianttype type);
|
||||
typedef bool FFTestXfconfPropCallback(void* data, const char* propertyName); // Return false to break loop
|
||||
FFvariant ffSettingsGetXFConfFirstMatch(const char* channelName, const char* propertyPrefix, FFvarianttype type, void* data, FFTestXfconfPropCallback* cb);
|
||||
|
||||
int ffSettingsGetSQLite3Int(const char* dbPath, const char* query);
|
||||
bool ffSettingsGetSQLite3String(const char* dbPath, const char* query, FFstrbuf* result);
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ static void appendNum(FFstrbuf* result, uint64_t bytes, uint32_t base, const cha
|
||||
if (counter == 0)
|
||||
ffStrbufAppendUInt(result, bytes);
|
||||
else
|
||||
ffStrbufAppendDouble(result, size, (int8_t) options->sizeNdigits);
|
||||
ffStrbufAppendDouble(result, size, (int8_t) options->sizeNdigits, true);
|
||||
if (options->sizeSpaceBeforeUnit != FF_SPACE_BEFORE_UNIT_NEVER)
|
||||
ffStrbufAppendC(result, ' ');
|
||||
ffStrbufAppendS(result, prefixes[counter]);
|
||||
|
||||
@@ -846,6 +846,18 @@
|
||||
"default": -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "fraction-trailing-zeros",
|
||||
"desc": "Set when to keep trailing zeros",
|
||||
"arg": {
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"default": "Use the behavior defined internally",
|
||||
"always": "Always keep trailing zeros",
|
||||
"never": "Never keep trailing zeros"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "temp-unit",
|
||||
"desc": "Set the temperature unit",
|
||||
|
||||
@@ -196,7 +196,7 @@ static const char* detectBluetooth(FFlist* devices, int32_t connectedCount)
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL);
|
||||
DBusMessage* managedObjects = ffDBusGetMethodReply(&dbus, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL, NULL);
|
||||
if(!managedObjects)
|
||||
return "Failed to call GetManagedObjects";
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ static const char* detectBluetoothRoot(FFBluetoothRadioResult* device, const cha
|
||||
char objPath[300];
|
||||
snprintf(objPath, sizeof(objPath), "/org/bluez/%s", hciName);
|
||||
|
||||
DBusMessage* properties = ffDBusGetMethodReply(dbus, "org.bluez", objPath, "org.freedesktop.DBus.Properties", "GetAll", "org.bluez.Adapter1");
|
||||
DBusMessage* properties = ffDBusGetMethodReply(dbus, "org.bluez", objPath, "org.freedesktop.DBus.Properties", "GetAll", "org.bluez.Adapter1", NULL);
|
||||
if(!properties)
|
||||
return "Failed to call org.freedesktop.DBus.Properties.GetAll";
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ typedef struct FFBtrfsDiskUsage
|
||||
uint64_t total;
|
||||
uint64_t used;
|
||||
const char* type;
|
||||
bool dup;
|
||||
const char* profile; // single / dup / raidx
|
||||
uint8_t copies;
|
||||
} FFBtrfsDiskUsage;
|
||||
|
||||
typedef struct FFBtrfsResult
|
||||
|
||||
@@ -73,20 +73,40 @@ static const char* detectAllocation(FFBtrfsResult* item, int dfd, FFstrbuf* buff
|
||||
item->globalReservationUsed = ffStrbufToUInt(buffer, 0);
|
||||
item->globalReservationUsed = item->globalReservationTotal - item->globalReservationUsed;
|
||||
|
||||
#define FF_BTRFS_DETECT_TYPE(index, _type) \
|
||||
if (ffReadFileBufferRelative(subfd, #_type "/total_bytes", buffer)) \
|
||||
item->allocation[index].total = ffStrbufToUInt(buffer, 0); \
|
||||
\
|
||||
if (ffReadFileBufferRelative(subfd, #_type "/bytes_used", buffer)) \
|
||||
item->allocation[index].used = ffStrbufToUInt(buffer, 0); \
|
||||
\
|
||||
item->allocation[index].dup = faccessat(subfd, #_type "/dup/", F_OK, 0) == 0; \
|
||||
\
|
||||
item->allocation[index].type = #_type;
|
||||
#define FF_BTRFS_DETECT_PROFILE(_index, _type, _profile, _copies) \
|
||||
else if (faccessat(subfd, _type "/" _profile "/", F_OK, 0) == 0) { \
|
||||
item->allocation[_index].profile = _profile; \
|
||||
item->allocation[_index].copies = _copies; \
|
||||
}
|
||||
|
||||
FF_BTRFS_DETECT_TYPE(0, data);
|
||||
FF_BTRFS_DETECT_TYPE(1, metadata);
|
||||
FF_BTRFS_DETECT_TYPE(2, system);
|
||||
#define FF_BTRFS_DETECT_TYPE(_index, _type) \
|
||||
do { \
|
||||
item->allocation[_index].type = _type; \
|
||||
if (ffReadFileBufferRelative(subfd, _type "/total_bytes", buffer)) \
|
||||
item->allocation[_index].total = ffStrbufToUInt(buffer, 0); \
|
||||
\
|
||||
if (ffReadFileBufferRelative(subfd, _type "/bytes_used", buffer)) \
|
||||
item->allocation[_index].used = ffStrbufToUInt(buffer, 0); \
|
||||
\
|
||||
if (false) {} \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "single", 1) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "dup", 2) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid0", 1) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid1", 2) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid10", 2) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid1c3", 3) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid1c4", 4) \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid5", 1) /* (n-1)/n */ \
|
||||
FF_BTRFS_DETECT_PROFILE(_index, _type, "raid6", 1) /* (n-2)/n */ \
|
||||
else { \
|
||||
item->allocation[_index].profile = "unknown"; \
|
||||
item->allocation[_index].copies = 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
FF_BTRFS_DETECT_TYPE(0, "data");
|
||||
FF_BTRFS_DETECT_TYPE(1, "metadata");
|
||||
FF_BTRFS_DETECT_TYPE(2, "system");
|
||||
|
||||
#undef FF_BTRFS_DETECT_TYPE
|
||||
|
||||
|
||||
+29
-45
@@ -296,23 +296,7 @@ void ffCPUDetectByCpuid(FFCPUResult* cpu)
|
||||
}
|
||||
#elif __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
#include <arm/cpu_capabilities_public.h>
|
||||
|
||||
#ifndef CAP_BIT_AdvSIMD
|
||||
#define CAP_BIT_AdvSIMD 49
|
||||
#endif
|
||||
#ifndef CAP_BIT_AdvSIMD_HPFPCvt
|
||||
#define CAP_BIT_AdvSIMD_HPFPCvt 50
|
||||
#endif
|
||||
#ifndef CAP_BIT_FEAT_CRC32
|
||||
#define CAP_BIT_FEAT_CRC32 51
|
||||
#endif
|
||||
#ifndef CAP_BIT_FEAT_HBC
|
||||
#define CAP_BIT_FEAT_HBC 64
|
||||
#endif
|
||||
#ifndef CAP_BIT_FEAT_CSSC
|
||||
#define CAP_BIT_FEAT_CSSC 67
|
||||
#endif
|
||||
// #include <arm/cpu_capabilities_public.h> // Not available in macOS 14-
|
||||
|
||||
void ffCPUDetectByCpuid(FFCPUResult* cpu)
|
||||
{
|
||||
@@ -328,59 +312,59 @@ void ffCPUDetectByCpuid(FFCPUResult* cpu)
|
||||
cpu->march = "unknown";
|
||||
|
||||
// ARMv8-A
|
||||
bool has_fp = FF_HAS_CAP(CAP_BIT_AdvSIMD_HPFPCvt); // Full FP16 support (implies FP/ASIMD)
|
||||
bool has_asimd = FF_HAS_CAP(CAP_BIT_AdvSIMD); // Advanced SIMD (NEON)
|
||||
bool has_fp = FF_HAS_CAP(50); /* CAP_BIT_AdvSIMD_HPFPCvt */ // Full FP16 support (implies FP/ASIMD)
|
||||
bool has_asimd = FF_HAS_CAP(49); /* CAP_BIT_AdvSIMD */ // Advanced SIMD (NEON)
|
||||
|
||||
// ARMv8.1-A
|
||||
bool has_lse = FF_HAS_CAP(CAP_BIT_FEAT_LSE); // Large System Extensions, optional in v8.0
|
||||
bool has_crc32 = FF_HAS_CAP(CAP_BIT_FEAT_CRC32); // CRC32 instructions, optional in v8.0
|
||||
bool has_rdm = FF_HAS_CAP(CAP_BIT_FEAT_RDM); // AdvSIMD rounding double multiply accumulate, optional in v8.0
|
||||
bool has_lse = FF_HAS_CAP(6); /* CAP_BIT_FEAT_LSE */ // Large System Extensions, optional in v8.0
|
||||
bool has_crc32 = FF_HAS_CAP(51); /* CAP_BIT_FEAT_CRC32 */ // CRC32 instructions, optional in v8.0
|
||||
bool has_rdm = FF_HAS_CAP(5); /* CAP_BIT_FEAT_RDM */ // AdvSIMD rounding double multiply accumulate, optional in v8.0
|
||||
|
||||
// ARMv8.2-A
|
||||
bool has_fp16 = FF_HAS_CAP(CAP_BIT_FEAT_FP16); // Half-precision FP support, optional
|
||||
bool has_dpb = FF_HAS_CAP(CAP_BIT_FEAT_DPB); // DC CVAP, optional from v8.1
|
||||
bool has_fp16 = FF_HAS_CAP(34); /* CAP_BIT_FEAT_FP16 */ // Half-precision FP support, optional
|
||||
bool has_dpb = FF_HAS_CAP(22); /* CAP_BIT_FEAT_DPB */ // DC CVAP, optional from v8.1
|
||||
|
||||
// ARMv8.3-A
|
||||
bool has_pauth = FF_HAS_CAP(CAP_BIT_FEAT_PAuth); // Pointer Authentication (PAC), optional from v8.2
|
||||
bool has_lrcpc = FF_HAS_CAP(CAP_BIT_FEAT_LRCPC); // LDAPR/LR with RCPC semantics, optional from v8.2
|
||||
bool has_fcma = FF_HAS_CAP(CAP_BIT_FEAT_FCMA); // Complex number multiply-add, optional from v8.2
|
||||
bool has_jscvt = FF_HAS_CAP(CAP_BIT_FEAT_JSCVT); // JavaScript-style conversion (FJCVTZS), optional from v8.2
|
||||
bool has_pauth = FF_HAS_CAP(19); /* CAP_BIT_FEAT_PAuth */ // Pointer Authentication (PAC), optional from v8.2
|
||||
bool has_lrcpc = FF_HAS_CAP(15); /* CAP_BIT_FEAT_LRCPC */ // LDAPR/LR with RCPC semantics, optional from v8.2
|
||||
bool has_fcma = FF_HAS_CAP(17); /* CAP_BIT_FEAT_FCMA */ // Complex number multiply-add, optional from v8.2
|
||||
bool has_jscvt = FF_HAS_CAP(18); /* CAP_BIT_FEAT_JSCVT */ // JavaScript-style conversion (FJCVTZS), optional from v8.2
|
||||
|
||||
// ARMv8.4-A
|
||||
bool has_lse2 = FF_HAS_CAP(CAP_BIT_FEAT_LSE2); // Large System Extensions version 2, optional from v8.2
|
||||
bool has_dit = FF_HAS_CAP(CAP_BIT_FEAT_DIT); // Data Independent Timing, optional from v8.3
|
||||
bool has_flagm = FF_HAS_CAP(CAP_BIT_FEAT_FlagM); // Flag manipulation (FMOV/FCVT), optional from v8.1
|
||||
bool has_lrcpc2 = FF_HAS_CAP(CAP_BIT_FEAT_LRCPC2); // Enhanced RCPC (LDAPUR/LDAPST), optional from v8.2
|
||||
bool has_lse2 = FF_HAS_CAP(30); /* CAP_BIT_FEAT_LSE2 */ // Large System Extensions version 2, optional from v8.2
|
||||
bool has_dit = FF_HAS_CAP(33); /* CAP_BIT_FEAT_DIT */ // Data Independent Timing, optional from v8.3
|
||||
bool has_flagm = FF_HAS_CAP(0); /* CAP_BIT_FEAT_FlagM */ // Flag manipulation (FMOV/FCVT), optional from v8.1
|
||||
bool has_lrcpc2 = FF_HAS_CAP(16); /* CAP_BIT_FEAT_LRCPC2 */ // Enhanced RCPC (LDAPUR/LDAPST), optional from v8.2
|
||||
|
||||
// ARMv8.5-A
|
||||
bool has_bti = FF_HAS_CAP(CAP_BIT_FEAT_BTI); // Branch Target Identification, optional from v8.4
|
||||
bool has_sb = FF_HAS_CAP(CAP_BIT_FEAT_SB); // Speculative Barrier, optional from v8.0
|
||||
bool has_dpb2 = FF_HAS_CAP(CAP_BIT_FEAT_DPB2); // DC CVADP (DPB2), optional from v8.1
|
||||
bool has_flagm2 = FF_HAS_CAP(CAP_BIT_FEAT_FlagM2); // Enhanced FlagM, optional from v8.4
|
||||
bool has_frintts = FF_HAS_CAP(CAP_BIT_FEAT_FRINTTS); // Floating-point to integer instructions, optional from v8.4
|
||||
bool has_bti = FF_HAS_CAP(36); /* CAP_BIT_FEAT_BTI */ // Branch Target Identification, optional from v8.4
|
||||
bool has_sb = FF_HAS_CAP(13); /* CAP_BIT_FEAT_SB */ // Speculative Barrier, optional from v8.0
|
||||
bool has_dpb2 = FF_HAS_CAP(23); /* CAP_BIT_FEAT_DPB2 */ // DC CVADP (DPB2), optional from v8.1
|
||||
bool has_flagm2 = FF_HAS_CAP(1); /* CAP_BIT_FEAT_FlagM2 */ // Enhanced FlagM, optional from v8.4
|
||||
bool has_frintts = FF_HAS_CAP(14); /* CAP_BIT_FEAT_FRINTTS */ // Floating-point to integer instructions, optional from v8.4
|
||||
|
||||
// ARMv9.0-A
|
||||
bool has_sve2 = false; // Not exposed and not supported by Apple M4
|
||||
bool has_sve2 = false; // Not exposed and not supported by Apple M4
|
||||
|
||||
// ARMv9.1-A
|
||||
// ARMv8.6-A
|
||||
bool has_bf16 = FF_HAS_CAP(CAP_BIT_FEAT_BF16); // Brain float16, optional from v8.2
|
||||
bool has_i8mm = FF_HAS_CAP(CAP_BIT_FEAT_I8MM); // Int8 Matrix Multiply, optional from v8.1
|
||||
bool has_bf16 = FF_HAS_CAP(24); /* CAP_BIT_FEAT_BF16 */ // Brain float16, optional from v8.2
|
||||
bool has_i8mm = FF_HAS_CAP(25); /* CAP_BIT_FEAT_I8MM */ // Int8 Matrix Multiply, optional from v8.1
|
||||
|
||||
// ARMv8.7-A
|
||||
bool has_afp = FF_HAS_CAP(CAP_BIT_FEAT_AFP); // Alternate FP16 (FEXPA), optional from v8.6
|
||||
bool has_afp = FF_HAS_CAP(29); /* CAP_BIT_FEAT_AFP */ // Alternate FP16 (FEXPA), optional from v8.6
|
||||
|
||||
// ARMv9.2-A
|
||||
bool has_sme = FF_HAS_CAP(CAP_BIT_FEAT_SME); // Scalable Matrix Extension, optional from v9.2
|
||||
bool has_sme = FF_HAS_CAP(40); /* CAP_BIT_FEAT_SME */ // Scalable Matrix Extension, optional from v9.2
|
||||
|
||||
// ARMv9.3-A
|
||||
bool has_sme2 = FF_HAS_CAP(CAP_BIT_FEAT_SME2); // SME2, optional from v9.2
|
||||
bool has_sme2 = FF_HAS_CAP(41); /* CAP_BIT_FEAT_SME2 */ // SME2, optional from v9.2
|
||||
|
||||
// ARMv8.8-A
|
||||
bool has_hbc = FF_HAS_CAP(CAP_BIT_FEAT_HBC); // Hinted conditional branches, optional from v8.7
|
||||
bool has_hbc = FF_HAS_CAP(64); /* CAP_BIT_FEAT_HBC */ // Hinted conditional branches, optional from v8.7
|
||||
|
||||
// ARMv8.9-A
|
||||
bool has_cssc = FF_HAS_CAP(CAP_BIT_FEAT_CSSC); // Common Short String Compare, optional from v8.7
|
||||
bool has_cssc = FF_HAS_CAP(67); /* CAP_BIT_FEAT_CSSC */ // Common Short String Compare, optional from v8.7
|
||||
|
||||
// ARMv9.4-A+ are not exposed yet
|
||||
|
||||
|
||||
@@ -353,6 +353,10 @@ static const char* parseCpuInfo(
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "processor 0:", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz static :", cpuMHz)) || // This one cannot be detected because of early return
|
||||
#elif __ia64__
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor :", &cpu->vendor)) ||
|
||||
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
|
||||
#else
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
|
||||
(cpu->name.length == 0 && ffParsePropLine(line, "model :", &cpu->name)) ||
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#define FF_WM_PROTOCOL_TTY "TTY"
|
||||
#define FF_WM_PROTOCOL_X11 "X11"
|
||||
#define FF_WM_PROTOCOL_WAYLAND "Wayland"
|
||||
#define FF_WM_PROTOCOL_SURFACEFLINGER "SurfaceFlinger"
|
||||
|
||||
typedef enum __attribute__((__packed__)) FFDisplayType {
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "displayserver.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/processing.h"
|
||||
#include "linux/displayserver_linux.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -82,13 +83,10 @@ static void detectWithDumpsys(FFDisplayServerResult* ds)
|
||||
|
||||
ffStrbufRecalculateLength(&name);
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
(uint32_t)width,
|
||||
(uint32_t)height,
|
||||
(uint32_t)width, (uint32_t)height,
|
||||
refreshRate,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
&name,
|
||||
@@ -121,13 +119,10 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
ffStrbufSubstrAfterFirstC(&buffer, ',');
|
||||
double scaleFactor = (double) ffStrbufToUInt(&buffer, 0) / 160.;
|
||||
FFDisplayResult* display = ffdsAppendDisplay(ds,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
(uint32_t) (width / scaleFactor + .5),
|
||||
(uint32_t) (height / scaleFactor + .5),
|
||||
0,
|
||||
width, height,
|
||||
0,
|
||||
(uint32_t) (width / scaleFactor + .5), (uint32_t) (height / scaleFactor + .5),
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
@@ -147,8 +142,19 @@ static bool detectWithGetprop(FFDisplayServerResult* ds)
|
||||
|
||||
void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
{
|
||||
ffStrbufSetStatic(&ds->wmProcessName, "surfaceflinger");
|
||||
ffStrbufSetStatic(&ds->wmPrettyName, "SurfaceFlinger");
|
||||
const char* error = ffdsConnectXcbRandr(ds);
|
||||
if (error)
|
||||
error = ffdsConnectXrandr(ds);
|
||||
if (!error)
|
||||
{
|
||||
ffdsDetectWMDE(ds);
|
||||
return;
|
||||
}
|
||||
|
||||
// https://source.android.com/docs/core/graphics/surfaceflinger-windowmanager
|
||||
ffStrbufSetStatic(&ds->wmProcessName, "system_server");
|
||||
ffStrbufSetStatic(&ds->wmPrettyName, "WindowManager"); // A system service managed by system_server
|
||||
ffStrbufSetStatic(&ds->wmProtocolName, FF_WM_PROTOCOL_SURFACEFLINGER);
|
||||
|
||||
if (!detectWithGetprop(ds))
|
||||
detectWithDumpsys(ds);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -95,17 +95,3 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
ffdsDetectWMDE(ds);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -396,13 +396,10 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
}
|
||||
|
||||
FFDisplayResult* item = ffdsAppendDisplay(result,
|
||||
width,
|
||||
height,
|
||||
width, height,
|
||||
refreshRate,
|
||||
0,
|
||||
0,
|
||||
preferredWidth,
|
||||
preferredHeight,
|
||||
0, 0,
|
||||
preferredWidth, preferredHeight,
|
||||
preferredRefreshRate,
|
||||
0,
|
||||
&name,
|
||||
|
||||
@@ -128,8 +128,8 @@ const char* ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry*
|
||||
(uint32_t) display.width,
|
||||
(uint32_t) display.height,
|
||||
display.refreshRate / 1000.0,
|
||||
(uint32_t) (display.width / display.scale),
|
||||
(uint32_t) (display.height / display.scale),
|
||||
(uint32_t) (display.width / display.scale + .5),
|
||||
(uint32_t) (display.height / display.scale + .5),
|
||||
(uint32_t) display.preferredWidth,
|
||||
(uint32_t) display.preferredHeight,
|
||||
display.preferredRefreshRate / 1000.0,
|
||||
|
||||
@@ -220,8 +220,8 @@ const char* ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* re
|
||||
(uint32_t) display.width,
|
||||
(uint32_t) display.height,
|
||||
display.refreshRate / 1000.0,
|
||||
(uint32_t) (display.width / display.scale),
|
||||
(uint32_t) (display.height / display.scale),
|
||||
(uint32_t) (display.width / display.scale + .5),
|
||||
(uint32_t) (display.height / display.scale + .5),
|
||||
(uint32_t) display.preferredWidth,
|
||||
(uint32_t) display.preferredHeight,
|
||||
display.preferredRefreshRate / 1000.0,
|
||||
|
||||
@@ -65,7 +65,7 @@ static const char* parseEnv(void)
|
||||
if(getenv("SWAYSOCK") != NULL)
|
||||
return "Sway";
|
||||
|
||||
#ifdef __linux__
|
||||
#if __linux__ && !__ANDROID__
|
||||
if(
|
||||
getenv("WAYLAND_DISPLAY") != NULL &&
|
||||
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
|
||||
@@ -433,6 +433,11 @@ static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||
|
||||
void ffdsDetectWMDE(FFDisplayServerResult* result)
|
||||
{
|
||||
#if __ANDROID__
|
||||
if(ffStrbufIgnCaseEqualS(&result->wmProtocolName, FF_WM_PROTOCOL_SURFACEFLINGER))
|
||||
return; // Only supported when connected to X11
|
||||
#endif
|
||||
|
||||
const char* env = parseEnv();
|
||||
|
||||
if(result->wmProcessName.length > 0)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifdef FF_HAVE_XCB_RANDR
|
||||
|
||||
#include "common/library.h"
|
||||
#include "common/time.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/mallocHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
@@ -56,7 +56,7 @@ static void* xcbGetProperty(XcbPropertyData* data, xcb_connection_t* connection,
|
||||
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);
|
||||
xcb_get_property_cookie_t propertyCookie = data->ffxcb_get_property(connection, false, window, requestAtomReply->atom, XCB_ATOM_ANY, 0, 8 * 1024);
|
||||
|
||||
FF_AUTO_FREE xcb_get_property_reply_t* propertyReply = data->ffxcb_get_property_reply(connection, propertyCookie, NULL);
|
||||
if(propertyReply == NULL)
|
||||
@@ -138,86 +138,9 @@ typedef struct XcbRandrData
|
||||
xcb_connection_t* connection;
|
||||
FFDisplayServerResult* result;
|
||||
XcbPropertyData propData;
|
||||
|
||||
//init per screen
|
||||
xcb_randr_get_screen_resources_current_reply_t* screenResources;
|
||||
} XcbRandrData;
|
||||
|
||||
static bool xcbRandrHandleCrtc(XcbRandrData* data, xcb_randr_crtc_t crtc, FFstrbuf* name, bool primary, xcb_randr_get_output_info_reply_t* output, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength)
|
||||
{
|
||||
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, crtc, XCB_CURRENT_TIME);
|
||||
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;
|
||||
|
||||
uint32_t rotation;
|
||||
switch (crtcInfoReply->rotation)
|
||||
{
|
||||
case XCB_RANDR_ROTATION_ROTATE_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
xcb_randr_mode_info_t* currentMode = NULL;
|
||||
xcb_randr_mode_info_t* preferredMode = NULL;
|
||||
|
||||
if(data->screenResources)
|
||||
{
|
||||
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(data->screenResources);
|
||||
|
||||
if (output->num_preferred > 0)
|
||||
preferredMode = modesIterator.data;
|
||||
|
||||
while (modesIterator.rem > 0)
|
||||
{
|
||||
if (modesIterator.data->id == crtcInfoReply->mode)
|
||||
{
|
||||
currentMode = modesIterator.data;
|
||||
break;
|
||||
}
|
||||
|
||||
data->ffxcb_randr_mode_info_next(&modesIterator);
|
||||
}
|
||||
}
|
||||
|
||||
FFDisplayResult* item = ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
currentMode ? (double) currentMode->dot_clock / (double) ((uint32_t) currentMode->htotal * currentMode->vtotal) : 0,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
preferredMode ? (uint32_t) preferredMode->width : 0,
|
||||
preferredMode ? (uint32_t) preferredMode->height : 0,
|
||||
preferredMode ? (double) preferredMode->dot_clock / (double) ((uint32_t) preferredMode->htotal * preferredMode->vtotal) : 0,
|
||||
rotation,
|
||||
name,
|
||||
displayType,
|
||||
primary,
|
||||
0,
|
||||
(uint32_t) output->mm_width,
|
||||
(uint32_t) output->mm_height,
|
||||
"xcb-randr-crtc"
|
||||
);
|
||||
if (item && edidLength)
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
}
|
||||
|
||||
return !!item;
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType)
|
||||
static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output, FFstrbuf* name, bool primary, FFDisplayType displayType, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
{
|
||||
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);
|
||||
@@ -246,12 +169,80 @@ static bool xcbRandrHandleOutput(XcbRandrData* data, xcb_randr_output_t output,
|
||||
}
|
||||
}
|
||||
|
||||
bool res = xcbRandrHandleCrtc(data, outputInfoReply->crtc, name, primary, outputInfoReply, displayType, edidData, edidLength);
|
||||
xcb_randr_get_crtc_info_cookie_t crtcInfoCookie = data->ffxcb_randr_get_crtc_info(data->connection, outputInfoReply->crtc, XCB_CURRENT_TIME);
|
||||
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;
|
||||
|
||||
return res;
|
||||
uint32_t rotation;
|
||||
switch (crtcInfoReply->rotation)
|
||||
{
|
||||
case XCB_RANDR_ROTATION_ROTATE_90:
|
||||
rotation = 90;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_180:
|
||||
rotation = 180;
|
||||
break;
|
||||
case XCB_RANDR_ROTATION_ROTATE_270:
|
||||
rotation = 270;
|
||||
break;
|
||||
default:
|
||||
rotation = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
xcb_randr_mode_info_t* currentMode = NULL;
|
||||
xcb_randr_mode_info_t* preferredMode = NULL;
|
||||
|
||||
if(screenResources)
|
||||
{
|
||||
xcb_randr_mode_info_iterator_t modesIterator = data->ffxcb_randr_get_screen_resources_current_modes_iterator(screenResources);
|
||||
|
||||
if (outputInfoReply->num_preferred > 0)
|
||||
preferredMode = modesIterator.data;
|
||||
|
||||
while (modesIterator.rem > 0)
|
||||
{
|
||||
if (modesIterator.data->id == crtcInfoReply->mode)
|
||||
{
|
||||
currentMode = modesIterator.data;
|
||||
break;
|
||||
}
|
||||
|
||||
data->ffxcb_randr_mode_info_next(&modesIterator);
|
||||
}
|
||||
}
|
||||
|
||||
FFDisplayResult* item = ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) crtcInfoReply->width,
|
||||
(uint32_t) crtcInfoReply->height,
|
||||
currentMode ? (double) currentMode->dot_clock / (double) ((uint32_t) currentMode->htotal * currentMode->vtotal) : 0,
|
||||
(uint32_t) (crtcInfoReply->width / scaleFactor + .5),
|
||||
(uint32_t) (crtcInfoReply->height / scaleFactor + .5),
|
||||
preferredMode ? (uint32_t) preferredMode->width : 0,
|
||||
preferredMode ? (uint32_t) preferredMode->height : 0,
|
||||
preferredMode ? (double) preferredMode->dot_clock / (double) ((uint32_t) preferredMode->htotal * preferredMode->vtotal) : 0,
|
||||
rotation,
|
||||
name,
|
||||
displayType,
|
||||
primary,
|
||||
0,
|
||||
(uint32_t) outputInfoReply->mm_width,
|
||||
(uint32_t) outputInfoReply->mm_height,
|
||||
"xcb-randr-crtc"
|
||||
);
|
||||
if (item && edidLength)
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, (uint32_t) edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
item->bitDepth = bitDepth;
|
||||
}
|
||||
|
||||
return !!item;
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* monitor)
|
||||
static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t* monitor, struct xcb_randr_get_screen_resources_current_reply_t* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
{
|
||||
//for some reasons, we have to construct this our self
|
||||
xcb_randr_output_iterator_t outputIterator = {
|
||||
@@ -275,18 +266,20 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
|
||||
|
||||
while(outputIterator.rem > 0)
|
||||
{
|
||||
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType))
|
||||
if(xcbRandrHandleOutput(data, *outputIterator.data, &name, monitor->primary, displayType, screenResources, bitDepth, scaleFactor))
|
||||
foundOutput = true;
|
||||
data->ffxcb_randr_output_next(&outputIterator);
|
||||
};
|
||||
}
|
||||
|
||||
return foundOutput ? true : !!ffdsAppendDisplay(
|
||||
if (foundOutput) return true;
|
||||
|
||||
FFDisplayResult* display = ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) monitor->width,
|
||||
(uint32_t) monitor->height,
|
||||
0,
|
||||
(uint32_t) monitor->width,
|
||||
(uint32_t) monitor->height,
|
||||
(uint32_t) (monitor->width / scaleFactor + .5),
|
||||
(uint32_t) (monitor->height / scaleFactor + .5),
|
||||
0, 0, 0,
|
||||
0,
|
||||
&name,
|
||||
@@ -297,6 +290,8 @@ static bool xcbRandrHandleMonitor(XcbRandrData* data, xcb_randr_monitor_info_t*
|
||||
(uint32_t) monitor->height_in_millimeters,
|
||||
"xcb-randr-monitor"
|
||||
);
|
||||
if (display) display->bitDepth = bitDepth;
|
||||
return !!display;
|
||||
}
|
||||
|
||||
static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
@@ -306,13 +301,27 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
if(monitorsReply == NULL)
|
||||
return false;
|
||||
|
||||
//Init screen resources. They are used to iterate over all modes. xcbRandrHandleMode checks for " == NULL", to fail as late as possible.
|
||||
xcb_randr_get_screen_resources_current_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources_current(data->connection, screen->root);
|
||||
FF_AUTO_FREE struct xcb_randr_get_screen_resources_current_reply_t* screenResources = data->ffxcb_randr_get_screen_resources_current_reply(data->connection, screenResourcesCookie, NULL);
|
||||
|
||||
double scaleFactor = 1;
|
||||
FF_AUTO_FREE const char* resourceManager = xcbGetProperty(&data->propData, data->connection, screen->root, "RESOURCE_MANAGER");
|
||||
if (resourceManager)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY dpi = ffStrbufCreate();
|
||||
if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpi))
|
||||
scaleFactor = ffStrbufToDouble(&dpi, 96) / 96;
|
||||
}
|
||||
uint8_t bitDepth = (uint8_t) (screen->root_depth / 3);
|
||||
|
||||
xcb_randr_monitor_info_iterator_t monitorInfoIterator = data->ffxcb_randr_get_monitors_monitors_iterator(monitorsReply);
|
||||
|
||||
bool foundMonitor = false;
|
||||
|
||||
while(monitorInfoIterator.rem > 0)
|
||||
{
|
||||
if(xcbRandrHandleMonitor(data, monitorInfoIterator.data))
|
||||
if(xcbRandrHandleMonitor(data, monitorInfoIterator.data, screenResources, bitDepth, scaleFactor))
|
||||
foundMonitor = true;
|
||||
data->ffxcb_randr_monitor_info_next(&monitorInfoIterator);
|
||||
}
|
||||
@@ -322,17 +331,8 @@ static bool xcbRandrHandleMonitors(XcbRandrData* data, xcb_screen_t* screen)
|
||||
|
||||
static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
{
|
||||
//Init screen resources. They are used to iterate over all modes. xcbRandrHandleMode checks for " == NULL", to fail as late as possible.
|
||||
xcb_randr_get_screen_resources_current_cookie_t screenResourcesCookie = data->ffxcb_randr_get_screen_resources_current(data->connection, screen->root);
|
||||
|
||||
data->screenResources = data->ffxcb_randr_get_screen_resources_current_reply(data->connection, screenResourcesCookie, NULL);
|
||||
|
||||
//With all the initialisation done, start the detection
|
||||
bool ret = xcbRandrHandleMonitors(data, screen);
|
||||
|
||||
free(data->screenResources);
|
||||
|
||||
if(ret)
|
||||
if(xcbRandrHandleMonitors(data, screen))
|
||||
return;
|
||||
|
||||
//If detetction failed, fallback to screen = monitor, like in the libxcb.so implementation
|
||||
@@ -348,7 +348,7 @@ static void xcbRandrHandleScreen(XcbRandrData* data, xcb_screen_t* screen)
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0,
|
||||
(uint64_t) screen->root,
|
||||
(uint32_t) screen->width_in_millimeters,
|
||||
(uint32_t) screen->height_in_millimeters,
|
||||
"xcb-randr-screen"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifdef FF_HAVE_XRANDR
|
||||
|
||||
#include "common/library.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/edidHelper.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
@@ -70,8 +70,6 @@ static void x11FetchServerVendor(X11PropertyData* data, Display* display, FFDisp
|
||||
if (serverVendor && !ffStrEquals(serverVendor, "The X.Org Foundation")) {
|
||||
ffStrbufSetS(&result->wmProtocolName, serverVendor);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
typedef struct XrandrData
|
||||
@@ -92,18 +90,16 @@ typedef struct XrandrData
|
||||
//Init once
|
||||
Display* display;
|
||||
FFDisplayServerResult* result;
|
||||
|
||||
//Init per screen
|
||||
XRRScreenResources* screenResources;
|
||||
X11PropertyData* propData;
|
||||
} XrandrData;
|
||||
|
||||
static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength)
|
||||
static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf* name, bool primary, FFDisplayType displayType, uint8_t* edidData, uint32_t edidLength, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
{
|
||||
//We do the check here, because we want the best fallback display if this call failed
|
||||
if(data->screenResources == NULL)
|
||||
if(screenResources == NULL)
|
||||
return false;
|
||||
|
||||
XRRCrtcInfo* crtcInfo = data->ffXRRGetCrtcInfo(data->display, data->screenResources, output->crtc);
|
||||
XRRCrtcInfo* crtcInfo = data->ffXRRGetCrtcInfo(data->display, screenResources, output->crtc);
|
||||
if(crtcInfo == NULL)
|
||||
return false;
|
||||
|
||||
@@ -125,27 +121,24 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
||||
}
|
||||
|
||||
XRRModeInfo* currentMode = NULL;
|
||||
if (data->screenResources)
|
||||
for(int i = 0; i < screenResources->nmode; i++)
|
||||
{
|
||||
for(int i = 0; i < data->screenResources->nmode; i++)
|
||||
if(screenResources->modes[i].id == crtcInfo->mode)
|
||||
{
|
||||
if(data->screenResources->modes[i].id == crtcInfo->mode)
|
||||
{
|
||||
currentMode = &data->screenResources->modes[i];
|
||||
break;
|
||||
}
|
||||
currentMode = &screenResources->modes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XRRModeInfo* preferredMode = data->screenResources && output->npreferred > 0 ? &data->screenResources->modes[0] : NULL;
|
||||
XRRModeInfo* preferredMode = output->npreferred > 0 ? &screenResources->modes[0] : NULL;
|
||||
|
||||
FFDisplayResult* item = ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) crtcInfo->width,
|
||||
(uint32_t) crtcInfo->height,
|
||||
currentMode ? (double) currentMode->dotClock / (double) ((uint32_t) currentMode->hTotal * currentMode->vTotal) : 0,
|
||||
(uint32_t) crtcInfo->width,
|
||||
(uint32_t) crtcInfo->height,
|
||||
(uint32_t) (crtcInfo->width / scaleFactor + .5),
|
||||
(uint32_t) (crtcInfo->height / scaleFactor + .5),
|
||||
preferredMode ? (uint32_t) preferredMode->width : 0,
|
||||
preferredMode ? (uint32_t) preferredMode->height : 0,
|
||||
preferredMode ? (double) preferredMode->dotClock / (double) ((uint32_t) preferredMode->hTotal * preferredMode->vTotal) : 0,
|
||||
@@ -159,19 +152,23 @@ static bool xrandrHandleCrtc(XrandrData* data, XRROutputInfo* output, FFstrbuf*
|
||||
"xlib-randr-crtc"
|
||||
);
|
||||
|
||||
if (item && edidLength)
|
||||
if (item)
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
if (edidLength)
|
||||
{
|
||||
item->hdrStatus = ffEdidGetHdrCompatible(edidData, edidLength) ? FF_DISPLAY_HDR_STATUS_SUPPORTED : FF_DISPLAY_HDR_STATUS_UNSUPPORTED;
|
||||
ffEdidGetSerialAndManufactureDate(edidData, &item->serial, &item->manufactureYear, &item->manufactureWeek);
|
||||
}
|
||||
item->bitDepth = bitDepth;
|
||||
}
|
||||
|
||||
data->ffXRRFreeCrtcInfo(crtcInfo);
|
||||
return !!item;
|
||||
}
|
||||
|
||||
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType)
|
||||
static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name, bool primary, FFDisplayType displayType, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
{
|
||||
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, data->screenResources, output);
|
||||
XRROutputInfo* outputInfo = data->ffXRRGetOutputInfo(data->display, screenResources, output);
|
||||
if(outputInfo == NULL)
|
||||
return false;
|
||||
|
||||
@@ -195,7 +192,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
|
||||
}
|
||||
}
|
||||
|
||||
bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, (uint32_t) edidLength);
|
||||
bool res = xrandrHandleCrtc(data, outputInfo, name, primary, displayType, edidData, (uint32_t) edidLength, screenResources, bitDepth, scaleFactor);
|
||||
|
||||
if (edidData)
|
||||
data->ffXFree(edidData);
|
||||
@@ -204,7 +201,7 @@ static bool xrandrHandleOutput(XrandrData* data, RROutput output, FFstrbuf* name
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo, XRRScreenResources* screenResources, uint8_t bitDepth, double scaleFactor)
|
||||
{
|
||||
bool foundOutput = false;
|
||||
char* xname = data->ffXGetAtomName(data->display, monitorInfo->name);
|
||||
@@ -213,17 +210,19 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
FFDisplayType displayType = ffdsGetDisplayType(name.chars);
|
||||
for(int i = 0; i < monitorInfo->noutput; i++)
|
||||
{
|
||||
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType))
|
||||
if(xrandrHandleOutput(data, monitorInfo->outputs[i], &name, monitorInfo->primary, displayType, screenResources, bitDepth, scaleFactor))
|
||||
foundOutput = true;
|
||||
}
|
||||
|
||||
return foundOutput ? true : !!ffdsAppendDisplay(
|
||||
if (foundOutput) return true;
|
||||
|
||||
FFDisplayResult* display = ffdsAppendDisplay(
|
||||
data->result,
|
||||
(uint32_t) monitorInfo->width,
|
||||
(uint32_t) monitorInfo->height,
|
||||
0,
|
||||
(uint32_t) monitorInfo->width,
|
||||
(uint32_t) monitorInfo->height,
|
||||
(uint32_t) (monitorInfo->width / scaleFactor + .5),
|
||||
(uint32_t) (monitorInfo->height / scaleFactor + .5),
|
||||
0, 0, 0,
|
||||
0,
|
||||
&name,
|
||||
@@ -234,6 +233,8 @@ static bool xrandrHandleMonitor(XrandrData* data, XRRMonitorInfo* monitorInfo)
|
||||
(uint32_t) monitorInfo->mheight,
|
||||
"xlib-randr-monitor"
|
||||
);
|
||||
if (display) display->bitDepth = bitDepth;
|
||||
return !!display;
|
||||
}
|
||||
|
||||
static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
|
||||
@@ -243,29 +244,36 @@ static bool xrandrHandleMonitors(XrandrData* data, Screen* screen)
|
||||
if(monitorInfos == NULL)
|
||||
return false;
|
||||
|
||||
XRRScreenResources* screenResources = data->ffXRRGetScreenResourcesCurrent(data->display, RootWindowOfScreen(screen));
|
||||
|
||||
double scaleFactor = 1;
|
||||
char* resourceManager = (char*) x11GetProperty(data->propData, data->display, screen->root, "RESOURCE_MANAGER");
|
||||
if (resourceManager)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY dpi = ffStrbufCreate();
|
||||
if (ffParsePropLines(resourceManager, "Xft.dpi:", &dpi))
|
||||
scaleFactor = ffStrbufToDouble(&dpi, 96) / 96;
|
||||
data->ffXFree(resourceManager);
|
||||
}
|
||||
uint8_t bitDepth = (uint8_t) (screen->root_depth / 3);
|
||||
|
||||
bool foundAMonitor = false;
|
||||
|
||||
for(int i = 0; i < numberOfMonitors; i++)
|
||||
{
|
||||
if(xrandrHandleMonitor(data, &monitorInfos[i]))
|
||||
if(xrandrHandleMonitor(data, &monitorInfos[i], screenResources, bitDepth, scaleFactor))
|
||||
foundAMonitor = true;
|
||||
}
|
||||
|
||||
data->ffXRRFreeMonitors(monitorInfos);
|
||||
data->ffXRRFreeScreenResources(screenResources);
|
||||
|
||||
return foundAMonitor;
|
||||
}
|
||||
|
||||
static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
{
|
||||
//Init screen resources
|
||||
data->screenResources = data->ffXRRGetScreenResourcesCurrent(data->display, RootWindowOfScreen(screen));
|
||||
|
||||
bool ret = xrandrHandleMonitors(data, screen);
|
||||
|
||||
data->ffXRRFreeScreenResources(data->screenResources);
|
||||
|
||||
if(ret)
|
||||
if(xrandrHandleMonitors(data, screen))
|
||||
return;
|
||||
|
||||
//Fallback to screen
|
||||
@@ -281,7 +289,7 @@ static void xrandrHandleScreen(XrandrData* data, Screen* screen)
|
||||
NULL,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0,
|
||||
RootWindowOfScreen(screen),
|
||||
(uint32_t) WidthMMOfScreen(screen),
|
||||
(uint32_t) HeightMMOfScreen(screen),
|
||||
"xlib-randr-screen"
|
||||
@@ -312,6 +320,7 @@ const char* ffdsConnectXrandr(FFDisplayServerResult* result)
|
||||
|
||||
X11PropertyData propertyData;
|
||||
bool propertyDataInitialized = x11InitPropertyData(xrandr, &propertyData);
|
||||
data.propData = &propertyData;
|
||||
|
||||
data.display = ffXOpenDisplay(NULL);
|
||||
if(data.display == NULL)
|
||||
|
||||
@@ -28,7 +28,7 @@ const char* ffDetectFontImpl(FFFontResult* result)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY))
|
||||
return "Font isn't supported in TTY";
|
||||
|
||||
FFfont qt;
|
||||
|
||||
+33
-28
@@ -34,6 +34,13 @@ static inline void applyGTKSettings(FFGTKResult* result, const char* themeName,
|
||||
ffStrbufAppendS(&result->wallpaper, wallpaper);
|
||||
}
|
||||
|
||||
static bool testXfconfWallpaperPropKey(FF_MAYBE_UNUSED void* data, const char* key)
|
||||
{
|
||||
int count = 0;
|
||||
sscanf(key, "/backdrop/screen0/monitor%*[^/]/workspace0/last-image%n", &count);
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
static void detectGTKFromSettings(FFGTKResult* result)
|
||||
{
|
||||
static const char* themeName = NULL;
|
||||
@@ -55,47 +62,45 @@ static void detectGTKFromSettings(FFGTKResult* result)
|
||||
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_XFCE4) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_XFCE4))
|
||||
{
|
||||
themeName = ffSettingsGetXFConf("xsettings", "/Net/ThemeName", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGetXFConf("xsettings", "/Net/IconThemeName", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGetXFConf("xsettings", "/Gtk/FontName", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeName", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGetXFConf("xsettings", "/Gtk/CursorThemeSize", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitor0/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if (!wallpaper) // FIXME: find a way to enumerate possible properties
|
||||
wallpaper = ffSettingsGetXFConf("xfce4-desktop", "/backdrop/screen0/monitoreDP-1/workspace0/last-image", FF_VARIANT_TYPE_STRING).strValue;
|
||||
wallpaper = ffSettingsGetXFConfFirstMatch("xfce4-desktop", "/backdrop/screen0", FF_VARIANT_TYPE_STRING, NULL, testXfconfWallpaperPropKey).strValue;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_CINNAMON) == 0)
|
||||
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_CINNAMON))
|
||||
{
|
||||
themeName = ffSettingsGet("/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGet("/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGet("/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGet("/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGet("/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGet("/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||
themeName = ffSettingsGetGnome("/org/cinnamon/desktop/interface/gtk-theme", "org.cinnamon.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGetGnome("/org/cinnamon/desktop/interface/icon-theme", "org.cinnamon.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGetGnome("/org/cinnamon/desktop/interface/font-name", "org.cinnamon.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGetGnome("/org/cinnamon/desktop/interface/cursor-theme", "org.cinnamon.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGetGnome("/org/cinnamon/desktop/interface/cursor-size", "org.cinnamon.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGetGnome("/org/cinnamon/desktop/background/picture-uri", "org.cinnamon.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||
}
|
||||
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_MATE) == 0)
|
||||
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_MATE))
|
||||
{
|
||||
themeName = ffSettingsGet("/org/mate/interface/gtk-theme", "org.mate.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGet("/org/mate/interface/icon-theme", "org.mate.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGet("/org/mate/interface/font-name", "org.mate.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGet("/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGet("/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGet("/org/mate/desktop/background", "org.mate.background", NULL, "picture-filename", FF_VARIANT_TYPE_STRING).strValue;
|
||||
themeName = ffSettingsGetGnome("/org/mate/interface/gtk-theme", "org.mate.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGetGnome("/org/mate/interface/icon-theme", "org.mate.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGetGnome("/org/mate/interface/font-name", "org.mate.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGetGnome("/org/mate/peripherals-mouse/cursor-theme", "org.mate.peripherals-mouse", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGetGnome("/org/mate/peripherals-mouse/cursor-size", "org.mate.peripherals-mouse", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGetGnome("/org/mate/desktop/background", "org.mate.background", NULL, "picture-filename", FF_VARIANT_TYPE_STRING).strValue;
|
||||
}
|
||||
else if(
|
||||
ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME) == 0 ||
|
||||
ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC) == 0 ||
|
||||
ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_UNITY) == 0 ||
|
||||
ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_BUDGIE) == 0
|
||||
ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME) ||
|
||||
ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC) ||
|
||||
ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_UNITY) ||
|
||||
ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_BUDGIE)
|
||||
) {
|
||||
themeName = ffSettingsGet("/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGet("/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGet("/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGet("/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGet("/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGet("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||
themeName = ffSettingsGetGnome("/org/gnome/desktop/interface/gtk-theme", "org.gnome.desktop.interface", NULL, "gtk-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
iconsName = ffSettingsGetGnome("/org/gnome/desktop/interface/icon-theme", "org.gnome.desktop.interface", NULL, "icon-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
fontName = ffSettingsGetGnome("/org/gnome/desktop/interface/font-name", "org.gnome.desktop.interface", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorTheme = ffSettingsGetGnome("/org/gnome/desktop/interface/cursor-theme", "org.gnome.desktop.interface", NULL, "cursor-theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
cursorSize = ffSettingsGetGnome("/org/gnome/desktop/interface/cursor-size", "org.gnome.desktop.interface", NULL, "cursor-size", FF_VARIANT_TYPE_INT).intValue;
|
||||
wallpaper = ffSettingsGetGnome("/org/gnome/desktop/background/picture-uri", "org.gnome.desktop.background", NULL, "picture-uri", FF_VARIANT_TYPE_STRING).strValue;
|
||||
}
|
||||
|
||||
applyGTKSettings(result, themeName, iconsName, fontName, cursorTheme, cursorSize, wallpaper);
|
||||
|
||||
@@ -7,7 +7,7 @@ const char* ffDetectIcons(FFIconsResult* result)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY))
|
||||
return "Icons aren't supported in TTY";
|
||||
|
||||
const FFstrbuf* plasma = &ffDetectQt()->icons;
|
||||
|
||||
@@ -414,6 +414,13 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
|
||||
FF_DEBUG("Processing adapter %s (IPv4 entries: %u, IPv6 entries: %u)",
|
||||
adapter->mac->ifa_name, adapter->ipv4.length, adapter->ipv6.length);
|
||||
|
||||
if (adapter->ipv4.length == 0 && adapter->ipv6.length == 0 &&
|
||||
!(options->showType & FF_LOCALIP_TYPE_MAC_BIT) )
|
||||
{
|
||||
FF_DEBUG("Skipping interface %s (no IP addresses)", adapter->mac->ifa_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
FFLocalIpResult* item = FF_LIST_ADD(FFLocalIpResult, *results);
|
||||
ffStrbufInitS(&item->name, adapter->mac->ifa_name);
|
||||
ffStrbufInit(&item->ipv4);
|
||||
|
||||
@@ -191,7 +191,7 @@ static void getBestBus(FFDBusData* data, FFMediaResult* result)
|
||||
getBusProperties(data, FF_DBUS_MPRIS_PREFIX "plasma-browser-integration", result)
|
||||
) return;
|
||||
|
||||
DBusMessage* reply = ffDBusGetMethodReply(data, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", NULL);
|
||||
DBusMessage* reply = ffDBusGetMethodReply(data, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", NULL, NULL);
|
||||
if(reply == NULL)
|
||||
return;
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ static bool detectRio(FFTerminalFontResult* terminalFont)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont);
|
||||
bool ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont);
|
||||
|
||||
static bool detectTerminalFontCommon(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
|
||||
const char* detectTermux(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(!ffPathExists(FF_TERMUX_FONT_PATH, FF_PATHTYPE_FILE))
|
||||
{
|
||||
ffFontInitCopy(&terminalFont->font, "monospace");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef FF_HAVE_FREETYPE
|
||||
|
||||
FF_LIBRARY_LOAD(freetype, "dlopen libfreetype"FF_LIBRARY_EXTENSION " failed", "libfreetype"FF_LIBRARY_EXTENSION, 2)
|
||||
@@ -53,19 +59,15 @@ exit:
|
||||
#endif
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
bool ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufCompS(&terminal->processName, "com.termux") != 0)
|
||||
if(ffStrbufEqualS(&terminal->processName, "com.termux"))
|
||||
ffStrbufSetS(&terminalFont->error, detectTermux(terminalFont));
|
||||
else
|
||||
{
|
||||
ffStrbufSetS(&terminalFont->error, "Unsupported terminal");
|
||||
return;
|
||||
bool ffDetectTerminalFontPlatformLinux(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont);
|
||||
return ffDetectTerminalFontPlatformLinux(terminal, terminalFont);
|
||||
}
|
||||
|
||||
if(!ffPathExists(FF_TERMUX_FONT_PATH, FF_PATHTYPE_FILE))
|
||||
{
|
||||
ffFontInitCopy(&terminalFont->font, "monospace");
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufSetS(&terminalFont->error, detectTermux(terminalFont));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ static void detectWarpTerminal(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
bool ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&terminal->processName, "iterm.app") ||
|
||||
ffStrbufStartsWithIgnCaseS(&terminal->processName, "iTermServer-"))
|
||||
@@ -100,4 +100,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
|
||||
detectAppleTerminal(terminalFont);
|
||||
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "WarpTerminal"))
|
||||
detectWarpTerminal(terminalFont);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,26 +16,26 @@ static const char* getSystemMonospaceFont(void)
|
||||
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Cinnamon"))
|
||||
{
|
||||
const char* systemMonospaceFont = ffSettingsGet("/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
const char* systemMonospaceFont = ffSettingsGetGnome("/org/cinnamon/desktop/interface/monospace-font-name", "org.cinnamon.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(systemMonospaceFont))
|
||||
return systemMonospaceFont;
|
||||
}
|
||||
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, "Mate"))
|
||||
{
|
||||
const char* systemMonospaceFont = ffSettingsGet("/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
const char* systemMonospaceFont = ffSettingsGetGnome("/org/mate/interface/monospace-font-name", "org.mate.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(systemMonospaceFont))
|
||||
return systemMonospaceFont;
|
||||
}
|
||||
|
||||
return ffSettingsGet("/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
return ffSettingsGetGnome("/org/gnome/desktop/interface/monospace-font-name", "org.gnome.desktop.interface", NULL, "monospace-font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
}
|
||||
|
||||
static void detectKgx(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
// kgx (gnome console) doesn't support profiles
|
||||
if(!ffSettingsGet("/org/gnome/Console/use-system-font", "org.gnome.Console", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
if(!ffSettingsGetGnome("/org/gnome/Console/use-system-font", "org.gnome.Console", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
{
|
||||
FF_AUTO_FREE const char* fontName = ffSettingsGet("/org/gnome/Console/custom-font", "org.gnome.Console", NULL, "custom-font", FF_VARIANT_TYPE_STRING).strValue;
|
||||
FF_AUTO_FREE const char* fontName = ffSettingsGetGnome("/org/gnome/Console/custom-font", "org.gnome.Console", NULL, "custom-font", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
@@ -53,9 +53,9 @@ static void detectKgx(FFTerminalFontResult* terminalFont)
|
||||
|
||||
static void detectPtyxis(FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(!ffSettingsGet("/org/gnome/Ptyxis/use-system-font", "org.gnome.Ptyxis", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
if(!ffSettingsGetGnome("/org/gnome/Ptyxis/use-system-font", "org.gnome.Ptyxis", NULL, "use-system-font", FF_VARIANT_TYPE_BOOL).boolValue)
|
||||
{
|
||||
FF_AUTO_FREE const char* fontName = ffSettingsGet("/org/gnome/Ptyxis/font-name", "org.gnome.Ptyxis", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
FF_AUTO_FREE const char* fontName = ffSettingsGetGnome("/org/gnome/Ptyxis/font-name", "org.gnome.Ptyxis", NULL, "font-name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(fontName))
|
||||
ffFontInitPango(&terminalFont->font, fontName);
|
||||
else
|
||||
@@ -167,7 +167,7 @@ static void detectXFCETerminal(FFTerminalFontResult* terminalFont)
|
||||
});
|
||||
}
|
||||
|
||||
if(configFound && (useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0))
|
||||
if(configFound && (useSysFont.length == 0 || ffStrbufIgnCaseEqualS(&useSysFont, "false")))
|
||||
{
|
||||
if(fontName.length == 0)
|
||||
ffStrbufAppendF(&terminalFont->error, "Couldn't find FontName in %s", path);
|
||||
@@ -433,7 +433,13 @@ static void detectHaikuTerminal(FFTerminalFontResult* terminalFont)
|
||||
}
|
||||
#endif
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
bool
|
||||
#ifdef __ANDROID__
|
||||
ffDetectTerminalFontPlatformLinux
|
||||
#else
|
||||
ffDetectTerminalFontPlatform
|
||||
#endif
|
||||
(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&terminal->processName, "konsole"))
|
||||
detectKonsole(terminalFont, "konsolerc");
|
||||
@@ -477,4 +483,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
|
||||
#endif
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "termite"))
|
||||
detectFromConfigFile("termite/config", "font =", terminalFont);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ static void detectWarp(FFTerminalFontResult* terminalFont)
|
||||
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
|
||||
}
|
||||
|
||||
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
bool ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
|
||||
{
|
||||
if(ffStrbufIgnCaseEqualS(&terminal->processName, "Windows Terminal") ||
|
||||
ffStrbufIgnCaseEqualS(&terminal->processName, "WindowsTerminal.exe"))
|
||||
@@ -287,4 +287,7 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
|
||||
detectConEmu(terminalFont);
|
||||
else if(ffStrbufStartsWithIgnCaseS(&terminal->processName, "warp"))
|
||||
detectWarp(terminalFont);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
ffStrbufEqualS(&result->processName, "proot") ||
|
||||
ffStrbufEqualS(&result->processName, "script") ||
|
||||
#ifdef __linux__
|
||||
ffStrbufStartsWithS(&result->processName, "Relay(") || // Unknown process in WSL2
|
||||
ffStrbufStartsWithS(&result->processName, "flatpak-") || // #707
|
||||
#endif
|
||||
ffStrbufEndsWithS(&result->processName, ".sh")
|
||||
|
||||
@@ -7,7 +7,7 @@ const char* ffDetectTheme(FFThemeResult* result)
|
||||
{
|
||||
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY))
|
||||
return "Theme isn't supported in TTY";
|
||||
|
||||
const FFQtResult* plasma = ffDetectQt();
|
||||
|
||||
@@ -57,7 +57,7 @@ static const char* detectWifiWithNm(FFWifiResult* item, FFstrbuf* buffer)
|
||||
|
||||
{
|
||||
FF_DEBUG("Getting device by IP interface name");
|
||||
DBusMessage* device = ffDBusGetMethodReply(&dbus, "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", "GetDeviceByIpIface", item->inf.description.chars);
|
||||
DBusMessage* device = ffDBusGetMethodReply(&dbus, "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", "GetDeviceByIpIface", item->inf.description.chars, NULL);
|
||||
if(!device)
|
||||
{
|
||||
FF_DEBUG("GetDeviceByIpIface failed for interface %s", item->inf.description.chars);
|
||||
|
||||
+64
-53
@@ -13,6 +13,17 @@ const char* ffDetectWMPlugin(FF_MAYBE_UNUSED FFstrbuf* pluginName)
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
|
||||
static bool extractCommonWmVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
int count = 0;
|
||||
sscanf(line, "%*d.%*d.%*d%n", &count);
|
||||
if (count == 0) return true;
|
||||
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, len, line);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !__ANDROID__
|
||||
static bool extractHyprlandVersion(const char* line, uint32_t len, void *userdata)
|
||||
{
|
||||
if (line[0] != 'v') return true;
|
||||
@@ -128,6 +139,48 @@ static const char* getSway(FFstrbuf* result)
|
||||
return "Failed to run command `sway --version`";
|
||||
}
|
||||
|
||||
static const char* getLabwc(FFstrbuf* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
const char* error = ffFindExecutableInPath("labwc", &path);
|
||||
if (error) return "Failed to find labwc executable path";
|
||||
|
||||
ffBinaryExtractStrings(path.chars, extractCommonWmVersion, result, (uint32_t) strlen("0.0.0"));
|
||||
if (result->length > 0) return NULL;
|
||||
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
path.chars,
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL)
|
||||
{ // labwc 0.9.0 (+xwayland +nls +rsvg +libsfdo)
|
||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||
ffStrbufSubstrBeforeFirstC(result, ' ');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return "Failed to run command `labwc --version`";
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static const char* getWslg(FFstrbuf* result)
|
||||
{
|
||||
if (!ffAppendFileBuffer("/mnt/wslg/versions.txt", result))
|
||||
return "Failed to read /mnt/wslg/versions.txt";
|
||||
|
||||
if (!ffStrbufStartsWithS(result, "WSLg "))
|
||||
return "Failed to find WSLg version";
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(result, '\n');
|
||||
ffStrbufSubstrBeforeFirstC(result, '+');
|
||||
ffStrbufSubstrAfterFirstC(result, ':');
|
||||
ffStrbufTrimLeft(result, ' ');
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !__ANDROID__
|
||||
|
||||
static bool extractI3Version(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -161,31 +214,6 @@ static const char* getI3(FFstrbuf* result)
|
||||
return "Failed to run command `i3 --version`";
|
||||
}
|
||||
|
||||
static const char* getWslg(FFstrbuf* result)
|
||||
{
|
||||
if (!ffAppendFileBuffer("/mnt/wslg/versions.txt", result))
|
||||
return "Failed to read /mnt/wslg/versions.txt";
|
||||
|
||||
if (!ffStrbufStartsWithS(result, "WSLg "))
|
||||
return "Failed to find WSLg version";
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(result, '\n');
|
||||
ffStrbufSubstrBeforeFirstC(result, '+');
|
||||
ffStrbufSubstrAfterFirstC(result, ':');
|
||||
ffStrbufTrimLeft(result, ' ');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool extractCommonWmVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
|
||||
{
|
||||
int count = 0;
|
||||
sscanf(line, "%*d.%*d.%*d%n", &count);
|
||||
if (count == 0) return true;
|
||||
|
||||
ffStrbufSetNS((FFstrbuf*) userdata, len, line);
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char* getCtwm(FFstrbuf* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
@@ -255,45 +283,31 @@ static const char* getOpenbox(FFstrbuf* result)
|
||||
return "Failed to run command `openbox --version`";
|
||||
}
|
||||
|
||||
static const char* getLabwc(FFstrbuf* result)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
|
||||
const char* error = ffFindExecutableInPath("labwc", &path);
|
||||
if (error) return "Failed to find labwc executable path";
|
||||
|
||||
ffBinaryExtractStrings(path.chars, extractCommonWmVersion, result, (uint32_t) strlen("0.0.0"));
|
||||
if (result->length > 0) return NULL;
|
||||
|
||||
if (ffProcessAppendStdOut(result, (char* const[]){
|
||||
path.chars,
|
||||
"--version",
|
||||
NULL
|
||||
}) == NULL)
|
||||
{ // labwc 0.9.0 (+xwayland +nls +rsvg +libsfdo)
|
||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||
ffStrbufSubstrBeforeFirstC(result, ' ');
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return "Failed to run command `labwc --version`";
|
||||
}
|
||||
|
||||
const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options)
|
||||
{
|
||||
if (!wmName)
|
||||
return "No WM detected";
|
||||
|
||||
#if !__ANDROID__
|
||||
// Wayland compositors
|
||||
if (ffStrbufIgnCaseEqualS(wmName, "Hyprland"))
|
||||
return getHyprland(result);
|
||||
|
||||
if (ffStrbufEqualS(wmName, "sway"))
|
||||
return getSway(result);
|
||||
|
||||
if (ffStrbufEqualS(wmName, "i3"))
|
||||
return getI3(result);
|
||||
if (ffStrbufEqualS(wmName, "labwc"))
|
||||
return getLabwc(result);
|
||||
|
||||
#if __linux__
|
||||
if (ffStrbufEqualS(wmName, "WSLg"))
|
||||
return getWslg(result);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// X11 WMs
|
||||
if (ffStrbufEqualS(wmName, "i3"))
|
||||
return getI3(result);
|
||||
|
||||
if (ffStrbufEqualS(wmName, "ctwm"))
|
||||
return getCtwm(result);
|
||||
@@ -304,8 +318,5 @@ const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE
|
||||
if (ffStrbufEqualS(wmName, "Openbox"))
|
||||
return getOpenbox(result);
|
||||
|
||||
if (ffStrbufEqualS(wmName, "labwc"))
|
||||
return getLabwc(result);
|
||||
|
||||
return "Unsupported WM";
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ static bool detectWMThemeFromConfigFile(const char* configFile, const char* them
|
||||
|
||||
static bool detectWMThemeFromSettings(const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFstrbuf* themeOrError)
|
||||
{
|
||||
const char* theme = ffSettingsGet(dconfKey, gsettingsSchemaName, gsettingsPath, gsettingsKey, FF_VARIANT_TYPE_STRING).strValue;
|
||||
const char* theme = ffSettingsGetGnome(dconfKey, gsettingsSchemaName, gsettingsPath, gsettingsKey, FF_VARIANT_TYPE_STRING).strValue;
|
||||
|
||||
if(!ffStrSet(theme))
|
||||
{
|
||||
@@ -80,7 +80,7 @@ ok:
|
||||
|
||||
static bool detectMutter(FFstrbuf* themeOrError)
|
||||
{
|
||||
const char* theme = ffSettingsGet("/org/gnome/shell/extensions/user-theme/name", "org.gnome.shell.extensions.user-theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
const char* theme = ffSettingsGetGnome("/org/gnome/shell/extensions/user-theme/name", "org.gnome.shell.extensions.user-theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
if(ffStrSet(theme))
|
||||
{
|
||||
ffStrbufAppendS(themeOrError, theme);
|
||||
@@ -92,8 +92,8 @@ static bool detectMutter(FFstrbuf* themeOrError)
|
||||
|
||||
static bool detectMuffin(FFstrbuf* themeOrError)
|
||||
{
|
||||
FF_AUTO_FREE const char* name = ffSettingsGet("/org/cinnamon/theme/name", "org.cinnamon.theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
FF_AUTO_FREE const char* theme = ffSettingsGet("/org/cinnamon/desktop/wm/preferences/theme", "org.cinnamon.desktop.wm.preferences", NULL, "theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
FF_AUTO_FREE const char* name = ffSettingsGetGnome("/org/cinnamon/theme/name", "org.cinnamon.theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue;
|
||||
FF_AUTO_FREE const char* theme = ffSettingsGetGnome("/org/cinnamon/desktop/wm/preferences/theme", "org.cinnamon.desktop.wm.preferences", NULL, "theme", FF_VARIANT_TYPE_STRING).strValue;
|
||||
|
||||
if(name == NULL && theme == NULL)
|
||||
{
|
||||
@@ -135,9 +135,9 @@ static bool detectOpenbox(const FFstrbuf* dePrettyName, FFstrbuf* themeOrError)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(64);
|
||||
const char *configFileSubpath = "openbox/rc.xml";
|
||||
if (ffStrbufIgnCaseCompS(dePrettyName, "LXQt") == 0)
|
||||
if (ffStrbufIgnCaseEqualS(dePrettyName, "LXQt"))
|
||||
configFileSubpath = "openbox/lxqt-rc.xml";
|
||||
else if (ffStrbufIgnCaseCompS(dePrettyName, "LXDE") == 0)
|
||||
else if (ffStrbufIgnCaseEqualS(dePrettyName, "LXDE"))
|
||||
configFileSubpath = "openbox/lxde-rc.xml";
|
||||
|
||||
if (!ffSearchUserConfigFile(&instance.state.platform.configDirs, configFileSubpath, &absolutePath))
|
||||
@@ -197,16 +197,19 @@ bool ffDetectWmTheme(FFstrbuf* themeOrError)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_KWIN) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_KWIN))
|
||||
return detectWMThemeFromConfigFile("kwinrc", "theme =", "Breeze", themeOrError);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_XFWM4) == 0)
|
||||
if(
|
||||
ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_XFWM4) ||
|
||||
(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, "labwc") && ffStrbufIgnCaseEqualS(&wm->dePrettyName, FF_DE_PRETTY_XFCE4))
|
||||
)
|
||||
return detectXFWM4(themeOrError);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MUTTER) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_MUTTER))
|
||||
{
|
||||
if(
|
||||
ffStrbufIgnCaseCompS(&wm->dePrettyName, FF_DE_PRETTY_GNOME) == 0 ||
|
||||
ffStrbufIgnCaseEqualS(&wm->dePrettyName, FF_DE_PRETTY_GNOME) ||
|
||||
ffStrbufIgnCaseEqualS(&wm->dePrettyName, FF_DE_PRETTY_GNOME_CLASSIC)
|
||||
)
|
||||
return detectMutter(themeOrError);
|
||||
@@ -214,13 +217,13 @@ bool ffDetectWmTheme(FFstrbuf* themeOrError)
|
||||
return detectGTKThemeAsWMTheme(themeOrError);
|
||||
}
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MUFFIN) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_MUFFIN))
|
||||
return detectMuffin(themeOrError);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_MARCO) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_MARCO))
|
||||
return detectWMThemeFromSettings("/org/mate/Marco/general/theme", "org.mate.Marco.general", NULL, "theme", themeOrError);
|
||||
|
||||
if(ffStrbufIgnCaseCompS(&wm->wmPrettyName, FF_WM_PRETTY_OPENBOX) == 0)
|
||||
if(ffStrbufIgnCaseEqualS(&wm->wmPrettyName, FF_WM_PRETTY_OPENBOX))
|
||||
return detectOpenbox(&wm->dePrettyName, themeOrError);
|
||||
|
||||
ffStrbufAppendS(themeOrError, "Unknown WM: ");
|
||||
|
||||
+2
-1
@@ -681,7 +681,8 @@ static void parseOption(FFdata* data, const char* key, const char* value)
|
||||
else if(
|
||||
ffOptionsParseGeneralCommandLine(&instance.config.general, key, value) ||
|
||||
ffOptionsParseLogoCommandLine(&instance.config.logo, key, value) ||
|
||||
ffOptionsParseDisplayCommandLine(&instance.config.display, key, value)
|
||||
ffOptionsParseDisplayCommandLine(&instance.config.display, key, value) ||
|
||||
ffParseModuleOptions(key, value)
|
||||
) {}
|
||||
|
||||
else
|
||||
|
||||
+2
-2
@@ -114,7 +114,7 @@ static bool ffLogoPrintCharsRaw(const char* data, size_t length, bool printError
|
||||
static uint32_t logoAppendChars(const char* data, bool doColorReplacement, FFstrbuf* result)
|
||||
{
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
uint32_t currentlineLength = options->width;
|
||||
uint32_t currentlineLength = options->type == FF_LOGO_TYPE_IMAGE_CHAFA ? 0 : options->width; // For chafa, unit of options->width is pixels
|
||||
uint32_t logoHeight = 0;
|
||||
|
||||
if (result)
|
||||
@@ -260,7 +260,7 @@ static uint32_t logoAppendChars(const char* data, bool doColorReplacement, FFstr
|
||||
if(currentlineLength > instance.state.logoWidth)
|
||||
instance.state.logoWidth = currentlineLength;
|
||||
|
||||
return options->height > logoHeight ? options->height : logoHeight;
|
||||
return options->type != FF_LOGO_TYPE_IMAGE_CHAFA && options->height > logoHeight ? options->height : logoHeight;
|
||||
}
|
||||
|
||||
void ffLogoPrintChars(const char* data, bool doColorReplacement)
|
||||
|
||||
@@ -27,9 +27,9 @@ static void printBtrfs(FFBtrfsOptions* options, FFBtrfsResult* result, uint8_t i
|
||||
}
|
||||
|
||||
uint64_t used = 0, allocated = 0, total = result->totalSize;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(result->allocation); ++i)
|
||||
{
|
||||
uint64_t times = result->allocation[i].dup ? 2 : 1;
|
||||
uint64_t times = result->allocation[i].copies;
|
||||
used += result->allocation[i].used * times;
|
||||
allocated += result->allocation[i].total * times;
|
||||
}
|
||||
@@ -180,11 +180,12 @@ bool ffGenerateBtrfsJsonResult(FF_MAYBE_UNUSED FFBtrfsOptions* options, yyjson_m
|
||||
yyjson_mut_obj_add_uint(doc, obj, "sectorSize", btrfs->sectorSize);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "totalSize", btrfs->totalSize);
|
||||
yyjson_mut_val* allocation = yyjson_mut_obj_add_arr(doc, obj, "allocation");
|
||||
for (int i = 0; i < 3; ++i)
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(btrfs->allocation); ++i)
|
||||
{
|
||||
yyjson_mut_val* item = yyjson_mut_arr_add_obj(doc, allocation);
|
||||
yyjson_mut_obj_add_str(doc, item, "type", btrfs->allocation[i].type);
|
||||
yyjson_mut_obj_add_bool(doc, item, "dup", btrfs->allocation[i].dup);
|
||||
yyjson_mut_obj_add_str(doc, item, "profile", btrfs->allocation[i].profile);
|
||||
yyjson_mut_obj_add_uint(doc, item, "copies", btrfs->allocation[i].copies);
|
||||
yyjson_mut_obj_add_uint(doc, item, "used", btrfs->allocation[i].used);
|
||||
yyjson_mut_obj_add_uint(doc, item, "total", btrfs->allocation[i].total);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ bool ffPrintDisplay(FFDisplayOptions* options)
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
double inch = sqrt(result->physicalWidth * result->physicalWidth + result->physicalHeight * result->physicalHeight) / 25.4;
|
||||
double scaleFactor = (double) result->height / (double) result->scaledHeight;
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
@@ -108,23 +109,28 @@ bool ffPrintDisplay(FFDisplayOptions* options)
|
||||
|
||||
ffStrbufAppendF(&buffer, "%ix%i", result->width, result->height);
|
||||
|
||||
if(result->refreshRate > 0)
|
||||
{
|
||||
const char* space = instance.config.display.freqSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_NEVER ? "" : " ";
|
||||
if(options->preciseRefreshRate)
|
||||
ffStrbufAppendF(&buffer, " @ %g%sHz", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0, space);
|
||||
else
|
||||
ffStrbufAppendF(&buffer, " @ %i%sHz", (uint32_t) (result->refreshRate + 0.5), space);
|
||||
}
|
||||
|
||||
if(
|
||||
result->scaledWidth > 0 && result->scaledWidth != result->width &&
|
||||
result->scaledHeight > 0 && result->scaledHeight != result->height)
|
||||
ffStrbufAppendF(&buffer, " (as %ix%i)", result->scaledWidth, result->scaledHeight);
|
||||
{
|
||||
ffStrbufAppendS(&buffer, " @ ");
|
||||
ffStrbufAppendDouble(&buffer, scaleFactor, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros == FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS);
|
||||
ffStrbufAppendC(&buffer, 'x');
|
||||
}
|
||||
|
||||
if (inch > 1)
|
||||
ffStrbufAppendF(&buffer, " in %i\"", (uint32_t) (inch + 0.5));
|
||||
|
||||
if(result->refreshRate > 0)
|
||||
{
|
||||
ffStrbufAppendS(&buffer, ", ");
|
||||
if(options->preciseRefreshRate)
|
||||
ffStrbufAppendDouble(&buffer, result->refreshRate, 3, false);
|
||||
else
|
||||
ffStrbufAppendSInt(&buffer, (int) (result->refreshRate + 0.5));
|
||||
ffStrbufAppendS(&buffer, instance.config.display.freqSpaceBeforeUnit == FF_SPACE_BEFORE_UNIT_NEVER ? "Hz" : " Hz");
|
||||
}
|
||||
|
||||
bool flag = false;
|
||||
if (result->type != FF_DISPLAY_TYPE_UNKNOWN)
|
||||
{
|
||||
@@ -185,8 +191,6 @@ bool ffPrintDisplay(FFDisplayOptions* options)
|
||||
else
|
||||
buf[0] = '\0';
|
||||
|
||||
double scaleFactor = (double) result->height / (double) result->scaledHeight;
|
||||
|
||||
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]) {
|
||||
FF_FORMAT_ARG(result->width, "width"),
|
||||
FF_FORMAT_ARG(result->height, "height"),
|
||||
|
||||
@@ -37,17 +37,13 @@ static void appendSpeed(FFLocalIpResult* ip, FFstrbuf* strbuf)
|
||||
{
|
||||
if (ip->speed >= 1000000)
|
||||
{
|
||||
if (instance.config.display.fractionNdigits >= 0)
|
||||
ffStrbufAppendF(strbuf, "%.*f Tbps", instance.config.display.fractionNdigits, ip->speed / 1000000.0);
|
||||
else
|
||||
ffStrbufAppendF(strbuf, "%g Tbps", ip->speed / 1000000.0);
|
||||
ffStrbufAppendDouble(strbuf, ip->speed / 1e6, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros == FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS);
|
||||
ffStrbufAppendS(strbuf, " Tbps");
|
||||
}
|
||||
else if (ip->speed >= 1000)
|
||||
{
|
||||
if (instance.config.display.fractionNdigits >= 0)
|
||||
ffStrbufAppendF(strbuf, "%.*f Gbps", instance.config.display.fractionNdigits, ip->speed / 1000.0);
|
||||
else
|
||||
ffStrbufAppendF(strbuf, "%g Gbps", ip->speed / 1000.0);
|
||||
ffStrbufAppendDouble(strbuf, ip->speed / 1e3, instance.config.display.fractionNdigits, instance.config.display.fractionTrailingZeros == FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS);
|
||||
ffStrbufAppendS(strbuf, " Gbps");
|
||||
}
|
||||
else
|
||||
ffStrbufAppendF(strbuf, "%u Mbps", (unsigned) ip->speed);
|
||||
|
||||
+79
-8
@@ -136,7 +136,15 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
}
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->sizeNdigits = (uint8_t) yyjson_get_uint(ndigits);
|
||||
if (ndigits)
|
||||
{
|
||||
if (!yyjson_is_uint(ndigits))
|
||||
return "display.size.ndigits must be an unsigned integer";
|
||||
uint64_t val = yyjson_get_uint(ndigits);
|
||||
if (val > 9)
|
||||
return "display.size.ndigits must be between 0 and 9";
|
||||
options->sizeNdigits = (uint8_t) val;
|
||||
}
|
||||
|
||||
yyjson_val* spaceBeforeUnit = yyjson_obj_get(val, "spaceBeforeUnit");
|
||||
if (spaceBeforeUnit)
|
||||
@@ -177,7 +185,15 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
}
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->tempNdigits = (uint8_t) yyjson_get_uint(ndigits);
|
||||
if (ndigits)
|
||||
{
|
||||
if (!yyjson_is_uint(ndigits))
|
||||
return "display.temperature.ndigits must be an unsigned integer";
|
||||
uint64_t val = yyjson_get_uint(ndigits);
|
||||
if (val > 9)
|
||||
return "display.temperature.ndigits must be between 0 and 9";
|
||||
options->tempNdigits = (uint8_t) val;
|
||||
}
|
||||
|
||||
yyjson_val* color = yyjson_obj_get(val, "color");
|
||||
if (color)
|
||||
@@ -222,7 +238,15 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
}
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->percentNdigits = (uint8_t) yyjson_get_uint(ndigits);
|
||||
if (ndigits)
|
||||
{
|
||||
if (!yyjson_is_uint(ndigits))
|
||||
return "display.percent.ndigits must be an unsigned integer";
|
||||
uint64_t val = yyjson_get_uint(ndigits);
|
||||
if (val > 9)
|
||||
return "display.percent.ndigits must be between 0 and 9";
|
||||
options->percentNdigits = (uint8_t) val;
|
||||
}
|
||||
|
||||
yyjson_val* color = yyjson_obj_get(val, "color");
|
||||
if (color)
|
||||
@@ -376,9 +400,33 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
{
|
||||
if (yyjson_is_null(ndigits))
|
||||
options->fractionNdigits = -1;
|
||||
else if (!yyjson_is_int(ndigits))
|
||||
return "display.fraction.ndigits must be an integer";
|
||||
options->fractionNdigits = (int8_t) yyjson_get_int(ndigits);
|
||||
else
|
||||
{
|
||||
if (!yyjson_is_int(ndigits))
|
||||
return "display.fraction.ndigits must be an integer";
|
||||
int64_t val = yyjson_get_int(ndigits);
|
||||
if (val < -1 || val > 9)
|
||||
return "display.fraction.ndigits must be between -1 and 9";
|
||||
options->fractionNdigits = (int8_t) val;
|
||||
}
|
||||
}
|
||||
yyjson_val* trailingZeros = yyjson_obj_get(val, "trailingZeros");
|
||||
if (trailingZeros)
|
||||
{
|
||||
if (yyjson_is_null(trailingZeros))
|
||||
options->fractionTrailingZeros = FF_FRACTION_TRAILING_ZEROS_TYPE_DEFAULT;
|
||||
else
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(trailingZeros, &value, (FFKeyValuePair[]) {
|
||||
{ "default", FF_FRACTION_TRAILING_ZEROS_TYPE_DEFAULT },
|
||||
{ "always", FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS },
|
||||
{ "never", FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER },
|
||||
{},
|
||||
});
|
||||
if (error) return error;
|
||||
options->fractionTrailingZeros = (FFFractionTrailingZerosType) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -431,7 +479,20 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va
|
||||
return "display.freq must be an object";
|
||||
|
||||
yyjson_val* ndigits = yyjson_obj_get(val, "ndigits");
|
||||
if (ndigits) options->freqNdigits = (int8_t) yyjson_get_int(ndigits);
|
||||
if (ndigits)
|
||||
{
|
||||
if (yyjson_is_null(ndigits))
|
||||
options->freqNdigits = -1;
|
||||
else
|
||||
{
|
||||
if (!yyjson_is_int(ndigits))
|
||||
return "display.freq.ndigits must be an integer";
|
||||
int64_t val = yyjson_get_int(ndigits);
|
||||
if (val < -1 || val > 9)
|
||||
return "display.freq.ndigits must be between -1 and 9";
|
||||
options->freqNdigits = (int8_t) val;
|
||||
}
|
||||
}
|
||||
|
||||
yyjson_val* spaceBeforeUnit = yyjson_obj_get(val, "spaceBeforeUnit");
|
||||
if (spaceBeforeUnit)
|
||||
@@ -690,6 +751,15 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "--fraction-ndigits"))
|
||||
options->fractionNdigits = (int8_t) ffOptionParseInt32(key, value);
|
||||
else if(ffStrEqualsIgnCase(key, "--fraction-trailing-zeros"))
|
||||
{
|
||||
options->fractionTrailingZeros = (FFFractionTrailingZerosType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "default", FF_FRACTION_TRAILING_ZEROS_TYPE_DEFAULT },
|
||||
{ "always", FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS },
|
||||
{ "never", FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER },
|
||||
{},
|
||||
});
|
||||
}
|
||||
else if(ffStrEqualsIgnCase(key, "--no-buffer"))
|
||||
options->noBuffer = ffOptionParseBoolean(value);
|
||||
else if(ffStrStartsWithIgnCase(key, "--bar-"))
|
||||
@@ -809,7 +879,8 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options)
|
||||
|
||||
options->freqNdigits = 2;
|
||||
options->freqSpaceBeforeUnit = FF_SPACE_BEFORE_UNIT_DEFAULT;
|
||||
options->fractionNdigits = -1;
|
||||
options->fractionNdigits = 2;
|
||||
options->fractionTrailingZeros = FF_FRACTION_TRAILING_ZEROS_TYPE_DEFAULT;
|
||||
|
||||
ffListInit(&options->constants, sizeof(FFstrbuf));
|
||||
}
|
||||
|
||||
@@ -25,6 +25,13 @@ typedef enum __attribute__((__packed__)) FFSpaceBeforeUnitType
|
||||
FF_SPACE_BEFORE_UNIT_NEVER,
|
||||
} FFSpaceBeforeUnitType;
|
||||
|
||||
typedef enum __attribute__((__packed__)) FFFractionTrailingZerosType
|
||||
{
|
||||
FF_FRACTION_TRAILING_ZEROS_TYPE_DEFAULT,
|
||||
FF_FRACTION_TRAILING_ZEROS_TYPE_ALWAYS,
|
||||
FF_FRACTION_TRAILING_ZEROS_TYPE_NEVER,
|
||||
} FFFractionTrailingZerosType;
|
||||
|
||||
typedef struct FFOptionsDisplay
|
||||
{
|
||||
//If one of those is empty, ffLogoPrint will set them
|
||||
@@ -81,6 +88,7 @@ typedef struct FFOptionsDisplay
|
||||
int8_t freqNdigits;
|
||||
FFSpaceBeforeUnitType freqSpaceBeforeUnit;
|
||||
int8_t fractionNdigits;
|
||||
FFFractionTrailingZerosType fractionTrailingZeros;
|
||||
|
||||
FFlist constants; // list of FFstrbuf
|
||||
} FFOptionsDisplay;
|
||||
|
||||
+21
-10
@@ -571,7 +571,7 @@ void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value)
|
||||
strbuf->length += (uint32_t)(end - start);
|
||||
}
|
||||
|
||||
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision)
|
||||
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros)
|
||||
{
|
||||
assert(precision <= 15); // yyjson_write_number supports up to 15 digits after the decimal point
|
||||
|
||||
@@ -598,18 +598,29 @@ void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision)
|
||||
return;
|
||||
}
|
||||
|
||||
if (precision > 1)
|
||||
if (trailingZeros)
|
||||
{
|
||||
for (char* p = end - 1; *p != '.' && p > start; --p)
|
||||
--precision;
|
||||
if (precision > 0)
|
||||
ffStrbufAppendNC(strbuf, (uint32_t) precision, '0');
|
||||
if (precision > 1)
|
||||
{
|
||||
for (char* p = end - 1; *p != '.' && p > start; --p)
|
||||
--precision;
|
||||
if (precision > 0)
|
||||
ffStrbufAppendNC(strbuf, (uint32_t) precision, '0');
|
||||
}
|
||||
else if (precision == 0 || (precision < 0 && end[-1] == '0'))
|
||||
{
|
||||
goto removeDecimalPoint;
|
||||
}
|
||||
}
|
||||
else if (precision == 0 || (precision < 0 && end[-1] == '0'))
|
||||
else
|
||||
{
|
||||
// yyjson always appends ".0", so we need to remove it
|
||||
strbuf->length -= 2;
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
if (end[-1] == '0')
|
||||
{
|
||||
removeDecimalPoint:
|
||||
// yyjson always appends ".0" to make it a float point number. We need to remove it
|
||||
strbuf->length -= 2;
|
||||
strbuf->chars[strbuf->length] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ void ffStrbufAppendSInt(FFstrbuf* strbuf, int64_t value);
|
||||
void ffStrbufAppendUInt(FFstrbuf* strbuf, uint64_t value);
|
||||
// Appends a double value to the string buffer with the specified precision (0~15).
|
||||
// if `precision < 0`, let yyjson decide the precision
|
||||
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision);
|
||||
void ffStrbufAppendDouble(FFstrbuf* strbuf, double value, int8_t precision, bool trailingZeros);
|
||||
|
||||
FF_C_NODISCARD static inline FFstrbuf ffStrbufCreateA(uint32_t allocate)
|
||||
{
|
||||
|
||||
+143
-28
@@ -744,115 +744,230 @@ int main(void)
|
||||
}
|
||||
|
||||
{
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 0);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 1);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 5);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.00000"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 5);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.12346"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.888888, 0);
|
||||
ffStrbufAppendDouble(&strbuf, 120.888888, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.999999, 2);
|
||||
ffStrbufAppendDouble(&strbuf, 120.999999, 2, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "121.00"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 0);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, -1);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, -1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.123456789"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123, 5);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.12300"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 0);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 1);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 5);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.00000"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 5);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.12346"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 0);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, -1);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, -1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.123456789"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123, 5);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123, 5, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.12300"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.888888, 0);
|
||||
ffStrbufAppendDouble(&strbuf, -120.888888, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.999999, 2);
|
||||
ffStrbufAppendDouble(&strbuf, -120.999999, 2, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-121.00"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 1);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 1);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 0);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 0);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, -1);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, -1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, -1);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, -1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e20, 1);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e20, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "123450000000000000000.0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e20, 1);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e20, 1, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-123450000000000000000.0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, +0.0, 0);
|
||||
ffStrbufAppendDouble(&strbuf, +0.0, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -0.0, 0);
|
||||
ffStrbufAppendDouble(&strbuf, -0.0, 0, true);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-0"));
|
||||
|
||||
ffStrbufDestroy(&strbuf);
|
||||
}
|
||||
|
||||
{
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.0, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.12346"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.888888, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.999999, 2, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123456789, -1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.123456789"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 120.123, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "120.123"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.0, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.12346"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123456789, -1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.123456789"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.123, 5, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-120.123"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.888888, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -120.999999, 2, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-121"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e50, -1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e50, -1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-1.2345e50"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, 1.2345e20, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "123450000000000000000"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -1.2345e20, 1, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-123450000000000000000"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, +0.0, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "0"));
|
||||
|
||||
ffStrbufClear(&strbuf);
|
||||
ffStrbufAppendDouble(&strbuf, -0.0, 0, false);
|
||||
VERIFY(ffStrbufEqualS(&strbuf, "-0"));
|
||||
|
||||
ffStrbufDestroy(&strbuf);
|
||||
|
||||
Reference in New Issue
Block a user