File freerdp_branch-1.0.x_provide-correct-multi-monitor-data.patch of Package freerdp1

From: Hans-Peter Jansen <hpj@urpla.net>
Subject: Provide the correct monitor data for multi monitor setups

This patch will determine the correct monitor data, if --multimon option
is given, even if a certain geometry is requested (-g with position
argument). Then, the monitor data cannot be simply forwarded, since the 
desktop window might span monitor 2 (middle) and 3 (right) of a 3 monitor
setup. In that case, the correct monitor data for a 2 monitor setup is 
assembled, and a new primary is elected. The windows desktop will notice
the two monitor setup, and act accordingly. Without this patch, windows
sees one big desktop, centering dialog exactly on the gap between both
monitors, resulting in a suboptimal user experience to say at least.

Care has been taken to keep the desktop in physical bounds, as well as 
respecting the -g workarea option by excluding the occupied areas.

Signed-off-by: Hans-Peter Jansen <hpj@urpla.net>

Index: b/cmake/ConfigOptions.cmake
===================================================================
--- a/cmake/ConfigOptions.cmake
+++ b/cmake/ConfigOptions.cmake
@@ -13,6 +13,7 @@ option(WITH_DEBUG_RFX "Print RemoteFX de
 option(WITH_DEBUG_X11 "Print X11 Client debug messages" OFF)
 option(WITH_DEBUG_X11_CLIPRDR "Print X11 clipboard redirection debug messages" OFF)
 option(WITH_DEBUG_X11_LOCAL_MOVESIZE "Print X11 Client local movesize debug messages" OFF)
+option(WITH_DEBUG_X11_MONITOR "Print X11 Monitor related debug messages" OFF)
 option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" OFF)
 option(WITH_DEBUG_XV "Print XVideo debug messages" OFF)
 option(WITH_DEBUG_SCARD "Print smartcard debug messages" OFF)
Index: b/config.h.in
===================================================================
--- a/config.h.in
+++ b/config.h.in
@@ -45,6 +45,7 @@
 #cmakedefine WITH_DEBUG_X11
 #cmakedefine WITH_DEBUG_X11_CLIPRDR
 #cmakedefine WITH_DEBUG_X11_LOCAL_MOVESIZE
+#cmakedefine WITH_DEBUG_X11_MONITOR
 #cmakedefine WITH_DEBUG_RAIL
 #cmakedefine WITH_DEBUG_XV
 #cmakedefine WITH_DEBUG_SCARD
Index: b/include/freerdp/settings.h
===================================================================
--- a/include/freerdp/settings.h
+++ b/include/freerdp/settings.h
@@ -294,7 +294,8 @@ struct rdp_settings
 	char* wm_class; /* 89 */
 	uint32 desktop_x_pos; /* 90 */
 	uint32 desktop_y_pos; /* 91 */
-	uint32 paddingD[112 - 92]; /* 92 */
+	boolean multimon; /* 92 */
+	uint32 paddingD[112 - 93]; /* 93 */
 
 	/* Internal Parameters */
 	char* home_path; /* 112 */
Index: b/libfreerdp-core/settings.c
===================================================================
--- a/libfreerdp-core/settings.c
+++ b/libfreerdp-core/settings.c
@@ -46,6 +46,7 @@ rdpSettings* settings_new(void* instance
 		settings->height = 768;
 		settings->workarea = false;
 		settings->fullscreen = false;
+		settings->multimon = false;
 		settings->grab_keyboard = true;
 		settings->decorations = true;
 		settings->rdp_version = 7;
Index: b/client/X11/xf_monitor.c
===================================================================
--- a/client/X11/xf_monitor.c
+++ b/client/X11/xf_monitor.c
@@ -33,7 +33,8 @@
 
 boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
 {
-	int i;
+	int i, nmon, primon;
+	int maxWidth, maxHeight;
 	VIRTUAL_SCREEN* vscreen;
 
 #ifdef WITH_XINERAMA
@@ -55,19 +56,34 @@ boolean xf_detect_monitors(xfInfo* xfi,
 	{
 		settings->width = WidthOfScreen(xfi->screen);
 		settings->height = HeightOfScreen(xfi->screen);	
+		maxWidth = settings->width;
+		maxHeight = settings->height;
 	}
 	else if (settings->workarea)
 	{
 		settings->width = xfi->workArea.width;
 		settings->height = xfi->workArea.height;
+		maxWidth = settings->width;
+		maxHeight = settings->height;
 	}
 	else if (settings->percent_screen)
 	{
 		settings->width = (xfi->workArea.width * settings->percent_screen) / 100;
 		settings->height = (xfi->workArea.height * settings->percent_screen) / 100;
+		maxWidth = settings->width;
+		maxHeight = settings->height;
+	}
+	else
+	{
+		maxWidth = WidthOfScreen(xfi->screen);
+		maxHeight = HeightOfScreen(xfi->screen);
 	}
 
-	if (settings->fullscreen != true && settings->workarea != true)
+	DEBUG_X11_MON("desktop: %dx%d+%d+%d (max: %dx%d)", settings->width, settings->height,
+							   settings->desktop_x_pos, settings->desktop_y_pos,
+							   maxWidth, maxHeight);
+
+	if (settings->fullscreen != true && settings->workarea != true && settings->multimon != true)
 		return true;
 
 #ifdef WITH_XINERAMA
@@ -101,27 +117,53 @@ boolean xf_detect_monitors(xfInfo* xfi,
 	}
 #endif
 
-	settings->num_monitors = vscreen->nmonitors;
-
 	for (i = 0; i < vscreen->nmonitors; i++)
-	{
-		settings->monitors[i].x = vscreen->monitors[i].area.left;
-		settings->monitors[i].y = vscreen->monitors[i].area.top;
-		settings->monitors[i].width = vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1;
-		settings->monitors[i].height = vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1;
-		settings->monitors[i].is_primary = vscreen->monitors[i].primary;
-
-		vscreen->area.left = MIN(vscreen->monitors[i].area.left, vscreen->area.left);
-		vscreen->area.right = MAX(vscreen->monitors[i].area.right, vscreen->area.right);
-		vscreen->area.top = MIN(vscreen->monitors[i].area.top, vscreen->area.top);
-		vscreen->area.bottom = MAX(vscreen->monitors[i].area.bottom, vscreen->area.bottom);
-	}
+		DEBUG_X11_MON("vscreen[%d]: %dx%d+%d+%d %s", i, vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1,
+								vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1,
+								vscreen->monitors[i].area.left, vscreen->monitors[i].area.top,
+								vscreen->monitors[i].primary ? "(primary)" : "");
+
+	vscreen->area.left = settings->desktop_x_pos;
+	vscreen->area.right = MIN(settings->desktop_x_pos + settings->width - 1, maxWidth);
+	vscreen->area.top = settings->desktop_y_pos;
+	vscreen->area.bottom = MIN(settings->desktop_y_pos + settings->height - 1, maxHeight);
+
+	DEBUG_X11_MON("area: %dx%d+%d+%d", vscreen->area.right - vscreen->area.left + 1,
+					   vscreen->area.bottom - vscreen->area.top + 1,
+					   vscreen->area.left, vscreen->area.top);
 
-	if (settings->num_monitors)
+	primon = false;
+	nmon = 0;
+	for (i = 0; i < vscreen->nmonitors; i++)
 	{
-		settings->width = vscreen->area.right - vscreen->area.left + 1;
-		settings->height = vscreen->area.bottom - vscreen->area.top + 1;
-	}
+		if (vscreen->monitors[i].area.left > vscreen->area.right ||
+		    vscreen->monitors[i].area.right < vscreen->area.left ||
+		    vscreen->monitors[i].area.top > vscreen->area.bottom ||
+		    vscreen->monitors[i].area.bottom < vscreen->area.top)
+			continue;
+
+		settings->monitors[nmon].x = vscreen->monitors[i].area.left - settings->desktop_x_pos;
+		settings->monitors[nmon].y = vscreen->monitors[i].area.top - settings->desktop_y_pos;
+		settings->monitors[nmon].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1,
+						     settings->width);
+		settings->monitors[nmon].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1,
+						      settings->height);
+		settings->monitors[nmon].is_primary = vscreen->monitors[i].primary;
+
+                primon |= vscreen->monitors[i].primary;
+                nmon++;
+        }
+
+	settings->num_monitors = nmon;
+        if (nmon && !primon)
+            settings->monitors[0].is_primary = true;
+
+        for (i = 0; i < settings->num_monitors; i++)
+                DEBUG_X11_MON("monitor[%d]: %dx%d+%d+%d %s", i, settings->monitors[i].width,
+                                                                settings->monitors[i].height,
+                                                                settings->monitors[i].x,
+                                                                settings->monitors[i].y,
+                                                                settings->monitors[i].is_primary ? "(primary)" : "");
 
 	return true;
 }
