[PATCH 7/7] Add a screen PaintWindow wrapper

Jon TURNEY jon.turney at dronecode.org.uk
Thu Nov 8 05:41:19 PST 2012


Revisit b3415187e92960cbff784108b5a3a8d130dc34c5, which shoves some rootless
specific code directly into miPaintWindow.

Unfortunately as written, this means that dix mi/libmi (when built with ROOTLESS
defined) must be linked into a ddx which links with miext/rootless/librootless,
which makes it impossible to build rootless supporting DDX (XWin and XQuartz)
and non-rootless supporting DDX (the rest) at the same time.  This is a pain
when developing for XWin, as you have to re-./configure to check if changes have
broken other DDXs, and is also a bit inconvenient for packaging and
tinderboxing.

Instead, add a way to wrap the PaintWindow function, so DDXs which have the
rootless extension can install a wrapper which does the the neccesary checking
which rootless needs to do.  DDXs which don't support rootless won't install the
hook, but the DIX remains compatible with them, so they can be built at the same
time.

This is kind of reverting part of what e4d11e58ce349dfe6af2f73ff341317f9b39684c
"Remove the PaintWindow optimization" did in removing the PaintWindowBackground
and PaintWindowBorder hooks, but it doesn't resurrect the problematic
optimization which made use of those hooks.

See [1] for admission that code as it stands is a horrible hack :-). But some
comments in that email make me wonder if this code is in the right place at all.

[1] http://lists.macosforge.org/pipermail/xquartz-dev/2009-September/002551.html

Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
---
 composite/compwindow.c          |    2 +-
 dix/window.c                    |    3 +--
 hw/dmx/doc/dmx.xml              |    2 +-
 hw/xquartz/quartz.c             |    2 +-
 hw/xwin/winrandr.c              |    2 +-
 include/scrnintstr.h            |    5 +++++
 mi/miexpose.c                   |   28 ++--------------------------
 mi/mioverlay.c                  |   12 ++++++------
 mi/miscrinit.c                  |    1 +
 mi/miwindow.c                   |    4 ++--
 miext/rootless/rootlessCommon.h |    1 +
 miext/rootless/rootlessScreen.c |    3 ++-
 miext/rootless/rootlessWindow.c |   35 +++++++++++++++++++++++++++++++++++
 miext/rootless/rootlessWindow.h |    1 +
 14 files changed, 60 insertions(+), 41 deletions(-)

diff --git a/composite/compwindow.c b/composite/compwindow.c
index 0be7a1b..f61600e 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -104,7 +104,7 @@ compRepaintBorder(ClientPtr pClient, pointer 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 e70531a..c78d171 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -122,7 +122,6 @@ Equipment Corporation.
 #endif
 #include "dixevents.h"
 #include "globals.h"
-#include "mi.h"                 /* miPaintWindow */
 #ifdef COMPOSITE
 #include "compint.h"
 #endif
@@ -1466,7 +1465,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;
diff --git a/hw/dmx/doc/dmx.xml b/hw/dmx/doc/dmx.xml
index 6d7df41..c6c8544 100644
--- a/hw/dmx/doc/dmx.xml
+++ b/hw/dmx/doc/dmx.xml
@@ -1268,7 +1268,7 @@ default routine is chosen during GC validation.
 
 <para>Note that some pointers to functions that draw to the screen are
 stored in the Screen structure.  They include GetImage(), GetSpans(),
-CopyWindow() and RestoreAreas().
+PaintWindow(), CopyWindow() and RestoreAreas().
 </para>
 </sect3>
 
diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c
index 31b0e61..e7f30e6 100644
--- a/hw/xquartz/quartz.c
+++ b/hw/xquartz/quartz.c
@@ -300,7 +300,7 @@ QuartzUpdateScreens(void)
     quartzProcs->UpdateScreen(pScreen);
 
     /* miPaintWindow needs to be called after RootlessUpdateScreenPixmap (from xprUpdateScreen) */
-    miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
+    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 1b34085..5624e75 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 df74073..3885a77 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -158,6 +158,10 @@ typedef void (*WindowExposuresProcPtr) (WindowPtr /*pWindow */ ,
                                         RegionPtr /*prgn */ ,
                                         RegionPtr /*other_exposed */ );
 
+typedef void (* PaintWindowProcPtr) (WindowPtr /*pWindow*/ ,
+                                     RegionPtr /*pRegion*/ ,
+                                     int /*what*/ );
+
 typedef void (*CopyWindowProcPtr) (WindowPtr /*pWindow */ ,
                                    DDXPointRec /*ptOldOrg */ ,
                                    RegionPtr /*prgnSrc */ );
@@ -403,6 +407,7 @@ typedef struct _Screen {
     ValidateTreeProcPtr ValidateTree;
     PostValidateTreeProcPtr PostValidateTree;
     WindowExposuresProcPtr WindowExposures;
+    PaintWindowProcPtr PaintWindow;
     CopyWindowProcPtr CopyWindow;
     ClearToBackgroundProcPtr ClearToBackground;
     ClipNotifyProcPtr ClipNotify;
diff --git a/mi/miexpose.c b/mi/miexpose.c
index 8b7c93f..881c969 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -277,7 +277,7 @@ miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
             /* miPaintWindow doesn't clip, so we have to */
             RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
         }
-        miPaintWindow((WindowPtr) pDstDrawable, &rgnExposed, PW_BACKGROUND);
+        (*pWin->drawable.pScreen->PaintWindow)(pWin, &rgnExposed, PW_BACKGROUND);
 
         if (extents) {
             RegionReset(&rgnExposed, &expBox);
@@ -467,7 +467,7 @@ miWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed)
             RegionIntersect(prgn, prgn, &pWin->clipList);
         }
         if (prgn && !RegionNil(prgn))
