Rework xrdp to support new module resize interface
This commit compiles.
This commit is contained in:
+179
-154
@@ -1136,34 +1136,10 @@ libxrdp_orders_send_font(struct xrdp_session *session,
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Note : if this is called on a multimon setup, the client is resized
|
||||
* to a single monitor */
|
||||
int EXPORT_CC
|
||||
libxrdp_reset(struct xrdp_session *session,
|
||||
unsigned int width, unsigned int height, int bpp)
|
||||
libxrdp_reset(struct xrdp_session *session)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_reset:");
|
||||
if (session->client_info != 0)
|
||||
{
|
||||
struct xrdp_client_info *client_info = session->client_info;
|
||||
|
||||
/* older client can't resize */
|
||||
if (client_info->build <= 419)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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->multimon = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_reset: session->client_info is NULL");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* this will send any lingering orders */
|
||||
if (xrdp_orders_reset((struct xrdp_orders *)session->orders) != 0)
|
||||
@@ -1792,6 +1768,19 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data,
|
||||
static void
|
||||
sanitise_extended_monitor_attributes(struct monitor_info *monitor_layout)
|
||||
{
|
||||
if (monitor_layout->physical_width == 0
|
||||
&& monitor_layout->physical_width == 0
|
||||
&& monitor_layout->orientation == 0
|
||||
&& monitor_layout->desktop_scale_factor == 0
|
||||
&& monitor_layout->device_scale_factor == 0)
|
||||
{
|
||||
/* Module expects us to provide defaults */
|
||||
monitor_layout->orientation = ORIENTATION_LANDSCAPE;
|
||||
monitor_layout->desktop_scale_factor = 100;
|
||||
monitor_layout->device_scale_factor = 100;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if EITHER physical_width or physical_height are
|
||||
* out of range, BOTH must be ignored.
|
||||
*/
|
||||
@@ -1882,16 +1871,16 @@ libxrdp_process_monitor_stream(struct stream *s,
|
||||
{
|
||||
uint32_t num_monitor;
|
||||
uint32_t monitor_index;
|
||||
struct monitor_info monitors[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS];
|
||||
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"
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR,
|
||||
"libxrdp_process_monitor_stream: description was"
|
||||
" null. Valid pointer to allocated description expected.");
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
@@ -1939,7 +1928,7 @@ libxrdp_process_monitor_stream(struct stream *s,
|
||||
" from [MS-RDPEDISP] 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT.";
|
||||
}
|
||||
|
||||
description->monitorCount = num_monitor;
|
||||
memset(monitors, 0, sizeof(monitors[0]) * num_monitor);
|
||||
|
||||
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
|
||||
{
|
||||
@@ -1951,7 +1940,8 @@ libxrdp_process_monitor_stream(struct stream *s,
|
||||
return SEC_PROCESS_MONITORS_ERR;
|
||||
}
|
||||
|
||||
monitor_layout = description->minfo + monitor_index;
|
||||
monitor_layout = &monitors[monitor_index];
|
||||
|
||||
if (full_parameters != 0)
|
||||
{
|
||||
in_uint32_le(s, monitor_layout->flags);
|
||||
@@ -2017,8 +2007,6 @@ libxrdp_process_monitor_stream(struct stream *s,
|
||||
in_uint32_le(s, monitor_layout->desktop_scale_factor);
|
||||
in_uint32_le(s, monitor_layout->device_scale_factor);
|
||||
|
||||
sanitise_extended_monitor_attributes(monitor_layout);
|
||||
|
||||
/*
|
||||
* 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT
|
||||
*/
|
||||
@@ -2047,130 +2035,10 @@ libxrdp_process_monitor_stream(struct stream *s,
|
||||
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;
|
||||
return libxrdp_init_display_size_description(
|
||||
num_monitor, monitors, description);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2274,6 +2142,163 @@ libxrdp_process_monitor_ex_stream(struct stream *s,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
libxrdp_init_display_size_description(
|
||||
unsigned int num_monitor,
|
||||
const struct monitor_info *monitors,
|
||||
struct display_size_description *description)
|
||||
{
|
||||
unsigned int monitor_index;
|
||||
struct monitor_info *monitor_layout;
|
||||
struct xrdp_rect all_monitors_encompassing_bounds = {0};
|
||||
int got_primary = 0;
|
||||
|
||||
/* Caller should have checked this, so don't log an error */
|
||||
if (num_monitor > CLIENT_MONITOR_DATA_MAXIMUM_MONITORS)
|
||||
{
|
||||
return SEC_PROCESS_MONITORS_ERR_TOO_MANY_MONITORS;
|
||||
}
|
||||
|
||||
description->monitorCount = num_monitor;
|
||||
for (monitor_index = 0 ; monitor_index < num_monitor; ++monitor_index)
|
||||
{
|
||||
monitor_layout = &description->minfo[monitor_index];
|
||||
*monitor_layout = monitors[monitor_index];
|
||||
sanitise_extended_monitor_attributes(monitor_layout);
|
||||
|
||||
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)
|
||||
{
|
||||
if (got_primary)
|
||||
{
|
||||
// Already got one - don't have two
|
||||
monitor_layout->is_primary = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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_init_display_size_description:"
|
||||
" 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_init_display_size_description: Calculated 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;
|
||||
|
||||
*monitor_layout = description->minfo[monitor_index];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int EXPORT_CC
|
||||
libxrdp_planar_compress(char *in_data, int width, int height,
|
||||
|
||||
+19
-2
@@ -24,6 +24,7 @@
|
||||
#include "xrdp_rail.h"
|
||||
|
||||
struct list;
|
||||
struct monitor_info;
|
||||
|
||||
/* struct xrdp_client_info moved to xrdp_client_info.h */
|
||||
|
||||
@@ -195,8 +196,7 @@ libxrdp_orders_send_font(struct xrdp_session *session,
|
||||
struct xrdp_font_char *font_char,
|
||||
int font_index, int char_index);
|
||||
int
|
||||
libxrdp_reset(struct xrdp_session *session,
|
||||
unsigned int width, unsigned int height, int bpp);
|
||||
libxrdp_reset(struct xrdp_session *session);
|
||||
int
|
||||
libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session,
|
||||
int width, int height, int bpp, char *data,
|
||||
@@ -346,4 +346,21 @@ int EXPORT_CC
|
||||
libxrdp_process_monitor_ex_stream(struct stream *s,
|
||||
struct display_size_description *description);
|
||||
|
||||
/**
|
||||
* Convert a list of monitors into a full description
|
||||
*
|
||||
* Monitor data is sanitised during the conversion
|
||||
*
|
||||
* @param num_monitor Monitor count (> 0)
|
||||
* @param monitors List of monitors
|
||||
* @param[out] description Display size description
|
||||
*
|
||||
* @return 0 if the data is processed, non-zero if there is an error.
|
||||
*/
|
||||
int
|
||||
libxrdp_init_display_size_description(
|
||||
unsigned int num_monitor,
|
||||
const struct monitor_info *monitors,
|
||||
struct display_size_description *description);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user