Bug 1846

Summary: xinerama gives unexpeccted results on unified walls
Product: xorg Reporter: Dale Southard <dsouth>
Component: Lib/XextAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: high CC: ajax, alan.coopersmith, dberkholz, kem, roland.mainz
Version: git   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Workaround for display walls none

Description Dale Southard 2004-11-13 21:10:19 UTC
Window managers and other clients that use the Xinerama extensions produce
unexpected results on large, "unified" display walls and projectors.  These
displays generally appear to the user as a single screen, but xinerama
aware apps treat each individual display pane as a seperate screen for
purposes of maximizaion and toolbar/control center placement.  This
in turn can cause issues with window movement.  This is most obvious
when running large Xdmx walls, but also on mutiple-input montiors:

 http://www.llnl.gov/icc/sdd/img/displaywall.shtml
 http://www.llnl.gov/icc/sdd/img/highres.shtml

We've addressed this internally by patching the Xdmx xinerama code
to add a new "+xineramawall" command-line option.  This mode is
identical to +xinerama, but does not report the underlying screens
to xinerama clients, instead reporting that xinerama is not active
and that there is only a single screen.

Since this patch is in the xinerama code, we are submitting to the dmx
project as well as X.org and XF86.  Patch for X.org is below

Index: programs/Xserver/Xserver.man
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/Xserver.man,v
retrieving revision 1.2
diff -u -r1.2 Xserver.man
--- programs/Xserver/Xserver.man        23 Apr 2004 18:44:35 -0000      1.2
+++ programs/Xserver/Xserver.man        13 Nov 2004 22:36:42 -0000
@@ -264,6 +264,9 @@
 .B [+-]xinerama
 enables(+) or disables(-) the XINERAMA extension.  The default state is
 platform and configuration specific.
+.B +xineramawall
+enables the XINERAMA extensions and forces it to report only a large
+single screen to clients.
 .SH SERVER DEPENDENT OPTIONS
 Some X servers accept the following options:
 .TP 8
