mirror of https://github.com/FreeRDP/FreeRDP
Add better handling of monitors
This patch makes FreeRDP announce the support for monitor layout PDU. It also adds support for servers to announce the monitors layout.
This commit is contained in:
parent
ca9e908f3c
commit
121a234866
|
@ -148,6 +148,7 @@ typedef BOOL (*pSetKeyboardIndicators)(rdpContext* context, UINT16 led_flags);
|
|||
|
||||
typedef BOOL (*pRefreshRect)(rdpContext* context, BYTE count, RECTANGLE_16* areas);
|
||||
typedef BOOL (*pSuppressOutput)(rdpContext* context, BYTE allow, RECTANGLE_16* area);
|
||||
typedef BOOL (*pRemoteMonitors)(rdpContext* context, UINT32 count, const MONITOR_DEF *monitors);
|
||||
|
||||
typedef BOOL (*pSurfaceCommand)(rdpContext* context, wStream* s);
|
||||
typedef BOOL (*pSurfaceBits)(rdpContext* context, SURFACE_BITS_COMMAND* surfaceBitsCommand);
|
||||
|
@ -180,7 +181,8 @@ struct rdp_update
|
|||
|
||||
pRefreshRect RefreshRect; /* 48 */
|
||||
pSuppressOutput SuppressOutput; /* 49 */
|
||||
UINT32 paddingD[64 - 50]; /* 50 */
|
||||
pRemoteMonitors RemoteMonitors; /* 50 */
|
||||
UINT32 paddingD[64 - 51]; /* 51 */
|
||||
|
||||
pSurfaceCommand SurfaceCommand; /* 64 */
|
||||
pSurfaceBits SurfaceBits; /* 65 */
|
||||
|
|
|
@ -364,9 +364,34 @@ BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
|
|||
|
||||
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
rdpSettings *settings = rdp->settings;
|
||||
|
||||
if (!rdp_recv_client_font_list_pdu(s))
|
||||
return FALSE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu && settings->MonitorCount)
|
||||
{
|
||||
/* client supports the monitorLayout PDU, let's send him the monitors if any */
|
||||
wStream *st;
|
||||
BOOL r;
|
||||
|
||||
st = rdp_data_pdu_init(rdp);
|
||||
if (!st)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray))
|
||||
{
|
||||
Stream_Free(st, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0);
|
||||
Stream_Free(st, TRUE);
|
||||
|
||||
if (!r)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rdp_send_server_font_map_pdu(rdp))
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -761,6 +761,9 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
|||
if (settings->SupportDynamicTimeZone)
|
||||
settings->SupportDynamicTimeZone = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu)
|
||||
settings->SupportMonitorLayoutPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE;
|
||||
|
||||
if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE))
|
||||
connectionType = 0;
|
||||
|
||||
|
@ -866,6 +869,9 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs)
|
|||
if (settings->SupportDynamicTimeZone)
|
||||
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu)
|
||||
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU;
|
||||
|
||||
Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */
|
||||
Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */
|
||||
|
||||
|
|
|
@ -706,13 +706,14 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
|||
UINT32 monitorCount;
|
||||
MONITOR_DEF* monitor;
|
||||
MONITOR_DEF* monitorDefArray;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, monitorCount); /* monitorCount (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < (monitorCount * 20))
|
||||
if ((Stream_GetRemainingLength(s) / 20) < monitorCount)
|
||||
return FALSE;
|
||||
|
||||
monitorDefArray = (MONITOR_DEF*) calloc(monitorCount, sizeof(MONITOR_DEF));
|
||||
|
@ -720,9 +721,8 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
|||
if (!monitorDefArray)
|
||||
return FALSE;
|
||||
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
for (monitor = monitorDefArray, index = 0; index < monitorCount; index++, monitor++)
|
||||
{
|
||||
monitor = &(monitorDefArray[index]);
|
||||
Stream_Read_UINT32(s, monitor->left); /* left (4 bytes) */
|
||||
Stream_Read_UINT32(s, monitor->top); /* top (4 bytes) */
|
||||
Stream_Read_UINT32(s, monitor->right); /* right (4 bytes) */
|
||||
|
@ -730,27 +730,30 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
|||
Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
IFCALLRET(rdp->update->RemoteMonitors, ret, rdp->context, monitorCount, monitorDefArray);
|
||||
|
||||
free(monitorDefArray);
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, MONITOR_DEF* monitorDefArray)
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, const rdpMonitor* monitorDefArray)
|
||||
{
|
||||
UINT32 index;
|
||||
MONITOR_DEF* monitor;
|
||||
const rdpMonitor* monitor;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20)))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */
|
||||
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++)
|
||||
{
|
||||
monitor = &(monitorDefArray[index]);
|
||||
Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->x); /* left (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->y); /* top (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->x + monitor->width - 1); /* right (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->y + monitor->height - 1); /* bottom (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->is_primary ? 0x01 : 0x00); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -214,6 +214,8 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s);
|
|||
|
||||
void rdp_read_flow_control_pdu(wStream* s, UINT16* type);
|
||||
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, const rdpMonitor* monitorDefArray);
|
||||
|
||||
int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra);
|
||||
|
||||
int rdp_check_fds(rdpRdp* rdp);
|
||||
|
|
|
@ -295,6 +295,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
|||
if (!settings->ChannelDefArray)
|
||||
goto out_fail;
|
||||
|
||||
settings->SupportMonitorLayoutPdu = TRUE;
|
||||
settings->MonitorCount = 0;
|
||||
settings->MonitorDefArraySize = 32;
|
||||
settings->MonitorDefArray = (rdpMonitor*) calloc(settings->MonitorDefArraySize, sizeof(rdpMonitor));
|
||||
|
|
Loading…
Reference in New Issue