Index: b/libfreerdp-utils/args.c
===================================================================
--- a/libfreerdp-utils/args.c
+++ b/libfreerdp-utils/args.c
@@ -124,6 +124,7 @@ int freerdp_parse_args(rdpSettings* sett
 				"  --disable-full-window-drag: disables full window drag\n"
 				"  --disable-menu-animations: disables menu animations\n"
 				"  --disable-theming: disables theming\n"
+				"  --multimon: Multi-monitor setup\n"
 				"  --kbd-list: list all keyboard layout ids used by -k\n"
 				"  --no-rdp: disable Standard RDP encryption\n"
 				"  --no-tls: disable TLS encryption\n"
@@ -478,6 +479,10 @@ int freerdp_parse_args(rdpSettings* sett
 		{
 			settings->disable_theming = true;
 		}
+		else if (strcmp("--multimon", argv[index]) == 0)
+		{
+			settings->multimon = true;
+		}
 		else if (strcmp("--composition", argv[index]) == 0)
 		{
 			settings->desktop_composition = true;
Index: b/client/X11/xf_monitor.h
===================================================================
--- a/client/X11/xf_monitor.h
+++ b/client/X11/xf_monitor.h
@@ -44,4 +44,10 @@ typedef struct _VIRTUAL_SCREEN VIRTUAL_S
 
 boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings);
 
+#ifdef WITH_DEBUG_X11_MONITOR
+#define DEBUG_X11_MON(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_X11_MON(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
+#endif
+
 #endif /* __XF_MONITOR_H */
Index: b/client/X11/xfreerdp.1.xml
===================================================================
--- a/client/X11/xfreerdp.1.xml
+++ b/client/X11/xfreerdp.1.xml
@@ -333,6 +333,14 @@
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term>--multimon</term>
+        <listitem>
+          <para>
+            Enable multi monitor setup (calculates the resulting monitor geometry from a given geometry and location).
+          </para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term>--ext <replaceable class="parameter">extname</replaceable></term>
         <listitem>
           <para>
openSUSE Build Service is sponsored by