[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