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