From 02f3789eaa44d910c3c56e1f28cfc105e7e85754 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 4 Jul 2024 10:24:10 +0800 Subject: [PATCH 01/41] Packaging: update debian stuff [ci skip] --- debian/changelog | 6 ++++++ debian/files | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 8040d8ed2e..c2f63e90d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.17.2) jammy; urgency=medium + + * Update to 2.17.2 + + -- Carter Li Thu, 04 Jul 2024 10:22:44 +0800 + fastfetch (2.17.1) jammy; urgency=medium * Update to 2.17.1 diff --git a/debian/files b/debian/files index 1080958808..abd2babea3 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.17.1_source.buildinfo universe/utils optional +fastfetch_2.17.2_source.buildinfo universe/utils optional From 0ae1bd57bd647dbc44d3d62a96652b609a5a15b3 Mon Sep 17 00:00:00 2001 From: Dennis ten Hoove <36002865+dennis1248@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:58:16 +0200 Subject: [PATCH 02/41] Add Arkane Linux logo (#1071) --- src/logo/ascii/arkane.txt | 23 +++++++++++++++++++++++ src/logo/builtin.c | 12 ++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/logo/ascii/arkane.txt diff --git a/src/logo/ascii/arkane.txt b/src/logo/ascii/arkane.txt new file mode 100644 index 0000000000..f4bae21258 --- /dev/null +++ b/src/logo/ascii/arkane.txt @@ -0,0 +1,23 @@ + .:.. + ..:::...... + $2.$1 .$2.$1..... + $2+=$1...$1==$1.... + ......:.$3:-$2:$1..$3+*$2=$1.... + $2:----::$1...... + $2.=***##*+=: $1.. + $2=$3***######*$2= + $2.$3-*######+ + $2:+$3###%%%###$1: + $2-+*$3########+$1. + $2=++*$3#######$1- + $2-+=+**$3*####$1= + $1.$2-=++==***$3##*$1- + $2-++++++==++++= + .-+++**+++=+===$1. +$2:---===++++=-=--$1. +$2-===============$1-==--: +$2.-==+++***++*$3*#########$1=:::. + $2.-=++++*++++**$3#######%%###$1= + $2.:==++++++**$3#############$1: + $2.$1-+*++*+++==$3###$1+ + -$3*+$1: diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 067d772ad0..e6bf168ea5 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -381,6 +381,18 @@ static const FFlogo A[] = { .colorKeys = FF_COLOR_FG_CYAN, .colorTitle = FF_COLOR_FG_CYAN, }, + // Arkane + { + .names = {"Arkane", "Arkane Linux"}, + .lines = FASTFETCH_DATATEXT_LOGO_ARKANE, + .colors = { + FF_COLOR_FG_256 "237", + FF_COLOR_FG_256 "130", + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_256 "130", + .colorTitle = FF_COLOR_FG_WHITE, + }, // Armbian { .names = {"Armbian"}, From 4dc0bd583c7d2c0cb1f73c98e549ab1ef90e8b07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 4 Jul 2024 21:21:26 +0800 Subject: [PATCH 03/41] Logo (Builtin): add Opak Fix #1070 --- src/logo/ascii/opak.txt | 13 +++++++++++++ src/logo/builtin.c | 6 ++++++ 2 files changed, 19 insertions(+) create mode 100644 src/logo/ascii/opak.txt diff --git a/src/logo/ascii/opak.txt b/src/logo/ascii/opak.txt new file mode 100644 index 0000000000..c095f50c1c --- /dev/null +++ b/src/logo/ascii/opak.txt @@ -0,0 +1,13 @@ + .':ldkOOOOkxo:,. + .:d0KKXXXXXXXXXXKkl, + .;xOOO0000KKKKXXXXXXX0l. + .cxxxkkkkOOO0000KKKKXXXXx' + ;ool;,,,,;coxkOOOO0000KKKd. +.clc'.........:oxkkkkOOOO0O, +.ccc:ccclc:,....,:oddxxdxkO; + cllllccccccc;'........'lxx. + 'ooooolllllccc:;,''',,coo, + ,ddddooooollllllccccccl' + cxxxdddddooooollllc; + ,dxxxxxddddddol. + .';::,. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index e6bf168ea5..c7f33adc03 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2957,6 +2957,12 @@ static const FFlogo O[] = { FF_COLOR_FG_LIGHT_BLACK, } }, + // Opak + { + .names = {"Opak"}, + .lines = FASTFETCH_DATATEXT_LOGO_OPAK, + .colors = {}, // #1070 + }, // OpenKylin { .names = {"openkylin", "open-kylin"}, From 313bb02188fd626dee0eaf673bab3cfe6259492b Mon Sep 17 00:00:00 2001 From: Dennis ten Hoove <36002865+dennis1248@users.noreply.github.com> Date: Thu, 4 Jul 2024 18:14:13 +0200 Subject: [PATCH 04/41] Fix Arkane Linux color code (#1072) --- src/logo/ascii/arkane.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/ascii/arkane.txt b/src/logo/ascii/arkane.txt index f4bae21258..34894053dc 100644 --- a/src/logo/ascii/arkane.txt +++ b/src/logo/ascii/arkane.txt @@ -1,7 +1,7 @@ .:.. ..:::...... $2.$1 .$2.$1..... - $2+=$1...$1==$1.... + $2+=$1...$2==$1.... ......:.$3:-$2:$1..$3+*$2=$1.... $2:----::$1...... $2.=***##*+=: $1.. From f89485640790428990374cae8f7d15c0482e5546 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 5 Jul 2024 10:16:25 +0800 Subject: [PATCH 05/41] Disk: update module description --- src/modules/disk/disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 0f225be2ed..48b494efed 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -448,7 +448,7 @@ void ffInitDiskOptions(FFDiskOptions* options) ffOptionInitModuleBaseInfo( &options->moduleInfo, FF_DISK_MODULE_NAME, - "Print partitions, space usage, disk type, etc", + "Print partitions, space usage, file system, etc", ffParseDiskCommandOptions, ffParseDiskJsonObject, ffPrintDisk, From c5fdcc5cfcbd4e38591f7728c5ee85e3053f0641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 5 Jul 2024 02:40:15 +0000 Subject: [PATCH 06/41] PhysicalDisk (Linux): detect revision of USB devices --- src/detection/physicaldisk/physicaldisk_linux.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c index f654017caf..b5a3bbc2a7 100644 --- a/src/detection/physicaldisk/physicaldisk_linux.c +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -149,6 +149,12 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/firmware_rev", devName); if (ffReadFileBuffer(pathSysBlock, &device->revision)) ffStrbufTrimRightSpace(&device->revision); + else + { + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/rev", devName); + if (ffReadFileBuffer(pathSysBlock, &device->revision)) + ffStrbufTrimRightSpace(&device->revision); + } } device->temperature = FF_PHYSICALDISK_TEMP_UNSET; From 3415d8197cdedfaced9aab43e5e5ee0bc02a94a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 4 Jul 2024 13:49:18 +0800 Subject: [PATCH 07/41] PhysicalMemory: don't print `(null)` in property `locator` --- src/detection/physicalmemory/physicalmemory_linux.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/detection/physicalmemory/physicalmemory_linux.c b/src/detection/physicalmemory/physicalmemory_linux.c index a1f0de70d1..1eb971e8ba 100644 --- a/src/detection/physicalmemory/physicalmemory_linux.c +++ b/src/detection/physicalmemory/physicalmemory_linux.c @@ -113,7 +113,15 @@ const char* ffDetectPhysicalMemory(FFlist* result) } } - ffStrbufSetF(&device->locator, "%s/%s", ffSmbiosLocateString(strings, data->BankLocator), ffSmbiosLocateString(strings, data->DeviceLocator)); + // https://github.com/fastfetch-cli/fastfetch/issues/1051#issuecomment-2206687345 + const char* lbank = ffSmbiosLocateString(strings, data->BankLocator); + const char* ldevice = ffSmbiosLocateString(strings, data->DeviceLocator); + if (lbank && ldevice) + ffStrbufSetF(&device->locator, "%s/%s", lbank, ldevice); + else if (lbank) + ffStrbufSetS(&device->locator, lbank); + else if (ldevice) + ffStrbufSetS(&device->locator, ldevice); switch (data->FormFactor) { From 013320bcde675f7119e9c1d28e2b4791ea06bb12 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 5 Jul 2024 16:14:56 +0800 Subject: [PATCH 08/41] Display (Wayland): support fractional scale for KDE --- CMakeLists.txt | 7 + .../kde-output-device-v2-client-protocol.h | 845 ++++++++++++++++++ .../wayland/kde-output-device-v2-protocol.c | 81 ++ .../displayserver/linux/wayland/kde-output.c | 225 +++++ .../displayserver/linux/wayland/wayland.c | 9 +- .../displayserver/linux/wayland/wayland.h | 2 + src/logo/image/image.c | 47 +- src/util/base64.c | 115 +++ src/util/base64.h | 23 + 9 files changed, 1309 insertions(+), 45 deletions(-) create mode 100644 src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h create mode 100644 src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c create mode 100644 src/detection/displayserver/linux/wayland/kde-output.c create mode 100644 src/util/base64.c create mode 100644 src/util/base64.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e22b7edb31..52407a14bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -395,6 +395,7 @@ set(LIBFASTFETCH_SRC src/options/general.c src/options/library.c src/util/edidHelper.c + src/util/base64.c src/util/FFlist.c src/util/FFstrbuf.c src/util/platform/FFPlatform.c @@ -429,7 +430,9 @@ if(LINUX) src/detection/displayserver/linux/wayland/wayland.c src/detection/displayserver/linux/wayland/global-output.c src/detection/displayserver/linux/wayland/zwlr-output.c + src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c + src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -562,7 +565,9 @@ elseif(BSD) src/detection/displayserver/linux/wayland/wayland.c src/detection/displayserver/linux/wayland/global-output.c src/detection/displayserver/linux/wayland/zwlr-output.c + src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c + src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -763,7 +768,9 @@ elseif(SunOS) src/detection/displayserver/linux/wayland/wayland.c src/detection/displayserver/linux/wayland/global-output.c src/detection/displayserver/linux/wayland/zwlr-output.c + src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c + src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c diff --git a/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h b/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h new file mode 100644 index 0000000000..605f41e39e --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h @@ -0,0 +1,845 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H +#define KDE_OUTPUT_DEVICE_V2_CLIENT_PROTOCOL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_kde_output_device_v2 The kde_output_device_v2 protocol + * @section page_ifaces_kde_output_device_v2 Interfaces + * - @subpage page_iface_kde_output_device_v2 - output configuration representation + * - @subpage page_iface_kde_output_device_mode_v2 - output mode + * @section page_copyright_kde_output_device_v2 Copyright + *
+ *
+ * SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
+ * SPDX-FileCopyrightText: 2010-2011 Intel Corporation
+ * SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd.
+ * SPDX-FileCopyrightText: 2015 Sebastian Kügler 
+ * SPDX-FileCopyrightText: 2021 Méven Car 
+ *
+ * SPDX-License-Identifier: MIT-CMU
+ * 
+ */ +struct kde_output_device_mode_v2; +struct kde_output_device_v2; + +#ifndef KDE_OUTPUT_DEVICE_V2_INTERFACE +#define KDE_OUTPUT_DEVICE_V2_INTERFACE +/** + * @page page_iface_kde_output_device_v2 kde_output_device_v2 + * @section page_iface_kde_output_device_v2_desc Description + * + * An output device describes a display device available to the compositor. + * output_device is similar to wl_output, but focuses on output + * configuration management. + * + * A client can query all global output_device objects to enlist all + * available display devices, even those that may currently not be + * represented by the compositor as a wl_output. + * + * The client sends configuration changes to the server through the + * outputconfiguration interface, and the server applies the configuration + * changes to the hardware and signals changes to the output devices + * accordingly. + * + * This object is published as global during start up for every available + * display devices, or when one later becomes available, for example by + * being hotplugged via a physical connector. + * @section page_iface_kde_output_device_v2_api API + * See @ref iface_kde_output_device_v2. + */ +/** + * @defgroup iface_kde_output_device_v2 The kde_output_device_v2 interface + * + * An output device describes a display device available to the compositor. + * output_device is similar to wl_output, but focuses on output + * configuration management. + * + * A client can query all global output_device objects to enlist all + * available display devices, even those that may currently not be + * represented by the compositor as a wl_output. + * + * The client sends configuration changes to the server through the + * outputconfiguration interface, and the server applies the configuration + * changes to the hardware and signals changes to the output devices + * accordingly. + * + * This object is published as global during start up for every available + * display devices, or when one later becomes available, for example by + * being hotplugged via a physical connector. + */ +extern const struct wl_interface kde_output_device_v2_interface; +#endif +#ifndef KDE_OUTPUT_DEVICE_MODE_V2_INTERFACE +#define KDE_OUTPUT_DEVICE_MODE_V2_INTERFACE +/** + * @page page_iface_kde_output_device_mode_v2 kde_output_device_mode_v2 + * @section page_iface_kde_output_device_mode_v2_desc Description + * + * This object describes an output mode. + * + * Some heads don't support output modes, in which case modes won't be + * advertised. + * + * Properties sent via this interface are applied atomically via the + * kde_output_device.done event. No guarantees are made regarding the order + * in which properties are sent. + * @section page_iface_kde_output_device_mode_v2_api API + * See @ref iface_kde_output_device_mode_v2. + */ +/** + * @defgroup iface_kde_output_device_mode_v2 The kde_output_device_mode_v2 interface + * + * This object describes an output mode. + * + * Some heads don't support output modes, in which case modes won't be + * advertised. + * + * Properties sent via this interface are applied atomically via the + * kde_output_device.done event. No guarantees are made regarding the order + * in which properties are sent. + */ +extern const struct wl_interface kde_output_device_mode_v2_interface; +#endif + +#ifndef KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM +#define KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * subpixel geometry information + * + * This enumeration describes how the physical pixels on an output are + * laid out. + */ +enum kde_output_device_v2_subpixel { + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_UNKNOWN = 0, + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_NONE = 1, + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_HORIZONTAL_RGB = 2, + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_HORIZONTAL_BGR = 3, + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_VERTICAL_RGB = 4, + KDE_OUTPUT_DEVICE_V2_SUBPIXEL_VERTICAL_BGR = 5, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_SUBPIXEL_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM +#define KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * transform from framebuffer to output + * + * This describes the transform, that a compositor will apply to a + * surface to compensate for the rotation or mirroring of an + * output device. + * + * The flipped values correspond to an initial flip around a + * vertical axis followed by rotation. + * + * The purpose is mainly to allow clients to render accordingly and + * tell the compositor, so that for fullscreen surfaces, the + * compositor is still able to scan out directly client surfaces. + */ +enum kde_output_device_v2_transform { + KDE_OUTPUT_DEVICE_V2_TRANSFORM_NORMAL = 0, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_90 = 1, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_180 = 2, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_270 = 3, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED = 4, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_90 = 5, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_180 = 6, + KDE_OUTPUT_DEVICE_V2_TRANSFORM_FLIPPED_270 = 7, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_TRANSFORM_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * describes capabilities of the outputdevice + * + * Describes what capabilities this device has. + */ +enum kde_output_device_v2_capability { + /** + * if this output_device can use overscan + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_OVERSCAN = 0x1, + /** + * if this outputdevice supports variable refresh rate + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_VRR = 0x2, + /** + * if setting the rgb range is possible + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_RGB_RANGE = 0x4, + /** + * if this outputdevice supports high dynamic range + * @since 3 + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_HIGH_DYNAMIC_RANGE = 0x8, + /** + * if this outputdevice supports a wide color gamut + * @since 3 + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_WIDE_COLOR_GAMUT = 0x10, + /** + * if this outputdevice supports autorotation + * @since 4 + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_AUTO_ROTATE = 0x20, + /** + * if this outputdevice supports icc profiles + * @since 5 + */ + KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE = 0x40, +}; +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_HIGH_DYNAMIC_RANGE_SINCE_VERSION 3 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_WIDE_COLOR_GAMUT_SINCE_VERSION 3 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_AUTO_ROTATE_SINCE_VERSION 4 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITY_ICC_PROFILE_SINCE_VERSION 5 +#endif /* KDE_OUTPUT_DEVICE_V2_CAPABILITY_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM +#define KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * describes vrr policy + * + * Describes when the compositor may employ variable refresh rate + */ +enum kde_output_device_v2_vrr_policy { + KDE_OUTPUT_DEVICE_V2_VRR_POLICY_NEVER = 0, + KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ALWAYS = 1, + KDE_OUTPUT_DEVICE_V2_VRR_POLICY_AUTOMATIC = 2, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_VRR_POLICY_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM +#define KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * describes RGB range policy + * + * Whether full or limited color range should be used + */ +enum kde_output_device_v2_rgb_range { + KDE_OUTPUT_DEVICE_V2_RGB_RANGE_AUTOMATIC = 0, + KDE_OUTPUT_DEVICE_V2_RGB_RANGE_FULL = 1, + KDE_OUTPUT_DEVICE_V2_RGB_RANGE_LIMITED = 2, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_RGB_RANGE_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM +#define KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * describes when auto rotate should be used + */ +enum kde_output_device_v2_auto_rotate_policy { + KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_NEVER = 0, + KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_IN_TABLET_MODE = 1, + KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ALWAYS = 2, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_ENUM */ + +#ifndef KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM +#define KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM +/** + * @ingroup iface_kde_output_device_v2 + * which source the compositor should use for the color profile on an output + */ +enum kde_output_device_v2_color_profile_source { + KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_SRGB = 0, + KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ICC = 1, + KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_EDID = 2, +}; +#endif /* KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_ENUM */ + +/** + * @ingroup iface_kde_output_device_v2 + * @struct kde_output_device_v2_listener + */ +struct kde_output_device_v2_listener { + /** + * geometric properties of the output + * + * The geometry event describes geometric properties of the + * output. The event is sent when binding to the output object and + * whenever any of the properties change. + * @param x x position within the global compositor space + * @param y y position within the global compositor space + * @param physical_width width in millimeters of the output + * @param physical_height height in millimeters of the output + * @param subpixel subpixel orientation of the output + * @param make textual description of the manufacturer + * @param model textual description of the model + * @param transform transform that maps framebuffer to output + */ + void (*geometry)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char *make, + const char *model, + int32_t transform); + /** + * current mode + * + * This event describes the mode currently in use for this head. + * It is only sent if the output is enabled. + */ + void (*current_mode)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + struct kde_output_device_mode_v2 *mode); + /** + * advertise available output modes and current one + * + * The mode event describes an available mode for the output. + * + * When the client binds to the output_device object, the server + * sends this event once for every available mode the output_device + * can be operated by. + * + * There will always be at least one event sent out on initial + * binding, which represents the current mode. + * + * Later if an output changes, its mode event is sent again for the + * eventual added modes and lastly the current mode. In other + * words, the current mode is always represented by the latest + * event sent with the current flag set. + * + * The size of a mode is given in physical hardware units of the + * output device. This is not necessarily the same as the output + * size in the global compositor space. For instance, the output + * may be scaled, as described in kde_output_device_v2.scale, or + * transformed, as described in kde_output_device_v2.transform. + */ + void (*mode)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + struct kde_output_device_mode_v2 *mode); + /** + * sent all information about output + * + * This event is sent after all other properties have been sent + * on binding to the output object as well as after any other + * output property change have been applied later on. This allows + * to see changes to the output properties as atomic, even if + * multiple events successively announce them. + */ + void (*done)(void *data, + struct kde_output_device_v2 *kde_output_device_v2); + /** + * output scaling properties + * + * This event contains scaling geometry information that is not + * in the geometry event. It may be sent after binding the output + * object or if the output scale changes later. If it is not sent, + * the client should assume a scale of 1. + * + * A scale larger than 1 means that the compositor will + * automatically scale surface buffers by this amount when + * rendering. This is used for high resolution displays where + * applications rendering at the native resolution would be too + * small to be legible. + * + * It is intended that scaling aware clients track the current + * output of a surface, and if it is on a scaled output it should + * use wl_surface.set_buffer_scale with the scale of the output. + * That way the compositor can avoid scaling the surface, and the + * client can supply a higher detail image. + * @param factor scaling factor of output + */ + void (*scale)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + wl_fixed_t factor); + /** + * advertise EDID data for the output + * + * The edid event encapsulates the EDID data for the + * outputdevice. + * + * The event is sent when binding to the output object. The EDID + * data may be empty, in which case this event is sent anyway. If + * the EDID information is empty, you can fall back to the name et + * al. properties of the outputdevice. + * @param raw base64-encoded EDID string + */ + void (*edid)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *raw); + /** + * output is enabled or disabled + * + * The enabled event notifies whether this output is currently + * enabled and used for displaying content by the server. The event + * is sent when binding to the output object and whenever later on + * an output changes its state by becoming enabled or disabled. + * @param enabled output enabled state + */ + void (*enabled)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + int32_t enabled); + /** + * A unique id for this outputdevice + * + * The uuid can be used to identify the output. It's controlled + * by the server entirely. The server should make sure the uuid is + * persistent across restarts. An empty uuid is considered invalid. + * @param uuid output devices ID + */ + void (*uuid)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *uuid); + /** + * Serial Number + * + * Serial ID of the monitor, sent on startup before the first + * done event. + * @param serialNumber textual representation of serial number + */ + void (*serial_number)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *serialNumber); + /** + * EISA ID + * + * EISA ID of the monitor, sent on startup before the first done + * event. + * @param eisaId textual representation of EISA identifier + */ + void (*eisa_id)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *eisaId); + /** + * capability flags + * + * What capabilities this device has, sent on startup before the + * first done event. + */ + void (*capabilities)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t flags); + /** + * overscan + * + * Overscan value of the monitor in percent, sent on startup + * before the first done event. + * @param overscan amount of overscan of the monitor + */ + void (*overscan)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t overscan); + /** + * Variable Refresh Rate Policy + * + * What policy the compositor will employ regarding its use of + * variable refresh rate. + */ + void (*vrr_policy)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t vrr_policy); + /** + * RGB range + * + * What rgb range the compositor is using for this output + */ + void (*rgb_range)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t rgb_range); + /** + * Output's name + * + * Name of the output, it's useful to cross-reference to an + * zxdg_output_v1 and ultimately QScreen + * @since 2 + */ + void (*name)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *name); + /** + * if HDR is enabled + * + * Whether or not high dynamic range is enabled for this output + * @param hdr_enabled 1 if enabled, 0 if disabled + * @since 3 + */ + void (*high_dynamic_range)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t hdr_enabled); + /** + * the brightness of sdr if hdr is enabled + * + * If high dynamic range is used, this value defines the + * brightness in nits for content that's in standard dynamic range + * format. Note that while the value is in nits, that doesn't + * necessarily translate to the same brightness on the screen. + * @since 3 + */ + void (*sdr_brightness)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t sdr_brightness); + /** + * if WCG is enabled + * + * Whether or not the use of a wide color gamut is enabled for + * this output + * @param wcg_enabled 1 if enabled, 0 if disabled + * @since 3 + */ + void (*wide_color_gamut)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t wcg_enabled); + /** + * describes when auto rotate is used + * + * + * @since 4 + */ + void (*auto_rotate_policy)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t policy); + /** + * describes when auto rotate is used + * + * + * @since 5 + */ + void (*icc_profile_path)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + const char *profile_path); + /** + * metadata about the screen's brightness limits + * + * + * @param max_peak_brightness in nits + * @param max_frame_average_brightness in nits + * @param min_brightness in 0.0001 nits + * @since 6 + */ + void (*brightness_metadata)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t max_peak_brightness, + uint32_t max_frame_average_brightness, + uint32_t min_brightness); + /** + * overrides for the screen's brightness limits + * + * + * @param max_peak_brightness -1 for no override, positive values are the brightness in nits + * @param max_average_brightness -1 for no override, positive values are the brightness in nits + * @param min_brightness -1 for no override, positive values are the brightness in 0.0001 nits + * @since 6 + */ + void (*brightness_overrides)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + int32_t max_peak_brightness, + int32_t max_average_brightness, + int32_t min_brightness); + /** + * describes which gamut is assumed for sRGB applications + * + * This can be used to provide the colors users assume sRGB + * applications should have based on the default experience on many + * modern sRGB screens. + * @param gamut_wideness 0 means rec.709 primaries, 10000 means native primaries + * @since 6 + */ + void (*sdr_gamut_wideness)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t gamut_wideness); + /** + * describes which source the compositor uses for the color profile on an output + * + * + * @since 7 + */ + void (*color_profile_source)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t source); + /** + * brightness multiplier + * + * This is the brightness modifier of the output. It doesn't + * specify any absolute values, but is merely a multiplier on top + * of other brightness values, like sdr_brightness and + * brightness_metadata. 0 is the minimum brightness (not completely + * dark) and 10000 is the maximum brightness. This is currently + * only supported / meaningful while HDR is active. + * @param brightness brightness in 0-10000 + * @since 8 + */ + void (*brightness)(void *data, + struct kde_output_device_v2 *kde_output_device_v2, + uint32_t brightness); +}; + +/** + * @ingroup iface_kde_output_device_v2 + */ +static inline int +kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device_v2, + const struct kde_output_device_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) kde_output_device_v2, + (void (**)(void)) listener, data); +} + +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_GEOMETRY_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CURRENT_MODE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_MODE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_SCALE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_EDID_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_ENABLED_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_UUID_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_SERIAL_NUMBER_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_EISA_ID_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_CAPABILITIES_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_OVERSCAN_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_VRR_POLICY_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_RGB_RANGE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_NAME_SINCE_VERSION 2 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_HIGH_DYNAMIC_RANGE_SINCE_VERSION 3 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_SDR_BRIGHTNESS_SINCE_VERSION 3 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_WIDE_COLOR_GAMUT_SINCE_VERSION 3 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_AUTO_ROTATE_POLICY_SINCE_VERSION 4 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_ICC_PROFILE_PATH_SINCE_VERSION 5 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_METADATA_SINCE_VERSION 6 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_OVERRIDES_SINCE_VERSION 6 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_SDR_GAMUT_WIDENESS_SINCE_VERSION 6 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_COLOR_PROFILE_SOURCE_SINCE_VERSION 7 +/** + * @ingroup iface_kde_output_device_v2 + */ +#define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_SINCE_VERSION 8 + + +/** @ingroup iface_kde_output_device_v2 */ +static inline void +kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data); +} + +/** @ingroup iface_kde_output_device_v2 */ +static inline void * +kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2); +} + +static inline uint32_t +kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2); +} + +/** @ingroup iface_kde_output_device_v2 */ +static inline void +kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2) +{ + wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2); +} + +/** + * @ingroup iface_kde_output_device_mode_v2 + * @struct kde_output_device_mode_v2_listener + */ +struct kde_output_device_mode_v2_listener { + /** + * mode size + * + * This event describes the mode size. The size is given in + * physical hardware units of the output device. This is not + * necessarily the same as the output size in the global compositor + * space. For instance, the output may be scaled or transformed. + * @param width width of the mode in hardware units + * @param height height of the mode in hardware units + */ + void (*size)(void *data, + struct kde_output_device_mode_v2 *kde_output_device_mode_v2, + int32_t width, + int32_t height); + /** + * mode refresh rate + * + * This event describes the mode's fixed vertical refresh rate. + * It is only sent if the mode has a fixed refresh rate. + * @param refresh vertical refresh rate in mHz + */ + void (*refresh)(void *data, + struct kde_output_device_mode_v2 *kde_output_device_mode_v2, + int32_t refresh); + /** + * mode is preferred + * + * This event advertises this mode as preferred. + */ + void (*preferred)(void *data, + struct kde_output_device_mode_v2 *kde_output_device_mode_v2); + /** + * the mode has been destroyed + * + * The compositor will destroy the object immediately after + * sending this event, so it will become invalid and the client + * should release any resources associated with it. + */ + void (*removed)(void *data, + struct kde_output_device_mode_v2 *kde_output_device_mode_v2); +}; + +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +static inline int +kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, + const struct kde_output_device_mode_v2_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) kde_output_device_mode_v2, + (void (**)(void)) listener, data); +} + +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +#define KDE_OUTPUT_DEVICE_MODE_V2_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +#define KDE_OUTPUT_DEVICE_MODE_V2_REFRESH_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +#define KDE_OUTPUT_DEVICE_MODE_V2_PREFERRED_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_device_mode_v2 + */ +#define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1 + + +/** @ingroup iface_kde_output_device_mode_v2 */ +static inline void +kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data); +} + +/** @ingroup iface_kde_output_device_mode_v2 */ +static inline void * +kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +{ + return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2); +} + +static inline uint32_t +kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +{ + return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2); +} + +/** @ingroup iface_kde_output_device_mode_v2 */ +static inline void +kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +{ + wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c b/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c new file mode 100644 index 0000000000..885962e5b6 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c @@ -0,0 +1,81 @@ +#ifdef FF_HAVE_WAYLAND + +/* Generated by wayland-scanner 1.22.0 */ + +/* + * SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg + * SPDX-FileCopyrightText: 2010-2011 Intel Corporation + * SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd. + * SPDX-FileCopyrightText: 2015 Sebastian Kügler + * SPDX-FileCopyrightText: 2021 Méven Car + * + * SPDX-License-Identifier: MIT-CMU + */ + +#include +#include +#include + +extern const struct wl_interface kde_output_device_mode_v2_interface; + +static const struct wl_interface *kde_output_device_v2_types[] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &kde_output_device_mode_v2_interface, + &kde_output_device_mode_v2_interface, +}; + +static const struct wl_message kde_output_device_v2_events[] = { + { "geometry", "iiiiissi", kde_output_device_v2_types + 0 }, + { "current_mode", "o", kde_output_device_v2_types + 8 }, + { "mode", "n", kde_output_device_v2_types + 9 }, + { "done", "", kde_output_device_v2_types + 0 }, + { "scale", "f", kde_output_device_v2_types + 0 }, + { "edid", "s", kde_output_device_v2_types + 0 }, + { "enabled", "i", kde_output_device_v2_types + 0 }, + { "uuid", "s", kde_output_device_v2_types + 0 }, + { "serial_number", "s", kde_output_device_v2_types + 0 }, + { "eisa_id", "s", kde_output_device_v2_types + 0 }, + { "capabilities", "u", kde_output_device_v2_types + 0 }, + { "overscan", "u", kde_output_device_v2_types + 0 }, + { "vrr_policy", "u", kde_output_device_v2_types + 0 }, + { "rgb_range", "u", kde_output_device_v2_types + 0 }, + { "name", "2s", kde_output_device_v2_types + 0 }, + { "high_dynamic_range", "3u", kde_output_device_v2_types + 0 }, + { "sdr_brightness", "3u", kde_output_device_v2_types + 0 }, + { "wide_color_gamut", "3u", kde_output_device_v2_types + 0 }, + { "auto_rotate_policy", "4u", kde_output_device_v2_types + 0 }, + { "icc_profile_path", "5s", kde_output_device_v2_types + 0 }, + { "brightness_metadata", "6uuu", kde_output_device_v2_types + 0 }, + { "brightness_overrides", "6iii", kde_output_device_v2_types + 0 }, + { "sdr_gamut_wideness", "6u", kde_output_device_v2_types + 0 }, + { "color_profile_source", "7u", kde_output_device_v2_types + 0 }, + { "brightness", "8u", kde_output_device_v2_types + 0 }, +}; + +WL_EXPORT const struct wl_interface kde_output_device_v2_interface = { + "kde_output_device_v2", 8, + 0, NULL, + 25, kde_output_device_v2_events, +}; + +static const struct wl_message kde_output_device_mode_v2_events[] = { + { "size", "ii", kde_output_device_v2_types + 0 }, + { "refresh", "i", kde_output_device_v2_types + 0 }, + { "preferred", "", kde_output_device_v2_types + 0 }, + { "removed", "", kde_output_device_v2_types + 0 }, +}; + +WL_EXPORT const struct wl_interface kde_output_device_mode_v2_interface = { + "kde_output_device_mode_v2", 1, + 0, NULL, + 4, kde_output_device_mode_v2_events, +}; + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c new file mode 100644 index 0000000000..07ad91a658 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -0,0 +1,225 @@ +#ifdef FF_HAVE_WAYLAND + +#include "wayland.h" +#include "kde-output-device-v2-client-protocol.h" +#include "util/edidHelper.h" +#include "util/base64.h" + +typedef struct WaylandKdeMode +{ + int32_t width; + int32_t height; + int32_t refreshRate; + struct kde_output_device_mode_v2* pMode; +} WaylandKdeMode; + +static void waylandKdeSizeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t width, int32_t height) +{ + WaylandKdeMode* mode = (WaylandKdeMode*) data; + mode->width = width; + mode->height = height; +} + +static void waylandKdeRefreshListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_mode_v2 *_, int32_t rate) +{ + WaylandKdeMode* mode = (WaylandKdeMode*) data; + mode->refreshRate = rate; +} + +static const struct kde_output_device_mode_v2_listener modeListener = { + .size = waylandKdeSizeListener, + .refresh = waylandKdeRefreshListener, + .preferred = (void*) stubListener, + .removed = (void*) stubListener, +}; + +static void waylandKdeModeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, struct kde_output_device_mode_v2 *mode) +{ + WaylandDisplay* wldata = (WaylandDisplay*) data; + if (!wldata->internal) return; + + WaylandKdeMode* newMode = ffListAdd((FFlist*) wldata->internal); + newMode->pMode = mode; + + // Strangely, the listener is called only in this function, but not in `waylandKdeCurrentModeListener` + wldata->parent->ffwl_proxy_add_listener((struct wl_proxy *) mode, (void (**)(void)) &modeListener, newMode); +} + +static void waylandKdeCurrentModeListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2 *_, struct kde_output_device_mode_v2 *mode) +{ + // waylandKdeModeListener is always run before this + WaylandDisplay* wldata = (WaylandDisplay*) data; + if (!wldata->internal) return; + + WaylandKdeMode* current = NULL; + FF_LIST_FOR_EACH(WaylandKdeMode, m, *(FFlist*) wldata->internal) + { + if (m->pMode == mode) + { + current = m; + break; + } + } + wldata->width = current->width; + wldata->height = current->height; + wldata->refreshRate = current->refreshRate; +} + +static void waylandKdeScaleListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, wl_fixed_t scale) +{ + WaylandDisplay* wldata = (WaylandDisplay*) data; + wldata->scale = wl_fixed_to_double(scale); +} + +static void waylandKdeEdidListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, const char* raw) +{ + if (!*raw) return; + WaylandDisplay* wldata = (WaylandDisplay*) data; + FF_STRBUF_AUTO_DESTROY b64 = ffStrbufCreateStatic(raw); + FF_STRBUF_AUTO_DESTROY edid = ffBase64DecodeStrbuf(&b64); + if (edid.length < 128) return; + ffEdidGetName((const uint8_t*) edid.chars, &wldata->edidName); +} + +static void waylandKdeEnabledListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* _, int32_t enabled) +{ + WaylandDisplay* wldata = (WaylandDisplay*) data; + if (!enabled) wldata->internal = NULL; +} + +static void waylandKdeGeometryListener(void *data, + FF_MAYBE_UNUSED struct kde_output_device_v2 *kde_output_device_v2, + FF_MAYBE_UNUSED int32_t x, + FF_MAYBE_UNUSED int32_t y, + FF_MAYBE_UNUSED int32_t physical_width, + FF_MAYBE_UNUSED int32_t physical_height, + FF_MAYBE_UNUSED int32_t subpixel, + FF_MAYBE_UNUSED const char *make, + FF_MAYBE_UNUSED const char *model, + int32_t transform) +{ + WaylandDisplay* display = data; + display->transform = (enum wl_output_transform) transform; +} + +void waylandOutputNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_device_v2* output, const char *name) +{ + WaylandDisplay* display = data; + if(ffStrStartsWith(name, "eDP-")) + display->type = FF_DISPLAY_TYPE_BUILTIN; + else if(ffStrStartsWith(name, "HDMI-")) + display->type = FF_DISPLAY_TYPE_EXTERNAL; + strncpy((char*) &display->id, name, sizeof(display->id)); + ffStrbufAppendS(&display->name, name); +} + +void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +{ + struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_device_v2_interface, version, name, kde_output_device_v2_interface.name, version, NULL); + if(output == NULL) + return; + + FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandKdeMode)); + WaylandDisplay display = { + .parent = wldata, + .width = 0, + .height = 0, + .refreshRate = 0, + .scale = 1, + .transform = WL_OUTPUT_TRANSFORM_NORMAL, + .type = FF_DISPLAY_TYPE_UNKNOWN, + .name = ffStrbufCreate(), + .description = ffStrbufCreate(), + .edidName = ffStrbufCreate(), + .internal = &modes, + }; + + struct kde_output_device_v2_listener outputListener = { + .geometry = waylandKdeGeometryListener, + .current_mode = waylandKdeCurrentModeListener, + .mode = waylandKdeModeListener, + .done = (void*) stubListener, + .scale = waylandKdeScaleListener, + .edid = waylandKdeEdidListener, + .enabled = waylandKdeEnabledListener, + .uuid = (void*) stubListener, + .serial_number = (void*) stubListener, + .eisa_id = (void*) stubListener, + .capabilities = (void*) stubListener, + .overscan = (void*) stubListener, + .vrr_policy = (void*) stubListener, + .rgb_range = (void*) stubListener, + .name = waylandOutputNameListener, + .high_dynamic_range = (void*) stubListener, + .sdr_brightness = (void*) stubListener, + .wide_color_gamut = (void*) stubListener, + .auto_rotate_policy = (void*) stubListener, + .icc_profile_path = (void*) stubListener, + .brightness_metadata = (void*) stubListener, + .brightness_overrides = (void*) stubListener, + .sdr_gamut_wideness = (void*) stubListener, + .color_profile_source = (void*) stubListener, + .brightness = (void*) stubListener, + }; + + wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display); + wldata->ffwl_display_roundtrip(wldata->display); + wldata->ffwl_proxy_destroy(output); + + if(display.width <= 0 || display.height <= 0 || !display.internal) + return; + + uint32_t rotation; + switch(display.transform) + { + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_90: + rotation = 90; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + case WL_OUTPUT_TRANSFORM_180: + rotation = 180; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + case WL_OUTPUT_TRANSFORM_270: + rotation = 270; + break; + default: + rotation = 0; + break; + } + + switch(rotation) + { + case 90: + case 270: { + int32_t temp = display.width; + display.width = display.height; + display.height = temp; + break; + } + default: + break; + } + + ffdsAppendDisplay(wldata->result, + (uint32_t) display.width, + (uint32_t) display.height, + display.refreshRate / 1000.0, + (uint32_t) (display.width / display.scale), + (uint32_t) (display.height / display.scale), + rotation, + display.edidName.length + ? &display.edidName + : &display.name, + display.type, + false, + 0 + ); + + ffStrbufDestroy(&display.description); + ffStrbufDestroy(&display.name); + ffStrbufDestroy(&display.edidName); +} + +#endif diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 9628dcdd7a..9479e7ba84 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -11,6 +11,7 @@ #include "wayland.h" #include "wlr-output-management-unstable-v1-client-protocol.h" +#include "kde-output-device-v2-client-protocol.h" #ifndef __FreeBSD__ static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -47,6 +48,11 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_ZWLR; ffWaylandHandleZwlrOutput(wldata, registry, name, version); } + else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_KDE) && ffStrEquals(interface, kde_output_device_v2_interface.name)) + { + wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE; + ffWaylandHandleKdeOutput(wldata, registry, name, version); + } } bool detectWayland(FFDisplayServerResult* result) @@ -107,7 +113,8 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const display->type = FF_DISPLAY_TYPE_BUILTIN; else if(ffStrStartsWith(name, "HDMI-")) display->type = FF_DISPLAY_TYPE_EXTERNAL; - ffdsMatchDrmConnector(name, &display->edidName); + if (!display->edidName.length) + ffdsMatchDrmConnector(name, &display->edidName); ffStrbufAppendS(&display->name, name); } diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index 4a65a98ad3..ada81ab01c 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -14,6 +14,7 @@ typedef enum WaylandProtocolType FF_WAYLAND_PROTOCOL_TYPE_NONE, FF_WAYLAND_PROTOCOL_TYPE_GLOBAL, FF_WAYLAND_PROTOCOL_TYPE_ZWLR, + FF_WAYLAND_PROTOCOL_TYPE_KDE, } WaylandProtocolType; typedef struct WaylandData @@ -53,5 +54,6 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); +void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); #endif diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 36bdea2811..c95455f505 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -2,6 +2,7 @@ #include "common/io/io.h" #include "common/printing.h" #include "util/stringUtils.h" +#include "util/base64.h" #include #include @@ -16,48 +17,6 @@ #include #endif -// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145 -static void base64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output) -{ - static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - char *out = output; - const char *ends = str + (size - size % 3); - while (str != ends) { - uint32_t n = __builtin_bswap32(*(uint32_t*) str); - *out++ = chars[(n >> 26) & 63]; - *out++ = chars[(n >> 20) & 63]; - *out++ = chars[(n >> 14) & 63]; - *out++ = chars[(n >> 8) & 63]; - str += 3; - } - - if (size % 3 == 1) { - uint64_t n = (uint64_t)*str << 16; - *out++ = chars[(n >> 18) & 63]; - *out++ = chars[(n >> 12) & 63]; - *out++ = '='; - *out++ = '='; - } else if (size % 3 == 2) { - uint64_t n = (uint64_t)*str++ << 16; - n |= (uint64_t)*str << 8; - *out++ = chars[(n >> 18) & 63]; - *out++ = chars[(n >> 12) & 63]; - *out++ = chars[(n >> 6) & 63]; - *out++ = '='; - } - *out = '\0'; - *out_size = (uint32_t) (out - output); -} - -static FFstrbuf base64Encode(const FFstrbuf* in) -{ - FFstrbuf out = ffStrbufCreateA(10 + in->length * 4 / 3); - base64EncodeRaw(in->length, in->chars, &out.length, out.chars); - assert(out.length < out.allocated); - - return out; -} - static bool printImageIterm(bool printError) { const FFOptionsLogo* options = &instance.config.logo; @@ -71,7 +30,7 @@ static bool printImageIterm(bool printError) fflush(stdout); - FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&buf); + FF_STRBUF_AUTO_DESTROY base64 = ffBase64EncodeStrbuf(&buf); ffStrbufClear(&buf); if (!options->width || !options->height) @@ -166,7 +125,7 @@ static bool printImageKittyDirect(bool printError) return false; } - FF_STRBUF_AUTO_DESTROY base64 = base64Encode(&options->source); + FF_STRBUF_AUTO_DESTROY base64 = ffBase64EncodeStrbuf(&options->source); if (!options->width || !options->height) { diff --git a/src/util/base64.c b/src/util/base64.c new file mode 100644 index 0000000000..866d59428c --- /dev/null +++ b/src/util/base64.c @@ -0,0 +1,115 @@ +#include "base64.h" + +// https://github.com/kostya/benchmarks/blob/master/base64/test-nolib.c#L145 +void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output) +{ + static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *out = output; + const char *ends = str + (size - size % 3); + while (str != ends) + { + uint32_t n = __builtin_bswap32(*(uint32_t *)str); + *out++ = chars[(n >> 26) & 63]; + *out++ = chars[(n >> 20) & 63]; + *out++ = chars[(n >> 14) & 63]; + *out++ = chars[(n >> 8) & 63]; + str += 3; + } + + if (size % 3 == 1) + { + uint64_t n = (uint64_t)*str << 16; + *out++ = chars[(n >> 18) & 63]; + *out++ = chars[(n >> 12) & 63]; + *out++ = '='; + *out++ = '='; + } + else if (size % 3 == 2) + { + uint64_t n = (uint64_t)*str++ << 16; + n |= (uint64_t)*str << 8; + *out++ = chars[(n >> 18) & 63]; + *out++ = chars[(n >> 12) & 63]; + *out++ = chars[(n >> 6) & 63]; + *out++ = '='; + } + *out = '\0'; + *out_size = (uint32_t)(out - output); +} + +static char decode_table[256]; + +void init_decode_table() +{ + uint8_t ch = 0; + do + { + int32_t code = -1; + if (ch >= 'A' && ch <= 'Z') + code = ch - 0x41; + if (ch >= 'a' && ch <= 'z') + code = ch - 0x47; + if (ch >= '0' && ch <= '9') + code = ch + 0x04; + if (ch == '+' || ch == '-') + code = 0x3E; + if (ch == '/' || ch == '_') + code = 0x3F; + decode_table[ch] = (char) code; + } while (ch++ < 0xFF); +} + +#define next_char(x) \ + char x = decode_table[(unsigned char)*str++]; \ + if (x < 0) \ + return false; + +bool ffBase64DecodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output) +{ + if (*(uint64_t*) decode_table == 0) + init_decode_table(); + + char *out = output; + while (size > 0 && (str[size - 1] == '\n' || str[size - 1] == '\r' || str[size - 1] == '=')) + size--; + + const char *ends = str + size - 4; + while (true) + { + if (str > ends) + break; + while (*str == '\n' || *str == '\r') + str++; + + if (str > ends) + break; + next_char(a); + next_char(b); + next_char(c); + next_char(d); + + *out++ = (char)(a << 2 | b >> 4); + *out++ = (char)(b << 4 | c >> 2); + *out++ = (char)(c << 6 | d >> 0); + } + + uint8_t mod = (uint8_t) (ends - str + 4) % 4; + if (mod == 2) + { + next_char(a); + next_char(b); + *out++ = (char)(a << 2 | b >> 4); + } + else if (mod == 3) + { + next_char(a); + next_char(b); + next_char(c); + *out++ = (char)(a << 2 | b >> 4); + *out++ = (char)(b << 4 | c >> 2); + } + + *out = '\0'; + *out_size = (uint32_t) (out - output); + return true; +} diff --git a/src/util/base64.h b/src/util/base64.h new file mode 100644 index 0000000000..5dc8ee7c6f --- /dev/null +++ b/src/util/base64.h @@ -0,0 +1,23 @@ +#pragma once + +#include "fastfetch.h" + +void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output); +static inline FFstrbuf ffBase64EncodeStrbuf(const FFstrbuf* in) +{ + FFstrbuf out = ffStrbufCreateA(10 + in->length * 4 / 3); + ffBase64EncodeRaw(in->length, in->chars, &out.length, out.chars); + assert(out.length < out.allocated); + + return out; +} + +bool ffBase64DecodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output); +static inline FFstrbuf ffBase64DecodeStrbuf(const FFstrbuf* in) +{ + FFstrbuf out = ffStrbufCreateA(10 + in->length * 3 / 4); + ffBase64DecodeRaw(in->length, in->chars, &out.length, out.chars); + assert(out.length < out.allocated); + + return out; +} From 5f1cb16534331cc7e2724286eb653b8ebf3f594b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 5 Jul 2024 16:54:43 +0800 Subject: [PATCH 09/41] Display (Linux): support primary display detection for KDE --- CMakeLists.txt | 3 + .../linux/wayland/global-output.c | 2 +- .../kde-output-order-v1-client-protocol.h | 133 ++++++++++++++++++ .../wayland/kde-output-order-v1-protocol.c | 35 +++++ .../displayserver/linux/wayland/kde-output.c | 27 +++- .../displayserver/linux/wayland/wayland.c | 18 +++ .../displayserver/linux/wayland/wayland.h | 3 + .../displayserver/linux/wayland/zwlr-output.c | 2 +- 8 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h create mode 100644 src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 52407a14bb..34283d1221 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,6 +433,7 @@ if(LINUX) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -568,6 +569,7 @@ elseif(BSD) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -771,6 +773,7 @@ elseif(SunOS) src/detection/displayserver/linux/wayland/kde-output.c src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c + src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 050f1b0de6..4b17271e0b 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -124,7 +124,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description); diff --git a/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h new file mode 100644 index 0000000000..776e51de6d --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h @@ -0,0 +1,133 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H +#define KDE_OUTPUT_ORDER_V1_CLIENT_PROTOCOL_H + +#include +#include +#include "wayland-client.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_kde_output_order_v1 The kde_output_order_v1 protocol + * @section page_ifaces_kde_output_order_v1 Interfaces + * - @subpage page_iface_kde_output_order_v1 - announce order of outputs + * @section page_copyright_kde_output_order_v1 Copyright + *
+ *
+ * SPDX-FileCopyrightText: 2022 Xaver Hugl 
+ *
+ * SPDX-License-Identifier: MIT-CMU
+ * 
+ */ +struct kde_output_order_v1; + +#ifndef KDE_OUTPUT_ORDER_V1_INTERFACE +#define KDE_OUTPUT_ORDER_V1_INTERFACE +/** + * @page page_iface_kde_output_order_v1 kde_output_order_v1 + * @section page_iface_kde_output_order_v1_desc Description + * + * Announce the order in which desktop environment components should be placed on outputs. + * The compositor will send the list of outputs when the global is bound and whenever there is a change. + * @section page_iface_kde_output_order_v1_api API + * See @ref iface_kde_output_order_v1. + */ +/** + * @defgroup iface_kde_output_order_v1 The kde_output_order_v1 interface + * + * Announce the order in which desktop environment components should be placed on outputs. + * The compositor will send the list of outputs when the global is bound and whenever there is a change. + */ +extern const struct wl_interface kde_output_order_v1_interface; +#endif + +/** + * @ingroup iface_kde_output_order_v1 + * @struct kde_output_order_v1_listener + */ +struct kde_output_order_v1_listener { + /** + * output name + * + * Specifies the output identified by their wl_output.name. + * @param output_name the name of the output + */ + void (*output)(void *data, + struct kde_output_order_v1 *kde_output_order_v1, + const char *output_name); + /** + * done + * + * Specifies that the output list is complete. On the next output + * event, a new list begins. + */ + void (*done)(void *data, + struct kde_output_order_v1 *kde_output_order_v1); +}; + +/** + * @ingroup iface_kde_output_order_v1 + */ +static inline int +kde_output_order_v1_add_listener(struct kde_output_order_v1 *kde_output_order_v1, + const struct kde_output_order_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) kde_output_order_v1, + (void (**)(void)) listener, data); +} + +#define KDE_OUTPUT_ORDER_V1_DESTROY 0 + +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_OUTPUT_SINCE_VERSION 1 +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_DONE_SINCE_VERSION 1 + +/** + * @ingroup iface_kde_output_order_v1 + */ +#define KDE_OUTPUT_ORDER_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_kde_output_order_v1 */ +static inline void +kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data); +} + +/** @ingroup iface_kde_output_order_v1 */ +static inline void * +kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1); +} + +static inline uint32_t +kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1); +} + +/** + * @ingroup iface_kde_output_order_v1 + */ +static inline void +kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1, + KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c b/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c new file mode 100644 index 0000000000..c7cf90f346 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c @@ -0,0 +1,35 @@ +#ifdef FF_HAVE_WAYLAND + +/* Generated by wayland-scanner 1.22.0 */ + +/* + * SPDX-FileCopyrightText: 2022 Xaver Hugl + * + * SPDX-License-Identifier: MIT-CMU + */ + +#include +#include +#include "wayland-util.h" + + +static const struct wl_interface *kde_output_order_v1_types[] = { + NULL, +}; + +static const struct wl_message kde_output_order_v1_requests[] = { + { "destroy", "", kde_output_order_v1_types + 0 }, +}; + +static const struct wl_message kde_output_order_v1_events[] = { + { "output", "s", kde_output_order_v1_types + 0 }, + { "done", "", kde_output_order_v1_types + 0 }, +}; + +WL_EXPORT const struct wl_interface kde_output_order_v1_interface = { + "kde_output_order_v1", 1, + 1, kde_output_order_v1_requests, + 2, kde_output_order_v1_events, +}; + +#endif diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index 07ad91a658..d638a3ec39 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -2,6 +2,7 @@ #include "wayland.h" #include "kde-output-device-v2-client-protocol.h" +#include "kde-output-order-v1-client-protocol.h" #include "util/edidHelper.h" #include "util/base64.h" @@ -214,7 +215,7 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description); @@ -222,4 +223,28 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, ffStrbufDestroy(&display.edidName); } + +static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde_output_order_v1 *_, const char *output_name) +{ + uint64_t* id = (uint64_t*) data; + if (*id == 0) + strncpy((char*) id, output_name, sizeof(*id)); +} + +void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +{ + struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_order_v1_interface, version, name, kde_output_order_v1_interface.name, version, NULL); + if(output == NULL) + return; + + struct kde_output_order_v1_listener orderListener = { + .output = waylandKdeOutputOrderListener, + .done = (void*) stubListener, + }; + + wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &orderListener, &wldata->primaryDisplayId); + wldata->ffwl_display_roundtrip(wldata->display); + wldata->ffwl_proxy_destroy(output); +} + #endif diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 9479e7ba84..708aaff02c 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -12,6 +12,7 @@ #include "wayland.h" #include "wlr-output-management-unstable-v1-client-protocol.h" #include "kde-output-device-v2-client-protocol.h" +#include "kde-output-order-v1-client-protocol.h" #ifndef __FreeBSD__ static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -53,6 +54,10 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u wldata->protocolType = FF_WAYLAND_PROTOCOL_TYPE_KDE; ffWaylandHandleKdeOutput(wldata, registry, name, version); } + else if(ffStrEquals(interface, kde_output_order_v1_interface.name)) + { + ffWaylandHandleKdeOutputOrder(wldata, registry, name, version); + } } bool detectWayland(FFDisplayServerResult* result) @@ -99,6 +104,18 @@ bool detectWayland(FFDisplayServerResult* result) data.ffwl_proxy_destroy(registry); ffwl_display_disconnect(data.display); + if(data.primaryDisplayId) + { + FF_LIST_FOR_EACH(FFDisplayResult, d, data.result->displays) + { + if(d->id == data.primaryDisplayId) + { + d->primary = true; + break; + } + } + } + //We successfully connected to wayland and detected the display. //So we can set set the session type to wayland. //This is used as an indicator that we are running wayland by the x11 backends. @@ -115,6 +132,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const display->type = FF_DISPLAY_TYPE_EXTERNAL; if (!display->edidName.length) ffdsMatchDrmConnector(name, &display->edidName); + strncpy((char*) &display->id, name, sizeof(display->id)); ffStrbufAppendS(&display->name, name); } diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index ada81ab01c..f972c03236 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -27,6 +27,7 @@ typedef struct WaylandData struct wl_display* display; const struct wl_interface* ffwl_output_interface; WaylandProtocolType protocolType; + uint64_t primaryDisplayId; } WaylandData; typedef struct WaylandDisplay @@ -41,6 +42,7 @@ typedef struct WaylandDisplay FFstrbuf name; FFstrbuf description; FFstrbuf edidName; + uint64_t id; void* internal; } WaylandDisplay; @@ -55,5 +57,6 @@ void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); +void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); #endif diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index 2071bfa52a..63ab7146c1 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -160,7 +160,7 @@ static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output : &display.name, display.type, false, - 0 + display.id ); ffStrbufDestroy(&display.description); From 73875de6a1fd3d4445c04a85bcfdb2492395ffbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 5 Jul 2024 20:02:57 +0800 Subject: [PATCH 10/41] LocalIP: don't print `*` if `defaultRouteOnly` is set --- src/modules/localip/localip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c index 54d21f2041..0825060a2b 100644 --- a/src/modules/localip/localip.c +++ b/src/modules/localip/localip.c @@ -105,7 +105,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options) if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); - printIp(ip, true); + printIp(ip, !(options->showType & FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT)); putchar('\n'); } else From c16373a7d7d81f8d13fcce7a80b1c7d6dfdb9976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 5 Jul 2024 23:10:42 +0800 Subject: [PATCH 11/41] Display (Linux): support primary display detection for GNOME --- CMakeLists.txt | 3 + .../linux/wayland/global-output.c | 71 ++- .../displayserver/linux/wayland/wayland.c | 8 + .../displayserver/linux/wayland/wayland.h | 2 + .../xdg-output-unstable-v1-client-protocol.h | 414 ++++++++++++++++++ .../wayland/xdg-output-unstable-v1-protocol.c | 70 +++ 6 files changed, 553 insertions(+), 15 deletions(-) create mode 100644 src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h create mode 100644 src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 34283d1221..a63ca12888 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -434,6 +434,7 @@ if(LINUX) src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c + src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -570,6 +571,7 @@ elseif(BSD) src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c + src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c @@ -774,6 +776,7 @@ elseif(SunOS) src/detection/displayserver/linux/wayland/wlr-output-management-unstable-v1-protocol.c src/detection/displayserver/linux/wayland/kde-output-device-v2-protocol.c src/detection/displayserver/linux/wayland/kde-output-order-v1-protocol.c + src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c src/detection/displayserver/linux/wmde.c src/detection/displayserver/linux/xcb.c src/detection/displayserver/linux/xlib.c diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 4b17271e0b..55b287afd5 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -2,6 +2,7 @@ #include "wayland.h" #include "util/stringUtils.h" +#include "xdg-output-unstable-v1-client-protocol.h" static void waylandOutputModeListener(void* data, FF_MAYBE_UNUSED struct wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refreshRate) { @@ -35,6 +36,39 @@ static void waylandOutputGeometryListener(void *data, display->transform = (enum wl_output_transform) transform; } +static void handleXdgLogicalSize(void *data, FF_MAYBE_UNUSED struct zxdg_output_v1 *_, int32_t width, FF_MAYBE_UNUSED int32_t height) +{ + WaylandDisplay* display = data; + // Seems the values are only useful when ractional scale is enabled + if (width < display->width) + { + display->scale = (double) display->width / width; + } +} + +// Dirty hack for #477 +// The order of these callbacks MUST follow `struct wl_output_listener` +static void* outputListener[] = { + waylandOutputGeometryListener, // geometry + waylandOutputModeListener, // mode + stubListener, // done + waylandOutputScaleListener, // scale + ffWaylandOutputNameListener, // name + ffWaylandOutputDescriptionListener, // description +}; +static_assert( + sizeof(outputListener) >= sizeof(struct wl_output_listener), + "sizeof(outputListener) is too small. Please report it to fastfetch github issue" +); + +static struct zxdg_output_v1_listener zxdgOutputListener = { + .logical_position = (void*) stubListener, + .logical_size = handleXdgLogicalSize, + .done = (void*) stubListener, + .name = (void*) stubListener, + .description = (void*) stubListener, +}; + void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, wldata->ffwl_output_interface, version, name, wldata->ffwl_output_interface->name, version, NULL); @@ -54,23 +88,21 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist .edidName = ffStrbufCreate(), }; - // Dirty hack for #477 - // The order of these callbacks MUST follow `struct wl_output_listener` - void* outputListener[] = { - waylandOutputGeometryListener, // geometry - waylandOutputModeListener, // mode - stubListener, // done - waylandOutputScaleListener, // scale - ffWaylandOutputNameListener, // name - ffWaylandOutputDescriptionListener, // description - }; - static_assert( - sizeof(outputListener) >= sizeof(struct wl_output_listener), - "sizeof(outputListener) is too small. Please report it to fastfetch github issue" - ); - wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display); wldata->ffwl_display_roundtrip(wldata->display); + + if (wldata->zxdgOutputManager) + { + struct wl_proxy* zxdgOutput = wldata->ffwl_proxy_marshal_constructor_versioned(wldata->zxdgOutputManager, ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, version, NULL, output); + + if (zxdgOutput) + { + wldata->ffwl_proxy_add_listener(zxdgOutput, (void(**)(void)) &zxdgOutputListener, &display); + wldata->ffwl_display_roundtrip(wldata->display); + wldata->ffwl_proxy_destroy(zxdgOutput); + } + } + wldata->ffwl_proxy_destroy(output); if(display.width <= 0 || display.height <= 0) @@ -132,4 +164,13 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist ffStrbufDestroy(&display.edidName); } +void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +{ + struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL); + if(manager == NULL) + return; + + wldata->zxdgOutputManager = manager; +} + #endif diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 708aaff02c..990df0f3bb 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -13,6 +13,7 @@ #include "wlr-output-management-unstable-v1-client-protocol.h" #include "kde-output-device-v2-client-protocol.h" #include "kde-output-order-v1-client-protocol.h" +#include "xdg-output-unstable-v1-client-protocol.h" #ifndef __FreeBSD__ static void waylandDetectWM(int fd, FFDisplayServerResult* result) @@ -58,6 +59,10 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u { ffWaylandHandleKdeOutputOrder(wldata, registry, name, version); } + else if(wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL && ffStrEquals(interface, zxdg_output_manager_v1_interface.name)) + { + ffWaylandHandleXdgOutput(wldata, registry, name, version); + } } bool detectWayland(FFDisplayServerResult* result) @@ -101,6 +106,9 @@ bool detectWayland(FFDisplayServerResult* result) data.ffwl_proxy_add_listener(registry, (void(**)(void)) ®istry_listener, &data); data.ffwl_display_roundtrip(data.display); + if (data.zxdgOutputManager) + data.ffwl_proxy_destroy(data.zxdgOutputManager); + data.ffwl_proxy_destroy(registry); ffwl_display_disconnect(data.display); diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index f972c03236..4e3f72665b 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -28,6 +28,7 @@ typedef struct WaylandData const struct wl_interface* ffwl_output_interface; WaylandProtocolType protocolType; uint64_t primaryDisplayId; + struct wl_proxy* zxdgOutputManager; } WaylandData; typedef struct WaylandDisplay @@ -58,5 +59,6 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); +void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); #endif diff --git a/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h new file mode 100644 index 0000000000..daba88fa8d --- /dev/null +++ b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h @@ -0,0 +1,414 @@ +/* Generated by wayland-scanner 1.22.0 */ + +#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H +#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol + * Protocol to describe output regions + * + * @section page_desc_xdg_output_unstable_v1 Description + * + * This protocol aims at describing outputs in a way which is more in line + * with the concept of an output on desktop oriented systems. + * + * Some information are more specific to the concept of an output for + * a desktop oriented system and may not make sense in other applications, + * such as IVI systems for example. + * + * Typically, the global compositor space on a desktop system is made of + * a contiguous or overlapping set of rectangular regions. + * + * The logical_position and logical_size events defined in this protocol + * might provide information identical to their counterparts already + * available from wl_output, in which case the information provided by this + * protocol should be preferred to their equivalent in wl_output. The goal is + * to move the desktop specific concepts (such as output location within the + * global compositor space, etc.) out of the core wl_output protocol. + * + * Warning! The protocol described in this file is experimental and + * backward incompatible changes may be made. Backward compatible + * changes may be added together with the corresponding interface + * version bump. + * Backward incompatible changes are done by bumping the version + * number in the protocol and interface names and resetting the + * interface version. Once the protocol is to be declared stable, + * the 'z' prefix and the version number in the protocol and + * interface names are removed and the interface version number is + * reset. + * + * @section page_ifaces_xdg_output_unstable_v1 Interfaces + * - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects + * - @subpage page_iface_zxdg_output_v1 - compositor logical output region + * @section page_copyright_xdg_output_unstable_v1 Copyright + *
+ *
+ * Copyright © 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ */ +struct wl_output; +struct zxdg_output_manager_v1; +struct zxdg_output_v1; + +#ifndef ZXDG_OUTPUT_MANAGER_V1_INTERFACE +#define ZXDG_OUTPUT_MANAGER_V1_INTERFACE +/** + * @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1 + * @section page_iface_zxdg_output_manager_v1_desc Description + * + * A global factory interface for xdg_output objects. + * @section page_iface_zxdg_output_manager_v1_api API + * See @ref iface_zxdg_output_manager_v1. + */ +/** + * @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface + * + * A global factory interface for xdg_output objects. + */ +extern const struct wl_interface zxdg_output_manager_v1_interface; +#endif +#ifndef ZXDG_OUTPUT_V1_INTERFACE +#define ZXDG_OUTPUT_V1_INTERFACE +/** + * @page page_iface_zxdg_output_v1 zxdg_output_v1 + * @section page_iface_zxdg_output_v1_desc Description + * + * An xdg_output describes part of the compositor geometry. + * + * This typically corresponds to a monitor that displays part of the + * compositor space. + * + * For objects version 3 onwards, after all xdg_output properties have been + * sent (when the object is created and when properties are updated), a + * wl_output.done event is sent. This allows changes to the output + * properties to be seen as atomic, even if they happen via multiple events. + * @section page_iface_zxdg_output_v1_api API + * See @ref iface_zxdg_output_v1. + */ +/** + * @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface + * + * An xdg_output describes part of the compositor geometry. + * + * This typically corresponds to a monitor that displays part of the + * compositor space. + * + * For objects version 3 onwards, after all xdg_output properties have been + * sent (when the object is created and when properties are updated), a + * wl_output.done event is sent. This allows changes to the output + * properties to be seen as atomic, even if they happen via multiple events. + */ +extern const struct wl_interface zxdg_output_v1_interface; +#endif + +#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0 +#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1 + + +/** + * @ingroup iface_zxdg_output_manager_v1 + */ +#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_manager_v1 + */ +#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_output_manager_v1 */ +static inline void +zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data); +} + +/** @ingroup iface_zxdg_output_manager_v1 */ +static inline void * +zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1); +} + +static inline uint32_t +zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1); +} + +/** + * @ingroup iface_zxdg_output_manager_v1 + * + * Using this request a client can tell the server that it is not + * going to use the xdg_output_manager object anymore. + * + * Any objects already created through this instance are not affected. + */ +static inline void +zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, + ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY); +} + +/** + * @ingroup iface_zxdg_output_manager_v1 + * + * This creates a new xdg_output object for the given wl_output. + */ +static inline struct zxdg_output_v1 * +zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output) +{ + struct wl_proxy *id; + + id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, + ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output); + + return (struct zxdg_output_v1 *) id; +} + +/** + * @ingroup iface_zxdg_output_v1 + * @struct zxdg_output_v1_listener + */ +struct zxdg_output_v1_listener { + /** + * position of the output within the global compositor space + * + * The position event describes the location of the wl_output + * within the global compositor space. + * + * The logical_position event is sent after creating an xdg_output + * (see xdg_output_manager.get_xdg_output) and whenever the + * location of the output changes within the global compositor + * space. + * @param x x position within the global compositor space + * @param y y position within the global compositor space + */ + void (*logical_position)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t x, + int32_t y); + /** + * size of the output in the global compositor space + * + * The logical_size event describes the size of the output in the + * global compositor space. + * + * Most regular Wayland clients should not pay attention to the + * logical size and would rather rely on xdg_shell interfaces. + * + * Some clients such as Xwayland, however, need this to configure + * their surfaces in the global compositor space as the compositor + * may apply a different scale from what is advertised by the + * output scaling property (to achieve fractional scaling, for + * example). + * + * For example, for a wl_output mode 3840×2160 and a scale factor + * 2: + * + * - A compositor not scaling the monitor viewport in its + * compositing space will advertise a logical size of 3840×2160, + * + * - A compositor scaling the monitor viewport with scale factor 2 + * will advertise a logical size of 1920×1080, + * + * - A compositor scaling the monitor viewport using a fractional + * scale of 1.5 will advertise a logical size of 2560×1440. + * + * For example, for a wl_output mode 1920×1080 and a 90 degree + * rotation, the compositor will advertise a logical size of + * 1080x1920. + * + * The logical_size event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output) and whenever the logical size + * of the output changes, either as a result of a change in the + * applied scale or because of a change in the corresponding output + * mode(see wl_output.mode) or transform (see wl_output.transform). + * @param width width in global compositor space + * @param height height in global compositor space + */ + void (*logical_size)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + int32_t width, + int32_t height); + /** + * all information about the output have been sent + * + * This event is sent after all other properties of an xdg_output + * have been sent. + * + * This allows changes to the xdg_output properties to be seen as + * atomic, even if they happen via multiple events. + * + * For objects version 3 onwards, this event is deprecated. + * Compositors are not required to send it anymore and must send + * wl_output.done instead. + */ + void (*done)(void *data, + struct zxdg_output_v1 *zxdg_output_v1); + /** + * name of this output + * + * Many compositors will assign names to their outputs, show them + * to the user, allow them to be configured by name, etc. The + * client may wish to know this name as well to offer the user + * similar behaviors. + * + * The naming convention is compositor defined, but limited to + * alphanumeric characters and dashes (-). Each name is unique + * among all wl_output globals, but if a wl_output global is + * destroyed the same name may be reused later. The names will also + * remain consistent across sessions with the same hardware and + * software configuration. + * + * Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. + * However, do not assume that the name is a reflection of an + * underlying DRM connector, X11 connection, etc. + * + * The name event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output). This event is only sent once + * per xdg_output, and the name does not change over the lifetime + * of the wl_output global. + * + * This event is deprecated, instead clients should use + * wl_output.name. Compositors must still support this event. + * @param name output name + * @since 2 + */ + void (*name)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *name); + /** + * human-readable description of this output + * + * Many compositors can produce human-readable descriptions of + * their outputs. The client may wish to know this description as + * well, to communicate the user for various purposes. + * + * The description is a UTF-8 string with no convention defined for + * its contents. Examples might include 'Foocorp 11" Display' or + * 'Virtual X11 output via :1'. + * + * The description event is sent after creating an xdg_output (see + * xdg_output_manager.get_xdg_output) and whenever the description + * changes. The description is optional, and may not be sent at + * all. + * + * For objects of version 2 and lower, this event is only sent once + * per xdg_output, and the description does not change over the + * lifetime of the wl_output global. + * + * This event is deprecated, instead clients should use + * wl_output.description. Compositors must still support this + * event. + * @param description output description + * @since 2 + */ + void (*description)(void *data, + struct zxdg_output_v1 *zxdg_output_v1, + const char *description); +}; + +/** + * @ingroup iface_zxdg_output_v1 + */ +static inline int +zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1, + const struct zxdg_output_v1_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1, + (void (**)(void)) listener, data); +} + +#define ZXDG_OUTPUT_V1_DESTROY 0 + +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2 +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2 + +/** + * @ingroup iface_zxdg_output_v1 + */ +#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1 + +/** @ingroup iface_zxdg_output_v1 */ +static inline void +zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data); +} + +/** @ingroup iface_zxdg_output_v1 */ +static inline void * +zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1) +{ + return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1); +} + +static inline uint32_t +zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1) +{ + return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1); +} + +/** + * @ingroup iface_zxdg_output_v1 + * + * Using this request a client can tell the server that it is not + * going to use the xdg_output object anymore. + */ +static inline void +zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1) +{ + wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1, + ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c new file mode 100644 index 0000000000..1f6abf2d57 --- /dev/null +++ b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-protocol.c @@ -0,0 +1,70 @@ +#ifdef FF_HAVE_WAYLAND +/* Generated by wayland-scanner 1.22.0 */ + +/* + * Copyright © 2017 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +extern const struct wl_interface wl_output_interface; +extern const struct wl_interface zxdg_output_v1_interface; + +static const struct wl_interface *xdg_output_unstable_v1_types[] = { + NULL, + NULL, + &zxdg_output_v1_interface, + NULL, // &wl_output_interface, +}; + +static const struct wl_message zxdg_output_manager_v1_requests[] = { + { "destroy", "", xdg_output_unstable_v1_types + 0 }, + { "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 }, +}; + +WL_EXPORT const struct wl_interface zxdg_output_manager_v1_interface = { + "zxdg_output_manager_v1", 3, + 2, zxdg_output_manager_v1_requests, + 0, NULL, +}; + +static const struct wl_message zxdg_output_v1_requests[] = { + { "destroy", "", xdg_output_unstable_v1_types + 0 }, +}; + +static const struct wl_message zxdg_output_v1_events[] = { + { "logical_position", "ii", xdg_output_unstable_v1_types + 0 }, + { "logical_size", "ii", xdg_output_unstable_v1_types + 0 }, + { "done", "", xdg_output_unstable_v1_types + 0 }, + { "name", "2s", xdg_output_unstable_v1_types + 0 }, + { "description", "2s", xdg_output_unstable_v1_types + 0 }, +}; + +WL_EXPORT const struct wl_interface zxdg_output_v1_interface = { + "zxdg_output_v1", 3, + 1, zxdg_output_v1_requests, + 5, zxdg_output_v1_events, +}; + +#endif From b6fff0c946d5599480fbb97b52ef81d61607f6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 5 Jul 2024 23:13:28 +0800 Subject: [PATCH 12/41] Display (Wayland): code refactor --- .../displayserver/linux/wayland/kde-output.c | 56 +++++++++---------- .../displayserver/linux/wayland/zwlr-output.c | 34 +++++------ 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index d638a3ec39..232b478920 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -114,6 +114,34 @@ void waylandOutputNameListener(void* data, FF_MAYBE_UNUSED struct kde_output_dev ffStrbufAppendS(&display->name, name); } +static struct kde_output_device_v2_listener outputListener = { + .geometry = waylandKdeGeometryListener, + .current_mode = waylandKdeCurrentModeListener, + .mode = waylandKdeModeListener, + .done = (void*) stubListener, + .scale = waylandKdeScaleListener, + .edid = waylandKdeEdidListener, + .enabled = waylandKdeEnabledListener, + .uuid = (void*) stubListener, + .serial_number = (void*) stubListener, + .eisa_id = (void*) stubListener, + .capabilities = (void*) stubListener, + .overscan = (void*) stubListener, + .vrr_policy = (void*) stubListener, + .rgb_range = (void*) stubListener, + .name = waylandOutputNameListener, + .high_dynamic_range = (void*) stubListener, + .sdr_brightness = (void*) stubListener, + .wide_color_gamut = (void*) stubListener, + .auto_rotate_policy = (void*) stubListener, + .icc_profile_path = (void*) stubListener, + .brightness_metadata = (void*) stubListener, + .brightness_overrides = (void*) stubListener, + .sdr_gamut_wideness = (void*) stubListener, + .color_profile_source = (void*) stubListener, + .brightness = (void*) stubListener, +}; + void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { struct wl_proxy* output = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &kde_output_device_v2_interface, version, name, kde_output_device_v2_interface.name, version, NULL); @@ -135,34 +163,6 @@ void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, .internal = &modes, }; - struct kde_output_device_v2_listener outputListener = { - .geometry = waylandKdeGeometryListener, - .current_mode = waylandKdeCurrentModeListener, - .mode = waylandKdeModeListener, - .done = (void*) stubListener, - .scale = waylandKdeScaleListener, - .edid = waylandKdeEdidListener, - .enabled = waylandKdeEnabledListener, - .uuid = (void*) stubListener, - .serial_number = (void*) stubListener, - .eisa_id = (void*) stubListener, - .capabilities = (void*) stubListener, - .overscan = (void*) stubListener, - .vrr_policy = (void*) stubListener, - .rgb_range = (void*) stubListener, - .name = waylandOutputNameListener, - .high_dynamic_range = (void*) stubListener, - .sdr_brightness = (void*) stubListener, - .wide_color_gamut = (void*) stubListener, - .auto_rotate_policy = (void*) stubListener, - .icc_profile_path = (void*) stubListener, - .brightness_metadata = (void*) stubListener, - .brightness_overrides = (void*) stubListener, - .sdr_gamut_wideness = (void*) stubListener, - .color_profile_source = (void*) stubListener, - .brightness = (void*) stubListener, - }; - wldata->ffwl_proxy_add_listener(output, (void(**)(void)) &outputListener, &display); wldata->ffwl_display_roundtrip(wldata->display); wldata->ffwl_proxy_destroy(output); diff --git a/src/detection/displayserver/linux/wayland/zwlr-output.c b/src/detection/displayserver/linux/wayland/zwlr-output.c index 63ab7146c1..861d7dc2ec 100644 --- a/src/detection/displayserver/linux/wayland/zwlr-output.c +++ b/src/detection/displayserver/linux/wayland/zwlr-output.c @@ -71,27 +71,27 @@ static void waylandZwlrCurrentModeListener(void* data, FF_MAYBE_UNUSED struct zw wldata->refreshRate = current->refreshRate; } +static const struct zwlr_output_head_v1_listener headListener = { + .name = (void*) ffWaylandOutputNameListener, + .description = (void*) ffWaylandOutputDescriptionListener, + .physical_size = (void*) stubListener, + .mode = waylandZwlrModeListener, + .enabled = (void*) stubListener, + .current_mode = waylandZwlrCurrentModeListener, + .position = (void*) stubListener, + .transform = waylandZwlrTransformListener, + .scale = waylandZwlrScaleListener, + .finished = (void*) stubListener, + .make = (void*) stubListener, + .model = (void*) stubListener, + .serial_number = (void*) stubListener, + .adaptive_sync = (void*) stubListener, +}; + static void waylandHandleZwlrHead(void *data, FF_MAYBE_UNUSED struct zwlr_output_manager_v1 *zwlr_output_manager_v1, struct zwlr_output_head_v1 *head) { WaylandData* wldata = data; - const struct zwlr_output_head_v1_listener headListener = { - .name = (void*) ffWaylandOutputNameListener, - .description = (void*) ffWaylandOutputDescriptionListener, - .physical_size = (void*) stubListener, - .mode = waylandZwlrModeListener, - .enabled = (void*) stubListener, - .current_mode = waylandZwlrCurrentModeListener, - .position = (void*) stubListener, - .transform = waylandZwlrTransformListener, - .scale = waylandZwlrScaleListener, - .finished = (void*) stubListener, - .make = (void*) stubListener, - .model = (void*) stubListener, - .serial_number = (void*) stubListener, - .adaptive_sync = (void*) stubListener, - }; - FF_LIST_AUTO_DESTROY modes = ffListCreate(sizeof(WaylandZwlrMode)); WaylandDisplay display = { .parent = wldata, From b0e51ba91d343500aa2247f05bd6e47237d22af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 5 Jul 2024 23:27:13 +0800 Subject: [PATCH 13/41] Global: fix memleaks --- src/detection/wmtheme/wmtheme_linux.c | 7 ++++--- src/modules/icons/icons.c | 6 ++++++ src/modules/theme/theme.c | 6 ++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/detection/wmtheme/wmtheme_linux.c b/src/detection/wmtheme/wmtheme_linux.c index 6b737a1338..bed430c435 100644 --- a/src/detection/wmtheme/wmtheme_linux.c +++ b/src/detection/wmtheme/wmtheme_linux.c @@ -6,6 +6,7 @@ #include "detection/gtk_qt/gtk_qt.h" #include "detection/displayserver/displayserver.h" #include "util/stringUtils.h" +#include "util/mallocHelper.h" static bool detectWMThemeFromConfigFile(const char* configFile, const char* themeRegex, const char* defaultValue, FFstrbuf* themeOrError) { @@ -91,8 +92,8 @@ static bool detectMutter(FFstrbuf* themeOrError) static bool detectMuffin(FFstrbuf* themeOrError) { - const char* name = ffSettingsGet("/org/cinnamon/theme/name", "org.cinnamon.theme", NULL, "name", FF_VARIANT_TYPE_STRING).strValue; - 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 = 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; if(name == NULL && theme == NULL) { @@ -133,7 +134,7 @@ static bool detectXFWM4(FFstrbuf* themeOrError) static bool detectOpenbox(const FFstrbuf* dePrettyName, FFstrbuf* themeOrError) { FF_STRBUF_AUTO_DESTROY absolutePath = ffStrbufCreateA(64); - const char *configFileSubpath = "openbox/rc.xml"; + const char *configFileSubpath = "openbox/rc.xml"; if (ffStrbufIgnCaseCompS(dePrettyName, "LXQt") == 0) configFileSubpath = "openbox/lxqt-rc.xml"; else if (ffStrbufIgnCaseCompS(dePrettyName, "LXDE") == 0) diff --git a/src/modules/icons/icons.c b/src/modules/icons/icons.c index 379a5d6a9b..51671bdeb8 100644 --- a/src/modules/icons/icons.c +++ b/src/modules/icons/icons.c @@ -40,6 +40,9 @@ void ffPrintIcons(FFIconsOptions* options) {FF_FORMAT_ARG_TYPE_STRBUF, &result.icons2, "icons2"}, })); } + + ffStrbufDestroy(&result.icons1); + ffStrbufDestroy(&result.icons2); } bool ffParseIconsCommandOptions(FFIconsOptions* options, const char* key, const char* value) @@ -94,6 +97,9 @@ void ffGenerateIconsJsonResult(FF_MAYBE_UNUSED FFIconsOptions* options, yyjson_m yyjson_mut_val* icons = yyjson_mut_obj_add_obj(doc, module, "result"); yyjson_mut_obj_add_strbuf(doc, icons, "icons1", &result.icons1); yyjson_mut_obj_add_strbuf(doc, icons, "icons2", &result.icons2); + + ffStrbufDestroy(&result.icons1); + ffStrbufDestroy(&result.icons2); } void ffPrintIconsHelpFormat(void) diff --git a/src/modules/theme/theme.c b/src/modules/theme/theme.c index b6eda5f06a..2f0f8032c9 100644 --- a/src/modules/theme/theme.c +++ b/src/modules/theme/theme.c @@ -40,6 +40,9 @@ void ffPrintTheme(FFThemeOptions* options) {FF_FORMAT_ARG_TYPE_STRBUF, &result.theme2, "theme2"}, })); } + + ffStrbufDestroy(&result.theme1); + ffStrbufDestroy(&result.theme2); } bool ffParseThemeCommandOptions(FFThemeOptions* options, const char* key, const char* value) @@ -94,6 +97,9 @@ void ffGenerateThemeJsonResult(FF_MAYBE_UNUSED FFThemeOptions* options, yyjson_m yyjson_mut_val* theme = yyjson_mut_obj_add_obj(doc, module, "result"); yyjson_mut_obj_add_strbuf(doc, theme, "theme1", &result.theme1); yyjson_mut_obj_add_strbuf(doc, theme, "theme2", &result.theme2); + + ffStrbufDestroy(&result.theme1); + ffStrbufDestroy(&result.theme2); } void ffPrintThemeHelpFormat(void) From 065b44ff5984985c8f6da0d8a5c7298beac806b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 6 Jul 2024 00:03:14 +0800 Subject: [PATCH 14/41] Display (Linux): better zxdg manager handling --- src/detection/displayserver/linux/wayland/global-output.c | 2 +- src/detection/displayserver/linux/wayland/wayland.c | 4 ++-- src/detection/displayserver/linux/wayland/wayland.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 55b287afd5..60a2881f9e 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -164,7 +164,7 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist ffStrbufDestroy(&display.edidName); } -void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) +void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) { struct wl_proxy* manager = wldata->ffwl_proxy_marshal_constructor_versioned((struct wl_proxy*) registry, WL_REGISTRY_BIND, &zxdg_output_manager_v1_interface, version, name, zxdg_output_manager_v1_interface.name, version, NULL); if(manager == NULL) diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 990df0f3bb..a98f7f5cd7 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -59,9 +59,9 @@ static void waylandGlobalAddListener(void* data, struct wl_registry* registry, u { ffWaylandHandleKdeOutputOrder(wldata, registry, name, version); } - else if(wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL && ffStrEquals(interface, zxdg_output_manager_v1_interface.name)) + else if((wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_GLOBAL || wldata->protocolType == FF_WAYLAND_PROTOCOL_TYPE_NONE) && ffStrEquals(interface, zxdg_output_manager_v1_interface.name)) { - ffWaylandHandleXdgOutput(wldata, registry, name, version); + ffWaylandHandleZxdgOutput(wldata, registry, name, version); } } diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index 4e3f72665b..a997b4e5fe 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -59,6 +59,6 @@ void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* regist void ffWaylandHandleZwlrOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); -void ffWaylandHandleXdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); +void ffWaylandHandleZxdgOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version); #endif From a61765c8b1387777be67d967bc2f69031c8ca399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 6 Jul 2024 00:10:59 +0800 Subject: [PATCH 15/41] Display (Linux): try fix building for old wayland version --- .../kde-output-device-v2-client-protocol.h | 92 +++++------ .../kde-output-order-v1-client-protocol.h | 58 +++---- .../xdg-output-unstable-v1-client-protocol.h | 146 +++++++++--------- 3 files changed, 148 insertions(+), 148 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h b/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h index 605f41e39e..6e585d281e 100644 --- a/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h +++ b/src/detection/displayserver/linux/wayland/kde-output-device-v2-client-protocol.h @@ -708,32 +708,32 @@ kde_output_device_v2_add_listener(struct kde_output_device_v2 *kde_output_device #define KDE_OUTPUT_DEVICE_V2_BRIGHTNESS_SINCE_VERSION 8 -/** @ingroup iface_kde_output_device_v2 */ -static inline void -kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data); -} +// /** @ingroup iface_kde_output_device_v2 */ +// static inline void +// kde_output_device_v2_set_user_data(struct kde_output_device_v2 *kde_output_device_v2, void *user_data) +// { +// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_v2, user_data); +// } -/** @ingroup iface_kde_output_device_v2 */ -static inline void * -kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2) -{ - return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2); -} +// /** @ingroup iface_kde_output_device_v2 */ +// static inline void * +// kde_output_device_v2_get_user_data(struct kde_output_device_v2 *kde_output_device_v2) +// { +// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_v2); +// } -static inline uint32_t -kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2) -{ - return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2); -} +// static inline uint32_t +// kde_output_device_v2_get_version(struct kde_output_device_v2 *kde_output_device_v2) +// { +// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_v2); +// } -/** @ingroup iface_kde_output_device_v2 */ -static inline void -kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2) -{ - wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2); -} +// /** @ingroup iface_kde_output_device_v2 */ +// static inline void +// kde_output_device_v2_destroy(struct kde_output_device_v2 *kde_output_device_v2) +// { +// wl_proxy_destroy((struct wl_proxy *) kde_output_device_v2); +// } /** * @ingroup iface_kde_output_device_mode_v2 @@ -811,32 +811,32 @@ kde_output_device_mode_v2_add_listener(struct kde_output_device_mode_v2 *kde_out #define KDE_OUTPUT_DEVICE_MODE_V2_REMOVED_SINCE_VERSION 1 -/** @ingroup iface_kde_output_device_mode_v2 */ -static inline void -kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data); -} +// /** @ingroup iface_kde_output_device_mode_v2 */ +// static inline void +// kde_output_device_mode_v2_set_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2, void *user_data) +// { +// wl_proxy_set_user_data((struct wl_proxy *) kde_output_device_mode_v2, user_data); +// } -/** @ingroup iface_kde_output_device_mode_v2 */ -static inline void * -kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) -{ - return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2); -} +// /** @ingroup iface_kde_output_device_mode_v2 */ +// static inline void * +// kde_output_device_mode_v2_get_user_data(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +// { +// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_device_mode_v2); +// } -static inline uint32_t -kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) -{ - return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2); -} +// static inline uint32_t +// kde_output_device_mode_v2_get_version(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +// { +// return wl_proxy_get_version((struct wl_proxy *) kde_output_device_mode_v2); +// } -/** @ingroup iface_kde_output_device_mode_v2 */ -static inline void -kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) -{ - wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2); -} +// /** @ingroup iface_kde_output_device_mode_v2 */ +// static inline void +// kde_output_device_mode_v2_destroy(struct kde_output_device_mode_v2 *kde_output_device_mode_v2) +// { +// wl_proxy_destroy((struct wl_proxy *) kde_output_device_mode_v2); +// } #ifdef __cplusplus } diff --git a/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h index 776e51de6d..40075998ff 100644 --- a/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h +++ b/src/detection/displayserver/linux/wayland/kde-output-order-v1-client-protocol.h @@ -96,35 +96,35 @@ kde_output_order_v1_add_listener(struct kde_output_order_v1 *kde_output_order_v1 */ #define KDE_OUTPUT_ORDER_V1_DESTROY_SINCE_VERSION 1 -/** @ingroup iface_kde_output_order_v1 */ -static inline void -kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data); -} - -/** @ingroup iface_kde_output_order_v1 */ -static inline void * -kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1); -} - -static inline uint32_t -kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1); -} - -/** - * @ingroup iface_kde_output_order_v1 - */ -static inline void -kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1, - KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY); -} +// /** @ingroup iface_kde_output_order_v1 */ +// static inline void +// kde_output_order_v1_set_user_data(struct kde_output_order_v1 *kde_output_order_v1, void *user_data) +// { +// wl_proxy_set_user_data((struct wl_proxy *) kde_output_order_v1, user_data); +// } + +// /** @ingroup iface_kde_output_order_v1 */ +// static inline void * +// kde_output_order_v1_get_user_data(struct kde_output_order_v1 *kde_output_order_v1) +// { +// return wl_proxy_get_user_data((struct wl_proxy *) kde_output_order_v1); +// } + +// static inline uint32_t +// kde_output_order_v1_get_version(struct kde_output_order_v1 *kde_output_order_v1) +// { +// return wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1); +// } + +// /** +// * @ingroup iface_kde_output_order_v1 +// */ +// static inline void +// kde_output_order_v1_destroy(struct kde_output_order_v1 *kde_output_order_v1) +// { +// wl_proxy_marshal_flags((struct wl_proxy *) kde_output_order_v1, +// KDE_OUTPUT_ORDER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) kde_output_order_v1), WL_MARSHAL_FLAG_DESTROY); +// } #ifdef __cplusplus } diff --git a/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h index daba88fa8d..c4f6833c23 100644 --- a/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h +++ b/src/detection/displayserver/linux/wayland/xdg-output-unstable-v1-client-protocol.h @@ -141,56 +141,56 @@ extern const struct wl_interface zxdg_output_v1_interface; */ #define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1 -/** @ingroup iface_zxdg_output_manager_v1 */ -static inline void -zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data); -} +// /** @ingroup iface_zxdg_output_manager_v1 */ +// static inline void +// zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data) +// { +// wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data); +// } -/** @ingroup iface_zxdg_output_manager_v1 */ -static inline void * -zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1); -} +// /** @ingroup iface_zxdg_output_manager_v1 */ +// static inline void * +// zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +// { +// return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1); +// } -static inline uint32_t -zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1); -} +// static inline uint32_t +// zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +// { +// return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1); +// } -/** - * @ingroup iface_zxdg_output_manager_v1 - * - * Using this request a client can tell the server that it is not - * going to use the xdg_output_manager object anymore. - * - * Any objects already created through this instance are not affected. - */ -static inline void -zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, - ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY); -} +// /** +// * @ingroup iface_zxdg_output_manager_v1 +// * +// * Using this request a client can tell the server that it is not +// * going to use the xdg_output_manager object anymore. +// * +// * Any objects already created through this instance are not affected. +// */ +// static inline void +// zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1) +// { +// wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, +// ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY); +// } -/** - * @ingroup iface_zxdg_output_manager_v1 - * - * This creates a new xdg_output object for the given wl_output. - */ -static inline struct zxdg_output_v1 * -zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output) -{ - struct wl_proxy *id; +// /** +// * @ingroup iface_zxdg_output_manager_v1 +// * +// * This creates a new xdg_output object for the given wl_output. +// */ +// static inline struct zxdg_output_v1 * +// zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output) +// { +// struct wl_proxy *id; - id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, - ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output); +// id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1, +// ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output); - return (struct zxdg_output_v1 *) id; -} +// return (struct zxdg_output_v1 *) id; +// } /** * @ingroup iface_zxdg_output_v1 @@ -374,38 +374,38 @@ zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1, */ #define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1 -/** @ingroup iface_zxdg_output_v1 */ -static inline void -zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data); -} +// /** @ingroup iface_zxdg_output_v1 */ +// static inline void +// zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data) +// { +// wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data); +// } -/** @ingroup iface_zxdg_output_v1 */ -static inline void * -zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1) -{ - return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1); -} +// /** @ingroup iface_zxdg_output_v1 */ +// static inline void * +// zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1) +// { +// return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1); +// } -static inline uint32_t -zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1) -{ - return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1); -} +// static inline uint32_t +// zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1) +// { +// return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1); +// } -/** - * @ingroup iface_zxdg_output_v1 - * - * Using this request a client can tell the server that it is not - * going to use the xdg_output object anymore. - */ -static inline void -zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1) -{ - wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1, - ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY); -} +// /** +// * @ingroup iface_zxdg_output_v1 +// * +// * Using this request a client can tell the server that it is not +// * going to use the xdg_output object anymore. +// */ +// static inline void +// zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1) +// { +// wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1, +// ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY); +// } #ifdef __cplusplus } From 3b1b81437eb656c4d98bc9548d0d902d22beca84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 6 Jul 2024 08:56:07 +0800 Subject: [PATCH 16/41] Battery (Linux): add comments [ci skip] --- src/detection/battery/battery_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/battery/battery_linux.c b/src/detection/battery/battery_linux.c index d77968a378..2f073aca14 100644 --- a/src/detection/battery/battery_linux.c +++ b/src/detection/battery/battery_linux.c @@ -33,7 +33,7 @@ static void parseBattery(FFstrbuf* dir, const char* id, FFBatteryOptions* option //capacity must exist and be not empty ffStrbufAppendS(dir, "/capacity"); - bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); + bool available = ffReadFileBuffer(dir->chars, &tmpBuffer); // This is expensive in my laptop ffStrbufSubstrBefore(dir, dirLength); if (!available) From 94b6f0fbd148974b709c8be8aac6616b2520eb29 Mon Sep 17 00:00:00 2001 From: David Adam Date: Sun, 7 Jul 2024 22:36:52 +0800 Subject: [PATCH 17/41] fish completion: pipe straight to Python (#1076) In https://github.com/fish-shell/fish-shell/issues/10599, a user of an older version of fish has run into an issue with the fastfetch completion requiring a relatively new version. Rewrite the (really quite clever) embedded Python into a straight pipe, dropping the string transformation entirely. Does require some escaping of quotes to support Python < 3.12. --- completions/fastfetch.fish | 91 ++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/completions/fastfetch.fish b/completions/fastfetch.fish index 90ab32bdb8..494de27308 100755 --- a/completions/fastfetch.fish +++ b/completions/fastfetch.fish @@ -54,51 +54,48 @@ function __fastfetch_complete_structure end end -string match -r -a -g "^###> ?(.*)" < (status -f) | string collect | python3 | source +echo ' +import json, subprocess, sys -###> #!/usr/bin/env python3 -###> -###> import json, subprocess, sys -###> -###> def main(): -###> data: dict[str, list[dict]] = json.loads(subprocess.check_output(['fastfetch', '--help-raw'])) -###> -###> for key in data: -###> for flag in data[key]: -###> if flag.get('pseudo', False): -###> continue -###> -###> command_prefix: str = f'complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}"'; -###> if 'short' in flag: -###> command_prefix += f' -o "{flag["short"]}"' -###> -###> if 'arg' in flag: -###> type: str = flag['arg']['type']; -###> if type == 'bool': -###> print(f'{command_prefix} -x -a "(__fastfetch_complete_bool)"') -###> elif type == 'color': -###> print(f'{command_prefix} -x -a "(__fastfetch_complete_color)"') -###> elif type == 'command': -###> print(f'{command_prefix} -x -a "(__fastfetch_complete_command)"') -###> elif type == 'config': -###> print(f'{command_prefix} -x -a "(__fastfetch_complete_config)"') -###> elif type == 'enum': -###> temp: str = ' '.join(flag["arg"]["enum"]) -###> print(f'{command_prefix} -x -a "{temp}"') -###> elif type == 'logo': -###> print(f'{command_prefix} -x -a "(__fastfetch_complete_logo)"') -###> elif type == 'structure': -###> print(f'{command_prefix} -x -a "(__fish_complete_list : __fastfetch_complete_structure)"') -###> elif type == 'path': -###> print(f'{command_prefix} -r -F') -###> else: -###> print(f'{command_prefix} -x') -###> else: -###> print(f'{command_prefix} -f') -###> -###> if __name__ == "__main__": -###> try: -###> main() -###> except: -###> sys.exit(1) -###> +def main(): + data: dict[str, list[dict]] = json.loads(subprocess.check_output(["fastfetch", "--help-raw"])) + + for key in data: + for flag in data[key]: + if flag.get("pseudo", False): + continue + + command_prefix = f"""complete -c fastfetch -d "{flag["desc"]}" -l "{flag["long"]}\"""" + if "short" in flag: + command_prefix += f""" -o {flag["short"]}""" + + if "arg" in flag: + type: str = flag["arg"]["type"]; + if type == "bool": + print(f"{command_prefix} -x -a \"(__fastfetch_complete_bool)\"") + elif type == "color": + print(f"{command_prefix} -x -a \"(__fastfetch_complete_color)\"") + elif type == "command": + print(f"{command_prefix} -x -a \"(__fastfetch_complete_command)\"") + elif type == "config": + print(f"{command_prefix} -x -a \"(__fastfetch_complete_config)\"") + elif type == "enum": + temp: str = " ".join(flag["arg"]["enum"]) + print(f"{command_prefix} -x -a \"{temp}\"") + elif type == "logo": + print(f"{command_prefix} -x -a \"(__fastfetch_complete_logo)\"") + elif type == "structure": + print(f"{command_prefix} -x -a \"(__fish_complete_list : __fastfetch_complete_structure)\"") + elif type == "path": + print(f"{command_prefix} -r -F") + else: + print(f"{command_prefix} -x") + else: + print(f"{command_prefix} -f") + +if __name__ == "__main__": + try: + main() + except: + sys.exit(1) +' | python3 | source From 8402dba0d9ec67619a801284d95fd40d6c438b60 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 6 Jul 2024 12:11:36 +0800 Subject: [PATCH 18/41] Util (Base64): silence compiler warnings --- src/util/base64.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/util/base64.c b/src/util/base64.c index 866d59428c..0fbcb41e6f 100644 --- a/src/util/base64.c +++ b/src/util/base64.c @@ -37,7 +37,7 @@ void ffBase64EncodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *out_size = (uint32_t)(out - output); } -static char decode_table[256]; +static uint8_t decode_table[256]; void init_decode_table() { @@ -59,10 +59,7 @@ void init_decode_table() } while (ch++ < 0xFF); } -#define next_char(x) \ - char x = decode_table[(unsigned char)*str++]; \ - if (x < 0) \ - return false; +#define next_char(x) uint8_t x = decode_table[(uint8_t) *str++]; bool ffBase64DecodeRaw(uint32_t size, const char *str, uint32_t *out_size, char *output) { From 4d1c62947b69858f7a6d1e1e5bab257a4aee20d6 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 08:52:15 +0800 Subject: [PATCH 19/41] GPU (Linux): don't detect frequency for AMD cards It's current frequency and may hang for some reason --- src/detection/gpu/gpu.h | 2 +- src/detection/gpu/gpu_linux.c | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 281b43ae10..0ba9ea74ee 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -32,7 +32,7 @@ typedef struct FFGPUResult FFstrbuf platformApi; double temperature; int32_t coreCount; - double frequency; // Real time clock frequency in GHz + double frequency; // Maximum time clock frequency in GHz FFGPUMemory dedicated; FFGPUMemory shared; uint64_t deviceId; // Used internally, may be uninitialized diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 3a4ecf3d65..96921085d8 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -92,11 +92,6 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, gpu->temperature = (double) value / 1000; } - ffStrbufSubstrBefore(pciDir, hwmonLen); - ffStrbufAppendS(pciDir, "freq1_input"); // The gfx/compute clock in hertz - if (ffReadFileBuffer(pciDir->chars, buffer) && (value = ffStrbufToUInt(buffer, 0))) - gpu->frequency = (double) value / (1000 * 1000 * 1000); - if (options->driverSpecific) { ffStrbufSubstrBefore(pciDir, pciDirLen); From f8d5f56deeac8718b93b78e8396df7c0c9462707 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 09:11:53 +0800 Subject: [PATCH 20/41] GPU (Linux): remove possible overhead --- src/common/io/io.h | 24 ++++++++++++++++-------- src/detection/gpu/gpu_linux.c | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/common/io/io.h b/src/common/io/io.h index 305cb03e7c..2958ac4545 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -101,17 +101,25 @@ static inline bool ffPathExists(const char* path, FFPathType pathType) #else - struct stat fileStat; - if(stat(path, &fileStat) != 0) - return false; + if (pathType == FF_PATHTYPE_ANY) + { + // Zero overhead + return access(path, F_OK) == 0; + } + else + { + struct stat fileStat; + if(stat(path, &fileStat) != 0) + return false; - unsigned int mode = fileStat.st_mode & S_IFMT; + unsigned int mode = fileStat.st_mode & S_IFMT; - if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR) - return true; + if(pathType & FF_PATHTYPE_FILE && mode != S_IFDIR) + return true; - if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR) - return true; + if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR) + return true; + } #endif diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 96921085d8..dc860b099b 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -78,7 +78,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, const uint32_t hwmonLen = pciDir->length; ffStrbufAppendS(pciDir, "in1_input"); // Northbridge voltage in millivolts (APUs only) - if (ffPathExists(pciDir->chars, FF_PATHTYPE_FILE)) + if (ffPathExists(pciDir->chars, FF_PATHTYPE_ANY)) gpu->type = FF_GPU_TYPE_INTEGRATED; else gpu->type = FF_GPU_TYPE_DISCRETE; From 4f70c16d636c308e8fbafcfddb5ee30ae0163a6b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 09:12:18 +0800 Subject: [PATCH 21/41] Editor: don't print `()` --- src/modules/editor/editor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/editor/editor.c b/src/modules/editor/editor.c index 7a9f8d3645..c7ac703b13 100644 --- a/src/modules/editor/editor.c +++ b/src/modules/editor/editor.c @@ -30,7 +30,7 @@ void ffPrintEditor(FFEditorOptions* options) { ffStrbufWriteTo(&result.exe, stdout); if (result.version.length) - printf(" (%s)", result.version.chars); + printf(" %s", result.version.chars); } else { From f9ce2fae0e04c2d2ff1063729e50f3ce213c78e6 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 11:02:54 +0800 Subject: [PATCH 22/41] Display (Linux): improve id generation for wayland --- .../displayserver/linux/wayland/kde-output.c | 2 +- src/detection/displayserver/linux/wayland/wayland.c | 2 +- src/detection/displayserver/linux/wayland/wayland.h | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/kde-output.c b/src/detection/displayserver/linux/wayland/kde-output.c index 232b478920..8d7ab51abe 100644 --- a/src/detection/displayserver/linux/wayland/kde-output.c +++ b/src/detection/displayserver/linux/wayland/kde-output.c @@ -228,7 +228,7 @@ static void waylandKdeOutputOrderListener(void *data, FF_MAYBE_UNUSED struct kde { uint64_t* id = (uint64_t*) data; if (*id == 0) - strncpy((char*) id, output_name, sizeof(*id)); + *id = ffWaylandGenerateIdFromName(output_name); } void ffWaylandHandleKdeOutputOrder(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index a98f7f5cd7..660e427712 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -140,7 +140,7 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const display->type = FF_DISPLAY_TYPE_EXTERNAL; if (!display->edidName.length) ffdsMatchDrmConnector(name, &display->edidName); - strncpy((char*) &display->id, name, sizeof(display->id)); + display->id = ffWaylandGenerateIdFromName(name); ffStrbufAppendS(&display->name, name); } diff --git a/src/detection/displayserver/linux/wayland/wayland.h b/src/detection/displayserver/linux/wayland/wayland.h index a997b4e5fe..21f1979c39 100644 --- a/src/detection/displayserver/linux/wayland/wayland.h +++ b/src/detection/displayserver/linux/wayland/wayland.h @@ -52,6 +52,17 @@ inline static void stubListener(void* data, ...) (void) data; } +inline static uint64_t ffWaylandGenerateIdFromName(const char* name) +{ + uint64_t id = 0; + size_t len = strlen(name); + if (len > sizeof(id)) + memcpy(&id, name + (len - sizeof(id)), sizeof(id)); // copy the last 8 bytes + else if (len > 0) + memcpy(&id, name, len); + return id; +} + void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name); void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output, const char* description); From d628bdea5a51912d899317f355a053c1638537dc Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 10:15:00 +0800 Subject: [PATCH 23/41] Display (Linux): support primary display detection for GNOME & Cinnamon --- .../linux/wayland/global-output.c | 4 +- .../displayserver/linux/wayland/wayland.c | 74 ++++++++++++++++++- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/global-output.c b/src/detection/displayserver/linux/wayland/global-output.c index 60a2881f9e..8d868ea756 100644 --- a/src/detection/displayserver/linux/wayland/global-output.c +++ b/src/detection/displayserver/linux/wayland/global-output.c @@ -65,8 +65,8 @@ static struct zxdg_output_v1_listener zxdgOutputListener = { .logical_position = (void*) stubListener, .logical_size = handleXdgLogicalSize, .done = (void*) stubListener, - .name = (void*) stubListener, - .description = (void*) stubListener, + .name = (void*) ffWaylandOutputNameListener, + .description = (void*) ffWaylandOutputDescriptionListener, }; void ffWaylandHandleGlobalOutput(WaylandData* wldata, struct wl_registry* registry, uint32_t name, uint32_t version) diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 660e427712..4b6d908e25 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -9,6 +9,8 @@ #include +#include "common/properties.h" + #include "wayland.h" #include "wlr-output-management-unstable-v1-client-protocol.h" #include "kde-output-device-v2-client-protocol.h" @@ -16,23 +18,26 @@ #include "xdg-output-unstable-v1-client-protocol.h" #ifndef __FreeBSD__ -static void waylandDetectWM(int fd, FFDisplayServerResult* result) +static bool waylandDetectWM(int fd, FFDisplayServerResult* result) { struct ucred ucred; socklen_t len = sizeof(struct ucred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) - return; + return false; FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreate(); ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed. ffReadFileBuffer(procPath.chars, &result->wmProcessName); ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path + puts(result->wmProcessName.chars); + return true; } #else static void waylandDetectWM(int fd, FFDisplayServerResult* result) { FF_UNUSED(fd, result); + return false; } #endif @@ -112,6 +117,67 @@ bool detectWayland(FFDisplayServerResult* result) data.ffwl_proxy_destroy(registry); ffwl_display_disconnect(data.display); + if(data.primaryDisplayId == 0 && result->wmProcessName.length > 0) + { + const char* fileName = ffStrbufEqualS(&result->wmProcessName, "gnome-shell") + ? "monitors.xml" + : ffStrbufEqualS(&result->wmProcessName, "cinnamon") + ? "cinnamon-monitors.xml" + : NULL; + if (fileName) + { + FF_STRBUF_AUTO_DESTROY monitorsXml = ffStrbufCreate(); + FF_LIST_FOR_EACH(FFstrbuf, basePath, instance.state.platform.configDirs) + { + char path[1024]; + snprintf(path, sizeof(path) - 1, "%s%s", basePath->chars, fileName); + if (ffReadFileBuffer(path, &monitorsXml)) + break; + } + if (monitorsXml.length) + { + // + // + // + // 0 + // 0 + // 1.7489879131317139 + // yes + // + // + // Virtual-1 + // unknown + // unknown + // unknown + // + // + // 3456 + // 2160 + // 60.000068664550781 + // + // + // + // + // + uint32_t start = ffStrbufFirstIndexS(&monitorsXml, "yes"); + if (start < monitorsXml.length) + { + start = ffStrbufNextIndexS(&monitorsXml, start, ""); + if (start < monitorsXml.length) + { + uint32_t end = ffStrbufNextIndexS(&monitorsXml, start, ""); + if (end < monitorsXml.length) + { + ffStrbufSubstrBefore(&monitorsXml, end); + const char* name = monitorsXml.chars + start + strlen(""); + data.primaryDisplayId = ffWaylandGenerateIdFromName(name); + } + } + } + } + } + } + if(data.primaryDisplayId) { FF_LIST_FOR_EACH(FFDisplayResult, d, data.result->displays) @@ -134,6 +200,8 @@ bool detectWayland(FFDisplayServerResult* result) void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const char *name) { WaylandDisplay* display = data; + if (display->id) return; + if(ffStrStartsWith(name, "eDP-")) display->type = FF_DISPLAY_TYPE_BUILTIN; else if(ffStrStartsWith(name, "HDMI-")) @@ -147,6 +215,8 @@ void ffWaylandOutputNameListener(void* data, FF_MAYBE_UNUSED void* output, const void ffWaylandOutputDescriptionListener(void* data, FF_MAYBE_UNUSED void* output, const char* description) { WaylandDisplay* display = data; + if (display->description.length) return; + while (*description == ' ') ++description; if (!ffStrEquals(description, "Unknown Display") && !ffStrContains(description, "(null)")) ffStrbufAppendS(&display->description, description); From ddc910e92436d72dc4de43330bf375bad7fcfc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 8 Jul 2024 14:20:57 +0800 Subject: [PATCH 24/41] Base64: silence warnings --- src/util/base64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/base64.c b/src/util/base64.c index 0fbcb41e6f..f59438e834 100644 --- a/src/util/base64.c +++ b/src/util/base64.c @@ -55,7 +55,7 @@ void init_decode_table() code = 0x3E; if (ch == '/' || ch == '_') code = 0x3F; - decode_table[ch] = (char) code; + decode_table[ch] = (uint8_t) code; } while (ch++ < 0xFF); } From 9c095967fce58aae50d2c1b05c848a6a641a9dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 8 Jul 2024 15:04:28 +0800 Subject: [PATCH 25/41] Separator: don't print color in `--pipe` mode --- src/modules/separator/separator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/separator/separator.c b/src/modules/separator/separator.c index 87ea882e65..f1b9ecc35e 100644 --- a/src/modules/separator/separator.c +++ b/src/modules/separator/separator.c @@ -4,6 +4,7 @@ #include "util/stringUtils.h" #include "util/mallocHelper.h" #include "util/wcwidth.h" +#include "util/textModifier.h" #include @@ -46,7 +47,7 @@ void ffPrintSeparator(FFSeparatorOptions* options) + (fqdn ? platform->hostName.length : ffStrbufFirstIndexC(&platform->hostName, '.')); // host name ffLogoPrintLine(); - if(options->outputColor.length) + if(options->outputColor.length && !instance.config.display.pipe) ffPrintColor(&options->outputColor); if(__builtin_expect(options->string.length == 1, 1)) { @@ -88,6 +89,8 @@ void ffPrintSeparator(FFSeparatorOptions* options) } } } + if(options->outputColor.length && !instance.config.display.pipe) + fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); putchar('\n'); setlocale(LC_CTYPE, "C"); } From 789f1e34ef7e8c6352b82dff155b9478b283d4fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 8 Jul 2024 15:05:42 +0800 Subject: [PATCH 26/41] Fastfetch: don't mess output with `--stat` in `--pipe` mode --- src/common/commandoption.c | 5 +---- src/common/jsonconfig.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/common/commandoption.c b/src/common/commandoption.c index 3d9c937426..c906d94164 100644 --- a/src/common/commandoption.c +++ b/src/common/commandoption.c @@ -130,10 +130,7 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc) { char str[32]; int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms); - if(instance.config.display.pipe) - puts(str); - else - printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load } } diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index 735b93032a..6f7cb6d703 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -213,10 +213,7 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) { char str[32]; int len = snprintf(str, sizeof str, "%" PRIu64 "ms", ms); - if(instance.config.display.pipe) - puts(str); - else - printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load } } From 545267bb7ed27927c27126864ba92396bb52c834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 8 Jul 2024 15:21:12 +0800 Subject: [PATCH 27/41] Percentage: support percent bar in custom formatting Fix #1075 --- src/modules/battery/battery.c | 14 +++++++---- src/modules/bluetooth/bluetooth.c | 14 +++++++---- src/modules/brightness/brightness.c | 14 +++++++---- src/modules/cpuusage/cpuusage.c | 38 +++++++++++++++++++---------- src/modules/disk/disk.c | 27 +++++++++++++------- src/modules/gamepad/gamepad.c | 14 +++++++---- src/modules/memory/memory.c | 14 +++++++---- src/modules/sound/sound.c | 14 +++++++---- src/modules/swap/swap.c | 14 +++++++---- 9 files changed, 106 insertions(+), 57 deletions(-) diff --git a/src/modules/battery/battery.c b/src/modules/battery/battery.c index 02a3a475d6..f098bf6ecd 100644 --- a/src/modules/battery/battery.c +++ b/src/modules/battery/battery.c @@ -7,7 +7,7 @@ #include "modules/battery/battery.h" #include "util/stringUtils.h" -#define FF_BATTERY_NUM_FORMAT_ARGS 9 +#define FF_BATTERY_NUM_FORMAT_ARGS 10 static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uint8_t index) { @@ -57,20 +57,23 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin } else { - FF_STRBUF_AUTO_DESTROY capacityStr = ffStrbufCreate(); - ffPercentAppendNum(&capacityStr, result->capacity, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY capacityNum = ffStrbufCreate(); + ffPercentAppendNum(&capacityNum, result->capacity, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY capacityBar = ffStrbufCreate(); + ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs); FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate(); ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer, "manufacturer"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "model-name"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->technology, "technology"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &capacityStr, "capacity"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &capacityNum, "capacity"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->status, "status"}, {FF_FORMAT_ARG_TYPE_STRBUF, &tempStr, "temperature"}, {FF_FORMAT_ARG_TYPE_UINT, &result->cycleCount, "cycle-count"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->serial, "serial"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->manufactureDate, "manufacture-date"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &capacityBar, "capacity-bar"}, })); } } @@ -225,12 +228,13 @@ void ffPrintBatteryHelpFormat(void) "Battery manufacturer - manufacturer", "Battery model name - model-name", "Battery technology - technology", - "Battery capacity (percentage) - capacity", + "Battery capacity (percentage num) - capacity", "Battery status - status", "Battery temperature (formatted) - temperature", "Battery cycle count - cycle-count", "Battery serial number - serial", "Battery manufactor date - manufacture-date", + "Battery capacity (percentage bar) - capacity-bar", })); } diff --git a/src/modules/bluetooth/bluetooth.c b/src/modules/bluetooth/bluetooth.c index 578a201bfd..d3c089df41 100644 --- a/src/modules/bluetooth/bluetooth.c +++ b/src/modules/bluetooth/bluetooth.c @@ -5,7 +5,7 @@ #include "modules/bluetooth/bluetooth.h" #include "util/stringUtils.h" -#define FF_BLUETOOTH_NUM_FORMAT_ARGS 5 +#define FF_BLUETOOTH_NUM_FORMAT_ARGS 6 static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* device, uint8_t index) { @@ -29,15 +29,18 @@ static void printDevice(FFBluetoothOptions* options, const FFBluetoothResult* de } else { - FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate(); - ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); + ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); + ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_BLUETOOTH_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BLUETOOTH_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &device->name, "name"}, {FF_FORMAT_ARG_TYPE_STRBUF, &device->address, "address"}, {FF_FORMAT_ARG_TYPE_STRBUF, &device->type, "type"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr, "battery-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageNum, "battery-percentage"}, {FF_FORMAT_ARG_TYPE_BOOL, &device->connected, "connected"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageBar, "battery-percentage-bar"}, })); } } @@ -178,8 +181,9 @@ void ffPrintBluetoothHelpFormat(void) "Name - name", "Address - address", "Type - type", - "Battery percentage - battery-percentage", + "Battery percentage number - battery-percentage", "Is connected - connected", + "Battery percentage bar - battery-percentage-bar", })); } diff --git a/src/modules/brightness/brightness.c b/src/modules/brightness/brightness.c index 01d0beb8f4..8030c6bef5 100644 --- a/src/modules/brightness/brightness.c +++ b/src/modules/brightness/brightness.c @@ -5,7 +5,7 @@ #include "modules/brightness/brightness.h" #include "util/stringUtils.h" -#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 5 +#define FF_BRIGHTNESS_NUM_FORMAT_ARGS 6 void ffPrintBrightness(FFBrightnessOptions* options) { @@ -67,14 +67,17 @@ void ffPrintBrightness(FFBrightnessOptions* options) } else { - FF_STRBUF_AUTO_DESTROY valueStr = ffStrbufCreate(); - ffPercentAppendNum(&valueStr, percent, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY valueNum = ffStrbufCreate(); + ffPercentAppendNum(&valueNum, percent, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY valueBar = ffStrbufCreate(); + ffPercentAppendBar(&valueBar, percent, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BRIGHTNESS_NUM_FORMAT_ARGS, ((FFformatarg[]) { - {FF_FORMAT_ARG_TYPE_STRBUF, &valueStr, "percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &valueNum, "percentage"}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->name, "name"}, {FF_FORMAT_ARG_TYPE_DOUBLE, &item->max, "max"}, {FF_FORMAT_ARG_TYPE_DOUBLE, &item->min, "min"}, {FF_FORMAT_ARG_TYPE_DOUBLE, &item->current, "current"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &item->current, "percentage-bar"}, })); } @@ -175,11 +178,12 @@ void ffGenerateBrightnessJsonResult(FF_MAYBE_UNUSED FFBrightnessOptions* options void ffPrintBrightnessHelpFormat(void) { FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_BRIGHTNESS_MODULE_NAME, "{1}", FF_BRIGHTNESS_NUM_FORMAT_ARGS, ((const char* []) { - "Screen brightness (percentage) - percentage", + "Screen brightness (percentage num) - percentage", "Screen name - name", "Maximum brightness value - max", "Minimum brightness value - min", "Current brightness value - current", + "Screen brightness (percentage bar) - percentage-bar", })); } diff --git a/src/modules/cpuusage/cpuusage.c b/src/modules/cpuusage/cpuusage.c index b90e475bc2..1629e237a4 100644 --- a/src/modules/cpuusage/cpuusage.c +++ b/src/modules/cpuusage/cpuusage.c @@ -6,7 +6,7 @@ #include "util/stringUtils.h" #define FF_CPUUSAGE_DISPLAY_NAME "CPU Usage" -#define FF_CPUUSAGE_NUM_FORMAT_ARGS 5 +#define FF_CPUUSAGE_NUM_FORMAT_ARGS 8 void ffPrintCPUUsage(FFCPUUsageOptions* options) { @@ -73,18 +73,27 @@ void ffPrintCPUUsage(FFCPUUsageOptions* options) } else { - FF_STRBUF_AUTO_DESTROY avgStr = ffStrbufCreate(); - ffPercentAppendNum(&avgStr, avgValue, options->percent, false, &options->moduleArgs); - FF_STRBUF_AUTO_DESTROY minStr = ffStrbufCreate(); - ffPercentAppendNum(&minStr, minValue, options->percent, false, &options->moduleArgs); - FF_STRBUF_AUTO_DESTROY maxStr = ffStrbufCreate(); - ffPercentAppendNum(&maxStr, maxValue, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY avgNum = ffStrbufCreate(); + ffPercentAppendNum(&avgNum, avgValue, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY avgBar = ffStrbufCreate(); + ffPercentAppendBar(&avgBar, avgValue, options->percent, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY minNum = ffStrbufCreate(); + ffPercentAppendNum(&minNum, minValue, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY minBar = ffStrbufCreate(); + ffPercentAppendBar(&minBar, minValue, options->percent, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY maxNum = ffStrbufCreate(); + ffPercentAppendNum(&maxNum, maxValue, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY maxBar = ffStrbufCreate(); + ffPercentAppendBar(&maxBar, maxValue, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_CPUUSAGE_DISPLAY_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPUUSAGE_NUM_FORMAT_ARGS, ((FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &avgStr, "avg"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &maxStr, "max"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &avgNum, "avg"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &maxNum, "max"}, {FF_FORMAT_ARG_TYPE_UINT, &maxIndex, "max-index"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &minStr, "min"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &minNum, "min"}, {FF_FORMAT_ARG_TYPE_UINT, &minIndex, "min-index"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &avgBar, "avg-bar"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &maxBar, "max-bar"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &minBar, "min-bar"}, })); } } @@ -167,11 +176,14 @@ void ffGenerateCPUUsageJsonResult(FF_MAYBE_UNUSED FFCPUUsageOptions* options, yy void ffPrintCPUUsageHelpFormat(void) { FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_CPUUSAGE_MODULE_NAME, "{1}", FF_CPUUSAGE_NUM_FORMAT_ARGS, ((const char* []) { - "CPU usage (percentage, average) - avg", - "CPU usage (percentage, maximum) - max", + "CPU usage (percentage num, average) - avg", + "CPU usage (percentage num, maximum) - max", "CPU core index of maximum usage - max-index", - "CPU usage (percentage, minimum) - min", + "CPU usage (percentage num, minimum) - min", "CPU core index of minimum usage - min-index", + "CPU usage (percentage bar, average) - avg-bar", + "CPU usage (percentage bar, maximum) - max-bar", + "CPU usage (percentage bar, minimum) - min-bar", })); } diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 48b494efed..3996ff6479 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -7,7 +7,7 @@ #include "modules/disk/disk.h" #include "util/stringUtils.h" -#define FF_DISK_NUM_FORMAT_ARGS 12 +#define FF_DISK_NUM_FORMAT_ARGS 14 #pragma GCC diagnostic ignored "-Wsign-conversion" static void printDisk(FFDiskOptions* options, const FFDisk* disk) @@ -104,11 +104,16 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk) } else { - FF_STRBUF_AUTO_DESTROY bytesPercentageStr = ffStrbufCreate(); - ffPercentAppendNum(&bytesPercentageStr, bytesPercentage, options->percent, false, &options->moduleArgs); - FF_STRBUF_AUTO_DESTROY filesPercentageStr = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY bytesPercentageNum = ffStrbufCreate(); + ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY bytesPercentageBar = ffStrbufCreate(); + ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs); + double filesPercentage = disk->filesTotal > 0 ? ((double) disk->filesUsed / (double) disk->filesTotal) * 100.0 : 0; - ffPercentAppendNum(&filesPercentageStr, filesPercentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY filesPercentageNum = ffStrbufCreate(); + ffPercentAppendNum(&filesPercentageNum, filesPercentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY filesPercentageBar = ffStrbufCreate(); + ffPercentAppendBar(&filesPercentageBar, filesPercentage, options->percent, &options->moduleArgs); bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT); bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT); @@ -117,16 +122,18 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk) FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISK_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty, "size-used"}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty, "size-total"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageStr, "size-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageNum, "size-percentage"}, {FF_FORMAT_ARG_TYPE_UINT, &disk->filesUsed, "files-used"}, {FF_FORMAT_ARG_TYPE_UINT, &disk->filesTotal, "files-total"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &filesPercentageStr, "files-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &filesPercentageNum, "files-percentage"}, {FF_FORMAT_ARG_TYPE_BOOL, &isExternal, "is-external"}, {FF_FORMAT_ARG_TYPE_BOOL, &isHidden, "is-hidden"}, {FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem, "filesystem"}, {FF_FORMAT_ARG_TYPE_STRBUF, &disk->name, "name"}, {FF_FORMAT_ARG_TYPE_BOOL, &isReadOnly, "is-readonly"}, {FF_FORMAT_ARG_TYPE_STRING, ffTimeToShortStr(disk->createTime), "create-time"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageBar, "size-percentage-bar"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &filesPercentageBar, "files-percentage-bar"}, })); } } @@ -430,16 +437,18 @@ void ffPrintDiskHelpFormat(void) FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_DISK_MODULE_NAME, "{1} / {2} ({3}) - {9}", FF_DISK_NUM_FORMAT_ARGS, ((const char* []) { "Size used - size-used", "Size total - size-total", - "Size percentage - size-percentage", + "Size percentage num - size-percentage", "Files used - files-used", "Files total - files-total", - "Files percentage - files-percentage", + "Files percentage num - files-percentage", "True if external volume - is-external", "True if hidden volume - is-hidden", "Filesystem - filesystem", "Label / name - name", "True if read-only - is-readonly", "Create time in local timezone - create-time", + "Size percentage bar - size-percentage-bar", + "Files percentage bar - files-percentage-bar", })); } diff --git a/src/modules/gamepad/gamepad.c b/src/modules/gamepad/gamepad.c index 062e375b86..e6fff3622b 100644 --- a/src/modules/gamepad/gamepad.c +++ b/src/modules/gamepad/gamepad.c @@ -5,7 +5,7 @@ #include "modules/gamepad/gamepad.h" #include "util/stringUtils.h" -#define FF_GAMEPAD_NUM_FORMAT_ARGS 3 +#define FF_GAMEPAD_NUM_FORMAT_ARGS 4 static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device, uint8_t index) { @@ -25,13 +25,16 @@ static void printDevice(FFGamepadOptions* options, const FFGamepadDevice* device } else { - FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate(); - ffPercentAppendNum(&percentageStr, device->battery, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); + ffPercentAppendNum(&percentageNum, device->battery, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); + ffPercentAppendBar(&percentageBar, device->battery, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_GAMEPAD_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_GAMEPAD_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_STRBUF, &device->name, "name"}, {FF_FORMAT_ARG_TYPE_STRBUF, &device->serial, "serial"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr, "battery-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageNum, "battery-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageBar, "battery-percentage-bar"}, })); } } @@ -138,7 +141,8 @@ void ffPrintGamepadHelpFormat(void) FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_GAMEPAD_MODULE_NAME, "{1} ({3})", FF_GAMEPAD_NUM_FORMAT_ARGS, ((const char* []) { "Name - name", "Serial number - serial", - "Battery percentage - battery-percentage", + "Battery percentage num - battery-percentage", + "Battery percentage bar - battery-percentage-bar", })); } diff --git a/src/modules/memory/memory.c b/src/modules/memory/memory.c index df623e8c53..832fecf205 100644 --- a/src/modules/memory/memory.c +++ b/src/modules/memory/memory.c @@ -6,7 +6,7 @@ #include "modules/memory/memory.h" #include "util/stringUtils.h" -#define FF_MEMORY_NUM_FORMAT_ARGS 3 +#define FF_MEMORY_NUM_FORMAT_ARGS 4 void ffPrintMemory(FFMemoryOptions* options) { @@ -56,12 +56,15 @@ void ffPrintMemory(FFMemoryOptions* options) } else { - FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate(); - ffPercentAppendNum(&percentageStr, percentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); + ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); + ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_MEMORY_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_MEMORY_NUM_FORMAT_ARGS, ((FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty, "used"}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty, "total"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr, "percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageNum, "percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageBar, "percentage-bar"}, })); } } @@ -130,7 +133,8 @@ void ffPrintMemoryHelpFormat(void) FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_MEMORY_MODULE_NAME, "{1} / {2} ({3})", FF_MEMORY_NUM_FORMAT_ARGS, ((const char* []) { "Used size - used", "Total size - total", - "Percentage used - percentage", + "Percentage used (num) - percentage", + "Percentage used (bar) - percentage-bar", })); } diff --git a/src/modules/sound/sound.c b/src/modules/sound/sound.c index 0b1c39cbfb..3ca23491a2 100644 --- a/src/modules/sound/sound.c +++ b/src/modules/sound/sound.c @@ -5,7 +5,7 @@ #include "modules/sound/sound.h" #include "util/stringUtils.h" -#define FF_SOUND_NUM_FORMAT_ARGS 4 +#define FF_SOUND_NUM_FORMAT_ARGS 5 static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, uint8_t index) { @@ -46,14 +46,17 @@ static void printDevice(FFSoundOptions* options, const FFSoundDevice* device, ui } else { - FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate(); - ffPercentAppendNum(&percentageStr, device->volume, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); + ffPercentAppendNum(&percentageNum, device->volume, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); + ffPercentAppendBar(&percentageBar, device->volume, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_SOUND_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SOUND_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_BOOL, &device->main, "is-main"}, {FF_FORMAT_ARG_TYPE_STRBUF, &device->name, "name"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr, "volume-percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageNum, "volume-percentage"}, {FF_FORMAT_ARG_TYPE_STRBUF, &device->identifier, "identifier"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageBar, "volume-percentage-bar"}, })); } } @@ -228,8 +231,9 @@ void ffPrintSoundHelpFormat(void) FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_SOUND_MODULE_NAME, "{2} ({3}%)", FF_SOUND_NUM_FORMAT_ARGS, ((const char* []) { "Is main sound device - is-main", "Device name - name", - "Volume (in percentage) - volume-percentage", + "Volume (in percentage num) - volume-percentage", "Identifier - identifier", + "Volume (in percentage bar) - volume-percentage-bar", })); } diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c index ac2b277b03..7b823f6715 100644 --- a/src/modules/swap/swap.c +++ b/src/modules/swap/swap.c @@ -6,7 +6,7 @@ #include "modules/swap/swap.h" #include "util/stringUtils.h" -#define FF_SWAP_NUM_FORMAT_ARGS 3 +#define FF_SWAP_NUM_FORMAT_ARGS 4 void ffPrintSwap(FFSwapOptions* options) { @@ -65,12 +65,15 @@ void ffPrintSwap(FFSwapOptions* options) } else { - FF_STRBUF_AUTO_DESTROY percentageStr = ffStrbufCreate(); - ffPercentAppendNum(&percentageStr, percentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageNum = ffStrbufCreate(); + ffPercentAppendNum(&percentageNum, percentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); + ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_SWAP_NUM_FORMAT_ARGS, ((FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty, "used"}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty, "total"}, - {FF_FORMAT_ARG_TYPE_STRBUF, &percentageStr, "percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageNum, "percentage"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentageBar, "percentage-bar"}, })); } } @@ -139,7 +142,8 @@ void ffPrintSwapHelpFormat(void) FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_SWAP_MODULE_NAME, "{1} / {2} ({3})", FF_SWAP_NUM_FORMAT_ARGS, ((const char* []) { "Used size - used", "Total size - total", - "Percentage used - percentage", + "Percentage used (num) - percentage", + "Percentage used (bar) - percentage-bar", })); } From fa872d7c9b9c4e07866c9c8c4ac45e05b93fc82f Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 15:32:09 +0800 Subject: [PATCH 28/41] Display: fix build on FreeBSD --- src/detection/displayserver/linux/wayland/wayland.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index 4b6d908e25..ac262979e2 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -17,7 +17,7 @@ #include "kde-output-order-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" -#ifndef __FreeBSD__ +#ifdef __linux__ static bool waylandDetectWM(int fd, FFDisplayServerResult* result) { struct ucred ucred; @@ -34,7 +34,7 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result) return true; } #else -static void waylandDetectWM(int fd, FFDisplayServerResult* result) +static bool waylandDetectWM(int fd, FFDisplayServerResult* result) { FF_UNUSED(fd, result); return false; From 5a39b69d1de503dec054850bf0e8e8174785ecc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 8 Jul 2024 16:08:20 +0800 Subject: [PATCH 29/41] Wifi: print signal quality --- src/modules/wifi/option.h | 2 ++ src/modules/wifi/wifi.c | 66 +++++++++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/modules/wifi/option.h b/src/modules/wifi/option.h index 0dcad05fd2..305a95a473 100644 --- a/src/modules/wifi/option.h +++ b/src/modules/wifi/option.h @@ -8,4 +8,6 @@ typedef struct FFWifiOptions { FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; + + FFColorRangeConfig percent; } FFWifiOptions; diff --git a/src/modules/wifi/wifi.c b/src/modules/wifi/wifi.c index 489063f603..16774f932a 100644 --- a/src/modules/wifi/wifi.c +++ b/src/modules/wifi/wifi.c @@ -4,7 +4,7 @@ #include "modules/wifi/wifi.h" #include "util/stringUtils.h" -#define FF_WIFI_NUM_FORMAT_ARGS 10 +#define FF_WIFI_NUM_FORMAT_ARGS 11 void ffPrintWifi(FFWifiOptions* options) { @@ -30,22 +30,56 @@ void ffPrintWifi(FFWifiOptions* options) if(options->moduleArgs.outputFormat.length == 0) { ffPrintLogoAndKey(FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); + + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if(item->conn.ssid.length) { - ffStrbufWriteTo(&item->conn.ssid, stdout); - if(item->conn.protocol.length) - printf(" - %s", item->conn.protocol.chars); - if(item->conn.security.length) - printf(" - %s", item->conn.security.chars); - putchar('\n'); + if(item->conn.signalQuality == item->conn.signalQuality) + { + if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_BAR_BIT) + { + ffPercentAppendBar(&buffer, item->conn.signalQuality, options->percent, &options->moduleArgs); + ffStrbufAppendC(&buffer, ' '); + } + } + + if (!(instance.config.display.percentType & FF_PERCENTAGE_TYPE_HIDE_OTHERS_BIT)) + { + ffStrbufAppend(&buffer, &item->conn.ssid); + + if(item->conn.protocol.length) + { + ffStrbufAppendS(&buffer, " - "); + ffStrbufAppend(&buffer, &item->conn.protocol); + } + if(item->conn.security.length) + { + ffStrbufAppendS(&buffer, " - "); + ffStrbufAppend(&buffer, &item->conn.security); + } + ffStrbufAppendC(&buffer, ' '); + } + + if(item->conn.signalQuality == item->conn.signalQuality) + { + if(instance.config.display.percentType & FF_PERCENTAGE_TYPE_NUM_BIT) + ffPercentAppendNum(&buffer, item->conn.signalQuality, options->percent, buffer.length > 0, &options->moduleArgs); + } + + ffStrbufTrimRight(&buffer, ' '); } else { - puts(item->inf.status.chars); + ffStrbufAppend(&buffer, &item->inf.status); } + ffStrbufPutTo(&buffer, stdout); } else { + FF_STRBUF_AUTO_DESTROY percentNum = ffStrbufCreate(); + ffPercentAppendNum(&percentNum, item->conn.signalQuality, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY percentBar = ffStrbufCreate(); + ffPercentAppendBar(&percentBar, item->conn.signalQuality, options->percent, &options->moduleArgs); FF_PRINT_FORMAT_CHECKED(FF_WIFI_MODULE_NAME, moduleIndex, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_WIFI_NUM_FORMAT_ARGS, ((FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.description, "inf-desc"}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->inf.status, "inf-status"}, @@ -53,10 +87,11 @@ void ffPrintWifi(FFWifiOptions* options) {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.ssid, "ssid"}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.macAddress, "mac-address"}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.protocol, "protocol"}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.signalQuality, "signal-quality"}, + {FF_FORMAT_ARG_TYPE_DOUBLE, &percentNum, "signal-quality"}, {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.rxRate, "rx-rate"}, {FF_FORMAT_ARG_TYPE_DOUBLE, &item->conn.txRate, "tx-rate"}, {FF_FORMAT_ARG_TYPE_STRBUF, &item->conn.security, "security"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &percentBar, "signal-quality-bar"}, })); } @@ -77,6 +112,9 @@ bool ffParseWifiCommandOptions(FFWifiOptions* options, const char* key, const ch if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) return true; + if (ffPercentParseCommandOptions(key, subKey, value, &options->percent)) + return true; + return false; } @@ -93,6 +131,9 @@ void ffParseWifiJsonObject(FFWifiOptions* options, yyjson_val* module) if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) continue; + if (ffPercentParseJsonObject(key, val, &options->percent)) + continue; + ffPrintError(FF_WIFI_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); } } @@ -103,6 +144,8 @@ void ffGenerateWifiJsonConfig(FFWifiOptions* options, yyjson_mut_doc* doc, yyjso ffInitWifiOptions(&defaultOptions); ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs); + + ffPercentGenerateJsonConfig(doc, module, defaultOptions.percent, options->percent); } void ffGenerateWifiJsonResult(FF_MAYBE_UNUSED FFWifiOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) @@ -156,10 +199,11 @@ void ffPrintWifiHelpFormat(void) "Connection SSID - ssid", "Connection BSSID - bssid", "Connection protocol - protocol", - "Connection signal quality (percentage) - signal-quality", + "Connection signal quality (percentage num) - signal-quality", "Connection RX rate - rx-rate", "Connection TX rate - tx-rate", "Connection Security algorithm - security", + "Connection signal quality (percentage bar) - signal-quality-bar", })); } @@ -177,6 +221,8 @@ void ffInitWifiOptions(FFWifiOptions* options) ffGenerateWifiJsonConfig ); ffOptionInitModuleArg(&options->moduleArgs); + + options->percent = (FFColorRangeConfig) { 50, 20 }; } void ffDestroyWifiOptions(FFWifiOptions* options) From 1652ec3512b9ef597a94e9d884699328a25d8ebd Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 18:27:42 +0800 Subject: [PATCH 30/41] Display (Linux): remove debug output --- src/detection/displayserver/linux/wayland/wayland.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/detection/displayserver/linux/wayland/wayland.c b/src/detection/displayserver/linux/wayland/wayland.c index ac262979e2..bfb8d366a8 100644 --- a/src/detection/displayserver/linux/wayland/wayland.c +++ b/src/detection/displayserver/linux/wayland/wayland.c @@ -30,7 +30,6 @@ static bool waylandDetectWM(int fd, FFDisplayServerResult* result) ffReadFileBuffer(procPath.chars, &result->wmProcessName); ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path - puts(result->wmProcessName.chars); return true; } #else From 39eccf189c23764b8498df27ae8edad6179e77be Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 8 Jul 2024 18:28:34 +0800 Subject: [PATCH 31/41] Presets: add missing modules to `all` & `ci` Fix #1081 --- presets/all.jsonc | 2 ++ presets/ci.jsonc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/presets/all.jsonc b/presets/all.jsonc index 6fc35a2e10..52d092d1c7 100644 --- a/presets/all.jsonc +++ b/presets/all.jsonc @@ -47,6 +47,7 @@ "cpuusage", { "type": "gpu", + "driverSpecific": true, "temp": true }, "memory", @@ -63,6 +64,7 @@ "showIpv6": true, "showMac": true }, + "dns", "wifi", "datetime", "locale", diff --git a/presets/ci.jsonc b/presets/ci.jsonc index 5f611d3aa3..ac34edab2b 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -49,6 +49,7 @@ "cpuusage", { "type": "gpu", + "driverSpecific": true, "temp": true }, "memory", @@ -65,6 +66,7 @@ "showIpv6": true, "showMac": true }, + "dns", "wifi", "datetime", "locale", From fea2d80743e5e104d4ced79fa4c31eecc59cdaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 9 Jul 2024 11:10:39 +0800 Subject: [PATCH 32/41] Doc: update changelog --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 551dec40b0..d5d5d861d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +# 2.17.3 + +Bugfixes: +* Don't print `*` if `defaultRouteOnly` is set (LocalIP) +* Fix some memory leaks +* Fix compatibility with old Python versions +* Don't detect frequency for AMD cards (GPU, Linux) + * Fix possible hang with discrete AMD cards (#1077) +* Don't print colors in `--pipe` mode (Separator) + +Features: +* Detect revision of USB drives (#1048, Disk) +* Don't print `(null)` in property `locator` (PhysicalMemory) +* Support fractional scale factor detection (Display, Linux) +* Support primary display detection for KDE and GNOME (Display, Linux) +* Support percent bar in custom formatting +* Print signal quality by default (Wifi) + +Logos: +* Add Arkane Linux +* Add Opak + # 2.17.2 Changes: From e5a04ee8144da438054deaeaf4a9f35637479126 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 9 Jul 2024 14:00:04 +0800 Subject: [PATCH 33/41] GPU (Linux): ignore disabled PCI devices --- src/detection/gpu/gpu_linux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index dc860b099b..0164f191e6 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -192,6 +192,13 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf if (sscanf(pPciPath, "%" SCNx32 ":%" SCNx32 ":%" SCNx32 ".%" SCNx32, &pciDomain, &pciBus, &pciDevice, &pciFunc) != 4) return "Invalid PCI device path"; + ffStrbufAppendS(deviceDir, "/enable"); + if (ffReadFileBuffer(deviceDir->chars, buffer)) + { + if (!ffStrbufStartsWithC(buffer, '1')) + return "GPU disabled"; + } + FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); ffStrbufInitStatic(&gpu->vendor, ffGetGPUVendorString((uint16_t) vendorId)); ffStrbufInit(&gpu->name); From 49639b6719c2e3e4ba1a591ec21935b1ab405d02 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 9 Jul 2024 14:27:25 +0800 Subject: [PATCH 34/41] OpenGL (Linux): fix flag `--opengl-library` doesn't work --- src/modules/opengl/opengl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/opengl/opengl.c b/src/modules/opengl/opengl.c index f0f49662bf..e8a29870f3 100644 --- a/src/modules/opengl/opengl.c +++ b/src/modules/opengl/opengl.c @@ -52,7 +52,7 @@ bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, cons return true; #if defined(__linux__) || defined(__FreeBSD__) - if (ffStrEqualsIgnCase(key, "library")) + if (ffStrEqualsIgnCase(subKey, "library")) { options->library = (FFOpenGLLibrary) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { { "auto", FF_OPENGL_LIBRARY_AUTO }, @@ -61,6 +61,7 @@ bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, cons { "osmesa", FF_OPENGL_LIBRARY_OSMESA }, {} }); + return true; } #endif From 1038668db939f213bcbd026bec278258a54b8758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 9 Jul 2024 20:39:15 +0800 Subject: [PATCH 35/41] OpenGL: detect library version --- src/detection/gpu/gpu.c | 3 +++ src/detection/opengl/opengl.h | 2 +- src/detection/opengl/opengl_apple.c | 12 ++++++++---- src/detection/opengl/opengl_linux.c | 25 +++++++++++++++++++------ src/detection/opengl/opengl_windows.c | 8 ++++---- src/modules/opengl/opengl.c | 9 ++++++--- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index 70eac725bd..d9b30cd2e1 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -42,6 +42,8 @@ const char* detectByOpenGL(FFlist* gpus) ffStrbufInit(&result.renderer); ffStrbufInit(&result.vendor); ffStrbufInit(&result.slv); + ffStrbufInit(&result.library); + const char* error = ffDetectOpenGL(&instance.config.modules.openGL, &result); if (!error) { @@ -75,6 +77,7 @@ const char* detectByOpenGL(FFlist* gpus) ffStrbufDestroy(&result.renderer); ffStrbufDestroy(&result.vendor); ffStrbufDestroy(&result.slv); + ffStrbufDestroy(&result.library); return error; } diff --git a/src/detection/opengl/opengl.h b/src/detection/opengl/opengl.h index 6614ea2f2f..b8d5ce7873 100644 --- a/src/detection/opengl/opengl.h +++ b/src/detection/opengl/opengl.h @@ -8,7 +8,7 @@ typedef struct FFOpenGLResult FFstrbuf renderer; FFstrbuf vendor; FFstrbuf slv; - const char* library; + FFstrbuf library; } FFOpenGLResult; const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result); diff --git a/src/detection/opengl/opengl_apple.c b/src/detection/opengl/opengl_apple.c index 3a8e7ac5eb..db3be29d24 100644 --- a/src/detection/opengl/opengl_apple.c +++ b/src/detection/opengl/opengl_apple.c @@ -6,14 +6,16 @@ #include #include // This brings in CGL, not GL -static const char* glHandleResult(FFOpenGLResult* result) +static void glHandleResult(FFOpenGLResult* result) { ffStrbufAppendS(&result->version, (const char*) glGetString(GL_VERSION)); ffStrbufAppendS(&result->renderer, (const char*) glGetString(GL_RENDERER)); ffStrbufAppendS(&result->vendor, (const char*) glGetString(GL_VENDOR)); ffStrbufAppendS(&result->slv, (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); - result->library = "CGL"; - return NULL; + + GLint major, minor; + CGLGetVersion(&major, &minor); + ffStrbufAppendF(&result->library, "CGL %d.%d", major, minor); } static const char* cglHandleContext(FFOpenGLResult* result, CGLContextObj context) @@ -21,7 +23,9 @@ static const char* cglHandleContext(FFOpenGLResult* result, CGLContextObj contex if(CGLSetCurrentContext(context) != kCGLNoError) return "CGLSetCurrentContext() failed"; - return glHandleResult(result); + glHandleResult(result); + + return NULL; } static const char* cglHandlePixelFormat(FFOpenGLResult* result, CGLPixelFormatObj pixelFormat) diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index bc957add79..bd0d50e418 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -18,14 +18,12 @@ typedef struct GLData FF_LIBRARY_SYMBOL(glGetString) } GLData; -static const char* glHandleResult(FFOpenGLResult* result, const GLData* data, const char* library) +static void glHandleResult(FFOpenGLResult* result, const GLData* data) { ffStrbufAppendS(&result->version, (const char*) data->ffglGetString(GL_VERSION)); ffStrbufAppendS(&result->renderer, (const char*) data->ffglGetString(GL_RENDERER)); ffStrbufAppendS(&result->vendor, (const char*) data->ffglGetString(GL_VENDOR)); ffStrbufAppendS(&result->slv, (const char*) data->ffglGetString(GL_SHADING_LANGUAGE_VERSION)); - result->library = library; - return NULL; } #endif // FF_HAVE_GL @@ -41,6 +39,7 @@ typedef struct EGLData FF_LIBRARY_SYMBOL(eglGetProcAddress) FF_LIBRARY_SYMBOL(eglGetDisplay) + FF_LIBRARY_SYMBOL(eglQueryString) FF_LIBRARY_SYMBOL(eglInitialize) FF_LIBRARY_SYMBOL(eglBindAPI) FF_LIBRARY_SYMBOL(eglGetConfigs) @@ -62,7 +61,9 @@ static const char* eglHandleContext(FFOpenGLResult* result, EGLData* data) if(data->ffeglMakeCurrent(data->display, data->surface, data->surface, data->context) != EGL_TRUE) return "eglMakeCurrent returned EGL_FALSE"; - return glHandleResult(result, &data->glData, "EGL"); + glHandleResult(result, &data->glData); + ffStrbufSetF(&result->library, "EGL %s", data->ffeglQueryString(data->display, EGL_VERSION)); + return NULL; } static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data) @@ -126,6 +127,7 @@ static const char* eglPrint(FFOpenGLResult* result) FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglQueryString); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglBindAPI); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetConfigs); @@ -150,6 +152,7 @@ typedef struct GLXData GLData glData; FF_LIBRARY_SYMBOL(glXGetProcAddress) + FF_LIBRARY_SYMBOL(glXQueryVersion) FF_LIBRARY_SYMBOL(XOpenDisplay) FF_LIBRARY_SYMBOL(glXChooseVisual) FF_LIBRARY_SYMBOL(XCreatePixmap); @@ -173,8 +176,15 @@ static const char* glxHandleContext(FFOpenGLResult* result, GLXData* data) { if(data->ffglXMakeCurrent(data->display, data->glxPixmap, data->context) != True) return "glXMakeCurrent returned False"; + glHandleResult(result, &data->glData); + + int major, minor; + if (data->ffglXQueryVersion(data->display, &major, &minor)) + ffStrbufSetF(&result->library, "GLX %d.%d", major, minor); + else + ffStrbufSetStatic(&result->library, "GLX"); - return glHandleResult(result, &data->glData, "GLX"); + return NULL; } static const char* glxHandleGLXPixmap(FFOpenGLResult* result, GLXData* data) @@ -242,6 +252,7 @@ static const char* glxPrint(FFOpenGLResult* result) FF_LIBRARY_LOAD(glx, &instance.config.library.libGLX, "dlopen glx failed", "libGLX" FF_LIBRARY_EXTENSION, 1); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXGetProcAddress); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXQueryVersion); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XOpenDisplay); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, glXChooseVisual); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(glx, data, XCreatePixmap); @@ -285,7 +296,9 @@ static const char* osMesaHandleContext(FFOpenGLResult* result, OSMesaData* data) if(data->ffOSMesaMakeCurrent(data->context, buffer, GL_UNSIGNED_BYTE, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT) != GL_TRUE) return "OSMesaMakeCurrent returned GL_FALSE"; - return glHandleResult(result, &data->glData, "OSMesa"); + glHandleResult(result, &data->glData); + ffStrbufSetF(&result->library, "OSMesa %d.%d.%d", OSMESA_MAJOR_VERSION, OSMESA_MINOR_VERSION, OSMESA_PATCH_VERSION); + return NULL; } static const char* osMesaHandleData(FFOpenGLResult* result, OSMesaData* data) diff --git a/src/detection/opengl/opengl_windows.c b/src/detection/opengl/opengl_windows.c index e0b29fc8a1..0ad0d4572f 100644 --- a/src/detection/opengl/opengl_windows.c +++ b/src/detection/opengl/opengl_windows.c @@ -19,21 +19,21 @@ typedef struct WGLData FF_LIBRARY_SYMBOL(wglDeleteContext) } WGLData; -static const char* glHandleResult(WGLData* wglData) +static void glHandleResult(WGLData* wglData) { ffStrbufAppendS(&wglData->result->version, (const char*) wglData->ffglGetString(GL_VERSION)); ffStrbufAppendS(&wglData->result->renderer, (const char*) wglData->ffglGetString(GL_RENDERER)); ffStrbufAppendS(&wglData->result->vendor, (const char*) wglData->ffglGetString(GL_VENDOR)); ffStrbufAppendS(&wglData->result->slv, (const char*) wglData->ffglGetString(GL_SHADING_LANGUAGE_VERSION)); - wglData->result->library = "WGL"; - return NULL; + ffStrbufSetStatic(&wglData->result->library, "WGL 1.0"); } static const char* wglHandleContext(WGLData* wglData, HDC hdc, HGLRC context) { if(wglData->ffwglMakeCurrent(hdc, context) == FALSE) return "wglMakeCurrent() failed"; - return glHandleResult(wglData); + glHandleResult(wglData); + return NULL; } static const char* wglHandlePixelFormat(WGLData* wglData, HWND hWnd) diff --git a/src/modules/opengl/opengl.c b/src/modules/opengl/opengl.c index e8a29870f3..e7bbff3ee8 100644 --- a/src/modules/opengl/opengl.c +++ b/src/modules/opengl/opengl.c @@ -13,7 +13,7 @@ void ffPrintOpenGL(FFOpenGLOptions* options) ffStrbufInit(&result.renderer); ffStrbufInit(&result.vendor); ffStrbufInit(&result.slv); - result.library = "Unknown"; + ffStrbufInit(&result.library); const char* error = ffDetectOpenGL(options, &result); if(error) @@ -34,7 +34,7 @@ void ffPrintOpenGL(FFOpenGLOptions* options) {FF_FORMAT_ARG_TYPE_STRBUF, &result.renderer, "renderer"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result.vendor, "vendor"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result.slv, "slv"}, - {FF_FORMAT_ARG_TYPE_STRING, result.library, "library"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.library, "library"}, })); } @@ -42,6 +42,7 @@ void ffPrintOpenGL(FFOpenGLOptions* options) ffStrbufDestroy(&result.renderer); ffStrbufDestroy(&result.vendor); ffStrbufDestroy(&result.slv); + ffStrbufDestroy(&result.library); } bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, const char* value) @@ -140,6 +141,7 @@ void ffGenerateOpenGLJsonResult(FF_MAYBE_UNUSED FFOpenGLOptions* options, yyjson ffStrbufInit(&result.renderer); ffStrbufInit(&result.vendor); ffStrbufInit(&result.slv); + ffStrbufInit(&result.library); const char* error = ffDetectOpenGL(options, &result); if(error != NULL) @@ -153,13 +155,14 @@ void ffGenerateOpenGLJsonResult(FF_MAYBE_UNUSED FFOpenGLOptions* options, yyjson yyjson_mut_obj_add_strbuf(doc, obj, "renderer", &result.renderer); yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &result.vendor); yyjson_mut_obj_add_strbuf(doc, obj, "slv", &result.slv); - yyjson_mut_obj_add_str(doc, obj, "library", result.library); + yyjson_mut_obj_add_strbuf(doc, obj, "library", &result.library); } ffStrbufDestroy(&result.version); ffStrbufDestroy(&result.renderer); ffStrbufDestroy(&result.vendor); ffStrbufDestroy(&result.slv); + ffStrbufDestroy(&result.library); } void ffPrintOpenGLHelpFormat(void) From 4777f7bec3119d1afc987b37e6ba54c8153f2568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 10 Jul 2024 00:20:11 +0800 Subject: [PATCH 36/41] OpenGL (Windows): support EGL via ANGLE --- CMakeLists.txt | 3 +- src/detection/opengl/opengl.h | 3 + src/detection/opengl/opengl_apple.c | 18 +-- src/detection/opengl/opengl_linux.c | 166 +++----------------------- src/detection/opengl/opengl_shared.c | 148 +++++++++++++++++++++++ src/detection/opengl/opengl_windows.c | 39 +++--- src/modules/opengl/opengl.c | 8 -- src/modules/opengl/option.h | 4 - src/options/library.c | 16 +-- src/options/library.h | 2 +- 10 files changed, 210 insertions(+), 197 deletions(-) create mode 100644 src/detection/opengl/opengl_shared.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a63ca12888..02cea22567 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR B cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR BSD OR APPLE OR SunOS" OFF) cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) cmake_dependent_option(ENABLE_ZLIB "Enable zlib" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7" OFF) -cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD OR SunOS" OFF) +cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR BSD OR WIN32 OR SunOS" OFF) cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR BSD OR SunOS" OFF) cmake_dependent_option(ENABLE_OSMESA "Enable osmesa" ON "LINUX OR BSD OR SunOS" OFF) cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR BSD OR WIN32 OR ANDROID OR SunOS" OFF) @@ -307,6 +307,7 @@ set(LIBFASTFETCH_SRC src/detection/media/media.c src/detection/netio/netio.c src/detection/opencl/opencl.c + src/detection/opengl/opengl_shared.c src/detection/os/os.c src/detection/packages/packages.c src/detection/physicalmemory/physicalmemory.c diff --git a/src/detection/opengl/opengl.h b/src/detection/opengl/opengl.h index b8d5ce7873..466dcf2565 100644 --- a/src/detection/opengl/opengl.h +++ b/src/detection/opengl/opengl.h @@ -11,4 +11,7 @@ typedef struct FFOpenGLResult FFstrbuf library; } FFOpenGLResult; +#define FF_OPENGL_BUFFER_WIDTH 1 +#define FF_OPENGL_BUFFER_HEIGHT 1 + const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result); diff --git a/src/detection/opengl/opengl_apple.c b/src/detection/opengl/opengl_apple.c index db3be29d24..c6b56f07f3 100644 --- a/src/detection/opengl/opengl_apple.c +++ b/src/detection/opengl/opengl_apple.c @@ -6,24 +6,18 @@ #include #include // This brings in CGL, not GL -static void glHandleResult(FFOpenGLResult* result) -{ - ffStrbufAppendS(&result->version, (const char*) glGetString(GL_VERSION)); - ffStrbufAppendS(&result->renderer, (const char*) glGetString(GL_RENDERER)); - ffStrbufAppendS(&result->vendor, (const char*) glGetString(GL_VENDOR)); - ffStrbufAppendS(&result->slv, (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); - - GLint major, minor; - CGLGetVersion(&major, &minor); - ffStrbufAppendF(&result->library, "CGL %d.%d", major, minor); -} +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString); static const char* cglHandleContext(FFOpenGLResult* result, CGLContextObj context) { if(CGLSetCurrentContext(context) != kCGLNoError) return "CGLSetCurrentContext() failed"; - glHandleResult(result); + ffOpenGLHandleResult(result, &glGetString); + + GLint major, minor; + CGLGetVersion(&major, &minor); + ffStrbufSetF(&result->library, "CGL %d.%d", major, minor); return NULL; } diff --git a/src/detection/opengl/opengl_linux.c b/src/detection/opengl/opengl_linux.c index bd0d50e418..4a417bace7 100644 --- a/src/detection/opengl/opengl_linux.c +++ b/src/detection/opengl/opengl_linux.c @@ -10,147 +10,17 @@ #include -#define FF_OPENGL_BUFFER_WIDTH 1 -#define FF_OPENGL_BUFFER_HEIGHT 1 - -typedef struct GLData -{ - FF_LIBRARY_SYMBOL(glGetString) -} GLData; - -static void glHandleResult(FFOpenGLResult* result, const GLData* data) -{ - ffStrbufAppendS(&result->version, (const char*) data->ffglGetString(GL_VERSION)); - ffStrbufAppendS(&result->renderer, (const char*) data->ffglGetString(GL_RENDERER)); - ffStrbufAppendS(&result->vendor, (const char*) data->ffglGetString(GL_VENDOR)); - ffStrbufAppendS(&result->slv, (const char*) data->ffglGetString(GL_SHADING_LANGUAGE_VERSION)); -} +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString); #endif // FF_HAVE_GL -#ifdef FF_HAVE_EGL -#include "common/io/io.h" - -#include - -typedef struct EGLData -{ - GLData glData; - - FF_LIBRARY_SYMBOL(eglGetProcAddress) - FF_LIBRARY_SYMBOL(eglGetDisplay) - FF_LIBRARY_SYMBOL(eglQueryString) - FF_LIBRARY_SYMBOL(eglInitialize) - FF_LIBRARY_SYMBOL(eglBindAPI) - FF_LIBRARY_SYMBOL(eglGetConfigs) - FF_LIBRARY_SYMBOL(eglCreatePbufferSurface) - FF_LIBRARY_SYMBOL(eglCreateContext) - FF_LIBRARY_SYMBOL(eglMakeCurrent) - FF_LIBRARY_SYMBOL(eglDestroyContext) - FF_LIBRARY_SYMBOL(eglDestroySurface) - FF_LIBRARY_SYMBOL(eglTerminate) - - EGLDisplay display; - EGLConfig config; - EGLSurface surface; - EGLContext context; -} EGLData; - -static const char* eglHandleContext(FFOpenGLResult* result, EGLData* data) -{ - if(data->ffeglMakeCurrent(data->display, data->surface, data->surface, data->context) != EGL_TRUE) - return "eglMakeCurrent returned EGL_FALSE"; - - glHandleResult(result, &data->glData); - ffStrbufSetF(&result->library, "EGL %s", data->ffeglQueryString(data->display, EGL_VERSION)); - return NULL; -} - -static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data) -{ - data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE}); - if(data->context == EGL_NO_CONTEXT) - return "eglCreateContext returned EGL_NO_CONTEXT"; - - const char* error = eglHandleContext(result, data); - data->ffeglDestroyContext(data->display, data->context); - return error; -} - -static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data) -{ - if(data->ffeglBindAPI(EGL_OPENGL_API) != EGL_TRUE) - return "eglBindAPI returned EGL_FALSE"; - - EGLint eglConfigCount; - data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount); - if(eglConfigCount == 0) - return "eglGetConfigs returned 0 configs"; - - data->surface = data->ffeglCreatePbufferSurface(data->display, data->config, (EGLint[]){ - EGL_WIDTH, FF_OPENGL_BUFFER_WIDTH, - EGL_HEIGHT, FF_OPENGL_BUFFER_HEIGHT, - EGL_NONE - }); - - if(data->surface == EGL_NO_SURFACE) - return "eglCreatePbufferSurface returned EGL_NO_SURFACE"; - - const char* error = eglHandleSurface(result, data); - data->ffeglDestroySurface(data->display, data->surface); - return error; -} - -static const char* eglHandleData(FFOpenGLResult* result, EGLData* data) -{ - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffeglGetProcAddress("glGetString"); - if(!data->glData.ffglGetString) - return "eglGetProcAddress(glGetString) returned NULL"; - - data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY); - if(data->display == EGL_NO_DISPLAY) - return "eglGetDisplay returned EGL_NO_DISPLAY"; - - EGLint major, minor; - if(data->ffeglInitialize(data->display, &major, &minor) == EGL_FALSE) - return "eglInitialize returned EGL_FALSE"; - - const char* error = eglHandleDisplay(result, data); - data->ffeglTerminate(data->display); - return error; -} - -static const char* eglPrint(FFOpenGLResult* result) -{ - EGLData eglData; - - FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglQueryString); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglBindAPI); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetConfigs); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreatePbufferSurface); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreateContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglMakeCurrent); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroyContext); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroySurface); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglTerminate); - - FF_SUPPRESS_IO(); - return eglHandleData(result, &eglData); -} - -#endif //FF_HAVE_EGL #ifdef FF_HAVE_GLX #include typedef struct GLXData { - GLData glData; - + FF_LIBRARY_SYMBOL(glGetString) FF_LIBRARY_SYMBOL(glXGetProcAddress) FF_LIBRARY_SYMBOL(glXQueryVersion) FF_LIBRARY_SYMBOL(XOpenDisplay) @@ -176,7 +46,7 @@ static const char* glxHandleContext(FFOpenGLResult* result, GLXData* data) { if(data->ffglXMakeCurrent(data->display, data->glxPixmap, data->context) != True) return "glXMakeCurrent returned False"; - glHandleResult(result, &data->glData); + ffOpenGLHandleResult(result, data->ffglGetString); int major, minor; if (data->ffglXQueryVersion(data->display, &major, &minor)) @@ -233,8 +103,8 @@ static const char* glxHandleDisplay(FFOpenGLResult* result, GLXData* data) static const char* glxHandleData(FFOpenGLResult* result, GLXData* data) { - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) data->ffglXGetProcAddress((const GLubyte*) "glGetString"); - if(data->glData.ffglGetString == NULL) + data->ffglGetString = (__typeof__(data->ffglGetString)) data->ffglXGetProcAddress((const GLubyte*) "glGetString"); + if(data->ffglGetString == NULL) return "glXGetProcAddress(glGetString) returned NULL"; data->display = data->ffXOpenDisplay(NULL); @@ -246,7 +116,7 @@ static const char* glxHandleData(FFOpenGLResult* result, GLXData* data) return error; } -static const char* glxPrint(FFOpenGLResult* result) +static const char* detectByGlx(FFOpenGLResult* result) { GLXData data; @@ -279,8 +149,7 @@ static const char* glxPrint(FFOpenGLResult* result) typedef struct OSMesaData { - GLData glData; - + FF_LIBRARY_SYMBOL(glGetString) FF_LIBRARY_SYMBOL(OSMesaGetProcAddress) FF_LIBRARY_SYMBOL(OSMesaCreateContext) FF_LIBRARY_SYMBOL(OSMesaMakeCurrent) @@ -296,16 +165,15 @@ static const char* osMesaHandleContext(FFOpenGLResult* result, OSMesaData* data) if(data->ffOSMesaMakeCurrent(data->context, buffer, GL_UNSIGNED_BYTE, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT) != GL_TRUE) return "OSMesaMakeCurrent returned GL_FALSE"; - glHandleResult(result, &data->glData); + ffOpenGLHandleResult(result, data->ffglGetString); ffStrbufSetF(&result->library, "OSMesa %d.%d.%d", OSMESA_MAJOR_VERSION, OSMESA_MINOR_VERSION, OSMESA_PATCH_VERSION); return NULL; } static const char* osMesaHandleData(FFOpenGLResult* result, OSMesaData* data) { - //The case to void* is required here, because OSMESAproc can't be cast to (__typeof__(data->glData.ffglGetString)) without a warning, even though it is the actual type. - data->glData.ffglGetString = (__typeof__(data->glData.ffglGetString)) (void*) data->ffOSMesaGetProcAddress("glGetString"); - if(data->glData.ffglGetString == NULL) + data->ffglGetString = (void*) data->ffOSMesaGetProcAddress("glGetString"); + if(data->ffglGetString == NULL) return "OSMesaGetProcAddress(glGetString) returned NULL"; data->context = data->ffOSMesaCreateContext(OSMESA_RGBA, NULL); @@ -317,7 +185,7 @@ static const char* osMesaHandleData(FFOpenGLResult* result, OSMesaData* data) return error; } -static const char* osMesaPrint(FFOpenGLResult* result) +static const char* detectByOsMesa(FFOpenGLResult* result) { OSMesaData data; @@ -339,7 +207,7 @@ const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) if(options->library == FF_OPENGL_LIBRARY_GLX) { #ifdef FF_HAVE_GLX - return glxPrint(result); + return detectByGlx(result); #else return "fastfetch was compiled without glx support"; #endif @@ -348,7 +216,8 @@ const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) if(options->library == FF_OPENGL_LIBRARY_EGL) { #ifdef FF_HAVE_EGL - return eglPrint(result); + const char* ffOpenGLDetectByEGL(FFOpenGLResult* result); + return ffOpenGLDetectByEGL(result); #else return "fastfetch was compiled without egl support"; #endif @@ -357,7 +226,7 @@ const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) if(options->library == FF_OPENGL_LIBRARY_OSMESA) { #ifdef FF_HAVE_OSMESA - return osMesaPrint(result); + return detectByOsMesa(result); #else return "fastfetch was compiled without osmesa support"; #endif @@ -366,12 +235,13 @@ const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) const char* error = ""; // not NULL dummy value #ifdef FF_HAVE_EGL - error = eglPrint(result); + const char* ffOpenGLDetectByEGL(FFOpenGLResult* result); + error = ffOpenGLDetectByEGL(result); #endif #ifdef FF_HAVE_GLX if(error != NULL) - error = glxPrint(result); + error = detectByGlx(result); #endif //We don't use osmesa in auto mode here, because it is a software implementation, diff --git a/src/detection/opengl/opengl_shared.c b/src/detection/opengl/opengl_shared.c new file mode 100644 index 0000000000..f8e190dc36 --- /dev/null +++ b/src/detection/opengl/opengl_shared.c @@ -0,0 +1,148 @@ +#include "opengl.h" +#include "common/library.h" + +#if __has_include() +#include +#elif __has_include() +#define GL_SILENCE_DEPRECATION 1 +#include +#else +#define FF_HAVE_NO_GL 1 +#endif + +#ifndef FF_HAVE_NO_GL + +#ifndef GL_SHADING_LANGUAGE_VERSION // For WGL + #define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#endif + +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString) +{ + ffStrbufAppendS(&result->version, (const char*) ffglGetString(GL_VERSION)); + ffStrbufAppendS(&result->renderer, (const char*) ffglGetString(GL_RENDERER)); + ffStrbufAppendS(&result->vendor, (const char*) ffglGetString(GL_VENDOR)); + ffStrbufAppendS(&result->slv, (const char*) ffglGetString(GL_SHADING_LANGUAGE_VERSION)); +} + +#if defined(FF_HAVE_EGL) || __has_include() +#include "common/io/io.h" + +#include + +typedef struct EGLData +{ + FF_LIBRARY_SYMBOL(glGetString) + FF_LIBRARY_SYMBOL(eglGetProcAddress) + FF_LIBRARY_SYMBOL(eglGetDisplay) + FF_LIBRARY_SYMBOL(eglQueryString) + FF_LIBRARY_SYMBOL(eglInitialize) + FF_LIBRARY_SYMBOL(eglBindAPI) + FF_LIBRARY_SYMBOL(eglGetConfigs) + FF_LIBRARY_SYMBOL(eglCreatePbufferSurface) + FF_LIBRARY_SYMBOL(eglCreateContext) + FF_LIBRARY_SYMBOL(eglMakeCurrent) + FF_LIBRARY_SYMBOL(eglDestroyContext) + FF_LIBRARY_SYMBOL(eglDestroySurface) + FF_LIBRARY_SYMBOL(eglTerminate) + + EGLDisplay display; + EGLConfig config; + EGLSurface surface; + EGLContext context; +} EGLData; + +static const char* eglHandleContext(FFOpenGLResult* result, EGLData* data) +{ + if(data->ffeglMakeCurrent(data->display, data->surface, data->surface, data->context) != EGL_TRUE) + return "eglMakeCurrent returned EGL_FALSE"; + + ffOpenGLHandleResult(result, data->ffglGetString); + ffStrbufSetF(&result->library, "EGL %s", data->ffeglQueryString(data->display, EGL_VERSION)); + return NULL; +} + +static const char* eglHandleSurface(FFOpenGLResult* result, EGLData* data) +{ + data->context = data->ffeglCreateContext(data->display, data->config, EGL_NO_CONTEXT, (EGLint[]){EGL_NONE}); + if(data->context == EGL_NO_CONTEXT) + return "eglCreateContext returned EGL_NO_CONTEXT"; + + const char* error = eglHandleContext(result, data); + data->ffeglDestroyContext(data->display, data->context); + return error; +} + +static const char* eglHandleDisplay(FFOpenGLResult* result, EGLData* data) +{ + if(data->ffeglBindAPI( + #ifdef _WIN32 + EGL_OPENGL_ES_API + #else + EGL_OPENGL_API + #endif + ) != EGL_TRUE) + return "eglBindAPI returned EGL_FALSE"; + + EGLint eglConfigCount; + data->ffeglGetConfigs(data->display, &data->config, 1, &eglConfigCount); + if(eglConfigCount == 0) + return "eglGetConfigs returned 0 configs"; + + data->surface = data->ffeglCreatePbufferSurface(data->display, data->config, (EGLint[]){ + EGL_WIDTH, FF_OPENGL_BUFFER_WIDTH, + EGL_HEIGHT, FF_OPENGL_BUFFER_HEIGHT, + EGL_NONE + }); + + if(data->surface == EGL_NO_SURFACE) + return "eglCreatePbufferSurface returned EGL_NO_SURFACE"; + + const char* error = eglHandleSurface(result, data); + data->ffeglDestroySurface(data->display, data->surface); + return error; +} + +static const char* eglHandleData(FFOpenGLResult* result, EGLData* data) +{ + data->ffglGetString = (__typeof__(&glGetString)) data->ffeglGetProcAddress("glGetString"); + if(!data->ffglGetString) + return "eglGetProcAddress(glGetString) returned NULL"; + + data->display = data->ffeglGetDisplay(EGL_DEFAULT_DISPLAY); + if(data->display == EGL_NO_DISPLAY) + return "eglGetDisplay returned EGL_NO_DISPLAY"; + + EGLint major, minor; + if(data->ffeglInitialize(data->display, &major, &minor) == EGL_FALSE) + return "eglInitialize returned EGL_FALSE"; + + const char* error = eglHandleDisplay(result, data); + data->ffeglTerminate(data->display); + return error; +} + +const char* ffOpenGLDetectByEGL(FFOpenGLResult* result) +{ + EGLData eglData; + + FF_LIBRARY_LOAD(egl, &instance.config.library.libEGL, "dlopen egl failed", "libEGL" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetProcAddress); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetDisplay); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglQueryString); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglInitialize); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglBindAPI); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglGetConfigs); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreatePbufferSurface); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglCreateContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglMakeCurrent); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroyContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglDestroySurface); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(egl, eglData, eglTerminate); + + FF_SUPPRESS_IO(); + return eglHandleData(result, &eglData); +} + +#endif //FF_HAVE_EGL + +#endif //FF_HAVE_NO_GL diff --git a/src/detection/opengl/opengl_windows.c b/src/detection/opengl/opengl_windows.c index 0ad0d4572f..3984c93098 100644 --- a/src/detection/opengl/opengl_windows.c +++ b/src/detection/opengl/opengl_windows.c @@ -4,9 +4,6 @@ #include #include -#ifndef GL_SHADING_LANGUAGE_VERSION // For WGL - #define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#endif typedef struct WGLData { @@ -19,20 +16,14 @@ typedef struct WGLData FF_LIBRARY_SYMBOL(wglDeleteContext) } WGLData; -static void glHandleResult(WGLData* wglData) -{ - ffStrbufAppendS(&wglData->result->version, (const char*) wglData->ffglGetString(GL_VERSION)); - ffStrbufAppendS(&wglData->result->renderer, (const char*) wglData->ffglGetString(GL_RENDERER)); - ffStrbufAppendS(&wglData->result->vendor, (const char*) wglData->ffglGetString(GL_VENDOR)); - ffStrbufAppendS(&wglData->result->slv, (const char*) wglData->ffglGetString(GL_SHADING_LANGUAGE_VERSION)); - ffStrbufSetStatic(&wglData->result->library, "WGL 1.0"); -} +void ffOpenGLHandleResult(FFOpenGLResult* result, __typeof__(&glGetString) ffglGetString); static const char* wglHandleContext(WGLData* wglData, HDC hdc, HGLRC context) { if(wglData->ffwglMakeCurrent(hdc, context) == FALSE) return "wglMakeCurrent() failed"; - glHandleResult(wglData); + ffOpenGLHandleResult(wglData->result, wglData->ffglGetString); + ffStrbufSetStatic(&wglData->result->library, "WGL 1.0"); return NULL; } @@ -88,16 +79,16 @@ static LRESULT CALLBACK wglHandleWndProc(HWND hWnd, UINT message, WPARAM wParam, } } -const char* ffDetectOpenGL(FF_MAYBE_UNUSED FFOpenGLOptions* options, FFOpenGLResult* result) +static const char* wglDetectOpenGL(FFOpenGLResult* result) { FF_LIBRARY_LOAD(opengl32, NULL, "dlopen opengl32" FF_LIBRARY_EXTENSION " failed", "opengl32" FF_LIBRARY_EXTENSION, 1); WGLData data = { .result = result }; - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, glGetString); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglMakeCurrent); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglCreateContext); FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, wglDeleteContext); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(opengl32, data, glGetString); MSG msg = {0}; WNDCLASSW wc = { @@ -110,10 +101,28 @@ const char* ffDetectOpenGL(FF_MAYBE_UNUSED FFOpenGLOptions* options, FFOpenGLRes if(!RegisterClassW(&wc)) return "RegisterClassW() failed"; - HWND hWnd = CreateWindowW(wc.lpszClassName, L"ogl_version_check", 0, 0, 0, 1, 1, NULL, NULL, NULL, &data); + HWND hWnd = CreateWindowW(wc.lpszClassName, L"ogl_version_check", 0, 0, 0, FF_OPENGL_BUFFER_WIDTH, FF_OPENGL_BUFFER_HEIGHT, NULL, NULL, NULL, &data); while(GetMessageW(&msg, hWnd, 0, 0) > 0) DispatchMessage(&msg); return data.error; } + + +const char* ffDetectOpenGL(FFOpenGLOptions* options, FFOpenGLResult* result) +{ + if (options->library == FF_OPENGL_LIBRARY_AUTO) + return wglDetectOpenGL(result); + else if (options->library == FF_OPENGL_LIBRARY_EGL) + { + #if __has_include() + const char* ffOpenGLDetectByEGL(FFOpenGLResult* result); + return ffOpenGLDetectByEGL(result); + #else + return "fastfetch was compiled without egl support"; + #endif + } + else + return "Unsupported OpenGL library"; +} diff --git a/src/modules/opengl/opengl.c b/src/modules/opengl/opengl.c index e7bbff3ee8..d5d56b8342 100644 --- a/src/modules/opengl/opengl.c +++ b/src/modules/opengl/opengl.c @@ -52,7 +52,6 @@ bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, cons if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) return true; - #if defined(__linux__) || defined(__FreeBSD__) if (ffStrEqualsIgnCase(subKey, "library")) { options->library = (FFOpenGLLibrary) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { @@ -64,7 +63,6 @@ bool ffParseOpenGLCommandOptions(FFOpenGLOptions* options, const char* key, cons }); return true; } - #endif return false; } @@ -82,7 +80,6 @@ void ffParseOpenGLJsonObject(FFOpenGLOptions* options, yyjson_val* module) if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) continue; - #if defined(__linux__) || defined(__FreeBSD__) if (ffStrEqualsIgnCase(key, "library")) { int value; @@ -99,7 +96,6 @@ void ffParseOpenGLJsonObject(FFOpenGLOptions* options, yyjson_val* module) options->library = (FFOpenGLLibrary) value; continue; } - #endif ffPrintError(FF_OPENGL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); } @@ -112,7 +108,6 @@ void ffGenerateOpenGLJsonConfig(FFOpenGLOptions* options, yyjson_mut_doc* doc, y ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs); - #if defined(__linux__) || defined(__FreeBSD__) if (options->library != defaultOptions.library) { switch (options->library) @@ -131,7 +126,6 @@ void ffGenerateOpenGLJsonConfig(FFOpenGLOptions* options, yyjson_mut_doc* doc, y break; } } - #endif } void ffGenerateOpenGLJsonResult(FF_MAYBE_UNUSED FFOpenGLOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) @@ -191,9 +185,7 @@ void ffInitOpenGLOptions(FFOpenGLOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs); - #if defined(__linux__) || defined(__FreeBSD__) options->library = FF_OPENGL_LIBRARY_AUTO; - #endif } void ffDestroyOpenGLOptions(FFOpenGLOptions* options) diff --git a/src/modules/opengl/option.h b/src/modules/opengl/option.h index ca60b7da33..8c9db63091 100644 --- a/src/modules/opengl/option.h +++ b/src/modules/opengl/option.h @@ -4,7 +4,6 @@ #include "common/option.h" -#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) typedef enum FFOpenGLLibrary { FF_OPENGL_LIBRARY_AUTO, @@ -12,14 +11,11 @@ typedef enum FFOpenGLLibrary FF_OPENGL_LIBRARY_GLX, FF_OPENGL_LIBRARY_OSMESA } FFOpenGLLibrary; -#endif typedef struct FFOpenGLOptions { FFModuleBaseInfo moduleInfo; FFModuleArgs moduleArgs; - #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) FFOpenGLLibrary library; - #endif } FFOpenGLOptions; diff --git a/src/options/library.c b/src/options/library.c index 36aa4033ba..a80f4b6c60 100644 --- a/src/options/library.c +++ b/src/options/library.c @@ -27,6 +27,8 @@ const char* ffOptionsParseLibraryJsonConfig(FFOptionsLibrary* options, yyjson_va ffStrbufSetS(&options->libChafa, yyjson_get_str(val)); else if (ffStrEqualsIgnCase(key, "z")) ffStrbufSetS(&options->libZ, yyjson_get_str(val)); + else if (ffStrEqualsIgnCase(key, "egl")) + ffStrbufSetS(&options->libEGL, yyjson_get_str(val)); #ifdef __ANDROID__ else if (ffStrEqualsIgnCase(key, "freetype")) @@ -54,8 +56,6 @@ const char* ffOptionsParseLibraryJsonConfig(FFOptionsLibrary* options, yyjson_va ffStrbufSetS(&options->libXFConf, yyjson_get_str(val)); else if (ffStrEqualsIgnCase(key, "rpm")) ffStrbufSetS(&options->librpm, yyjson_get_str(val)); - else if (ffStrEqualsIgnCase(key, "egl")) - ffStrbufSetS(&options->libEGL, yyjson_get_str(val)); else if (ffStrEqualsIgnCase(key, "glx")) ffStrbufSetS(&options->libGLX, yyjson_get_str(val)); else if (ffStrEqualsIgnCase(key, "osmesa")) @@ -94,6 +94,8 @@ bool ffOptionsParseLibraryCommandLine(FFOptionsLibrary* options, const char* key ffOptionParseString(key, value, &options->libChafa); else if(ffStrEqualsIgnCase(subkey, "z")) ffOptionParseString(key, value, &options->libZ); + else if(ffStrEqualsIgnCase(subkey, "egl")) + ffOptionParseString(key, value, &options->libEGL); #ifdef __ANDROID__ else if(ffStrEqualsIgnCase(subkey, "freetype")) @@ -121,8 +123,6 @@ bool ffOptionsParseLibraryCommandLine(FFOptionsLibrary* options, const char* key ffOptionParseString(key, value, &options->libXFConf); else if(ffStrEqualsIgnCase(subkey, "rpm")) ffOptionParseString(key, value, &options->librpm); - else if(ffStrEqualsIgnCase(subkey, "egl")) - ffOptionParseString(key, value, &options->libEGL); else if(ffStrEqualsIgnCase(subkey, "glx")) ffOptionParseString(key, value, &options->libGLX); else if(ffStrEqualsIgnCase(subkey, "osmesa")) @@ -184,7 +184,10 @@ void ffOptionsGenerateLibraryJsonConfig(FFOptionsLibrary* options, yyjson_mut_do if (!ffStrbufEqual(&options->libZ, &defaultOptions.libZ)) yyjson_mut_obj_add_strbuf(doc, obj, "z", &options->libZ); -#if defined(__linux__) || defined(__FreeBSD__) + if (!ffStrbufEqual(&options->libEGL, &defaultOptions.libEGL)) + yyjson_mut_obj_add_strbuf(doc, obj, "egl", &options->libEGL); + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) if (!ffStrbufEqual(&options->libWayland, &defaultOptions.libWayland)) yyjson_mut_obj_add_strbuf(doc, obj, "wayland", &options->libWayland); @@ -215,9 +218,6 @@ void ffOptionsGenerateLibraryJsonConfig(FFOptionsLibrary* options, yyjson_mut_do if (!ffStrbufEqual(&options->librpm, &defaultOptions.librpm)) yyjson_mut_obj_add_strbuf(doc, obj, "rpm", &options->librpm); - if (!ffStrbufEqual(&options->libEGL, &defaultOptions.libEGL)) - yyjson_mut_obj_add_strbuf(doc, obj, "egl", &options->libEGL); - if (!ffStrbufEqual(&options->libGLX, &defaultOptions.libGLX)) yyjson_mut_obj_add_strbuf(doc, obj, "glx", &options->libGLX); diff --git a/src/options/library.h b/src/options/library.h index cc65302b5e..55f2be4e22 100644 --- a/src/options/library.h +++ b/src/options/library.h @@ -10,6 +10,7 @@ typedef struct FFOptionsLibrary FFstrbuf libImageMagick; FFstrbuf libChafa; FFstrbuf libZ; + FFstrbuf libEGL; #ifdef __ANDROID__ FFstrbuf libfreetype; @@ -26,7 +27,6 @@ typedef struct FFOptionsLibrary FFstrbuf libDBus; FFstrbuf libXFConf; FFstrbuf librpm; - FFstrbuf libEGL; FFstrbuf libGLX; FFstrbuf libOSMesa; FFstrbuf libPulse; From ab84c2ca760d9fd43c0bf913dcbbf0c532fdc12a Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 10 Jul 2024 11:13:28 +0800 Subject: [PATCH 37/41] Doc: update json schema and help message --- completions/fastfetch.bash | 1 - doc/json_schema.json | 44 +++++++++++++++++++------------------- src/data/help.json | 7 ------ 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/completions/fastfetch.bash b/completions/fastfetch.bash index 5edb9419f0..8cfdc9a84d 100644 --- a/completions/fastfetch.bash +++ b/completions/fastfetch.bash @@ -356,7 +356,6 @@ __fastfetch_completion() local FF_OPTIONS_PATH=( "-c" "--config" - "--lib-pci" "--lib-vulkan" "--lib-wayland" "--lib-xcb-randr" diff --git a/doc/json_schema.json b/doc/json_schema.json index c8a317aa3d..0545cce7f3 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -586,10 +586,6 @@ "type": "object", "additionalProperties": false, "properties": { - "pci": { - "type": "string", - "description": "GPU output (Linux and FreeBSD)" - }, "vulkan": { "type": "string", "description": "Vulkan module & fallback for GPU output" @@ -604,39 +600,39 @@ }, "xcbRandr": { "type": "string", - "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)" }, "xcb": { "type": "string", - "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)" }, "xrandr": { "type": "string", - "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)" }, "x11": { "type": "string", - "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD)" + "description": "X11 sessions for better display detection and faster WM detection.\nThe *randr ones provide multi monitor support The libxcb* ones usually have better performance.\n (Linux, FreeBSD, SunOS)" }, "drm": { "type": "string", - "description": "Used for fast resolution and refresh rate detection (Linux)" + "description": "Used for fast resolution and refresh rate detection (Linux, FreeBSD)" }, "gio": { "type": "string", - "description": "Needed for values that are only stored GSettings (Linux, FreeBSD)" + "description": "Needed for values that are only stored GSettings (Linux, FreeBSD, SunOS)" }, "dconf": { "type": "string", - "description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD)" + "description": "Needed for values that are only stored in DConf + Fallback for GSettings (Linux, FreeBSD, SunOS)" }, "dbus": { "type": "string", - "description": "Bluetooth, Player & Media detection (Linux, FreeBSD)" + "description": "Bluetooth, Player & Media detection (Linux, FreeBSD, SunOS)" }, "xfconf": { "type": "string", - "description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD)" + "description": "Needed for XFWM theme and XFCE Terminal font (Linux, FreeBSD, SunOS)" }, "sqlite3": { "type": "string", @@ -648,34 +644,34 @@ }, "imagemagick": { "type": "string", - "description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, macOS)" + "description": "Images in terminal using sixel or kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)" }, "z": { - "description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, macOS)", + "description": "Libz. Faster image output when using kitty graphics protocol (Linux, FreeBSD, SunOS, macOS)", "type": "string" }, "chafa": { "type": "string", - "description": "Image output as ascii art (Linux, FreeBSD, macOS)" + "description": "Image output as ascii art (Linux, FreeBSD, SunOS, macOS)" }, "egl": { "type": "string", - "description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + "description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS, Windows)" }, "glx": { "type": "string", - "description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + "description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)" }, "osmesa": { "type": "string", - "description": "Needed by the OpenGL module for gl context creation (Linux, FreeBSD)" + "description": "Library used by the OpenGL module for gl context creation (Linux, FreeBSD, SunOS)" }, "opencl": { "type": "string", - "description": "OpenCL module (Linux, FreeBSD, Windows)" + "description": "OpenCL module (Linux, FreeBSD, SunOS, Windows)" }, "pulse": { - "description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD)", + "description": "Pulseaudio. Used for Sound detection (Linux, FreeBSD, SunOS)", "type": "string" }, "nm": { @@ -1771,7 +1767,7 @@ "const": "opengl" }, "library": { - "description": "Set the OpenGL context creation library to use. Linux only", + "description": "Set the OpenGL context creation library to use", "enum": [ "auto", "egl", @@ -1820,6 +1816,9 @@ "emerge", "eopkg", "flatpak", + "guix", + "lpkg", + "lpkgbuild", "macports", "nix", "opkg", @@ -1830,6 +1829,7 @@ "rpm", "scoop", "snap", + "sorcery", "winget", "xbps" ], diff --git a/src/data/help.json b/src/data/help.json index bdefdd8e26..3fb1678e60 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -738,13 +738,6 @@ } ], "Library path": [ - { - "long": "lib-pci", - "desc": "Pciutils. Used for GPU output", - "arg": { - "type": "path" - } - }, { "long": "lib-vulkan", "desc": "Vulkan module & fallback for GPU output", From 5e9c0d03ff714e1c387fe5bc50972b1c8565dabd Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 10 Jul 2024 13:36:23 +0800 Subject: [PATCH 38/41] 3rdparty: upgrade yyjson to 0.10.0 --- src/3rdparty/yyjson/repo.json | 2 +- src/3rdparty/yyjson/yyjson.c | 209 ++++++++++++++++++++++++---------- src/3rdparty/yyjson/yyjson.h | 24 +++- 3 files changed, 174 insertions(+), 61 deletions(-) diff --git a/src/3rdparty/yyjson/repo.json b/src/3rdparty/yyjson/repo.json index 1d62a5a24d..f0deb32295 100644 --- a/src/3rdparty/yyjson/repo.json +++ b/src/3rdparty/yyjson/repo.json @@ -1,6 +1,6 @@ { "home": "https://github.com/ibireme/yyjson", "license": "MIT ( embed in source )", - "version": "0.9.0", + "version": "0.10.0", "author": "ibireme" } diff --git a/src/3rdparty/yyjson/yyjson.c b/src/3rdparty/yyjson/yyjson.c index 4202d8a031..16ecbacf52 100644 --- a/src/3rdparty/yyjson/yyjson.c +++ b/src/3rdparty/yyjson/yyjson.c @@ -1831,6 +1831,42 @@ bool unsafe_yyjson_mut_equals(yyjson_mut_val *lhs, yyjson_mut_val *rhs) { } } +bool yyjson_locate_pos(const char *str, size_t len, size_t pos, + size_t *line, size_t *col, size_t *chr) { + usize line_sum = 0, line_pos = 0, chr_sum = 0; + const u8 *cur = (const u8 *)str; + const u8 *end = cur + pos; + + if (!str || pos > len) { + if (line) *line = 0; + if (col) *col = 0; + if (chr) *chr = 0; + return false; + } + + while (cur < end) { + u8 c = *cur; + chr_sum += 1; + if (likely(c < 0x80)) { /* 0xxxxxxx (0x00-0x7F) ASCII */ + if (c == '\n') { + line_sum += 1; + line_pos = chr_sum; + } + cur += 1; + } + else if (c < 0xC0) cur += 1; /* 10xxxxxx (0x80-0xBF) Invalid */ + else if (c < 0xE0) cur += 2; /* 110xxxxx (0xC0-0xDF) 2-byte UTF-8 */ + else if (c < 0xF0) cur += 3; /* 1110xxxx (0xE0-0xEF) 3-byte UTF-8 */ + else if (c < 0xF8) cur += 4; /* 11110xxx (0xF0-0xF7) 4-byte UTF-8 */ + else cur += 1; /* 11111xxx (0xF8-0xFF) Invalid */ + } + + if (line) *line = line_sum + 1; + if (col) *col = chr_sum - line_pos + 1; + if (chr) *chr = chr_sum; + return true; +} + #if !YYJSON_DISABLE_UTILS @@ -4434,7 +4470,7 @@ static_inline bool read_number(u8 **ptr, bool sign; /* read number as raw string if has `YYJSON_READ_NUMBER_AS_RAW` flag */ - if (unlikely(pre && !has_read_flag(BIGNUM_AS_RAW))) { + if (has_read_flag(NUMBER_AS_RAW)) { return read_number_raw(ptr, pre, flg, val, msg); } @@ -5036,7 +5072,7 @@ static_inline bool read_number(u8 **ptr, bool sign; /* read number as raw string if has `YYJSON_READ_NUMBER_AS_RAW` flag */ - if (unlikely(pre && !has_read_flag(BIGNUM_AS_RAW))) { + if (has_read_flag(NUMBER_AS_RAW)) { return read_number_raw(ptr, pre, flg, val, msg); } @@ -5744,18 +5780,18 @@ static_noinline yyjson_doc *read_root_single(u8 *hdr, } if (*cur == 't') { if (likely(read_true(&cur, val))) goto doc_end; - goto fail_literal; + goto fail_literal_true; } if (*cur == 'f') { if (likely(read_false(&cur, val))) goto doc_end; - goto fail_literal; + goto fail_literal_false; } if (*cur == 'n') { if (likely(read_null(&cur, val))) goto doc_end; if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_nan(false, &cur, pre, val)) goto doc_end; } - goto fail_literal; + goto fail_literal_null; } if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_inf_or_nan(false, &cur, pre, val)) goto doc_end; @@ -5789,15 +5825,26 @@ static_noinline yyjson_doc *read_root_single(u8 *hdr, fail_number: return_err(cur, INVALID_NUMBER, msg); fail_alloc: - return_err(cur, MEMORY_ALLOCATION, "memory allocation failed"); -fail_literal: - return_err(cur, LITERAL, "invalid literal"); -fail_comment: - return_err(cur, INVALID_COMMENT, "unclosed multiline comment"); + return_err(cur, MEMORY_ALLOCATION, + "memory allocation failed"); +fail_literal_true: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'true'"); +fail_literal_false: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'false'"); +fail_literal_null: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'null'"); fail_character: - return_err(cur, UNEXPECTED_CHARACTER, "unexpected character"); + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a valid root value"); +fail_comment: + return_err(cur, INVALID_COMMENT, + "unclosed multiline comment"); fail_garbage: - return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document"); + return_err(cur, UNEXPECTED_CONTENT, + "unexpected content after document"); #undef return_err } @@ -5927,13 +5974,13 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, val_incr(); ctn_len++; if (likely(read_true(&cur, val))) goto arr_val_end; - goto fail_literal; + goto fail_literal_true; } if (*cur == 'f') { val_incr(); ctn_len++; if (likely(read_false(&cur, val))) goto arr_val_end; - goto fail_literal; + goto fail_literal_false; } if (*cur == 'n') { val_incr(); @@ -5942,7 +5989,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_nan(false, &cur, pre, val)) goto arr_val_end; } - goto fail_literal; + goto fail_literal_null; } if (*cur == ']') { cur++; @@ -5960,13 +6007,13 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, val_incr(); ctn_len++; if (read_inf_or_nan(false, &cur, pre, val)) goto arr_val_end; - goto fail_character; + goto fail_character_val; } if (has_read_flag(ALLOW_COMMENTS)) { if (skip_spaces_and_comments(&cur)) goto arr_val_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_val; arr_val_end: if (*cur == ',') { @@ -5985,7 +6032,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto arr_val_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_arr_end; arr_end: /* get parent container */ @@ -6038,7 +6085,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_key_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_key; obj_key_end: if (*cur == ':') { @@ -6053,7 +6100,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_key_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_sep; obj_val_begin: if (*cur == '"') { @@ -6080,13 +6127,13 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, val++; ctn_len++; if (likely(read_true(&cur, val))) goto obj_val_end; - goto fail_literal; + goto fail_literal_true; } if (*cur == 'f') { val++; ctn_len++; if (likely(read_false(&cur, val))) goto obj_val_end; - goto fail_literal; + goto fail_literal_false; } if (*cur == 'n') { val++; @@ -6095,7 +6142,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_nan(false, &cur, pre, val)) goto obj_val_end; } - goto fail_literal; + goto fail_literal_null; } if (char_is_space(*cur)) { while (char_is_space(*++cur)); @@ -6106,13 +6153,13 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, val++; ctn_len++; if (read_inf_or_nan(false, &cur, pre, val)) goto obj_val_end; - goto fail_character; + goto fail_character_val; } if (has_read_flag(ALLOW_COMMENTS)) { if (skip_spaces_and_comments(&cur)) goto obj_val_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_val; obj_val_end: if (likely(*cur == ',')) { @@ -6131,7 +6178,7 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_val_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_end; obj_end: /* pop container */ @@ -6174,17 +6221,41 @@ static_inline yyjson_doc *read_root_minify(u8 *hdr, fail_number: return_err(cur, INVALID_NUMBER, msg); fail_alloc: - return_err(cur, MEMORY_ALLOCATION, "memory allocation failed"); + return_err(cur, MEMORY_ALLOCATION, + "memory allocation failed"); fail_trailing_comma: - return_err(cur, JSON_STRUCTURE, "trailing comma is not allowed"); -fail_literal: - return_err(cur, LITERAL, "invalid literal"); + return_err(cur, JSON_STRUCTURE, + "trailing comma is not allowed"); +fail_literal_true: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'true'"); +fail_literal_false: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'false'"); +fail_literal_null: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'null'"); +fail_character_val: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a valid JSON value"); +fail_character_arr_end: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a comma or a closing bracket"); +fail_character_obj_key: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a string for object key"); +fail_character_obj_sep: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a colon after object key"); +fail_character_obj_end: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a comma or a closing brace"); fail_comment: - return_err(cur, INVALID_COMMENT, "unclosed multiline comment"); -fail_character: - return_err(cur, UNEXPECTED_CHARACTER, "unexpected character"); + return_err(cur, INVALID_COMMENT, + "unclosed multiline comment"); fail_garbage: - return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document"); + return_err(cur, UNEXPECTED_CONTENT, + "unexpected content after document"); #undef val_incr #undef return_err @@ -6330,13 +6401,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, val_incr(); ctn_len++; if (likely(read_true(&cur, val))) goto arr_val_end; - goto fail_literal; + goto fail_literal_true; } if (*cur == 'f') { val_incr(); ctn_len++; if (likely(read_false(&cur, val))) goto arr_val_end; - goto fail_literal; + goto fail_literal_false; } if (*cur == 'n') { val_incr(); @@ -6345,7 +6416,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_nan(false, &cur, pre, val)) goto arr_val_end; } - goto fail_literal; + goto fail_literal_null; } if (*cur == ']') { cur++; @@ -6363,13 +6434,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, val_incr(); ctn_len++; if (read_inf_or_nan(false, &cur, pre, val)) goto arr_val_end; - goto fail_character; + goto fail_character_val; } if (has_read_flag(ALLOW_COMMENTS)) { if (skip_spaces_and_comments(&cur)) goto arr_val_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_val; arr_val_end: if (byte_match_2(cur, ",\n")) { @@ -6392,7 +6463,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto arr_val_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_arr_end; arr_end: /* get parent container */ @@ -6458,7 +6529,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_key_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_key; obj_key_end: if (byte_match_2(cur, ": ")) { @@ -6477,7 +6548,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_key_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_sep; obj_val_begin: if (*cur == '"') { @@ -6504,13 +6575,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, val++; ctn_len++; if (likely(read_true(&cur, val))) goto obj_val_end; - goto fail_literal; + goto fail_literal_true; } if (*cur == 'f') { val++; ctn_len++; if (likely(read_false(&cur, val))) goto obj_val_end; - goto fail_literal; + goto fail_literal_false; } if (*cur == 'n') { val++; @@ -6519,7 +6590,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (has_read_flag(ALLOW_INF_AND_NAN)) { if (read_nan(false, &cur, pre, val)) goto obj_val_end; } - goto fail_literal; + goto fail_literal_null; } if (char_is_space(*cur)) { while (char_is_space(*++cur)); @@ -6530,13 +6601,13 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, val++; ctn_len++; if (read_inf_or_nan(false, &cur, pre, val)) goto obj_val_end; - goto fail_character; + goto fail_character_val; } if (has_read_flag(ALLOW_COMMENTS)) { if (skip_spaces_and_comments(&cur)) goto obj_val_begin; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_val; obj_val_end: if (byte_match_2(cur, ",\n")) { @@ -6559,7 +6630,7 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, if (skip_spaces_and_comments(&cur)) goto obj_val_end; if (byte_match_2(cur, "/*")) goto fail_comment; } - goto fail_character; + goto fail_character_obj_end; obj_end: /* pop container */ @@ -6603,17 +6674,41 @@ static_inline yyjson_doc *read_root_pretty(u8 *hdr, fail_number: return_err(cur, INVALID_NUMBER, msg); fail_alloc: - return_err(cur, MEMORY_ALLOCATION, "memory allocation failed"); + return_err(cur, MEMORY_ALLOCATION, + "memory allocation failed"); fail_trailing_comma: - return_err(cur, JSON_STRUCTURE, "trailing comma is not allowed"); -fail_literal: - return_err(cur, LITERAL, "invalid literal"); + return_err(cur, JSON_STRUCTURE, + "trailing comma is not allowed"); +fail_literal_true: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'true'"); +fail_literal_false: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'false'"); +fail_literal_null: + return_err(cur, LITERAL, + "invalid literal, expected a valid literal such as 'null'"); +fail_character_val: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a valid JSON value"); +fail_character_arr_end: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a comma or a closing bracket"); +fail_character_obj_key: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a string for object key"); +fail_character_obj_sep: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a colon after object key"); +fail_character_obj_end: + return_err(cur, UNEXPECTED_CHARACTER, + "unexpected character, expected a comma or a closing brace"); fail_comment: - return_err(cur, INVALID_COMMENT, "unclosed multiline comment"); -fail_character: - return_err(cur, UNEXPECTED_CHARACTER, "unexpected character"); + return_err(cur, INVALID_COMMENT, + "unclosed multiline comment"); fail_garbage: - return_err(cur, UNEXPECTED_CONTENT, "unexpected content after document"); + return_err(cur, UNEXPECTED_CONTENT, + "unexpected content after document"); #undef val_incr #undef return_err @@ -7835,7 +7930,7 @@ static const u8 esc_single_char_table[512] = { /** Returns the encode table with options. */ static_inline const char_enc_type *get_enc_table_with_flag( - yyjson_read_flag flg) { + yyjson_write_flag flg) { if (has_write_flag(ESCAPE_UNICODE)) { if (has_write_flag(ESCAPE_SLASHES)) { return enc_table_esc_slash; diff --git a/src/3rdparty/yyjson/yyjson.h b/src/3rdparty/yyjson/yyjson.h index 64c44742fe..88cec2b09e 100644 --- a/src/3rdparty/yyjson/yyjson.h +++ b/src/3rdparty/yyjson/yyjson.h @@ -527,16 +527,16 @@ extern "C" { #define YYJSON_VERSION_MAJOR 0 /** The minor version of yyjson. */ -#define YYJSON_VERSION_MINOR 9 +#define YYJSON_VERSION_MINOR 10 /** The patch version of yyjson. */ #define YYJSON_VERSION_PATCH 0 /** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */ -#define YYJSON_VERSION_HEX 0x000900 +#define YYJSON_VERSION_HEX 0x000A00 /** The version string of yyjson. */ -#define YYJSON_VERSION_STRING "0.9.0" +#define YYJSON_VERSION_STRING "0.10.0" /** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */ yyjson_api uint32_t yyjson_version(void); @@ -841,6 +841,24 @@ typedef struct yyjson_read_err { size_t pos; } yyjson_read_err; +/** + Locate the line and column number for a byte position in a string. + This can be used to get better description for error position. + + @param str The input string. + @param len The byte length of the input string. + @param pos The byte position within the input string. + @param line A pointer to receive the line number, starting from 1. + @param col A pointer to receive the column number, starting from 1. + @param chr A pointer to receive the character index, starting from 0. + @return true on success, false if `str` is NULL or `pos` is out of bounds. + @note Line/column/character are calculated based on Unicode characters for + compatibility with text editors. For multi-byte UTF-8 characters, + the returned value may not directly correspond to the byte position. + */ +yyjson_api bool yyjson_locate_pos(const char *str, size_t len, size_t pos, + size_t *line, size_t *col, size_t *chr); + /** From 6a33027892daa468f1823cb8ed70f77e4a05d88b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 10 Jul 2024 13:37:11 +0800 Subject: [PATCH 39/41] Fastfetch: use the official function instead of our local copy --- src/fastfetch.c | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/src/fastfetch.c b/src/fastfetch.c index 12de044e56..2f4a56e32f 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -319,44 +319,6 @@ static void listModules(bool pretty) } } -// Temporary copy before new release of yyjson -static bool ffyyjson_locate_pos(const char *str, size_t len, size_t pos, - size_t *line, size_t *col, size_t *chr) { - size_t line_sum = 0, line_pos = 0, chr_sum = 0; - const uint8_t *cur = (const uint8_t *)str; - const uint8_t *end = cur + pos; - - if (!str || pos > len) { - if (line) *line = 0; - if (col) *col = 0; - if (chr) *chr = 0; - return false; - } - - while (cur < end) { - uint8_t c = *cur; - chr_sum += 1; - if (__builtin_expect(c < 0x80, true)) { /* 0xxxxxxx (0x00-0x7F) ASCII */ - if (c == '\n') { - line_sum += 1; - line_pos = chr_sum; - } - cur += 1; - } - else if (c < 0xC0) cur += 1; /* 10xxxxxx (0x80-0xBF) Invalid */ - else if (c < 0xE0) cur += 2; /* 110xxxxx (0xC0-0xDF) 2-byte UTF-8 */ - else if (c < 0xF0) cur += 3; /* 1110xxxx (0xE0-0xEF) 3-byte UTF-8 */ - else if (c < 0xF8) cur += 4; /* 11110xxx (0xF0-0xF7) 4-byte UTF-8 */ - else cur += 1; /* 11111xxx (0xF8-0xFF) Invalid */ - } - - if (line) *line = line_sum + 1; - if (col) *col = chr_sum - line_pos + 1; - if (chr) *chr = chr_sum; - return true; -} - - static bool parseJsoncFile(const char* path) { assert(!instance.state.configDoc); @@ -371,7 +333,7 @@ static bool parseJsoncFile(const char* path) size_t row = 0, col = error.pos; FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate(); if (ffAppendFileBuffer(path, &content)) - ffyyjson_locate_pos(content.chars, content.length, error.pos, &row, &col, NULL); + yyjson_locate_pos(content.chars, content.length, error.pos, &row, &col, NULL); fprintf(stderr, "Error: failed to parse JSON config file `%s` at (%zu, %zu): %s\n", path, row, col, error.msg); exit(477); } From eefed2be9c83cf258dcb1607a0f79268c960049e Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 10 Jul 2024 13:57:02 +0800 Subject: [PATCH 40/41] Release: v2.18.0 --- CHANGELOG.md | 13 ++++++++++--- CMakeLists.txt | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d5d861d2..7590c997fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,27 @@ -# 2.17.3 +# 2.18.0 + +Changes: +* `yyjson 0.10.0` is required +* Fastfetch no longer prints `*` (which means it's the default route) if `defaultRouteOnly` is set (LocalIP) Bugfixes: -* Don't print `*` if `defaultRouteOnly` is set (LocalIP) * Fix some memory leaks * Fix compatibility with old Python versions * Don't detect frequency for AMD cards (GPU, Linux) * Fix possible hang with discrete AMD cards (#1077) * Don't print colors in `--pipe` mode (Separator) +* Don't print `(null)` in property `locator` (PhysicalMemory) +* Ignore disabled PCI devices (GPU) +* Fix flag `--opengl-library` doesn't work (OpenGL) Features: * Detect revision of USB drives (#1048, Disk) -* Don't print `(null)` in property `locator` (PhysicalMemory) * Support fractional scale factor detection (Display, Linux) * Support primary display detection for KDE and GNOME (Display, Linux) * Support percent bar in custom formatting * Print signal quality by default (Wifi) +* Detect used OpenGL library version (OpenGL) +* Support detecting OpenGL version by `EGL` (ANGLE) on Windows (OpenGL) Logos: * Add Arkane Linux diff --git a/CMakeLists.txt b/CMakeLists.txt index 02cea22567..74a6603eb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.17.2 + VERSION 2.18.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" From fca4b3eee8cff73f32ac4322198a4fc2776daf6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 10 Jul 2024 14:41:08 +0800 Subject: [PATCH 41/41] CI: remove freebsd-aarch64 It's unstable and I don't think anyone uses it --- .github/workflows/ci.yml | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e6c9a4f60..068825001b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -438,43 +438,6 @@ jobs: name: fastfetch-freebsd-amd64 path: ./fastfetch-*.* - freebsd-aarch64: - name: FreeBSD-aarch64 - runs-on: ubuntu-latest - permissions: - security-events: write - contents: read - steps: - - name: checkout repository - uses: actions/checkout@v4 - - - name: run VM - uses: cross-platform-actions/action@master - with: - operating_system: freebsd - architecture: arm64 - cpu_count: 3 - shell: bash - version: '13.2' - run: | - uname -a - sudo pkg update - sudo pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf ImageMagick6 ImageMagick7 chafa egl libosmesa opencl ocl-icd v4l_compat - cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . - cmake --build . --target package --verbose -j4 - ./fastfetch --list-features - time ./fastfetch - time ./fastfetch --format json - time ./flashfetch - ldd fastfetch - ctest - - - name: upload artifacts - uses: actions/upload-artifact@v4 - with: - name: fastfetch-freebsd-aarch64 - path: ./fastfetch-*.* - windows-amd64: name: Windows-amd64 runs-on: windows-latest @@ -623,7 +586,6 @@ jobs: - musl-aarch64 - macos-universal - freebsd-amd64 - - freebsd-aarch64 - sunos-amd64 - windows-amd64 - windows-i686