From f90fe19fc75924139a73715baf31ad8fdfb84a19 Mon Sep 17 00:00:00 2001 From: David Fort Date: Tue, 17 Oct 2017 14:07:23 +0200 Subject: [PATCH 1/2] multimon: correctly set the primary monitor According to the spec the primary monitor is supposed to be in (0,0) and other monitors to be given relative to this one. --- libfreerdp/core/gcc.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 87466db21..7b2a2126f 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1772,6 +1772,7 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) int i; UINT16 length; UINT32 left, top, right, bottom, flags; + INT32 baseX, baseY; rdpSettings* settings = mcs->settings; if (settings->MonitorCount > 1) @@ -1781,13 +1782,23 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs) Stream_Write_UINT32(s, 0); /* flags */ Stream_Write_UINT32(s, settings->MonitorCount); /* monitorCount */ + /* first pass to get the primary monitor coordinates (it is supposed to be + * in (0,0) */ for (i = 0; i < settings->MonitorCount; i++) { - left = settings->MonitorDefArray[i].x; - top = settings->MonitorDefArray[i].y; - right = settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width - 1; - bottom = settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height - - 1; + if (settings->MonitorDefArray[i].is_primary) + { + baseX = settings->MonitorDefArray[i].x; + baseY = settings->MonitorDefArray[i].y; + } + } + + for (i = 0; i < settings->MonitorCount; i++) + { + left = settings->MonitorDefArray[i].x - baseX; + top = settings->MonitorDefArray[i].y - baseY; + right = left + settings->MonitorDefArray[i].width - 1; + bottom = top + settings->MonitorDefArray[i].height - 1; flags = settings->MonitorDefArray[i].is_primary ? MONITOR_PRIMARY : 0; Stream_Write_UINT32(s, left); /* left */ Stream_Write_UINT32(s, top); /* top */ From 46c7097a8638f5c9b650fd3a54da510749d6a91e Mon Sep 17 00:00:00 2001 From: David Fort Date: Tue, 17 Oct 2017 14:31:11 +0200 Subject: [PATCH 2/2] multimon: flag the primary monitor according to the /monitors option The first monitor of the list is considered like the primary monitor. --- client/X11/xf_monitor.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index 31b8b0540..e1de5605d 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -115,7 +115,7 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) { int i; int nmonitors = 0; - int primaryMonitorFound = FALSE; + BOOL primaryMonitorFound = FALSE; VIRTUAL_SCREEN* vscreen; rdpSettings* settings = xfc->context.settings; int mouse_x, mouse_y, _dummy_i; @@ -233,8 +233,7 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) return TRUE; /* If single monitor fullscreen OR workarea without remote app */ - if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) - || + if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) || (settings->Workarea && !settings->RemoteApplicationMode)) { /* If no monitors were specified on the command-line then set the current monitor as active */ @@ -264,6 +263,10 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, *pMaxHeight); settings->MonitorDefArray[nmonitors].orig_screen = i; + if (i == settings->MonitorIds[0]) { + settings->MonitorDefArray[nmonitors].is_primary = TRUE; + primaryMonitorFound = TRUE; + } nmonitors++; } @@ -385,5 +388,11 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) *pMaxHeight = vscreen->area.bottom - vscreen->area.top + 1; } + /* some 2008 server freeze at logon if we announce support for monitor layout PDU with + * #monitors < 2. So let's announce it only if we have more than 1 monitor. + */ + if (settings->MonitorCount) + settings->SupportMonitorLayoutPdu = TRUE; + return TRUE; }