[client,sdl] add support for /monitors argument

This commit is contained in:
akallabeth 2024-08-23 13:08:55 +02:00
parent fc6ba9f8f9
commit 49dc431045
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
6 changed files with 149 additions and 21 deletions

View File

@ -705,6 +705,9 @@ static BOOL sdl_create_windows(SdlContext* sdl)
for (UINT32 x = 0; x < windowCount; x++)
{
auto id = sdl_monitor_id_for_index(sdl, x);
if (id < 0)
return FALSE;
auto monitor = static_cast<rdpMonitor*>(
freerdp_settings_get_pointer_array_writable(settings, FreeRDP_MonitorDefArray, x));
@ -718,8 +721,8 @@ static BOOL sdl_create_windows(SdlContext* sdl)
}
Uint32 flags = SDL_WINDOW_SHOWN;
Uint32 startupX = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
Uint32 startupY = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
Uint32 startupX = SDL_WINDOWPOS_CENTERED_DISPLAY(id);
Uint32 startupY = SDL_WINDOWPOS_CENTERED_DISPLAY(id);
if (monitor->attributes.desktopScaleFactor > 100)
{

View File

@ -24,6 +24,7 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <SDL.h>
@ -324,13 +325,56 @@ BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
WINPR_ASSERT(settings);
const int numDisplays = SDL_GetNumVideoDisplays();
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, nullptr, numDisplays))
return FALSE;
for (size_t x = 0; x < numDisplays; x++)
auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
if (nr == 0)
{
if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorIds, x, &x))
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, nullptr, numDisplays))
return FALSE;
for (size_t x = 0; x < numDisplays; x++)
{
if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorIds, x, &x))
return FALSE;
}
}
else
{
/* There were more IDs supplied than there are monitors */
if (nr > numDisplays)
{
WLog_ERR(TAG,
"Found %" PRIu32 " monitor IDs, but only have %" PRIu32 " monitors connected",
nr, numDisplays);
return FALSE;
}
std::vector<UINT32> used;
for (size_t x = 0; x < nr; x++)
{
auto cur = static_cast<const UINT32*>(
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, x));
WINPR_ASSERT(cur);
auto id = *cur;
/* the ID is no valid monitor index */
if (id >= nr)
{
WLog_ERR(TAG,
"Supplied monitor ID[%" PRIuz "]=%" PRIu32 " is invalid, only [0-%" PRIu32
"] are allowed",
x, id, nr - 1);
return FALSE;
}
/* The ID is already taken */
if (std::find(used.begin(), used.end(), id) != used.end())
{
WLog_ERR(TAG, "Duplicate monitor ID[%" PRIuz "]=%" PRIu32 " detected", x, id);
return FALSE;
}
used.push_back(*cur);
}
}
if (!sdl_apply_display_properties(sdl))
@ -338,3 +382,21 @@ BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
return sdl_detect_single_window(sdl, pMaxWidth, pMaxHeight);
}
INT64 sdl_monitor_id_for_index(SdlContext* sdl, UINT32 index)
{
WINPR_ASSERT(sdl);
auto settings = sdl->context()->settings;
auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
if (nr == 0)
return index;
if (nr <= index)
return -1;
auto cur = static_cast<const UINT32*>(
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, index));
WINPR_ASSERT(cur);
return *cur;
}

View File

@ -26,3 +26,4 @@
int sdl_list_monitors(SdlContext* sdl);
BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pWidth, UINT32* pHeight);
INT64 sdl_monitor_id_for_index(SdlContext* sdl, UINT32 index);

View File

@ -703,6 +703,10 @@ static BOOL sdl_create_windows(SdlContext* sdl)
for (UINT32 x = 0; x < windowCount; x++)
{
auto id = sdl_monitor_id_for_index(sdl, x);
if (id < 0)
return FALSE;
auto monitor = static_cast<rdpMonitor*>(
freerdp_settings_get_pointer_array_writable(settings, FreeRDP_MonitorDefArray, x));
@ -716,8 +720,8 @@ static BOOL sdl_create_windows(SdlContext* sdl)
}
Uint32 flags = 0;
Uint32 startupX = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
Uint32 startupY = SDL_WINDOWPOS_CENTERED_DISPLAY(x);
Uint32 startupX = SDL_WINDOWPOS_CENTERED_DISPLAY(id);
Uint32 startupY = SDL_WINDOWPOS_CENTERED_DISPLAY(id);
if (monitor->attributes.desktopScaleFactor > 100)
{

View File

@ -24,6 +24,7 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <SDL3/SDL.h>
@ -318,28 +319,84 @@ BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
rdpSettings* settings = sdl->context()->settings;
WINPR_ASSERT(settings);
int numDisplays = 0;
auto ids = SDL_GetDisplays(&numDisplays);
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, nullptr, numDisplays))
std::vector<SDL_DisplayID> ids;
{
SDL_free(ids);
return FALSE;
int numDisplays = 0;
auto sids = SDL_GetDisplays(&numDisplays);
ids = std::vector<SDL_DisplayID>(sids, sids + numDisplays);
SDL_free(sids);
}
for (size_t x = 0; x < numDisplays; x++)
auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
if (nr == 0)
{
auto id = ids[x];
if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorIds, x, &id))
{
SDL_free(ids);
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, nullptr, ids.size()))
return FALSE;
for (size_t x = 0; x < ids.size(); x++)
{
auto id = ids[x];
if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorIds, x, &id))
return FALSE;
}
}
else
{
/* There were more IDs supplied than there are monitors */
if (nr > ids.size())
{
WLog_ERR(TAG,
"Found %" PRIu32 " monitor IDs, but only have %" PRIuz " monitors connected",
nr, ids.size());
return FALSE;
}
std::vector<UINT32> used;
for (size_t x = 0; x < nr; x++)
{
auto cur = static_cast<const UINT32*>(
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, x));
WINPR_ASSERT(cur);
auto id = *cur;
/* the ID is no valid monitor index */
if (std::find(ids.begin(), ids.end(), id) == ids.end())
{
WLog_ERR(TAG, "Supplied monitor ID[%" PRIuz "]=%" PRIu32 " is invalid", x, id);
return FALSE;
}
/* The ID is already taken */
if (std::find(used.begin(), used.end(), id) != used.end())
{
WLog_ERR(TAG, "Duplicate monitor ID[%" PRIuz "]=%" PRIu32 " detected", x, id);
return FALSE;
}
used.push_back(*cur);
}
}
SDL_free(ids);
if (!sdl_apply_display_properties(sdl))
return FALSE;
return sdl_detect_single_window(sdl, pMaxWidth, pMaxHeight);
}
INT64 sdl_monitor_id_for_index(SdlContext* sdl, UINT32 index)
{
WINPR_ASSERT(sdl);
auto settings = sdl->context()->settings;
auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
if (nr == 0)
return index;
if (nr <= index)
return -1;
auto cur = static_cast<const UINT32*>(
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, index));
WINPR_ASSERT(cur);
return *cur;
}

View File

@ -26,3 +26,4 @@
int sdl_list_monitors(SdlContext* sdl);
BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pWidth, UINT32* pHeight);
INT64 sdl_monitor_id_for_index(SdlContext* sdl, UINT32 index);