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);
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 */
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;
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;
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 */
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));
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) */
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;
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);
if (!settings->ChannelDefArray)
goto out_fail;
+ settings->SupportMonitorLayoutPdu = TRUE;
settings->MonitorCount = 0;
settings->MonitorDefArraySize = 32;
settings->MonitorDefArray = (rdpMonitor*) calloc(settings->MonitorDefArraySize, sizeof(rdpMonitor));