Ok, I've updated the configure script to make the Xinerama dependency
optional.

Also, I had tried numerous times to use negative offsets for the screens
without success, but I just tried it now, and it works perfectly. Oh well.

Here's an updated patch. Any objections?

On Fri, Feb 4, 2011 at 6:22 AM, Otavio Salvador <ota...@ossystems.com.br>wrote:

> Hello Josh,
>
> First I'd like to thank you for the work on this.
>
> On Fri, Feb 4, 2011 at 03:37, Josh Nisly <free...@joshnisly.com> wrote:
> ...
> > I'm using Xinerama under X11 to determine monitor position. Is this the
> best
> > way to do it? Is it okay to depend on the Xinerama extension at compile
> > time? (If it's not enabled, we fall back to previous behavior.)
>
> It is OK however we need a way to disable xinerama dependency.
>
> > Currently, this functionality is enabled when the -f switch is used on
> the
> > commandline. Does this seem like a reasonable check?
>
> Seems OK for me.
>
> > I have no idea what I'm doing with the configure.ac library check. Can
> > someone help me?
>
> http://www.gnu.org/software/hello/manual/autoconf/Libraries.html
>
> You can use HAVE_LIBXINERAMA to enable/disable code depending on it
> been available or not.
>
> > According to MS documentation, the primary monitor must be at position
> (0,
> > 0), and all other monitors are relative to this. Since the coordinates
> are
> > specified as unsigned 32-bit ints, this implies that all monitors must be
> > the the right/bottom of the primary monitor. In practice, the official
> > Windows RDP client allows monitors left of the primary monitor. Any ideas
> on
> > how to specify this in the CS_MONITOR structure?
>
> I'd say to use an offset like:
>
> offset = -1 so it would have one monitor at left.
> ...
>
> --
> Otavio Salvador                             O.S. Systems
> E-mail: ota...@ossystems.com.br  http://www.ossystems.com.br
> Mobile: +55 53 9981-7854              http://projetos.ossystems.com.br
>
diff --git a/X11/xf_win.c b/X11/xf_win.c
index b3e3d49..ac6b158 100644
--- a/X11/xf_win.c
+++ b/X11/xf_win.c
@@ -39,6 +39,10 @@
 #include "xf_keyboard.h"
 #include "xf_win.h"
 
+#ifdef HAVE_LIBXINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
 #define MWM_HINTS_DECORATIONS   (1L << 1)
 #define PROP_MOTIF_WM_HINTS_ELEMENTS    5
 
@@ -998,6 +1002,12 @@ xf_get_pixmap_info(xfInfo * xfi)
 int
 xf_pre_connect(xfInfo * xfi)
 {
+#ifdef HAVE_LIBXINERAMA
+	XineramaScreenInfo * screen_info = NULL;
+	int ignored, ignored2;
+	int n;
+#endif
+
 	xf_assign_callbacks(xfi->inst);
 	xfi->display = XOpenDisplay(NULL);
 	if (xfi->display == NULL)
@@ -1012,10 +1022,37 @@ xf_pre_connect(xfInfo * xfi)
 	xfi->xserver_be = (ImageByteOrder(xfi->display) == MSBFirst);
 	xf_kb_inst_init(xfi);
 
+	xfi->settings->num_monitors = 0;
 	if (xfi->fullscreen)
 	{
 		xfi->settings->width = WidthOfScreen(xfi->screen);
 		xfi->settings->height = HeightOfScreen(xfi->screen);
+
+#ifdef HAVE_LIBXINERAMA
+		if (XineramaQueryExtension(xfi->display, &ignored, &ignored2))
+		{
+			if (XineramaIsActive(xfi->display))
+			{
+				screen_info = XineramaQueryScreens(xfi->display, &xfi->settings->num_monitors);
+				if (xfi->settings->num_monitors > 16)
+					xfi->settings->num_monitors = 0;
+
+				if (xfi->settings->num_monitors)
+				{
+					for (n = 0; n < xfi->settings->num_monitors; n++)
+					{
+						xfi->settings->monitors[n].x = screen_info[n].x_org;
+						xfi->settings->monitors[n].y = screen_info[n].y_org;
+						xfi->settings->monitors[n].width = screen_info[n].width;
+						xfi->settings->monitors[n].height = screen_info[n].height;
+						xfi->settings->monitors[n].is_primary = screen_info[n].x_org == 0 &&
+																screen_info[n].y_org == 0;
+					}
+				}
+				XFree(screen_info);
+			}
+		}
+#endif
 	}
 
 	return 0;
diff --git a/configure.ac b/configure.ac
index 07c136b..3c25a5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -913,6 +913,19 @@ else
 fi
 
 #
+# Xinerama
+#
+xinerama="yes"
+AM_CONDITIONAL(WITH_XINERAMA, true)
+AC_PATH_XTRA
+if test "$no_x" = "yes"; then
+	xinerama="no"
+	AM_CONDITIONAL(WITH_XINERAMA, false)
+else
+	AC_CHECK_LIB(Xinerama, XineramaIsActive)
+fi
+
+#
 # DirectFB (optionally built when --with-dfb specified)
 #
 dfb="no"
@@ -976,3 +989,4 @@ echo "Printer      : $printer"
 echo "CUnit        : $cunit"
 echo "X11          : $x11"
 echo "DirectFB     : $dfb"
+echo "Xinerama     : $xinerama"
diff --git a/include/freerdp/rdpset.h b/include/freerdp/rdpset.h
index ec06a80..aa22274 100644
--- a/include/freerdp/rdpset.h
+++ b/include/freerdp/rdpset.h
@@ -35,6 +35,15 @@ struct rdp_ext_set
 	void * data; /* plugin data */
 };
 
+struct rdp_monitor
+{
+	int x;
+	int y;
+	int width;
+	int height;
+	int is_primary;
+};
+
 struct rdp_set
 {
 	int tls;
@@ -75,6 +84,8 @@ struct rdp_set
 	int num_channels;
 	struct rdp_chan channels[16];
 	struct rdp_ext_set extensions[16];
+	int num_monitors;
+	struct rdp_monitor monitors[16];
 };
 
 #endif
diff --git a/libfreerdp/secure.c b/libfreerdp/secure.c
index 6bcdc30..007fc54 100644
--- a/libfreerdp/secure.c
+++ b/libfreerdp/secure.c
@@ -489,6 +489,32 @@ sec_out_client_cluster_data(rdpSec * sec, rdpSet * settings, STREAM s)
 	out_uint32_le(s, sec->rdp->redirect_session_id); /* RedirectedSessionID */
 }
 
