diff --git a/composite/compwindow.c b/composite/compwindow.c
index 77bdfa23c5d68d7a682592c975f6bdf4d6bba5cc..344138ad7a78840b4ee5f1b081128e1099281659 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -104,7 +104,7 @@ compRepaintBorder(ClientPtr pClient, void *closure)
 
         RegionNull(&exposed);
         RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
-        miPaintWindow(pWindow, &exposed, PW_BORDER);
+        pWindow->drawable.pScreen->PaintWindow(pWindow, &exposed, PW_BORDER);
         RegionUninit(&exposed);
     }
     return TRUE;
diff --git a/dix/window.c b/dix/window.c
index 1b44305c904add16470a931021cc7abd3d520a1e..d57f320f8a3de2d6ee22512357ce10419487983f 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -1467,7 +1467,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
 
         RegionNull(&exposed);
         RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize);
-        miPaintWindow(pWin, &exposed, PW_BORDER);
+        pWin->drawable.pScreen->PaintWindow(pWin, &exposed, PW_BORDER);
         RegionUninit(&exposed);
     }
     return error;
@@ -3034,7 +3034,7 @@ dixSaveScreens(ClientPtr client, int on, int mode)
 
                 /* make it look like screen saver is off, so that
                  * NotClippedByChildren will compute a clip list
-                 * for the root window, so miPaintWindow works
+                 * for the root window, so PaintWindow works
                  */
                 screenIsSaved = SCREEN_SAVER_OFF;
                 (*pWin->drawable.pScreen->MoveWindow) (pWin,
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 851ce4842aea1ff6d958d65a852fb722c16e0641..d3ec133f640db35dd1efa9650703224d15bbe6b5 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -300,8 +300,8 @@ QuartzUpdateScreens(void)
 
     quartzProcs->UpdateScreen(pScreen);
 
-    /* miPaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */
-    miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
+    /* PaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */
+    pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
 
     /* Tell RandR about the new size, so new connections get the correct info */
     RRScreenSizeNotify(pScreen);
diff --git a/hw/xwin/winrandr.c b/hw/xwin/winrandr.c
index 73925070dcb994ddbc0e2db03d3434ae022ddbd7..f4ba054bc395fd6d4f63331937d16d00bdb89684 100644
--- a/hw/xwin/winrandr.c
+++ b/hw/xwin/winrandr.c
@@ -104,7 +104,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
     SetRootClip(pScreen, TRUE);
 
     // and arrange for it to be repainted
-    miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
+    pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
 
     /* Indicate that a screen size change took place */
     RRScreenSizeNotify(pScreen);
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index a627fe7ac8bc6a202a9e9e0ad4ded7814bcd4a2b..2e617c46673d8029ade2b5c3eb5fb1161df7b8c0 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -158,6 +158,10 @@ typedef void (*PostValidateTreeProcPtr) (WindowPtr /*pParent */ ,
 typedef void (*WindowExposuresProcPtr) (WindowPtr /*pWindow */ ,
                                         RegionPtr /*prgn */);
 
+typedef void (*PaintWindowProcPtr) (WindowPtr /*pWindow*/,
+                                    RegionPtr /*pRegion*/,
+                                    int /*what*/);
+
 typedef void (*CopyWindowProcPtr) (WindowPtr /*pWindow */ ,
                                    DDXPointRec /*ptOldOrg */ ,
                                    RegionPtr /*prgnSrc */ );
@@ -498,6 +502,7 @@ typedef struct _Screen {
     ClearToBackgroundProcPtr ClearToBackground;
     ClipNotifyProcPtr ClipNotify;
     RestackWindowProcPtr RestackWindow;
+    PaintWindowProcPtr PaintWindow;
 
     /* Pixmap procedures */
 
diff --git a/mi/miexpose.c b/mi/miexpose.c
index f4c6e89a06e3f9b2a1976184c7ea315c0d6a17fe..148d1a63b80f9bbcfcfee50f79edd3f8937d73de 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -268,10 +268,11 @@ miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
         RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y);
 
         if (extents) {
-            /* miPaintWindow doesn't clip, so we have to */
+            /* PaintWindow doesn't clip, so we have to */
             RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
         }
-        miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND);
+        pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable,
+                                           &rgnExposed, PW_BACKGROUND);
 
         if (extents) {
             RegionReset(&rgnExposed, &expBox);
@@ -383,16 +384,14 @@ miWindowExposures(WindowPtr pWin, RegionPtr prgn)
              * work overall, on both client and server.  This is cheating, but
              * isn't prohibited by the protocol ("spontaneous combustion" :-).
              */
-            BoxRec box;
-
-            box = *RegionExtents(prgn);
+            BoxRec box = *RegionExtents(prgn);
             exposures = &expRec;
             RegionInit(exposures, &box, 1);
             RegionReset(prgn, &box);
             /* miPaintWindow doesn't clip, so we have to */
             RegionIntersect(prgn, prgn, &pWin->clipList);
         }