Index: programs/Xserver/Xext/panoramiX.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/Xext/panoramiX.c,v
retrieving revision 1.3
diff -u -r1.3 panoramiX.c
--- programs/Xserver/Xext/panoramiX.c   30 Jun 2004 20:06:53 -0000      1.3
+++ programs/Xserver/Xext/panoramiX.c   13 Nov 2004 22:36:42 -0000
@@ -1037,7 +1037,11 @@
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    rep.state = !noPanoramiXExtension;
+    if (XineramaWall) {
+        rep.state = FALSE;
+    } else {
+        rep.state = !noPanoramiXExtension;
+    }
     if (client->swapped) {
        register int n;
        swaps (&rep.sequenceNumber, n);
@@ -1059,7 +1063,11 @@
 
     rep.type = X_Reply;
     rep.sequenceNumber = client->sequence;
-    rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
+    if (XineramaWall) {
+        rep.number = (noPanoramiXExtension) ? 0 : 1;
+    } else {
+        rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
+    }
     rep.length = rep.number * sz_XineramaScreenInfo >> 2;
     if (client->swapped) {
        register int n;
@@ -1073,12 +1081,11 @@
        xXineramaScreenInfo scratch;
        int i;
 
-       for(i = 0; i < PanoramiXNumScreens; i++) {
-           scratch.x_org  = panoramiXdataPtr[i].x;
-           scratch.y_org  = panoramiXdataPtr[i].y;
-           scratch.width  = panoramiXdataPtr[i].width;
-           scratch.height = panoramiXdataPtr[i].height;
-
+        if (XineramaWall) {
+            scratch.x_org  = 0;
+            scratch.y_org  = 0;
+            scratch.width  = PanoramiXPixWidth;
+            scratch.height = PanoramiXPixHeight;
            if(client->swapped) {
                register int n;
                swaps (&scratch.x_org, n);
@@ -1087,6 +1094,21 @@
                swaps (&scratch.height, n);
            }
            WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
+        } else {
+            for(i = 0; i < PanoramiXNumScreens; i++) {
+                scratch.x_org  = panoramiXdataPtr[i].x;
+                scratch.y_org  = panoramiXdataPtr[i].y;
+                scratch.width  = panoramiXdataPtr[i].width;
+                scratch.height = panoramiXdataPtr[i].height;
+                if(client->swapped) {
+                    register int n;
+                    swaps (&scratch.x_org, n);
+                    swaps (&scratch.y_org, n);
+                    swaps (&scratch.width, n);
+                    swaps (&scratch.height, n);
+                }
+                WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch
);
+            }
        }
     }
 
Index: programs/Xserver/hw/dmx/Xdmx.man
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/hw/dmx/Xdmx.man,v
retrieving revision 1.1
diff -u -r1.1 Xdmx.man
--- programs/Xserver/hw/dmx/Xdmx.man    30 Jun 2004 20:06:53 -0000      1.1
+++ programs/Xserver/hw/dmx/Xdmx.man    13 Nov 2004 22:36:43 -0000
@@ -43,6 +43,14 @@
 configuration.  If Xinerama is enabled (e.g., with
 .B +xinerama
 on the command line), the clients see a single large screen.
+If xineramawall is enabled with
+.B +xineramawall
+on the command line, Xinerama will be enabled and
+.I Xdmx
+will only report the single, unified screen back to the clients
+when queried though the Xinerama extensions.  This can be useful
+for forcing "xinerama-aware" window managers to treat the large
+screen as a single desktop.
 .PP
 .I Xdmx
 communicates to the back-end X servers using the standard X11 protocol,
Index: programs/Xserver/include/globals.h
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/include/globals.h,v
retrieving revision 1.5
diff -u -r1.5 globals.h
--- programs/Xserver/include/globals.h  14 Sep 2004 00:51:24 -0000      1.5
+++ programs/Xserver/include/globals.h  13 Nov 2004 22:36:45 -0000
@@ -187,6 +187,7 @@
 
 #ifdef PANORAMIX
 extern Bool noPanoramiXExtension;
+extern Bool XineramaWall;
 #endif
 
 #ifdef XINPUT
Index: programs/Xserver/os/utils.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/os/utils.c,v
retrieving revision 1.9
diff -u -r1.9 utils.c
--- programs/Xserver/os/utils.c 29 Sep 2004 04:17:44 -0000      1.9
+++ programs/Xserver/os/utils.c 13 Nov 2004 22:36:46 -0000
@@ -229,6 +229,7 @@
 #ifdef PANORAMIX
 /* Xinerama is disabled by default unless enabled via +xinerama */
 Bool noPanoramiXExtension = TRUE;
+Bool XineramaWall = FALSE;
 #endif
 #ifdef XINPUT
 Bool noXInputExtension = FALSE;
@@ -665,6 +666,7 @@
 #ifdef PANORAMIX
     ErrorF("+xinerama              Enable XINERAMA extension\n");
     ErrorF("-xinerama              Disable XINERAMA extension\n");
+    ErrorF("+xineramawall          Enable XINERAMA in single screen mode\n");
 #endif
 #ifdef SMART_SCHEDULE
     ErrorF("-dumbSched             Disable smart scheduling, enable old behavio
r\n");
@@ -1028,6 +1030,10 @@
        else if ( strcmp( argv[i], "+xinerama") == 0){
            noPanoramiXExtension = FALSE;
        }
+        else if ( strcmp( argv[i], "+xineramawall") == 0){
+            noPanoramiXExtension = FALSE;
+            XineramaWall = TRUE;
+        }
        else if ( strcmp( argv[i], "-xinerama") == 0){
            noPanoramiXExtension = TRUE;
        }
Comment 1 Kevin E. Martin 2005-02-01 14:10:01 UTC
Ideally, the window managers and applications that are Xinerama-aware should be
updated to make them to work effectively in both multi-monitor and display wall
environments.  But, that will take a while to make happen.  So, while I don't
think changing the X server is the "correct" solution, a workaround is needed
while the apps and window managers fix their code.

Thankfully, there is a simple workaround to fool Xinerama-aware clients into
thinking that the Xinerama extension is disabled, which is simpler than the one
above.  I'll attach it next.  What it does is to exploit the XineramaIsActive
library call, which all Xinerama-aware clients use to determine if Xinerama
should be used.  When this call returns FALSE, the client does not use their
special Xinerama-aware code, and falls back to the single screen case.
Comment 2 Kevin E. Martin 2005-02-01 14:11:48 UTC
Created attachment 1810 [details] [review]
Workaround for display walls
Comment 3 Dale Southard 2005-02-02 08:51:58 UTC
Kevin's patch looks good, and is less intrusive than mine.

As an additional note, I agree that the correct place to fix this is
in the client code.  We actually started down that path prior to
developing this work-around, and are continuing to push for
better xinerama handling in kwin and metacity.  Unfortunately,
it will take significantly longer than we first hoped for those
developers to add that flexibility, so a work-around like this
will be necessary for some time to come.
Comment 4 Adam Jackson 2005-06-08 19:30:27 UTC
applied to HEAD.

this patch doesn't document this flag, and i think that's a good thing, it's not
something we want people to be relying on, and the toolkits really do need to
get fixed to handle this.  if you feel strongly otherwise, feel free to reopen
with a patch ;)
Comment 5 Dale Southard 2005-06-08 20:17:56 UTC
Thanks for commit to head.  That's one less local fix we'll be carrying around.

RE documentation, I probably would argue that it should be added to the
help output in utils.c, but that's largely a matter of opinion.  The users I
work with know the flag, and the vendors we partner with have the
URL for this bug, so they can find it and apply it.  Beyond that, it depends 
on how quickly the desktop people fix their apps.  If this patch is still relevant
two years from now, I'll probably suggest making it more visible.  :-)

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.