[PATCH 11/13] gc: Move GC funcs vector to the ScreenRec

Adam Jackson ajax at redhat.com
Tue Nov 23 11:45:46 PST 2010


The only plausible reason to want per-GC funcs wrapping is if, in the
process of executing one of the GC funcs, you would need to create
another GC to do it.  If you have that problem you are doing something
very very very wrong.  Don't.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 Xext/panoramiX.c                       |   81 +++++++++++++------------------
 dix/gc.c                               |   17 +++---
 exa/exa.c                              |   73 ++-------------------------
 exa/exa_priv.h                         |    4 +-
 fb/fb.h                                |    3 +-
 fb/fbgc.c                              |   10 +---
 fb/fbscreen.c                          |    4 ++
 fb/wfbrename.h                         |    1 -
 hw/dmx/dmx.h                           |    4 ++
 hw/dmx/dmxgc.c                         |   43 ++--------------
 hw/dmx/dmxgc.h                         |   24 +--------
 hw/dmx/dmxscrinit.c                    |    4 ++
 hw/dmx/dmxwindow.h                     |   17 ------
 hw/xfree86/common/xf86VGAarbiter.c     |   48 ------------------
 hw/xfree86/common/xf86VGAarbiterPriv.h |   13 +----
 hw/xfree86/shadowfb/shadow.c           |   76 ++++++-----------------------
 hw/xfree86/xaa/xaa.h                   |    6 --
 hw/xfree86/xaa/xaaGC.c                 |   59 ++++++-----------------
 hw/xfree86/xaa/xaaGCmisc.c             |   40 +++------------
 hw/xfree86/xaa/xaaInit.c               |   12 +++-
 hw/xfree86/xaa/xaaStateChange.c        |   40 ++++++++--------
 hw/xfree86/xaa/xaalocal.h              |   58 ++++++----------------
 hw/xfree86/xaa/xaawrap.h               |   17 ++-----
 hw/xnest/GC.c                          |   14 +----
 hw/xnest/Screen.c                      |    4 ++
 hw/xnest/XNGC.h                        |    6 +-
 hw/xwin/win.h                          |    6 ++
 hw/xwin/wingc.c                        |   73 +--------------------------
 hw/xwin/winscrinit.c                   |    4 ++
 include/gcstruct.h                     |   24 ---------
 include/scrnintstr.h                   |   12 +++++
 mi/migc.c                              |    4 +-
 mi/migc.h                              |    4 +-
 miext/cw/cw.c                          |   84 +++++++++++---------------------
 miext/cw/cw.h                          |    3 +-
 miext/cw/cw_ops.c                      |    5 --
 miext/damage/damage.c                  |   62 +++++-------------------
 miext/damage/damagestr.h               |    2 +-
 miext/rootless/rootlessCommon.h        |    2 +-
 miext/rootless/rootlessGC.c            |   64 ++++--------------------
 miext/rootless/rootlessScreen.c        |    3 +
 41 files changed, 256 insertions(+), 774 deletions(-)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 8dc3d8f..821eaf9 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -111,31 +111,31 @@ static DevPrivateKeyRec PanoramiXScreenKeyRec;
 typedef struct {
   DDXPointRec clipOrg;
   DDXPointRec patOrg;
-  GCFuncs *wrapFuncs;
 } PanoramiXGCRec, *PanoramiXGCPtr;
 
 typedef struct {
   CreateGCProcPtr	CreateGC;
+  ValidateGCProcPtr     ValidateGC;
+  ChangeGCProcPtr       ChangeGC;
+  CopyGCProcPtr         CopyGC;
+  DestroyGCProcPtr      DestroyGC;
   CloseScreenProcPtr	CloseScreen;
 } PanoramiXScreenRec, *PanoramiXScreenPtr;
 
-static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void XineramaChangeGC(GCPtr, unsigned long);
-static void XineramaCopyGC(GCPtr, unsigned long, GCPtr);
-static void XineramaDestroyGC(GCPtr);
+static void XineramaValidateGC(GCPtr, unsigned, DrawablePtr);
+static void XineramaChangeGC(GCPtr, unsigned);
+static void XineramaCopyGC(GCPtr, unsigned, GCPtr);
 
-static GCFuncs XineramaGCFuncs = {
-    XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC,
-};
-
-#define Xinerama_GC_FUNC_PROLOGUE(pGC)\
+#define Xinerama_GC_FUNC_PROLOGUE(pGC, func)\
     PanoramiXGCPtr  pGCPriv = (PanoramiXGCPtr) \
 	dixLookupPrivate(&(pGC)->devPrivates, PanoramiXGCKey); \
-    (pGC)->funcs = pGCPriv->wrapFuncs;
+    PanoramiXScreenPtr pScreenPriv = \
+        dixLookupPrivate(&(pGC)->pScreen->devPrivates, PanoramiXScreenKey); \
+    (pGC)->pScreen->func = pScreenPriv->func;
 
-#define Xinerama_GC_FUNC_EPILOGUE(pGC)\
-    pGCPriv->wrapFuncs = (pGC)->funcs;\
-    (pGC)->funcs = &XineramaGCFuncs;
+#define Xinerama_GC_FUNC_EPILOGUE(pGC, func)\
+    pScreenPriv->func = (pGC)->pScreen->func; \
+    (pGC)->pScreen->func = Xinerama##func;
 
 
 static Bool
@@ -168,9 +168,6 @@ XineramaCreateGC(GCPtr pGC)
 	PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr)
 	    dixLookupPrivate(&pGC->devPrivates, PanoramiXGCKey);
 
-	pGCPriv->wrapFuncs = pGC->funcs;
-        pGC->funcs = &XineramaGCFuncs;
-
 	pGCPriv->clipOrg.x = pGC->clipOrg.x; 
 	pGCPriv->clipOrg.y = pGC->clipOrg.y;
 	pGCPriv->patOrg.x = pGC->patOrg.x;
@@ -182,12 +179,9 @@ XineramaCreateGC(GCPtr pGC)
 }
 
 static void
-XineramaValidateGC(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw 
-){
-    Xinerama_GC_FUNC_PROLOGUE (pGC);
+XineramaValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
+{
+    Xinerama_GC_FUNC_PROLOGUE (pGC, ValidateGC);
 
     if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) {
 	/* the root window */
@@ -234,24 +228,14 @@ XineramaValidateGC(
 	}
     }
   
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
-    Xinerama_GC_FUNC_EPILOGUE (pGC);
+    pGC->pScreen->ValidateGC(pGC, changes, pDraw);
+    Xinerama_GC_FUNC_EPILOGUE (pGC, ValidateGC);
 }
 
 static void
-XineramaDestroyGC(GCPtr pGC)
+XineramaChangeGC (GCPtr pGC, unsigned mask)
 {
-    Xinerama_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->DestroyGC)(pGC);
-    Xinerama_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XineramaChangeGC (
-    GCPtr	    pGC,
-    unsigned long   mask
-){
-    Xinerama_GC_FUNC_PROLOGUE (pGC);
+    Xinerama_GC_FUNC_PROLOGUE (pGC, ChangeGC);
 
     if(mask & GCTileStipXOrigin)
 	pGCPriv->patOrg.x = pGC->patOrg.x;
@@ -262,19 +246,16 @@ XineramaChangeGC (
     if(mask & GCClipYOrigin)
 	pGCPriv->clipOrg.y = pGC->clipOrg.y;
 
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    Xinerama_GC_FUNC_EPILOGUE (pGC);
+    pGC->pScreen->ChangeGC (pGC, mask);
+    Xinerama_GC_FUNC_EPILOGUE (pGC, ChangeGC);
 }
 
 static void
-XineramaCopyGC (
-    GCPtr	    pGCSrc, 
-    unsigned long   mask,
-    GCPtr	    pGCDst
-){
+XineramaCopyGC (GCPtr pGCSrc, unsigned mask, GCPtr pGCDst)
+{
     PanoramiXGCPtr pSrcPriv = (PanoramiXGCPtr)
 	dixLookupPrivate(&pGCSrc->devPrivates, PanoramiXGCKey);
-    Xinerama_GC_FUNC_PROLOGUE (pGCDst);
+    Xinerama_GC_FUNC_PROLOGUE (pGCDst, CopyGC);
 
     if(mask & GCTileStipXOrigin)
         pGCPriv->patOrg.x = pSrcPriv->patOrg.x;
@@ -285,8 +266,8 @@ XineramaCopyGC (
     if(mask & GCClipYOrigin)
         pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y;
 
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    Xinerama_GC_FUNC_EPILOGUE (pGCDst);
+    pGCDst->pScreen->CopyGC (pGCSrc, mask, pGCDst);
+    Xinerama_GC_FUNC_EPILOGUE (pGCDst, CopyGC);
 }
 
 int
@@ -451,9 +432,15 @@ void PanoramiXExtensionInit(int argc, char *argv[])
 	   }
 	
 	   pScreenPriv->CreateGC = pScreen->CreateGC;
+           pScreenPriv->ValidateGC = pScreen->ValidateGC;
+           pScreenPriv->ChangeGC = pScreen->ChangeGC;
+           pScreenPriv->CopyGC = pScreen->CopyGC;
 	   pScreenPriv->CloseScreen = pScreen->CloseScreen;
 	
 	   pScreen->CreateGC = XineramaCreateGC;
+           pScreen->ValidateGC = XineramaValidateGC;
+           pScreen->ChangeGC = XineramaChangeGC;
+           pScreen->CopyGC = XineramaCopyGC;
 	   pScreen->CloseScreen = XineramaCloseScreen;
 	}
 
diff --git a/dix/gc.c b/dix/gc.c
index 8339374..81d3b3f 100644
--- a/dix/gc.c
+++ b/dix/gc.c
@@ -76,7 +76,7 @@ static unsigned char DefaultDash[2] = {4, 4};
 void
 ValidateGC(DrawablePtr pDraw, GC *pGC)
 {
-    (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
+    pGC->pScreen->ValidateGC (pGC, pGC->stateChanges, pDraw);
     pGC->stateChanges = 0;
     pGC->serialNumber = pDraw->serialNumber;
 }
@@ -476,7 +476,7 @@ ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
 	    error = BadAlloc;
 	}
     }
-    (*pGC->funcs->ChangeGC)(pGC, maskQ);
+    pGC->pScreen->ChangeGC(pGC, maskQ);
     return error;
 }
 
@@ -555,7 +555,6 @@ CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus,
     pGC->alu = GXcopy; /* dst <- src */
     pGC->planemask = ~0;
     pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
-    pGC->funcs = 0;
     pGC->fgPixel = 0;
     pGC->bgPixel = 1;
     pGC->lineWidth = 0;
@@ -821,7 +820,7 @@ CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
 	    error = BadAlloc;
 	}
     }
-    (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
+    pgcDst->pScreen->CopyGC(pgcSrc, maskQ, pgcDst);
     return error;
 }
 