-            miPaintWindow(pWin, prgn, PW_BACKGROUND);
+            (*pWin->drawable.pScreen->PaintWindow)(pWin, prgn, PW_BACKGROUND);
         if (clientInterested && exposures && !RegionNil(exposures))
             miSendExposures(pWin, exposures,
                             pWin->drawable.x, pWin->drawable.y);
@@ -483,14 +483,6 @@ miWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr other_exposed)
         RegionDestroy(exposures);
 }
 
-#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)
 {
@@ -518,22 +510,6 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool solid = TRUE;
     DrawablePtr drawable = &pWin->drawable;
 
-#ifdef ROOTLESS
-    if (!drawable || drawable->type == UNDRAWABLE_WINDOW)
-        return;
-
-    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 2bfd5e4..018f78a 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);
+                        (*pTree->pWin->drawable.pScreen->PaintWindow)(pTree->pWin, &mival->borderExposed,
+                                                                      PW_BORDER);
                     }
                     RegionUninit(&mival->borderExposed);
 
@@ -884,7 +884,7 @@ miOverlayHandleExposures(WindowPtr pWin)
             }
             else {
                 if (RegionNotEmpty(&val->after.borderExposed)) {
-                    miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
+                    (*pChild->drawable.pScreen->PaintWindow)(pChild, &val->after.borderExposed, PW_BORDER);
                 }
                 (*WindowExposures) (pChild, &val->after.exposed, NullRegion);
             }