-        miPaintWindow(pWin, prgn, PW_BACKGROUND);
+        pWin->drawable.pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND);
         if (clientInterested)
             miSendExposures(pWin, exposures,
                             pWin->drawable.x, pWin->drawable.y);
@@ -402,14 +401,6 @@ miWindowExposures(WindowPtr pWin, RegionPtr prgn)
     }
 }
 
-#ifdef ROOTLESS
-/* Ugly, ugly, but we lost our hooks into miPaintWindow... =/ */
-void RootlessSetPixmapOfAncestors(WindowPtr pWin);
-void RootlessStartDrawing(WindowPtr pWin);
-void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
-Bool IsFramedWindow(WindowPtr pWin);
-#endif
-
 void
 miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
 {
@@ -437,19 +428,6 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool solid = TRUE;
     DrawablePtr drawable = &pWin->drawable;
 
-#ifdef ROOTLESS
-    if (IsFramedWindow(pWin)) {
-        RootlessStartDrawing(pWin);
-        RootlessDamageRegion(pWin, prgn);
-
-        if (pWin->backgroundState == ParentRelative) {
-            if ((what == PW_BACKGROUND) ||
-                (what == PW_BORDER && !pWin->borderIsPixel))
-                RootlessSetPixmapOfAncestors(pWin);
-        }
-    }
-#endif
-
     if (what == PW_BACKGROUND) {
         while (pWin->backgroundState == ParentRelative)
             pWin = pWin->parent;
diff --git a/mi/mioverlay.c b/mi/mioverlay.c
index 2b20fd72f3e616d80a21568adafbfff636896721..9f3ef0725aae35f62e66664fa1ca965767be767d 100644
--- a/mi/mioverlay.c
+++ b/mi/mioverlay.c
@@ -844,8 +844,8 @@ miOverlayHandleExposures(WindowPtr pWin)
             if ((mival = pTree->valdata)) {
                 if (!((*pPriv->InOverlay) (pTree->pWin))) {
                     if (RegionNotEmpty(&mival->borderExposed)) {
-                        miPaintWindow(pTree->pWin, &mival->borderExposed,
-                                      PW_BORDER);
+                        pScreen->PaintWindow(pTree->pWin, &mival->borderExposed,
+                                             PW_BORDER);
                     }
                     RegionUninit(&mival->borderExposed);
 
@@ -883,7 +883,8 @@ miOverlayHandleExposures(WindowPtr pWin)
             }
             else {
                 if (RegionNotEmpty(&val->after.borderExposed)) {
-                    miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
+                    pScreen->PaintWindow(pChild, &val->after.borderExposed,
+                                         PW_BORDER);
                 }
                 (*WindowExposures) (pChild, &val->after.exposed);
             }
@@ -982,6 +983,7 @@ static void
 miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn)
 {
     RegionPtr exposures = prgn;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
 
     if (prgn && !RegionNil(prgn)) {
         RegionRec expRec;
@@ -1007,7 +1009,7 @@ miOverlayWindowExposures(WindowPtr pWin, RegionPtr prgn)
             else
                 RegionIntersect(prgn, prgn, &pWin->clipList);
         }
-        miPaintWindow(pWin, prgn, PW_BACKGROUND);
+        pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND);
         if (clientInterested)
             miSendExposures(pWin, exposures,
                             pWin->drawable.x, pWin->drawable.y);
@@ -1606,7 +1608,7 @@ miOverlayClearToBackground(WindowPtr pWin,
     if (generateExposures)
         (*pScreen->WindowExposures) (pWin, &reg);
     else if (pWin->backgroundState != None)
-        miPaintWindow(pWin, &reg, PW_BACKGROUND);
+        pScreen->PaintWindow(pWin, &reg, PW_BACKGROUND);
     RegionUninit(&reg);
 }
 
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index b53c7e41a30a1cfd4639d58dae2c5da93789e4aa..9c6af0dc7595f9f70301b8b6ad82a5ba538fb3ac 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -253,6 +253,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
     pScreen->ClearToBackground = miClearToBackground;
     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
     pScreen->RestackWindow = (RestackWindowProcPtr) 0;
+    pScreen->PaintWindow = miPaintWindow;
     /* CreatePixmap, DestroyPixmap */
     /* RealizeFont, UnrealizeFont */
     /* CreateGC */
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 2fc7cfb79be5e7d7f7ab483f687921ec2496d694..39c279e184d1cc2555d48a52f920b3f53bd05d99 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -113,7 +113,7 @@ miClearToBackground(WindowPtr pWin,
     if (generateExposures)
         (*pWin->drawable.pScreen->WindowExposures) (pWin, &reg);
     else if (pWin->backgroundState != None)
-        miPaintWindow(pWin, &reg, PW_BACKGROUND);
+        pWin->drawable.pScreen->PaintWindow(pWin, &reg, PW_BACKGROUND);
     RegionUninit(&reg);
 }
 
@@ -219,7 +219,9 @@ miHandleValidateExposures(WindowPtr pWin)
     while (1) {
         if ((val = pChild->valdata)) {
             if (RegionNotEmpty(&val->after.borderExposed))
-                miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
+                pWin->drawable.pScreen->PaintWindow(pChild,
+                                                    &val->after.borderExposed,
+                                                    PW_BORDER);
             RegionUninit(&val->after.borderExposed);
             (*WindowExposures) (pChild, &val->after.exposed);
             RegionUninit(&val->after.exposed);
diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h
index fd9c941f4d7e976793ec89b940ce92e065837743..aa5557954cb572f64246901331145489eb9951ae 100644
--- a/miext/rootless/rootlessCommon.h
+++ b/miext/rootless/rootlessCommon.h
@@ -94,6 +94,7 @@ typedef struct _RootlessScreenRec {
     ChangeBorderWidthProcPtr ChangeBorderWidth;
     PositionWindowProcPtr PositionWindow;
     ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+    PaintWindowProcPtr PaintWindow;
 
     CreateGCProcPtr CreateGC;
     CopyWindowProcPtr CopyWindow;
diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c
index 6226ee84a20c36c0fdd7750f1e75d10aaa3bb1a9..471656428834547db270e3d8cb0e723c03837fe5 100644
--- a/miext/rootless/rootlessScreen.c
+++ b/miext/rootless/rootlessScreen.c
@@ -473,7 +473,7 @@ expose_1(WindowPtr pWin)
     if (!pWin->realized)
         return;
 
-    miPaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
+    pWin->drawable.pScreen->PaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
 
     /* FIXME: comments in windowstr.h indicate that borderClip doesn't
        include subwindow visibility. But I'm not so sure.. so we may
@@ -669,6 +669,7 @@ RootlessWrap(ScreenPtr pScreen)
     WRAP(CloseScreen);
     WRAP(CreateGC);
     WRAP(CopyWindow);
+    WRAP(PaintWindow);
     WRAP(GetImage);
     WRAP(SourceValidate);
     WRAP(CreateWindow);
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index 3240acce56ff1c019f49079630b8dcc32272b169..e3042990c8e6d273c11be22dc199ba25bf6f2d31 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -720,7 +720,7 @@ RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
 /*
  * RootlessCopyWindow
  *  Update *new* location of window. Old location is redrawn with
- *  miPaintWindow. Cloned from fbCopyWindow.
+ *  PaintWindow. Cloned from fbCopyWindow.
  *  The original always draws on the root pixmap, which we don't have.
  *  Instead, draw on the parent window's pixmap.
  */
@@ -794,6 +794,27 @@ RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     RL_DEBUG_MSG("copywindowFB end\n");
 }
 
+void
+RootlessPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (IsFramedWindow(pWin)) {
+        RootlessStartDrawing(pWin);
+        RootlessDamageRegion(pWin, prgn);
+
+        if (pWin->backgroundState == ParentRelative) {
+            if ((what == PW_BACKGROUND) ||
+                (what == PW_BORDER && !pWin->borderIsPixel))
+                RootlessSetPixmapOfAncestors(pWin);
+        }
+    }
+
+    SCREEN_UNWRAP(pScreen, PaintWindow);
+    pScreen->PaintWindow(pWin, prgn, what);
+    SCREEN_WRAP(pScreen, PaintWindow);
+}
+
 /*
  * Window resize procedures
  */
diff --git a/miext/rootless/rootlessWindow.h b/miext/rootless/rootlessWindow.h
index d3955fc89b470cf5a1dece5507de6e4179c56f43..4fd34d54d9316eca113333a03ea3a092a425a015 100644
--- a/miext/rootless/rootlessWindow.h
+++ b/miext/rootless/rootlessWindow.h
@@ -48,6 +48,7 @@ Bool RootlessUnrealizeWindow(WindowPtr pWin);
 void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
 void RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
                         RegionPtr prgnSrc);
+void RootlessPaintWindow(WindowPtr pWin, RegionPtr prgn, int what);
 void RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib,
                         VTKind kind);
 void RootlessResizeWindow(WindowPtr pWin, int x, int y, unsigned int w,