@@ -843,7 +842,7 @@ FreeGC(pointer value, XID gid)
     if (pGC->stipple)
 	(* pGC->pScreen->DestroyPixmap)(pGC->stipple);
 
-    (*pGC->funcs->DestroyGC) (pGC);
+    pGC->pScreen->DestroyGC(pGC);
     if (pGC->dash != DefaultDash)
 	free(pGC->dash);
     dixFreeObjectWithPrivates(pGC, PRIVATE_GC);
@@ -1062,8 +1061,8 @@ SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
     pGC->stateChanges |= GCDashList;
     maskQ |= GCDashList;
 
-    if (pGC->funcs->ChangeGC)
-	(*pGC->funcs->ChangeGC) (pGC, maskQ);
+    if (pGC->pScreen->ChangeGC)
+	pGC->pScreen->ChangeGC(pGC, maskQ);
     return Success;
 }
 
@@ -1142,8 +1141,8 @@ SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
     if (size)
 	memmove((char *)prectsNew, (char *)prects, size);
     ChangeClip(pGC, newct, prectsNew, nrects);
-    if (pGC->funcs->ChangeGC)
-	(*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+    if (pGC->pScreen->ChangeGC)
+	pGC->pScreen->ChangeGC(pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
     return Success;
 }
 
diff --git a/exa/exa.c b/exa/exa.c
index 780aa25..5d01dd9 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -463,33 +463,7 @@ exaDestroyPixmap(PixmapPtr pPixmap)
  */
 
 static void
-exaValidateGC(GCPtr pGC,
-		unsigned long changes,
-		DrawablePtr pDrawable);
-
-static void
-exaDestroyGC(GCPtr pGC);
-
-static void
-exaChangeGC (GCPtr pGC,
-		unsigned long mask);
-
-static void
-exaCopyGC (GCPtr pGCSrc,
-	      unsigned long mask,
-	      GCPtr	 pGCDst);
-
-const GCFuncs exaGCFuncs = {
-    exaValidateGC,
-    exaChangeGC,
-    exaCopyGC,
-    exaDestroyGC,
-};
-
-static void
-exaValidateGC(GCPtr pGC,
-		unsigned long changes,
-		DrawablePtr pDrawable)
+exaValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
     /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
      * Do a few smart things so fbValidateGC can do it's work.
@@ -497,7 +471,6 @@ exaValidateGC(GCPtr pGC,
 
     ScreenPtr pScreen = pDrawable->pScreen;
     ExaScreenPriv(pScreen);
-    ExaGCPriv(pGC);
     PixmapPtr pTile = NULL;
     Bool finish_current_tile = FALSE;
 
@@ -527,9 +500,9 @@ exaValidateGC(GCPtr pGC,
 
     /* Calls to Create/DestroyPixmap have to be identified as special. */
     pExaScr->fallback_counter++;
-    swap(pExaGC, pGC, funcs);
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
-    swap(pExaGC, pGC, funcs);
+    swap(pExaScr, pScreen, ValidateGC);
+    pGC->pScreen->ValidateGC(pGC, changes, pDrawable);
+    swap(pExaScr, pScreen, ValidateGC);
     pExaScr->fallback_counter--;
 
     if (pTile)
@@ -540,41 +513,6 @@ exaValidateGC(GCPtr pGC,
 	exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
 }
 
-/* Is exaPrepareAccessGC() needed? */
-static void
-exaDestroyGC(GCPtr pGC)
-{
-    ExaGCPriv(pGC);
-    swap(pExaGC, pGC, funcs);
-    (*pGC->funcs->DestroyGC)(pGC);
-    swap(pExaGC, pGC, funcs);
-}
-
-static void
-exaChangeGC (GCPtr pGC,
-		unsigned long mask)
-{
-    ExaGCPriv(pGC);
-    swap(pExaGC, pGC, funcs);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    swap(pExaGC, pGC, funcs);
-}
-
-static void
-exaCopyGC (GCPtr pGCSrc,
-	      unsigned long mask,
-	      GCPtr	 pGCDst)
-{
-    ExaGCPriv(pGCDst);
-    swap(pExaGC, pGCDst, funcs);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    swap(pExaGC, pGCDst, funcs);
-}
-
-/**
- * exaCreateGC makes a new GC and hooks up its funcs handler, so that
- * exaValidateGC() will get called.
- */
 static int
 exaCreateGC (GCPtr pGC)
 {
@@ -585,7 +523,6 @@ exaCreateGC (GCPtr pGC)
 
     swap(pExaScr, pScreen, CreateGC);
     if ((ret = (*pScreen->CreateGC) (pGC))) {
-	wrap(pExaGC, pGC, funcs, (GCFuncs *) &exaGCFuncs);
 	wrap(pExaGC, pGC, ops, (GCOps *) &exaOps);
     }
     swap(pExaScr, pScreen, CreateGC);
@@ -734,6 +671,7 @@ exaCloseScreen(int i, ScreenPtr pScreen)
     if (pScreen->WakeupHandler == ExaWakeupHandler)
 	unwrap(pExaScr, pScreen, WakeupHandler);
     unwrap(pExaScr, pScreen, CreateGC);
+    unwrap(pExaScr, pScreen, ValidateGC);
     unwrap(pExaScr, pScreen, CloseScreen);
     unwrap(pExaScr, pScreen, GetImage);
     unwrap(pExaScr, pScreen, GetSpans);
@@ -899,6 +837,7 @@ exaDriverInit (ScreenPtr		pScreen,
 	!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
 	wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
     wrap(pExaScr, pScreen, CreateGC, exaCreateGC);
+    wrap(pExaScr, pScreen, ValidateGC, exaValidateGC);
     wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
     wrap(pExaScr, pScreen, GetImage, exaGetImage);
     wrap(pExaScr, pScreen, GetSpans, ExaCheckGetSpans);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 8b3a4c5..563924f 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -153,6 +153,7 @@ typedef struct {
     ScreenBlockHandlerProcPtr	 SavedBlockHandler;
     ScreenWakeupHandlerProcPtr	 SavedWakeupHandler;
     CreateGCProcPtr 		 SavedCreateGC;
+    ValidateGCProcPtr            SavedValidateGC;
     CloseScreenProcPtr 		 SavedCloseScreen;
     GetImageProcPtr 		 SavedGetImage;
     GetSpansProcPtr 		 SavedGetSpans;
@@ -333,7 +334,6 @@ typedef struct {
 typedef struct {
     /* GC values from the layer below. */
     GCOps *Savedops;
-    GCFuncs *Savedfuncs;
 } ExaGCPrivRec, *ExaGCPrivPtr;
 
 typedef struct {
@@ -583,8 +583,6 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
 Bool
 exaPixmapIsPinned (PixmapPtr pPix);
 
-extern const GCFuncs exaGCFuncs;
-
 /* exa_classic.c */
 PixmapPtr
 exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
diff --git a/fb/fb.h b/fb/fb.h
index 021a940..3f0fb5d 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -610,7 +610,6 @@ extern _X_EXPORT DevPrivateKey
 fbGetWinPrivateKey (void);
 
 extern _X_EXPORT const GCOps	fbGCOps;
-extern _X_EXPORT const GCFuncs	fbGCFuncs;
 
 #ifdef FB_24_32BIT
 #define FB_SCREEN_PRIVATE
@@ -1477,7 +1476,7 @@ extern _X_EXPORT void
 fbPadPixmap (PixmapPtr pPixmap);
     
 extern _X_EXPORT void
-fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+fbValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable);
 
 /*
  * fbgetsp.c
diff --git a/fb/fbgc.c b/fb/fbgc.c
index 1db3771..2b8c7ef 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -28,13 +28,6 @@
 
 #include "fb.h"
 
-const GCFuncs fbGCFuncs = {
-    fbValidateGC,
-    miChangeGC,
-    miCopyGC,
-    miDestroyGC,
-};
-
 const GCOps	fbGCOps = {
     fbFillSpans,
     fbSetSpans,
@@ -62,7 +55,6 @@ Bool
 fbCreateGC(GCPtr pGC)
 {
     pGC->ops = (GCOps *) &fbGCOps;
-    pGC->funcs = (GCFuncs *) &fbGCFuncs;
 
     /* fb wants to translate before scan conversion */
     pGC->miTranslate = 1;
@@ -185,7 +177,7 @@ fbCanEvenStipple (PixmapPtr pStipple, int bpp)
 }
 
 void
-fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+fbValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
     FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
     FbBits	mask;
diff --git a/fb/fbscreen.c b/fb/fbscreen.c
index 2502efe..300ddf0 100644
--- a/fb/fbscreen.c
+++ b/fb/fbscreen.c
@@ -121,6 +121,10 @@ fbSetupScreen(ScreenPtr	pScreen,
     pScreen->RealizeFont = fbRealizeFont;
     pScreen->UnrealizeFont = fbUnrealizeFont;
     pScreen->CreateGC = fbCreateGC;
+    pScreen->ValidateGC = fbValidateGC;
+    pScreen->ChangeGC = miChangeGC;
+    pScreen->CopyGC = miCopyGC;
+    pScreen->DestroyGC = miDestroyGC;
     pScreen->CreateColormap = fbInitializeColormap;
     pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
     pScreen->InstallColormap = fbInstallColormap;
diff --git a/fb/wfbrename.h b/fb/wfbrename.h
index e855edd..54dd626 100644
--- a/fb/wfbrename.h
+++ b/fb/wfbrename.h
@@ -67,7 +67,6 @@
 #define fbFillRegionSolid wfbFillRegionSolid
 #define fbFillSpans wfbFillSpans
 #define fbFixCoordModePrevious wfbFixCoordModePrevious
-#define fbGCFuncs wfbGCFuncs
 #define fbGCOps wfbGCOps
 #define fbGCPrivateKeyRec wfbGCPrivateKeyRec
 #define fbGeneration wfbGeneration
diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h
index bf4b92c..f7d8943 100644
--- a/hw/dmx/dmx.h
+++ b/hw/dmx/dmx.h
@@ -198,6 +198,10 @@ typedef struct _DMXScreenInfo {
     SaveScreenProcPtr              SaveScreen;
 
     CreateGCProcPtr                CreateGC;
+    ValidateGCProcPtr              ValidateGC;
+    CopyGCProcPtr                  CopyGC;
+    ChangeGCProcPtr                ChangeGC;
+    DestroyGCProcPtr               DestroyGC;
 
     CreateWindowProcPtr            CreateWindow;
     DestroyWindowProcPtr           DestroyWindow;
diff --git a/hw/dmx/dmxgc.c b/hw/dmx/dmxgc.c
index ae615be..099b45e 100644
--- a/hw/dmx/dmxgc.c
+++ b/hw/dmx/dmxgc.c
@@ -49,13 +49,6 @@
 #include "pixmapstr.h"
 #include "migc.h"
 
-static GCFuncs dmxGCFuncs = {
-    dmxValidateGC,
-    dmxChangeGC,
-    dmxCopyGC,
-    dmxDestroyGC,
-};
-
 static GCOps dmxGCOps = {
     dmxFillSpans,
     dmxSetSpans,
@@ -123,10 +116,8 @@ Bool dmxCreateGC(GCPtr pGC)
     DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
     if ((ret = pScreen->CreateGC(pGC))) {
 	/* Save the old funcs */
-	pGCPriv->funcs = pGC->funcs;
-	pGCPriv->ops   = NULL;
-
-	pGC->funcs = &dmxGCFuncs;
+	pGCPriv->ops    = pGC->ops;
+        pGC->ops        = &dmxGCOps;
 
 	if (dmxScreen->beDisplay) {
 	    dmxBECreateGC(pScreen, pGC);
@@ -147,15 +138,10 @@ Bool dmxCreateGC(GCPtr pGC)
 
 /** Validate a graphics context, \a pGC, locally in the DMX server and
  *  recompute the composite clip, if necessary. */
-void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+void dmxValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
     dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
 
-    DMX_GC_FUNC_PROLOGUE(pGC);
-#if 0
-    pGC->funcs->ValidateGC(pGC, changes, pDrawable);
-#endif
-
     if (pDrawable->type == DRAWABLE_WINDOW ||
 	pDrawable->type == DRAWABLE_PIXMAP) {
 	/* Save the old ops, since we're about to change the ops in the
@@ -178,24 +164,17 @@ void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 	 (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
 	miComputeCompositeClip(pGC, pDrawable);
     }
-
-    DMX_GC_FUNC_EPILOGUE(pGC);
 }
 
 /** Set the values in the graphics context on the back-end server
  *  associated with \a pGC's screen. */
-void dmxChangeGC(GCPtr pGC, unsigned long mask)
+void dmxChangeGC(GCPtr pGC, unsigned mask)
 {
     ScreenPtr      pScreen = pGC->pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
     dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
     XGCValues      v;
 
-    DMX_GC_FUNC_PROLOGUE(pGC);
-#if 0
-    pGC->funcs->ChangeGC(pGC, mask);
-#endif
-
     /* Handle "magic special case" from CreateGC */
     if (pGCPriv->msc) {
 	/* The "magic special case" is used to handle the case where a
@@ -282,27 +261,20 @@ void dmxChangeGC(GCPtr pGC, unsigned long mask)
 	XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
 	dmxSync(dmxScreen, FALSE);
     }
-
-    DMX_GC_FUNC_EPILOGUE(pGC);
 }
 
 /** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
  *  \a pGCSrc's screen. */
-void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
+void dmxCopyGC(GCPtr pGCSrc, unsigned changes, GCPtr pGCDst)
 {
     ScreenPtr      pScreen = pGCSrc->pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
     dmxGCPrivPtr   pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
     dmxGCPrivPtr   pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
 
-    DMX_GC_FUNC_PROLOGUE(pGCDst);
-    pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
-
     /* Copy the GC on the back-end server */
     if (dmxScreen->beDisplay)
 	XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
-
-    DMX_GC_FUNC_EPILOGUE(pGCDst);
 }
 
 /** Free the \a pGC on the back-end server. */
@@ -328,12 +300,7 @@ void dmxDestroyGC(GCPtr pGC)
     ScreenPtr      pScreen   = pGC->pScreen;
     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
 
-    DMX_GC_FUNC_PROLOGUE(pGC);
-
     /* Free the GC on the back-end server */
     if (dmxScreen->beDisplay)
 	dmxBEFreeGC(pGC);
-
-    pGC->funcs->DestroyGC(pGC);
-    DMX_GC_FUNC_EPILOGUE(pGC);
 }
diff --git a/hw/dmx/dmxgc.h b/hw/dmx/dmxgc.h
index 4ff3cd8..b4f4725 100644
--- a/hw/dmx/dmxgc.h
+++ b/hw/dmx/dmxgc.h
@@ -42,7 +42,6 @@
 /** GC private area. */
 typedef struct _dmxGCPriv {
     GCOps   *ops;
-    GCFuncs *funcs;
     XlibGC   gc;
     Bool     msc;
 } dmxGCPrivRec, *dmxGCPrivPtr;
@@ -51,10 +50,9 @@ typedef struct _dmxGCPriv {
 extern Bool dmxInitGC(ScreenPtr pScreen);
 
 extern Bool dmxCreateGC(GCPtr pGC);
-extern void dmxValidateGC(GCPtr pGC, unsigned long changes,
-			  DrawablePtr pDrawable);
-extern void dmxChangeGC(GCPtr pGC, unsigned long mask);
-extern void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst);
+extern void dmxValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable);
+extern void dmxChangeGC(GCPtr pGC, unsigned mask);
+extern void dmxCopyGC(GCPtr pGCSrc, unsigned changes, GCPtr pGCDst);
 extern void dmxDestroyGC(GCPtr pGC);
 extern void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
 extern void dmxDestroyClip(GCPtr pGC);
@@ -67,20 +65,4 @@ extern Bool dmxBEFreeGC(GCPtr pGC);
 #define DMX_GET_GC_PRIV(_pGC)						\
     (dmxGCPrivPtr)dixLookupPrivate(&(_pGC)->devPrivates, dmxGCPrivateKey)
 
-#define DMX_GC_FUNC_PROLOGUE(_pGC)					\
-do {									\
-    dmxGCPrivPtr _pGCPriv = DMX_GET_GC_PRIV(_pGC);			\
-    DMX_UNWRAP(funcs, _pGCPriv, (_pGC));				\
-    if (_pGCPriv->ops)							\
-	DMX_UNWRAP(ops, _pGCPriv, (_pGC));				\
-} while (0)
-
-#define DMX_GC_FUNC_EPILOGUE(_pGC)					\
-do {									\
-    dmxGCPrivPtr _pGCPriv = DMX_GET_GC_PRIV(_pGC);			\
-    DMX_WRAP(funcs, &dmxGCFuncs, _pGCPriv, (_pGC));			\
-    if (_pGCPriv->ops)							\
-	DMX_WRAP(ops, &dmxGCOps, _pGCPriv, (_pGC));			\
-} while (0)
-
 #endif /* DMXGC_H */
diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
index 7a94627..3b6295d 100644
--- a/hw/dmx/dmxscrinit.c
+++ b/hw/dmx/dmxscrinit.c
@@ -306,6 +306,10 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
     if (!dmxShadowFB) {
 	/* Wrap GC functions */
 	DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
+	DMX_WRAP(ValidateGC, dmxValidateGC, dmxScreen, pScreen);
+	DMX_WRAP(CopyGC, dmxCopyGC, dmxScreen, pScreen);
+	DMX_WRAP(ChangeGC, dmxChangeGC, dmxScreen, pScreen);
+	DMX_WRAP(DestroyGC, dmxDestroyGC, dmxScreen, pScreen);
 
 	/* Wrap Window functions */
 	DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
diff --git a/hw/dmx/dmxwindow.h b/hw/dmx/dmxwindow.h
index f93121e..2553db5 100644
--- a/hw/dmx/dmxwindow.h
+++ b/hw/dmx/dmxwindow.h
@@ -100,23 +100,6 @@ extern void dmxSetShape(WindowPtr pWindow, int kind);
 #define DMX_GET_WINDOW_PRIV(_pWin) ((dmxWinPrivPtr) \
     dixLookupPrivate(&(_pWin)->devPrivates, dmxWinPrivateKey))
 
-/* All of these macros are only used in dmxwindow.c */
-#define DMX_WINDOW_FUNC_PROLOGUE(_pGC)					\
-do {									\
-    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(_pGC);			\
-    DMX_UNWRAP(funcs, pGCPriv, (_pGC));					\
-    if (pGCPriv->ops)							\
-	DMX_UNWRAP(ops, pGCPriv, (_pGC));				\
-} while (0)
-
-#define DMX_WINDOW_FUNC_EPILOGUE(_pGC)					\
-do {									\
-    dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(_pGC);			\
-    DMX_WRAP(funcs, &dmxGCFuncs, pGCPriv, (_pGC));			\
-    if (pGCPriv->ops)							\
-	DMX_WRAP(ops, &dmxGCOps, pGCPriv, (_pGC));			\
-} while (0)
-
 #define DMX_WINDOW_X1(_pWin)						\
     ((_pWin)->drawable.x - wBorderWidth(_pWin))
 #define DMX_WINDOW_Y1(_pWin)						\
diff --git a/hw/xfree86/common/xf86VGAarbiter.c b/hw/xfree86/common/xf86VGAarbiter.c
index 78e9120..64dc276 100644
--- a/hw/xfree86/common/xf86VGAarbiter.c
+++ b/hw/xfree86/common/xf86VGAarbiter.c
@@ -38,12 +38,6 @@
 #include "xf86Priv.h"
 #include "pciaccess.h"
 
-
-static GCFuncs VGAarbiterGCFuncs = {
-    VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
-    VGAarbiterDestroyGC,
-};
-
 static GCOps VGAarbiterGCOps = {
     VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
     VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
@@ -579,48 +573,6 @@ VGAarbiterCreateGC(GCPtr pGC)
     return ret;
 }
 
-/* GC funcs */
-static void
-VGAarbiterValidateGC(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
-{
-    GC_UNWRAP(pGC);
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
-    GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterDestroyGC(GCPtr pGC)
-{
-    GC_UNWRAP (pGC);
-    (*pGC->funcs->DestroyGC)(pGC);
-    GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterChangeGC (
-    GCPtr       pGC,
-    unsigned long   mask)
-{
-    GC_UNWRAP (pGC);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterCopyGC (
-    GCPtr       pGCSrc,
-    unsigned long   mask,
-    GCPtr       pGCDst)
-{
-    GC_UNWRAP (pGCDst);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    GC_WRAP (pGCDst);
-}
-
 /* GC Ops */
 static void
 VGAarbiterFillSpans(
diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h
index 927bb69..7bc1ab6 100644
--- a/hw/xfree86/common/xf86VGAarbiterPriv.h
+++ b/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -86,12 +86,11 @@
 #define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite
 
 #define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\
-    pGCPriv->wrapFuncs = (x)->funcs; (x)->ops = &VGAarbiterGCOps;\
-    (x)->funcs = &VGAarbiterGCFuncs;
+    (x)->ops = &VGAarbiterGCOps;\
 
 #define GC_UNWRAP(x) VGAarbiterGCPtr  pGCPriv = \
     (VGAarbiterGCPtr)dixLookupPrivate(&(x)->devPrivates, VGAarbiterGCKey);\
-    (x)->ops = pGCPriv->wrapOps; (x)->funcs = pGCPriv->wrapFuncs;
+    (x)->ops = pGCPriv->wrapOps;
 
 static inline void
 VGAGet(ScreenPtr pScreen) {
@@ -137,7 +136,6 @@ typedef struct _VGAarbiterScreen {
 
 typedef struct _VGAarbiterGC {
     GCOps                       *wrapOps;
-    GCFuncs                     *wrapFuncs;
 } VGAarbiterGCRec, *VGAarbiterGCPtr;
 
 /* Screen funcs */
@@ -176,13 +174,6 @@ static Bool VGAarbiterEnterVT(int index, int flags);
 static void VGAarbiterLeaveVT(int index, int flags);
 static void VGAarbiterFreeScreen(int index, int flags);
 
-/* GC funcs */
-static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes,
-    DrawablePtr pDraw);
-static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask);
-static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void VGAarbiterDestroyGC(GCPtr pGC);
-
 /* GC ops */
 static void VGAarbiterFillSpans( DrawablePtr pDraw, GC *pGC, int nInit,
     DDXPointPtr pptInit, int *pwidthInit, int fSorted);
diff --git a/hw/xfree86/shadowfb/shadow.c b/hw/xfree86/shadowfb/shadow.c
index 499bbc3..314eb26 100644
--- a/hw/xfree86/shadowfb/shadow.c
+++ b/hw/xfree86/shadowfb/shadow.c
@@ -36,6 +36,7 @@ static void ShadowCopyWindow(
     RegionPtr prgn 
 );
 static Bool ShadowCreateGC(GCPtr pGC);
+static void ShadowValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 static Bool ShadowEnterVT(int index, int flags);
 static void ShadowLeaveVT(int index, int flags);
@@ -63,6 +64,7 @@ typedef struct {
   CloseScreenProcPtr			CloseScreen;
   CopyWindowProcPtr			CopyWindow;
   CreateGCProcPtr			CreateGC;
+  ValidateGCProcPtr                     ValidateGC;
   ModifyPixmapHeaderProcPtr		ModifyPixmapHeader;
   CompositeProcPtr Composite;
   Bool				(*EnterVT)(int, int);
@@ -72,7 +74,6 @@ typedef struct {
 
 typedef struct {
    GCOps   *ops;
-   GCFuncs *funcs;
 } ShadowGCRec, *ShadowGCPtr;
 
 static DevPrivateKeyRec ShadowScreenKeyRec;
@@ -86,15 +87,16 @@ static DevPrivateKeyRec ShadowGCKeyRec;
 #define GET_GC_PRIVATE(pGC) \
     (ShadowGCPtr)dixLookupPrivate(&(pGC)->devPrivates, ShadowGCKey)
 
-#define SHADOW_GC_FUNC_PROLOGUE(pGC)\
+#define SHADOW_GC_FUNC_PROLOGUE(pGC, func)\
+    ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
     ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
-    (pGC)->funcs = pGCPriv->funcs;\
+    (pGC)->pScreen->func = pPriv->func; \
     if(pGCPriv->ops)\
         (pGC)->ops = pGCPriv->ops
 
-#define SHADOW_GC_FUNC_EPILOGUE(pGC)\
-    pGCPriv->funcs = (pGC)->funcs;\
-    (pGC)->funcs = &ShadowGCFuncs;\
+#define SHADOW_GC_FUNC_EPILOGUE(pGC, func)\
+    pPriv->func = (pGC)->pScreen->func; \
+    (pGC)->pScreen->func = Shadow##func; \
     if(pGCPriv->ops) {\
         pGCPriv->ops = (pGC)->ops;\
         (pGC)->ops = &ShadowGCOps;\
@@ -103,14 +105,11 @@ static DevPrivateKeyRec ShadowGCKeyRec;
 #define SHADOW_GC_OP_PROLOGUE(pGC)\
     ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
     ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
-    GCFuncs *oldFuncs = pGC->funcs;\
-    pGC->funcs = pGCPriv->funcs;\
     pGC->ops = pGCPriv->ops
 
     
 #define SHADOW_GC_OP_EPILOGUE(pGC)\
     pGCPriv->ops = pGC->ops;\
-    pGC->funcs = oldFuncs;\
     pGC->ops   = &ShadowGCOps
 
 #define IS_VISIBLE(pWin) (pPriv->vtSema && \
@@ -172,6 +171,7 @@ ShadowFBInit2 (
     pPriv->CloseScreen = pScreen->CloseScreen;
     pPriv->CopyWindow = pScreen->CopyWindow;
     pPriv->CreateGC = pScreen->CreateGC;
+    pPriv->ValidateGC = pScreen->ValidateGC;
     pPriv->ModifyPixmapHeader = pScreen->ModifyPixmapHeader;
 
     pPriv->EnterVT = pScrn->EnterVT;
@@ -180,6 +180,7 @@ ShadowFBInit2 (
     pScreen->CloseScreen = ShadowCloseScreen;
     pScreen->CopyWindow = ShadowCopyWindow;
     pScreen->CreateGC = ShadowCreateGC;
+    pScreen->ValidateGC = ShadowValidateGC;
 
     pScrn->EnterVT = ShadowEnterVT;
     pScrn->LeaveVT = ShadowLeaveVT;
@@ -248,6 +249,7 @@ ShadowCloseScreen (int i, ScreenPtr pScreen)
     pScreen->CloseScreen = pPriv->CloseScreen;
     pScreen->CopyWindow = pPriv->CopyWindow;
     pScreen->CreateGC = pPriv->CreateGC;
+    pScreen->ValidateGC = pPriv->ValidateGC;
     pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
 
     pScrn->EnterVT = pPriv->EnterVT;
@@ -355,16 +357,6 @@ ShadowComposite(
 
 /**********************************************************/
 
-static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void ShadowChangeGC(GCPtr, unsigned long);
-static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
-static void ShadowDestroyGC(GCPtr);
-
-GCFuncs ShadowGCFuncs = {
-    ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC,
-};
-
-
 extern GCOps ShadowGCOps;
 
 static Bool
@@ -378,58 +370,22 @@ ShadowCreateGC(GCPtr pGC)
     pScreen->CreateGC = pPriv->CreateGC;
     if((ret = (*pScreen->CreateGC) (pGC))) {
 	pGCPriv->ops = NULL;
-	pGCPriv->funcs = pGC->funcs;
-	pGC->funcs = &ShadowGCFuncs;
     }
     pScreen->CreateGC = ShadowCreateGC;
 
     return ret;
 }
 
-
 static void
-ShadowValidateGC(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw 
-){
-    SHADOW_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ShadowValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
+{
+    SHADOW_GC_FUNC_PROLOGUE (pGC, ValidateGC);
+    pGC->pScreen->ValidateGC(pGC, changes, pDraw);
     if(pDraw->type == DRAWABLE_WINDOW)
 	pGCPriv->ops = pGC->ops;  /* just so it's not NULL */
     else 
 	pGCPriv->ops = NULL;
-    SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-
-static void
-ShadowDestroyGC(GCPtr pGC)
-{
-    SHADOW_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->DestroyGC)(pGC);
-    SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-ShadowChangeGC (
-    GCPtr	    pGC,
-    unsigned long   mask
-){
-    SHADOW_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-ShadowCopyGC (
-    GCPtr	    pGCSrc, 
-    unsigned long   mask,
-    GCPtr	    pGCDst
-){
-    SHADOW_GC_FUNC_PROLOGUE (pGCDst);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    SHADOW_GC_FUNC_EPILOGUE (pGCDst);
+    SHADOW_GC_FUNC_EPILOGUE (pGC, ValidateGC);
 }
 
 /**********************************************************/
diff --git a/hw/xfree86/xaa/xaa.h b/hw/xfree86/xaa/xaa.h
index 40b49e5..c2ba307 100644
--- a/hw/xfree86/xaa/xaa.h
+++ b/hw/xfree86/xaa/xaa.h
@@ -205,12 +205,6 @@
 
 #define XAA_RENDER_REPEAT		0x00000001
 
-typedef void (* ValidateGCProcPtr)(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
-
 typedef struct {
     unsigned char *bits;
     int width;
diff --git a/hw/xfree86/xaa/xaaGC.c b/hw/xfree86/xaa/xaaGC.c
index 74eefb1..6f90e72 100644
--- a/hw/xfree86/xaa/xaaGC.c
+++ b/hw/xfree86/xaa/xaaGC.c
@@ -19,15 +19,6 @@
 #include "pixmapstr.h"
 #include "xaawrap.h"
 
-static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
-static void XAAChangeGC(GCPtr pGC, unsigned long mask);
-static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void XAADestroyGC(GCPtr pGC);
-
-GCFuncs XAAGCFuncs = {
-    XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
-};
-
 extern GCOps XAAPixmapOps;
 
 Bool
@@ -42,9 +33,7 @@ XAACreateGC(GCPtr pGC)
 
     if((ret = (*pScreen->CreateGC)(pGC))) {	
 	pGCPriv->wrapOps = NULL;
-	pGCPriv->wrapFuncs = pGC->funcs;
 	pGCPriv->XAAOps = &XAAFallbackOps;
-	pGC->funcs = &XAAGCFuncs;
     }
  
     XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);
@@ -53,16 +42,13 @@ XAACreateGC(GCPtr pGC)
 }
 
 
-static void
-XAAValidateGC(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw 
-){
+void
+XAAValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
+{
     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-    XAA_GC_FUNC_PROLOGUE(pGC);
+    XAA_GC_FUNC_PROLOGUE(pGC, ValidateGC);
 
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+    pGC->pScreen->ValidateGC(pGC, changes, pDraw);
 
     if((changes & GCPlaneMask) &&
        ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) == 
@@ -126,7 +112,7 @@ XAAValidateGC(
 #endif
     }
 
-    XAA_GC_FUNC_EPILOGUE(pGC);
+    XAA_GC_FUNC_EPILOGUE(pGC, ValidateGC);
 
     if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;
 
@@ -225,30 +211,26 @@ XAAValidateGC(
 	(*infoRec->ValidatePushPixels)(pGC, changes, pDraw); 	
 }
 
-
-static void
+void
 XAADestroyGC(GCPtr pGC)
 {
-    XAA_GC_FUNC_PROLOGUE (pGC);
+    XAA_GC_FUNC_PROLOGUE (pGC, DestroyGC);
      
     if(pGCPriv->XAAOps != &XAAFallbackOps)
 	free(pGCPriv->XAAOps);
 
     free(pGCPriv->DashPattern);
 
-    (*pGC->funcs->DestroyGC)(pGC);
-    XAA_GC_FUNC_EPILOGUE (pGC);
+    pGC->pScreen->DestroyGC(pGC);
+    XAA_GC_FUNC_EPILOGUE (pGC, DestroyGC);
 }
 
-static void
-XAAChangeGC (
-    GCPtr	    pGC,
-    unsigned long   mask
-)
+void
+XAAChangeGC (GCPtr pGC, unsigned mask)
 {
-    XAA_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    XAA_GC_FUNC_EPILOGUE (pGC);
+    XAA_GC_FUNC_PROLOGUE (pGC, ChangeGC);
+    pGC->pScreen->ChangeGC(pGC, mask);
+    XAA_GC_FUNC_EPILOGUE (pGC, ChangeGC);
 
    /* we have to assume that shared memory pixmaps are dirty 
       because we can't wrap all operations on them */
@@ -266,17 +248,6 @@ XAAChangeGC (
     }
 }
 
-static void
-XAACopyGC (
-    GCPtr	    pGCSrc, 
-    unsigned long   mask,
-    GCPtr	    pGCDst)
-{
-    XAA_GC_FUNC_PROLOGUE (pGCDst);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    XAA_GC_FUNC_EPILOGUE (pGCDst);
-}
- 
 /**** Pixmap Wrappers ****/
 
 static void
diff --git a/hw/xfree86/xaa/xaaGCmisc.c b/hw/xfree86/xaa/xaaGCmisc.c
index 5823cc0..cd6aa0c 100644
--- a/hw/xfree86/xaa/xaaGCmisc.c
+++ b/hw/xfree86/xaa/xaaGCmisc.c
@@ -20,10 +20,7 @@
 #include "pixmapstr.h"
 
 void
-XAAValidateCopyArea(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidateCopyArea(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
@@ -38,10 +35,7 @@ XAAValidateCopyArea(
 }
 
 void
-XAAValidatePutImage(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidatePutImage(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
@@ -57,10 +51,7 @@ XAAValidatePutImage(
 }
 
 void
-XAAValidateCopyPlane(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidateCopyPlane(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
@@ -76,10 +67,7 @@ XAAValidateCopyPlane(
 }
 
 void
-XAAValidatePushPixels(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidatePushPixels(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
@@ -107,10 +95,7 @@ XAAValidatePushPixels(
 
 
 void
-XAAValidateFillSpans(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidateFillSpans(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
 
@@ -183,10 +168,7 @@ XAAValidateFillSpans(
    this assumption */
 
 void
-XAAValidatePolyGlyphBlt(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidatePolyGlyphBlt(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    Bool BigFont = FALSE;
@@ -238,10 +220,7 @@ XAAValidatePolyGlyphBlt(
 }
 
 void
-XAAValidateImageGlyphBlt(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidateImageGlyphBlt(GCPtr pGC, unsigned changes,DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    Bool BigFont = FALSE;
@@ -299,10 +278,7 @@ XAAValidateImageGlyphBlt(
 
 
 void
-XAAValidatePolylines(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw )
+XAAValidatePolylines(GCPtr pGC, unsigned changes, DrawablePtr pDraw)
 {
    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
    XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
diff --git a/hw/xfree86/xaa/xaaInit.c b/hw/xfree86/xaa/xaaInit.c
index 11443a6..6a7ca71 100644
--- a/hw/xfree86/xaa/xaaInit.c
+++ b/hw/xfree86/xaa/xaaInit.c
@@ -137,7 +137,6 @@ XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
     pScreenPriv->AccelInfoRec = infoRec;
     infoRec->ScratchGC.pScreen = pScreen;
 
-    
     if(!infoRec->GetImage)
 	infoRec->GetImage = XAAGetImage;
     if(!infoRec->GetSpans)
@@ -147,6 +146,12 @@ XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
 
     pScreenPriv->CreateGC = pScreen->CreateGC;
     pScreen->CreateGC = XAACreateGC;
+    pScreenPriv->ValidateGC = pScreen->ValidateGC;
+    pScreen->ValidateGC = XAAValidateGC;
+    pScreenPriv->ChangeGC = pScreen->ChangeGC;
+    pScreen->ChangeGC = XAAChangeGC;
+    pScreenPriv->DestroyGC = pScreen->DestroyGC;
+    pScreen->DestroyGC = XAADestroyGC;
     pScreenPriv->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = XAACloseScreen;
     pScreenPriv->GetImage = pScreen->GetImage;
@@ -204,8 +209,6 @@ XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
     return TRUE;
 }
 
-
-
 static Bool
 XAACloseScreen (int i, ScreenPtr pScreen)
 {
@@ -218,6 +221,9 @@ XAACloseScreen (int i, ScreenPtr pScreen)
     pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
    
     pScreen->CreateGC = pScreenPriv->CreateGC;
+    pScreen->ValidateGC = pScreenPriv->ValidateGC;
+    pScreen->ChangeGC = pScreenPriv->ChangeGC;
+    pScreen->DestroyGC = pScreenPriv->DestroyGC;
     pScreen->CloseScreen = pScreenPriv->CloseScreen;
     pScreen->GetImage = pScreenPriv->GetImage;
     pScreen->GetSpans = pScreenPriv->GetSpans;
diff --git a/hw/xfree86/xaa/xaaStateChange.c b/hw/xfree86/xaa/xaaStateChange.c
index 189441d..6b74063 100644
--- a/hw/xfree86/xaa/xaaStateChange.c
+++ b/hw/xfree86/xaa/xaaStateChange.c
@@ -1084,7 +1084,7 @@ static void XAAStateWrapPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x,
 			   w, h, leftPad, format, pImage);
 }
 
-static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned changes, 
 					  DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1094,7 +1094,7 @@ static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned long changes,
 				    pDraw);
 }
 
-static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned changes, 
 					 DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1104,7 +1104,7 @@ static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned long changes,
 				   pDraw);
 }
 
-static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned changes,
 					 DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1114,7 +1114,7 @@ static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned long changes,
 				   pDraw);
 }
 
-static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned changes,
 					 DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1124,7 +1124,7 @@ static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned long changes,
 				   pDraw);
 }
 
-static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned changes,
 					  DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1134,7 +1134,7 @@ static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned long changes,
 				    pDraw);
 }
 
-static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned changes, 
 					  DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1144,7 +1144,7 @@ static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned long changes,
 				    pDraw);
 }
 
-static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned changes,
 					  DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1154,7 +1154,7 @@ static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned long changes,
 				    pDraw);
 }
 
-static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned changes, 
 					    DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1164,7 +1164,7 @@ static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned long changes,
 				      pDraw);
 }
 
-static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned changes, 
 					      DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1174,7 +1174,7 @@ static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned long changes,
 					pDraw);
 }
 
-static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned changes,
 					DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1184,7 +1184,7 @@ static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned long changes,
 				  pDraw);
 }
 
-static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned changes,
 					    DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1194,7 +1194,7 @@ static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned long changes,
 				      pDraw);
 }
 
-static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned changes,
 					     DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1204,7 +1204,7 @@ static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned long changes,
 				       pDraw);
 }
 
-static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned changes,
 					    DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1214,7 +1214,7 @@ static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned long changes,
 				      pDraw);
 }
 
-static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned changes,
 					  DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1224,7 +1224,7 @@ static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned long changes,
 				    pDraw);
 }
 
-static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned changes, 
 					   DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1234,7 +1234,7 @@ static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned long changes,
 				     pDraw);
 }
 
-static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned changes, 
 					   DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1244,7 +1244,7 @@ static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned long changes,
 				     pDraw);
 }
 
-static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned changes, 
 					    DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1254,7 +1254,7 @@ static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned long changes,
 				      pDraw);
 }
 
-static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned changes, 
 					     DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1264,7 +1264,7 @@ static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes,
 				       pDraw);
 }
 
-static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned long changes, 
+static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned changes, 
 					      DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
@@ -1273,7 +1273,7 @@ static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned long changes,
 					pDraw);
 }
 
-static void XAAStateWrapValidatePushPixels(GCPtr pGC, unsigned long changes,
+static void XAAStateWrapValidatePushPixels(GCPtr pGC, unsigned changes,
 					   DrawablePtr pDraw)
 {
    GET_STATEPRIV_GC(pGC);
diff --git a/hw/xfree86/xaa/xaalocal.h b/hw/xfree86/xaa/xaalocal.h
index a9a70da..464eae7 100644
--- a/hw/xfree86/xaa/xaalocal.h
+++ b/hw/xfree86/xaa/xaalocal.h
@@ -40,6 +40,9 @@ typedef void (*TrapFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
 
 typedef struct _XAAScreen {
    CreateGCProcPtr 		CreateGC;
+   ValidateGCProcPtr            ValidateGC;
+   DestroyGCProcPtr             DestroyGC;
+   ChangeGCProcPtr              ChangeGC;
    CloseScreenProcPtr 		CloseScreen;
    GetImageProcPtr 		GetImage;
    GetSpansProcPtr 		GetSpans;
@@ -62,7 +65,6 @@ typedef struct _XAAScreen {
 
 typedef struct _XAAGC {
     GCOps 	*wrapOps;
-    GCFuncs 	*wrapFuncs;
     GCOps 	*XAAOps;
     int		DashLength;
     unsigned char* DashPattern;
@@ -98,6 +100,10 @@ XAACreateGC(
     GCPtr pGC
 );
 
+void XAAValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
+void XAAChangeGC(GCPtr pGC, unsigned mask);
+void XAADestroyGC(GCPtr pGC);
+
 extern _X_EXPORT Bool
 XAAInitAccel(
     ScreenPtr pScreen, 
@@ -180,61 +186,28 @@ XAACopyArea(
 );
 
 extern _X_EXPORT void
-XAAValidateCopyArea(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidateCopyArea(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidatePutImage(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw 
-);
+XAAValidatePutImage(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidateCopyPlane(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidateCopyPlane(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidatePushPixels(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidatePushPixels(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidateFillSpans(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidateFillSpans(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidatePolyGlyphBlt(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidatePolyGlyphBlt(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidateImageGlyphBlt(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
+XAAValidateImageGlyphBlt(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT void
-XAAValidatePolylines(
-   GCPtr         pGC,
-   unsigned long changes,
-   DrawablePtr   pDraw
-);
-
+XAAValidatePolylines(GCPtr pGC, unsigned changes, DrawablePtr pDraw);
 
 extern _X_EXPORT RegionPtr
 XAACopyPlaneColorExpansion(
@@ -1625,7 +1598,6 @@ XAAGetPixelFromRGBA (
 /* XXX should be static */
 extern _X_EXPORT GCOps XAAFallbackOps;
 extern _X_EXPORT GCOps *XAAGetFallbackOps(void);
-extern _X_EXPORT GCFuncs XAAGCFuncs;
 extern _X_EXPORT DevPrivateKey XAAGetScreenKey(void);
 extern _X_EXPORT DevPrivateKey XAAGetGCKey(void);
 extern _X_EXPORT DevPrivateKey XAAGetPixmapKey(void);
diff --git a/hw/xfree86/xaa/xaawrap.h b/hw/xfree86/xaa/xaawrap.h
index 3f3c261..866f1ff 100644
--- a/hw/xfree86/xaa/xaawrap.h
+++ b/hw/xfree86/xaa/xaawrap.h
@@ -7,15 +7,14 @@
     ((pScreen)->field = wrapper)
 
 
-#define XAA_GC_FUNC_PROLOGUE(pGC)\
+#define XAA_GC_FUNC_PROLOGUE(pGC, func)\
     XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
-    (pGC)->funcs = pGCPriv->wrapFuncs;\
+    XAA_SCREEN_PROLOGUE((pGC)->pScreen, func); \
     if(pGCPriv->flags)\
 	(pGC)->ops = pGCPriv->wrapOps
 
-#define XAA_GC_FUNC_EPILOGUE(pGC)\
-    pGCPriv->wrapFuncs = (pGC)->funcs;\
-    (pGC)->funcs = &XAAGCFuncs;\
+#define XAA_GC_FUNC_EPILOGUE(pGC, func)\
+    XAA_SCREEN_EPILOGUE((pGC)->pScreen, func, XAA##func); \
     if(pGCPriv->flags) {\
 	pGCPriv->wrapOps = (pGC)->ops;\
 	(pGC)->ops = (pGCPriv->flags & OPS_ARE_ACCEL) ? pGCPriv->XAAOps :\
@@ -25,35 +24,27 @@
 
 #define XAA_GC_OP_PROLOGUE(pGC)\
     XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
-    GCFuncs *oldFuncs = pGC->funcs;\
-    pGC->funcs = pGCPriv->wrapFuncs;\
     pGC->ops = pGCPriv->wrapOps
 
 #define XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC)\
     XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
-    GCFuncs *oldFuncs = pGC->funcs;\
     if(!RegionNumRects(pGC->pCompositeClip)) return; \
-    pGC->funcs = pGCPriv->wrapFuncs;\
     pGC->ops = pGCPriv->wrapOps
 
     
 #define XAA_GC_OP_EPILOGUE(pGC)\
     pGCPriv->wrapOps = pGC->ops;\
-    pGC->funcs = oldFuncs;\
     pGC->ops   = pGCPriv->XAAOps
 
 
 #define XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw)\
     XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
     XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDraw));\
-    GCFuncs *oldFuncs = pGC->funcs;\
-    pGC->funcs = pGCPriv->wrapFuncs;\
     pGC->ops = pGCPriv->wrapOps; \
     SYNC_CHECK(pGC)
     
 #define XAA_PIXMAP_OP_EPILOGUE(pGC)\
     pGCPriv->wrapOps = pGC->ops;\
-    pGC->funcs = oldFuncs;\
     pGC->ops   = &XAAPixmapOps;\
     pixPriv->flags |= DIRTY
 
diff --git a/hw/xnest/GC.c b/hw/xnest/GC.c
index 9d3ec9d..2535eac 100644
--- a/hw/xnest/GC.c
+++ b/hw/xnest/GC.c
@@ -37,13 +37,6 @@ is" without express or implied warranty.
 
 DevPrivateKeyRec xnestGCPrivateKeyRec;
 
-static GCFuncs xnestFuncs = {
-  xnestValidateGC,
-  xnestChangeGC,
-  xnestCopyGC,
-  xnestDestroyGC,
-};
-
 static GCOps xnestOps = {
   xnestFillSpans,
   xnestSetSpans,
@@ -70,7 +63,6 @@ static GCOps xnestOps = {
 Bool
 xnestCreateGC(GCPtr pGC)
 {
-  pGC->funcs = &xnestFuncs;
   pGC->ops = &xnestOps;
   
   pGC->miTranslate = 1;
@@ -84,12 +76,12 @@ xnestCreateGC(GCPtr pGC)
 }
 
 void
-xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+xnestValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
 }
 
 void
-xnestChangeGC(GCPtr pGC, unsigned long mask)
+xnestChangeGC(GCPtr pGC, unsigned mask)
 {
   XGCValues values;
   
@@ -174,7 +166,7 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
 }
 
 void
-xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+xnestCopyGC(GCPtr pGCSrc, unsigned mask, GCPtr pGCDst)
 {
   XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
 }
diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c
index d0c7fc8..8a7c422 100644
--- a/hw/xnest/Screen.c
+++ b/hw/xnest/Screen.c
@@ -290,6 +290,10 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
   /* GC procedures */
   
   pScreen->CreateGC = xnestCreateGC;
+  pScreen->ValidateGC = xnestValidateGC;
+  pScreen->ChangeGC = xnestChangeGC;
+  pScreen->CopyGC = xnestCopyGC;
+  pScreen->DestroyGC = xnestDestroyGC;
 
   /* Colormap procedures */
 
diff --git a/hw/xnest/XNGC.h b/hw/xnest/XNGC.h
index 8693d20..ed19aa6 100644
--- a/hw/xnest/XNGC.h
+++ b/hw/xnest/XNGC.h
@@ -31,9 +31,9 @@ extern DevPrivateKeyRec xnestGCPrivateKeyRec;
 #define xnestGC(pGC) (xnestGCPriv(pGC)->gc)
 
 Bool xnestCreateGC(GCPtr pGC);
-void xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
-void xnestChangeGC(GCPtr pGC, unsigned long mask);
-void xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+void xnestValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable);
+void xnestChangeGC(GCPtr pGC, unsigned mask);
+void xnestCopyGC(GCPtr pGCSrc, unsigned mask, GCPtr pGCDst);
 void xnestDestroyGC(GCPtr pGC);
 
 #endif /* XNESTGC_H */
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index f22a2d5..e73d4b5 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -906,6 +906,12 @@ winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
 
 Bool
 winCreateGCNativeGDI (GCPtr pGC);
+
+void
+winValidateGCNativeGDI (GCPtr pGC, unsigned changes, DrawablePtr pDrawable);
+
+void
+winDestroyGCNativeGDI (GCPtr pGC);
 #endif
 
 
diff --git a/hw/xwin/wingc.c b/hw/xwin/wingc.c
index 09e9968..82e9a30 100644
--- a/hw/xwin/wingc.c
+++ b/hw/xwin/wingc.c
@@ -36,46 +36,6 @@
 void
 winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg);
 
-
-/*
- * Local prototypes
- */
-
-#if 0
-static void
-winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges);
-#endif
-
-static void
-winValidateGCNativeGDI (GCPtr pGC,
-			unsigned long changes,
-			DrawablePtr pDrawable);
-
-#if 0
-static void
-winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst);
-#endif
-
-static void
-winDestroyGCNativeGDI (GCPtr pGC);
-
-#if 0
-/* GC Handling Routines */
-const GCFuncs winGCFuncs = {
-  winValidateGCNativeGDI,
-  winChangeGCNativeGDI,
-  winCopyGCNativeGDI,
-  winDestroyGCNativeGDI,
-};
-#else
-const GCFuncs winGCFuncs = {
-  winValidateGCNativeGDI,
-  miChangeGC,
-  miCopyGC,
-  winDestroyGCNativeGDI,
-};
-#endif
-
 /* Drawing Primitives */
 const GCOps winGCOps = {
   winFillSpansNativeGDI,
@@ -121,7 +81,6 @@ winCreateGCNativeGDI (GCPtr pGC)
 #endif
 
   pGC->ops = (GCOps *) &winGCOps;
-  pGC->funcs = (GCFuncs *) &winGCFuncs;
 
   /* We want all coordinates passed to spans functions to be screen relative */
   pGC->miTranslate = TRUE;
@@ -144,23 +103,8 @@ winCreateGCNativeGDI (GCPtr pGC)
   return TRUE;
 }
 
-
-#if 0
-/* See Porting Layer Definition - p. 45 */
-static void
-winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges)
-{
-#if 0
-  ErrorF ("winChangeGCNativeGDI () - Doing nothing\n");
-#endif
-}
-#endif
-
-
-static void
-winValidateGCNativeGDI (GCPtr pGC,
-			unsigned long ulChanges,
-			DrawablePtr pDrawable)
+void
+winValidateGCNativeGDI (GCPtr pGC, unsigned ulChanges, DrawablePtr pDrawable)
 {
   if ((ulChanges & (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) 
       || (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
@@ -169,19 +113,8 @@ winValidateGCNativeGDI (GCPtr pGC,
   }
 }
 
-
-#if 0
 /* See Porting Layer Definition - p. 46 */
-static void
-winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst)
-{
-
-}
-#endif
-
-
-/* See Porting Layer Definition - p. 46 */
-static void
+void
 winDestroyGCNativeGDI (GCPtr pGC)
 {
   winGCPriv(pGC);
diff --git a/hw/xwin/winscrinit.c b/hw/xwin/winscrinit.c
index 21036f4..cce2ce4 100644
--- a/hw/xwin/winscrinit.c
+++ b/hw/xwin/winscrinit.c
@@ -708,6 +708,10 @@ winFinishScreenInitNativeGDI (int index,
 
   /* GC */
   pScreen->CreateGC = winCreateGCNativeGDI;
+  pScreen->ValidateGC = winValidateGCNativeGDI;
+  pScreen->DestroyGC = winDestroyGCNativeGDI;
+  pScreen->ChangeGC = miChangeGC;
+  pScreen->CopyGC = miCopyGC;
 
   /* Colormap Routines */
   pScreen->CreateColormap = miInitializeColormap;
diff --git a/include/gcstruct.h b/include/gcstruct.h
index 933d477..9bff8d1 100644
--- a/include/gcstruct.h
+++ b/include/gcstruct.h
@@ -62,29 +62,6 @@ SOFTWARE.
 #define GCAllBits ((1 << (GCLastBit + 1)) - 1)
 
 /*
- * functions which modify the state of the GC
- */
-
-typedef struct _GCFuncs {
-    void	(* ValidateGC)(
-		GCPtr /*pGC*/,
-		unsigned long /*stateChanges*/,
-		DrawablePtr /*pDrawable*/);
-
-    void	(* ChangeGC)(
-		GCPtr /*pGC*/,
-		unsigned long /*mask*/);
-
-    void	(* CopyGC)(
-		GCPtr /*pGCSrc*/,
-		unsigned long /*mask*/,
-		GCPtr /*pGCDst*/);
-
-    void	(* DestroyGC)(
-		GCPtr /*pGC*/);
-} GCFuncs;
-
-/*
  * graphics operations invoked through a GC
  */
 
@@ -293,7 +270,6 @@ typedef struct _GC {
     pointer		clientClip;
     unsigned int	stateChanges;	/* masked with GC_<kind> */
     unsigned int	serialNumber;
-    GCFuncs		*funcs;
     GCOps		*ops;
     PrivateRec		*devPrivates;
     /*
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index 7724302..7fb4ed5 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -263,6 +263,14 @@ typedef    Bool (* SetCursorPositionProcPtr)(
 typedef    Bool (* CreateGCProcPtr)(
 	GCPtr /*pGC*/);
 
+typedef void (*ValidateGCProcPtr)(GCPtr, unsigned, DrawablePtr);
+
+typedef void (*ChangeGCProcPtr)(GCPtr, unsigned);
+
+typedef void (*CopyGCProcPtr)(GCPtr, unsigned, GCPtr);
+
+typedef void (*DestroyGCProcPtr)(GCPtr);
+
 typedef    Bool (* CreateColormapProcPtr)(
 	ColormapPtr /*pColormap*/);
 
@@ -477,6 +485,10 @@ typedef struct _Screen {
     /* GC procedures */
 
     CreateGCProcPtr		CreateGC;
+    ValidateGCProcPtr           ValidateGC;
+    ChangeGCProcPtr             ChangeGC;
+    CopyGCProcPtr               CopyGC;
+    DestroyGCProcPtr            DestroyGC;
 
     /* Colormap procedures */
 
diff --git a/mi/migc.c b/mi/migc.c
index dce1f30..4b2a4ab 100644
--- a/mi/migc.c
+++ b/mi/migc.c
@@ -39,7 +39,7 @@ from The Open Group.
 
 /* ARGSUSED */
 void
-miChangeGC(GCPtr pGC, unsigned long mask)
+miChangeGC(GCPtr pGC, unsigned mask)
 {
     return;
 }
@@ -55,7 +55,7 @@ miDestroyGC(GCPtr pGC)
 
 /* ARGSUSED */
 void
-miCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
+miCopyGC(GCPtr pGCSrc, unsigned changes, GCPtr pGCDst)
 {
     return;
 }
diff --git a/mi/migc.h b/mi/migc.h
index c357ba7..278f02f 100644
--- a/mi/migc.h
+++ b/mi/migc.h
@@ -28,7 +28,7 @@ from The Open Group.
 
 extern _X_EXPORT void miChangeGC(
     GCPtr  /*pGC*/,
-    unsigned long /*mask*/
+    unsigned /*mask*/
 );
 
 extern _X_EXPORT void miDestroyGC(
@@ -37,7 +37,7 @@ extern _X_EXPORT void miDestroyGC(
 
 extern _X_EXPORT void miCopyGC(
     GCPtr /*pGCSrc*/,
-    unsigned long /*changes*/,
+    unsigned /*changes*/,
     GCPtr /*pGCDst*/
 );
 
diff --git a/miext/cw/cw.c b/miext/cw/cw.c
index 94f3b0f..ba69d20 100644
--- a/miext/cw/cw.c
+++ b/miext/cw/cw.c
@@ -54,21 +54,8 @@ static Bool
 cwCloseScreen (int i, ScreenPtr pScreen);
 
 static void
-cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
-static void
-cwChangeGC(GCPtr pGC, unsigned long mask);
-static void
-cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void
 cwDestroyGC(GCPtr pGC);
 
-GCFuncs cwGCFuncs = {
-    cwValidateGC,
-    cwChangeGC,
-    cwCopyGC,
-    cwDestroyGC,
-};
-
 /* Find the real drawable to draw to, and provide offsets that will translate
  * window coordinates to backing pixmap coordinates.
  */
@@ -89,15 +76,15 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
     }
 }
 
-#define FUNC_PROLOGUE(pGC, pPriv) do {					\
-    (pGC)->funcs = (pPriv)->wrapFuncs;					\
+#define FUNC_PROLOGUE(pGC, pPriv, func) do {				\
+    (pGC)->pScreen->func = (pPriv)->func;                               \
     (pGC)->ops = (pPriv)->wrapOps;					\
 } while (0)
 
-#define FUNC_EPILOGUE(pGC, pPriv) do {					\
-    (pPriv)->wrapFuncs = (pGC)->funcs;					\
+#define FUNC_EPILOGUE(pGC, pPriv, func) do {				\
+    (pPriv)->func = (pGC)->pScreen->func;                               \
     (pPriv)->wrapOps = (pGC)->ops;					\
-    (pGC)->funcs = &cwGCFuncs;						\
+    (pGC)->pScreen->func = cw##func;                                    \
     (pGC)->ops = &cwGCOps;						\
 } while (0)
 
@@ -136,29 +123,33 @@ cwDestroyBackingGC(GCPtr pGC)
 }
 
 static void
-cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
+cwValidateGC(GCPtr pGC, unsigned stateChanges, DrawablePtr pDrawable)
 {
     GCPtr   	  	pBackingGC;
     cwGCPtr		pPriv;
     DrawablePtr		pBackingDrawable;
     int			x_off, y_off;
+    cwScreenPtr         pScreenPriv;
 
-    pPriv = (cwGCPtr) getCwGC (pGC);
+    pPriv = getCwGC (pGC);
+    pScreenPriv = dixLookupPrivate(&pGC->pScreen->devPrivates, cwScreenKey);
 
-    FUNC_PROLOGUE(pGC, pPriv);
+    pGC->pScreen->ValidateGC = pScreenPriv->ValidateGC;
 
     /*
      * Must call ValidateGC to ensure pGC->pCompositeClip is valid
      */
-    (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
+    pGC->pScreen->ValidateGC(pGC, stateChanges, pDrawable);
 
     if (!cwDrawableIsRedirWindow(pDrawable)) {
 	cwDestroyBackingGC(pGC);
-	FUNC_EPILOGUE(pGC, pPriv);
+        pScreenPriv->ValidateGC = pGC->pScreen->ValidateGC;
+        pGC->pScreen->ValidateGC = cwValidateGC;
 	return;
     } else {
 	if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
-	    FUNC_EPILOGUE(pGC, pPriv);
+            pScreenPriv->ValidateGC = pGC->pScreen->ValidateGC;
+            pGC->pScreen->ValidateGC = cwValidateGC;
 	    return;
 	}
     }
@@ -219,45 +210,24 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
 
     ValidateGC(pBackingDrawable, pBackingGC);
 
-    FUNC_EPILOGUE(pGC, pPriv);
-}
-
-static void
-cwChangeGC(GCPtr pGC, unsigned long mask)
-{
-    cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
-
-    FUNC_PROLOGUE(pGC, pPriv);
-
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-
-    FUNC_EPILOGUE(pGC, pPriv);
-}
-
-static void
-cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
-    cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGCDst->devPrivates, cwGCKey);
-
-    FUNC_PROLOGUE(pGCDst, pPriv);
-
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-
-    FUNC_EPILOGUE(pGCDst, pPriv);
+    pScreenPriv->ValidateGC = pGC->pScreen->ValidateGC;
+    pGC->pScreen->ValidateGC = cwValidateGC;
 }
 
 static void
 cwDestroyGC(GCPtr pGC)
 {
-    cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey);
+    cwScreenPtr pScreenPriv = dixLookupPrivate(&pGC->pScreen->devPrivates,
+                                               cwScreenKey);
 
-    FUNC_PROLOGUE(pGC, pPriv);
+    pGC->pScreen->DestroyGC = pScreenPriv->DestroyGC;
 
     cwDestroyBackingGC(pGC);
 
-    (*pGC->funcs->DestroyGC) (pGC);
+    pGC->pScreen->DestroyGC (pGC);
 
-    /* leave it unwrapped */
+    pScreenPriv->DestroyGC = pGC->pScreen->DestroyGC;
+    pGC->pScreen->DestroyGC = cwDestroyGC;
 }
 
 /*
@@ -275,14 +245,12 @@ cwDestroyGC(GCPtr pGC)
 static Bool
 cwCreateGC(GCPtr pGC)
 {
-    cwGCPtr	pPriv = getCwGC(pGC);
     ScreenPtr	pScreen = pGC->pScreen;
     Bool	ret;
 
     SCREEN_PROLOGUE(pScreen, CreateGC);
 
-    if ( (ret = (*pScreen->CreateGC)(pGC)) )
-	FUNC_EPILOGUE(pGC, pPriv);
+    ret = (*pScreen->CreateGC)(pGC);
 
     SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
 
@@ -449,6 +417,8 @@ miInitializeCompositeWrapper(ScreenPtr pScreen)
     SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
     SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
     SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
+    SCREEN_EPILOGUE(pScreen, ValidateGC, cwValidateGC);
+    SCREEN_EPILOGUE(pScreen, DestroyGC, cwDestroyGC);
     SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
 
     SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap);
@@ -470,6 +440,8 @@ cwCloseScreen (int i, ScreenPtr pScreen)
     pScreen->GetImage = pScreenPriv->GetImage;
     pScreen->GetSpans = pScreenPriv->GetSpans;
     pScreen->CreateGC = pScreenPriv->CreateGC;
+    pScreen->ValidateGC = pScreenPriv->ValidateGC;
+    pScreen->DestroyGC = pScreenPriv->DestroyGC;
     pScreen->CopyWindow = pScreenPriv->CopyWindow;
 
     if (ps)
diff --git a/miext/cw/cw.h b/miext/cw/cw.h
index 31eb9e5..6d23613 100644
--- a/miext/cw/cw.h
+++ b/miext/cw/cw.h
@@ -41,7 +41,6 @@ typedef struct {
     unsigned long   serialNumber;   /* clientClip computed time */
     unsigned long   stateChanges;   /* changes in parent gc since last copy */
     GCOps	    *wrapOps;	    /* wrapped ops */
-    GCFuncs	    *wrapFuncs;	    /* wrapped funcs */
 } cwGCRec, *cwGCPtr;
 
 extern _X_EXPORT DevPrivateKeyRec cwGCKeyRec;
@@ -88,6 +87,8 @@ typedef struct {
     GetImageProcPtr		GetImage;
     GetSpansProcPtr		GetSpans;
     CreateGCProcPtr		CreateGC;
+    ValidateGCProcPtr		ValidateGC;
+    DestroyGCProcPtr            DestroyGC;
 
     CopyWindowProcPtr		CopyWindow;
 
diff --git a/miext/cw/cw_ops.c b/miext/cw/cw_ops.c
index 9ae56cb..ea8ac49 100644
--- a/miext/cw/cw_ops.c
+++ b/miext/cw/cw_ops.c
@@ -47,19 +47,14 @@
     if (pBackingGC->serialNumber != pBackingDst->serialNumber) { \
 	ValidateGC(pBackingDst, pBackingGC); \
     } \
-    pGC->funcs = pGCPrivate->wrapFuncs;\
     pGC->ops = pGCPrivate->wrapOps;\
 } while (0)
 
 #define EPILOGUE(pGC) do { \
-    pGCPrivate->wrapFuncs = (pGC)->funcs; \
     pGCPrivate->wrapOps = (pGC)->ops; \
-    (pGC)->funcs = &cwGCFuncs; \
     (pGC)->ops = &cwGCOps; \
 } while (0)
 
-extern GCFuncs cwGCFuncs;
-
 /*
  * GC ops -- wrap each GC operation with our own function
  */
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index b683f2c..ac30e19 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -423,14 +423,7 @@ damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
     RegionUninit(&region);
 }
 
-static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void damageChangeGC(GCPtr, unsigned long);
-static void damageCopyGC(GCPtr, unsigned long, GCPtr);
-static void damageDestroyGC(GCPtr);
-
-static GCFuncs damageGCFuncs = {
-    damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
-};
+static void damageValidateGC(GCPtr, unsigned, DrawablePtr);
 
 static GCOps damageGCOps;
 
@@ -445,8 +438,6 @@ damageCreateGC(GCPtr pGC)
     unwrap (pScrPriv, pScreen, CreateGC);
     if((ret = (*pScreen->CreateGC) (pGC))) {
 	pGCPriv->ops = NULL;
-	pGCPriv->funcs = pGC->funcs;
-	pGC->funcs = &damageGCFuncs;
     }
     wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
 
@@ -455,59 +446,28 @@ damageCreateGC(GCPtr pGC)
 
 #define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
     damageGCPriv(pGC);  \
-    GCFuncs *oldFuncs = pGC->funcs; \
-    unwrap(pGCPriv, pGC, funcs);  \
     unwrap(pGCPriv, pGC, ops); \
 
 #define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
-    wrap(pGCPriv, pGC, funcs, oldFuncs); \
     wrap(pGCPriv, pGC, ops, &damageGCOps)
 
-#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC, func) \
+    damageScrPriv(pGC->pScreen); \
     damageGCPriv(pGC); \
-    unwrap(pGCPriv, pGC, funcs); \
+    unwrap(pScrPriv, pGC->pScreen, func); \
     if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
 
-#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
-    wrap(pGCPriv, pGC, funcs, &damageGCFuncs);  \
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC, func) \
+    wrap(pScrPriv, pGC->pScreen, func, damage##func); \
     if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
 
 static void
-damageValidateGC(GCPtr         pGC,
-		 unsigned long changes,
-		 DrawablePtr   pDrawable)
+damageValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
-    DAMAGE_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    DAMAGE_GC_FUNC_PROLOGUE (pGC, ValidateGC);
+    pGC->pScreen->ValidateGC(pGC, changes, pDrawable);
     pGCPriv->ops = pGC->ops;  /* just so it's not NULL */
-    DAMAGE_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-damageDestroyGC(GCPtr pGC)
-{
-    DAMAGE_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->DestroyGC)(pGC);
-    DAMAGE_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-damageChangeGC (GCPtr		pGC,
-		unsigned long   mask)
-{
-    DAMAGE_GC_FUNC_PROLOGUE (pGC);
-    (*pGC->funcs->ChangeGC) (pGC, mask);
-    DAMAGE_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-damageCopyGC (GCPtr	    pGCSrc,
-	      unsigned long mask,
-	      GCPtr	    pGCDst)
-{
-    DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
-    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
-    DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC, ValidateGC);
 }
 
 #define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
@@ -1786,6 +1746,7 @@ damageCloseScreen (int i, ScreenPtr pScreen)
 
     unwrap (pScrPriv, pScreen, DestroyPixmap);
     unwrap (pScrPriv, pScreen, CreateGC);
+    unwrap (pScrPriv, pScreen, ValidateGC);
     unwrap (pScrPriv, pScreen, CopyWindow);
     unwrap (pScrPriv, pScreen, CloseScreen);
     free(pScrPriv);
@@ -1848,6 +1809,7 @@ DamageSetup (ScreenPtr pScreen)
 
     wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
     wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+    wrap (pScrPriv, pScreen, ValidateGC, damageValidateGC);
     wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
     wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
     wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
diff --git a/miext/damage/damagestr.h b/miext/damage/damagestr.h
index b224958..7cce023 100644
--- a/miext/damage/damagestr.h
+++ b/miext/damage/damagestr.h
@@ -67,6 +67,7 @@ typedef struct _damageScrPriv {
     CopyWindowProcPtr		CopyWindow;
     CloseScreenProcPtr		CloseScreen;
     CreateGCProcPtr		CreateGC;
+    ValidateGCProcPtr           ValidateGC;
     DestroyPixmapProcPtr	DestroyPixmap;
     SetWindowPixmapProcPtr	SetWindowPixmap;
     DestroyWindowProcPtr	DestroyWindow;
@@ -80,7 +81,6 @@ typedef struct _damageScrPriv {
 
 typedef struct _damageGCPriv {
     GCOps   *ops;
-    GCFuncs *funcs;
 } DamageGCPrivRec, *DamageGCPrivPtr;
 
 /* XXX should move these into damage.c, damageScrPrivateIndex is static */
diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h
index 6faf1fe..fd96198 100644
--- a/miext/rootless/rootlessCommon.h
+++ b/miext/rootless/rootlessCommon.h
@@ -69,7 +69,6 @@ extern DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
 
 // RootlessGCRec: private per-gc data
 typedef struct {
-    GCFuncs *originalFuncs;
     GCOps *originalOps;
 } RootlessGCRec;
 
@@ -96,6 +95,7 @@ typedef struct _RootlessScreenRec {
     ChangeWindowAttributesProcPtr ChangeWindowAttributes;
 
     CreateGCProcPtr CreateGC;
+    ValidateGCProcPtr ValidateGC;
     CopyWindowProcPtr CopyWindow;
     GetImageProcPtr GetImage;
     SourceValidateProcPtr SourceValidate;
diff --git a/miext/rootless/rootlessGC.c b/miext/rootless/rootlessGC.c
index 93080c7..2225ee2 100644
--- a/miext/rootless/rootlessGC.c
+++ b/miext/rootless/rootlessGC.c
@@ -49,23 +49,8 @@
 
 #include "rootlessCommon.h"
 
-
-// GC functions
-static void RootlessValidateGC(GCPtr pGC, unsigned long changes,
-                               DrawablePtr pDrawable);
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void RootlessDestroyGC(GCPtr pGC);
-
 Bool RootlessCreateGC(GCPtr pGC);
 
-GCFuncs rootlessGCFuncs = {
-    RootlessValidateGC,
-    RootlessChangeGC,
-    RootlessCopyGC,
-    RootlessDestroyGC,
-};
-
 // GC operations
 static void RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
 			      DDXPointPtr pptInit, int *pwidthInit, 
@@ -219,7 +204,7 @@ static GCOps rootlessGCOps = {
 
 #define VALIDATE_GC(pGC, changes, pDrawable)				\
     do {								\
-        pGC->funcs->ValidateGC(pGC, changes, pDrawable);		\
+        pGC->pScreen->ValidateGC(pGC, changes, pDrawable);		\
         if (((WindowPtr) pDrawable)->viewable) {			\
             gcrec->originalOps = pGC->ops;				\
         }								\
@@ -280,8 +265,6 @@ RootlessCreateGC(GCPtr pGC)
     gcrec = (RootlessGCRec *)
 	dixLookupPrivate(&pGC->devPrivates, rootlessGCPrivateKey);
     gcrec->originalOps = NULL; // don't wrap ops yet
-    gcrec->originalFuncs = pGC->funcs;
-    pGC->funcs = &rootlessGCFuncs;
 
     SCREEN_WRAP(pGC->pScreen, CreateGC);
     return result;
@@ -298,27 +281,25 @@ RootlessCreateGC(GCPtr pGC)
 
 // GCFUNC_UNRAP assumes funcs have been wrapped and 
 // does not assume ops have been wrapped
-#define GCFUNC_UNWRAP(pGC) \
+#define GCFUNC_UNWRAP(pGC, func) \
     RootlessGCRec *gcrec = (RootlessGCRec *) \
 	dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \
-    (pGC)->funcs = gcrec->originalFuncs; \
+    SCREEN_UNWRAP(pGC->pScreen, func); \
     if (gcrec->originalOps) { \
         (pGC)->ops = gcrec->originalOps; \
 }
 
-#define GCFUNC_WRAP(pGC) \
-    gcrec->originalFuncs = (pGC)->funcs; \
-    (pGC)->funcs = &rootlessGCFuncs; \
+#define GCFUNC_WRAP(pGC, func) \
+    SCREEN_WRAP(pGC->pScreen, func); \
     if (gcrec->originalOps) { \
         gcrec->originalOps = (pGC)->ops; \
         (pGC)->ops = &rootlessGCOps; \
 }
 
-
-static void
-RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+void
+RootlessValidateGC(GCPtr pGC, unsigned changes, DrawablePtr pDrawable)
 {
-    GCFUNC_UNWRAP(pGC);
+    GCFUNC_UNWRAP(pGC, ValidateGC);
 
     gcrec->originalOps = NULL;
 
@@ -337,31 +318,10 @@ RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
         VALIDATE_GC(pGC, changes, pDrawable);
 #endif
     } else {
-        pGC->funcs->ValidateGC(pGC, changes, pDrawable);
+        pGC->pScreen->ValidateGC(pGC, changes, pDrawable);
     }
 
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessChangeGC(GCPtr pGC, unsigned long mask)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->ChangeGC(pGC, mask);
-    GCFUNC_WRAP(pGC);
-}
-
-static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
-    GCFUNC_UNWRAP(pGCDst);
-    pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst);
-    GCFUNC_WRAP(pGCDst);
-}
-
-static void RootlessDestroyGC(GCPtr pGC)
-{
-    GCFUNC_UNWRAP(pGC);
-    pGC->funcs->DestroyGC(pGC);
-    GCFUNC_WRAP(pGC);
+    GCFUNC_WRAP(pGC, ValidateGC);
 }
 
 /*
@@ -372,17 +332,13 @@ static void RootlessDestroyGC(GCPtr pGC)
  * However, much of this code is copied from shadowfb.
  */
 
-// assumes both funcs and ops are wrapped
 #define GCOP_UNWRAP(pGC) \
     RootlessGCRec *gcrec = (RootlessGCRec *) \
         dixLookupPrivate(&(pGC)->devPrivates, rootlessGCPrivateKey); \
-    GCFuncs *saveFuncs = pGC->funcs; \
-    (pGC)->funcs = gcrec->originalFuncs; \
     (pGC)->ops = gcrec->originalOps;
 
 #define GCOP_WRAP(pGC) \
     gcrec->originalOps = (pGC)->ops; \
-    (pGC)->funcs = saveFuncs; \
     (pGC)->ops = &rootlessGCOps;
 
 static void
diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c
index 61d2f5d..353bd68 100644
--- a/miext/rootless/rootlessScreen.c
+++ b/miext/rootless/rootlessScreen.c
@@ -60,6 +60,8 @@
 extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
                                   VTKind kind);
 extern Bool RootlessCreateGC(GCPtr pGC);
+extern void RootlessValidateGC(GCPtr pGC, unsigned changes,
+                               DrawablePtr pDrawable);
 
 // Initialize globals
 DevPrivateKeyRec rootlessGCPrivateKeyRec;
@@ -671,6 +673,7 @@ RootlessWrap(ScreenPtr pScreen)
     WRAP(CreateScreenResources);
     WRAP(CloseScreen);
     WRAP(CreateGC);
+    WRAP(ValidateGC);
     WRAP(CopyWindow);
     WRAP(GetImage);
     WRAP(SourceValidate);
-- 
1.7.3.1



More information about the xorg-devel mailing list