From 8394d8c6778f504e8befd15beefc9f2fb8b105ba Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 27 Aug 2015 14:10:42 +0800 Subject: [PATCH 1/2] gcc: read and write monitor extended data. --- include/freerdp/settings.h | 26 ++++++++------- libfreerdp/core/gcc.c | 67 ++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 352a38d28..10b500cea 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -392,17 +392,6 @@ typedef struct _GLYPH_CACHE_DEFINITION GLYPH_CACHE_DEFINITION; /* Monitors */ -struct rdp_monitor -{ - INT32 x; - INT32 y; - INT32 width; - INT32 height; - UINT32 is_primary; - UINT32 orig_screen; -}; -typedef struct rdp_monitor rdpMonitor; - struct _MONITOR_DEF { INT32 left; @@ -423,6 +412,18 @@ struct _MONITOR_ATTRIBUTES }; typedef struct _MONITOR_ATTRIBUTES MONITOR_ATTRIBUTES; +struct rdp_monitor +{ + INT32 x; + INT32 y; + INT32 width; + INT32 height; + UINT32 is_primary; + UINT32 orig_screen; + MONITOR_ATTRIBUTES attributes; +}; +typedef struct rdp_monitor rdpMonitor; + /* Device Redirection */ #define RDPDR_DTYP_SERIAL 0x00000001 @@ -903,7 +904,8 @@ struct rdp_settings ALIGN64 UINT32 NumMonitorIds; /* 394 */ ALIGN64 UINT32 MonitorLocalShiftX; /*395 */ ALIGN64 UINT32 MonitorLocalShiftY; /* 396 */ - UINT64 padding0448[448 - 397]; /* 397 */ + ALIGN64 BOOL HasMonitorAttributes; /* 397 */ + UINT64 padding0448[448 - 398]; /* 398 */ /* Client Message Channel Data */ diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 542e3eeba..3604d085a 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -418,6 +418,7 @@ void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs) if (settings->UseMultimon && !settings->SpanMonitors) { gcc_write_client_monitor_data(s, mcs); + gcc_write_client_monitor_extended_data(s, mcs); } gcc_write_client_message_channel_data(s, mcs); @@ -433,6 +434,7 @@ void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs) { WLog_ERR(TAG, "Sending multi monitor information anyway (may break connectivity!)"); gcc_write_client_monitor_data(s, mcs); + gcc_write_client_monitor_extended_data(s, mcs); } else { @@ -1582,7 +1584,8 @@ BOOL gcc_read_client_monitor_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) UINT32 index; UINT32 flags; UINT32 monitorCount; - MONITOR_DEF* monitorDefArray; + UINT32 left, top, right, bottom; + rdpSettings* settings = mcs->settings; if (blockLength < 8) return FALSE; @@ -1593,20 +1596,22 @@ BOOL gcc_read_client_monitor_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (((blockLength - 8) / 20) < monitorCount) return FALSE; - monitorDefArray = (MONITOR_DEF*) calloc(monitorCount, sizeof(MONITOR_DEF)); - if (!monitorDefArray) - return FALSE; + settings->MonitorCount = monitorCount; for (index = 0; index < monitorCount; index++) { - Stream_Read_UINT32(s, monitorDefArray[index].left); /* left */ - Stream_Read_UINT32(s, monitorDefArray[index].top); /* top */ - Stream_Read_UINT32(s, monitorDefArray[index].right); /* right */ - Stream_Read_UINT32(s, monitorDefArray[index].bottom); /* bottom */ - Stream_Read_UINT32(s, monitorDefArray[index].flags); /* flags */ - } + Stream_Read_UINT32(s, left); /* left */ + Stream_Read_UINT32(s, top); /* top */ + Stream_Read_UINT32(s, right); /* right */ + Stream_Read_UINT32(s, bottom); /* bottom */ + Stream_Read_UINT32(s, flags); /* flags */ - free(monitorDefArray); + settings->MonitorDefArray[index].x = left; + settings->MonitorDefArray[index].y = top; + settings->MonitorDefArray[index].width = right - left + 1; + settings->MonitorDefArray[index].height = bottom - top + 1; + settings->MonitorDefArray[index].is_primary = (flags & MONITOR_PRIMARY); + } return TRUE; } @@ -1656,7 +1661,7 @@ BOOL gcc_read_client_monitor_extended_data(wStream* s, rdpMcs* mcs, UINT16 block UINT32 flags; UINT32 monitorCount; UINT32 monitorAttributeSize; - MONITOR_ATTRIBUTES* monitorAttributesArray; + rdpSettings* settings = mcs->settings; if (blockLength < 12) return FALSE; @@ -1671,27 +1676,47 @@ BOOL gcc_read_client_monitor_extended_data(wStream* s, rdpMcs* mcs, UINT16 block if ((blockLength - 12) / monitorAttributeSize < monitorCount) return FALSE; - monitorAttributesArray = (MONITOR_ATTRIBUTES*) calloc(monitorCount, sizeof(MONITOR_ATTRIBUTES)); - if (!monitorAttributesArray) + if (settings->MonitorCount != monitorCount) return FALSE; + settings->HasMonitorAttributes = TRUE; + for (index = 0; index < monitorCount; index++) { - Stream_Read_UINT32(s, monitorAttributesArray[index].physicalWidth); /* physicalWidth */ - Stream_Read_UINT32(s, monitorAttributesArray[index].physicalHeight); /* physicalHeight */ - Stream_Read_UINT32(s, monitorAttributesArray[index].orientation); /* orientation */ - Stream_Read_UINT32(s, monitorAttributesArray[index].desktopScaleFactor); /* desktopScaleFactor */ - Stream_Read_UINT32(s, monitorAttributesArray[index].deviceScaleFactor); /* deviceScaleFactor */ + Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.physicalWidth); /* physicalWidth */ + Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.physicalHeight); /* physicalHeight */ + Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.orientation); /* orientation */ + Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.desktopScaleFactor); /* desktopScaleFactor */ + Stream_Read_UINT32(s, settings->MonitorDefArray[index].attributes.deviceScaleFactor); /* deviceScaleFactor */ } - free(monitorAttributesArray); - return TRUE; } void gcc_write_client_monitor_extended_data(wStream* s, rdpMcs* mcs) { + int i; + UINT16 length; + rdpSettings* settings = mcs->settings; + if (settings->HasMonitorAttributes) + { + length = (20 * settings->MonitorCount) + 16; + gcc_write_user_data_header(s, CS_MONITOR_EX, length); + + Stream_Write_UINT32(s, 0); /* flags */ + Stream_Write_UINT32(s, 20); /* monitorAttributeSize */ + Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ + + for (i = 0; i < settings->MonitorCount; i++) + { + Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.physicalWidth); /* physicalWidth */ + Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.physicalHeight); /* physicalHeight */ + Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.orientation); /* orientation */ + Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.desktopScaleFactor); /* desktopScaleFactor */ + Stream_Write_UINT32(s, settings->MonitorDefArray[i].attributes.deviceScaleFactor); /* deviceScaleFactor */ + } + } } /** From 6f639c1e3434d564a0a50a4ecdc9a885921e4431 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 27 Aug 2015 16:18:22 +0800 Subject: [PATCH 2/2] gcc: read and write desktop scale settings in core data. --- include/freerdp/settings.h | 13 ++++++++++++- libfreerdp/core/gcc.c | 23 ++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 10b500cea..388551a11 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -263,6 +263,12 @@ typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS; #define PACKET_COMPR_TYPE_RDP61 0x03 #define PACKET_COMPR_TYPE_RDP8 0x04 +/* Desktop Rotation Flags */ +#define ORIENTATION_LANDSCAPE 0 +#define ORIENTATION_PORTRAIT 90 +#define ORIENTATION_LANDSCAPE_FLIPPED 180 +#define ORIENTATION_PORTRAIT_FLIPPED 270 + /* SYSTEM_TIME */ typedef struct { @@ -863,7 +869,12 @@ struct rdp_settings ALIGN64 BOOL SupportGraphicsPipeline; /* 142 */ ALIGN64 BOOL SupportDynamicTimeZone; /* 143 */ ALIGN64 BOOL SupportHeartbeatPdu; /* 144 */ - UINT64 padding0192[192 - 145]; /* 145 */ + ALIGN64 UINT32 DesktopPhysicalWidth; /* 145 */ + ALIGN64 UINT32 DesktopPhysicalHeight; /* 146 */ + ALIGN64 UINT16 DesktopOrientation; /* 147 */ + ALIGN64 UINT32 DesktopScaleFactor; /* 148 */ + ALIGN64 UINT32 DeviceScaleFactor; /* 149 */ + UINT64 padding0192[192 - 150]; /* 150 */ /* Client/Server Security Data */ ALIGN64 BOOL UseRdpSecurityLayer; /* 192 */ diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 3604d085a..18bf20b9d 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -571,11 +571,6 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) UINT16 highColorDepth = 0; UINT16 supportedColorDepths = 0; UINT32 serverSelectedProtocol = 0; - UINT32 desktopPhysicalWidth = 0; - UINT32 desktopPhysicalHeight = 0; - UINT16 desktopOrientation = 0; - UINT32 desktopScaleFactor = 0; - UINT32 deviceScaleFactor = 0; UINT16 earlyCapabilityFlags = 0; rdpSettings* settings = mcs->settings; @@ -675,27 +670,27 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 4) break; - Stream_Read_UINT32(s, desktopPhysicalWidth); /* desktopPhysicalWidth (4 bytes) */ + Stream_Read_UINT32(s, settings->DesktopPhysicalWidth); /* desktopPhysicalWidth (4 bytes) */ blockLength -= 4; if (blockLength < 4) break; - Stream_Read_UINT32(s, desktopPhysicalHeight); /* desktopPhysicalHeight (4 bytes) */ + Stream_Read_UINT32(s, settings->DesktopPhysicalHeight); /* desktopPhysicalHeight (4 bytes) */ blockLength -= 4; if (blockLength < 2) break; - Stream_Read_UINT16(s, desktopOrientation); /* desktopOrientation (2 bytes) */ + Stream_Read_UINT16(s, settings->DesktopOrientation); /* desktopOrientation (2 bytes) */ blockLength -= 2; if (blockLength < 4) break; - Stream_Read_UINT32(s, desktopScaleFactor); /* desktopScaleFactor (4 bytes) */ + Stream_Read_UINT32(s, settings->DesktopScaleFactor); /* desktopScaleFactor (4 bytes) */ blockLength -= 4; if (blockLength < 4) break; - Stream_Read_UINT32(s, deviceScaleFactor); /* deviceScaleFactor (4 bytes) */ + Stream_Read_UINT32(s, settings->DeviceScaleFactor); /* deviceScaleFactor (4 bytes) */ blockLength -= 4; if (settings->SelectedProtocol != serverSelectedProtocol) @@ -796,7 +791,7 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) int clientDigProductIdLength; rdpSettings* settings = mcs->settings; - gcc_write_user_data_header(s, CS_CORE, 216); + gcc_write_user_data_header(s, CS_CORE, 234); version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; @@ -890,6 +885,12 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT8(s, 0); /* pad1octet */ Stream_Write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ + + Stream_Write_UINT32(s, settings->DesktopPhysicalWidth); /* desktopPhysicalWidth */ + Stream_Write_UINT32(s, settings->DesktopPhysicalHeight); /* desktopPhysicalHeight */ + Stream_Write_UINT16(s, settings->DesktopOrientation); /* desktopOrientation */ + Stream_Write_UINT32(s, settings->DesktopScaleFactor); /* desktopScaleFactor */ + Stream_Write_UINT32(s, settings->DeviceScaleFactor); /* deviceScaleFactor */ } BOOL gcc_read_server_core_data(wStream* s, rdpMcs* mcs)