[RFC] [PATCH] Call xf86ReconfigureLayout when xrandr changes screen layout

Adam Greenblatt adam.greenblatt at gmail.com
Sun Jan 4 18:24:51 PST 2015


Hi,
   I have an atypical setup that doesn't work properly using 
xorg-server-1.16.3.
I have 3 Nvidia NVS 315 cards, each card drives 2 1920x1200 monitors in 
portrait
mode, for a total of 6 screens :0.0 through :0.5.  The total effective 
resolution
is 7200 horizontal by 1920 vertical.  (I've been using this layout since 
2007 with
various versions of X and Linux -- see 
http://misc.cyclecounters.org/emacs.jpg --
I find it great for programming!)
   I'm using the Nvidia proprietary driver, version 340.65, on 64-bit 
Linux with
kernel 3.18.1.
   If I set up my xorg.conf in the obvious way:

Section "ServerLayout"
    Screen 0 "nvidia 1"
    Screen 1 "nvidia 2" rightof "nvidia 1"
    Screen 2 "nvidia 3" rightof "nvidia 2"
    Screen 3 "nvidia 4" rightof "nvidia 3"
    Screen 4 "nvidia 5" rightof "nvidia 4"
    Screen 5 "nvidia 6" rightof "nvidia 5"
    ...
EndSection

everything works fine -- but this produces a layout where each monitor 
is 1920 horizontal
by 1200 vertical, for a total resolution of 11520 horizontal by 1200 
vertical.  So I have
my .xinitrc switch everything to portrait mode:

xrandr -display :0.0 -o left
xrandr -display :0.1 -o left
xrandr -display :0.2 -o left
xrandr -display :0.3 -o left
xrandr -display :0.4 -o left
xrandr -display :0.5 -o left

   The displays all work fine, but the mouse gets stuck when moving 
between screens.
Specifically, it can only move from a lower numbered screen to a higher 
one, so it
eventually ends up stuck on the :0.5, the rightmost screen.

   Running the server under gdb, it looks like what is happening is that 
there's all
this machinery in hw/xfree86/common/xf86Cursor.c's xf86ReconfigureLayout 
() to keep
track of how the different screens adjoin.  That function is only 
getting called when
the server starts up, not when I invoke xrandr.  So xf86Cursor's idea of 
the screen
adjacency and size is incorrect once the screens have been rotated, and 
the generic code
in mipointer.c does the wrong thing, trapping the mouse as observed.

   I have a straightforward fix that is almost certainly too simple to 
use as is,
not least because it adds a new field to struct _Screen.  Please let me 
know the
proper way to go about fixing this, thanks!  Aloha,
   Adam Greenblatt adam.greenblatt at gmail.com

diff -Naur xorg-server-1.16.3-orig xorg-server-1.16.3
diff -Naur xorg-server-1.16.3-orig/hw/xfree86/common/xf86Cursor.c 
xorg-server-1.16.3/hw/xfree86/common/xf86Cursor.c
--- xorg-server-1.16.3-orig/hw/xfree86/common/xf86Cursor.c      
2014-12-09 06:39:16.000000000 -1000
+++ xorg-server-1.16.3/hw/xfree86/common/xf86Cursor.c   2015-01-04 
15:43:12.000000000 -1000
@@ -587,6 +587,14 @@
     /* need to have this set up with a config file option */
     HardEdges = FALSE;
 
+    {
+      int scr;
+      for (scr = 0; scr < xf86NumScreens; scr++)
+      {
+        xf86Screens[scr]->pScreen->ReconfigureLayout = 
xf86ReconfigureLayout;
+      }
+    }
+   
     memset(xf86ScreenLayout, 0, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
 
     screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
diff -Naur xorg-server-1.16.3-orig/include/scrnintstr.h 
xorg-server-1.16.3/include/scrnintstr.h
--- xorg-server-1.16.3-orig/include/scrnintstr.h        2014-12-09 
06:39:16.000000000 -1000
+++ xorg-server-1.16.3/include/scrnintstr.h     2015-01-04 
15:43:12.000000000 -1000
@@ -356,6 +356,8 @@
 typedef WindowPtr (*XYToWindowProcPtr)(ScreenPtr pScreen,
                                        SpritePtr pSprite, int x, int y);
 
+typedef void (*ReconfigureLayoutProcPtr) (void);
+
 typedef int (*NameWindowPixmapProcPtr)(WindowPtr, PixmapPtr, CARD32);
 
 typedef struct _Screen {
@@ -520,6 +522,7 @@
 
     ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
     XYToWindowProcPtr XYToWindow;
+    ReconfigureLayoutProcPtr ReconfigureLayout;
 } ScreenRec;
 
 static inline RegionPtr
diff -Naur xorg-server-1.16.3-orig/randr/rrscreen.c 
xorg-server-1.16.3/randr/rrscreen.c
--- xorg-server-1.16.3-orig/randr/rrscreen.c    2014-12-09 
06:39:16.000000000 -1000
+++ xorg-server-1.16.3/randr/rrscreen.c 2015-01-04 15:43:12.000000000 -1000
@@ -129,6 +129,14 @@
 RRScreenSizeNotify(ScreenPtr pScreen)
 {
     rrScrPriv(pScreen);
+
+    /*
+     * Give XF86 backends a chance to refigure their layout information
+     * so that the cursor moves between screens properly.
+     */
+    if (pScreen->ReconfigureLayout)
+      pScreen->ReconfigureLayout();
+
     /*
      * Deliver ConfigureNotify events when root changes
      * pixel size




More information about the xorg-devel mailing list