+static void
+sec_out_client_monitor_data(rdpSec * sec, rdpSet * settings, STREAM s)
+{
+	int length, n;
+	if (settings->num_monitors <= 1)
+		return;
+
+	DEBUG("Setting monitor data...\n");
+	out_uint16_le(s, UDH_CS_MONITOR);	/* User Data Header type */
+
+	length = 12 + (20 * settings->num_monitors);
+	out_uint16_le(s, length);
+	out_uint32_le(s, 0); /* flags (unused) */
+	out_uint32_le(s, settings->num_monitors); /* monitorCount */
+	for (n = 0; n < settings->num_monitors; n++)
+	{
+		out_uint32_le(s, settings->monitors[n].x); /* left */
+		out_uint32_le(s, settings->monitors[n].y); /* top */
+		out_uint32_le(s, settings->monitors[n].x + 
+						 settings->monitors[n].width-1); /* right */
+		out_uint32_le(s, settings->monitors[n].y +
+						 settings->monitors[n].height-1); /* bottom */
+		out_uint32_le(s, settings->monitors[n].is_primary ? 1 : 0); /* isPrimary */
+	}
+}
+
 void
 sec_out_gcc_conference_create_request(rdpSec * sec, STREAM s)
 {
@@ -503,6 +529,7 @@ sec_out_gcc_conference_create_request(rdpSec * sec, STREAM s)
 	sec_out_client_cluster_data(sec, settings, s);
 	sec_out_client_security_data(sec, settings, s);
 	sec_out_client_network_data(sec, settings, s);
+	sec_out_client_monitor_data(sec, settings, s);
 	length = (s->p - s->data) - 23;
 	s->p = s->data;
 
------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world? 
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
Freerdp-devel mailing list
Freerdp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freerdp-devel

Reply via email to