/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2015 Pierre Ossman for Cendio AB
+ * Copyright 2009-2017 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
GlyphsProcPtr Glyphs;
#endif
#ifdef RANDR
- RRSetConfigProcPtr RandRSetConfig;
- RRScreenSetSizeProcPtr RandRScreenSetSize;
- RRCrtcSetProcPtr RandRCrtcSet;
+ RRSetConfigProcPtr rrSetConfig;
+ RRScreenSetSizeProcPtr rrScreenSetSize;
+ RRCrtcSetProcPtr rrCrtcSet;
#endif
} vncHooksScreenRec, *vncHooksScreenPtr;
typedef struct _vncHooksGCRec {
#if XORG >= 116
- const GCFuncs *wrappedFuncs;
- const GCOps *wrappedOps;
+ const GCFuncs *funcs;
+ const GCOps *ops;
#else
- GCFuncs *wrappedFuncs;
- GCOps *wrappedOps;
+ GCFuncs *funcs;
+ GCOps *ops;
#endif
} vncHooksGCRec, *vncHooksGCPtr;
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
#if XORG < 19
static int vncHooksScreenPrivateKeyIndex;
static int vncHooksGCPrivateKeyIndex;
vncHooksScreen->ignoreHooks = 0;
- vncHooksScreen->CloseScreen = pScreen->CloseScreen;
- vncHooksScreen->CreateGC = pScreen->CreateGC;
- vncHooksScreen->CopyWindow = pScreen->CopyWindow;
- vncHooksScreen->ClearToBackground = pScreen->ClearToBackground;
+ wrap(vncHooksScreen, pScreen, CloseScreen, vncHooksCloseScreen);
+ wrap(vncHooksScreen, pScreen, CreateGC, vncHooksCreateGC);
+ wrap(vncHooksScreen, pScreen, CopyWindow, vncHooksCopyWindow);
+ wrap(vncHooksScreen, pScreen, ClearToBackground, vncHooksClearToBackground);
#if XORG < 110
- vncHooksScreen->RestoreAreas = pScreen->RestoreAreas;
+ wrap(vncHooksScreen, pScreen, RestoreAreas, vncHooksRestoreAreas);
#endif
- vncHooksScreen->DisplayCursor = pScreen->DisplayCursor;
- vncHooksScreen->BlockHandler = pScreen->BlockHandler;
+ wrap(vncHooksScreen, pScreen, DisplayCursor, vncHooksDisplayCursor);
+ wrap(vncHooksScreen, pScreen, BlockHandler, vncHooksBlockHandler);
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
if (ps) {
- vncHooksScreen->Composite = ps->Composite;
- vncHooksScreen->Glyphs = ps->Glyphs;
+ wrap(vncHooksScreen, ps, Composite, vncHooksComposite);
+ wrap(vncHooksScreen, ps, Glyphs, vncHooksGlyphs);
}
#endif
#ifdef RANDR
rp = rrGetScrPriv(pScreen);
if (rp) {
- vncHooksScreen->RandRSetConfig = rp->rrSetConfig;
- vncHooksScreen->RandRScreenSetSize = rp->rrScreenSetSize;
- vncHooksScreen->RandRCrtcSet = rp->rrCrtcSet;
- }
-#endif
-
- pScreen->CloseScreen = vncHooksCloseScreen;
- pScreen->CreateGC = vncHooksCreateGC;
- pScreen->CopyWindow = vncHooksCopyWindow;
- pScreen->ClearToBackground = vncHooksClearToBackground;
-#if XORG < 110
- pScreen->RestoreAreas = vncHooksRestoreAreas;
-#endif
- pScreen->DisplayCursor = vncHooksDisplayCursor;
- pScreen->BlockHandler = vncHooksBlockHandler;
-#ifdef RENDER
- if (ps) {
- ps->Composite = vncHooksComposite;
- ps->Glyphs = vncHooksGlyphs;
- }
-#endif
-#ifdef RANDR
- if (rp) {
- /* Some RandR callbacks are optional */
- if (rp->rrSetConfig)
- rp->rrSetConfig = vncHooksRandRSetConfig;
- if (rp->rrScreenSetSize)
- rp->rrScreenSetSize = vncHooksRandRScreenSetSize;
- if (rp->rrCrtcSet)
- rp->rrCrtcSet = vncHooksRandRCrtcSet;
+ wrap(vncHooksScreen, rp, rrSetConfig, vncHooksRandRSetConfig);
+ wrap(vncHooksScreen, rp, rrScreenSetSize, vncHooksRandRScreenSetSize);
+ wrap(vncHooksScreen, rp, rrCrtcSet, vncHooksRandRCrtcSet);
}
#endif
// screen functions
//
-// SCREEN_UNWRAP and SCREEN_REWRAP unwrap and rewrap the given screen function.
+// Unwrap and rewrap helpers
-#define SCREEN_UNWRAP(scrn,field) \
+#define SCREEN_PROLOGUE(scrn,field) \
ScreenPtr pScreen = scrn; \
vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); \
- pScreen->field = vncHooksScreen->field; \
+ unwrap(vncHooksScreen, pScreen, field); \
DBGPRINT((stderr,"vncHooks" #field " called\n"));
-#define SCREEN_REWRAP(field) pScreen->field = vncHooks##field;
+#define SCREEN_EPILOGUE(field) \
+ wrap(vncHooksScreen, pScreen, field, vncHooks##field); \
// CloseScreen - unwrap the screen functions and call the original CloseScreen
rrScrPrivPtr rp;
#endif
- SCREEN_UNWRAP(pScreen_, CloseScreen);
+ SCREEN_PROLOGUE(pScreen_, CloseScreen);
- pScreen->CreateGC = vncHooksScreen->CreateGC;
- pScreen->CopyWindow = vncHooksScreen->CopyWindow;
- pScreen->ClearToBackground = vncHooksScreen->ClearToBackground;
+ unwrap(vncHooksScreen, pScreen, CreateGC);
+ unwrap(vncHooksScreen, pScreen, CopyWindow);
+ unwrap(vncHooksScreen, pScreen, ClearToBackground);
#if XORG < 110
- pScreen->RestoreAreas = vncHooksScreen->RestoreAreas;
+ unwrap(vncHooksScreen, pScreen, RestoreAreas);
#endif
- pScreen->DisplayCursor = vncHooksScreen->DisplayCursor;
- pScreen->BlockHandler = vncHooksScreen->BlockHandler;
+ unwrap(vncHooksScreen, pScreen, DisplayCursor);
+ unwrap(vncHooksScreen, pScreen, BlockHandler);
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
if (ps) {
- ps->Composite = vncHooksScreen->Composite;
- ps->Glyphs = vncHooksScreen->Glyphs;
+ unwrap(vncHooksScreen, ps, Composite);
+ unwrap(vncHooksScreen, ps, Glyphs);
}
#endif
#ifdef RANDR
rp = rrGetScrPriv(pScreen);
if (rp) {
- rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
- rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize;
- rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet;
+ unwrap(vncHooksScreen, rp, rrSetConfig);
+ unwrap(vncHooksScreen, rp, rrScreenSetSize);
+ unwrap(vncHooksScreen, rp, rrCrtcSet);
}
#endif
vncHooksGCPtr vncHooksGC = vncHooksGCPrivate(pGC);
Bool ret;
- SCREEN_UNWRAP(pGC->pScreen, CreateGC);
+ SCREEN_PROLOGUE(pGC->pScreen, CreateGC);
ret = (*pScreen->CreateGC) (pGC);
- vncHooksGC->wrappedOps = 0;
- vncHooksGC->wrappedFuncs = pGC->funcs;
+ vncHooksGC->ops = NULL;
+ vncHooksGC->funcs = pGC->funcs;
pGC->funcs = &vncHooksGCFuncs;
- SCREEN_REWRAP(CreateGC);
+ SCREEN_EPILOGUE(CreateGC);
return ret;
}
BoxRec screen_box;
RegionRec copied, screen_rgn;
- SCREEN_UNWRAP(pWin->drawable.pScreen, CopyWindow);
+ SCREEN_PROLOGUE(pWin->drawable.pScreen, CopyWindow);
REGION_NULL(pScreen, &copied);
REGION_COPY(pScreen, &copied, pOldRegion);
REGION_UNINIT(pScreen, &copied);
REGION_UNINIT(pScreen, &screen_rgn);
- SCREEN_REWRAP(CopyWindow);
+ SCREEN_EPILOGUE(CopyWindow);
}
// ClearToBackground - changed region is the given rectangle, clipped by
BoxRec box;
RegionRec reg;
- SCREEN_UNWRAP(pWin->drawable.pScreen, ClearToBackground);
+ SCREEN_PROLOGUE(pWin->drawable.pScreen, ClearToBackground);
box.x1 = x + pWin->drawable.x;
box.y1 = y + pWin->drawable.y;
REGION_UNINIT(pScreen, ®);
- SCREEN_REWRAP(ClearToBackground);
+ SCREEN_EPILOGUE(ClearToBackground);
}
#if XORG < 110
{
RegionRec reg;
- SCREEN_UNWRAP(pWin->drawable.pScreen, RestoreAreas);
+ SCREEN_PROLOGUE(pWin->drawable.pScreen, RestoreAreas);
REGION_NULL(pScreen, ®);
REGION_COPY(pScreen, ®, pRegion);
REGION_UNINIT(pScreen, ®);
- SCREEN_REWRAP(RestoreAreas);
+ SCREEN_EPILOGUE(RestoreAreas);
return result;
}
{
Bool ret;
- SCREEN_UNWRAP(pScreen_, DisplayCursor);
+ SCREEN_PROLOGUE(pScreen_, DisplayCursor);
ret = (*pScreen->DisplayCursor) (pDev, pScreen, cursor);
}
out:
- SCREEN_REWRAP(DisplayCursor);
+ SCREEN_EPILOGUE(DisplayCursor);
return ret;
}
#endif
{
#if XORG <= 112
- SCREEN_UNWRAP(screenInfo.screens[i], BlockHandler);
+ SCREEN_PROLOGUE(screenInfo.screens[i], BlockHandler);
#else
- SCREEN_UNWRAP(pScreen_, BlockHandler);
+ SCREEN_PROLOGUE(pScreen_, BlockHandler);
#endif
vncHooksScreen->ignoreHooks++;
vncHooksScreen->ignoreHooks--;
- SCREEN_REWRAP(BlockHandler);
+ SCREEN_EPILOGUE(BlockHandler);
}
#ifdef RENDER
+// Unwrap and rewrap helpers
+
+#define RENDER_PROLOGUE(scrn,field) \
+ ScreenPtr pScreen = scrn; \
+ PictureScreenPtr ps = GetPictureScreen(pScreen); \
+ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); \
+ unwrap(vncHooksScreen, ps, field); \
+ DBGPRINT((stderr,"vncHooks" #field " called\n"));
+
+#define RENDER_EPILOGUE(field) \
+ wrap(vncHooksScreen, ps, field, vncHooks##field); \
+
// Composite - The core of XRENDER
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)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
RegionRec changed;
+ RENDER_PROLOGUE(pDst->pDrawable->pScreen, Composite);
+
if (is_visible(pDst->pDrawable)) {
BoxRec box;
RegionRec fbreg;
}
- ps->Composite = vncHooksScreen->Composite;
(*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
- ps->Composite = vncHooksComposite;
if (REGION_NOTEMPTY(pScreen, &changed))
add_changed(pScreen, &changed);
REGION_UNINIT(pScreen, &changed);
+
+ RENDER_EPILOGUE(Composite);
}
static int
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists,
GlyphListPtr lists, GlyphPtr * glyphs)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
RegionPtr changed;
+ RENDER_PROLOGUE(pDst->pDrawable->pScreen, Glyphs);
+
if (is_visible(pDst->pDrawable)) {
BoxRec fbbox;
RegionRec fbreg;
changed = REGION_CREATE(pScreen, NullBox, 0);
}
- ps->Glyphs = vncHooksScreen->Glyphs;
(*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
- ps->Glyphs = vncHooksGlyphs;
if (REGION_NOTEMPTY(pScreen, changed))
add_changed(pScreen, changed);
REGION_DESTROY(pScreen, changed);
+
+ RENDER_EPILOGUE(Glyphs);
}
#endif /* RENDER */
-// RandRSetConfig - follow any framebuffer changes
-
#ifdef RANDR
+// Unwrap and rewrap helpers
+
+#define RANDR_PROLOGUE(field) \
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen); \
+ vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen); \
+ unwrap(vncHooksScreen, rp, rr##field); \
+ DBGPRINT((stderr,"vncHooksRandR" #field " called\n"));
+
+#define RANDR_EPILOGUE(field) \
+ wrap(vncHooksScreen, rp, rr##field, vncHooksRandR##field); \
+
+// RandRSetConfig - follow any framebuffer changes
+
static Bool vncHooksRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
int rate, RRScreenSizePtr pSize)
{
- vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
Bool ret;
- vncPreScreenResize(pScreen->myNum);
+ RANDR_PROLOGUE(SetConfig);
- rp->rrSetConfig = vncHooksScreen->RandRSetConfig;
+ vncPreScreenResize(pScreen->myNum);
ret = (*rp->rrSetConfig)(pScreen, rotation, rate, pSize);
- rp->rrSetConfig = vncHooksRandRSetConfig;
-
vncPostScreenResize(pScreen->myNum, ret, pScreen->width, pScreen->height);
+ RANDR_EPILOGUE(SetConfig);
+
if (!ret)
return FALSE;
CARD16 width, CARD16 height,
CARD32 mmWidth, CARD32 mmHeight)
{
- vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
Bool ret;
- vncPreScreenResize(pScreen->myNum);
+ RANDR_PROLOGUE(ScreenSetSize);
- rp->rrScreenSetSize = vncHooksScreen->RandRScreenSetSize;
+ vncPreScreenResize(pScreen->myNum);
ret = (*rp->rrScreenSetSize)(pScreen, width, height, mmWidth, mmHeight);
- rp->rrScreenSetSize = vncHooksRandRScreenSetSize;
-
vncPostScreenResize(pScreen->myNum, ret, pScreen->width, pScreen->height);
+ RANDR_EPILOGUE(ScreenSetSize);
+
if (!ret)
return FALSE;
Rotation rotation, int num_outputs,
RROutputPtr *outputs)
{
- vncHooksScreenPtr vncHooksScreen = vncHooksScreenPrivate(pScreen);
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
Bool ret;
- rp->rrCrtcSet = vncHooksScreen->RandRCrtcSet;
+ RANDR_PROLOGUE(CrtcSet);
+
ret = (*rp->rrCrtcSet)(pScreen, crtc, mode, x, y, rotation,
num_outputs, outputs);
- rp->rrCrtcSet = vncHooksRandRCrtcSet;
+
+ RANDR_EPILOGUE(CrtcSet);
if (!ret)
return FALSE;
#define GC_FUNC_PROLOGUE(pGC, name)\
vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
- (pGC)->funcs = pGCPriv->wrappedFuncs;\
- if(pGCPriv->wrappedOps)\
- (pGC)->ops = pGCPriv->wrappedOps; \
+ unwrap(pGCPriv, pGC, funcs);\
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)\
DBGPRINT((stderr,"vncHooks" #name " called\n"))
#define GC_FUNC_EPILOGUE(pGC)\
- pGCPriv->wrappedFuncs = (pGC)->funcs;\
- (pGC)->funcs = &vncHooksGCFuncs;\
- if(pGCPriv->wrappedOps) {\
- pGCPriv->wrappedOps = (pGC)->ops;\
- (pGC)->ops = &vncHooksGCOps;\
- }
+ wrap(pGCPriv, pGC, funcs, &vncHooksGCFuncs);\
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &vncHooksGCOps)
// ValidateGC - wrap the "ops" if the drawable is on screen
GC_FUNC_PROLOGUE(pGC, ValidateGC);
(*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
if (is_visible(pDrawable)) {
- pGCPriv->wrappedOps = pGC->ops;
+ pGCPriv->ops = pGC->ops;
DBGPRINT((stderr,"vncHooksValidateGC: wrapped GC ops\n"));
} else {
- pGCPriv->wrappedOps = NULL;
+ pGCPriv->ops = NULL;
}
GC_FUNC_EPILOGUE(pGC);
}
#define GC_OP_PROLOGUE(pGC, name)\
vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
const GCFuncs *oldFuncs = pGC->funcs;\
- pGC->funcs = pGCPriv->wrappedFuncs;\
- pGC->ops = pGCPriv->wrappedOps; \
+ unwrap(pGCPriv, pGC, funcs);\
+ unwrap(pGCPriv, pGC, ops);\
DBGPRINT((stderr,"vncHooks" #name " called\n"))
#else
#define GC_OP_PROLOGUE(pGC, name)\
vncHooksGCPtr pGCPriv = vncHooksGCPrivate(pGC);\
GCFuncs *oldFuncs = pGC->funcs;\
- pGC->funcs = pGCPriv->wrappedFuncs;\
- pGC->ops = pGCPriv->wrappedOps; \
+ unwrap(pGCPriv, pGC, funcs);\
+ unwrap(pGCPriv, pGC, ops);\
DBGPRINT((stderr,"vncHooks" #name " called\n"))
#endif
#define GC_OP_EPILOGUE(pGC)\
- pGCPriv->wrappedOps = pGC->ops;\
- pGC->funcs = oldFuncs;\
- pGC->ops = &vncHooksGCOps
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &vncHooksGCOps)
// FillSpans - assume the entire clip region is damaged. This is pessimistic,
// but I believe this function is rarely used so it doesn't matter.