From 9148d8700b7c5afc2644e5820c57c509378f93ce Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Mon, 23 Jan 2006 13:59:14 +0000 Subject: Commit slight variation of bug #5460 which is the merge of the new shadow code from kdrive. --- miext/shadow/shadow.c | 1527 ++++------------------------------------------ miext/shadow/shadow.h | 35 +- miext/shadow/shpacked.c | 2 +- miext/shadow/shplanar.c | 2 +- miext/shadow/shplanar8.c | 2 +- miext/shadow/shrotate.c | 2 +- miext/shadow/shrotpack.h | 2 +- 7 files changed, 135 insertions(+), 1437 deletions(-) (limited to 'miext') diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c index 92cb5e980..d3d9135a5 100644 --- a/miext/shadow/shadow.c +++ b/miext/shadow/shadow.c @@ -1,7 +1,7 @@ /* - * $XFree86: xc/programs/Xserver/miext/shadow/shadow.c,v 1.14tsi Exp $ + * $Id$ * - * Copyright © 2000 Keith Packard + * Copyright © 2000 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -22,7 +22,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ - #ifdef HAVE_DIX_CONFIG_H #include #endif @@ -30,32 +29,19 @@ #include #include "scrnintstr.h" #include "windowstr.h" -#include #include "dixfontstr.h" -#include #include "mi.h" #include "regionstr.h" #include "globals.h" #include "gcstruct.h" #include "shadow.h" -typedef struct _shadowGCPriv { - GCOps *ops; - GCFuncs *funcs; -} shadowGCPrivRec, *shadowGCPrivPtr; - int shadowScrPrivateIndex; -int shadowGCPrivateIndex; int shadowGeneration; -#define shadowGetGCPriv(pGC) \ - ((shadowGCPrivPtr) (pGC)->devPrivates[shadowGCPrivateIndex].ptr) -#define shadowGCPriv(pGC) \ - shadowGCPrivPtr pGCPriv = shadowGetGCPriv(pGC) - -#define wrap(priv, real, mem, func) {\ +#define wrap(priv, real, mem) {\ priv->mem = real->mem; \ - real->mem = func; \ + real->mem = shadow##mem; \ } #define unwrap(priv, real, mem) {\ @@ -63,1400 +49,146 @@ int shadowGeneration; } static void -shadowRedisplay (ScreenPtr pScreen) +shadowRedisplay(ScreenPtr pScreen) { - shadowScrPriv(pScreen); - shadowBufPtr pBuf; + shadowBuf(pScreen); + RegionPtr pRegion; - for (pBuf = pScrPriv->pBuf; pBuf; pBuf = pBuf->pNext) - { - if (REGION_NOTEMPTY (pScreen, &pBuf->damage)) - { - REGION_INTERSECT (pScreen, &pBuf->damage, &pBuf->damage, - &WindowTable[pScreen->myNum]->borderClip); - (*pBuf->update) (pScreen, pBuf); - REGION_EMPTY (pScreen, &pBuf->damage); - } + if (!pBuf || !pBuf->pDamage || !pBuf->update) + return; + pRegion = DamageRegion(pBuf->pDamage); + if (REGION_NOTEMPTY(pScreen, pRegion)) { + (*pBuf->update)(pScreen, pBuf); + DamageEmpty(pBuf->pDamage); } } static void -shadowBlockHandler (pointer data, - OSTimePtr pTimeout, - pointer pRead) -{ - ScreenPtr pScreen = (ScreenPtr) data; - - shadowRedisplay (pScreen); -} - -static void -shadowWakeupHandler (pointer data, int i, pointer LastSelectMask) -{ -} - -static void -shadowDamageRegion (WindowPtr pWindow, RegionPtr pRegion) +shadowBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead) { - shadowBufPtr pBuf = shadowFindBuf (pWindow); - - if (!pBuf) - abort (); + ScreenPtr pScreen = (ScreenPtr) data; - REGION_INTERSECT(pWindow->drawable.pScreen, pRegion, pRegion, - &pWindow->borderClip); - REGION_UNION(pWindow->drawable.pScreen, &pBuf->damage, &pBuf->damage, - pRegion); -#ifdef ALWAYS_DISPLAY - shadowRedisplay (pWindow->drawable.pScreen); -#endif + shadowRedisplay(pScreen); } static void -shadowDamageBox (WindowPtr pWindow, BoxPtr pBox) +shadowWakeupHandler(pointer data, int i, pointer LastSelectMask) { - RegionRec region; - - REGION_INIT (pWindow->drawable.pScreen, ®ion, pBox, 1); - shadowDamageRegion (pWindow, ®ion); - REGION_UNINIT (pWindow->drawable.pScreen, ®ion); } static void -shadowDamageRect (WindowPtr pWindow, int x, int y, int w, int h) +shadowGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planeMask, char *pdstLine) { - BoxRec box; + ScreenPtr pScreen = pDrawable->pScreen; + shadowBuf(pScreen); - x += pWindow->drawable.x; - y += pWindow->drawable.y; - box.x1 = x; - box.x2 = x + w; - box.y1 = y; - box.y2 = y + h; - shadowDamageBox (pWindow, &box); + /* Many apps use GetImage to sync with the visable frame buffer */ + if (pDrawable->type == DRAWABLE_WINDOW) + shadowRedisplay(pScreen); + unwrap(pBuf, pScreen, GetImage); + pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); + wrap(pBuf, pScreen, GetImage); } -static void shadowValidateGC(GCPtr, unsigned long, DrawablePtr); -static void shadowChangeGC(GCPtr, unsigned long); -static void shadowCopyGC(GCPtr, unsigned long, GCPtr); -static void shadowDestroyGC(GCPtr); -static void shadowChangeClip(GCPtr, int, pointer, int); -static void shadowDestroyClip(GCPtr); -static void shadowCopyClip(GCPtr, GCPtr); - -GCFuncs shadowGCFuncs = { - shadowValidateGC, shadowChangeGC, shadowCopyGC, shadowDestroyGC, - shadowChangeClip, shadowDestroyClip, shadowCopyClip -}; - -extern GCOps shadowGCOps; +#define BACKWARDS_COMPATIBILITY static Bool -shadowCreateGC(GCPtr pGC) +shadowCloseScreen(int i, ScreenPtr pScreen) { - ScreenPtr pScreen = pGC->pScreen; - shadowScrPriv(pScreen); - shadowGCPriv(pGC); - Bool ret; + shadowBuf(pScreen); - unwrap (pScrPriv, pScreen, CreateGC); - if((ret = (*pScreen->CreateGC) (pGC))) { - pGCPriv->ops = NULL; - pGCPriv->funcs = pGC->funcs; - pGC->funcs = &shadowGCFuncs; - } - wrap (pScrPriv, pScreen, CreateGC, shadowCreateGC); - - return ret; -} - -void -shadowWrapGC (GCPtr pGC) -{ - shadowGCPriv(pGC); - - pGCPriv->ops = NULL; - pGCPriv->funcs = pGC->funcs; - pGC->funcs = &shadowGCFuncs; -} - -void -shadowUnwrapGC (GCPtr pGC) -{ - shadowGCPriv(pGC); - - pGC->funcs = pGCPriv->funcs; - if (pGCPriv->ops) - pGC->ops = pGCPriv->ops; -} - -#define SHADOW_GC_OP_PROLOGUE(pGC, pDraw) \ - shadowGCPriv(pGC); \ - GCFuncs *oldFuncs = pGC->funcs; \ - unwrap(pGCPriv, pGC, funcs); \ - unwrap(pGCPriv, pGC, ops); \ - -#define SHADOW_GC_OP_EPILOGUE(pGC, pDraw) \ - wrap(pGCPriv, pGC, funcs, oldFuncs); \ - wrap(pGCPriv, pGC, ops, &shadowGCOps) - -#define SHADOW_GC_FUNC_PROLOGUE(pGC) \ - shadowGCPriv(pGC); \ - unwrap(pGCPriv, pGC, funcs); \ - if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops) - -#define SHADOW_GC_FUNC_EPILOGUE(pGC) \ - wrap(pGCPriv, pGC, funcs, &shadowGCFuncs); \ - if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &shadowGCOps) - -static void -shadowValidateGC( - GCPtr pGC, - unsigned long changes, - DrawablePtr pDraw -){ - SHADOW_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->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); -} - -static void -shadowChangeClip ( - GCPtr pGC, - int type, - pointer pvalue, - int nrects -){ - SHADOW_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - SHADOW_GC_FUNC_EPILOGUE (pGC); -} - -static void -shadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - SHADOW_GC_FUNC_PROLOGUE (pgcDst); - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - SHADOW_GC_FUNC_EPILOGUE (pgcDst); -} - -static void -shadowDestroyClip(GCPtr pGC) -{ - SHADOW_GC_FUNC_PROLOGUE (pGC); - (* pGC->funcs->DestroyClip)(pGC); - SHADOW_GC_FUNC_EPILOGUE (pGC); -} - -#define IS_VISIBLE(pWin) 1 - - -#define TRIM_BOX(box, pGC) { \ - BoxPtr extents = &pGC->pCompositeClip->extents;\ - if(box.x1 < extents->x1) box.x1 = extents->x1; \ - if(box.x2 > extents->x2) box.x2 = extents->x2; \ - if(box.y1 < extents->y1) box.y1 = extents->y1; \ - if(box.y2 > extents->y2) box.y2 = extents->y2; \ - } - -#define TRANSLATE_BOX(box, pDraw) { \ - box.x1 += pDraw->x; \ - box.x2 += pDraw->x; \ - box.y1 += pDraw->y; \ - box.y2 += pDraw->y; \ - } - -#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \ - TRANSLATE_BOX(box, pDraw); \ - TRIM_BOX(box, pGC); \ - } - -#define BOX_NOT_EMPTY(box) \ - (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) - -#ifdef RENDER -static void -shadowComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - shadowScrPriv(pScreen); - - unwrap (pScrPriv, ps, Composite); - (*ps->Composite) (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - wrap (pScrPriv, ps, Composite, shadowComposite); - if (pDst->pDrawable->type == DRAWABLE_WINDOW) - shadowDamageRect ((WindowPtr) pDst->pDrawable, xDst, yDst, - width, height); -} - -static void -shadowGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - shadowScrPriv(pScreen); - int x, y; - int n; - GlyphPtr glyph; - - unwrap (pScrPriv, ps, Glyphs); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - wrap (pScrPriv, ps, Glyphs, shadowGlyphs); - if (pDst->pDrawable->type == DRAWABLE_WINDOW) - { - x = xSrc; - y = ySrc; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) - { - glyph = *glyphs++; - shadowDamageRect ((WindowPtr) pDst->pDrawable, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } - } -} + unwrap(pBuf, pScreen, GetImage); + unwrap(pBuf, pScreen, CloseScreen); + shadowRemove(pScreen, pBuf->pPixmap); + DamageDestroy(pBuf->pDamage); +#ifdef BACKWARDS_COMPATIBILITY + REGION_UNINIT(pScreen, &pBuf->damage); /* bc */ #endif - -/**********************************************************/ - - -static void -shadowFillSpans( - DrawablePtr pDraw, - GC *pGC, - int nInit, - DDXPointPtr pptInit, - int *pwidthInit, - int fSorted -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nInit) { - DDXPointPtr ppt = pptInit; - int *pwidth = pwidthInit; - int i = nInit; - BoxRec box; - - box.x1 = ppt->x; - box.x2 = box.x1 + *pwidth; - box.y2 = box.y1 = ppt->y; - - while(--i) { - ppt++; - pwidth++; - if(box.x1 > ppt->x) box.x1 = ppt->x; - if(box.x2 < (ppt->x + *pwidth)) - box.x2 = ppt->x + *pwidth; - if(box.y1 > ppt->y) box.y1 = ppt->y; - else if(box.y2 < ppt->y) box.y2 = ppt->y; - } - - box.y2++; - - (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDraw); - } - TRIM_BOX(box, pGC); - - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } else - (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); - - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); -} - -static void -shadowSetSpans( - DrawablePtr pDraw, - GCPtr pGC, - char *pcharsrc, - DDXPointPtr pptInit, - int *pwidthInit, - int nspans, - int fSorted -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nspans) { - DDXPointPtr ppt = pptInit; - int *pwidth = pwidthInit; - int i = nspans; - BoxRec box; - - box.x1 = ppt->x; - box.x2 = box.x1 + *pwidth; - box.y2 = box.y1 = ppt->y; - - while(--i) { - ppt++; - pwidth++; - if(box.x1 > ppt->x) box.x1 = ppt->x; - if(box.x2 < (ppt->x + *pwidth)) - box.x2 = ppt->x + *pwidth; - if(box.y1 > ppt->y) box.y1 = ppt->y; - else if(box.y2 < ppt->y) box.y2 = ppt->y; - } - - box.y2++; - - (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, - pwidthInit, nspans, fSorted); - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDraw); - } - TRIM_BOX(box, pGC); - - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } else - (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit, - pwidthInit, nspans, fSorted); - - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); + if (pBuf->pPixmap) + pScreen->DestroyPixmap(pBuf->pPixmap); + xfree(pBuf); + return pScreen->CloseScreen(i, pScreen); } +#ifdef BACKWARDS_COMPATIBILITY static void -shadowPutImage( - DrawablePtr pDraw, - GCPtr pGC, - int depth, - int x, int y, int w, int h, - int leftPad, - int format, - char *pImage -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, - leftPad, format, pImage); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw)) { - BoxRec box; - - box.x1 = x + pDraw->x; - box.x2 = box.x1 + w; - box.y1 = y + pDraw->y; - box.y2 = box.y1 + h; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static RegionPtr -shadowCopyArea( - DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty -){ - RegionPtr ret; - SHADOW_GC_OP_PROLOGUE(pGC, pDst); - ret = (*pGC->ops->CopyArea)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty); - SHADOW_GC_OP_EPILOGUE(pGC, pDst); - - if(IS_VISIBLE(pDst)) { - BoxRec box; - - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDst, &box); - } - - return ret; -} - -static RegionPtr -shadowCopyPlane( - DrawablePtr pSrc, - DrawablePtr pDst, - GCPtr pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty, - unsigned long bitPlane -){ - RegionPtr ret; - SHADOW_GC_OP_PROLOGUE(pGC, pDst); - ret = (*pGC->ops->CopyPlane)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); - SHADOW_GC_OP_EPILOGUE(pGC, pDst); - - if(IS_VISIBLE(pDst)) { - BoxRec box; - - box.x1 = dstx + pDst->x; - box.x2 = box.x1 + width; - box.y1 = dsty + pDst->y; - box.y2 = box.y1 + height; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDst, &box); - } - - return ret; -} - -static void -shadowPolyPoint( - DrawablePtr pDraw, - GCPtr pGC, - int mode, - int npt, - xPoint *pptInit -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && npt) { - BoxRec box; - - box.x2 = box.x1 = pptInit->x; - box.y2 = box.y1 = pptInit->y; - - /* this could be slow if the points were spread out */ - - while(--npt) { - pptInit++; - if(box.x1 > pptInit->x) box.x1 = pptInit->x; - else if(box.x2 < pptInit->x) box.x2 = pptInit->x; - if(box.y1 > pptInit->y) box.y1 = pptInit->y; - else if(box.y2 < pptInit->y) box.y2 = pptInit->y; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowPolylines( - DrawablePtr pDraw, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr pptInit -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - - if(IS_VISIBLE(pDraw) && npt) { - BoxRec box; - int extra = pGC->lineWidth >> 1; - - box.x2 = box.x1 = pptInit->x; - box.y2 = box.y1 = pptInit->y; - - if(npt > 1) { - if(pGC->joinStyle == JoinMiter) - extra = 6 * pGC->lineWidth; - else if(pGC->capStyle == CapProjecting) - extra = pGC->lineWidth; - } - - if(mode == CoordModePrevious) { - int x = box.x1; - int y = box.y1; - while(--npt) { - pptInit++; - x += pptInit->x; - y += pptInit->y; - if(box.x1 > x) box.x1 = x; - else if(box.x2 < x) box.x2 = x; - if(box.y1 > y) box.y1 = y; - else if(box.y2 < y) box.y2 = y; - } - } else { - while(--npt) { - pptInit++; - if(box.x1 > pptInit->x) box.x1 = pptInit->x; - else if(box.x2 < pptInit->x) box.x2 = pptInit->x; - if(box.y1 > pptInit->y) box.y1 = pptInit->y; - else if(box.y2 < pptInit->y) box.y2 = pptInit->y; - } - } - - box.x2++; - box.y2++; - - if(extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowPolySegment( - DrawablePtr pDraw, - GCPtr pGC, - int nseg, - xSegment *pSeg -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nseg) { - BoxRec box; - int extra = pGC->lineWidth; - - if(pGC->capStyle != CapProjecting) - extra >>= 1; - - if(pSeg->x2 > pSeg->x1) { - box.x1 = pSeg->x1; - box.x2 = pSeg->x2; - } else { - box.x2 = pSeg->x1; - box.x1 = pSeg->x2; - } - - if(pSeg->y2 > pSeg->y1) { - box.y1 = pSeg->y1; - box.y2 = pSeg->y2; - } else { - box.y2 = pSeg->y1; - box.y1 = pSeg->y2; - } - - while(--nseg) { - pSeg++; - if(pSeg->x2 > pSeg->x1) { - if(pSeg->x1 < box.x1) box.x1 = pSeg->x1; - if(pSeg->x2 > box.x2) box.x2 = pSeg->x2; - } else { - if(pSeg->x2 < box.x1) box.x1 = pSeg->x2; - if(pSeg->x1 > box.x2) box.x2 = pSeg->x1; - } - if(pSeg->y2 > pSeg->y1) { - if(pSeg->y1 < box.y1) box.y1 = pSeg->y1; - if(pSeg->y2 > box.y2) box.y2 = pSeg->y2; - } else { - if(pSeg->y2 < box.y1) box.y1 = pSeg->y2; - if(pSeg->y1 > box.y2) box.y2 = pSeg->y1; - } - } - - box.x2++; - box.y2++; - - if(extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowPolyRectangle( - DrawablePtr pDraw, - GCPtr pGC, - int nRects, - xRectangle *pRects -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolyRectangle)(pDraw, pGC, nRects, pRects); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nRects) - { - BoxRec box; - int offset1, offset2, offset3; - - offset2 = pGC->lineWidth; - if(!offset2) offset2 = 1; - offset1 = offset2 >> 1; - offset3 = offset2 - offset1; - - while(nRects--) - { - box.x1 = pRects->x - offset1; - box.y1 = pRects->y - offset1; - box.x2 = box.x1 + pRects->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - - box.x1 = pRects->x - offset1; - box.y1 = pRects->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - - box.x1 = pRects->x + pRects->width - offset1; - box.y1 = pRects->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRects->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - - box.x1 = pRects->x - offset1; - box.y1 = pRects->y + pRects->height - offset1; - box.x2 = box.x1 + pRects->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - - pRects++; - } - } - } - -static void -shadowPolyArc( - DrawablePtr pDraw, - GCPtr pGC, - int narcs, - xArc *parcs -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && narcs) { - int extra = pGC->lineWidth >> 1; - BoxRec box; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - while(--narcs) { - parcs++; - if(box.x1 > parcs->x) box.x1 = parcs->x; - if(box.x2 < (parcs->x + parcs->width)) - box.x2 = parcs->x + parcs->width; - if(box.y1 > parcs->y) box.y1 = parcs->y; - if(box.y2 < (parcs->y + parcs->height)) - box.y2 = parcs->y + parcs->height; - } - - if(extra) { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowFillPolygon( - DrawablePtr pDraw, - GCPtr pGC, - int shape, - int mode, - int count, - DDXPointPtr pptInit -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && (count > 2)) { - DDXPointPtr ppt = pptInit; - int i = count; - BoxRec box; - - box.x2 = box.x1 = ppt->x; - box.y2 = box.y1 = ppt->y; - - if(mode != CoordModeOrigin) { - int x = box.x1; - int y = box.y1; - while(--i) { - ppt++; - x += ppt->x; - y += ppt->y; - if(box.x1 > x) box.x1 = x; - else if(box.x2 < x) box.x2 = x; - if(box.y1 > y) box.y1 = y; - else if(box.y2 < y) box.y2 = y; - } - } else { - while(--i) { - ppt++; - if(box.x1 > ppt->x) box.x1 = ppt->x; - else if(box.x2 < ppt->x) box.x2 = ppt->x; - if(box.y1 > ppt->y) box.y1 = ppt->y; - else if(box.y2 < ppt->y) box.y2 = ppt->y; - } - } - - box.x2++; - box.y2++; - - (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit); - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } else - (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit); - - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); -} - - -static void -shadowPolyFillRect( - DrawablePtr pDraw, - GCPtr pGC, - int nRectsInit, - xRectangle *pRectsInit -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nRectsInit) { - BoxRec box; - xRectangle *pRects = pRectsInit; - int nRects = nRectsInit; - - box.x1 = pRects->x; - box.x2 = box.x1 + pRects->width; - box.y1 = pRects->y; - box.y2 = box.y1 + pRects->height; - - while(--nRects) { - pRects++; - if(box.x1 > pRects->x) box.x1 = pRects->x; - if(box.x2 < (pRects->x + pRects->width)) - box.x2 = pRects->x + pRects->width; - if(box.y1 > pRects->y) box.y1 = pRects->y; - if(box.y2 < (pRects->y + pRects->height)) - box.y2 = pRects->y + pRects->height; - } - - /* cfb messes with the pRectsInit so we have to do our - calculations first */ - - (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit); - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } else - (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit); - - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); -} - - -static void -shadowPolyFillArc( - DrawablePtr pDraw, - GCPtr pGC, - int narcs, - xArc *parcs -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && narcs) { - BoxRec box; - - box.x1 = parcs->x; - box.x2 = box.x1 + parcs->width; - box.y1 = parcs->y; - box.y2 = box.y1 + parcs->height; - - /* should I break these up instead ? */ - - while(--narcs) { - parcs++; - if(box.x1 > parcs->x) box.x1 = parcs->x; - if(box.x2 < (parcs->x + parcs->width)) - box.x2 = parcs->x + parcs->width; - if(box.y1 > parcs->y) box.y1 = parcs->y; - if(box.y2 < (parcs->y + parcs->height)) - box.y2 = parcs->y + parcs->height; - } - - TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } - -} - -static int -shadowPolyText8( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - char *chars -){ - int width; - - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - width -= x; - - if(IS_VISIBLE(pDraw) && (width > 0)) { - BoxRec box; - - /* ugh */ - box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); - - if(count > 1) { - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } - - return (width + x); -} - -static int -shadowPolyText16( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars -){ - int width; - - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - width -= x; - - if(IS_VISIBLE(pDraw) && (width > 0)) { - BoxRec box; - - /* ugh */ - box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing); - - if(count > 1) { - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } - - return (width + x); -} - -static void -shadowImageText8( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - char *chars -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && count) { - int top, bot, Min, Max; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if(Min > 0) Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if(Max < 0) Max = 0; - - /* ugh */ - box.x1 = pDraw->x + x + Min + - FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} -static void -shadowImageText16( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && count) { - int top, bot, Min, Max; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - Min = count * FONTMINBOUNDS(pGC->font, characterWidth); - if(Min > 0) Min = 0; - Max = count * FONTMAXBOUNDS(pGC->font, characterWidth); - if(Max < 0) Max = 0; - - /* ugh */ - box.x1 = pDraw->x + x + Min + - FONTMINBOUNDS(pGC->font, leftSideBearing); - box.x2 = pDraw->x + x + Max + - FONTMAXBOUNDS(pGC->font, rightSideBearing); - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - - -static void -shadowImageGlyphBlt( - DrawablePtr pDraw, - GCPtr pGC, - int x, int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyph, - ppci, pglyphBase); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nglyph) { - int top, bot, width = 0; - BoxRec box; - - top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font)); - bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font)); - - box.x1 = ppci[0]->metrics.leftSideBearing; - if(box.x1 > 0) box.x1 = 0; - box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing - - ppci[nglyph - 1]->metrics.characterWidth; - if(box.x2 < 0) box.x2 = 0; - - box.x2 += pDraw->x + x; - box.x1 += pDraw->x + x; - - while(nglyph--) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if(width > 0) - box.x2 += width; - else - box.x1 += width; - - box.y1 = pDraw->y + y - top; - box.y2 = pDraw->y + y + bot; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowPolyGlyphBlt( - DrawablePtr pDraw, - GCPtr pGC, - int x, int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyph, - ppci, pglyphBase); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw) && nglyph) { - BoxRec box; - - /* ugh */ - box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing; - box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing; - - if(nglyph > 1) { - int width = 0; - - while(--nglyph) { - width += (*ppci)->metrics.characterWidth; - ppci++; - } - - if(width > 0) box.x2 += width; - else box.x1 += width; - } - - box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent); - box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent); - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - -static void -shadowPushPixels( - GCPtr pGC, - PixmapPtr pBitMap, - DrawablePtr pDraw, - int dx, int dy, int xOrg, int yOrg -){ - SHADOW_GC_OP_PROLOGUE(pGC, pDraw); - (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg); - SHADOW_GC_OP_EPILOGUE(pGC, pDraw); - - if(IS_VISIBLE(pDraw)) { - BoxRec box; - - box.x1 = xOrg; - box.y1 = yOrg; - - if(!pGC->miTranslate) { - box.x1 += pDraw->x; - box.y1 += pDraw->y; - } - - box.x2 = box.x1 + dx; - box.y2 = box.y1 + dy; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - shadowDamageBox ((WindowPtr) pDraw, &box); - } -} - - -static void -shadowPaintWindow( - WindowPtr pWindow, - RegionPtr prgn, - int what -){ - ScreenPtr pScreen = pWindow->drawable.pScreen; - shadowScrPriv(pScreen); - - if(what == PW_BACKGROUND) { - unwrap (pScrPriv, pScreen, PaintWindowBackground); - (*pScreen->PaintWindowBackground) (pWindow, prgn, what); - wrap (pScrPriv, pScreen, PaintWindowBackground, shadowPaintWindow); - } else { - unwrap (pScrPriv, pScreen, PaintWindowBorder); - (*pScreen->PaintWindowBorder) (pWindow, prgn, what); - wrap (pScrPriv, pScreen, PaintWindowBorder, shadowPaintWindow); - } - shadowDamageRegion (pWindow, prgn); -} - - -static void -shadowCopyWindow( - WindowPtr pWindow, - DDXPointRec ptOldOrg, - RegionPtr prgn -){ - ScreenPtr pScreen = pWindow->drawable.pScreen; - shadowScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CopyWindow); - (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgn); - wrap (pScrPriv, pScreen, CopyWindow, shadowCopyWindow); - shadowDamageRegion (pWindow, prgn); -} - -GCOps shadowGCOps = { - shadowFillSpans, shadowSetSpans, - shadowPutImage, shadowCopyArea, - shadowCopyPlane, shadowPolyPoint, - shadowPolylines, shadowPolySegment, - shadowPolyRectangle, shadowPolyArc, - shadowFillPolygon, shadowPolyFillRect, - shadowPolyFillArc, shadowPolyText8, - shadowPolyText16, shadowImageText8, - shadowImageText16, shadowImageGlyphBlt, - shadowPolyGlyphBlt, shadowPushPixels, -#ifdef NEED_LINEHELPER - NULL, -#endif - {NULL} /* devPrivate */ -}; - -static void -shadowGetImage (DrawablePtr pDrawable, - int sx, - int sy, - int w, - int h, - unsigned int format, - unsigned long planeMask, - char * pdstLine) +shadowReportFunc(DamagePtr pDamage, RegionPtr pRegion, void *closure) { - ScreenPtr pScreen = pDrawable->pScreen; - shadowScrPriv(pScreen); + ScreenPtr pScreen = closure; + shadowBufPtr pBuf = pScreen->devPrivates[shadowScrPrivateIndex].ptr; - /* Many apps use GetImage to sync with the visable frame buffer */ - if (pDrawable->type == DRAWABLE_WINDOW) - shadowRedisplay (pScreen); - unwrap (pScrPriv, pScreen, GetImage); - (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planeMask, pdstLine); - wrap (pScrPriv, pScreen, GetImage, shadowGetImage); -} + /* Register the damaged region, use DamageReportNone below when we + * want to break BC below... */ + REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage, pRegion); -static void -shadowRestoreAreas (PixmapPtr pPixmap, - RegionPtr prgn, - int xorg, - int yorg, - WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - shadowScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas); - (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn, - xorg, yorg, pWin); - wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas, - shadowRestoreAreas); - shadowDamageRegion (pWin, prgn); -} - -static Bool -shadowCloseScreen (int i, ScreenPtr pScreen) -{ - shadowScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, CreateGC); - unwrap (pScrPriv, pScreen, PaintWindowBackground); - unwrap (pScrPriv, pScreen, PaintWindowBorder); - unwrap (pScrPriv, pScreen, CopyWindow); - unwrap (pScrPriv, pScreen, CloseScreen); - unwrap (pScrPriv, pScreen, GetImage); - unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas); - xfree (pScrPriv); - return (*pScreen->CloseScreen) (i, pScreen); + /* + * BC hack. In 7.0 and earlier several drivers would inspect the + * 'damage' member directly, so we have to keep it existing. + */ + REGION_COPY(pScreen, &pBuf->damage, pRegion); } +#endif Bool -shadowSetup (ScreenPtr pScreen) +shadowSetup(ScreenPtr pScreen) { - shadowScrPrivPtr pScrPriv; -#ifdef RENDER - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); -#endif + shadowBufPtr pBuf; + + if (!DamageSetup(pScreen)) + return FALSE; - if (shadowGeneration != serverGeneration) - { - shadowScrPrivateIndex = AllocateScreenPrivateIndex (); + if (shadowGeneration != serverGeneration) { + shadowScrPrivateIndex = AllocateScreenPrivateIndex(); if (shadowScrPrivateIndex == -1) return FALSE; - shadowGCPrivateIndex = AllocateGCPrivateIndex (); - if (shadowGCPrivateIndex == -1) - return FALSE; shadowGeneration = serverGeneration; } - if (!AllocateGCPrivate (pScreen, shadowGCPrivateIndex, sizeof (shadowGCPrivRec))) - return FALSE; - pScrPriv = (shadowScrPrivPtr) xalloc (sizeof (shadowScrPrivRec)); - if (!pScrPriv) - return FALSE; - if (!RegisterBlockAndWakeupHandlers (shadowBlockHandler, - shadowWakeupHandler, - (pointer) pScreen)) + pBuf = (shadowBufPtr) xalloc(sizeof(shadowBufRec)); + if (!pBuf) + return FALSE; +#ifdef BACKWARDS_COMPATIBILITY + pBuf->pDamage = DamageCreate((DamageReportFunc)shadowReportFunc, + (DamageDestroyFunc)NULL, + DamageReportRawRegion, + TRUE, pScreen, pScreen); +#else + pBuf->pDamage = DamageCreate((DamageReportFunc)NULL, + (DamageDestroyFunc)NULL, + DamageReportNone, + TRUE, pScreen, pScreen); +#endif + if (!pBuf->pDamage) { + xfree(pBuf); return FALSE; - - wrap (pScrPriv, pScreen, CreateGC, shadowCreateGC); - wrap (pScrPriv, pScreen, PaintWindowBackground, shadowPaintWindow); - wrap (pScrPriv, pScreen, PaintWindowBorder, shadowPaintWindow); - wrap (pScrPriv, pScreen, CopyWindow, shadowCopyWindow); - wrap (pScrPriv, pScreen, CloseScreen, shadowCloseScreen); - wrap (pScrPriv, pScreen, GetImage, shadowGetImage); - wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas, - shadowRestoreAreas); -#ifdef RENDER - if (ps) { - wrap (pScrPriv, ps, Glyphs, shadowGlyphs); - wrap (pScrPriv, ps, Composite, shadowComposite); } + + wrap(pBuf, pScreen, CloseScreen); + wrap(pBuf, pScreen, GetImage); + pBuf->update = 0; + pBuf->window = 0; + pBuf->pPixmap = 0; + pBuf->closure = 0; + pBuf->randr = 0; +#ifdef BACKWARDS_COMPATIBILITY + REGION_NULL(pScreen, &pBuf->damage); /* bc */ #endif - pScrPriv->pBuf = 0; - pScreen->devPrivates[shadowScrPrivateIndex].ptr = (pointer) pScrPriv; + pScreen->devPrivates[shadowScrPrivateIndex].ptr = (pointer) pBuf; return TRUE; } Bool -shadowAdd (ScreenPtr pScreen, - PixmapPtr pPixmap, - ShadowUpdateProc update, - ShadowWindowProc window, - int randr, - void *closure) +shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update, + ShadowWindowProc window, int randr, void *closure) { - shadowScrPriv(pScreen); - shadowBufPtr pBuf; + shadowBuf(pScreen); - pBuf = (shadowBufPtr) xalloc (sizeof (shadowBufRec)); - if (!pBuf) + if (!RegisterBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler, + (pointer)pScreen)) return FALSE; + /* * Map simple rotation values to bitmasks; fortunately, * these are all unique @@ -1475,70 +207,49 @@ shadowAdd (ScreenPtr pScreen, randr = SHADOW_ROTATE_270; break; } - pBuf->pPixmap = pPixmap; pBuf->update = update; pBuf->window = window; - REGION_NULL(pScreen, &pBuf->damage); - pBuf->pNext = pScrPriv->pBuf; pBuf->randr = randr; pBuf->closure = 0; - pScrPriv->pBuf = pBuf; + pBuf->pPixmap = pPixmap; + DamageRegister(&pPixmap->drawable, pBuf->pDamage); return TRUE; } void -shadowRemove (ScreenPtr pScreen, PixmapPtr pPixmap) -{ - shadowScrPriv(pScreen); - shadowBufPtr pBuf, *pPrev; - - for (pPrev = &pScrPriv->pBuf; (pBuf = *pPrev); pPrev = &pBuf->pNext) - if (pBuf->pPixmap == pPixmap) - { - REGION_UNINIT (pScreen, &pBuf->damage); - *pPrev = pBuf->pNext; - xfree (pBuf); - break; - } -} - -shadowBufPtr -shadowFindBuf (WindowPtr pWindow) +shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap) { - ScreenPtr pScreen = pWindow->drawable.pScreen; - shadowScrPriv(pScreen); - shadowBufPtr pBuf, *pPrev; - PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow); + shadowBuf(pScreen); - for (pPrev = &pScrPriv->pBuf; (pBuf = *pPrev); pPrev = &pBuf->pNext) - { - if (!pBuf->pPixmap) - pBuf->pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - if (pBuf->pPixmap == pPixmap) - { - /* - * Reorder so this one is first next time - */ - if (pPrev != &pScrPriv->pBuf) - { - *pPrev = pBuf->pNext; - pBuf->pNext = pScrPriv->pBuf; - pScrPriv->pBuf = pBuf; - } - return pBuf; - } + if (pBuf->pPixmap) { + DamageUnregister(&pBuf->pPixmap->drawable, pBuf->pDamage); + pBuf->update = 0; + pBuf->window = 0; + pBuf->randr = 0; + pBuf->closure = 0; + pBuf->pPixmap = 0; } - return 0; + + RemoveBlockAndWakeupHandlers(shadowBlockHandler, shadowWakeupHandler, + (pointer) pScreen); } Bool -shadowInit (ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window) +shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window) { - if (!shadowSetup (pScreen)) + PixmapPtr pPixmap; + + pPixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height, + pScreen->rootDepth); + if (!pPixmap) return FALSE; - - if (!shadowAdd (pScreen, 0, update, window, SHADOW_ROTATE_0, 0)) + + if (!shadowSetup(pScreen)) { + pScreen->DestroyPixmap(pPixmap); return FALSE; + } + + shadowAdd(pScreen, pPixmap, update, window, SHADOW_ROTATE_0, 0); return TRUE; } diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h index 85b2604f5..2b51f2c82 100644 --- a/miext/shadow/shadow.h +++ b/miext/shadow/shadow.h @@ -31,6 +31,8 @@ #include "picturestr.h" #endif +#include "damage.h" +#include "damagestr.h" typedef struct _shadowBuf *shadowBufPtr; typedef void (*ShadowUpdateProc) (ScreenPtr pScreen, @@ -47,14 +49,19 @@ typedef void *(*ShadowWindowProc) (ScreenPtr pScreen, CARD32 *size, void *closure); +/* BC hack: do not move the damage member. see shadow.c for explanation. */ typedef struct _shadowBuf { - shadowBufPtr pNext; + DamagePtr pDamage; ShadowUpdateProc update; ShadowWindowProc window; RegionRec damage; PixmapPtr pPixmap; void *closure; int randr; + + /* screen wrappers */ + GetImageProcPtr GetImage; + CloseScreenProcPtr CloseScreen; } shadowBufRec; /* Match defines from randr extension */ @@ -68,25 +75,11 @@ typedef struct _shadowBuf { #define SHADOW_REFLECT_Y 32 #define SHADOW_REFLECT_ALL (SHADOW_REFLECT_X|SHADOW_REFLECT_Y) -typedef struct _shadowScrPriv { - PaintWindowBackgroundProcPtr PaintWindowBackground; - PaintWindowBorderProcPtr PaintWindowBorder; - CopyWindowProcPtr CopyWindow; - CloseScreenProcPtr CloseScreen; - CreateGCProcPtr CreateGC; - GetImageProcPtr GetImage; -#ifdef RENDER - CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; -#endif - shadowBufPtr pBuf; - BSFuncRec BackingStoreFuncs; -} shadowScrPrivRec, *shadowScrPrivPtr; - extern int shadowScrPrivateIndex; -#define shadowGetScrPriv(pScr) ((shadowScrPrivPtr) (pScr)->devPrivates[shadowScrPrivateIndex].ptr) -#define shadowScrPriv(pScr) shadowScrPrivPtr pScrPriv = shadowGetScrPriv(pScr) +#define shadowGetBuf(pScr) ((shadowBufPtr) (pScr)->devPrivates[shadowScrPrivateIndex].ptr) +#define shadowBuf(pScr) shadowBufPtr pBuf = shadowGetBuf(pScr) +#define shadowDamage(pBuf) DamageRegion(pBuf->pDamage) Bool shadowSetup (ScreenPtr pScreen); @@ -170,10 +163,4 @@ shadowUpdateProc shadowUpdatePlanar4Weak(void); shadowUpdateProc shadowUpdatePlanar4x8Weak(void); shadowUpdateProc shadowUpdateRotatePackedWeak(void); -void -shadowWrapGC (GCPtr pGC); - -void -shadowUnwrapGC (GCPtr pGC); - #endif /* _SHADOW_H_ */ diff --git a/miext/shadow/shpacked.c b/miext/shadow/shpacked.c index 3fdee1473..8989760d7 100644 --- a/miext/shadow/shpacked.c +++ b/miext/shadow/shpacked.c @@ -43,7 +43,7 @@ void shadowUpdatePacked (ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = &pBuf->damage; + RegionPtr damage = shadowDamage (pBuf); PixmapPtr pShadow = pBuf->pPixmap; int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); diff --git a/miext/shadow/shplanar.c b/miext/shadow/shplanar.c index 979905b86..3a8f05a85 100644 --- a/miext/shadow/shplanar.c +++ b/miext/shadow/shplanar.c @@ -89,7 +89,7 @@ void shadowUpdatePlanar4 (ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = &pBuf->damage; + RegionPtr damage = shadowDamage (pBuf); PixmapPtr pShadow = pBuf->pPixmap; int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); diff --git a/miext/shadow/shplanar8.c b/miext/shadow/shplanar8.c index f1d87dc50..fc45a8086 100644 --- a/miext/shadow/shplanar8.c +++ b/miext/shadow/shplanar8.c @@ -92,7 +92,7 @@ void shadowUpdatePlanar4x8 (ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = &pBuf->damage; + RegionPtr damage = shadowDamage (pBuf); PixmapPtr pShadow = pBuf->pPixmap; int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); diff --git a/miext/shadow/shrotate.c b/miext/shadow/shrotate.c index 927bc61be..8e46fcecf 100644 --- a/miext/shadow/shrotate.c +++ b/miext/shadow/shrotate.c @@ -53,7 +53,7 @@ void shadowUpdateRotatePacked (ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = &pBuf->damage; + RegionPtr damage = shadowDamage (pBuf); PixmapPtr pShadow = pBuf->pPixmap; int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); diff --git a/miext/shadow/shrotpack.h b/miext/shadow/shrotpack.h index 062d8c394..7ed94fc1f 100644 --- a/miext/shadow/shrotpack.h +++ b/miext/shadow/shrotpack.h @@ -96,7 +96,7 @@ void FUNC (ScreenPtr pScreen, shadowBufPtr pBuf) { - RegionPtr damage = &pBuf->damage; + RegionPtr damage = shadowDamage (pBuf); PixmapPtr pShadow = pBuf->pPixmap; int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); -- cgit v1.2.3