2022-12-30 13:25:28 +03:00
|
|
|
/**
|
|
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
|
|
* X11 Monitor Handling
|
|
|
|
*
|
|
|
|
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
|
|
* Copyright 2017 David Fort <contact@hardening-consulting.com>
|
|
|
|
* Copyright 2018 Kai Harms <kharms@rangee.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <freerdp/config.h>
|
|
|
|
|
2024-02-13 11:52:47 +03:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2024-08-23 14:08:55 +03:00
|
|
|
#include <algorithm>
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2024-05-07 11:16:02 +03:00
|
|
|
#include <SDL3/SDL.h>
|
2022-12-30 13:25:28 +03:00
|
|
|
|
|
|
|
#include <winpr/assert.h>
|
|
|
|
#include <winpr/crt.h>
|
|
|
|
|
|
|
|
#include <freerdp/log.h>
|
|
|
|
|
|
|
|
#define TAG CLIENT_TAG("sdl")
|
|
|
|
|
2023-04-14 09:36:05 +03:00
|
|
|
#include "sdl_monitor.hpp"
|
2023-04-14 10:16:50 +03:00
|
|
|
#include "sdl_freerdp.hpp"
|
2022-12-30 13:25:28 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
RECTANGLE_16 area;
|
|
|
|
RECTANGLE_16 workarea;
|
|
|
|
BOOL primary;
|
|
|
|
} MONITOR_INFO;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int nmonitors;
|
|
|
|
RECTANGLE_16 area;
|
|
|
|
RECTANGLE_16 workarea;
|
|
|
|
MONITOR_INFO* monitors;
|
|
|
|
} VIRTUAL_SCREEN;
|
|
|
|
|
|
|
|
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071
|
|
|
|
*/
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
int sdl_list_monitors(SdlContext* sdl)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
SDL_Init(SDL_INIT_VIDEO);
|
2024-05-07 11:16:02 +03:00
|
|
|
|
|
|
|
int nmonitors = 0;
|
|
|
|
auto ids = SDL_GetDisplays(&nmonitors);
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2023-01-25 14:43:22 +03:00
|
|
|
printf("listing %d monitors:\n", nmonitors);
|
2022-12-30 13:25:28 +03:00
|
|
|
for (int i = 0; i < nmonitors; i++)
|
|
|
|
{
|
2023-04-14 10:16:50 +03:00
|
|
|
SDL_Rect rect = {};
|
2024-05-07 11:16:02 +03:00
|
|
|
auto id = ids[i];
|
|
|
|
const int brc = SDL_GetDisplayBounds(id, &rect);
|
|
|
|
const char* name = SDL_GetDisplayName(id);
|
2022-12-30 13:25:28 +03:00
|
|
|
|
|
|
|
if (brc != 0)
|
|
|
|
continue;
|
2024-05-07 11:16:02 +03:00
|
|
|
printf(" %s [%d] [%s] %dx%d\t+%d+%d\n", (i == 0) ? "*" : " ", id, name, rect.w, rect.h,
|
2022-12-30 13:25:28 +03:00
|
|
|
rect.x, rect.y);
|
|
|
|
}
|
2024-05-07 11:16:02 +03:00
|
|
|
SDL_free(ids);
|
2022-12-30 13:25:28 +03:00
|
|
|
SDL_Quit();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
static BOOL sdl_is_monitor_id_active(SdlContext* sdl, UINT32 id)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-01-23 18:49:54 +03:00
|
|
|
const rdpSettings* settings = nullptr;
|
2022-12-30 13:25:28 +03:00
|
|
|
|
|
|
|
WINPR_ASSERT(sdl);
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
settings = sdl->context()->settings;
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(settings);
|
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
const UINT32 NumMonitorIds = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
|
|
|
|
if (!NumMonitorIds)
|
2022-12-30 13:25:28 +03:00
|
|
|
return TRUE;
|
|
|
|
|
2024-01-30 12:25:38 +03:00
|
|
|
for (UINT32 index = 0; index < NumMonitorIds; index++)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2023-10-13 10:48:44 +03:00
|
|
|
auto cur = static_cast<const UINT32*>(
|
|
|
|
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, index));
|
|
|
|
if (cur && (*cur == id))
|
2022-12-30 13:25:28 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
static BOOL sdl_apply_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
WINPR_ASSERT(sdl);
|
|
|
|
WINPR_ASSERT(pMaxWidth);
|
|
|
|
WINPR_ASSERT(pMaxHeight);
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
auto settings = sdl->context()->settings;
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(settings);
|
|
|
|
|
|
|
|
*pMaxWidth = 0;
|
|
|
|
*pMaxHeight = 0;
|
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
for (size_t x = 0; x < freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount); x++)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2023-10-13 10:48:44 +03:00
|
|
|
auto monitor = static_cast<const rdpMonitor*>(
|
|
|
|
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x));
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
if (freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
*pMaxWidth = monitor->width;
|
|
|
|
*pMaxHeight = monitor->height;
|
|
|
|
}
|
2023-10-13 10:48:44 +03:00
|
|
|
else if (freerdp_settings_get_bool(settings, FreeRDP_Workarea))
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2023-05-23 09:59:14 +03:00
|
|
|
SDL_Rect rect = {};
|
2022-12-30 13:25:28 +03:00
|
|
|
SDL_GetDisplayUsableBounds(monitor->orig_screen, &rect);
|
|
|
|
*pMaxWidth = rect.w;
|
|
|
|
*pMaxHeight = rect.h;
|
|
|
|
}
|
2023-10-13 10:48:44 +03:00
|
|
|
else if (freerdp_settings_get_uint32(settings, FreeRDP_PercentScreen) > 0)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2023-05-23 09:59:14 +03:00
|
|
|
SDL_Rect rect = {};
|
2022-12-30 13:25:28 +03:00
|
|
|
SDL_GetDisplayUsableBounds(monitor->orig_screen, &rect);
|
|
|
|
|
|
|
|
*pMaxWidth = rect.w;
|
|
|
|
*pMaxHeight = rect.h;
|
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
if (freerdp_settings_get_bool(settings, FreeRDP_PercentScreenUseWidth))
|
|
|
|
*pMaxWidth =
|
|
|
|
(rect.w * freerdp_settings_get_uint32(settings, FreeRDP_PercentScreen)) / 100;
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
if (freerdp_settings_get_bool(settings, FreeRDP_PercentScreenUseHeight))
|
|
|
|
*pMaxHeight =
|
|
|
|
(rect.h * freerdp_settings_get_uint32(settings, FreeRDP_PercentScreen)) / 100;
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
2023-10-13 10:48:44 +03:00
|
|
|
else if (freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth) &&
|
|
|
|
freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight))
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2023-10-13 10:48:44 +03:00
|
|
|
*pMaxWidth = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
|
|
|
|
*pMaxHeight = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UINT32 sdl_orientaion_to_rdp(SDL_DisplayOrientation orientation)
|
|
|
|
{
|
|
|
|
switch (orientation)
|
|
|
|
{
|
|
|
|
case SDL_ORIENTATION_LANDSCAPE:
|
|
|
|
return ORIENTATION_LANDSCAPE;
|
|
|
|
case SDL_ORIENTATION_LANDSCAPE_FLIPPED:
|
2024-02-21 00:19:00 +03:00
|
|
|
return ORIENTATION_LANDSCAPE_FLIPPED;
|
2022-12-30 13:25:28 +03:00
|
|
|
case SDL_ORIENTATION_PORTRAIT_FLIPPED:
|
|
|
|
return ORIENTATION_PORTRAIT_FLIPPED;
|
|
|
|
case SDL_ORIENTATION_PORTRAIT:
|
|
|
|
default:
|
|
|
|
return ORIENTATION_PORTRAIT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-11 23:57:21 +03:00
|
|
|
static Uint32 scale(Uint32 val, float scale)
|
|
|
|
{
|
2024-09-12 11:11:05 +03:00
|
|
|
const auto dval = static_cast<float>(val);
|
|
|
|
const auto sval = dval / scale;
|
2024-09-11 23:57:21 +03:00
|
|
|
return static_cast<Uint32>(sval);
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
static BOOL sdl_apply_display_properties(SdlContext* sdl)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
WINPR_ASSERT(sdl);
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
rdpSettings* settings = sdl->context()->settings;
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(settings);
|
|
|
|
|
|
|
|
const UINT32 numIds = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
|
2023-03-06 18:04:05 +03:00
|
|
|
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorDefArray, nullptr, numIds))
|
2022-12-30 13:25:28 +03:00
|
|
|
return FALSE;
|
|
|
|
if (!freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount, numIds))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (UINT32 x = 0; x < numIds; x++)
|
|
|
|
{
|
2024-04-15 13:14:24 +03:00
|
|
|
auto id = static_cast<const int*>(
|
2023-03-06 18:04:05 +03:00
|
|
|
freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorIds, x));
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(id);
|
|
|
|
|
2024-05-07 11:16:02 +03:00
|
|
|
float dpi = SDL_GetDisplayContentScale(*id);
|
|
|
|
float hdpi = dpi;
|
|
|
|
float vdpi = dpi;
|
2023-05-23 09:59:14 +03:00
|
|
|
SDL_Rect rect = {};
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2024-04-15 13:06:34 +03:00
|
|
|
if (SDL_GetDisplayBounds(*id, &rect) < 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
WINPR_ASSERT(rect.w > 0);
|
|
|
|
WINPR_ASSERT(rect.h > 0);
|
2023-06-17 21:06:14 +03:00
|
|
|
|
2024-05-07 11:16:02 +03:00
|
|
|
bool highDpi = dpi > 100;
|
2023-06-17 21:06:14 +03:00
|
|
|
|
2023-06-18 12:03:53 +03:00
|
|
|
if (highDpi)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
// HighDPI is problematic with SDL: We can only get native resolution by creating a
|
|
|
|
// window. Work around this by checking the supported resolutions (and keep maximum)
|
|
|
|
// Also scale the DPI
|
|
|
|
const SDL_Rect scaleRect = rect;
|
2024-05-07 11:16:02 +03:00
|
|
|
int count = 0;
|
|
|
|
auto modes = SDL_GetFullscreenDisplayModes(x, &count);
|
|
|
|
for (int i = 0; i < count; i++)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-05-07 11:16:02 +03:00
|
|
|
auto mode = modes[i];
|
|
|
|
if (!mode)
|
|
|
|
break;
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2024-05-07 11:16:02 +03:00
|
|
|
if (mode->w > rect.w)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-05-07 11:16:02 +03:00
|
|
|
rect.w = mode->w;
|
|
|
|
rect.h = mode->h;
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
2024-05-07 11:16:02 +03:00
|
|
|
else if (mode->w == rect.w)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-05-07 11:16:02 +03:00
|
|
|
if (mode->h > rect.h)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-05-07 11:16:02 +03:00
|
|
|
rect.w = mode->w;
|
|
|
|
rect.h = mode->h;
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-07 11:16:02 +03:00
|
|
|
SDL_free(modes);
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2024-09-12 11:46:17 +03:00
|
|
|
const float dw = 1.0f * static_cast<float>(rect.w) / static_cast<float>(scaleRect.w);
|
|
|
|
const float dh = 1.0f * static_cast<float>(rect.h) / static_cast<float>(scaleRect.h);
|
2022-12-30 13:25:28 +03:00
|
|
|
hdpi /= dw;
|
|
|
|
vdpi /= dh;
|
|
|
|
}
|
|
|
|
|
2024-05-07 11:16:02 +03:00
|
|
|
const SDL_DisplayOrientation orientation = SDL_GetCurrentDisplayOrientation(*id);
|
2022-12-30 13:25:28 +03:00
|
|
|
const UINT32 rdp_orientation = sdl_orientaion_to_rdp(orientation);
|
|
|
|
|
2023-03-06 18:04:05 +03:00
|
|
|
auto monitor = static_cast<rdpMonitor*>(
|
|
|
|
freerdp_settings_get_pointer_array_writable(settings, FreeRDP_MonitorDefArray, x));
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(monitor);
|
2023-03-06 18:04:05 +03:00
|
|
|
|
2023-07-24 11:42:45 +03:00
|
|
|
/* windows uses 96 dpi as 'default' and the scale factors are in percent. */
|
2024-05-07 11:16:02 +03:00
|
|
|
const auto factor = dpi / 96.0f * 100.0f;
|
2022-12-30 13:25:28 +03:00
|
|
|
monitor->orig_screen = x;
|
|
|
|
monitor->x = rect.x;
|
|
|
|
monitor->y = rect.y;
|
|
|
|
monitor->width = rect.w;
|
|
|
|
monitor->height = rect.h;
|
2023-10-13 03:03:54 +03:00
|
|
|
monitor->is_primary = x == 0;
|
2024-09-11 23:57:21 +03:00
|
|
|
monitor->attributes.desktopScaleFactor = static_cast<UINT32>(factor);
|
2022-12-30 13:25:28 +03:00
|
|
|
monitor->attributes.deviceScaleFactor = 100;
|
|
|
|
monitor->attributes.orientation = rdp_orientation;
|
2024-09-11 23:57:21 +03:00
|
|
|
monitor->attributes.physicalWidth = scale(rect.w, hdpi);
|
|
|
|
monitor->attributes.physicalHeight = scale(rect.h, vdpi);
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
static BOOL sdl_detect_single_window(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
WINPR_ASSERT(sdl);
|
|
|
|
WINPR_ASSERT(pMaxWidth);
|
|
|
|
WINPR_ASSERT(pMaxHeight);
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
rdpSettings* settings = sdl->context()->settings;
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(settings);
|
|
|
|
|
2023-10-13 10:48:44 +03:00
|
|
|
if ((!freerdp_settings_get_bool(settings, FreeRDP_UseMultimon) &&
|
|
|
|
!freerdp_settings_get_bool(settings, FreeRDP_SpanMonitors)) ||
|
|
|
|
(freerdp_settings_get_bool(settings, FreeRDP_Workarea) &&
|
|
|
|
!freerdp_settings_get_bool(settings, FreeRDP_RemoteApplicationMode)))
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
/* If no monitors were specified on the command-line then set the current monitor as active
|
|
|
|
*/
|
2023-10-13 10:48:44 +03:00
|
|
|
if (freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds) == 0)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
const size_t id =
|
2024-08-29 17:00:42 +03:00
|
|
|
(!sdl->windows.empty()) ? sdl->windows.begin()->second.displayIndex() : 0;
|
2022-12-30 13:25:28 +03:00
|
|
|
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, &id, 1))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Always sets number of monitors from command-line to just 1.
|
|
|
|
* If the monitor is invalid then we will default back to current monitor
|
|
|
|
* later as a fallback. So, there is no need to validate command-line entry here.
|
|
|
|
*/
|
2023-10-13 10:48:44 +03:00
|
|
|
if (!freerdp_settings_set_uint32(settings, FreeRDP_NumMonitorIds, 1))
|
|
|
|
return FALSE;
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Fill monitor struct
|
|
|
|
if (!sdl_apply_display_properties(sdl))
|
|
|
|
return FALSE;
|
|
|
|
return sdl_apply_max_size(sdl, pMaxWidth, pMaxHeight);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
BOOL sdl_detect_monitors(SdlContext* sdl, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
|
|
|
WINPR_ASSERT(sdl);
|
|
|
|
WINPR_ASSERT(pMaxWidth);
|
|
|
|
WINPR_ASSERT(pMaxHeight);
|
|
|
|
|
2023-05-31 12:44:27 +03:00
|
|
|
rdpSettings* settings = sdl->context()->settings;
|
2022-12-30 13:25:28 +03:00
|
|
|
WINPR_ASSERT(settings);
|
|
|
|
|
2024-08-23 14:08:55 +03:00
|
|
|
std::vector<SDL_DisplayID> ids;
|
2024-05-07 11:16:02 +03:00
|
|
|
{
|
2024-08-23 14:08:55 +03:00
|
|
|
int numDisplays = 0;
|
|
|
|
auto sids = SDL_GetDisplays(&numDisplays);
|
2024-09-03 15:38:45 +03:00
|
|
|
if (sids && (numDisplays > 0))
|
|
|
|
ids = std::vector<SDL_DisplayID>(sids, sids + numDisplays);
|
2024-08-23 14:08:55 +03:00
|
|
|
SDL_free(sids);
|
2024-09-03 15:38:45 +03:00
|
|
|
if (numDisplays < 0)
|
|
|
|
return FALSE;
|
2024-05-07 11:16:02 +03:00
|
|
|
}
|
2022-12-30 13:25:28 +03:00
|
|
|
|
2024-08-23 14:08:55 +03:00
|
|
|
auto nr = freerdp_settings_get_uint32(settings, FreeRDP_NumMonitorIds);
|
|
|
|
if (nr == 0)
|
2022-12-30 13:25:28 +03:00
|
|
|
{
|
2024-08-23 14:08:55 +03:00
|
|
|
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_MonitorIds, nullptr, ids.size()))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (size_t x = 0; x < ids.size(); x++)
|
2024-05-07 11:16:02 +03:00
|
|
|
{
|
2024-08-23 14:08:55 +03:00
|
|
|
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());
|
2022-12-30 13:25:28 +03:00
|
|
|
return FALSE;
|
2024-05-07 11:16:02 +03:00
|
|
|
}
|
2024-08-23 14:08:55 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2022-12-30 13:25:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!sdl_apply_display_properties(sdl))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return sdl_detect_single_window(sdl, pMaxWidth, pMaxHeight);
|
|
|
|
}
|
2024-08-23 14:08:55 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|