@@ -984,6 +984,7 @@ miOverlayWindowExposures(WindowPtr pWin,
                          RegionPtr prgn, RegionPtr other_exposed)
 {
     RegionPtr exposures = prgn;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
 
     if ((prgn && !RegionNil(prgn)) ||
         (exposures && !RegionNil(exposures)) || other_exposed) {
@@ -1002,7 +1003,6 @@ miOverlayWindowExposures(WindowPtr pWin,
         }
         if (clientInterested && exposures &&
             (RegionNumRects(exposures) > RECTLIMIT)) {
-            ScreenPtr pScreen = pWin->drawable.pScreen;
             miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
             BoxRec box;
 
@@ -1028,7 +1028,7 @@ miOverlayWindowExposures(WindowPtr pWin,
                 RegionIntersect(prgn, prgn, &pWin->clipList);
         }
         if (prgn && !RegionNil(prgn))
-            miPaintWindow(pWin, prgn, PW_BACKGROUND);
+            (*pScreen->PaintWindow)(pWin, prgn, PW_BACKGROUND);
         if (clientInterested && exposures && !RegionNil(exposures))
             miSendExposures(pWin, exposures,
                             pWin->drawable.x, pWin->drawable.y);
@@ -1638,7 +1638,7 @@ miOverlayClearToBackground(WindowPtr pWin,
     if (generateExposures)
         (*pScreen->WindowExposures) (pWin, &reg, pBSReg);
     else if (pWin->backgroundState != None)
-        miPaintWindow(pWin, &reg, PW_BACKGROUND);
+        (*pScreen->PaintWindow)(pWin, &reg, PW_BACKGROUND);
     RegionUninit(&reg);
     if (pBSReg)
         RegionDestroy(pBSReg);
diff --git a/mi/miscrinit.c b/mi/miscrinit.c
index 4698b53..f8e6706 100644
--- a/mi/miscrinit.c
+++ b/mi/miscrinit.c
@@ -249,6 +249,7 @@ miScreenInit(ScreenPtr pScreen, pointer pbits,  /* pointer to screen bits */
     pScreen->ValidateTree = miValidateTree;
     pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
     pScreen->WindowExposures = miWindowExposures;
+    pScreen->PaintWindow = miPaintWindow;
     /* CopyWindow */
     pScreen->ClearToBackground = miClearToBackground;
     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
diff --git a/mi/miwindow.c b/mi/miwindow.c
index 8dd99db..4b33ca6 100644
--- a/mi/miwindow.c
+++ b/mi/miwindow.c
@@ -112,7 +112,7 @@ miClearToBackground(WindowPtr pWin,
     if (generateExposures)
         (*pWin->drawable.pScreen->WindowExposures) (pWin, &reg, NULL);
     else if (pWin->backgroundState != None)
-        miPaintWindow(pWin, &reg, PW_BACKGROUND);
+        (*pWin->drawable.pScreen->PaintWindow)(pWin, &reg, PW_BACKGROUND);
     RegionUninit(&reg);
 }
 
@@ -218,7 +218,7 @@ miHandleValidateExposures(WindowPtr pWin)
     while (1) {
         if ((val = pChild->valdata)) {
             if (RegionNotEmpty(&val->after.borderExposed))
-                miPaintWindow(pChild, &val->after.borderExposed, PW_BORDER);
+                (*pChild->drawable.pScreen->PaintWindow)(pChild, &val->after.borderExposed, PW_BORDER);
             RegionUninit(&val->after.borderExposed);
             (*WindowExposures) (pChild, &val->after.exposed, NullRegion);
             RegionUninit(&val->after.exposed);
diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h
index fd9c941..dadeab3 100644
--- a/miext/rootless/rootlessCommon.h
+++ b/miext/rootless/rootlessCommon.h
@@ -96,6 +96,7 @@ typedef struct _RootlessScreenRec {
     ChangeWindowAttributesProcPtr ChangeWindowAttributes;
 
     CreateGCProcPtr CreateGC;
+    PaintWindowProcPtr PaintWindow;
     CopyWindowProcPtr CopyWindow;
     GetImageProcPtr GetImage;
     SourceValidateProcPtr SourceValidate;
diff --git a/miext/rootless/rootlessScreen.c b/miext/rootless/rootlessScreen.c
index a1af3e7..4e7ecf4 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
@@ -668,6 +668,7 @@ RootlessWrap(ScreenPtr pScreen)
     WRAP(CreateScreenResources);
     WRAP(CloseScreen);
     WRAP(CreateGC);
+    WRAP(PaintWindow);
     WRAP(CopyWindow);
     WRAP(GetImage);
     WRAP(SourceValidate);
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index cfcb6e5..dde2856 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -1636,3 +1636,38 @@ RootlessSetPixmapOfAncestors(WindowPtr pWin)
         pScreen->SetWindowPixmap(pWin, topWinRec->pixmap);
     }
 }
+
+/*
+ * RootlessPaintWindow
+ *
+ * Wrapper for miPaintWindow
+ *
+ * Returns directly if there is nothing more for miPaintWindow() to do
+ *
+ */
+void
+RootlessPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+    DrawablePtr drawable = &pWin->drawable;
+
+    if (!drawable || drawable->type == UNDRAWABLE_WINDOW)
+        return;
+
+    if (IsFramedWindow(pWin)) {
+        RootlessStartDrawing(pWin);
+        RootlessDamageRegion(pWin, pRegion);
+
+        // For ParentRelative windows, if painting background, or with
+        // tiled borders, we have to make sure the window pixmap is
+        // set correctly all the way up the ancestor chain.
+        if (pWin->backgroundState == ParentRelative) {
+            if ((what == PW_BACKGROUND) ||
+                (what == PW_BORDER && !pWin->borderIsPixel))
+                RootlessSetPixmapOfAncestors(pWin);
+        }
+    }
+
+    SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindow);
+    pWin->drawable.pScreen->PaintWindow(pWin, pRegion, what);
+    SCREEN_WRAP(pWin->drawable.pScreen, PaintWindow);
+}
diff --git a/miext/rootless/rootlessWindow.h b/miext/rootless/rootlessWindow.h
index d3955fc..3b7ea42 100644
--- a/miext/rootless/rootlessWindow.h
+++ b/miext/rootless/rootlessWindow.h
@@ -53,6 +53,7 @@ void RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib,
 void RootlessResizeWindow(WindowPtr pWin, int x, int y, unsigned int w,
                           unsigned int h, WindowPtr pSib);
 void RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent);
+void RootlessPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
 void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width);
 
 #ifdef __APPLE__
-- 
1.7.9



More information about the xorg-devel mailing list