[PATCH] xvfb: add randr support

Mike Frysinger vapier at gentoo.org
Sat Jan 12 09:55:58 PST 2013


From: Lambros Lambrou <lambroslambrou at google.com>

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=26391
Signed-off-by: Lambros Lambrou <lambroslambrou at google.com>
Signed-off-by: Mike Frysinger <vapier at gentoo.org>
---
 hw/vfb/InitOutput.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)

diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c
index 97eccfd..672842f 100644
--- a/hw/vfb/InitOutput.c
+++ b/hw/vfb/InitOutput.c
@@ -66,6 +66,7 @@ from The Open Group.
 #include "dix.h"
 #include "miline.h"
 #include "glx_extinit.h"
+#include "randrstr.h"
 
 #define VFB_DEFAULT_WIDTH      1280
 #define VFB_DEFAULT_HEIGHT     1024
@@ -785,6 +786,147 @@ vfbCloseScreen(ScreenPtr pScreen)
 }
 
 static Bool
+vfbRROutputValidateMode(ScreenPtr pScreen, RROutputPtr output, RRModePtr mode)
+{
+    rrScrPriv(pScreen);
+
+    if (pScrPriv->minWidth <= mode->mode.width &&
+        pScrPriv->maxWidth >= mode->mode.width &&
+        pScrPriv->minHeight <= mode->mode.height &&
+        pScrPriv->maxHeight >= mode->mode.height)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+static Bool
+vfbRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
+                   CARD32 mmWidth, CARD32 mmHeight)
+{
+    WindowPtr root = pScreen->root;
+    WindowPtr layer;
+    WindowPtr child;
+    BoxRec box;
+
+    pScreen->width = width;
+    pScreen->height = height;
+    pScreen->mmWidth = mmWidth;
+    pScreen->mmHeight = mmHeight;
+
+    // Resize the root window & adjust its clipping
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &root->winSize, &box, 1);
+    REGION_INIT(pScreen, &root->borderSize, &box, 1);
+    REGION_RESET(pScreen, &root->borderClip, &box);
+    root->drawable.width = pScreen->width;
+    root->drawable.height = pScreen->height;
+    REGION_BREAK(pScreen, &root->clipList);
+
+    // Update the clipping regions of all windows
+    for (child = root->firstChild; child; child = child->nextSib)
+        (*pScreen->MarkOverlappedWindows)(child, child, &layer);
+
+    if (root->firstChild)
+        (*pScreen->MarkOverlappedWindows)(root->firstChild,
+                                          root->firstChild,
+                                          NULL);
+    else
+        (*pScreen->MarkWindow)(root);
+
+    (*pScreen->ValidateTree)(root, NullWindow, VTOther);
+    (*pScreen->HandleExposures)(root);
+
+    // Reposition top-level windows to fit new root size
+    // XXX I assume this is what it does, but I'm not sure
+    ResizeChildrenWinSize(root, 0, 0, 0, 0);
+
+    // Check the pointer position
+    WindowsRestructured();
+
+    RRScreenSizeNotify(pScreen);
+    RRTellChanged(pScreen);
+
+    // Flush resulting events, etc to clients
+    FlushAllOutput();
+
+    return TRUE;
+}
+
+static Bool
+vfbRRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, int x, int y,
+             Rotation rotation, int numOutput, RROutputPtr *outputs)
+{
+    return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutput, outputs);
+}
+
+static Bool
+vfbRRGetInfo(ScreenPtr pScreen, Rotation *rotations)
+{
+    return TRUE;
+}
+
+static Bool
+vfbRandRInit(ScreenPtr pScreen)
+{
+    rrScrPrivPtr pScrPriv;
+#if RANDR_12_INTERFACE
+    RRModePtr mode;
+    RRCrtcPtr crtc;
+    RROutputPtr output;
+    xRRModeInfo modeInfo;
+    char name[64];
+#endif
+
+    if (!RRScreenInit(pScreen))
+        return FALSE;
+    pScrPriv = rrGetScrPriv(pScreen);
+    pScrPriv->rrGetInfo = vfbRRGetInfo;
+#if RANDR_12_INTERFACE
+    pScrPriv->rrCrtcSet = vfbRRCrtcSet;
+    pScrPriv->rrScreenSetSize = vfbRRScreenSetSize;
+    pScrPriv->rrOutputSetProperty = NULL;
+# if RANDR_13_INTERFACE
+    pScrPriv->rrOutputGetProperty = NULL;
+# endif
+    pScrPriv->rrOutputValidateMode = vfbRROutputValidateMode;
+    pScrPriv->rrModeDestroy = NULL;
+
+    RRScreenSetSizeRange(pScreen, 1, 1, pScreen->width, pScreen->height);
+
+    sprintf(name, "%dx%d", pScreen->width, pScreen->height);
+    memset(&modeInfo, '\0', sizeof(modeInfo));
+    modeInfo.width = pScreen->width;
+    modeInfo.height = pScreen->height;
+    modeInfo.nameLength = strlen(name);
+
+    mode = RRModeGet(&modeInfo, name);
+    if (!mode)
+        return FALSE;
+
+    crtc = RRCrtcCreate(pScreen, NULL);
+    if (!crtc)
+        return FALSE;
+
+    output = RROutputCreate(pScreen, "screen", 6, NULL);
+    if (!output)
+        return FALSE;
+    if (!RROutputSetClones(output, NULL, 0))
+        return FALSE;
+    if (!RROutputSetModes(output, &mode, 1, 0))
+        return FALSE;
+    if (!RROutputSetCrtcs(output, &crtc, 1))
+        return FALSE;
+    if (!RROutputSetConnection(output, RR_Connected))
+        return FALSE;
+    RRCrtcNotify(crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
+#endif
+    return TRUE;
+}
+
+static Bool
 vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
 {
     vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
@@ -860,6 +1002,9 @@ vfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
     if (!ret)
         return FALSE;
 
+    if (!vfbRandRInit(pScreen))
+        return FALSE;
+
     pScreen->InstallColormap = vfbInstallColormap;
     pScreen->UninstallColormap = vfbUninstallColormap;
     pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
-- 
1.8.0.2



More information about the xorg-devel mailing list