summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2009-03-18 17:22:30 +0000
committerPierre Ossman <ossman@cendio.se>2009-03-18 17:22:30 +0000
commitef27ba18353159b4e1a363e09162c04ddf9091a7 (patch)
tree554c9bfd76ba32c5c02748cbc839fe434d72953a /unix
parent8698f02b9f13f579df94ae35545b5e3bdb13b2e9 (diff)
downloadtigervnc-ef27ba18353159b4e1a363e09162c04ddf9091a7.tar.gz
tigervnc-ef27ba18353159b4e1a363e09162c04ddf9091a7.zip
Support for RandR on the server.
Based on patch by George Wright but heavily rewritten in order to dynamically reallocate the framebuffer, allowing any resize. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3688 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'unix')
-rw-r--r--unix/xserver/hw/vnc/XserverDesktop.cc40
-rw-r--r--unix/xserver/hw/vnc/XserverDesktop.h5
-rw-r--r--unix/xserver/hw/vnc/vncExtInit.cc4
-rw-r--r--unix/xserver/hw/vnc/vncExtInit.h1
-rw-r--r--unix/xserver/hw/vnc/vncHooks.cc69
-rw-r--r--unix/xserver/hw/vnc/xvnc.cc276
-rw-r--r--unix/xserver11.patch2
-rw-r--r--unix/xserver15.patch2
-rw-r--r--unix/xserver16.patch2
9 files changed, 386 insertions, 15 deletions
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index fa4172ed..cb57a6d1 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2009 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -168,12 +169,12 @@ public:
XserverDesktop::XserverDesktop(ScreenPtr pScreen_,
network::TcpListener* listener_,
network::TcpListener* httpListener_,
- const char* name, void* fbptr)
+ const char* name, void* fbptr, int stride)
: pScreen(pScreen_), deferredUpdateTimer(0), dummyTimer(0),
server(0), httpServer(0),
listener(listener_), httpListener(httpListener_),
cmap(0), deferredUpdateTimerSet(false),
- grabbing(false), ignoreHooks_(false), directFbptr(fbptr != 0),
+ grabbing(false), ignoreHooks_(false), directFbptr(true),
oldButtonMask(0),
queryConnectId(0)
{
@@ -212,18 +213,12 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_,
format.greenMax = vis->greenMask >> format.greenShift;
format.blueMax = vis->blueMask >> format.blueShift;
- width_ = pScreen->width;
- height_ = pScreen->height;
- if (fbptr)
- data = (rdr::U8*)fbptr;
- else
- data = new rdr::U8[pScreen->width * pScreen->height * (format.bpp/8)];
colourmap = this;
serverReset(pScreen);
server = new VNCServerST(name, this);
- server->setPixelBuffer(this);
+ setFramebuffer(pScreen->width, pScreen->height, fbptr, stride);
server->setQueryConnectionHandler(this);
if (httpListener)
@@ -288,6 +283,28 @@ void XserverDesktop::serverReset(ScreenPtr pScreen_)
cmap = (ColormapPtr) retval;
}
+void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride)
+{
+ width_ = w;
+ height_ = h;
+
+ if (!directFbptr) {
+ delete [] data;
+ directFbptr = true;
+ }
+
+ if (!fbptr) {
+ fbptr = new rdr::U8[w * h * (format.bpp/8)];
+ stride = w;
+ directFbptr = false;
+ }
+
+ data = (rdr::U8*)fbptr;
+ stride_ = stride;
+
+ server->setPixelBuffer(this);
+}
+
char* XserverDesktop::substitute(const char* varName)
{
if (strcmp(varName, "$$") == 0) {
@@ -839,6 +856,11 @@ void XserverDesktop::grabRegion(const rfb::Region& region)
grabbing = false;
}
+int XserverDesktop::getStride() const
+{
+ return stride_;
+}
+
void XserverDesktop::lookup(int index, int* r, int* g, int* b)
{
if ((cmap->c_class | DynamicClass) == DirectColor) {
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
index fb758470..50b7d935 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -62,11 +62,12 @@ public:
XserverDesktop(ScreenPtr pScreen, network::TcpListener* listener,
network::TcpListener* httpListener_,
- const char* name, void* fbptr);
+ const char* name, void* fbptr, int stride);
virtual ~XserverDesktop();
// methods called from X server code
void serverReset(ScreenPtr pScreen);
+ void setFramebuffer(int w, int h, void* fbptr, int stride);
void setColormap(ColormapPtr cmap);
void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef);
void bell();
@@ -106,6 +107,7 @@ public:
// rfb::PixelBuffer callbacks
virtual void grabRegion(const rfb::Region& r);
+ virtual int getStride() const;
// rfb::ColourMap callbacks
virtual void lookup(int index, int* r, int* g, int* b);
@@ -130,6 +132,7 @@ private:
network::TcpListener* listener;
network::TcpListener* httpListener;
ColormapPtr cmap;
+ int stride_;
bool deferredUpdateTimerSet;
bool grabbing;
bool ignoreHooks_;
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
index b4040d44..54e92f9a 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -80,6 +80,7 @@ static unsigned long vncExtGeneration = 0;
static bool initialised = false;
static XserverDesktop* desktop[MAXSCREENS] = { 0, };
void* vncFbptr[MAXSCREENS] = { 0, };
+int vncFbstride[MAXSCREENS];
static char* clientCutText = 0;
static int clientCutTextLen = 0;
@@ -188,7 +189,8 @@ void vncExtensionInit()
desktop[scr] = new XserverDesktop(screenInfo.screens[scr], listener,
httpListener,
desktopNameStr.buf,
- vncFbptr[scr]);
+ vncFbptr[scr],
+ vncFbstride[scr]);
vlog.info("created VNC server for screen %d", scr);
if (scr == 0 && vncInetdSock != -1 && !listener) {
diff --git a/unix/xserver/hw/vnc/vncExtInit.h b/unix/xserver/hw/vnc/vncExtInit.h
index 606666bb..af9b2ea6 100644
--- a/unix/xserver/hw/vnc/vncExtInit.h
+++ b/unix/xserver/hw/vnc/vncExtInit.h
@@ -30,6 +30,7 @@ extern void vncQueryConnect(XserverDesktop* desktop, void* opaqueId);
extern void vncClientGone(int fd);
extern void vncBell();
extern void* vncFbptr[];
+extern int vncFbstride[];
extern int vncInetdSock;
extern rfb::StringParameter httpDir;
diff --git a/unix/xserver/hw/vnc/vncHooks.cc b/unix/xserver/hw/vnc/vncHooks.cc
index 9eee2458..1ec55de5 100644
--- a/unix/xserver/hw/vnc/vncHooks.cc
+++ b/unix/xserver/hw/vnc/vncHooks.cc
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright (C) 2009 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +24,7 @@
#include <stdio.h>
#include "XserverDesktop.h"
#include "vncHooks.h"
+#include "vncExtInit.h"
extern "C" {
#define class c_class
@@ -37,6 +39,9 @@ extern "C" {
#ifdef RENDER
#include "picturestr.h"
#endif
+#ifdef RANDR
+#include "randrstr.h"
+#endif
#undef class
#undef private
@@ -74,6 +79,9 @@ typedef struct {
#ifdef RENDER
CompositeProcPtr Composite;
#endif
+#ifdef RANDR
+ RRSetConfigProcPtr RandRSetConfig;
+#endif
} vncHooksScreenRec, *vncHooksScreenPtr;
typedef struct {
@@ -122,6 +130,10 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
#endif
+#ifdef RANDR
+static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize);
+#endif
// GC "funcs"
@@ -239,6 +251,13 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop)
vncHooksScreen->Composite = ps->Composite;
}
#endif
+#ifdef RANDR
+ rrScrPrivPtr rp;
+ rp = rrGetScrPriv(pScreen);
+ if (rp) {
+ vncHooksScreen->RandRSetConfig = rp->rrSetConfig;
+ }
+#endif
pScreen->CloseScreen = vncHooksCloseScreen;
pScreen->CreateGC = vncHooksCreateGC;
@@ -254,6 +273,11 @@ Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop)
ps->Composite = vncHooksComposite;
}
#endif
+#ifdef RANDR
+ if (rp) {
+ rp->rrSetConfig = vncHooksRandRSetConfig;
+ }
+#endif
return TRUE;
}
@@ -294,6 +318,13 @@ static Bool vncHooksCloseScreen(int i, ScreenPtr pScreen_)
pScreen->StoreColors = vncHooksScreen->StoreColors;
pScreen->DisplayCursor = vncHooksScreen->DisplayCursor;
pScreen->BlockHandler = vncHooksScreen->BlockHandler;
+#ifdef RANDR
+ rrScrPrivPtr rp;
+ rp = rrGetScrPriv(pScreen);
+ if (rp) {
+ rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
+ }
+#endif
DBGPRINT((stderr,"vncHooksCloseScreen: unwrapped screen functions\n"));
@@ -498,6 +529,44 @@ void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
#endif /* RENDER */
+// RandRSetConfig - follow any framebuffer changes
+
+#ifdef RANDR
+
+static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize)
+{
+ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ Bool ret;
+ RegionRec reg;
+ BoxRec box;
+
+ rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
+ ret = (*rp->rrSetConfig)(pScreen, rotation, rate, pSize);
+ rp->rrSetConfig = vncHooksRandRSetConfig;
+
+ if (!ret)
+ return FALSE;
+
+ // Let the RFB core know of the new dimensions and framebuffer
+ vncHooksScreen->desktop->setFramebuffer(pScreen->width, pScreen->height,
+ vncFbptr[pScreen->myNum],
+ vncFbstride[pScreen->myNum]);
+
+ // Mark entire screen as changed
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &reg, &box, 1);
+
+ vncHooksScreen->desktop->add_changed(&reg);
+
+ return TRUE;
+}
+
+#endif /* RANDR */
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/unix/xserver/hw/vnc/xvnc.cc b/unix/xserver/hw/vnc/xvnc.cc
index 3349103e..514ebf7d 100644
--- a/unix/xserver/hw/vnc/xvnc.cc
+++ b/unix/xserver/hw/vnc/xvnc.cc
@@ -75,6 +75,9 @@ extern "C" {
#include "dix.h"
#include "miline.h"
#include "inputstr.h"
+#ifdef RANDR
+#include "randrstr.h"
+#endif /* RANDR */
#include <X11/keysym.h>
extern char buildtime[];
#undef class
@@ -794,6 +797,263 @@ static miPointerScreenFuncRec vfbPointerCursorFuncs = {
miPointerWarpCursor
};
+#ifdef RANDR
+
+static Bool vncRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
+ Bool gotCurrent = FALSE;
+ int i;
+
+ const int widths[] = { 1920, 1920, 1600, 1680, 1400, 1360, 1280, 1280, 1280, 1280, 1024, 800, 640 };
+ const int heights[] = { 1200, 1080, 1200, 1050, 1050, 768, 1024, 960, 800, 720, 768, 600, 480 };
+
+ for (i = 0;i < sizeof(widths)/sizeof(*widths);i++) {
+ RRScreenSizePtr pSize;
+
+ pSize = RRRegisterSize(pScreen, widths[i], heights[i],
+ pScreen->mmWidth, pScreen->mmHeight);
+ if (!pSize)
+ return FALSE;
+
+ RRRegisterRate(pScreen, pSize, 60);
+
+ if ((widths[i] == pScreen->width) && (heights[i] == pScreen->height)) {
+ RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+ gotCurrent = TRUE;
+ }
+ }
+
+ if (!gotCurrent) {
+ RRScreenSizePtr pSize;
+
+ pSize = RRRegisterSize(pScreen, pScreen->width, pScreen->height,
+ pScreen->mmWidth, pScreen->mmHeight);
+ if (!pSize)
+ return FALSE;
+
+ RRRegisterRate(pScreen, pSize, 60);
+
+ RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+ }
+
+ *rotations = RR_Rotate_0;
+
+ return TRUE;
+}
+
+/* from hw/xfree86/common/xf86Helper.c */
+
+#include "mivalidate.h"
+static void
+xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ /*
+ * Use REGION_BREAK to avoid optimizations in ValidateTree
+ * that assume the root borderClip can't change well, normally
+ * it doesn't...)
+ */
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+ if (WasViewable)
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.height = pScreen->height;
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ FlushAllOutput ();
+}
+
+static Bool vncRandRSetConfig (ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize)
+{
+ vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
+ vfbFramebufferInfo fb;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ void *pbits;
+ Bool ret;
+ int oldwidth, oldheight, oldmmWidth, oldmmHeight;
+
+ /* Prevent updates while we fiddle */
+ xf86SetRootClip(pScreen, FALSE);
+
+ /* Store current state in case we fail */
+ oldwidth = pScreen->width;
+ oldheight = pScreen->height;
+ oldmmWidth = pScreen->mmWidth;
+ oldmmHeight = pScreen->mmHeight;
+
+ /* Then set the new dimensions */
+ pScreen->width = pSize->width;
+ pScreen->height = pSize->height;
+ pScreen->mmWidth = pSize->mmWidth;
+ pScreen->mmHeight = pSize->mmHeight;
+
+ /* Allocate a new framebuffer */
+ memset(&fb, 0, sizeof(vfbFramebufferInfo));
+
+ fb.width = pScreen->width;
+ fb.height = pScreen->height;
+ fb.depth = pvfb->fb.depth;
+
+ pbits = vfbAllocateFramebufferMemory(&fb);
+ if (!pbits) {
+ /* Allocation failed. Restore old state */
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+
+ return FALSE;
+ }
+
+ /* Update root pixmap with the new dimensions and buffer */
+ ret = pScreen->ModifyPixmapHeader(rootPixmap, fb.width, fb.height,
+ -1, -1, fb.paddedBytesWidth, pbits);
+ if (!ret) {
+ /* Update failed. Free the new framebuffer and restore old state */
+ vfbFreeFramebufferMemory(&fb);
+
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+
+ return FALSE;
+ }
+
+ /* Free the old framebuffer and keep the info about the new one */
+ vfbFreeFramebufferMemory(&pvfb->fb);
+ memcpy(&pvfb->fb, &fb, sizeof(vfbFramebufferInfo));
+
+ /* Let VNC get the new framebuffer (actual update is in vncHooks.cc) */
+ vncFbptr[pScreen->myNum] = pbits;
+ vncFbstride[pScreen->myNum] = fb.paddedWidth;
+
+ /* Restore ability to update screen, now with new dimensions */
+ xf86SetRootClip(pScreen, TRUE);
+
+ return TRUE;
+}
+
+#endif
+
static Bool
vfbCloseScreen(int index, ScreenPtr pScreen)
{
@@ -825,6 +1085,7 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
pbits = vfbAllocateFramebufferMemory(&pvfb->fb);
if (!pbits) return FALSE;
vncFbptr[index] = pbits;
+ vncFbstride[index] = pvfb->fb.paddedWidth;
miSetPixmapDepths();
@@ -920,13 +1181,26 @@ vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
}
ret = fbCreateDefColormap(pScreen);
+ if (!ret) return FALSE;
miSetZeroLineBias(pScreen, pvfb->lineBias);
pvfb->closeScreen = pScreen->CloseScreen;
pScreen->CloseScreen = vfbCloseScreen;
- return ret;
+#ifdef RANDR
+ rrScrPrivPtr rp;
+
+ ret = RRScreenInit(pScreen);
+ if (!ret) return FALSE;
+
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = vncRandRGetInfo;
+ rp->rrSetConfig = vncRandRSetConfig;
+#endif
+
+
+ return TRUE;
} /* end vfbScreenInit */
diff --git a/unix/xserver11.patch b/unix/xserver11.patch
index bae1bd3d..8bcb4002 100644
--- a/unix/xserver11.patch
+++ b/unix/xserver11.patch
@@ -24,7 +24,7 @@ diff -up xserver/configure.ac.vnc xserver/configure.ac
+ dnl Xvnc DDX
+
-+ AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC"])
++ AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+ AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB"])
+
+
diff --git a/unix/xserver15.patch b/unix/xserver15.patch
index 2c2831e6..ee7f4fe2 100644
--- a/unix/xserver15.patch
+++ b/unix/xserver15.patch
@@ -22,7 +22,7 @@ diff -up xserver/configure.ac.vnc xserver/configure.ac
fi
+dnl Xvnc DDX
-+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC"])
++AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB"])
dnl Xnest DDX
diff --git a/unix/xserver16.patch b/unix/xserver16.patch
index 63c54322..0a3a93f8 100644
--- a/unix/xserver16.patch
+++ b/unix/xserver16.patch
@@ -22,7 +22,7 @@ diff -up xserver/configure.ac.vnc xserver/configure.ac
fi
+dnl Xvnc DDX
-+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC"])
++AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB"])
dnl Xnest DDX