mirror of https://github.com/neutrinolabs/xrdp
Merge pull request #1895 from Nexarian/unify_monitor_description_processing_resize_sec
Unify monitor processing logic.
This commit is contained in:
commit
46e23ebcab
|
@ -83,10 +83,24 @@
|
|||
#define RDPSND_SVC_CHANNEL_NAME "rdpsnd"
|
||||
#define RDPDR_SVC_CHANNEL_NAME "rdpdr"
|
||||
|
||||
/* 2.2.1.3.6 Client Monitor Data - */
|
||||
/* 2.2.1.3.6 Client Monitor Data */
|
||||
/* monitorCount (4 bytes): A 32-bit, unsigned integer. The number of display */
|
||||
/* monitor definitions in the monitorDefArray field (the maximum allowed is 16). */
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_MONITORS 16
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_MONITORS 16
|
||||
|
||||
/* 2.2.1.3.6 Client Monitor Data */
|
||||
/* The maximum width of the virtual desktop resulting from the union of the monitors */
|
||||
/* contained in the monitorDefArray field MUST NOT exceed 32,766 pixels. Similarly, */
|
||||
/* the maximum height of the virtual desktop resulting from the union of the monitors */
|
||||
/* contained in the monitorDefArray field MUST NOT exceed 32,766 pixels. */
|
||||
/* The minimum permitted size of the virtual desktop is 200 x 200 pixels. */
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_WIDTH 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_HEIGHT 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH 0x7FFE
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT 0x7FFE
|
||||
|
||||
/* 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF) */
|
||||
#define TS_MONITOR_PRIMARY 0x00000001
|
||||
|
||||
/* Options field */
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
|
|
|
@ -23,7 +23,19 @@
|
|||
#define MS_RDPEDISP_H
|
||||
|
||||
/* Display Control Messages: Display Virtual Channel Extension (2.2.2) */
|
||||
#define DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAYCONTROL_PDU_TYPE_CAPS 0x00000005
|
||||
#define DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAYCONTROL_PDU_TYPE_CAPS 0x00000005
|
||||
|
||||
/* Display Control Monitor Layout (2.2.2.2.1) */
|
||||
#define DISPLAYCONTROL_MONITOR_PRIMARY 0x00000001
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_WIDTH 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_HEIGHT 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_WIDTH 0x2000
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_HEIGHT 0x2000
|
||||
|
||||
#define ORIENTATION_LANDSCAPE 0
|
||||
#define ORIENTATION_PORTRAIT 90
|
||||
#define ORIENTATION_LANDSCAPE_FLIPPED 180
|
||||
#define ORIENTATION_PORTRAIT_FLIPPED 270
|
||||
|
||||
#endif /* MS_RDPEDISP_H */
|
||||
|
|
|
@ -24,13 +24,29 @@
|
|||
#if !defined(XRDP_CLIENT_INFO_H)
|
||||
#define XRDP_CLIENT_INFO_H
|
||||
|
||||
/*
|
||||
* 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF)
|
||||
* 2.2.1.3.9.1 Monitor Attributes (TS_MONITOR_ATTRIBUTES)
|
||||
* 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT
|
||||
*/
|
||||
struct monitor_info
|
||||
{
|
||||
/* From 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF) */
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
int is_primary;
|
||||
int flags;
|
||||
|
||||
/* From 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT */
|
||||
unsigned int physical_width;
|
||||
unsigned int physical_height;
|
||||
unsigned int orientation;
|
||||
unsigned int desktop_scale_factor;
|
||||
unsigned int device_scale_factor;
|
||||
|
||||
/* Derived setting */
|
||||
unsigned int is_primary;
|
||||
};
|
||||
|
||||
/* xrdp keyboard overrids */
|
||||
|
@ -41,6 +57,15 @@ struct xrdp_keyboard_overrides
|
|||
int layout;
|
||||
};
|
||||
|
||||
struct display_size_description
|
||||
{
|
||||
unsigned int monitorCount; /* 2.2.2.2 DISPLAYCONTROL_MONITOR_LAYOUT_PDU: number of monitors detected (max = 16) */
|
||||
struct monitor_info minfo[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data */
|
||||
struct monitor_info minfo_wm[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data, non-negative values */
|
||||
unsigned int session_width;
|
||||
unsigned int session_height;
|
||||
};
|
||||
|
||||
/**
|
||||
* Information about the xrdp client
|
||||
*
|
||||
|
@ -54,8 +79,6 @@ struct xrdp_client_info
|
|||
int size; /* bytes for this structure */
|
||||
int version; /* Should be CLIENT_INFO_CURRENT_VERSION */
|
||||
int bpp;
|
||||
int width;
|
||||
int height;
|
||||
/* bitmap cache info */
|
||||
int cache1_entries;
|
||||
int cache1_size;
|
||||
|
@ -128,9 +151,7 @@ struct xrdp_client_info
|
|||
|
||||
int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */
|
||||
int multimon; /* 0 = deny , 1 = allow */
|
||||
int monitorCount; /* number of monitors detected (max = 16) */
|
||||
struct monitor_info minfo[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data */
|
||||
struct monitor_info minfo_wm[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data, non-negative values */
|
||||
struct display_size_description display_sizes;
|
||||
|
||||
int keyboard_type;
|
||||
int keyboard_subtype;
|
||||
|
@ -186,6 +207,6 @@ struct xrdp_client_info
|
|||
};
|
||||
|
||||
/* yyyymmdd of last incompatible change to xrdp_client_info */
|
||||
#define CLIENT_INFO_CURRENT_VERSION 20210723
|
||||
#define CLIENT_INFO_CURRENT_VERSION 20220320
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
#include "libxrdp.h"
|
||||
#include "string_calls.h"
|
||||
#include "xrdp_orders_rail.h"
|
||||
|
||||
#include "ms-rdpedisp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -1136,7 +1134,7 @@ libxrdp_orders_send_font(struct xrdp_session *session,
|
|||
* to a single monitor */
|
||||
int EXPORT_CC
|
||||
libxrdp_reset(struct xrdp_session *session,
|
||||
int width, int height, int bpp)
|
||||
unsigned int width, unsigned int height, int bpp)
|
||||
{
|
||||
if (session->client_info != 0)
|
||||
{
|
||||
|
@ -1149,18 +1147,18 @@ libxrdp_reset(struct xrdp_session *session,
|
|||
}
|
||||
|
||||
/* if same (and only one monitor on client) don't need to do anything */
|
||||
if (client_info->width == width &&
|
||||
client_info->height == height &&
|
||||
if (client_info->display_sizes.session_width == width &&
|
||||
client_info->display_sizes.session_height == height &&
|
||||
client_info->bpp == bpp &&
|
||||
(client_info->monitorCount == 0 || client_info->multimon == 0))
|
||||
(client_info->display_sizes.monitorCount == 0 || client_info->multimon == 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
client_info->width = width;
|
||||
client_info->height = height;
|
||||
client_info->display_sizes.session_width = width;
|
||||
client_info->display_sizes.session_height = height;
|
||||
client_info->display_sizes.monitorCount = 0;
|
||||
client_info->bpp = bpp;
|
||||
client_info->monitorCount = 0;
|
||||
client_info->multimon = 0;
|
||||
}
|
||||
else
|
||||
|
@ -1766,3 +1764,380 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data,
|
|||
return xrdp_rdp_send_session_info(rdp, data, data_bytes);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
|
||||
reads the client monitors data
|
||||
*/
|
||||
int
|
||||
libxrdp_process_monitor_stream(struct stream *s,
|
||||
struct display_size_description *description,
|
||||
int full_parameters)
|
||||
{
|
||||
uint32_t num_monitor;
|
||||
uint32_t monitor_index;
|
||||
struct monitor_info *monitor_layout;
|
||||
struct xrdp_rect all_monitors_encompassing_bounds = {0};
|
||||
int got_primary = 0;
|
||||
int monitor_struct_stream_check_bytes;
|
||||
const char *monitor_struct_stream_check_message;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_monitor_stream:");
|
||||
if (description == NULL)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "libxrdp_process_monitor_stream: description was"
|
||||
" null. Valid pointer to allocated description expected.");
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
|
||||
if (!s_check_rem_and_log(s, 4,
|
||||
"libxrdp_process_monitor_stream:"
|
||||
" Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR"))
|
||||
{
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
|
||||
in_uint32_le(s, num_monitor);
|
||||
LOG(LOG_LEVEL_DEBUG, "libxrdp_process_monitor_stream:"
|
||||
" The number of monitors received is: %d",
|
||||
num_monitor);
|
||||
|
||||
if (num_monitor >= CLIENT_MONITOR_DATA_MAXIMUM_MONITORS)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"libxrdp_process_monitor_stream: [MS-RDPBCGR] Protocol"
|
||||
" error: TS_UD_CS_MONITOR monitorCount"
|
||||
" MUST be less than %d, received: %d",
|
||||
CLIENT_MONITOR_DATA_MAXIMUM_MONITORS, num_monitor);
|
||||
return SEC_PROCESS_MONITORS_ERR_TOO_MANY_MONITORS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunately the structure length values aren't directly defined in the
|
||||
* Microsoft specifications. They are derived from the lengths of the
|
||||
* specific structures referenced below.
|
||||
*/
|
||||
if (full_parameters == 0)
|
||||
{
|
||||
monitor_struct_stream_check_bytes = 20;
|
||||
monitor_struct_stream_check_message =
|
||||
"libxrdp_process_monitor_stream: Parsing monitor definitions"
|
||||
" from [MS-RDPBCGR] 2.2.1.3.6.1 Monitor Definition"
|
||||
" (TS_MONITOR_DEF).";
|
||||
}
|
||||
else
|
||||
{
|
||||
monitor_struct_stream_check_bytes = 40;
|
||||
monitor_struct_stream_check_message =
|
||||
"libxrdp_process_monitor_stream: Parsing monitor definitions"
|
||||
" from [MS-RDPEDISP] 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT.";
|
||||
}
|
||||
|
||||
description->monitorCount = num_monitor;
|
||||
|
||||
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
|
||||
{
|
||||
if (!s_check_rem_and_log(
|
||||
s,
|
||||
monitor_struct_stream_check_bytes,
|
||||
monitor_struct_stream_check_message))
|
||||
{
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
|
||||
monitor_layout = description->minfo + monitor_index;
|
||||
if (full_parameters != 0)
|
||||
{
|
||||
in_uint32_le(s, monitor_layout->flags);
|
||||
}
|
||||
in_uint32_le(s, monitor_layout->left);
|
||||
in_uint32_le(s, monitor_layout->top);
|
||||
|
||||
if (full_parameters == 0)
|
||||
{
|
||||
in_uint32_le(s, monitor_layout->right);
|
||||
in_uint32_le(s, monitor_layout->bottom);
|
||||
in_uint32_le(s, monitor_layout->is_primary);
|
||||
|
||||
/*
|
||||
* 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF)
|
||||
*/
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_monitor_stream:"
|
||||
" Received [MS-RDPBCGR] 2.2.1.3.6.1"
|
||||
" TS_UD_CS_MONITOR.TS_MONITOR_DEF"
|
||||
" Index: %d, Left %d, Top %d, Right %d, Bottom %d,"
|
||||
" Flags 0x%8.8x",
|
||||
monitor_index,
|
||||
monitor_layout->left,
|
||||
monitor_layout->top,
|
||||
monitor_layout->right,
|
||||
monitor_layout->bottom,
|
||||
monitor_layout->is_primary);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT),
|
||||
* this is the width.
|
||||
* 200 <= width <= 8192 and must not be odd.
|
||||
* Ex: in_uint32_le(s, monitor_layout->width);
|
||||
*/
|
||||
in_uint32_le(s, monitor_layout->right);
|
||||
if (monitor_layout->right
|
||||
> CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_WIDTH
|
||||
|| monitor_layout->right
|
||||
< CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_WIDTH
|
||||
|| monitor_layout->right % 2 != 0)
|
||||
{
|
||||
return SEC_PROCESS_MONITORS_ERR_INVALID_MONITOR;
|
||||
}
|
||||
|
||||
/* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT),
|
||||
* this is the height.
|
||||
* 200 <= height <= 8192
|
||||
* Ex: in_uint32_le(s, monitor_layout->height);
|
||||
*/
|
||||
in_uint32_le(s, monitor_layout->bottom);
|
||||
if (monitor_layout->bottom
|
||||
> CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_HEIGHT
|
||||
|| monitor_layout->bottom
|
||||
< CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_HEIGHT)
|
||||
{
|
||||
return SEC_PROCESS_MONITORS_ERR_INVALID_MONITOR;
|
||||
}
|
||||
|
||||
in_uint32_le(s, monitor_layout->physical_width);
|
||||
in_uint32_le(s, monitor_layout->physical_height);
|
||||
|
||||
/* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT),
|
||||
* if EITHER physical_width or physical_height are
|
||||
* out of range, BOTH must be ignored.
|
||||
*/
|
||||
if (monitor_layout->physical_width > 10000
|
||||
|| monitor_layout->physical_width < 10)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
|
||||
" physical_width is not within valid range."
|
||||
" Setting physical_width to 0mm,"
|
||||
" Setting physical_height to 0mm,"
|
||||
" physical_width was: %d",
|
||||
monitor_layout->physical_width);
|
||||
monitor_layout->physical_width = 0;
|
||||
monitor_layout->physical_height = 0;
|
||||
}
|
||||
|
||||
if (monitor_layout->physical_height > 10000
|
||||
|| monitor_layout->physical_height < 10)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
|
||||
" physical_height is not within valid range."
|
||||
" Setting physical_width to 0mm,"
|
||||
" Setting physical_height to 0mm,"
|
||||
" physical_height was: %d",
|
||||
monitor_layout->physical_height);
|
||||
monitor_layout->physical_width = 0;
|
||||
monitor_layout->physical_height = 0;
|
||||
}
|
||||
|
||||
in_uint32_le(s, monitor_layout->orientation);
|
||||
switch (monitor_layout->orientation)
|
||||
{
|
||||
case ORIENTATION_LANDSCAPE:
|
||||
case ORIENTATION_PORTRAIT:
|
||||
case ORIENTATION_LANDSCAPE_FLIPPED:
|
||||
case ORIENTATION_PORTRAIT_FLIPPED:
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
|
||||
" Orientation is not one of %d, %d, %d, or %d."
|
||||
" Value was %d and ignored and set to default value of LANDSCAPE.",
|
||||
ORIENTATION_LANDSCAPE,
|
||||
ORIENTATION_PORTRAIT,
|
||||
ORIENTATION_LANDSCAPE_FLIPPED,
|
||||
ORIENTATION_PORTRAIT_FLIPPED,
|
||||
monitor_layout->orientation);
|
||||
monitor_layout->orientation = ORIENTATION_LANDSCAPE;
|
||||
}
|
||||
|
||||
in_uint32_le(s, monitor_layout->desktop_scale_factor);
|
||||
if (monitor_layout->desktop_scale_factor < 100
|
||||
|| monitor_layout->desktop_scale_factor > 500
|
||||
|| (monitor_layout->desktop_scale_factor != 100
|
||||
&& monitor_layout->desktop_scale_factor != 140
|
||||
&& monitor_layout->desktop_scale_factor != 180))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
|
||||
" desktop_scale_factor is not within valid range. Assuming 100."
|
||||
" Value was: %d",
|
||||
monitor_layout->desktop_scale_factor);
|
||||
monitor_layout->desktop_scale_factor = 100;
|
||||
}
|
||||
|
||||
in_uint32_le(s, monitor_layout->device_scale_factor);
|
||||
if (monitor_layout->device_scale_factor < 100
|
||||
|| monitor_layout->device_scale_factor > 500
|
||||
|| (monitor_layout->device_scale_factor != 100
|
||||
&& monitor_layout->device_scale_factor != 140
|
||||
&& monitor_layout->device_scale_factor != 180))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
|
||||
" device_scale_factor is not within valid range. Assuming 100."
|
||||
" Value was: %d",
|
||||
monitor_layout->device_scale_factor);
|
||||
monitor_layout->device_scale_factor = 100;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT
|
||||
*/
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "libxrdp_process_monitor_stream:"
|
||||
" Received [MS-RDPEDISP] 2.2.2.2.1"
|
||||
" DISPLAYCONTROL_MONITOR_LAYOUT_PDU"
|
||||
".DISPLAYCONTROL_MONITOR_LAYOUT"
|
||||
" Index: %d, Flags 0x%8.8x, Left %d, Top %d, Width %d,"
|
||||
" Height %d, PhysicalWidth %d, PhysicalHeight %d,"
|
||||
" Orientation %d, DesktopScaleFactor %d,"
|
||||
" DeviceScaleFactor %d",
|
||||
monitor_index,
|
||||
monitor_layout->flags,
|
||||
monitor_layout->left,
|
||||
monitor_layout->top,
|
||||
monitor_layout->right,
|
||||
monitor_layout->bottom,
|
||||
monitor_layout->physical_width,
|
||||
monitor_layout->physical_height,
|
||||
monitor_layout->orientation,
|
||||
monitor_layout->desktop_scale_factor,
|
||||
monitor_layout->device_scale_factor);
|
||||
|
||||
monitor_layout->right =
|
||||
monitor_layout->left + monitor_layout->right;
|
||||
monitor_layout->bottom =
|
||||
monitor_layout->top + monitor_layout->bottom;
|
||||
|
||||
if (monitor_layout->flags == DISPLAYCONTROL_MONITOR_PRIMARY)
|
||||
{
|
||||
monitor_layout->is_primary = TS_MONITOR_PRIMARY;
|
||||
}
|
||||
}
|
||||
|
||||
if (monitor_index == 0)
|
||||
{
|
||||
all_monitors_encompassing_bounds.left = monitor_layout->left;
|
||||
all_monitors_encompassing_bounds.top = monitor_layout->top;
|
||||
all_monitors_encompassing_bounds.right = monitor_layout->right;
|
||||
all_monitors_encompassing_bounds.bottom = monitor_layout->bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
all_monitors_encompassing_bounds.left =
|
||||
MIN(monitor_layout->left,
|
||||
all_monitors_encompassing_bounds.left);
|
||||
all_monitors_encompassing_bounds.top =
|
||||
MIN(monitor_layout->top,
|
||||
all_monitors_encompassing_bounds.top);
|
||||
all_monitors_encompassing_bounds.right =
|
||||
MAX(all_monitors_encompassing_bounds.right,
|
||||
monitor_layout->right);
|
||||
all_monitors_encompassing_bounds.bottom =
|
||||
MAX(all_monitors_encompassing_bounds.bottom,
|
||||
monitor_layout->bottom);
|
||||
}
|
||||
|
||||
if (monitor_layout->is_primary == TS_MONITOR_PRIMARY)
|
||||
{
|
||||
got_primary = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!got_primary)
|
||||
{
|
||||
/* no primary monitor was set,
|
||||
* choose the leftmost monitor as primary.
|
||||
*/
|
||||
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
|
||||
{
|
||||
monitor_layout = description->minfo + monitor_index;
|
||||
if (monitor_layout->left
|
||||
== all_monitors_encompassing_bounds.left
|
||||
&& monitor_layout->top
|
||||
== all_monitors_encompassing_bounds.top)
|
||||
{
|
||||
monitor_layout->is_primary = TS_MONITOR_PRIMARY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set wm geometry if the encompassing area is well formed. Otherwise, log and return an error.*/
|
||||
if (all_monitors_encompassing_bounds.right
|
||||
> all_monitors_encompassing_bounds.left
|
||||
&& all_monitors_encompassing_bounds.bottom
|
||||
> all_monitors_encompassing_bounds.top)
|
||||
{
|
||||
description->session_width =
|
||||
all_monitors_encompassing_bounds.right
|
||||
- all_monitors_encompassing_bounds.left + 1;
|
||||
description->session_height =
|
||||
all_monitors_encompassing_bounds.bottom
|
||||
- all_monitors_encompassing_bounds.top + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_monitor_stream:"
|
||||
" The area encompassing the monitors is not a"
|
||||
" well-formed rectangle. Received"
|
||||
" (top: %d, left: %d, right: %d, bottom: %d)."
|
||||
" This will prevent initialization.",
|
||||
all_monitors_encompassing_bounds.top,
|
||||
all_monitors_encompassing_bounds.left,
|
||||
all_monitors_encompassing_bounds.right,
|
||||
all_monitors_encompassing_bounds.bottom);
|
||||
return SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP;
|
||||
}
|
||||
|
||||
/* Make sure virtual desktop size is OK
|
||||
* 2.2.1.3.6 Client Monitor Data (TS_UD_CS_MONITOR)
|
||||
*/
|
||||
if (description->session_width
|
||||
> CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH
|
||||
|| description->session_width
|
||||
< CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_WIDTH
|
||||
|| description->session_height
|
||||
> CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT
|
||||
|| description->session_height
|
||||
< CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_HEIGHT)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"libxrdp_process_monitor_stream: Client supplied virtual"
|
||||
" desktop width or height is invalid."
|
||||
" Allowed width range: min %d, max %d. Width received: %d."
|
||||
" Allowed height range: min %d, max %d. Height received: %d",
|
||||
CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_WIDTH,
|
||||
CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH,
|
||||
description->session_width,
|
||||
CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_HEIGHT,
|
||||
CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT,
|
||||
description->session_width);
|
||||
return SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP;
|
||||
}
|
||||
|
||||
/* keep a copy of non negative monitor info values for xrdp_wm usage */
|
||||
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
|
||||
{
|
||||
monitor_layout = description->minfo_wm + monitor_index;
|
||||
|
||||
g_memcpy(monitor_layout,
|
||||
description->minfo + monitor_index,
|
||||
sizeof(struct monitor_info));
|
||||
|
||||
monitor_layout->left =
|
||||
monitor_layout->left - all_monitors_encompassing_bounds.left;
|
||||
monitor_layout->top =
|
||||
monitor_layout->top - all_monitors_encompassing_bounds.top;
|
||||
monitor_layout->right =
|
||||
monitor_layout->right - all_monitors_encompassing_bounds.left;
|
||||
monitor_layout->bottom =
|
||||
monitor_layout->bottom - all_monitors_encompassing_bounds.top;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -359,6 +359,18 @@ int
|
|||
xrdp_mcs_disconnect(struct xrdp_mcs *self);
|
||||
|
||||
/* xrdp_sec.c */
|
||||
|
||||
/*
|
||||
These are error return codes for both:
|
||||
1. xrdp_sec_process_mcs_data_monitors
|
||||
2. libxrdp_process_monitor_stream
|
||||
To clarify any reason for a non-zero response code.
|
||||
*/
|
||||
#define SEC_PROCESS_MONITORS_ERR 1
|
||||
#define SEC_PROCESS_MONITORS_ERR_TOO_MANY_MONITORS 2
|
||||
#define SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP 3
|
||||
#define SEC_PROCESS_MONITORS_ERR_INVALID_MONITOR 4
|
||||
|
||||
struct xrdp_sec *
|
||||
xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans);
|
||||
void
|
||||
|
@ -383,6 +395,8 @@ int
|
|||
xrdp_sec_incoming(struct xrdp_sec *self);
|
||||
int
|
||||
xrdp_sec_disconnect(struct xrdp_sec *self);
|
||||
int
|
||||
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s);
|
||||
|
||||
/* xrdp_rdp.c */
|
||||
struct xrdp_rdp *
|
||||
|
|
|
@ -86,6 +86,9 @@ struct xrdp_drdynvc_procs
|
|||
int (*data)(intptr_t id, int chan_id, char *data, int bytes);
|
||||
};
|
||||
|
||||
/* Defined in xrdp_client_info.h */
|
||||
struct display_size_description;
|
||||
|
||||
/***
|
||||
* Initialise the XRDP library
|
||||
*
|
||||
|
@ -190,7 +193,7 @@ libxrdp_orders_send_font(struct xrdp_session *session,
|
|||
int font_index, int char_index);
|
||||
int
|
||||
libxrdp_reset(struct xrdp_session *session,
|
||||
int width, int height, int bpp);
|
||||
unsigned int width, unsigned int height, int bpp);
|
||||
int
|
||||
libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session,
|
||||
int width, int height, int bpp, char *data,
|
||||
|
@ -304,4 +307,21 @@ int EXPORT_CC
|
|||
libxrdp_send_session_info(struct xrdp_session *session, const char *data,
|
||||
int data_bytes);
|
||||
|
||||
/**
|
||||
* Processes a stream that is based on either
|
||||
* 2.2.1.3.6 Client Monitor Data (TS_UD_CS_MONITOR) or 2.2.2.2 DISPLAYCONTROL_MONITOR_LAYOUT_PDU
|
||||
* and then stores the processed monitor data into the description parameter.
|
||||
* @param s
|
||||
* The stream to process.
|
||||
* @param description
|
||||
* Must be pre-allocated. Monitor data is filled in as part of processing the stream.
|
||||
* @param full_parameters
|
||||
* 0 if the monitor stream is from 2.2.1.3.6 Client Monitor Data (TS_UD_CS_MONITOR)
|
||||
* 1 if the monitor stream is from 2.2.2.2 DISPLAYCONTROL_MONITOR_LAYOUT_PDU
|
||||
* @return 0 if the data is processed, non-zero if there is an error.
|
||||
*/
|
||||
int EXPORT_CC
|
||||
libxrdp_process_monitor_stream(struct stream *s, struct display_size_description *description,
|
||||
int full_parameters);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,8 @@ static int
|
|||
xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
||||
{
|
||||
struct stream *s;
|
||||
int i;
|
||||
uint32_t i;
|
||||
struct display_size_description *description;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
@ -56,16 +57,18 @@ xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
|||
return 1;
|
||||
}
|
||||
|
||||
out_uint32_le(s, self->client_info.monitorCount); /* monitorCount (4 bytes) */
|
||||
description = &self->client_info.display_sizes;
|
||||
|
||||
out_uint32_le(s, description->monitorCount); /* monitorCount (4 bytes) */
|
||||
|
||||
/* TODO: validate for allowed monitors in terminal server (maybe by config?) */
|
||||
for (i = 0; i < self->client_info.monitorCount; i++)
|
||||
for (i = 0; i < description->monitorCount; i++)
|
||||
{
|
||||
out_uint32_le(s, self->client_info.minfo[i].left);
|
||||
out_uint32_le(s, self->client_info.minfo[i].top);
|
||||
out_uint32_le(s, self->client_info.minfo[i].right);
|
||||
out_uint32_le(s, self->client_info.minfo[i].bottom);
|
||||
out_uint32_le(s, self->client_info.minfo[i].is_primary);
|
||||
out_uint32_le(s, description->minfo[i].left);
|
||||
out_uint32_le(s, description->minfo[i].top);
|
||||
out_uint32_le(s, description->minfo[i].right);
|
||||
out_uint32_le(s, description->minfo[i].bottom);
|
||||
out_uint32_le(s, description->minfo[i].is_primary);
|
||||
}
|
||||
|
||||
s_mark_end(s);
|
||||
|
@ -883,8 +886,8 @@ unsigned int calculate_multifragmentupdate_len(const struct xrdp_rdp *self)
|
|||
{
|
||||
unsigned int result = MAX_MULTIFRAGMENTUPDATE_SIZE;
|
||||
|
||||
unsigned int x_tiles = (self->client_info.width + 63) / 64;
|
||||
unsigned int y_tiles = (self->client_info.height + 63) / 64;
|
||||
unsigned int x_tiles = (self->client_info.display_sizes.session_width + 63) / 64;
|
||||
unsigned int y_tiles = (self->client_info.display_sizes.session_height + 63) / 64;
|
||||
|
||||
/* Check for overflow on calculation if bad parameters are supplied */
|
||||
if ((x_tiles * y_tiles + 1) < (UINT_MAX / 16384))
|
||||
|
@ -979,8 +982,8 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
|||
out_uint16_le(s, 1); /* Receive 1 BPP */
|
||||
out_uint16_le(s, 1); /* Receive 4 BPP */
|
||||
out_uint16_le(s, 1); /* Receive 8 BPP */
|
||||
out_uint16_le(s, self->client_info.width); /* width */
|
||||
out_uint16_le(s, self->client_info.height); /* height */
|
||||
out_uint16_le(s, self->client_info.display_sizes.session_width); /* width */
|
||||
out_uint16_le(s, self->client_info.display_sizes.session_height); /* height */
|
||||
out_uint16_le(s, 0); /* Pad */
|
||||
out_uint16_le(s, 1); /* Allow resize */
|
||||
out_uint16_le(s, 1); /* bitmap compression */
|
||||
|
@ -1242,7 +1245,7 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
|||
}
|
||||
|
||||
/* send Monitor Layout PDU for dual monitor */
|
||||
if (self->client_info.monitorCount > 0 &&
|
||||
if (self->client_info.display_sizes.monitorCount > 0 &&
|
||||
self->client_info.multimon == 1)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu");
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#include "log.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
|
||||
|
||||
/* some compilers need unsigned char to avoid warnings */
|
||||
static tui8 g_pad_54[40] =
|
||||
{
|
||||
|
@ -1955,8 +1953,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
|
|||
|
||||
/* TS_UD_CS_CORE requiered fields */
|
||||
in_uint8s(s, 4); /* version */
|
||||
in_uint16_le(s, self->rdp_layer->client_info.width);
|
||||
in_uint16_le(s, self->rdp_layer->client_info.height);
|
||||
in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_width);
|
||||
in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_height);
|
||||
in_uint16_le(s, colorDepth);
|
||||
switch (colorDepth)
|
||||
{
|
||||
|
@ -1983,8 +1981,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
|
|||
"clientName %s, keyboardType (ignored), "
|
||||
"keyboardSubType (ignored), keyboardFunctionKey (ignored), "
|
||||
"imeFileName (ignroed)",
|
||||
self->rdp_layer->client_info.width,
|
||||
self->rdp_layer->client_info.height,
|
||||
self->rdp_layer->client_info.display_sizes.session_width,
|
||||
self->rdp_layer->client_info.display_sizes.session_height,
|
||||
(colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" :
|
||||
colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"),
|
||||
clientName);
|
||||
|
@ -2333,155 +2331,61 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
|
|||
int
|
||||
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||
{
|
||||
int index;
|
||||
int monitorCount;
|
||||
int flags;
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int got_primary;
|
||||
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
|
||||
int error = 0;
|
||||
struct xrdp_client_info *client_info = &(self->rdp_layer->client_info);
|
||||
|
||||
client_info = &(self->rdp_layer->client_info);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_monitors:");
|
||||
|
||||
/* this is an option set in xrdp.ini */
|
||||
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "Multi-monitor is disabled by server config");
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"xrdp_sec_process_mcs_data_monitors:"
|
||||
" Multi-monitor is disabled by server config");
|
||||
return 0;
|
||||
}
|
||||
if (!s_check_rem_and_log(s, 8, "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR"))
|
||||
if (!s_check_rem_and_log(s, 4,
|
||||
"xrdp_sec_process_mcs_data_monitors:"
|
||||
" Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR"))
|
||||
{
|
||||
return 1;
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
in_uint32_le(s, flags); /* flags */
|
||||
in_uint32_le(s, monitorCount);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_MONITOR "
|
||||
"flags 0x%8.8x, monitorCount %d", flags, monitorCount);
|
||||
|
||||
//verify flags - must be 0x0
|
||||
if (flags != 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR flags MUST be zero, "
|
||||
"received: 0x%8.8x", flags);
|
||||
return 1;
|
||||
"xrdp_sec_process_mcs_data_monitors: [MS-RDPBCGR]"
|
||||
" Protocol error: TS_UD_CS_MONITOR flags MUST be zero,"
|
||||
" received: 0x%8.8x", flags);
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
//verify monitorCount - max 16
|
||||
if (monitorCount > 16)
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
error = libxrdp_process_monitor_stream(s, description, 0);
|
||||
if (error == 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR monitorCount "
|
||||
"MUST be less than 16, received: %d", monitorCount);
|
||||
return 2;
|
||||
client_info->display_sizes.monitorCount = description->monitorCount;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_monitors:"
|
||||
" Received [MS-RDPBCGR] TS_UD_CS_MONITOR"
|
||||
" flags 0x%8.8x, monitorCount %d",
|
||||
flags, description->monitorCount);
|
||||
|
||||
client_info->display_sizes.session_width = description->session_width;
|
||||
client_info->display_sizes.session_height = description->session_height;
|
||||
g_memcpy(client_info->display_sizes.minfo, description->minfo, sizeof(struct monitor_info) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS);
|
||||
g_memcpy(client_info->display_sizes.minfo_wm, description->minfo_wm, sizeof(struct monitor_info) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS);
|
||||
}
|
||||
|
||||
client_info->monitorCount = monitorCount;
|
||||
g_free(description);
|
||||
|
||||
x1 = 0;
|
||||
y1 = 0;
|
||||
x2 = 0;
|
||||
y2 = 0;
|
||||
got_primary = 0;
|
||||
/* Add client_monitor_data to client_info struct, will later pass to X11rdp */
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
{
|
||||
if (!s_check_rem_and_log(s, 20, "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR.TS_MONITOR_DEF"))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, client_info->minfo[index].left);
|
||||
in_uint32_le(s, client_info->minfo[index].top);
|
||||
in_uint32_le(s, client_info->minfo[index].right);
|
||||
in_uint32_le(s, client_info->minfo[index].bottom);
|
||||
in_uint32_le(s, client_info->minfo[index].is_primary);
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] "
|
||||
"TS_UD_CS_MONITOR.TS_MONITOR_DEF %d "
|
||||
"left %d, top %d, right %d, bottom %d, flags 0x%8.8x",
|
||||
index,
|
||||
client_info->minfo[index].left,
|
||||
client_info->minfo[index].top,
|
||||
client_info->minfo[index].right,
|
||||
client_info->minfo[index].bottom,
|
||||
client_info->minfo[index].is_primary);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
x1 = client_info->minfo[index].left;
|
||||
y1 = client_info->minfo[index].top;
|
||||
x2 = client_info->minfo[index].right;
|
||||
y2 = client_info->minfo[index].bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = MIN(x1, client_info->minfo[index].left);
|
||||
y1 = MIN(y1, client_info->minfo[index].top);
|
||||
x2 = MAX(x2, client_info->minfo[index].right);
|
||||
y2 = MAX(y2, client_info->minfo[index].bottom);
|
||||
}
|
||||
|
||||
if (client_info->minfo[index].is_primary)
|
||||
{
|
||||
got_primary = 1;
|
||||
}
|
||||
|
||||
LOG(LOG_LEVEL_DEBUG,
|
||||
"Client monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, "
|
||||
"is_primary?= %d",
|
||||
index,
|
||||
client_info->minfo[index].left,
|
||||
client_info->minfo[index].top,
|
||||
client_info->minfo[index].right,
|
||||
client_info->minfo[index].bottom,
|
||||
client_info->minfo[index].is_primary);
|
||||
}
|
||||
|
||||
if (!got_primary)
|
||||
{
|
||||
/* no primary monitor was set, choose the leftmost monitor as primary */
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
{
|
||||
if (client_info->minfo[index].left == x1 &&
|
||||
client_info->minfo[index].top == y1)
|
||||
{
|
||||
client_info->minfo[index].is_primary = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set wm geometry */
|
||||
if ((x2 > x1) && (y2 > y1))
|
||||
{
|
||||
client_info->width = (x2 - x1) + 1;
|
||||
client_info->height = (y2 - y1) + 1;
|
||||
}
|
||||
/* make sure virtual desktop size is ok */
|
||||
if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
|
||||
client_info->height > 0x7FFE || client_info->height < 0xC8)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Client supplied virtual desktop width or height is invalid. "
|
||||
"Allowed width range: min %d, max %d. Width received: %d. "
|
||||
"Allowed height range: min %d, max %d. Height received: %d",
|
||||
0xC8, 0x7FFE, client_info->width,
|
||||
0xC8, 0x7FFE, client_info->height);
|
||||
return 3; /* error */
|
||||
}
|
||||
|
||||
/* keep a copy of non negative monitor info values for xrdp_wm usage */
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
{
|
||||
client_info->minfo_wm[index].left = client_info->minfo[index].left - x1;
|
||||
client_info->minfo_wm[index].top = client_info->minfo[index].top - y1;
|
||||
client_info->minfo_wm[index].right = client_info->minfo[index].right - x1;
|
||||
client_info->minfo_wm[index].bottom = client_info->minfo[index].bottom - y1;
|
||||
client_info->minfo_wm[index].is_primary = client_info->minfo[index].is_primary;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -14,7 +14,8 @@ check_PROGRAMS = test_libxrdp
|
|||
test_libxrdp_SOURCES = \
|
||||
test_libxrdp.h \
|
||||
test_libxrdp_main.c \
|
||||
test_monitor_processing.c
|
||||
test_libxrdp_process_monitor_stream.c \
|
||||
test_xrdp_sec_process_mcs_data_monitors.c
|
||||
|
||||
test_libxrdp_CFLAGS = \
|
||||
@CHECK_CFLAGS@
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <check.h>
|
||||
|
||||
Suite *make_suite_test_xrdp_sec_process_mcs_data_monitors(void);
|
||||
Suite *make_suite_test_monitor_processing(void);
|
||||
|
||||
#endif /* TEST_LIBXRDP_H */
|
|
@ -11,8 +11,8 @@ int main (void)
|
|||
int number_failed;
|
||||
SRunner *sr;
|
||||
|
||||
sr = srunner_create (make_suite_test_monitor_processing());
|
||||
// srunner_add_suite(sr, make_list_suite());
|
||||
sr = srunner_create(make_suite_test_xrdp_sec_process_mcs_data_monitors());
|
||||
srunner_add_suite(sr, make_suite_test_monitor_processing());
|
||||
|
||||
srunner_set_tap(sr, "-");
|
||||
srunner_run_all (sr, CK_ENV);
|
||||
|
|
|
@ -0,0 +1,406 @@
|
|||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config_ac.h"
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "os_calls.h"
|
||||
|
||||
#include "test_libxrdp.h"
|
||||
|
||||
START_TEST(test_libxrdp_process_monitor_stream__when_description_is_null__fail)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
init_stream(s, 4);
|
||||
|
||||
//Dummy data.
|
||||
out_uint32_le(s, 0);
|
||||
s_mark_end(s);
|
||||
//Reset the read counter of the stream so the processing function handles it properly.
|
||||
s->p = s->data;
|
||||
|
||||
int error = libxrdp_process_monitor_stream(s, NULL, 1);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_libxrdp_process_monitor_stream__when_stream_is_too_small__fail)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
init_stream(s, 2);
|
||||
|
||||
//Dummy data.
|
||||
out_uint16_le(s, 0);
|
||||
s_mark_end(s);
|
||||
//Reset the read counter of the stream so the processing function handles it properly.
|
||||
s->p = s->data;
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
int error = libxrdp_process_monitor_stream(s, description, 1);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR);
|
||||
|
||||
free(description);
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_libxrdp_process_monitor_stream__when_monitor_count_is_greater_than_sixteen__fail)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
init_stream(s, 4);
|
||||
|
||||
//Dummy data.
|
||||
out_uint32_le(s, 17);
|
||||
s_mark_end(s);
|
||||
//Reset the read counter of the stream so the processing function handles it properly.
|
||||
s->p = s->data;
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
int error = libxrdp_process_monitor_stream(s, description, 1);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_TOO_MANY_MONITORS);
|
||||
|
||||
free(description);
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_libxrdp_process_monitor_stream__with_single_monitor_happy_path)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
init_stream(s, 44);
|
||||
|
||||
out_uint32_le(s, 1); //monitorCount
|
||||
|
||||
// Pretend we have a 4k monitor
|
||||
out_uint32_le(s, TS_MONITOR_PRIMARY); //flags
|
||||
out_uint32_le(s, 0); //monitor left
|
||||
out_uint32_le(s, 0); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor right
|
||||
out_uint32_le(s, 2160); //monitor bottom
|
||||
out_uint32_le(s, 2000); //physical width
|
||||
out_uint32_le(s, 2000); //physical height
|
||||
out_uint32_le(s, 0); //orientation
|
||||
out_uint32_le(s, 100); //desktop scale factor
|
||||
out_uint32_le(s, 100); //device scale factor
|
||||
|
||||
s_mark_end(s);
|
||||
//Reset the read counter of the stream so the processing function handles it properly.
|
||||
s->p = s->data;
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
int error = libxrdp_process_monitor_stream(s, description, 1);
|
||||
|
||||
//Verify function call passed.
|
||||
ck_assert_int_eq(error, 0);
|
||||
|
||||
ck_assert_int_eq(description->monitorCount, 1);
|
||||
|
||||
// Verify normal monitor
|
||||
ck_assert_int_eq(description->minfo[0].left, 0);
|
||||
ck_assert_int_eq(description->minfo[0].top, 0);
|
||||
ck_assert_int_eq(description->minfo[0].right, 3840);
|
||||
ck_assert_int_eq(description->minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo[0].physical_width, 2000);
|
||||
ck_assert_int_eq(description->minfo[0].physical_height, 2000);
|
||||
ck_assert_int_eq(description->minfo[0].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[0].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[0].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[0].is_primary, 1);
|
||||
|
||||
// Verify normalized monitor
|
||||
ck_assert_int_eq(description->minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(description->minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo_wm[0].physical_width, 2000);
|
||||
ck_assert_int_eq(description->minfo_wm[0].physical_height, 2000);
|
||||
ck_assert_int_eq(description->minfo_wm[0].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[0].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[0].is_primary, 1);
|
||||
|
||||
// Verify geometry (+1 greater than )
|
||||
ck_assert_int_eq(description->session_width, 3841);
|
||||
ck_assert_int_eq(description->session_height, 2161);
|
||||
|
||||
free(description);
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_libxrdp_process_monitor_stream__with_sextuple_monitor_happy_path)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
init_stream(s, 233);
|
||||
|
||||
out_uint32_le(s, 6); //monitorCount
|
||||
|
||||
// 4k monitor at position (0, 0)
|
||||
out_uint32_le(s, 0); //flags
|
||||
out_uint32_le(s, 0); //monitor left
|
||||
out_uint32_le(s, 0); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor width
|
||||
out_uint32_le(s, 2160); //monitor height
|
||||
out_uint32_le(s, 9); //physical width
|
||||
out_uint32_le(s, 9); //physical height
|
||||
out_uint32_le(s, -10); //orientation
|
||||
out_uint32_le(s, -100); //desktop scale factor
|
||||
out_uint32_le(s, 600); //device scale factor
|
||||
|
||||
// 4k monitor at position (1, 0)
|
||||
out_uint32_le(s, TS_MONITOR_PRIMARY); //flags
|
||||
out_uint32_le(s, 3841); //monitor left
|
||||
out_uint32_le(s, 0); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor right
|
||||
out_uint32_le(s, 2160); //monitor bottom
|
||||
out_uint32_le(s, 5); //physical width
|
||||
out_uint32_le(s, 11000); //physical height
|
||||
out_uint32_le(s, 10); //orientation (Expect to be reset to 0)
|
||||
out_uint32_le(s, 360); //desktop scale factor
|
||||
out_uint32_le(s, 720); //device scale factor
|
||||
|
||||
// 4k monitor at position (2, 0)
|
||||
out_uint32_le(s, 0); //flags
|
||||
out_uint32_le(s, 7682); //monitor left
|
||||
out_uint32_le(s, 0); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor width
|
||||
out_uint32_le(s, 2160); //monitor height
|
||||
out_uint32_le(s, 1000); //physical width
|
||||
out_uint32_le(s, 1000); //physical height
|
||||
out_uint32_le(s, 5000); //orientation
|
||||
out_uint32_le(s, 80); //desktop scale factor
|
||||
out_uint32_le(s, 140); //device scale factor
|
||||
|
||||
// 4k monitor at position (0, 1)
|
||||
out_uint32_le(s, 0); //flags
|
||||
out_uint32_le(s, 0); //monitor left
|
||||
out_uint32_le(s, 2161); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor width
|
||||
out_uint32_le(s, 2160); //monitor height
|
||||
out_uint32_le(s, 1000); //physical width
|
||||
out_uint32_le(s, 1000); //physical height
|
||||
out_uint32_le(s, 91); //orientation
|
||||
out_uint32_le(s, 180); //desktop scale factor
|
||||
out_uint32_le(s, 100); //device scale factor
|
||||
|
||||
// 4k monitor at position (1, 1)
|
||||
out_uint32_le(s, 0); //flags
|
||||
out_uint32_le(s, 3841); //monitor left
|
||||
out_uint32_le(s, 2161); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor width
|
||||
out_uint32_le(s, 2160); //monitor height
|
||||
out_uint32_le(s, 1000); //physical width
|
||||
out_uint32_le(s, 1000); //physical height
|
||||
out_uint32_le(s, 0); //orientation
|
||||
out_uint32_le(s, 20); //desktop scale factor
|
||||
out_uint32_le(s, 50); //device scale factor
|
||||
|
||||
// 4k monitor at position (2, 1)
|
||||
out_uint32_le(s, 0); //flags
|
||||
out_uint32_le(s, 7682); //monitor left
|
||||
out_uint32_le(s, 2161); //monitor top
|
||||
out_uint32_le(s, 3840); //monitor width
|
||||
out_uint32_le(s, 2160); //monitor height
|
||||
out_uint32_le(s, 1000); //physical width
|
||||
out_uint32_le(s, 1000); //physical height
|
||||
out_uint32_le(s, 0); //orientation
|
||||
out_uint32_le(s, 300); //desktop scale factor
|
||||
out_uint32_le(s, 400); //device scale factor
|
||||
|
||||
s_mark_end(s);
|
||||
// Reset the read counter of the stream so the processing function handles it properly.
|
||||
s->p = s->data;
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
int error = libxrdp_process_monitor_stream(s, description, 1);
|
||||
|
||||
//Verify function call passed.
|
||||
ck_assert_int_eq(error, 0);
|
||||
|
||||
ck_assert_int_eq(description->monitorCount, 6);
|
||||
|
||||
/*************************************************
|
||||
* Verify standard monitors
|
||||
*************************************************/
|
||||
ck_assert_int_eq(description->minfo[0].left, 0);
|
||||
ck_assert_int_eq(description->minfo[0].top, 0);
|
||||
ck_assert_int_eq(description->minfo[0].right, 3840);
|
||||
ck_assert_int_eq(description->minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo[0].physical_width, 0);
|
||||
ck_assert_int_eq(description->minfo[0].physical_height, 0);
|
||||
ck_assert_int_eq(description->minfo[0].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[0].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[0].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[0].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo[1].left, 3841);
|
||||
ck_assert_int_eq(description->minfo[1].top, 0);
|
||||
ck_assert_int_eq(description->minfo[1].right, 7681);
|
||||
ck_assert_int_eq(description->minfo[1].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo[1].physical_width, 0);
|
||||
ck_assert_int_eq(description->minfo[1].physical_height, 0);
|
||||
ck_assert_int_eq(description->minfo[1].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[1].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[1].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[1].is_primary, 1);
|
||||
|
||||
ck_assert_int_eq(description->minfo[2].left, 7682);
|
||||
ck_assert_int_eq(description->minfo[2].top, 0);
|
||||
ck_assert_int_eq(description->minfo[2].right, 11522);
|
||||
ck_assert_int_eq(description->minfo[2].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo[2].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo[2].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo[2].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[2].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[2].device_scale_factor, 140);
|
||||
ck_assert_int_eq(description->minfo[2].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo[3].left, 0);
|
||||
ck_assert_int_eq(description->minfo[3].top, 2161);
|
||||
ck_assert_int_eq(description->minfo[3].right, 3840);
|
||||
ck_assert_int_eq(description->minfo[3].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo[3].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo[3].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo[3].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[3].desktop_scale_factor, 180);
|
||||
ck_assert_int_eq(description->minfo[3].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[3].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo[4].left, 3841);
|
||||
ck_assert_int_eq(description->minfo[4].top, 2161);
|
||||
ck_assert_int_eq(description->minfo[4].right, 7681);
|
||||
ck_assert_int_eq(description->minfo[4].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo[4].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo[4].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo[4].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[4].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[4].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[4].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo[5].left, 7682);
|
||||
ck_assert_int_eq(description->minfo[5].top, 2161);
|
||||
ck_assert_int_eq(description->minfo[5].right, 11522);
|
||||
ck_assert_int_eq(description->minfo[5].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo[5].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo[5].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo[5].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo[5].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[5].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo[5].is_primary, 0);
|
||||
|
||||
/*************************************************
|
||||
* Verify normalized monitors
|
||||
*************************************************/
|
||||
ck_assert_int_eq(description->minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(description->minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo_wm[0].physical_width, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].physical_height, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[0].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[0].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[0].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo_wm[1].left, 3841);
|
||||
ck_assert_int_eq(description->minfo_wm[1].top, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[1].right, 7681);
|
||||
ck_assert_int_eq(description->minfo_wm[1].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo_wm[1].physical_width, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[1].physical_height, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[1].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[1].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[1].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[1].is_primary, 1);
|
||||
|
||||
ck_assert_int_eq(description->minfo_wm[2].left, 7682);
|
||||
ck_assert_int_eq(description->minfo_wm[2].top, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[2].right, 11522);
|
||||
ck_assert_int_eq(description->minfo_wm[2].bottom, 2160);
|
||||
ck_assert_int_eq(description->minfo_wm[2].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[2].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[2].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[2].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[2].device_scale_factor, 140);
|
||||
ck_assert_int_eq(description->minfo_wm[2].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo_wm[3].left, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[3].top, 2161);
|
||||
ck_assert_int_eq(description->minfo_wm[3].right, 3840);
|
||||
ck_assert_int_eq(description->minfo_wm[3].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo_wm[3].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[3].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[3].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[3].desktop_scale_factor, 180);
|
||||
ck_assert_int_eq(description->minfo_wm[3].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[3].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo_wm[4].left, 3841);
|
||||
ck_assert_int_eq(description->minfo_wm[4].top, 2161);
|
||||
ck_assert_int_eq(description->minfo_wm[4].right, 7681);
|
||||
ck_assert_int_eq(description->minfo_wm[4].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo_wm[4].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[4].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[4].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[4].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[4].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[4].is_primary, 0);
|
||||
|
||||
ck_assert_int_eq(description->minfo_wm[5].left, 7682);
|
||||
ck_assert_int_eq(description->minfo_wm[5].top, 2161);
|
||||
ck_assert_int_eq(description->minfo_wm[5].right, 11522);
|
||||
ck_assert_int_eq(description->minfo_wm[5].bottom, 4321);
|
||||
ck_assert_int_eq(description->minfo_wm[5].physical_width, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[5].physical_height, 1000);
|
||||
ck_assert_int_eq(description->minfo_wm[5].orientation, 0);
|
||||
ck_assert_int_eq(description->minfo_wm[5].desktop_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[5].device_scale_factor, 100);
|
||||
ck_assert_int_eq(description->minfo_wm[5].is_primary, 0);
|
||||
|
||||
// Verify geometry
|
||||
ck_assert_int_eq(description->session_width, 11523);
|
||||
ck_assert_int_eq(description->session_height, 4322);
|
||||
|
||||
free(description);
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/******************************************************************************/
|
||||
Suite *
|
||||
make_suite_test_monitor_processing(void)
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc_process_monitors;
|
||||
|
||||
s = suite_create("test_libxrdp_process_monitor_stream");
|
||||
|
||||
tc_process_monitors = tcase_create("libxrdp_process_monitor_stream");
|
||||
tcase_add_test(tc_process_monitors, test_libxrdp_process_monitor_stream__when_description_is_null__fail);
|
||||
tcase_add_test(tc_process_monitors, test_libxrdp_process_monitor_stream__when_stream_is_too_small__fail);
|
||||
tcase_add_test(tc_process_monitors, test_libxrdp_process_monitor_stream__when_monitor_count_is_greater_than_sixteen__fail);
|
||||
tcase_add_test(tc_process_monitors, test_libxrdp_process_monitor_stream__with_single_monitor_happy_path);
|
||||
tcase_add_test(tc_process_monitors, test_libxrdp_process_monitor_stream__with_sextuple_monitor_happy_path);
|
||||
|
||||
suite_add_tcase(s, tc_process_monitors);
|
||||
|
||||
return s;
|
||||
}
|
|
@ -11,9 +11,6 @@ struct xrdp_sec *sec_layer;
|
|||
struct xrdp_rdp *rdp_layer;
|
||||
struct xrdp_session *session;
|
||||
|
||||
int
|
||||
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s);
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
rdp_layer = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1);
|
||||
|
@ -32,7 +29,7 @@ void teardown(void)
|
|||
g_free(rdp_layer);
|
||||
}
|
||||
|
||||
START_TEST(test_process_monitors__when_flags_is_not_zero__fail)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_flags_is_not_zero__fail)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -45,13 +42,13 @@ START_TEST(test_process_monitors__when_flags_is_not_zero__fail)
|
|||
s->p = s->data;
|
||||
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 1);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_mounter_count_is_greater_than_sixteen__fail)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_monitor_count_is_greater_than_sixteen__fail)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -64,13 +61,13 @@ START_TEST(test_process_monitors__when_mounter_count_is_greater_than_sixteen__fa
|
|||
s->p = s->data;
|
||||
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 2);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_TOO_MANY_MONITORS);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__with_single_monitor_happy_path)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__with_single_monitor_happy_path)
|
||||
{
|
||||
struct xrdp_client_info *client_info = &(rdp_layer->client_info);
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
|
@ -95,31 +92,31 @@ START_TEST(test_process_monitors__with_single_monitor_happy_path)
|
|||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 0);
|
||||
|
||||
ck_assert_int_eq(client_info->monitorCount, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.monitorCount, 1);
|
||||
|
||||
// Verify normal monitor
|
||||
ck_assert_int_eq(client_info->minfo[0].left, 0);
|
||||
ck_assert_int_eq(client_info->minfo[0].top, 0);
|
||||
ck_assert_int_eq(client_info->minfo[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->minfo[0].is_primary, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].left, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].top, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].is_primary, 1);
|
||||
|
||||
// Verify normalized monitor
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].is_primary, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].is_primary, 1);
|
||||
|
||||
// Verify geometry (+1 greater than )
|
||||
ck_assert_int_eq(client_info->width, 3841);
|
||||
ck_assert_int_eq(client_info->height, 2161);
|
||||
ck_assert_int_eq(client_info->display_sizes.session_width, 3841);
|
||||
ck_assert_int_eq(client_info->display_sizes.session_height, 2161);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_no_primary_monitor_is_specified_one_is_selected)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_no_primary_monitor_is_specified_one_is_selected)
|
||||
{
|
||||
struct xrdp_client_info *client_info = &(rdp_layer->client_info);
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
|
@ -144,31 +141,31 @@ START_TEST(test_process_monitors__when_no_primary_monitor_is_specified_one_is_se
|
|||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 0);
|
||||
|
||||
ck_assert_int_eq(client_info->monitorCount, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.monitorCount, 1);
|
||||
|
||||
// Verify normal monitor
|
||||
ck_assert_int_eq(client_info->minfo[0].left, 0);
|
||||
ck_assert_int_eq(client_info->minfo[0].top, 0);
|
||||
ck_assert_int_eq(client_info->minfo[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->minfo[0].is_primary, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].left, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].top, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo[0].is_primary, 1);
|
||||
|
||||
// Verify normalized monitor
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->minfo_wm[0].is_primary, 1);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].left, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].top, 0);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].right, 3840);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].bottom, 2160);
|
||||
ck_assert_int_eq(client_info->display_sizes.minfo_wm[0].is_primary, 1);
|
||||
|
||||
// Verify geometry (+1 greater than )
|
||||
ck_assert_int_eq(client_info->width, 3841);
|
||||
ck_assert_int_eq(client_info->height, 2161);
|
||||
ck_assert_int_eq(client_info->display_sizes.session_width, 3841);
|
||||
ck_assert_int_eq(client_info->display_sizes.session_height, 2161);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_large)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_width_is_too_large)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -190,13 +187,13 @@ START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_large)
|
|||
|
||||
//Verify function call passed.
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 3);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_small)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_width_is_too_small)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -218,13 +215,13 @@ START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_small)
|
|||
|
||||
//Verify function call passed.
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 3);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_large)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_height_is_too_large)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -246,13 +243,13 @@ START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_large)
|
|||
|
||||
//Verify function call passed.
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 3);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_small)
|
||||
START_TEST(test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_height_is_too_small)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
make_stream(s);
|
||||
|
@ -274,7 +271,7 @@ START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_small)
|
|||
|
||||
//Verify function call passed.
|
||||
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||
ck_assert_int_eq(error, 3);
|
||||
ck_assert_int_eq(error, SEC_PROCESS_MONITORS_ERR_INVALID_DESKTOP);
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
|
@ -282,23 +279,23 @@ END_TEST
|
|||
|
||||
/******************************************************************************/
|
||||
Suite *
|
||||
make_suite_test_monitor_processing(void)
|
||||
make_suite_test_xrdp_sec_process_mcs_data_monitors(void)
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc_process_monitors;
|
||||
|
||||
s = suite_create("Monitor_Processing");
|
||||
s = suite_create("test_xrdp_sec_process_mcs_data_monitors");
|
||||
|
||||
tc_process_monitors = tcase_create("xrdp_sec_process_mcs_data_monitors");
|
||||
tcase_add_checked_fixture(tc_process_monitors, setup, teardown);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_flags_is_not_zero__fail);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_mounter_count_is_greater_than_sixteen__fail);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__with_single_monitor_happy_path);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_no_primary_monitor_is_specified_one_is_selected);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_width_is_too_large);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_width_is_too_small);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_height_is_too_large);
|
||||
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_height_is_too_small);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_flags_is_not_zero__fail);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_monitor_count_is_greater_than_sixteen__fail);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__with_single_monitor_happy_path);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_no_primary_monitor_is_specified_one_is_selected);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_width_is_too_large);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_width_is_too_small);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_height_is_too_large);
|
||||
tcase_add_test(tc_process_monitors, test_xrdp_sec_process_mcs_data_monitors__when_virtual_desktop_height_is_too_small);
|
||||
|
||||
suite_add_tcase(s, tc_process_monitors);
|
||||
|
28
vnc/vnc.c
28
vnc/vnc.c
|
@ -2039,25 +2039,25 @@ static void
|
|||
init_client_layout(struct vnc_screen_layout *layout,
|
||||
const struct xrdp_client_info *client_info)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
|
||||
layout->total_width = client_info->width;
|
||||
layout->total_height = client_info->height;
|
||||
layout->total_width = client_info->display_sizes.session_width;
|
||||
layout->total_height = client_info->display_sizes.session_height;
|
||||
|
||||
layout->count = client_info->monitorCount;
|
||||
layout->count = client_info->display_sizes.monitorCount;
|
||||
layout->s = g_new(struct vnc_screen, layout->count);
|
||||
|
||||
for (i = 0 ; i < client_info->monitorCount ; ++i)
|
||||
for (i = 0 ; i < client_info->display_sizes.monitorCount ; ++i)
|
||||
{
|
||||
/* Use minfo_wm, as this is normalised for a top-left of (0,0)
|
||||
* as required by RFC6143 */
|
||||
layout->s[i].id = i;
|
||||
layout->s[i].x = client_info->minfo_wm[i].left;
|
||||
layout->s[i].y = client_info->minfo_wm[i].top;
|
||||
layout->s[i].width = client_info->minfo_wm[i].right -
|
||||
client_info->minfo_wm[i].left + 1;
|
||||
layout->s[i].height = client_info->minfo_wm[i].bottom -
|
||||
client_info->minfo_wm[i].top + 1;
|
||||
layout->s[i].x = client_info->display_sizes.minfo_wm[i].left;
|
||||
layout->s[i].y = client_info->display_sizes.minfo_wm[i].top;
|
||||
layout->s[i].width = client_info->display_sizes.minfo_wm[i].right -
|
||||
client_info->display_sizes.minfo_wm[i].left + 1;
|
||||
layout->s[i].height = client_info->display_sizes.minfo_wm[i].bottom -
|
||||
client_info->display_sizes.minfo_wm[i].top + 1;
|
||||
layout->s[i].flags = 0;
|
||||
}
|
||||
}
|
||||
|
@ -2106,11 +2106,11 @@ lib_mod_set_param(struct vnc *v, const char *name, const char *value)
|
|||
g_free(v->client_layout.s);
|
||||
|
||||
/* Save monitor information from the client */
|
||||
if (!client_info->multimon || client_info->monitorCount < 1)
|
||||
if (!client_info->multimon || client_info->display_sizes.monitorCount < 1)
|
||||
{
|
||||
set_single_screen_layout(&v->client_layout,
|
||||
client_info->width,
|
||||
client_info->height);
|
||||
client_info->display_sizes.session_width,
|
||||
client_info->display_sizes.session_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -652,7 +652,7 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
|
|||
int primary_height;
|
||||
int primary_x_offset; /* Offset of centre of primary screen */
|
||||
int primary_y_offset;
|
||||
int index;
|
||||
uint32_t index;
|
||||
int x;
|
||||
int y;
|
||||
int cx;
|
||||
|
@ -684,16 +684,16 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
|
|||
}
|
||||
|
||||
/* multimon scenario, draw login window on primary monitor */
|
||||
if (self->client_info->monitorCount > 1)
|
||||
if (self->client_info->display_sizes.monitorCount > 1)
|
||||
{
|
||||
for (index = 0; index < self->client_info->monitorCount; index++)
|
||||
for (index = 0; index < self->client_info->display_sizes.monitorCount; index++)
|
||||
{
|
||||
if (self->client_info->minfo_wm[index].is_primary)
|
||||
if (self->client_info->display_sizes.minfo_wm[index].is_primary)
|
||||
{
|
||||
x = self->client_info->minfo_wm[index].left;
|
||||
y = self->client_info->minfo_wm[index].top;
|
||||
cx = self->client_info->minfo_wm[index].right;
|
||||
cy = self->client_info->minfo_wm[index].bottom;
|
||||
x = self->client_info->display_sizes.minfo_wm[index].left;
|
||||
y = self->client_info->display_sizes.minfo_wm[index].top;
|
||||
cx = self->client_info->display_sizes.minfo_wm[index].right;
|
||||
cy = self->client_info->display_sizes.minfo_wm[index].bottom;
|
||||
|
||||
primary_width = cx - x;
|
||||
primary_height = cy - y;
|
||||
|
|
240
xrdp/xrdp_mm.c
240
xrdp/xrdp_mm.c
|
@ -1022,27 +1022,154 @@ dynamic_monitor_data_first(intptr_t id, int chan_id, char *data, int bytes,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
process_dynamic_monitor_description(struct xrdp_wm *wm,
|
||||
struct display_size_description *description)
|
||||
{
|
||||
int error = 0;
|
||||
struct xrdp_mm *mm = wm->mm;
|
||||
struct xrdp_mod *module = mm->mod;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "process_dynamic_monitor_description:");
|
||||
|
||||
if (wm->client_info->suppress_output == 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description:"
|
||||
" Not allowing resize. Suppress output is active.");
|
||||
return 0;
|
||||
}
|
||||
if (description == NULL)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description:"
|
||||
" description is null.");
|
||||
return 0;
|
||||
}
|
||||
if (description->session_width <= 0 || description->session_height <= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description: Not allowing resize due to"
|
||||
" invalid dimensions (w: %d x h: %d)",
|
||||
description->session_width, description->session_height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: Unify this logic with server_reset
|
||||
error = libxrdp_reset(wm->session,
|
||||
description->session_width,
|
||||
description->session_height,
|
||||
wm->screen->bpp);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description:"
|
||||
" libxrdp_reset failed %d", error);
|
||||
return error;
|
||||
}
|
||||
/* reset cache */
|
||||
error = xrdp_cache_reset(wm->cache, wm->client_info);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description: xrdp_cache_reset"
|
||||
" failed %d", error);
|
||||
return error;
|
||||
}
|
||||
/* load some stuff */
|
||||
error = xrdp_wm_load_static_colors_plus(wm, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
" xrdp_wm_load_static_colors_plus failed %d", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = xrdp_wm_load_static_pointers(wm);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
" xrdp_wm_load_static_pointers failed %d", error);
|
||||
return error;
|
||||
}
|
||||
/* resize the main window */
|
||||
error = xrdp_bitmap_resize(wm->screen,
|
||||
description->session_width,
|
||||
description->session_height);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
" xrdp_bitmap_resize failed %d", error);
|
||||
return error;
|
||||
}
|
||||
/* redraw */
|
||||
error = xrdp_bitmap_invalidate(wm->screen, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||
"process_dynamic_monitor_description:"
|
||||
" xrdp_bitmap_invalidate failed %d", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (module != 0)
|
||||
{
|
||||
error = module->mod_server_version_message(module);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
" mod_server_version_message failed %d", error);
|
||||
return error;
|
||||
}
|
||||
error = module->mod_server_monitor_resize(
|
||||
module,
|
||||
description->session_width,
|
||||
description->session_height);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
"mod_server_monitor_resize failed %d", error);
|
||||
return error;
|
||||
}
|
||||
error = module->mod_server_monitor_full_invalidate(
|
||||
module,
|
||||
description->session_width,
|
||||
description->session_height);
|
||||
if (error != 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_dynamic_monitor_description:"
|
||||
"mod_server_monitor_full_invalidate failed %d", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
wm->client_info->display_sizes.monitorCount = description->monitorCount;
|
||||
wm->client_info->display_sizes.session_width = description->session_width;
|
||||
wm->client_info->display_sizes.session_height = description->session_height;
|
||||
g_memcpy(wm->client_info->display_sizes.minfo,
|
||||
description->minfo,
|
||||
sizeof(struct monitor_info)
|
||||
* CLIENT_MONITOR_DATA_MAXIMUM_MONITORS);
|
||||
g_memcpy(wm->client_info->display_sizes.minfo_wm,
|
||||
description->minfo_wm,
|
||||
sizeof(struct monitor_info)
|
||||
* CLIENT_MONITOR_DATA_MAXIMUM_MONITORS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
dynamic_monitor_data(intptr_t id, int chan_id, char *data, int bytes)
|
||||
{
|
||||
int error = 0;
|
||||
struct stream ls;
|
||||
struct stream *s;
|
||||
int msg_type;
|
||||
int msg_length;
|
||||
int monitor_index;
|
||||
struct xrdp_process *pro;
|
||||
struct xrdp_wm *wm;
|
||||
|
||||
int MonitorLayoutSize;
|
||||
int NumMonitor;
|
||||
|
||||
struct dynamic_monitor_layout monitor_layouts[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS];
|
||||
struct dynamic_monitor_layout *monitor_layout;
|
||||
|
||||
struct xrdp_rect rect;
|
||||
int session_width;
|
||||
int session_height;
|
||||
int monitor_layout_size;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_data:");
|
||||
pro = (struct xrdp_process *) id;
|
||||
|
@ -1058,70 +1185,31 @@ dynamic_monitor_data(intptr_t id, int chan_id, char *data, int bytes)
|
|||
LOG(LOG_LEVEL_DEBUG, "dynamic_monitor_data: msg_type %d msg_length %d",
|
||||
msg_type, msg_length);
|
||||
|
||||
rect.left = 8192;
|
||||
rect.top = 8192;
|
||||
rect.right = -8192;
|
||||
rect.bottom = -8192;
|
||||
|
||||
if (msg_type == DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT)
|
||||
if (msg_type != DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT)
|
||||
{
|
||||
in_uint32_le(s, MonitorLayoutSize);
|
||||
in_uint32_le(s, NumMonitor);
|
||||
LOG(LOG_LEVEL_DEBUG, " MonitorLayoutSize %d NumMonitor %d",
|
||||
MonitorLayoutSize, NumMonitor);
|
||||
for (monitor_index = 0; monitor_index < NumMonitor; monitor_index++)
|
||||
{
|
||||
monitor_layout = monitor_layouts + monitor_index;
|
||||
in_uint32_le(s, monitor_layout->flags);
|
||||
in_uint32_le(s, monitor_layout->left);
|
||||
in_uint32_le(s, monitor_layout->top);
|
||||
in_uint32_le(s, monitor_layout->width);
|
||||
in_uint32_le(s, monitor_layout->height);
|
||||
in_uint32_le(s, monitor_layout->physical_width);
|
||||
in_uint32_le(s, monitor_layout->physical_height);
|
||||
in_uint32_le(s, monitor_layout->orientation);
|
||||
in_uint32_le(s, monitor_layout->desktop_scale_factor);
|
||||
in_uint32_le(s, monitor_layout->device_scale_factor);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " Flags 0x%8.8x Left %d Top %d "
|
||||
"Width %d Height %d PhysicalWidth %d PhysicalHeight %d "
|
||||
"Orientation %d DesktopScaleFactor %d DeviceScaleFactor %d",
|
||||
monitor_layout->flags, monitor_layout->left, monitor_layout->top,
|
||||
monitor_layout->width, monitor_layout->height,
|
||||
monitor_layout->physical_width, monitor_layout->physical_height,
|
||||
monitor_layout->orientation, monitor_layout->desktop_scale_factor,
|
||||
monitor_layout->device_scale_factor);
|
||||
|
||||
rect.left = MIN(monitor_layout->left, rect.left);
|
||||
rect.top = MIN(monitor_layout->top, rect.top);
|
||||
rect.right = MAX(rect.right, monitor_layout->left + monitor_layout->width);
|
||||
rect.bottom = MAX(rect.bottom, monitor_layout->top + monitor_layout->height);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
session_width = rect.right - rect.left;
|
||||
session_height = rect.bottom - rect.top;
|
||||
if ((session_width > 0) && (session_height > 0))
|
||||
in_uint32_le(s, monitor_layout_size);
|
||||
if (monitor_layout_size != 40)
|
||||
{
|
||||
// TODO: Unify this logic with server_reset
|
||||
libxrdp_reset(wm->session, session_width, session_height, wm->screen->bpp);
|
||||
/* reset cache */
|
||||
xrdp_cache_reset(wm->cache, wm->client_info);
|
||||
/* resize the main window */
|
||||
xrdp_bitmap_resize(wm->screen, session_width, session_height);
|
||||
/* load some stuff */
|
||||
xrdp_wm_load_static_colors_plus(wm, 0);
|
||||
xrdp_wm_load_static_pointers(wm);
|
||||
/* redraw */
|
||||
xrdp_bitmap_invalidate(wm->screen, 0);
|
||||
|
||||
struct xrdp_mod *v = wm->mm->mod;
|
||||
if (v != 0)
|
||||
{
|
||||
v->mod_server_version_message(v);
|
||||
v->mod_server_monitor_resize(v, session_width, session_height);
|
||||
v->mod_server_monitor_full_invalidate(v, session_width, session_height);
|
||||
}
|
||||
LOG(LOG_LEVEL_ERROR, "dynamic_monitor_data: monitor_layout_size"
|
||||
" is %d. Per spec ([MS-RDPEDISP] 2.2.2.2"
|
||||
" DISPLAYCONTROL_MONITOR_LAYOUT_PDU) it must be 40.",
|
||||
monitor_layout_size);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
struct display_size_description *description =
|
||||
(struct display_size_description *)
|
||||
g_malloc(sizeof(struct display_size_description), 1);
|
||||
|
||||
error = libxrdp_process_monitor_stream(s, description, 1);
|
||||
if (error == 0)
|
||||
{
|
||||
error = process_dynamic_monitor_description(wm, description);
|
||||
}
|
||||
g_free(description);
|
||||
return error;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -3515,10 +3603,10 @@ server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
|
|||
}
|
||||
|
||||
/* if same (and only one monitor on client) don't need to do anything */
|
||||
if (wm->client_info->width == width &&
|
||||
wm->client_info->height == height &&
|
||||
if (wm->client_info->display_sizes.session_width == (uint32_t)width &&
|
||||
wm->client_info->display_sizes.session_height == (uint32_t)height &&
|
||||
wm->client_info->bpp == bpp &&
|
||||
(wm->client_info->monitorCount == 0 || wm->client_info->multimon == 0))
|
||||
(wm->client_info->display_sizes.monitorCount == 0 || wm->client_info->multimon == 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -3532,8 +3620,8 @@ server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
|
|||
/* reset cache */
|
||||
xrdp_cache_reset(wm->cache, wm->client_info);
|
||||
/* resize the main window */
|
||||
xrdp_bitmap_resize(wm->screen, wm->client_info->width,
|
||||
wm->client_info->height);
|
||||
xrdp_bitmap_resize(wm->screen, wm->client_info->display_sizes.session_width,
|
||||
wm->client_info->display_sizes.session_height);
|
||||
/* load some stuff */
|
||||
xrdp_wm_load_static_colors_plus(wm, 0);
|
||||
xrdp_wm_load_static_pointers(wm);
|
||||
|
|
|
@ -45,8 +45,8 @@ xrdp_wm_create(struct xrdp_process *owner,
|
|||
|
||||
self = (struct xrdp_wm *)g_malloc(sizeof(struct xrdp_wm), 1);
|
||||
self->client_info = client_info;
|
||||
self->screen = xrdp_bitmap_create(client_info->width,
|
||||
client_info->height,
|
||||
self->screen = xrdp_bitmap_create(client_info->display_sizes.session_width,
|
||||
client_info->display_sizes.session_height,
|
||||
client_info->bpp,
|
||||
WND_TYPE_SCREEN, self);
|
||||
self->screen->wm = self;
|
||||
|
@ -2088,7 +2088,7 @@ xrdp_wm_show_log(struct xrdp_wm *self)
|
|||
int h;
|
||||
int xoffset;
|
||||
int yoffset;
|
||||
int index;
|
||||
uint32_t index;
|
||||
int primary_x_offset;
|
||||
int primary_y_offset;
|
||||
|
||||
|
@ -2124,14 +2124,14 @@ xrdp_wm_show_log(struct xrdp_wm *self)
|
|||
primary_y_offset = 0;
|
||||
|
||||
/* multimon scenario, draw log window on primary monitor */
|
||||
if (self->client_info->monitorCount > 1)
|
||||
if (self->client_info->display_sizes.monitorCount > 1)
|
||||
{
|
||||
for (index = 0; index < self->client_info->monitorCount; index++)
|
||||
for (index = 0; index < self->client_info->display_sizes.monitorCount; index++)
|
||||
{
|
||||
if (self->client_info->minfo_wm[index].is_primary)
|
||||
if (self->client_info->display_sizes.minfo_wm[index].is_primary)
|
||||
{
|
||||
primary_x_offset = self->client_info->minfo_wm[index].left;
|
||||
primary_y_offset = self->client_info->minfo_wm[index].top;
|
||||
primary_x_offset = self->client_info->display_sizes.minfo_wm[index].left;
|
||||
primary_y_offset = self->client_info->display_sizes.minfo_wm[index].top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue