From d7d160f79db84528693375606e65263d478784dd Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Tue, 6 Nov 2012 16:08:24 +0000 Subject: Add a screen PaintWindow wrapper 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 --- 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 0be7a1b34..f61600e9e 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 e70531af6..c78d171b3 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 6d7df4133..c6c8544ff 100644 --- a/hw/dmx/doc/dmx.xml +++ b/hw/dmx/doc/dmx.xml @@ -1268,7 +1268,7 @@ default routine is chosen during GC validation. 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(). diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 31b0e619a..e7f30e626 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 1b340850c..5624e7563 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 df7407391..3885a7771 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 8b7c93fb8..881c9698f 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 2bfd5e401..018f78a15 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, ®, pBSReg); else if (pWin->backgroundState != None) - miPaintWindow(pWin, ®, PW_BACKGROUND); + (*pScreen->PaintWindow)(pWin, ®, PW_BACKGROUND); RegionUninit(®); if (pBSReg) RegionDestroy(pBSReg); diff --git a/mi/miscrinit.c b/mi/miscrinit.c index 4698b532f..f8e6706ee 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 8dd99dbf0..4b33ca6a4 100644 --- a/mi/miwindow.c +++ b/mi/miwindow.c @@ -112,7 +112,7 @@ miClearToBackground(WindowPtr pWin, if (generateExposures) (*pWin->drawable.pScreen->WindowExposures) (pWin, ®, NULL); else if (pWin->backgroundState != None) - miPaintWindow(pWin, ®, PW_BACKGROUND); + (*pWin->drawable.pScreen->PaintWindow)(pWin, ®, PW_BACKGROUND); RegionUninit(®); } @@ -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 fd9c941f4..dadeab3cb 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 a1af3e7ac..4e7ecf4d3 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 cfcb6e558..dde285666 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 d3955fc89..3b7ea42d3 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__ -- cgit v1.2.3