[core,settings] Fix MONITOR_DEF settings

* Make FreeRDP_MonitorLocalShiftX and FreeRDP_MonitorLocalShiftY signed
* Add function freerdp_settings_set_monitor_def_array_sorted to proplery
  align the MONITOR_DEF array according to RDP requirements
This commit is contained in:
akallabeth
2025-01-18 10:08:08 +01:00
parent 1c7b291dc2
commit 567887fbb0
7 changed files with 174 additions and 50 deletions

View File

@@ -2257,3 +2257,114 @@ BOOL freerdp_settings_are_valid(const rdpSettings* settings)
{
return settings != NULL;
}
/* Function to sort rdpMonitor arrays:
* 1. first element is primary monitor
* 2. all others are sorted by coordinates of x/y
*/
static int sort_monitor_fn(const void* pva, const void* pvb)
{
const rdpMonitor* a = pva;
const rdpMonitor* b = pvb;
WINPR_ASSERT(a);
WINPR_ASSERT(b);
if (a->is_primary && b->is_primary)
return 0;
if (a->is_primary)
return -1;
if (b->is_primary)
return 1;
if (a->x != b->x)
return a->x - b->x;
if (a->y != b->y)
return a->y - b->y;
return 0;
}
BOOL freerdp_settings_set_monitor_def_array_sorted(rdpSettings* settings,
const rdpMonitor* monitors, size_t count)
{
WINPR_ASSERT(monitors || (count == 0));
if (count == 0)
{
if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftX, 0))
return FALSE;
if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftY, 0))
return FALSE;
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorDefArray, NULL, 0))
return FALSE;
return freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount, 0);
return TRUE;
}
// Find primary or alternatively the monitor at 0/0
const rdpMonitor* primary = NULL;
for (size_t x = 0; x < count; x++)
{
const rdpMonitor* cur = &monitors[x];
if (cur->is_primary)
{
primary = cur;
break;
}
}
if (!primary)
{
for (size_t x = 0; x < count; x++)
{
const rdpMonitor* cur = &monitors[x];
if ((cur->x == 0) && (cur->y == 0))
{
primary = cur;
break;
}
}
}
if (!primary)
{
WLog_ERR(TAG, "Could not find primary monitor, aborting");
return FALSE;
}
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorDefArray, NULL, count))
return FALSE;
rdpMonitor* sorted = freerdp_settings_get_pointer_writable(settings, FreeRDP_MonitorDefArray);
WINPR_ASSERT(sorted);
size_t sortpos = 0;
/* Set primary. Ensure left/top is at 0/0 and flags contains MONITOR_PRIMARY */
sorted[sortpos] = *primary;
sorted[sortpos].x = 0;
sorted[sortpos].y = 0;
sorted[sortpos].is_primary = TRUE;
sortpos++;
/* Set monitor shift to original layout */
const INT32 offsetX = primary->x;
const INT32 offsetY = primary->y;
if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftX, offsetX))
return FALSE;
if (!freerdp_settings_set_int32(settings, FreeRDP_MonitorLocalShiftY, offsetY))
return FALSE;
for (size_t x = 0; x < count; x++)
{
const rdpMonitor* cur = &monitors[x];
if (cur == primary)
continue;
rdpMonitor m = monitors[x];
m.x -= offsetX;
m.y -= offsetY;
sorted[sortpos++] = m;
}
// Sort remaining monitors by x/y ?
qsort(sorted, count, sizeof(rdpMonitor), sort_monitor_fn);
return freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount,
WINPR_ASSERTING_INT_CAST(uint32_t, count));
}

View File

@@ -1812,12 +1812,6 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, FreeRDP_Settings
case FreeRDP_MonitorFlags:
return settings->MonitorFlags;
case FreeRDP_MonitorLocalShiftX:
return settings->MonitorLocalShiftX;
case FreeRDP_MonitorLocalShiftY:
return settings->MonitorLocalShiftY;
case FreeRDP_MultifragMaxRequestSize:
return settings->MultifragMaxRequestSize;
@@ -2277,14 +2271,6 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, FreeRDP_Settings_Keys_UI
settings->MonitorFlags = cnv.c;
break;
case FreeRDP_MonitorLocalShiftX:
settings->MonitorLocalShiftX = cnv.c;
break;
case FreeRDP_MonitorLocalShiftY:
settings->MonitorLocalShiftY = cnv.c;
break;
case FreeRDP_MultifragMaxRequestSize:
settings->MultifragMaxRequestSize = cnv.c;
break;
@@ -2544,6 +2530,12 @@ INT32 freerdp_settings_get_int32(const rdpSettings* settings, FreeRDP_Settings_K
switch (id)
{
case FreeRDP_MonitorLocalShiftX:
return settings->MonitorLocalShiftX;
case FreeRDP_MonitorLocalShiftY:
return settings->MonitorLocalShiftY;
case FreeRDP_XPan:
return settings->XPan;
@@ -2574,6 +2566,14 @@ BOOL freerdp_settings_set_int32(rdpSettings* settings, FreeRDP_Settings_Keys_Int
switch (id)
{
case FreeRDP_MonitorLocalShiftX:
settings->MonitorLocalShiftX = cnv.c;
break;
case FreeRDP_MonitorLocalShiftY:
settings->MonitorLocalShiftY = cnv.c;
break;
case FreeRDP_XPan:
settings->XPan = cnv.c;
break;

View File

@@ -362,8 +362,6 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_MonitorCount, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorCount" },
{ FreeRDP_MonitorDefArraySize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorDefArraySize" },
{ FreeRDP_MonitorFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorFlags" },
{ FreeRDP_MonitorLocalShiftX, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorLocalShiftX" },
{ FreeRDP_MonitorLocalShiftY, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MonitorLocalShiftY" },
{ FreeRDP_MultifragMaxRequestSize, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_MultifragMaxRequestSize" },
{ FreeRDP_MultitransportFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_MultitransportFlags" },
@@ -448,6 +446,8 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_TlsSecLevel, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_TlsSecLevel" },
{ FreeRDP_VCChunkSize, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_VCChunkSize" },
{ FreeRDP_VCFlags, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_VCFlags" },
{ FreeRDP_MonitorLocalShiftX, FREERDP_SETTINGS_TYPE_INT32, "FreeRDP_MonitorLocalShiftX" },
{ 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_ParentWindowId, FREERDP_SETTINGS_TYPE_UINT64, "FreeRDP_ParentWindowId" },