diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2015-02-10 14:36:37 +0000 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2016-02-29 14:04:36 -0500 |
commit | a4d8a64c4ba467964476c4a1486da698bd6aed9e (patch) | |
tree | acf496173d55c4fe40a734554a9cc98d39954143 | |
parent | 008efebda801b9b80e2ab3f2c95aeef8c82102ee (diff) |
xwin: Update to XRANDR 1.2 internal interface to ensure an output is reported by XRANDR
If using the X server internal XRANDR 1.0 interface, it seems we must
register a display size with RRRegisterSize() in order to make
RRGetInfo() call RRScanOldConfig() to generate an output and crtc for
us.
Without this, the following GDM bug means that an XDMCP session to GDM
cannot be started.
https://bugzilla.gnome.org/show_bug.cgi?id=736054
Instead, use the more recent XRANDR 1.2 internal interface to explicitly
create the output and crtc, and maintain a single mode which represents
the current display size.
Also don't emit a RRScreenSizeNotify when a RRScreenSizeSize is done
which has no effect, this seems to throw the GDM greeter into a loop...
v2: Maintain reference count for the mode we maintain more correctly, to
avoid double free causing a crash on shutdown
Connect crtc to output, so a subsequent RRSetCrtcConfig request doesn't
change anything, so we don't fail due to our lack of rrSetConfig or
rrCrtcSet hooks.
See https://cygwin.com/ml/cygwin-xfree/2015-02/msg00032.html
v3:
Raise limit on X display size from 4Kx4K to 32Kx32K
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
-rw-r--r-- | hw/xwin/winrandr.c | 92 |
1 files changed, 81 insertions, 11 deletions
diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c index c29d7b37a..1560199c1 100644 --- a/hw/xwin/winrandr.c +++ b/hw/xwin/winrandr.c @@ -34,11 +34,6 @@ #include <xwin-config.h> #endif #include "win.h" -#include "mivalidate.h" // for union _Validate used by windowstr.h - -#ifndef RANDR_12_INTERFACE -#error X server must have RandR 1.2 interface -#endif /* * Answer queries about the RandR features supported. @@ -47,17 +42,47 @@ static Bool winRandRGetInfo(ScreenPtr pScreen, Rotation * pRotations) { + rrScrPrivPtr pRRScrPriv; + RROutputPtr output; + + pRRScrPriv = rrGetScrPriv(pScreen); + output = pRRScrPriv->outputs[0]; + winDebug("winRandRGetInfo ()\n"); /* Don't support rotations */ *pRotations = RR_Rotate_0; - /* - The screen doesn't have to be limited to the actual - monitor size (we can have scrollbars :-), so what is - the upper limit? - */ - RRScreenSetSizeRange(pScreen, 0, 0, 4096, 4096); + /* Delete previous mode */ + if (output->modes[0]) + { + RRModeDestroy(output->modes[0]); + RRModeDestroy(output->crtc->mode); + } + + /* Register current mode */ + { + xRRModeInfo modeInfo; + RRModePtr mode; + char name[100]; + + memset(&modeInfo, '\0', sizeof(modeInfo)); + snprintf(name, sizeof(name), "%dx%d", pScreen->width, pScreen->height); + + modeInfo.width = pScreen->width; + modeInfo.height = pScreen->height; + modeInfo.hTotal = pScreen->width; + modeInfo.vTotal = pScreen->height; + modeInfo.dotClock = 0; + modeInfo.nameLength = strlen(name); + mode = RRModeGet(&modeInfo, name); + + output->modes[0] = mode; + output->numModes = 1; + + mode = RRModeGet(&modeInfo, name); + output->crtc->mode = mode; + } return TRUE; } @@ -74,6 +99,11 @@ winDoRandRScreenSetSize(ScreenPtr pScreen, winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; WindowPtr pRoot = pScreen->root; + /* Ignore changes which do nothing */ + if ((pScreen->width == width) && (pScreen->height == height) && + (pScreen->mmWidth == mmWidth) && (pScreen->mmHeight == mmHeight)) + return; + // Prevent screen updates while we change things around SetRootClip(pScreen, ROOT_CLIP_NONE); @@ -214,5 +244,45 @@ winRandRInit(ScreenPtr pScreen) pRRScrPriv->rrCrtcSet = NULL; pRRScrPriv->rrCrtcSetGamma = NULL; + /* Create a CRTC and an output for the screen, and hook them together */ + { + RRCrtcPtr crtc; + RROutputPtr output; + + crtc = RRCrtcCreate(pScreen, NULL); + if (!crtc) + return FALSE; + + crtc->rotations = RR_Rotate_0; + + output = RROutputCreate(pScreen, "default", 7, NULL); + if (!output) + return FALSE; + + RROutputSetCrtcs(output, &crtc, 1); + RROutputSetConnection(output, RR_Connected); + RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen)); + + output->crtc = crtc; + + /* Set crtc outputs (should use RRCrtcNotify?) */ + crtc->outputs = malloc(sizeof(RROutputPtr)); + crtc->outputs[0] = output; + crtc->numOutputs = 1; + + pRRScrPriv->primaryOutput = output; + + /* Ensure we have space for exactly one mode */ + output->modes = malloc(sizeof(RRModePtr)); + output->modes[0] = NULL; + } + + /* + The screen doesn't have to be limited to the actual + monitor size (we can have scrollbars :-), so set the + upper limit to the maximum coordinates X11 can use. + */ + RRScreenSetSizeRange(pScreen, 0, 0, 32768, 32768); + return TRUE; } |