From 7e11df73ba98270cdfb427d48a4e3fbea8b105df Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 7 Apr 2025 21:23:14 +0200 Subject: [PATCH] [client,common] add setting FreeRDP_MonitorOverrideFlags use this mask to mark monitor settings set from command line. --- client/SDL/SDL3/sdl_disp.cpp | 53 +++++++++++-------- client/SDL/SDL3/sdl_disp.hpp | 2 - client/common/cmdline.c | 17 ++++++ include/freerdp/settings_types.h | 5 ++ include/freerdp/settings_types_private.h | 5 +- libfreerdp/common/settings_getters.c | 7 +++ libfreerdp/common/settings_str.h | 1 + .../core/test/settings_property_lists.h | 1 + 8 files changed, 66 insertions(+), 25 deletions(-) diff --git a/client/SDL/SDL3/sdl_disp.cpp b/client/SDL/SDL3/sdl_disp.cpp index abf9a54e9..a441bfef4 100644 --- a/client/SDL/SDL3/sdl_disp.cpp +++ b/client/SDL/SDL3/sdl_disp.cpp @@ -198,37 +198,37 @@ UINT sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors) WINPR_ASSERT(settings); std::vector layouts; - layouts.resize(nmonitors); + layouts.reserve(nmonitors); for (size_t i = 0; i < nmonitors; i++) { auto monitor = &monitors[i]; - auto layout = &layouts[i]; + DISPLAY_CONTROL_MONITOR_LAYOUT layout = {}; - layout->Flags = (monitor->is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0); - layout->Left = monitor->x; - layout->Top = monitor->y; - layout->Width = WINPR_ASSERTING_INT_CAST(uint32_t, monitor->width); - layout->Height = WINPR_ASSERTING_INT_CAST(uint32_t, monitor->height); - layout->Orientation = ORIENTATION_LANDSCAPE; - layout->PhysicalWidth = monitor->attributes.physicalWidth; - layout->PhysicalHeight = monitor->attributes.physicalHeight; + layout.Flags = (monitor->is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0); + layout.Left = monitor->x; + layout.Top = monitor->y; + layout.Width = WINPR_ASSERTING_INT_CAST(uint32_t, monitor->width); + layout.Height = WINPR_ASSERTING_INT_CAST(uint32_t, monitor->height); + layout.Orientation = ORIENTATION_LANDSCAPE; + layout.PhysicalWidth = monitor->attributes.physicalWidth; + layout.PhysicalHeight = monitor->attributes.physicalHeight; switch (monitor->attributes.orientation) { - case 90: - layout->Orientation = ORIENTATION_PORTRAIT; + case ORIENTATION_PORTRAIT: + layout.Orientation = ORIENTATION_PORTRAIT; break; - case 180: - layout->Orientation = ORIENTATION_LANDSCAPE_FLIPPED; + case ORIENTATION_LANDSCAPE_FLIPPED: + layout.Orientation = ORIENTATION_LANDSCAPE_FLIPPED; break; - case 270: - layout->Orientation = ORIENTATION_PORTRAIT_FLIPPED; + case ORIENTATION_PORTRAIT_FLIPPED: + layout.Orientation = ORIENTATION_PORTRAIT_FLIPPED; break; - case 0: + case ORIENTATION_LANDSCAPE: default: /* MS-RDPEDISP - 2.2.2.2.1: * Orientation (4 bytes): A 32-bit unsigned integer that specifies the @@ -237,14 +237,23 @@ UINT sdlDispContext::sendLayout(const rdpMonitor* monitors, size_t nmonitors) * * So we default to ORIENTATION_LANDSCAPE */ - layout->Orientation = ORIENTATION_LANDSCAPE; + layout.Orientation = ORIENTATION_LANDSCAPE; break; } - layout->DesktopScaleFactor = - freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor); - layout->DeviceScaleFactor = - freerdp_settings_get_uint32(settings, FreeRDP_DeviceScaleFactor); + layout.DesktopScaleFactor = monitor->attributes.desktopScaleFactor; + layout.DeviceScaleFactor = monitor->attributes.deviceScaleFactor; + + auto mask = freerdp_settings_get_uint64(settings, FreeRDP_MonitorOverrideFlags); + if ((mask & FREERDP_MONITOR_OVERRIDE_ORIENTATION) != 0) + layout.Orientation = freerdp_settings_get_uint16(settings, FreeRDP_DesktopOrientation); + if ((mask & FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE) != 0) + layout.DesktopScaleFactor = + freerdp_settings_get_uint32(settings, FreeRDP_DesktopScaleFactor); + if ((mask & FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE) != 0) + layout.DeviceScaleFactor = + freerdp_settings_get_uint32(settings, FreeRDP_DeviceScaleFactor); + layouts.emplace_back(layout); } if (!settings_changed(layouts)) diff --git a/client/SDL/SDL3/sdl_disp.hpp b/client/SDL/SDL3/sdl_disp.hpp index 8d5d9401d..9acbc8561 100644 --- a/client/SDL/SDL3/sdl_disp.hpp +++ b/client/SDL/SDL3/sdl_disp.hpp @@ -46,8 +46,6 @@ class sdlDispContext [[nodiscard]] bool handle_display_event(const SDL_DisplayEvent* ev); [[nodiscard]] bool handle_window_event(const SDL_WindowEvent* ev); - [[nodiscard]] UINT32 scale_factor() const; - private: UINT DisplayControlCaps(UINT32 maxNumMonitors, UINT32 maxMonitorAreaFactorA, UINT32 maxMonitorAreaFactorB); diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 516eb8b9c..84f9b920e 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -3557,6 +3557,14 @@ static int parse_reconnect_cookie_options(rdpSettings* settings, const COMMAND_L return 0; } +static BOOL set_monitor_override(rdpSettings* settings, uint64_t flag) +{ + const FreeRDP_Settings_Keys_UInt64 key = FreeRDP_MonitorOverrideFlags; + uint64_t mask = freerdp_settings_get_uint64(settings, key); + mask |= flag; + return freerdp_settings_set_uint64(settings, key, mask); +} + static int parse_scale_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_A* arg) { WINPR_ASSERT(settings); @@ -3576,6 +3584,9 @@ static int parse_scale_options(rdpSettings* settings, const COMMAND_LINE_ARGUMEN return COMMAND_LINE_ERROR; if (!freerdp_settings_set_uint32(settings, FreeRDP_DeviceScaleFactor, (UINT32)val)) return COMMAND_LINE_ERROR; + if (!set_monitor_override(settings, FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE | + FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE)) + return fail_at(arg, COMMAND_LINE_ERROR); break; default: @@ -3601,6 +3612,8 @@ static int parse_scale_device_options(rdpSettings* settings, const COMMAND_LINE_ case 180: if (!freerdp_settings_set_uint32(settings, FreeRDP_DeviceScaleFactor, (UINT32)val)) return COMMAND_LINE_ERROR; + if (!set_monitor_override(settings, FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE)) + return fail_at(arg, COMMAND_LINE_ERROR); break; default: @@ -5368,6 +5381,8 @@ static int parse_command_line(rdpSettings* settings, const COMMAND_LINE_ARGUMENT if (!freerdp_settings_set_uint16(settings, FreeRDP_DesktopOrientation, (UINT16)val)) return fail_at(arg, COMMAND_LINE_ERROR); + if (!set_monitor_override(settings, FREERDP_MONITOR_OVERRIDE_ORIENTATION)) + return fail_at(arg, COMMAND_LINE_ERROR); } CommandLineSwitchCase(arg, "old-license") { @@ -5386,6 +5401,8 @@ static int parse_command_line(rdpSettings* settings, const COMMAND_LINE_ARGUMENT FreeRDP_DesktopScaleFactor, 100, 500); if (rc != 0) return fail_at(arg, rc); + if (!set_monitor_override(settings, FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE)) + return fail_at(arg, COMMAND_LINE_ERROR); } CommandLineSwitchCase(arg, "scale-device") { diff --git a/include/freerdp/settings_types.h b/include/freerdp/settings_types.h index be1ce6bde..6256085a4 100644 --- a/include/freerdp/settings_types.h +++ b/include/freerdp/settings_types.h @@ -341,6 +341,11 @@ extern "C" (CLIPRDR_FLAG_LOCAL_TO_REMOTE | CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES | \ CLIPRDR_FLAG_REMOTE_TO_LOCAL | CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES) + /* Commandline helper defines */ +#define FREERDP_MONITOR_OVERRIDE_ORIENTATION (1 << 0) /** @since version 3.14.2 */ +#define FREERDP_MONITOR_OVERRIDE_DESKTOP_SCALE (1 << 1) /** @since version 3.14.2 */ +#define FREERDP_MONITOR_OVERRIDE_DEVICE_SCALE (1 << 2) /** @since version 3.14.2 */ + /* ARC_CS_PRIVATE_PACKET */ typedef struct { diff --git a/include/freerdp/settings_types_private.h b/include/freerdp/settings_types_private.h index fa0cd1b9b..5e85bfa82 100644 --- a/include/freerdp/settings_types_private.h +++ b/include/freerdp/settings_types_private.h @@ -115,7 +115,10 @@ struct rdp_settings SETTINGS_DEPRECATED(ALIGN64 BOOL SupportEdgeActionV2); /* 151 */ SETTINGS_DEPRECATED(ALIGN64 BOOL SupportSkipChannelJoin); /* 152 */ SETTINGS_DEPRECATED(ALIGN64 UINT16 SupportedColorDepths); /* 153 */ - UINT64 padding0192[192 - 154]; /* 154 */ + SETTINGS_DEPRECATED(ALIGN64 UINT64 MonitorOverrideFlags); /** 154 + * @since version 3.14.2 + */ + UINT64 padding0192[192 - 155]; /* 155 */ /* Client/Server Security Data */ SETTINGS_DEPRECATED(ALIGN64 BOOL UseRdpSecurityLayer); /* 192 */ diff --git a/libfreerdp/common/settings_getters.c b/libfreerdp/common/settings_getters.c index d7c0ddc3b..3ec1003ed 100644 --- a/libfreerdp/common/settings_getters.c +++ b/libfreerdp/common/settings_getters.c @@ -2630,6 +2630,9 @@ UINT64 freerdp_settings_get_uint64(WINPR_ATTR_UNUSED const rdpSettings* settings switch (id) { + case FreeRDP_MonitorOverrideFlags: + return settings->MonitorOverrideFlags; + case FreeRDP_ParentWindowId: return settings->ParentWindowId; @@ -2658,6 +2661,10 @@ BOOL freerdp_settings_set_uint64(WINPR_ATTR_UNUSED rdpSettings* settings, switch (id) { + case FreeRDP_MonitorOverrideFlags: + settings->MonitorOverrideFlags = cnv.c; + break; + case FreeRDP_ParentWindowId: settings->ParentWindowId = cnv.c; break; diff --git a/libfreerdp/common/settings_str.h b/libfreerdp/common/settings_str.h index 30769e3d2..19cbf3a12 100644 --- a/libfreerdp/common/settings_str.h +++ b/libfreerdp/common/settings_str.h @@ -450,6 +450,7 @@ static const struct settings_str_entry settings_map[] = { { FreeRDP_MonitorLocalShiftY, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_MonitorLocalShiftY" }, { FreeRDP_XPan, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_XPan" }, { FreeRDP_YPan, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_YPan" }, + { FreeRDP_MonitorOverrideFlags, FREERDP_SETTINGS_TYPE_UINT64, "FreeRDP_MonitorOverrideFlags" }, { FreeRDP_ParentWindowId, FREERDP_SETTINGS_TYPE_UINT64, "FreeRDP_ParentWindowId" }, { FreeRDP_AadServerHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AadServerHostname" }, { FreeRDP_AcceptedCert, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_AcceptedCert" }, diff --git a/libfreerdp/core/test/settings_property_lists.h b/libfreerdp/core/test/settings_property_lists.h index 244da35ed..fd1762e8a 100644 --- a/libfreerdp/core/test/settings_property_lists.h +++ b/libfreerdp/core/test/settings_property_lists.h @@ -354,6 +354,7 @@ static const size_t int32_list_indices[] = { #define have_uint64_list_indices static const size_t uint64_list_indices[] = { + FreeRDP_MonitorOverrideFlags, FreeRDP_ParentWindowId, };