]> source.dussan.org Git - tigervnc.git/commitdiff
Fix wrapping/unwrapping of X11 hooks
authorPierre Ossman <ossman@cendio.se>
Mon, 13 Feb 2017 12:47:37 +0000 (13:47 +0100)
committerPierre Ossman <ossman@cendio.se>
Mon, 13 Feb 2017 12:47:37 +0000 (13:47 +0100)
The functions might change so we need to also make sure we grab
the updated value after each call. Clean up the code to use the
same style as the rest of the Xorg code.

unix/xserver/hw/vnc/vncHooks.c

index 29f3f8b86cac7461f4374d441b61a45207b68c0d..ef340b359208203cc463b68b8ba590c9ec902eec 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -73,22 +73,31 @@ typedef struct _vncHooksScreenRec {
   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;
@@ -284,55 +293,28 @@ int vncHooksInit(int scrIdx)
 
   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
 
@@ -433,15 +415,16 @@ static inline Bool is_visible(DrawablePtr drawable)
 // 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
@@ -460,29 +443,29 @@ static Bool vncHooksCloseScreen(ScreenPtr pScreen_)
   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
 
@@ -502,15 +485,15 @@ static Bool vncHooksCreateGC(GCPtr pGC)
   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;
 }
@@ -526,7 +509,7 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
   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);
@@ -558,7 +541,7 @@ static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
   REGION_UNINIT(pScreen, &copied);
   REGION_UNINIT(pScreen, &screen_rgn);
 
-  SCREEN_REWRAP(CopyWindow);
+  SCREEN_EPILOGUE(CopyWindow);
 }
 
 // ClearToBackground - changed region is the given rectangle, clipped by
@@ -570,7 +553,7 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
   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;
@@ -588,7 +571,7 @@ static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
 
   REGION_UNINIT(pScreen, &reg);
 
-  SCREEN_REWRAP(ClearToBackground);
+  SCREEN_EPILOGUE(ClearToBackground);
 }
 
 #if XORG < 110
@@ -598,7 +581,7 @@ static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr pRegion)
 {
   RegionRec reg;
 
-  SCREEN_UNWRAP(pWin->drawable.pScreen, RestoreAreas);
+  SCREEN_PROLOGUE(pWin->drawable.pScreen, RestoreAreas);
 
   REGION_NULL(pScreen, &reg);
   REGION_COPY(pScreen, &reg, pRegion);
@@ -609,7 +592,7 @@ static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr pRegion)
 
   REGION_UNINIT(pScreen, &reg);
 
-  SCREEN_REWRAP(RestoreAreas);
+  SCREEN_EPILOGUE(RestoreAreas);
 
   return result;
 }
@@ -622,7 +605,7 @@ static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
 {
   Bool ret;
 
-  SCREEN_UNWRAP(pScreen_, DisplayCursor);
+  SCREEN_PROLOGUE(pScreen_, DisplayCursor);
 
   ret = (*pScreen->DisplayCursor) (pDev, pScreen, cursor);
 
@@ -707,7 +690,7 @@ static Bool vncHooksDisplayCursor(DeviceIntPtr pDev,
   }
 
 out:
-  SCREEN_REWRAP(DisplayCursor);
+  SCREEN_EPILOGUE(DisplayCursor);
 
   return ret;
 }
@@ -726,9 +709,9 @@ static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
 #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++;
@@ -743,23 +726,33 @@ static void vncHooksBlockHandler(ScreenPtr pScreen_, void * pTimeout)
 
   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;
@@ -784,15 +777,15 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
   }
 
 
-  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
@@ -849,12 +842,10 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
            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;
@@ -876,37 +867,46 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
     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;
 
@@ -917,18 +917,16 @@ static Bool vncHooksRandRScreenSetSize(ScreenPtr pScreen,
                                        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;
 
@@ -940,14 +938,14 @@ static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc,
                                  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;
@@ -968,18 +966,13 @@ static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc,
 
 #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
 
@@ -989,10 +982,10 @@ static void vncHooksValidateGC(GCPtr pGC, unsigned long changes,
   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);
 }
@@ -1043,22 +1036,21 @@ static void vncHooksCopyClip(GCPtr dst, GCPtr src) {
 #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.