diff options
Diffstat (limited to 'xorg-server/miext')
-rw-r--r-- | xorg-server/miext/damage/damage.c | 4256 | ||||
-rw-r--r-- | xorg-server/miext/damage/damage.h | 264 | ||||
-rw-r--r-- | xorg-server/miext/damage/makefile | 7 | ||||
-rw-r--r-- | xorg-server/miext/rootless/makefile | 10 | ||||
-rw-r--r-- | xorg-server/miext/rootless/rootlessGC.c | 3 | ||||
-rw-r--r-- | xorg-server/miext/rootless/rootlessScreen.c | 1508 | ||||
-rw-r--r-- | xorg-server/miext/rootless/rootlessValTree.c | 1242 | ||||
-rw-r--r-- | xorg-server/miext/rootless/rootlessWindow.c | 18 | ||||
-rw-r--r-- | xorg-server/miext/rootless/xplugin.h | 592 | ||||
-rw-r--r-- | xorg-server/miext/shadow/makefile | 25 | ||||
-rw-r--r-- | xorg-server/miext/sync/makefile | 4 |
11 files changed, 4289 insertions, 3640 deletions
diff --git a/xorg-server/miext/damage/damage.c b/xorg-server/miext/damage/damage.c index d79121165..de7b53543 100644 --- a/xorg-server/miext/damage/damage.c +++ b/xorg-server/miext/damage/damage.c @@ -1,2128 +1,2128 @@ -/* - * Copyright © 2003 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 - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stdlib.h> - -#include <X11/X.h> -#include "scrnintstr.h" -#include "windowstr.h" -#include <X11/fonts/font.h> -#include "dixfontstr.h" -#include <X11/fonts/fontstruct.h> -#include "mi.h" -#include "regionstr.h" -#include "globals.h" -#include "gcstruct.h" -#include "damage.h" -#include "damagestr.h" -#ifdef COMPOSITE -#include "cw.h" -#endif - -#define wrap(priv, real, mem, func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv, real, mem) {\ - real->mem = priv->mem; \ -} - -#define BOX_SAME(a,b) \ - ((a)->x1 == (b)->x1 && \ - (a)->y1 == (b)->y1 && \ - (a)->x2 == (b)->x2 && \ - (a)->y2 == (b)->y2) - -#define DAMAGE_VALIDATE_ENABLE 0 -#define DAMAGE_DEBUG_ENABLE 0 -#if DAMAGE_DEBUG_ENABLE -#define DAMAGE_DEBUG(x) ErrorF x -#else -#define DAMAGE_DEBUG(x) -#endif - -#define getPixmapDamageRef(pPixmap) ((DamagePtr *) \ - dixLookupPrivateAddr(&(pPixmap)->devPrivates, damagePixPrivateKey)) - -#define pixmapDamage(pPixmap) damagePixPriv(pPixmap) - -static DevPrivateKeyRec damageScrPrivateKeyRec; -#define damageScrPrivateKey (&damageScrPrivateKeyRec) -static DevPrivateKeyRec damagePixPrivateKeyRec; -#define damagePixPrivateKey (&damagePixPrivateKeyRec) -static DevPrivateKeyRec damageGCPrivateKeyRec; -#define damageGCPrivateKey (&damageGCPrivateKeyRec) -static DevPrivateKeyRec damageWinPrivateKeyRec; -#define damageWinPrivateKey (&damageWinPrivateKeyRec) - -static DamagePtr * -getDrawableDamageRef (DrawablePtr pDrawable) -{ - PixmapPtr pPixmap; - - if (WindowDrawable(pDrawable->type)) - { - ScreenPtr pScreen = pDrawable->pScreen; - - pPixmap = 0; - if (pScreen->GetWindowPixmap -#ifdef ROOTLESS_WORKAROUND - && ((WindowPtr)pDrawable)->viewable -#endif - ) - pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable); - - if (!pPixmap) - { - damageScrPriv(pScreen); - - return &pScrPriv->pScreenDamage; - } - } - else - pPixmap = (PixmapPtr) pDrawable; - return getPixmapDamageRef (pPixmap); -} - -#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable)) -#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable) - -#define drawableDamage(pDrawable) \ - DamagePtr pDamage = getDrawableDamage(pDrawable) - -#define windowDamage(pWin) drawableDamage(&(pWin)->drawable) - -#define winDamageRef(pWindow) \ - DamagePtr *pPrev = (DamagePtr *) \ - dixLookupPrivateAddr(&(pWindow)->devPrivates, damageWinPrivateKey) - -static void -damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pDamageRegion) -{ - BoxRec tmpBox; - RegionRec tmpRegion, newDamage; - Bool was_empty; - - RegionUnion(&newDamage, pOldDamage, pDamageRegion); - - switch (pDamage->damageLevel) { - case DamageReportRawRegion: - (*pDamage->damageReportPostRendering) (pDamage, pDamageRegion, pDamage->closure); - break; - case DamageReportDeltaRegion: - RegionNull(&tmpRegion); - RegionSubtract(&tmpRegion, pDamageRegion, pOldDamage); - if (RegionNotEmpty(&tmpRegion)) { - (*pDamage->damageReportPostRendering) (pDamage, &tmpRegion, pDamage->closure); - } - RegionUninit(&tmpRegion); - break; - case DamageReportBoundingBox: - tmpBox = *RegionExtents(pOldDamage); - if (!BOX_SAME (&tmpBox, RegionExtents(&newDamage))) { - (*pDamage->damageReportPostRendering) (pDamage, &newDamage, - pDamage->closure); - } - break; - case DamageReportNonEmpty: - was_empty = !RegionNotEmpty(pOldDamage); - if (was_empty && RegionNotEmpty(&newDamage)) { - (*pDamage->damageReportPostRendering) (pDamage, &newDamage, - pDamage->closure); - } - break; - case DamageReportNone: - break; - } - - RegionUninit(&newDamage); -} - -#if DAMAGE_DEBUG_ENABLE -static void -_damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where) -#define damageRegionAppend(d,r,c,m) _damageRegionAppend(d,r,c,m,__FUNCTION__) -#else -static void -damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, - int subWindowMode) -#endif -{ - ScreenPtr pScreen = pDrawable->pScreen; - damageScrPriv(pScreen); - drawableDamage(pDrawable); - DamagePtr pNext; - RegionRec clippedRec; - RegionPtr pDamageRegion; - RegionRec pixClip; - int draw_x, draw_y; -#ifdef COMPOSITE - int screen_x = 0, screen_y = 0; -#endif - - /* short circuit for empty regions */ - if (!RegionNotEmpty(pRegion)) - return; - -#ifdef COMPOSITE - /* - * When drawing to a pixmap which is storing window contents, - * the region presented is in pixmap relative coordinates which - * need to be converted to screen relative coordinates - */ - if (pDrawable->type != DRAWABLE_WINDOW) - { - screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x; - screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y; - } - if (screen_x || screen_y) - RegionTranslate(pRegion, screen_x, screen_y); -#endif - - if (pDrawable->type == DRAWABLE_WINDOW && - ((WindowPtr)(pDrawable))->backingStore == NotUseful) - { - if (subWindowMode == ClipByChildren) - { - RegionIntersect(pRegion, pRegion, - &((WindowPtr)(pDrawable))->clipList); - } - else if (subWindowMode == IncludeInferiors) - { - RegionPtr pTempRegion = - NotClippedByChildren((WindowPtr)(pDrawable)); - RegionIntersect(pRegion, pRegion, pTempRegion); - RegionDestroy(pTempRegion); - } - /* If subWindowMode is set to an invalid value, don't perform - * any drawable-based clipping. */ - } - - - RegionNull(&clippedRec); - for (; pDamage; pDamage = pNext) - { - pNext = pDamage->pNext; - /* - * Check for internal damage and don't send events - */ - if (pScrPriv->internalLevel > 0 && !pDamage->isInternal) - { - DAMAGE_DEBUG (("non internal damage, skipping at %d\n", - pScrPriv->internalLevel)); - continue; - } - /* - * Check for unrealized windows - */ - if (pDamage->pDrawable->type == DRAWABLE_WINDOW && - !((WindowPtr) (pDamage->pDrawable))->realized) - { - continue; - } - - draw_x = pDamage->pDrawable->x; - draw_y = pDamage->pDrawable->y; -#ifdef COMPOSITE - /* - * Need to move everyone to screen coordinates - * XXX what about off-screen pixmaps with non-zero x/y? - */ - if (!WindowDrawable(pDamage->pDrawable->type)) - { - draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x; - draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y; - } -#endif - - /* - * Clip against border or pixmap bounds - */ - - pDamageRegion = pRegion; - if (clip || pDamage->pDrawable != pDrawable) - { - pDamageRegion = &clippedRec; - if (pDamage->pDrawable->type == DRAWABLE_WINDOW) { - RegionIntersect(pDamageRegion, pRegion, - &((WindowPtr)(pDamage->pDrawable))->borderClip); - } else { - BoxRec box; - box.x1 = draw_x; - box.y1 = draw_y; - box.x2 = draw_x + pDamage->pDrawable->width; - box.y2 = draw_y + pDamage->pDrawable->height; - RegionInit(&pixClip, &box, 1); - RegionIntersect(pDamageRegion, pRegion, &pixClip); - RegionUninit(&pixClip); - } - /* - * Short circuit empty results - */ - if (!RegionNotEmpty(pDamageRegion)) - continue; - } - - DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n", - where, - pDamageRegion->extents.x2 - pDamageRegion->extents.x1, - pDamageRegion->extents.y2 - pDamageRegion->extents.y1, - pDamageRegion->extents.x1, pDamageRegion->extents.y1, - pDrawable->id, pDamage->pDrawable->id)); - - /* - * Move region to target coordinate space - */ - if (draw_x || draw_y) - RegionTranslate(pDamageRegion, -draw_x, -draw_y); - - /* Store damage region if needed after submission. */ - if (pDamage->reportAfter || pDamage->damageMarker) - RegionUnion(&pDamage->pendingDamage, - &pDamage->pendingDamage, pDamageRegion); - - /* Duplicate current damage if needed. */ - if (pDamage->damageMarker) - RegionCopy(&pDamage->backupDamage, &pDamage->damage); - - /* Report damage now, if desired. */ - if (!pDamage->reportAfter) { - if (pDamage->damageReport) - DamageReportDamage (pDamage, pDamageRegion); - else - RegionUnion(&pDamage->damage, - &pDamage->damage, pDamageRegion); - } - - /* - * translate original region back - */ - if (pDamageRegion == pRegion && (draw_x || draw_y)) - RegionTranslate(pDamageRegion, draw_x, draw_y); - } -#ifdef COMPOSITE - if (screen_x || screen_y) - RegionTranslate(pRegion, -screen_x, -screen_y); -#endif - - RegionUninit(&clippedRec); -} - -static void -damageRegionProcessPending (DrawablePtr pDrawable) -{ - drawableDamage(pDrawable); - - for (; pDamage != NULL; pDamage = pDamage->pNext) - { - /* submit damage marker whenever possible. */ - if (pDamage->damageMarker) - (*pDamage->damageMarker) (pDrawable, pDamage, &pDamage->backupDamage, &pDamage->pendingDamage, pDamage->closure); - if (pDamage->reportAfter) { - /* It's possible that there is only interest in postRendering reporting. */ - if (pDamage->damageReport) - DamageReportDamage (pDamage, &pDamage->pendingDamage); - else - RegionUnion(&pDamage->damage, &pDamage->damage, - &pDamage->pendingDamage); - } - - if (pDamage->reportAfter || pDamage->damageMarker) - RegionEmpty(&pDamage->pendingDamage); - if (pDamage->damageMarker) - RegionEmpty(&pDamage->backupDamage); - } - -} - -#if DAMAGE_DEBUG_ENABLE -#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__) -static void -_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where) -#else -static void -damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode) -#endif -{ - RegionRec region; - - RegionInit(®ion, pBox, 1); -#if DAMAGE_DEBUG_ENABLE - _damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode, where); -#else - damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode); -#endif - RegionUninit(®ion); -} - -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 void damageChangeClip(GCPtr, int, pointer, int); -static void damageDestroyClip(GCPtr); -static void damageCopyClip(GCPtr, GCPtr); - -static GCFuncs damageGCFuncs = { - damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC, - damageChangeClip, damageDestroyClip, damageCopyClip -}; - -static GCOps damageGCOps; - -static Bool -damageCreateGC(GCPtr pGC) -{ - ScreenPtr pScreen = pGC->pScreen; - damageScrPriv(pScreen); - damageGCPriv(pGC); - Bool ret; - - unwrap (pScrPriv, pScreen, CreateGC); - if((ret = (*pScreen->CreateGC) (pGC))) { - pGCPriv->ops = NULL; - pGCPriv->funcs = pGC->funcs; - pGC->funcs = &damageGCFuncs; - } - wrap (pScrPriv, pScreen, CreateGC, damageCreateGC); - - return ret; -} - -#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) \ - damageGCPriv(pGC); \ - unwrap(pGCPriv, pGC, funcs); \ - if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops) - -#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \ - wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \ - if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps) - -static void -damageValidateGC(GCPtr pGC, - unsigned long changes, - DrawablePtr pDrawable) -{ - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->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); -} - -static void -damageChangeClip (GCPtr pGC, - int type, - pointer pvalue, - int nrects) -{ - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - DAMAGE_GC_FUNC_EPILOGUE (pGC); -} - -static void -damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - DAMAGE_GC_FUNC_PROLOGUE (pgcDst); - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - DAMAGE_GC_FUNC_EPILOGUE (pgcDst); -} - -static void -damageDestroyClip(GCPtr pGC) -{ - DAMAGE_GC_FUNC_PROLOGUE (pGC); - (* pGC->funcs->DestroyClip)(pGC); - DAMAGE_GC_FUNC_EPILOGUE (pGC); -} - -#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \ - 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, pDrawable) { \ - box.x1 += pDrawable->x; \ - box.x2 += pDrawable->x; \ - box.y1 += pDrawable->y; \ - box.y2 += pDrawable->y; \ - } - -#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \ - TRANSLATE_BOX(box, pDrawable); \ - TRIM_BOX(box, pGC); \ - } - -#define BOX_NOT_EMPTY(box) \ - (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) - -#define checkGCDamage(d,g) (getDrawableDamage(d) && \ - (!g->pCompositeClip ||\ - RegionNotEmpty(g->pCompositeClip))) - -#define TRIM_PICTURE_BOX(box, pDst) { \ - BoxPtr extents = &pDst->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 checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \ - RegionNotEmpty(p->pCompositeClip)) - -static void -damageComposite (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); - damageScrPriv(pScreen); - - if (checkPictureDamage (pDst)) - { - BoxRec box; - - box.x1 = xDst + pDst->pDrawable->x; - box.y1 = yDst + pDst->pDrawable->y; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - TRIM_PICTURE_BOX(box, pDst); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode); - } - unwrap (pScrPriv, ps, Composite); - (*ps->Composite) (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - damageRegionProcessPending (pDst->pDrawable); - wrap (pScrPriv, ps, Composite, damageComposite); -} - -static void -damageGlyphs (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); - damageScrPriv(pScreen); - - if (checkPictureDamage (pDst)) - { - int nlistTmp = nlist; - GlyphListPtr listTmp = list; - GlyphPtr *glyphsTmp = glyphs; - int x, y; - int n; - GlyphPtr glyph; - BoxRec box; - int x1, y1, x2, y2; - - box.x1 = 32767; - box.y1 = 32767; - box.x2 = -32767; - box.y2 = -32767; - x = pDst->pDrawable->x; - y = pDst->pDrawable->y; - while (nlistTmp--) - { - x += listTmp->xOff; - y += listTmp->yOff; - n = listTmp->len; - while (n--) - { - glyph = *glyphsTmp++; - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - x2 = x1 + glyph->info.width; - y2 = y1 + glyph->info.height; - if (x1 < box.x1) - box.x1 = x1; - if (y1 < box.y1) - box.y1 = y1; - if (x2 > box.x2) - box.x2 = x2; - if (y2 > box.y2) - box.y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - listTmp++; - } - TRIM_PICTURE_BOX (box, pDst); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode); - } - unwrap (pScrPriv, ps, Glyphs); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - damageRegionProcessPending (pDst->pDrawable); - wrap (pScrPriv, ps, Glyphs, damageGlyphs); -} - -static void -damageAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - damageScrPriv(pScreen); - - if (checkPictureDamage (pPicture)) - { - BoxRec box; - int i; - int x, y; - xTrap *t = traps; - - box.x1 = 32767; - box.y1 = 32767; - box.x2 = -32767; - box.y2 = -32767; - x = pPicture->pDrawable->x + x_off; - y = pPicture->pDrawable->y + y_off; - for (i = 0; i < ntrap; i++) - { - pixman_fixed_t l = min (t->top.l, t->bot.l); - pixman_fixed_t r = max (t->top.r, t->bot.r); - int x1 = x + pixman_fixed_to_int (l); - int x2 = x + pixman_fixed_to_int (pixman_fixed_ceil (r)); - int y1 = y + pixman_fixed_to_int (t->top.y); - int y2 = y + pixman_fixed_to_int (pixman_fixed_ceil (t->bot.y)); - - if (x1 < box.x1) - box.x1 = x1; - if (x2 > box.x2) - box.x2 = x2; - if (y1 < box.y1) - box.y1 = y1; - if (y2 > box.y2) - box.y2 = y2; - } - TRIM_PICTURE_BOX (box, pPicture); - if (BOX_NOT_EMPTY(box)) - damageDamageBox (pPicture->pDrawable, &box, pPicture->subWindowMode); - } - unwrap (pScrPriv, ps, AddTraps); - (*ps->AddTraps) (pPicture, x_off, y_off, ntrap, traps); - damageRegionProcessPending (pPicture->pDrawable); - wrap (pScrPriv, ps, AddTraps, damageAddTraps); -} - -/**********************************************************/ - - -static void -damageFillSpans(DrawablePtr pDrawable, - GC *pGC, - int npt, - DDXPointPtr ppt, - int *pwidth, - int fSorted) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (npt && checkGCDamage (pDrawable, pGC)) - { - int nptTmp = npt; - DDXPointPtr pptTmp = ppt; - int *pwidthTmp = pwidth; - BoxRec box; - - box.x1 = pptTmp->x; - box.x2 = box.x1 + *pwidthTmp; - box.y2 = box.y1 = pptTmp->y; - - while(--nptTmp) - { - pptTmp++; - pwidthTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - if(box.x2 < (pptTmp->x + *pwidthTmp)) - box.x2 = pptTmp->x + *pwidthTmp; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - - box.y2++; - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDrawable); - } - TRIM_BOX(box, pGC); - - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - - (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted); - - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damageSetSpans(DrawablePtr pDrawable, - GCPtr pGC, - char *pcharsrc, - DDXPointPtr ppt, - int *pwidth, - int npt, - int fSorted) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (npt && checkGCDamage (pDrawable, pGC)) - { - DDXPointPtr pptTmp = ppt; - int *pwidthTmp = pwidth; - int nptTmp = npt; - BoxRec box; - - box.x1 = pptTmp->x; - box.x2 = box.x1 + *pwidthTmp; - box.y2 = box.y1 = pptTmp->y; - - while(--nptTmp) - { - pptTmp++; - pwidthTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - if(box.x2 < (pptTmp->x + *pwidthTmp)) - box.x2 = pptTmp->x + *pwidthTmp; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - - box.y2++; - - if(!pGC->miTranslate) { - TRANSLATE_BOX(box, pDrawable); - } - TRIM_BOX(box, pGC); - - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePutImage(DrawablePtr pDrawable, - GCPtr pGC, - int depth, - int x, - int y, - int w, - int h, - int leftPad, - int format, - char *pImage) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - - box.x1 = x + pDrawable->x; - box.x2 = box.x1 + w; - box.y1 = y + pDrawable->y; - box.y2 = box.y1 + h; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h, - leftPad, format, pImage); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static RegionPtr -damageCopyArea(DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - int srcx, - int srcy, - int width, - int height, - int dstx, - int dsty) -{ - RegionPtr ret; - DAMAGE_GC_OP_PROLOGUE(pGC, pDst); - - if (checkGCDamage (pDst, pGC)) - { - 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)) - damageDamageBox (pDst, &box, pGC->subWindowMode); - } - - ret = (*pGC->ops->CopyArea)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty); - damageRegionProcessPending (pDst); - DAMAGE_GC_OP_EPILOGUE(pGC, pDst); - return ret; -} - -static RegionPtr -damageCopyPlane(DrawablePtr pSrc, - DrawablePtr pDst, - GCPtr pGC, - int srcx, - int srcy, - int width, - int height, - int dstx, - int dsty, - unsigned long bitPlane) -{ - RegionPtr ret; - DAMAGE_GC_OP_PROLOGUE(pGC, pDst); - - if (checkGCDamage (pDst, pGC)) - { - 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)) - damageDamageBox (pDst, &box, pGC->subWindowMode); - } - - ret = (*pGC->ops->CopyPlane)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); - damageRegionProcessPending (pDst); - DAMAGE_GC_OP_EPILOGUE(pGC, pDst); - return ret; -} - -static void -damagePolyPoint(DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - xPoint *ppt) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (npt && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int nptTmp = npt; - xPoint *pptTmp = ppt; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - /* this could be slow if the points were spread out */ - - while(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePolylines(DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ppt) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (npt && checkGCDamage (pDrawable, pGC)) - { - int nptTmp = npt; - DDXPointPtr pptTmp = ppt; - BoxRec box; - int extra = pGC->lineWidth >> 1; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - if(nptTmp > 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(--nptTmp) - { - pptTmp++; - x += pptTmp->x; - y += pptTmp->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(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - } - - box.x2++; - box.y2++; - - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePolySegment(DrawablePtr pDrawable, - GCPtr pGC, - int nSeg, - xSegment *pSeg) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (nSeg && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int extra = pGC->lineWidth; - int nsegTmp = nSeg; - xSegment *pSegTmp = pSeg; - - if(pGC->capStyle != CapProjecting) - extra >>= 1; - - if(pSegTmp->x2 > pSegTmp->x1) { - box.x1 = pSegTmp->x1; - box.x2 = pSegTmp->x2; - } else { - box.x2 = pSegTmp->x1; - box.x1 = pSegTmp->x2; - } - - if(pSegTmp->y2 > pSegTmp->y1) { - box.y1 = pSegTmp->y1; - box.y2 = pSegTmp->y2; - } else { - box.y2 = pSegTmp->y1; - box.y1 = pSegTmp->y2; - } - - while(--nsegTmp) - { - pSegTmp++; - if(pSegTmp->x2 > pSegTmp->x1) - { - if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1; - if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2; - } - else - { - if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2; - if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1; - } - if(pSegTmp->y2 > pSegTmp->y1) - { - if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1; - if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2; - } - else - { - if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2; - if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1; - } - } - - box.x2++; - box.y2++; - - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePolyRectangle(DrawablePtr pDrawable, - GCPtr pGC, - int nRects, - xRectangle *pRects) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (nRects && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int offset1, offset2, offset3; - int nRectsTmp = nRects; - xRectangle *pRectsTmp = pRects; - - offset2 = pGC->lineWidth; - if(!offset2) offset2 = 1; - offset1 = offset2 >> 1; - offset3 = offset2 - offset1; - - while(nRectsTmp--) - { - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y - offset1; - box.x2 = box.x1 + pRectsTmp->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRectsTmp->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x + pRectsTmp->width - offset1; - box.y1 = pRectsTmp->y + offset3; - box.x2 = box.x1 + offset2; - box.y2 = box.y1 + pRectsTmp->height - offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - box.x1 = pRectsTmp->x - offset1; - box.y1 = pRectsTmp->y + pRectsTmp->height - offset1; - box.x2 = box.x1 + pRectsTmp->width + offset2; - box.y2 = box.y1 + offset2; - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - - pRectsTmp++; - } - } - (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePolyArc(DrawablePtr pDrawable, - GCPtr pGC, - int nArcs, - xArc *pArcs) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (nArcs && checkGCDamage (pDrawable, pGC)) - { - int extra = pGC->lineWidth >> 1; - BoxRec box; - int nArcsTmp = nArcs; - xArc *pArcsTmp = pArcs; - - box.x1 = pArcsTmp->x; - box.x2 = box.x1 + pArcsTmp->width; - box.y1 = pArcsTmp->y; - box.y2 = box.y1 + pArcsTmp->height; - - while(--nArcsTmp) - { - pArcsTmp++; - if(box.x1 > pArcsTmp->x) - box.x1 = pArcsTmp->x; - if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) - box.x2 = pArcsTmp->x + pArcsTmp->width; - if(box.y1 > pArcsTmp->y) - box.y1 = pArcsTmp->y; - if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) - box.y2 = pArcsTmp->y + pArcsTmp->height; - } - - if(extra) - { - box.x1 -= extra; - box.x2 += extra; - box.y1 -= extra; - box.y2 += extra; - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damageFillPolygon(DrawablePtr pDrawable, - GCPtr pGC, - int shape, - int mode, - int npt, - DDXPointPtr ppt) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (npt > 2 && checkGCDamage (pDrawable, pGC)) - { - DDXPointPtr pptTmp = ppt; - int nptTmp = npt; - BoxRec box; - - box.x2 = box.x1 = pptTmp->x; - box.y2 = box.y1 = pptTmp->y; - - if(mode != CoordModeOrigin) - { - int x = box.x1; - int y = box.y1; - while(--nptTmp) - { - pptTmp++; - x += pptTmp->x; - y += pptTmp->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(--nptTmp) - { - pptTmp++; - if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; - else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; - if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; - else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; - } - } - - box.x2++; - box.y2++; - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - - (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - - -static void -damagePolyFillRect(DrawablePtr pDrawable, - GCPtr pGC, - int nRects, - xRectangle *pRects) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if (nRects && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - xRectangle *pRectsTmp = pRects; - int nRectsTmp = nRects; - - box.x1 = pRectsTmp->x; - box.x2 = box.x1 + pRectsTmp->width; - box.y1 = pRectsTmp->y; - box.y2 = box.y1 + pRectsTmp->height; - - while(--nRectsTmp) - { - pRectsTmp++; - if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x; - if(box.x2 < (pRectsTmp->x + pRectsTmp->width)) - box.x2 = pRectsTmp->x + pRectsTmp->width; - if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y; - if(box.y2 < (pRectsTmp->y + pRectsTmp->height)) - box.y2 = pRectsTmp->y + pRectsTmp->height; - } - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - - -static void -damagePolyFillArc(DrawablePtr pDrawable, - GCPtr pGC, - int nArcs, - xArc *pArcs) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (nArcs && checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - int nArcsTmp = nArcs; - xArc *pArcsTmp = pArcs; - - box.x1 = pArcsTmp->x; - box.x2 = box.x1 + pArcsTmp->width; - box.y1 = pArcsTmp->y; - box.y2 = box.y1 + pArcsTmp->height; - - while(--nArcsTmp) - { - pArcsTmp++; - if(box.x1 > pArcsTmp->x) - box.x1 = pArcsTmp->x; - if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) - box.x2 = pArcsTmp->x + pArcsTmp->width; - if(box.y1 > pArcsTmp->y) - box.y1 = pArcsTmp->y; - if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) - box.y2 = pArcsTmp->y + pArcsTmp->height; - } - - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -/* - * general Poly/Image text function. Extract glyph information, - * compute bounding box and remove cursor if it is overlapped. - */ - -static void -damageDamageChars (DrawablePtr pDrawable, - FontPtr font, - int x, - int y, - unsigned int n, - CharInfoPtr *charinfo, - Bool imageblt, - int subWindowMode) -{ - ExtentInfoRec extents; - BoxRec box; - - QueryGlyphExtents(font, charinfo, n, &extents); - if (imageblt) - { - if (extents.overallWidth > extents.overallRight) - extents.overallRight = extents.overallWidth; - if (extents.overallWidth < extents.overallLeft) - extents.overallLeft = extents.overallWidth; - if (extents.overallLeft > 0) - extents.overallLeft = 0; - if (extents.fontAscent > extents.overallAscent) - extents.overallAscent = extents.fontAscent; - if (extents.fontDescent > extents.overallDescent) - extents.overallDescent = extents.fontDescent; - } - box.x1 = x + extents.overallLeft; - box.y1 = y - extents.overallAscent; - box.x2 = x + extents.overallRight; - box.y2 = y + extents.overallDescent; - damageDamageBox (pDrawable, &box, subWindowMode); -} - -/* - * values for textType: - */ -#define TT_POLY8 0 -#define TT_IMAGE8 1 -#define TT_POLY16 2 -#define TT_IMAGE16 3 - -static int -damageText (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned long count, - char *chars, - FontEncoding fontEncoding, - Bool textType) -{ - CharInfoPtr *charinfo; - CharInfoPtr *info; - unsigned long i; - unsigned int n; - int w; - Bool imageblt; - - imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); - - charinfo = malloc(count * sizeof(CharInfoPtr)); - if (!charinfo) - return x; - - GetGlyphs(pGC->font, count, (unsigned char *)chars, - fontEncoding, &i, charinfo); - n = (unsigned int)i; - w = 0; - if (!imageblt) - for (info = charinfo; i--; info++) - w += (*info)->metrics.characterWidth; - - if (n != 0) { - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n, - charinfo, imageblt, pGC->subWindowMode); - if (imageblt) - (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); - else - (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); - } - free(charinfo); - return x + w; -} - -static int -damagePolyText8(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - char *chars) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (checkGCDamage (pDrawable, pGC)) - x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars, - Linear8Bit, TT_POLY8); - else - x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); - return x; -} - -static int -damagePolyText16(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (checkGCDamage (pDrawable, pGC)) - x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, - FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, - TT_POLY16); - else - x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); - return x; -} - -static void -damageImageText8(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - char *chars) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (checkGCDamage (pDrawable, pGC)) - damageText (pDrawable, pGC, x, y, (unsigned long) count, chars, - Linear8Bit, TT_IMAGE8); - else - (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damageImageText16(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - - if (checkGCDamage (pDrawable, pGC)) - damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, - FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, - TT_IMAGE16); - else - (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - - -static void -damageImageGlyphBlt(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, - nglyph, ppci, TRUE, pGC->subWindowMode); - (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, - ppci, pglyphBase); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePolyGlyphBlt(DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, - nglyph, ppci, FALSE, pGC->subWindowMode); - (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, - ppci, pglyphBase); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damagePushPixels(GCPtr pGC, - PixmapPtr pBitMap, - DrawablePtr pDrawable, - int dx, - int dy, - int xOrg, - int yOrg) -{ - DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable); - if(checkGCDamage (pDrawable, pGC)) - { - BoxRec box; - - box.x1 = xOrg; - box.y1 = yOrg; - - if(!pGC->miTranslate) { - box.x1 += pDrawable->x; - box.y1 += pDrawable->y; - } - - box.x2 = box.x1 + dx; - box.y2 = box.y1 + dy; - - TRIM_BOX(box, pGC); - if(BOX_NOT_EMPTY(box)) - damageDamageBox (pDrawable, &box, pGC->subWindowMode); - } - (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg); - damageRegionProcessPending (pDrawable); - DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable); -} - -static void -damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage) -{ - while (*pPrev) - { - if (*pPrev == pDamage) - { - *pPrev = pDamage->pNext; - return; - } - pPrev = &(*pPrev)->pNext; - } -#if DAMAGE_VALIDATE_ENABLE - ErrorF ("Damage not on list\n"); - OsAbort (); -#endif -} - -static void -damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage) -{ -#if DAMAGE_VALIDATE_ENABLE - DamagePtr pOld; - - for (pOld = *pPrev; pOld; pOld = pOld->pNext) - if (pOld == pDamage) { - ErrorF ("Damage already on list\n"); - OsAbort (); - } -#endif - pDamage->pNext = *pPrev; - *pPrev = pDamage; -} - -static Bool -damageDestroyPixmap (PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - damageScrPriv(pScreen); - - if (pPixmap->refcnt == 1) - { - DamagePtr *pPrev = getPixmapDamageRef (pPixmap); - DamagePtr pDamage; - - while ((pDamage = *pPrev)) - { - damageRemoveDamage (pPrev, pDamage); - if (!pDamage->isWindow) - DamageDestroy (pDamage); - } - } - unwrap (pScrPriv, pScreen, DestroyPixmap); - (*pScreen->DestroyPixmap) (pPixmap); - wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); - return TRUE; -} - -static void -damageCopyWindow(WindowPtr pWindow, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc) -{ - ScreenPtr pScreen = pWindow->drawable.pScreen; - damageScrPriv(pScreen); - - if (getWindowDamage (pWindow)) - { - int dx = pWindow->drawable.x - ptOldOrg.x; - int dy = pWindow->drawable.y - ptOldOrg.y; - - /* - * The region comes in source relative, but the damage occurs - * at the destination location. Translate back and forth. - */ - RegionTranslate(prgnSrc, dx, dy); - damageRegionAppend (&pWindow->drawable, prgnSrc, FALSE, -1); - RegionTranslate(prgnSrc, -dx, -dy); - } - unwrap (pScrPriv, pScreen, CopyWindow); - (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); - damageRegionProcessPending (&pWindow->drawable); - wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow); -} - -static GCOps damageGCOps = { - damageFillSpans, damageSetSpans, - damagePutImage, damageCopyArea, - damageCopyPlane, damagePolyPoint, - damagePolylines, damagePolySegment, - damagePolyRectangle, damagePolyArc, - damageFillPolygon, damagePolyFillRect, - damagePolyFillArc, damagePolyText8, - damagePolyText16, damageImageText8, - damageImageText16, damageImageGlyphBlt, - damagePolyGlyphBlt, damagePushPixels, -}; - -static void -damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) -{ - DamagePtr pDamage; - ScreenPtr pScreen = pWindow->drawable.pScreen; - damageScrPriv(pScreen); - - if ((pDamage = damageGetWinPriv(pWindow))) - { - PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow); - DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap); - - while (pDamage) - { - damageRemoveDamage (pPrev, pDamage); - pDamage = pDamage->pNextWin; - } - } - unwrap (pScrPriv, pScreen, SetWindowPixmap); - (*pScreen->SetWindowPixmap) (pWindow, pPixmap); - wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); - if ((pDamage = damageGetWinPriv(pWindow))) - { - DamagePtr *pPrev = getPixmapDamageRef(pPixmap); - - while (pDamage) - { - damageInsertDamage (pPrev, pDamage); - pDamage = pDamage->pNextWin; - } - } -} - -static Bool -damageDestroyWindow (WindowPtr pWindow) -{ - DamagePtr pDamage; - ScreenPtr pScreen = pWindow->drawable.pScreen; - Bool ret; - damageScrPriv(pScreen); - - while ((pDamage = damageGetWinPriv(pWindow))) - { - DamageUnregister (&pWindow->drawable, pDamage); - DamageDestroy (pDamage); - } - unwrap (pScrPriv, pScreen, DestroyWindow); - ret = (*pScreen->DestroyWindow) (pWindow); - wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); - return ret; -} - -static Bool -damageCloseScreen (int i, ScreenPtr pScreen) -{ - damageScrPriv(pScreen); - - unwrap (pScrPriv, pScreen, DestroyPixmap); - unwrap (pScrPriv, pScreen, CreateGC); - unwrap (pScrPriv, pScreen, CopyWindow); - unwrap (pScrPriv, pScreen, CloseScreen); - free(pScrPriv); - return (*pScreen->CloseScreen) (i, pScreen); -} - -/** - * Default implementations of the damage management functions. - */ -void miDamageCreate (DamagePtr pDamage) -{ -} - -void miDamageRegister (DrawablePtr pDrawable, DamagePtr pDamage) -{ -} - -void miDamageUnregister (DrawablePtr pDrawable, DamagePtr pDamage) -{ -} - -void miDamageDestroy (DamagePtr pDamage) -{ -} - -/** - * Public functions for consumption outside this file. - */ - -Bool -DamageSetup (ScreenPtr pScreen) -{ - DamageScrPrivPtr pScrPriv; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - const DamageScreenFuncsRec miFuncs = { - miDamageCreate, miDamageRegister, miDamageUnregister, miDamageDestroy - }; - - if (!dixRegisterPrivateKey(&damageScrPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - if (dixLookupPrivate(&pScreen->devPrivates, damageScrPrivateKey)) - return TRUE; - - if (!dixRegisterPrivateKey(&damageGCPrivateKeyRec, PRIVATE_GC, sizeof(DamageGCPrivRec))) - return FALSE; - - if (!dixRegisterPrivateKey(&damagePixPrivateKeyRec, PRIVATE_PIXMAP, 0)) - return FALSE; - - if (!dixRegisterPrivateKey(&damageWinPrivateKeyRec, PRIVATE_WINDOW, 0)) - return FALSE; - - pScrPriv = malloc(sizeof (DamageScrPrivRec)); - if (!pScrPriv) - return FALSE; - - pScrPriv->internalLevel = 0; - pScrPriv->pScreenDamage = 0; - - wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap); - wrap (pScrPriv, pScreen, CreateGC, damageCreateGC); - wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow); - wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap); - wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow); - wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen); - if (ps) { - wrap (pScrPriv, ps, Glyphs, damageGlyphs); - wrap (pScrPriv, ps, Composite, damageComposite); - wrap (pScrPriv, ps, AddTraps, damageAddTraps); - } - - pScrPriv->funcs = miFuncs; - - dixSetPrivate(&pScreen->devPrivates, damageScrPrivateKey, pScrPriv); - return TRUE; -} - -DamagePtr -DamageCreate (DamageReportFunc damageReport, - DamageDestroyFunc damageDestroy, - DamageReportLevel damageLevel, - Bool isInternal, - ScreenPtr pScreen, - void *closure) -{ - damageScrPriv(pScreen); - DamagePtr pDamage; - - pDamage = dixAllocateObjectWithPrivates(DamageRec, PRIVATE_DAMAGE); - if (!pDamage) - return 0; - pDamage->pNext = 0; - pDamage->pNextWin = 0; - RegionNull(&pDamage->damage); - RegionNull(&pDamage->pendingDamage); - - pDamage->damageLevel = damageLevel; - pDamage->isInternal = isInternal; - pDamage->closure = closure; - pDamage->isWindow = FALSE; - pDamage->pDrawable = 0; - pDamage->reportAfter = FALSE; - - pDamage->damageReport = damageReport; - pDamage->damageReportPostRendering = NULL; - pDamage->damageDestroy = damageDestroy; - pDamage->damageMarker = NULL; - pDamage->pScreen = pScreen; - - (*pScrPriv->funcs.Create) (pDamage); - - return pDamage; -} - -void -DamageRegister (DrawablePtr pDrawable, - DamagePtr pDamage) -{ - ScreenPtr pScreen = pDrawable->pScreen; - damageScrPriv(pScreen); - -#if DAMAGE_VALIDATE_ENABLE - if (pDrawable->pScreen != pDamage->pScreen) - { - ErrorF ("DamageRegister called with mismatched screens\n"); - OsAbort (); - } -#endif - - if (pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pWindow = (WindowPtr) pDrawable; - winDamageRef(pWindow); - -#if DAMAGE_VALIDATE_ENABLE - DamagePtr pOld; - - for (pOld = *pPrev; pOld; pOld = pOld->pNextWin) - if (pOld == pDamage) { - ErrorF ("Damage already on window list\n"); - OsAbort (); - } -#endif - pDamage->pNextWin = *pPrev; - *pPrev = pDamage; - pDamage->isWindow = TRUE; - } - else - pDamage->isWindow = FALSE; - pDamage->pDrawable = pDrawable; - damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage); - (*pScrPriv->funcs.Register) (pDrawable, pDamage); -} - -void -DamageDrawInternal (ScreenPtr pScreen, Bool enable) -{ - damageScrPriv (pScreen); - - pScrPriv->internalLevel += enable ? 1 : -1; -} - -void -DamageUnregister (DrawablePtr pDrawable, - DamagePtr pDamage) -{ - ScreenPtr pScreen = pDrawable->pScreen; - damageScrPriv(pScreen); - - (*pScrPriv->funcs.Unregister) (pDrawable, pDamage); - - if (pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pWindow = (WindowPtr) pDrawable; - winDamageRef (pWindow); -#if DAMAGE_VALIDATE_ENABLE - int found = 0; -#endif - - while (*pPrev) - { - if (*pPrev == pDamage) - { - *pPrev = pDamage->pNextWin; -#if DAMAGE_VALIDATE_ENABLE - found = 1; -#endif - break; - } - pPrev = &(*pPrev)->pNextWin; - } -#if DAMAGE_VALIDATE_ENABLE - if (!found) { - ErrorF ("Damage not on window list\n"); - OsAbort (); - } -#endif - } - pDamage->pDrawable = 0; - damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage); -} - -void -DamageDestroy (DamagePtr pDamage) -{ - ScreenPtr pScreen = pDamage->pScreen; - damageScrPriv(pScreen); - - if (pDamage->damageDestroy) - (*pDamage->damageDestroy) (pDamage, pDamage->closure); - (*pScrPriv->funcs.Destroy) (pDamage); - RegionUninit(&pDamage->damage); - RegionUninit(&pDamage->pendingDamage); - dixFreeObjectWithPrivates(pDamage, PRIVATE_DAMAGE); -} - -Bool -DamageSubtract (DamagePtr pDamage, - const RegionPtr pRegion) -{ - RegionPtr pClip; - RegionRec pixmapClip; - DrawablePtr pDrawable = pDamage->pDrawable; - - RegionSubtract(&pDamage->damage, &pDamage->damage, pRegion); - if (pDrawable) - { - if (pDrawable->type == DRAWABLE_WINDOW) - pClip = &((WindowPtr) pDrawable)->borderClip; - else - { - BoxRec box; - - box.x1 = pDrawable->x; - box.y1 = pDrawable->y; - box.x2 = pDrawable->x + pDrawable->width; - box.y2 = pDrawable->y + pDrawable->height; - RegionInit(&pixmapClip, &box, 1); - pClip = &pixmapClip; - } - RegionTranslate(&pDamage->damage, pDrawable->x, pDrawable->y); - RegionIntersect(&pDamage->damage, &pDamage->damage, pClip); - RegionTranslate(&pDamage->damage, -pDrawable->x, -pDrawable->y); - if (pDrawable->type != DRAWABLE_WINDOW) - RegionUninit(&pixmapClip); - } - return RegionNotEmpty(&pDamage->damage); -} - -void -DamageEmpty (DamagePtr pDamage) -{ - RegionEmpty(&pDamage->damage); -} - -RegionPtr -DamageRegion (DamagePtr pDamage) -{ - return &pDamage->damage; -} - -RegionPtr -DamagePendingRegion (DamagePtr pDamage) -{ - return &pDamage->pendingDamage; -} - -void -DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion) -{ - damageRegionAppend (pDrawable, pRegion, FALSE, -1); -} - -void -DamageRegionProcessPending (DrawablePtr pDrawable) -{ - damageRegionProcessPending (pDrawable); -} - -/* If a damage marker is provided, then this function must be called after rendering is done. */ -/* Please do call back so any future enhancements can assume this function is called. */ -/* There are no strict timing requirements for calling this function, just as soon as (is cheaply) possible. */ -void -DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion) -{ - if (pDamage->damageReportPostRendering) - damageReportDamagePostRendering (pDamage, pOldDamage, pRegion); -} - -/* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */ -void -DamageDamageRegion (DrawablePtr pDrawable, - RegionPtr pRegion) -{ - damageRegionAppend (pDrawable, pRegion, FALSE, -1); - - /* Go back and report this damage for DamagePtrs with reportAfter set, since - * this call isn't part of an in-progress drawing op in the call chain and - * the DDX probably just wants to know about it right away. - */ - damageRegionProcessPending (pDrawable); -} - -void -DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter) -{ - pDamage->reportAfter = reportAfter; -} - -void -DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering, - DamageMarkerFunc damageMarker) -{ - pDamage->damageReportPostRendering = damageReportPostRendering; - pDamage->damageMarker = damageMarker; -} - -DamageScreenFuncsPtr -DamageGetScreenFuncs (ScreenPtr pScreen) -{ - damageScrPriv(pScreen); - return &pScrPriv->funcs; -} - -void -DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion) -{ - BoxRec tmpBox; - RegionRec tmpRegion; - Bool was_empty; - - switch (pDamage->damageLevel) { - case DamageReportRawRegion: - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure); - break; - case DamageReportDeltaRegion: - RegionNull(&tmpRegion); - RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage); - if (RegionNotEmpty(&tmpRegion)) { - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure); - } - RegionUninit(&tmpRegion); - break; - case DamageReportBoundingBox: - tmpBox = *RegionExtents(&pDamage->damage); - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage))) { - (*pDamage->damageReport) (pDamage, &pDamage->damage, - pDamage->closure); - } - break; - case DamageReportNonEmpty: - was_empty = !RegionNotEmpty(&pDamage->damage); - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - if (was_empty && RegionNotEmpty(&pDamage->damage)) { - (*pDamage->damageReport) (pDamage, &pDamage->damage, - pDamage->closure); - } - break; - case DamageReportNone: - RegionUnion(&pDamage->damage, &pDamage->damage, - pDamageRegion); - break; - } -} - +/*
+ * Copyright © 2003 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
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <X11/fonts/font.h>
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "damage.h"
+#include "damagestr.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+ ((a)->x1 == (b)->x1 && \
+ (a)->y1 == (b)->y1 && \
+ (a)->x2 == (b)->x2 && \
+ (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x) ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) ((DamagePtr *) \
+ dixLookupPrivateAddr(&(pPixmap)->devPrivates, damagePixPrivateKey))
+
+#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
+
+static DevPrivateKeyRec damageScrPrivateKeyRec;
+#define damageScrPrivateKey (&damageScrPrivateKeyRec)
+static DevPrivateKeyRec damagePixPrivateKeyRec;
+#define damagePixPrivateKey (&damagePixPrivateKeyRec)
+static DevPrivateKeyRec damageGCPrivateKeyRec;
+#define damageGCPrivateKey (&damageGCPrivateKeyRec)
+static DevPrivateKeyRec damageWinPrivateKeyRec;
+#define damageWinPrivateKey (&damageWinPrivateKeyRec)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap;
+
+ if (WindowDrawable(pDrawable->type))
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ pPixmap = 0;
+ if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+ && ((WindowPtr)pDrawable)->viewable
+#endif
+ )
+ pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+ if (!pPixmap)
+ {
+ damageScrPriv(pScreen);
+
+ return &pScrPriv->pScreenDamage;
+ }
+ }
+ else
+ pPixmap = (PixmapPtr) pDrawable;
+ return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable) \
+ DamagePtr pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+ DamagePtr *pPrev = (DamagePtr *) \
+ dixLookupPrivateAddr(&(pWindow)->devPrivates, damageWinPrivateKey)
+
+static void
+damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pDamageRegion)
+{
+ BoxRec tmpBox;
+ RegionRec tmpRegion, newDamage;
+ Bool was_empty;
+
+ RegionUnion(&newDamage, pOldDamage, pDamageRegion);
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReportPostRendering) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ RegionNull(&tmpRegion);
+ RegionSubtract(&tmpRegion, pDamageRegion, pOldDamage);
+ if (RegionNotEmpty(&tmpRegion)) {
+ (*pDamage->damageReportPostRendering) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ RegionUninit(&tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *RegionExtents(pOldDamage);
+ if (!BOX_SAME (&tmpBox, RegionExtents(&newDamage))) {
+ (*pDamage->damageReportPostRendering) (pDamage, &newDamage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !RegionNotEmpty(pOldDamage);
+ if (was_empty && RegionNotEmpty(&newDamage)) {
+ (*pDamage->damageReportPostRendering) (pDamage, &newDamage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNone:
+ break;
+ }
+
+ RegionUninit(&newDamage);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageRegionAppend(d,r,c,m) _damageRegionAppend(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+ int subWindowMode)
+#endif
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+ drawableDamage(pDrawable);
+ DamagePtr pNext;
+ RegionRec clippedRec;
+ RegionPtr pDamageRegion;
+ RegionRec pixClip;
+ int draw_x, draw_y;
+#ifdef COMPOSITE
+ int screen_x = 0, screen_y = 0;
+#endif
+
+ /* short circuit for empty regions */
+ if (!RegionNotEmpty(pRegion))
+ return;
+
+#ifdef COMPOSITE
+ /*
+ * When drawing to a pixmap which is storing window contents,
+ * the region presented is in pixmap relative coordinates which
+ * need to be converted to screen relative coordinates
+ */
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ {
+ screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+ screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+ }
+ if (screen_x || screen_y)
+ RegionTranslate(pRegion, screen_x, screen_y);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)(pDrawable))->backingStore == NotUseful)
+ {
+ if (subWindowMode == ClipByChildren)
+ {
+ RegionIntersect(pRegion, pRegion,
+ &((WindowPtr)(pDrawable))->clipList);
+ }
+ else if (subWindowMode == IncludeInferiors)
+ {
+ RegionPtr pTempRegion =
+ NotClippedByChildren((WindowPtr)(pDrawable));
+ RegionIntersect(pRegion, pRegion, pTempRegion);
+ RegionDestroy(pTempRegion);
+ }
+ /* If subWindowMode is set to an invalid value, don't perform
+ * any drawable-based clipping. */
+ }
+
+
+ RegionNull(&clippedRec);
+ for (; pDamage; pDamage = pNext)
+ {
+ pNext = pDamage->pNext;
+ /*
+ * Check for internal damage and don't send events
+ */
+ if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+ {
+ DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+ pScrPriv->internalLevel));
+ continue;
+ }
+ /*
+ * Check for unrealized windows
+ */
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr) (pDamage->pDrawable))->realized)
+ {
+ continue;
+ }
+
+ draw_x = pDamage->pDrawable->x;
+ draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+ /*
+ * Need to move everyone to screen coordinates
+ * XXX what about off-screen pixmaps with non-zero x/y?
+ */
+ if (!WindowDrawable(pDamage->pDrawable->type))
+ {
+ draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+ draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+ }
+#endif
+
+ /*
+ * Clip against border or pixmap bounds
+ */
+
+ pDamageRegion = pRegion;
+ if (clip || pDamage->pDrawable != pDrawable)
+ {
+ pDamageRegion = &clippedRec;
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+ RegionIntersect(pDamageRegion, pRegion,
+ &((WindowPtr)(pDamage->pDrawable))->borderClip);
+ } else {
+ BoxRec box;
+ box.x1 = draw_x;
+ box.y1 = draw_y;
+ box.x2 = draw_x + pDamage->pDrawable->width;
+ box.y2 = draw_y + pDamage->pDrawable->height;
+ RegionInit(&pixClip, &box, 1);
+ RegionIntersect(pDamageRegion, pRegion, &pixClip);
+ RegionUninit(&pixClip);
+ }
+ /*
+ * Short circuit empty results
+ */
+ if (!RegionNotEmpty(pDamageRegion))
+ continue;
+ }
+
+ DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+ where,
+ pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+ pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+ pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+ pDrawable->id, pDamage->pDrawable->id));
+
+ /*
+ * Move region to target coordinate space
+ */
+ if (draw_x || draw_y)
+ RegionTranslate(pDamageRegion, -draw_x, -draw_y);
+
+ /* Store damage region if needed after submission. */
+ if (pDamage->reportAfter || pDamage->damageMarker)
+ RegionUnion(&pDamage->pendingDamage,
+ &pDamage->pendingDamage, pDamageRegion);
+
+ /* Duplicate current damage if needed. */
+ if (pDamage->damageMarker)
+ RegionCopy(&pDamage->backupDamage, &pDamage->damage);
+
+ /* Report damage now, if desired. */
+ if (!pDamage->reportAfter) {
+ if (pDamage->damageReport)
+ DamageReportDamage (pDamage, pDamageRegion);
+ else
+ RegionUnion(&pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ }
+
+ /*
+ * translate original region back
+ */
+ if (pDamageRegion == pRegion && (draw_x || draw_y))
+ RegionTranslate(pDamageRegion, draw_x, draw_y);
+ }
+#ifdef COMPOSITE
+ if (screen_x || screen_y)
+ RegionTranslate(pRegion, -screen_x, -screen_y);
+#endif
+
+ RegionUninit(&clippedRec);
+}
+
+static void
+damageRegionProcessPending (DrawablePtr pDrawable)
+{
+ drawableDamage(pDrawable);
+
+ for (; pDamage != NULL; pDamage = pDamage->pNext)
+ {
+ /* submit damage marker whenever possible. */
+ if (pDamage->damageMarker)
+ (*pDamage->damageMarker) (pDrawable, pDamage, &pDamage->backupDamage, &pDamage->pendingDamage, pDamage->closure);
+ if (pDamage->reportAfter) {
+ /* It's possible that there is only interest in postRendering reporting. */
+ if (pDamage->damageReport)
+ DamageReportDamage (pDamage, &pDamage->pendingDamage);
+ else
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ &pDamage->pendingDamage);
+ }
+
+ if (pDamage->reportAfter || pDamage->damageMarker)
+ RegionEmpty(&pDamage->pendingDamage);
+ if (pDamage->damageMarker)
+ RegionEmpty(&pDamage->backupDamage);
+ }
+
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+ RegionRec region;
+
+ RegionInit(®ion, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+ _damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode, where);
+#else
+ damageRegionAppend (pDrawable, ®ion, TRUE, subWindowMode);
+#endif
+ RegionUninit(®ion);
+}
+
+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 void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+static GCFuncs damageGCFuncs = {
+ damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+ damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+static GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ damageScrPriv(pScreen);
+ damageGCPriv(pGC);
+ Bool ret;
+
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+ return ret;
+}
+
+#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) \
+ damageGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->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);
+}
+
+static void
+damageChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+ 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, pDrawable) { \
+ box.x1 += pDrawable->x; \
+ box.x2 += pDrawable->x; \
+ box.y1 += pDrawable->y; \
+ box.y2 += pDrawable->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+ TRANSLATE_BOX(box, pDrawable); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g) (getDrawableDamage(d) && \
+ (!g->pCompositeClip ||\
+ RegionNotEmpty(g->pCompositeClip)))
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+ BoxPtr extents = &pDst->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 checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
+ RegionNotEmpty(p->pCompositeClip))
+
+static void
+damageComposite (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);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ BoxRec box;
+
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ TRIM_PICTURE_BOX(box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ damageRegionProcessPending (pDst->pDrawable);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (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);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ int nlistTmp = nlist;
+ GlyphListPtr listTmp = list;
+ GlyphPtr *glyphsTmp = glyphs;
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ BoxRec box;
+ int x1, y1, x2, y2;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+ while (nlistTmp--)
+ {
+ x += listTmp->xOff;
+ y += listTmp->yOff;
+ n = listTmp->len;
+ while (n--)
+ {
+ glyph = *glyphsTmp++;
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ listTmp++;
+ }
+ TRIM_PICTURE_BOX (box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ damageRegionProcessPending (pDst->pDrawable);
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+
+static void
+damageAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pPicture))
+ {
+ BoxRec box;
+ int i;
+ int x, y;
+ xTrap *t = traps;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pPicture->pDrawable->x + x_off;
+ y = pPicture->pDrawable->y + y_off;
+ for (i = 0; i < ntrap; i++)
+ {
+ pixman_fixed_t l = min (t->top.l, t->bot.l);
+ pixman_fixed_t r = max (t->top.r, t->bot.r);
+ int x1 = x + pixman_fixed_to_int (l);
+ int x2 = x + pixman_fixed_to_int (pixman_fixed_ceil (r));
+ int y1 = y + pixman_fixed_to_int (t->top.y);
+ int y2 = y + pixman_fixed_to_int (pixman_fixed_ceil (t->bot.y));
+
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ }
+ TRIM_PICTURE_BOX (box, pPicture);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pPicture->pDrawable, &box, pPicture->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, AddTraps);
+ (*ps->AddTraps) (pPicture, x_off, y_off, ntrap, traps);
+ damageRegionProcessPending (pPicture->pDrawable);
+ wrap (pScrPriv, ps, AddTraps, damageAddTraps);
+}
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+ GC *pGC,
+ int npt,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int npt,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = x + pDrawable->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDrawable->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ 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))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ damageRegionProcessPending (pDst);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ 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))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ damageRegionProcessPending (pDst);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nptTmp = npt;
+ xPoint *pptTmp = ppt;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(nptTmp > 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(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->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(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSeg,
+ xSegment *pSeg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nSeg && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+ int nsegTmp = nSeg;
+ xSegment *pSegTmp = pSeg;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSegTmp->x2 > pSegTmp->x1) {
+ box.x1 = pSegTmp->x1;
+ box.x2 = pSegTmp->x2;
+ } else {
+ box.x2 = pSegTmp->x1;
+ box.x1 = pSegTmp->x2;
+ }
+
+ if(pSegTmp->y2 > pSegTmp->y1) {
+ box.y1 = pSegTmp->y1;
+ box.y2 = pSegTmp->y2;
+ } else {
+ box.y2 = pSegTmp->y1;
+ box.y1 = pSegTmp->y2;
+ }
+
+ while(--nsegTmp)
+ {
+ pSegTmp++;
+ if(pSegTmp->x2 > pSegTmp->x1)
+ {
+ if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+ if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+ }
+ else
+ {
+ if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+ if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+ }
+ if(pSegTmp->y2 > pSegTmp->y1)
+ {
+ if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+ if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+ }
+ else
+ {
+ if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+ if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+ int nRectsTmp = nRects;
+ xRectangle *pRectsTmp = pRects;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRectsTmp--)
+ {
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ pRectsTmp++;
+ }
+ }
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt > 2 && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(mode != CoordModeOrigin)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->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(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ xRectangle *pRectsTmp = pRects;
+ int nRectsTmp = nRects;
+
+ box.x1 = pRectsTmp->x;
+ box.x2 = box.x1 + (short)pRectsTmp->width;
+ box.y1 = pRectsTmp->y;
+ box.y2 = box.y1 + (short)pRectsTmp->height;
+
+ while(--nRectsTmp)
+ {
+ pRectsTmp++;
+ if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+ if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+ box.x2 = pRectsTmp->x + pRectsTmp->width;
+ if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+ if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+ box.y2 = pRectsTmp->y + pRectsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr pDrawable,
+ FontPtr font,
+ int x,
+ int y,
+ unsigned int n,
+ CharInfoPtr *charinfo,
+ Bool imageblt,
+ int subWindowMode)
+{
+ ExtentInfoRec extents;
+ BoxRec box;
+
+ QueryGlyphExtents(font, charinfo, n, &extents);
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ box.x1 = x + extents.overallLeft;
+ box.y1 = y - extents.overallAscent;
+ box.x2 = x + extents.overallRight;
+ box.y2 = y + extents.overallDescent;
+ damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = malloc(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ }
+ free(charinfo);
+ return x + w;
+}
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+ else
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+ else
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+ else
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+ else
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damageImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, TRUE, pGC->subWindowMode);
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, FALSE, pGC->subWindowMode);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if(checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDrawable->x;
+ box.y1 += pDrawable->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ damageRegionProcessPending (pDrawable);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNext;
+ return;
+ }
+ pPrev = &(*pPrev)->pNext;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ ErrorF ("Damage not on list\n");
+ OsAbort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on list\n");
+ OsAbort ();
+ }
+#endif
+ pDamage->pNext = *pPrev;
+ *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (pPixmap->refcnt == 1)
+ {
+ DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
+ DamagePtr pDamage;
+
+ while ((pDamage = *pPrev))
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ if (!pDamage->isWindow)
+ DamageDestroy (pDamage);
+ }
+ }
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ return TRUE;
+}
+
+static void
+damageCopyWindow(WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (getWindowDamage (pWindow))
+ {
+ int dx = pWindow->drawable.x - ptOldOrg.x;
+ int dy = pWindow->drawable.y - ptOldOrg.y;
+
+ /*
+ * The region comes in source relative, but the damage occurs
+ * at the destination location. Translate back and forth.
+ */
+ RegionTranslate(prgnSrc, dx, dy);
+ damageRegionAppend (&pWindow->drawable, prgnSrc, FALSE, -1);
+ RegionTranslate(prgnSrc, -dx, -dy);
+ }
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ damageRegionProcessPending (&pWindow->drawable);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+static GCOps damageGCOps = {
+ damageFillSpans, damageSetSpans,
+ damagePutImage, damageCopyArea,
+ damageCopyPlane, damagePolyPoint,
+ damagePolylines, damagePolySegment,
+ damagePolyRectangle, damagePolyArc,
+ damageFillPolygon, damagePolyFillRect,
+ damagePolyFillArc, damagePolyText8,
+ damagePolyText16, damageImageText8,
+ damageImageText16, damageImageGlyphBlt,
+ damagePolyGlyphBlt, damagePushPixels,
+};
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
+
+ while (pDamage)
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+ unwrap (pScrPriv, pScreen, SetWindowPixmap);
+ (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
+
+ while (pDamage)
+ {
+ damageInsertDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ Bool ret;
+ damageScrPriv(pScreen);
+
+ while ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamageUnregister (&pWindow->drawable, pDamage);
+ DamageDestroy (pDamage);
+ }
+ unwrap (pScrPriv, pScreen, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ free(pScrPriv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+/**
+ * Default implementations of the damage management functions.
+ */
+void miDamageCreate (DamagePtr pDamage)
+{
+}
+
+void miDamageRegister (DrawablePtr pDrawable, DamagePtr pDamage)
+{
+}
+
+void miDamageUnregister (DrawablePtr pDrawable, DamagePtr pDamage)
+{
+}
+
+void miDamageDestroy (DamagePtr pDamage)
+{
+}
+
+/**
+ * Public functions for consumption outside this file.
+ */
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+ DamageScrPrivPtr pScrPriv;
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ const DamageScreenFuncsRec miFuncs = {
+ miDamageCreate, miDamageRegister, miDamageUnregister, miDamageDestroy
+ };
+
+ if (!dixRegisterPrivateKey(&damageScrPrivateKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+
+ if (dixLookupPrivate(&pScreen->devPrivates, damageScrPrivateKey))
+ return TRUE;
+
+ if (!dixRegisterPrivateKey(&damageGCPrivateKeyRec, PRIVATE_GC, sizeof(DamageGCPrivRec)))
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&damagePixPrivateKeyRec, PRIVATE_PIXMAP, 0))
+ return FALSE;
+
+ if (!dixRegisterPrivateKey(&damageWinPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ pScrPriv = malloc(sizeof (DamageScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ pScrPriv->internalLevel = 0;
+ pScrPriv->pScreenDamage = 0;
+
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+ wrap (pScrPriv, ps, AddTraps, damageAddTraps);
+ }
+
+ pScrPriv->funcs = miFuncs;
+
+ dixSetPrivate(&pScreen->devPrivates, damageScrPrivateKey, pScrPriv);
+ return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void *closure)
+{
+ damageScrPriv(pScreen);
+ DamagePtr pDamage;
+
+ pDamage = dixAllocateObjectWithPrivates(DamageRec, PRIVATE_DAMAGE);
+ if (!pDamage)
+ return 0;
+ pDamage->pNext = 0;
+ pDamage->pNextWin = 0;
+ RegionNull(&pDamage->damage);
+ RegionNull(&pDamage->pendingDamage);
+
+ pDamage->damageLevel = damageLevel;
+ pDamage->isInternal = isInternal;
+ pDamage->closure = closure;
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = 0;
+ pDamage->reportAfter = FALSE;
+
+ pDamage->damageReport = damageReport;
+ pDamage->damageReportPostRendering = NULL;
+ pDamage->damageDestroy = damageDestroy;
+ pDamage->damageMarker = NULL;
+ pDamage->pScreen = pScreen;
+
+ (*pScrPriv->funcs.Create) (pDamage);
+
+ return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+
+#if DAMAGE_VALIDATE_ENABLE
+ if (pDrawable->pScreen != pDamage->pScreen)
+ {
+ ErrorF ("DamageRegister called with mismatched screens\n");
+ OsAbort ();
+ }
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on window list\n");
+ OsAbort ();
+ }
+#endif
+ pDamage->pNextWin = *pPrev;
+ *pPrev = pDamage;
+ pDamage->isWindow = TRUE;
+ }
+ else
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = pDrawable;
+ damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+ (*pScrPriv->funcs.Register) (pDrawable, pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+ damageScrPriv (pScreen);
+
+ pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+
+ (*pScrPriv->funcs.Unregister) (pDrawable, pDamage);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+ int found = 0;
+#endif
+
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+ found = 1;
+#endif
+ break;
+ }
+ pPrev = &(*pPrev)->pNextWin;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ if (!found) {
+ ErrorF ("Damage not on window list\n");
+ OsAbort ();
+ }
+#endif
+ }
+ pDamage->pDrawable = 0;
+ damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr pDamage)
+{
+ ScreenPtr pScreen = pDamage->pScreen;
+ damageScrPriv(pScreen);
+
+ if (pDamage->damageDestroy)
+ (*pDamage->damageDestroy) (pDamage, pDamage->closure);
+ (*pScrPriv->funcs.Destroy) (pDamage);
+ RegionUninit(&pDamage->damage);
+ RegionUninit(&pDamage->pendingDamage);
+ dixFreeObjectWithPrivates(pDamage, PRIVATE_DAMAGE);
+}
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion)
+{
+ RegionPtr pClip;
+ RegionRec pixmapClip;
+ DrawablePtr pDrawable = pDamage->pDrawable;
+
+ RegionSubtract(&pDamage->damage, &pDamage->damage, pRegion);
+ if (pDrawable)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pClip = &((WindowPtr) pDrawable)->borderClip;
+ else
+ {
+ BoxRec box;
+
+ box.x1 = pDrawable->x;
+ box.y1 = pDrawable->y;
+ box.x2 = pDrawable->x + pDrawable->width;
+ box.y2 = pDrawable->y + pDrawable->height;
+ RegionInit(&pixmapClip, &box, 1);
+ pClip = &pixmapClip;
+ }
+ RegionTranslate(&pDamage->damage, pDrawable->x, pDrawable->y);
+ RegionIntersect(&pDamage->damage, &pDamage->damage, pClip);
+ RegionTranslate(&pDamage->damage, -pDrawable->x, -pDrawable->y);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ RegionUninit(&pixmapClip);
+ }
+ return RegionNotEmpty(&pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr pDamage)
+{
+ RegionEmpty(&pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr pDamage)
+{
+ return &pDamage->damage;
+}
+
+RegionPtr
+DamagePendingRegion (DamagePtr pDamage)
+{
+ return &pDamage->pendingDamage;
+}
+
+void
+DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ damageRegionAppend (pDrawable, pRegion, FALSE, -1);
+}
+
+void
+DamageRegionProcessPending (DrawablePtr pDrawable)
+{
+ damageRegionProcessPending (pDrawable);
+}
+
+/* If a damage marker is provided, then this function must be called after rendering is done. */
+/* Please do call back so any future enhancements can assume this function is called. */
+/* There are no strict timing requirements for calling this function, just as soon as (is cheaply) possible. */
+void
+DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion)
+{
+ if (pDamage->damageReportPostRendering)
+ damageReportDamagePostRendering (pDamage, pOldDamage, pRegion);
+}
+
+/* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ const RegionPtr pRegion)
+{
+ damageRegionAppend (pDrawable, pRegion, FALSE, -1);
+
+ /* Go back and report this damage for DamagePtrs with reportAfter set, since
+ * this call isn't part of an in-progress drawing op in the call chain and
+ * the DDX probably just wants to know about it right away.
+ */
+ damageRegionProcessPending (pDrawable);
+}
+
+void
+DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter)
+{
+ pDamage->reportAfter = reportAfter;
+}
+
+void
+DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering,
+ DamageMarkerFunc damageMarker)
+{
+ pDamage->damageReportPostRendering = damageReportPostRendering;
+ pDamage->damageMarker = damageMarker;
+}
+
+DamageScreenFuncsPtr
+DamageGetScreenFuncs (ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+ return &pScrPriv->funcs;
+}
+
+void
+DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
+{
+ BoxRec tmpBox;
+ RegionRec tmpRegion;
+ Bool was_empty;
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ RegionNull(&tmpRegion);
+ RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage);
+ if (RegionNotEmpty(&tmpRegion)) {
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ RegionUninit(&tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *RegionExtents(&pDamage->damage);
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage))) {
+ (*pDamage->damageReport) (pDamage, &pDamage->damage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !RegionNotEmpty(&pDamage->damage);
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && RegionNotEmpty(&pDamage->damage)) {
+ (*pDamage->damageReport) (pDamage, &pDamage->damage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNone:
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+}
+
diff --git a/xorg-server/miext/damage/damage.h b/xorg-server/miext/damage/damage.h index 0c7fc316c..d2a032986 100644 --- a/xorg-server/miext/damage/damage.h +++ b/xorg-server/miext/damage/damage.h @@ -1,132 +1,132 @@ -/* - * Copyright © 2003 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 - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#ifndef _DAMAGE_H_ -#define _DAMAGE_H_ - -typedef struct _damage *DamagePtr; - -typedef enum _damageReportLevel { - DamageReportRawRegion, - DamageReportDeltaRegion, - DamageReportBoundingBox, - DamageReportNonEmpty, - DamageReportNone -} DamageReportLevel; - -typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure); -typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure); -/* It's the responsibility of the driver to duplicate both regions. */ -/* At some point DamageRegionRendered() must be called. */ -typedef void (*DamageMarkerFunc) (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion, void *closure); - -typedef void (*DamageScreenCreateFunc) (DamagePtr); -typedef void (*DamageScreenRegisterFunc) (DrawablePtr, DamagePtr); -typedef void (*DamageScreenUnregisterFunc) (DrawablePtr, DamagePtr); -typedef void (*DamageScreenDestroyFunc) (DamagePtr); - -typedef struct _damageScreenFuncs { - DamageScreenCreateFunc Create; - DamageScreenRegisterFunc Register; - DamageScreenUnregisterFunc Unregister; - DamageScreenDestroyFunc Destroy; -} DamageScreenFuncsRec, *DamageScreenFuncsPtr; - -extern _X_EXPORT void miDamageCreate (DamagePtr); -extern _X_EXPORT void miDamageRegister (DrawablePtr, DamagePtr); -extern _X_EXPORT void miDamageUnregister (DrawablePtr, DamagePtr); -extern _X_EXPORT void miDamageDestroy (DamagePtr); - -extern _X_EXPORT Bool -DamageSetup (ScreenPtr pScreen); - -extern _X_EXPORT DamagePtr -DamageCreate (DamageReportFunc damageReport, - DamageDestroyFunc damageDestroy, - DamageReportLevel damageLevel, - Bool isInternal, - ScreenPtr pScreen, - void * closure); - -extern _X_EXPORT void -DamageDrawInternal (ScreenPtr pScreen, Bool enable); - -extern _X_EXPORT void -DamageRegister (DrawablePtr pDrawable, - DamagePtr pDamage); - -extern _X_EXPORT void -DamageUnregister (DrawablePtr pDrawable, - DamagePtr pDamage); - -extern _X_EXPORT void -DamageDestroy (DamagePtr pDamage); - -extern _X_EXPORT Bool -DamageSubtract (DamagePtr pDamage, - const RegionPtr pRegion); - -extern _X_EXPORT void -DamageEmpty (DamagePtr pDamage); - -extern _X_EXPORT RegionPtr -DamageRegion (DamagePtr pDamage); - -extern _X_EXPORT RegionPtr -DamagePendingRegion (DamagePtr pDamage); - -/* In case of rendering, call this before the submitting the commands. */ -extern _X_EXPORT void -DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion); - -/* Call this directly after the rendering operation has been submitted. */ -extern _X_EXPORT void -DamageRegionProcessPending (DrawablePtr pDrawable); - -/* Call this some time after rendering is done, only relevant when a damageMarker is provided. */ -extern _X_EXPORT void -DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion); - -/* Call this when you create a new Damage and you wish to send an initial damage message (to it). */ -extern _X_EXPORT void -DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion); - -/* Avoid using this call, it only exists for API compatibility. */ -extern _X_EXPORT void -DamageDamageRegion (DrawablePtr pDrawable, - const RegionPtr pRegion); - -extern _X_EXPORT void -DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter); - -extern _X_EXPORT void -DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering, - DamageMarkerFunc damageMarker); - -extern _X_EXPORT DamageScreenFuncsPtr -DamageGetScreenFuncs (ScreenPtr); - -#endif /* _DAMAGE_H_ */ +/*
+ * Copyright © 2003 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
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DAMAGE_H_
+#define _DAMAGE_H_
+
+typedef struct _damage *DamagePtr;
+
+typedef enum _damageReportLevel {
+ DamageReportRawRegion,
+ DamageReportDeltaRegion,
+ DamageReportBoundingBox,
+ DamageReportNonEmpty,
+ DamageReportNone
+} DamageReportLevel;
+
+typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure);
+typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure);
+/* It's the responsibility of the driver to duplicate both regions. */
+/* At some point DamageRegionRendered() must be called. */
+typedef void (*DamageMarkerFunc) (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion, void *closure);
+
+typedef void (*DamageScreenCreateFunc) (DamagePtr);
+typedef void (*DamageScreenRegisterFunc) (DrawablePtr, DamagePtr);
+typedef void (*DamageScreenUnregisterFunc) (DrawablePtr, DamagePtr);
+typedef void (*DamageScreenDestroyFunc) (DamagePtr);
+
+typedef struct _damageScreenFuncs {
+ DamageScreenCreateFunc Create;
+ DamageScreenRegisterFunc Register;
+ DamageScreenUnregisterFunc Unregister;
+ DamageScreenDestroyFunc Destroy;
+} DamageScreenFuncsRec, *DamageScreenFuncsPtr;
+
+extern _X_EXPORT void miDamageCreate (DamagePtr);
+extern _X_EXPORT void miDamageRegister (DrawablePtr, DamagePtr);
+extern _X_EXPORT void miDamageUnregister (DrawablePtr, DamagePtr);
+extern _X_EXPORT void miDamageDestroy (DamagePtr);
+
+extern _X_EXPORT Bool
+DamageSetup (ScreenPtr pScreen);
+
+extern _X_EXPORT DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void * closure);
+
+extern _X_EXPORT void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable);
+
+extern _X_EXPORT void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage);
+
+extern _X_EXPORT void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage);
+
+extern _X_EXPORT void
+DamageDestroy (DamagePtr pDamage);
+
+extern _X_EXPORT Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion);
+
+extern _X_EXPORT void
+DamageEmpty (DamagePtr pDamage);
+
+extern _X_EXPORT RegionPtr
+DamageRegion (DamagePtr pDamage);
+
+extern _X_EXPORT RegionPtr
+DamagePendingRegion (DamagePtr pDamage);
+
+/* In case of rendering, call this before the submitting the commands. */
+extern _X_EXPORT void
+DamageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion);
+
+/* Call this directly after the rendering operation has been submitted. */
+extern _X_EXPORT void
+DamageRegionProcessPending (DrawablePtr pDrawable);
+
+/* Call this some time after rendering is done, only relevant when a damageMarker is provided. */
+extern _X_EXPORT void
+DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion);
+
+/* Call this when you create a new Damage and you wish to send an initial damage message (to it). */
+extern _X_EXPORT void
+DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion);
+
+/* Avoid using this call, it only exists for API compatibility. */
+extern _X_EXPORT void
+DamageDamageRegion (DrawablePtr pDrawable,
+ const RegionPtr pRegion);
+
+extern _X_EXPORT void
+DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter);
+
+extern _X_EXPORT void
+DamageSetPostRenderingFunctions(DamagePtr pDamage, DamageReportFunc damageReportPostRendering,
+ DamageMarkerFunc damageMarker);
+
+extern _X_EXPORT DamageScreenFuncsPtr
+DamageGetScreenFuncs (ScreenPtr);
+
+#endif /* _DAMAGE_H_ */
diff --git a/xorg-server/miext/damage/makefile b/xorg-server/miext/damage/makefile new file mode 100644 index 000000000..e58f4a883 --- /dev/null +++ b/xorg-server/miext/damage/makefile @@ -0,0 +1,7 @@ +LIBRARY = libdamage + +#INCLUDES = -I$(srcdir)/../cw -I$(top_srcdir)/hw/xfree86/os-support + +CSRCS =damage.c + + diff --git a/xorg-server/miext/rootless/makefile b/xorg-server/miext/rootless/makefile new file mode 100644 index 000000000..d49e810a2 --- /dev/null +++ b/xorg-server/miext/rootless/makefile @@ -0,0 +1,10 @@ +LIBRARY=librootless + +librootless_la_SOURCES = \ + rootlessCommon.c \ + rootlessGC.c \ + rootlessScreen.c \ + rootlessValTree.c \ + rootlessWindow.c + +CSRCS = $(filter %.c,$(librootless_la_SOURCES)) diff --git a/xorg-server/miext/rootless/rootlessGC.c b/xorg-server/miext/rootless/rootlessGC.c index 21a3bd806..2af251ee6 100644 --- a/xorg-server/miext/rootless/rootlessGC.c +++ b/xorg-server/miext/rootless/rootlessGC.c @@ -49,6 +49,9 @@ #include "rootlessCommon.h"
+#ifdef _MSC_VER
+#define inline __inline
+#endif
// GC functions
static void RootlessValidateGC(GCPtr pGC, unsigned long changes,
diff --git a/xorg-server/miext/rootless/rootlessScreen.c b/xorg-server/miext/rootless/rootlessScreen.c index 0801e7206..03e3278d3 100644 --- a/xorg-server/miext/rootless/rootlessScreen.c +++ b/xorg-server/miext/rootless/rootlessScreen.c @@ -1,754 +1,754 @@ -/* - * Screen routines for generic rootless X server - */ -/* - * Copyright (c) 2001 Greg Parker. All Rights Reserved. - * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "mi.h" -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "propertyst.h" -#include "mivalidate.h" -#include "picturestr.h" -#include "colormapst.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> - -#include "rootlessCommon.h" -#include "rootlessWindow.h" - -/* In milliseconds */ -#ifndef ROOTLESS_REDISPLAY_DELAY -#define ROOTLESS_REDISPLAY_DELAY 10 -#endif - -extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, - VTKind kind); -extern Bool RootlessCreateGC(GCPtr pGC); - -// Initialize globals -DevPrivateKeyRec rootlessGCPrivateKeyRec; -DevPrivateKeyRec rootlessScreenPrivateKeyRec; -DevPrivateKeyRec rootlessWindowPrivateKeyRec; -DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec; - -/* - * RootlessUpdateScreenPixmap - * miCreateScreenResources does not like a null framebuffer pointer, - * it leaves the screen pixmap with an uninitialized data pointer. - * Thus, rootless implementations typically set the framebuffer width - * to zero so that miCreateScreenResources does not allocate a screen - * pixmap for us. We allocate our own screen pixmap here since we need - * the screen pixmap to be valid (e.g. CopyArea from the root window). - */ -void -RootlessUpdateScreenPixmap(ScreenPtr pScreen) -{ - RootlessScreenRec *s = SCREENREC(pScreen); - PixmapPtr pPix; - unsigned int rowbytes; - - pPix = (*pScreen->GetScreenPixmap)(pScreen); - if (pPix == NULL) { - pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); - (*pScreen->SetScreenPixmap)(pPix); - } - - rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth); - - if (s->pixmap_data_size < rowbytes) { - free(s->pixmap_data); - - s->pixmap_data_size = rowbytes; - s->pixmap_data = malloc(s->pixmap_data_size); - if (s->pixmap_data == NULL) - return; - - memset(s->pixmap_data, 0xFF, s->pixmap_data_size); - - pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height, - pScreen->rootDepth, - BitsPerPixel(pScreen->rootDepth), - 0, s->pixmap_data); - /* ModifyPixmapHeader ignores zero arguments, so install rowbytes - by hand. */ - pPix->devKind = 0; - } -} - - -/* - * RootlessCreateScreenResources - * Rootless implementations typically set a null framebuffer pointer, which - * causes problems with miCreateScreenResources. We fix things up here. - */ -static Bool -RootlessCreateScreenResources(ScreenPtr pScreen) -{ - Bool ret = TRUE; - - SCREEN_UNWRAP(pScreen, CreateScreenResources); - - if (pScreen->CreateScreenResources != NULL) - ret = (*pScreen->CreateScreenResources)(pScreen); - - SCREEN_WRAP(pScreen, CreateScreenResources); - - if (!ret) - return ret; - - /* Make sure we have a valid screen pixmap. */ - - RootlessUpdateScreenPixmap(pScreen); - - return ret; -} - - -static Bool -RootlessCloseScreen(int i, ScreenPtr pScreen) -{ - RootlessScreenRec *s; - - s = SCREENREC(pScreen); - - // fixme unwrap everything that was wrapped? - pScreen->CloseScreen = s->CloseScreen; - - if (s->pixmap_data != NULL) { - free(s->pixmap_data); - s->pixmap_data = NULL; - s->pixmap_data_size = 0; - } - - free(s); - return pScreen->CloseScreen(i, pScreen); -} - - -static void -RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, - unsigned int format, unsigned long planeMask, char *pdstLine) -{ - ScreenPtr pScreen = pDrawable->pScreen; - SCREEN_UNWRAP(pScreen, GetImage); - - if (pDrawable->type == DRAWABLE_WINDOW) { - int x0, y0, x1, y1; - RootlessWindowRec *winRec; - - // Many apps use GetImage to sync with the visible frame buffer - // FIXME: entire screen or just window or all screens? - RootlessRedisplayScreen(pScreen); - - // RedisplayScreen stops drawing, so we need to start it again - RootlessStartDrawing((WindowPtr)pDrawable); - - /* Check that we have some place to read from. */ - winRec = WINREC(TopLevelParent((WindowPtr) pDrawable)); - if (winRec == NULL) - goto out; - - /* Clip to top-level window bounds. */ - /* FIXME: fbGetImage uses the width parameter to calculate the - stride of the destination pixmap. If w is clipped, the data - returned will be garbage, although we will not crash. */ - - x0 = pDrawable->x + sx; - y0 = pDrawable->y + sy; - x1 = x0 + w; - y1 = y0 + h; - - x0 = max (x0, winRec->x); - y0 = max (y0, winRec->y); - x1 = min (x1, winRec->x + winRec->width); - y1 = min (y1, winRec->y + winRec->height); - - sx = x0 - pDrawable->x; - sy = y0 - pDrawable->y; - w = x1 - x0; - h = y1 - y0; - - if (w <= 0 || h <= 0) - goto out; - } - - pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); - -out: - SCREEN_WRAP(pScreen, GetImage); -} - - -/* - * RootlessSourceValidate - * CopyArea and CopyPlane use a GC tied to the destination drawable. - * StartDrawing/StopDrawing wrappers won't be called if source is - * a visible window but the destination isn't. So, we call StartDrawing - * here and leave StopDrawing for the block handler. - */ -static void -RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int subWindowMode) -{ - SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate); - if (pDrawable->type == DRAWABLE_WINDOW) { - WindowPtr pWin = (WindowPtr)pDrawable; - RootlessStartDrawing(pWin); - } - if (pDrawable->pScreen->SourceValidate) { - pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode); - } - SCREEN_WRAP(pDrawable->pScreen, SourceValidate); -} - -static void -RootlessComposite(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); - WindowPtr srcWin, dstWin, maskWin = NULL; - - if (pMask) { // pMask can be NULL - maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pMask->pDrawable : NULL; - } - srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pSrc->pDrawable : NULL; - dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pDst->pDrawable : NULL; - - // SCREEN_UNWRAP(ps, Composite); - ps->Composite = SCREENREC(pScreen)->Composite; - - if (srcWin && IsFramedWindow(srcWin)) - RootlessStartDrawing(srcWin); - if (maskWin && IsFramedWindow(maskWin)) - RootlessStartDrawing(maskWin); - if (dstWin && IsFramedWindow(dstWin)) - RootlessStartDrawing(dstWin); - - ps->Composite(op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, - xDst, yDst, width, height); - - if (dstWin && IsFramedWindow(dstWin)) { - RootlessDamageRect(dstWin, xDst, yDst, width, height); - } - - ps->Composite = RootlessComposite; - // SCREEN_WRAP(ps, Composite); -} - - -static void -RootlessGlyphs(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); - int x, y; - int n; - GlyphPtr glyph; - WindowPtr srcWin, dstWin; - - srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pSrc->pDrawable : NULL; - dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? - (WindowPtr)pDst->pDrawable : NULL; - - if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); - if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); - - //SCREEN_UNWRAP(ps, Glyphs); - ps->Glyphs = SCREENREC(pScreen)->Glyphs; - ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - ps->Glyphs = RootlessGlyphs; - //SCREEN_WRAP(ps, Glyphs); - - if (dstWin && IsFramedWindow(dstWin)) { - x = xSrc; - y = ySrc; - - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - - /* Calling DamageRect for the bounding box of each glyph is - inefficient. So compute the union of all glyphs in a list - and damage that. */ - - if (n > 0) { - BoxRec box; - - glyph = *glyphs++; - - box.x1 = x - glyph->info.x; - box.y1 = y - glyph->info.y; - box.x2 = box.x1 + glyph->info.width; - box.y2 = box.y1 + glyph->info.height; - - x += glyph->info.xOff; - y += glyph->info.yOff; - - while (--n > 0) { - short x1, y1, x2, y2; - - glyph = *glyphs++; - - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - x2 = x1 + glyph->info.width; - y2 = y1 + glyph->info.height; - - box.x1 = max (box.x1, x1); - box.y1 = max (box.y1, y1); - box.x2 = max (box.x2, x2); - box.y2 = max (box.y2, y2); - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - - RootlessDamageBox(dstWin, &box); - } - list++; - } - } -} - - -/* - * RootlessValidateTree - * ValidateTree is modified in two ways: - * - top-level windows don't clip each other - * - windows aren't clipped against root. - * These only matter when validating from the root. - */ -static int -RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) -{ - int result; - RegionRec saveRoot; - ScreenPtr pScreen = pParent->drawable.pScreen; - - SCREEN_UNWRAP(pScreen, ValidateTree); - RL_DEBUG_MSG("VALIDATETREE start "); - - // Use our custom version to validate from root - if (IsRoot(pParent)) { - RL_DEBUG_MSG("custom "); - result = RootlessMiValidateTree(pParent, pChild, kind); - } else { - HUGE_ROOT(pParent); - result = pScreen->ValidateTree(pParent, pChild, kind); - NORMAL_ROOT(pParent); - } - - SCREEN_WRAP(pScreen, ValidateTree); - RL_DEBUG_MSG("VALIDATETREE end\n"); - - return result; -} - - -/* - * RootlessMarkOverlappedWindows - * MarkOverlappedWindows is modified to ignore overlapping - * top-level windows. - */ -static Bool -RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, - WindowPtr *ppLayerWin) -{ - RegionRec saveRoot; - Bool result; - ScreenPtr pScreen = pWin->drawable.pScreen; - SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); - RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); - - HUGE_ROOT(pWin); - if (IsRoot(pWin)) { - // root - mark nothing - RL_DEBUG_MSG("is root not marking "); - result = FALSE; - } - else if (! IsTopLevel(pWin)) { - // not top-level window - mark normally - result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); - } - else { - //top-level window - mark children ONLY - NO overlaps with sibs (?) - // This code copied from miMarkOverlappedWindows() - - register WindowPtr pChild; - Bool anyMarked = FALSE; - MarkWindowProcPtr MarkWindow = pScreen->MarkWindow; - - RL_DEBUG_MSG("is top level! "); - /* single layered systems are easy */ - if (ppLayerWin) *ppLayerWin = pWin; - - if (pWin == pFirst) { - /* Blindly mark pWin and all of its inferiors. This is a slight - * overkill if there are mapped windows that outside pWin's border, - * but it's better than wasting time on RectIn checks. - */ - pChild = pWin; - while (1) { - if (pChild->viewable) { - if (RegionBroken(&pChild->winSize)) - SetWinSize (pChild); - if (RegionBroken(&pChild->borderSize)) - SetBorderSize (pChild); - (* MarkWindow)(pChild); - if (pChild->firstChild) { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pWin)) - pChild = pChild->parent; - if (pChild == pWin) - break; - pChild = pChild->nextSib; - } - anyMarked = TRUE; - } - if (anyMarked) - (* MarkWindow)(pWin->parent); - result = anyMarked; - } - NORMAL_ROOT(pWin); - SCREEN_WRAP(pScreen, MarkOverlappedWindows); - RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n"); - - return result; -} - -static void expose_1 (WindowPtr pWin) { - WindowPtr pChild; - - if (!pWin->realized) - return; - - miPaintWindow(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 - be exposing too much.. */ - - miSendExposures (pWin, &pWin->borderClip, - pWin->drawable.x, pWin->drawable.y); - - for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) - expose_1 (pChild); -} - -void -RootlessScreenExpose (ScreenPtr pScreen) -{ - expose_1 (pScreen->root); -} - - -ColormapPtr -RootlessGetColormap (ScreenPtr pScreen) -{ - RootlessScreenRec *s = SCREENREC (pScreen); - - return s->colormap; -} - -static void -RootlessInstallColormap (ColormapPtr pMap) -{ - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); - - SCREEN_UNWRAP(pScreen, InstallColormap); - - if (s->colormap != pMap) { - s->colormap = pMap; - s->colormap_changed = TRUE; - RootlessQueueRedisplay (pScreen); - } - - pScreen->InstallColormap (pMap); - - SCREEN_WRAP (pScreen, InstallColormap); -} - -static void -RootlessUninstallColormap (ColormapPtr pMap) -{ - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); - - SCREEN_UNWRAP(pScreen, UninstallColormap); - - if (s->colormap == pMap) - s->colormap = NULL; - - pScreen->UninstallColormap (pMap); - - SCREEN_WRAP(pScreen, UninstallColormap); -} - -static void -RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) -{ - ScreenPtr pScreen = pMap->pScreen; - RootlessScreenRec *s = SCREENREC (pScreen); - - SCREEN_UNWRAP(pScreen, StoreColors); - - if (s->colormap == pMap && ndef > 0) { - s->colormap_changed = TRUE; - RootlessQueueRedisplay (pScreen); - } - - pScreen->StoreColors (pMap, ndef, pdef); - - SCREEN_WRAP(pScreen, StoreColors); -} - - -static CARD32 -RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg) -{ - RootlessScreenRec *screenRec = arg; - - if (!screenRec->redisplay_queued) { - /* No update needed. Stop the timer. */ - - screenRec->redisplay_timer_set = FALSE; - return 0; - } - - screenRec->redisplay_queued = FALSE; - - /* Mark that we should redisplay before waiting for I/O next time */ - screenRec->redisplay_expired = TRUE; - - /* Reinstall the timer immediately, so we get as close to our - redisplay interval as possible. */ - - return ROOTLESS_REDISPLAY_DELAY; -} - - -/* - * RootlessQueueRedisplay - * Queue a redisplay after a timer delay to ensure we do not redisplay - * too frequently. - */ -void -RootlessQueueRedisplay(ScreenPtr pScreen) -{ - RootlessScreenRec *screenRec = SCREENREC(pScreen); - - screenRec->redisplay_queued = TRUE; - - if (screenRec->redisplay_timer_set) - return; - - screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer, - 0, ROOTLESS_REDISPLAY_DELAY, - RootlessRedisplayCallback, - screenRec); - screenRec->redisplay_timer_set = TRUE; -} - - -/* - * RootlessBlockHandler - * If the redisplay timer has expired, flush drawing before blocking - * on select(). - */ -static void -RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask) -{ - ScreenPtr pScreen = pbdata; - RootlessScreenRec *screenRec = SCREENREC(pScreen); - - if (screenRec->redisplay_expired) { - screenRec->redisplay_expired = FALSE; - - RootlessRedisplayScreen(pScreen); - } -} - - -static void -RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask) -{ - // nothing here -} - - -static Bool -RootlessAllocatePrivates(ScreenPtr pScreen) -{ - RootlessScreenRec *s; - - if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec))) - return FALSE; - if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) - return FALSE; - if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0)) - return FALSE; - - s = malloc(sizeof(RootlessScreenRec)); - if (! s) return FALSE; - SETSCREENREC(pScreen, s); - - s->pixmap_data = NULL; - s->pixmap_data_size = 0; - - s->redisplay_timer = NULL; - s->redisplay_timer_set = FALSE; - - return TRUE; -} - - -static void -RootlessWrap(ScreenPtr pScreen) -{ - RootlessScreenRec *s = SCREENREC(pScreen); - -#define WRAP(a) \ - if (pScreen->a) { \ - s->a = pScreen->a; \ - } else { \ - RL_DEBUG_MSG("null screen fn " #a "\n"); \ - s->a = NULL; \ - } \ - pScreen->a = Rootless##a - - WRAP(CreateScreenResources); - WRAP(CloseScreen); - WRAP(CreateGC); - WRAP(CopyWindow); - WRAP(GetImage); - WRAP(SourceValidate); - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(MoveWindow); - WRAP(PositionWindow); - WRAP(ResizeWindow); - WRAP(RestackWindow); - WRAP(ReparentWindow); - WRAP(ChangeBorderWidth); - WRAP(MarkOverlappedWindows); - WRAP(ValidateTree); - WRAP(ChangeWindowAttributes); - WRAP(InstallColormap); - WRAP(UninstallColormap); - WRAP(StoreColors); - - WRAP(SetShape); - - { - // Composite and Glyphs don't use normal screen wrapping - PictureScreenPtr ps = GetPictureScreen(pScreen); - s->Composite = ps->Composite; - ps->Composite = RootlessComposite; - s->Glyphs = ps->Glyphs; - ps->Glyphs = RootlessGlyphs; - } - - // WRAP(ClearToBackground); fixme put this back? useful for shaped wins? - -#undef WRAP -} - - -/* - * RootlessInit - * Called by the rootless implementation to initialize the rootless layer. - * Rootless wraps lots of stuff and needs a bunch of devPrivates. - */ -Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs) -{ - RootlessScreenRec *s; - - if (!RootlessAllocatePrivates(pScreen)) - return FALSE; - - s = SCREENREC(pScreen); - - s->imp = procs; - s->colormap = NULL; - s->redisplay_expired = FALSE; - - RootlessWrap(pScreen); - - if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler, - RootlessWakeupHandler, - (pointer) pScreen)) - { - return FALSE; - } - - return TRUE; -} - -void RootlessUpdateRooted (Bool state) { - int i; - - if (!state) - { - for (i = 0; i < screenInfo.numScreens; i++) - RootlessDisableRoot (screenInfo.screens[i]); - } - else - { - for (i = 0; i < screenInfo.numScreens; i++) - RootlessEnableRoot (screenInfo.screens[i]); - } -} +/*
+ * Screen routines for generic rootless X server
+ */
+/*
+ * Copyright (c) 2001 Greg Parker. All Rights Reserved.
+ * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "mivalidate.h"
+#include "picturestr.h"
+#include "colormapst.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "rootlessCommon.h"
+#include "rootlessWindow.h"
+
+/* In milliseconds */
+#ifndef ROOTLESS_REDISPLAY_DELAY
+#define ROOTLESS_REDISPLAY_DELAY 10
+#endif
+
+extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
+ VTKind kind);
+extern Bool RootlessCreateGC(GCPtr pGC);
+
+// Initialize globals
+DevPrivateKeyRec rootlessGCPrivateKeyRec;
+DevPrivateKeyRec rootlessScreenPrivateKeyRec;
+DevPrivateKeyRec rootlessWindowPrivateKeyRec;
+DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
+
+/*
+ * RootlessUpdateScreenPixmap
+ * miCreateScreenResources does not like a null framebuffer pointer,
+ * it leaves the screen pixmap with an uninitialized data pointer.
+ * Thus, rootless implementations typically set the framebuffer width
+ * to zero so that miCreateScreenResources does not allocate a screen
+ * pixmap for us. We allocate our own screen pixmap here since we need
+ * the screen pixmap to be valid (e.g. CopyArea from the root window).
+ */
+void
+RootlessUpdateScreenPixmap(ScreenPtr pScreen)
+{
+ RootlessScreenRec *s = SCREENREC(pScreen);
+ PixmapPtr pPix;
+ unsigned int rowbytes;
+
+ pPix = (*pScreen->GetScreenPixmap)(pScreen);
+ if (pPix == NULL) {
+ pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
+ (*pScreen->SetScreenPixmap)(pPix);
+ }
+
+ rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
+
+ if (s->pixmap_data_size < rowbytes) {
+ free(s->pixmap_data);
+
+ s->pixmap_data_size = rowbytes;
+ s->pixmap_data = malloc(s->pixmap_data_size);
+ if (s->pixmap_data == NULL)
+ return;
+
+ memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
+
+ pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
+ pScreen->rootDepth,
+ BitsPerPixel(pScreen->rootDepth),
+ 0, s->pixmap_data);
+ /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
+ by hand. */
+ pPix->devKind = 0;
+ }
+}
+
+
+/*
+ * RootlessCreateScreenResources
+ * Rootless implementations typically set a null framebuffer pointer, which
+ * causes problems with miCreateScreenResources. We fix things up here.
+ */
+static Bool
+RootlessCreateScreenResources(ScreenPtr pScreen)
+{
+ Bool ret = TRUE;
+
+ SCREEN_UNWRAP(pScreen, CreateScreenResources);
+
+ if (pScreen->CreateScreenResources != NULL)
+ ret = (*pScreen->CreateScreenResources)(pScreen);
+
+ SCREEN_WRAP(pScreen, CreateScreenResources);
+
+ if (!ret)
+ return ret;
+
+ /* Make sure we have a valid screen pixmap. */
+
+ RootlessUpdateScreenPixmap(pScreen);
+
+ return ret;
+}
+
+
+static Bool
+RootlessCloseScreen(int i, ScreenPtr pScreen)
+{
+ RootlessScreenRec *s;
+
+ s = SCREENREC(pScreen);
+
+ // fixme unwrap everything that was wrapped?
+ pScreen->CloseScreen = s->CloseScreen;
+
+ if (s->pixmap_data != NULL) {
+ free(s->pixmap_data);
+ s->pixmap_data = NULL;
+ s->pixmap_data_size = 0;
+ }
+
+ free(s);
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+
+static void
+RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planeMask, char *pdstLine)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_UNWRAP(pScreen, GetImage);
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ int x0, y0, x1, y1;
+ RootlessWindowRec *winRec;
+
+ // Many apps use GetImage to sync with the visible frame buffer
+ // FIXME: entire screen or just window or all screens?
+ RootlessRedisplayScreen(pScreen);
+
+ // RedisplayScreen stops drawing, so we need to start it again
+ RootlessStartDrawing((WindowPtr)pDrawable);
+
+ /* Check that we have some place to read from. */
+ winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
+ if (winRec == NULL)
+ goto out;
+
+ /* Clip to top-level window bounds. */
+ /* FIXME: fbGetImage uses the width parameter to calculate the
+ stride of the destination pixmap. If w is clipped, the data
+ returned will be garbage, although we will not crash. */
+
+ x0 = pDrawable->x + sx;
+ y0 = pDrawable->y + sy;
+ x1 = x0 + w;
+ y1 = y0 + h;
+
+ x0 = max (x0, winRec->x);
+ y0 = max (y0, winRec->y);
+ x1 = min (x1, winRec->x + winRec->width);
+ y1 = min (y1, winRec->y + winRec->height);
+
+ sx = x0 - pDrawable->x;
+ sy = y0 - pDrawable->y;
+ w = x1 - x0;
+ h = y1 - y0;
+
+ if (w <= 0 || h <= 0)
+ goto out;
+ }
+
+ pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+
+out:
+ SCREEN_WRAP(pScreen, GetImage);
+}
+
+
+/*
+ * RootlessSourceValidate
+ * CopyArea and CopyPlane use a GC tied to the destination drawable.
+ * StartDrawing/StopDrawing wrappers won't be called if source is
+ * a visible window but the destination isn't. So, we call StartDrawing
+ * here and leave StopDrawing for the block handler.
+ */
+static void
+RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int subWindowMode)
+{
+ SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDrawable;
+ RootlessStartDrawing(pWin);
+ }
+ if (pDrawable->pScreen->SourceValidate) {
+ pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode);
+ }
+ SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
+}
+
+static void
+RootlessComposite(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);
+ WindowPtr srcWin, dstWin, maskWin = NULL;
+
+ if (pMask) { // pMask can be NULL
+ maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pMask->pDrawable : NULL;
+ }
+ srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pSrc->pDrawable : NULL;
+ dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pDst->pDrawable : NULL;
+
+ // SCREEN_UNWRAP(ps, Composite);
+ ps->Composite = SCREENREC(pScreen)->Composite;
+
+ if (srcWin && IsFramedWindow(srcWin))
+ RootlessStartDrawing(srcWin);
+ if (maskWin && IsFramedWindow(maskWin))
+ RootlessStartDrawing(maskWin);
+ if (dstWin && IsFramedWindow(dstWin))
+ RootlessStartDrawing(dstWin);
+
+ ps->Composite(op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+
+ if (dstWin && IsFramedWindow(dstWin)) {
+ RootlessDamageRect(dstWin, xDst, yDst, width, height);
+ }
+
+ ps->Composite = RootlessComposite;
+ // SCREEN_WRAP(ps, Composite);
+}
+
+
+static void
+RootlessGlyphs(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);
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ WindowPtr srcWin, dstWin;
+
+ srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pSrc->pDrawable : NULL;
+ dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pDst->pDrawable : NULL;
+
+ if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
+ if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
+
+ //SCREEN_UNWRAP(ps, Glyphs);
+ ps->Glyphs = SCREENREC(pScreen)->Glyphs;
+ ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ ps->Glyphs = RootlessGlyphs;
+ //SCREEN_WRAP(ps, Glyphs);
+
+ if (dstWin && IsFramedWindow(dstWin)) {
+ x = xSrc;
+ y = ySrc;
+
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+
+ /* Calling DamageRect for the bounding box of each glyph is
+ inefficient. So compute the union of all glyphs in a list
+ and damage that. */
+
+ if (n > 0) {
+ BoxRec box;
+
+ glyph = *glyphs++;
+
+ box.x1 = x - glyph->info.x;
+ box.y1 = y - glyph->info.y;
+ box.x2 = box.x1 + glyph->info.width;
+ box.y2 = box.y1 + glyph->info.height;
+
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+
+ while (--n > 0) {
+ short x1, y1, x2, y2;
+
+ glyph = *glyphs++;
+
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+
+ box.x1 = max (box.x1, x1);
+ box.y1 = max (box.y1, y1);
+ box.x2 = max (box.x2, x2);
+ box.y2 = max (box.y2, y2);
+
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+
+ RootlessDamageBox(dstWin, &box);
+ }
+ list++;
+ }
+ }
+}
+
+
+/*
+ * RootlessValidateTree
+ * ValidateTree is modified in two ways:
+ * - top-level windows don't clip each other
+ * - windows aren't clipped against root.
+ * These only matter when validating from the root.
+ */
+static int
+RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ int result;
+ RegionRec saveRoot;
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+
+ SCREEN_UNWRAP(pScreen, ValidateTree);
+ RL_DEBUG_MSG("VALIDATETREE start ");
+
+ // Use our custom version to validate from root
+ if (IsRoot(pParent)) {
+ RL_DEBUG_MSG("custom ");
+ result = RootlessMiValidateTree(pParent, pChild, kind);
+ } else {
+ HUGE_ROOT(pParent);
+ result = pScreen->ValidateTree(pParent, pChild, kind);
+ NORMAL_ROOT(pParent);
+ }
+
+ SCREEN_WRAP(pScreen, ValidateTree);
+ RL_DEBUG_MSG("VALIDATETREE end\n");
+
+ return result;
+}
+
+
+/*
+ * RootlessMarkOverlappedWindows
+ * MarkOverlappedWindows is modified to ignore overlapping
+ * top-level windows.
+ */
+static Bool
+RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
+ WindowPtr *ppLayerWin)
+{
+ RegionRec saveRoot;
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
+ RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
+
+ HUGE_ROOT(pWin);
+ if (IsRoot(pWin)) {
+ // root - mark nothing
+ RL_DEBUG_MSG("is root not marking ");
+ result = FALSE;
+ }
+ else if (! IsTopLevel(pWin)) {
+ // not top-level window - mark normally
+ result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
+ }
+ else {
+ //top-level window - mark children ONLY - NO overlaps with sibs (?)
+ // This code copied from miMarkOverlappedWindows()
+
+ register WindowPtr pChild;
+ Bool anyMarked = FALSE;
+ MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;
+
+ RL_DEBUG_MSG("is top level! ");
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst) {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1) {
+ if (pChild->viewable) {
+ if (RegionBroken(&pChild->winSize))
+ SetWinSize (pChild);
+ if (RegionBroken(&pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ result = anyMarked;
+ }
+ NORMAL_ROOT(pWin);
+ SCREEN_WRAP(pScreen, MarkOverlappedWindows);
+ RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
+
+ return result;
+}
+
+static void expose_1 (WindowPtr pWin) {
+ WindowPtr pChild;
+
+ if (!pWin->realized)
+ return;
+
+ miPaintWindow(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
+ be exposing too much.. */
+
+ miSendExposures (pWin, &pWin->borderClip,
+ pWin->drawable.x, pWin->drawable.y);
+
+ for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
+ expose_1 (pChild);
+}
+
+void
+RootlessScreenExpose (ScreenPtr pScreen)
+{
+ expose_1 (pScreen->root);
+}
+
+
+ColormapPtr
+RootlessGetColormap (ScreenPtr pScreen)
+{
+ RootlessScreenRec *s = SCREENREC (pScreen);
+
+ return s->colormap;
+}
+
+static void
+RootlessInstallColormap (ColormapPtr pMap)
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ RootlessScreenRec *s = SCREENREC (pScreen);
+
+ SCREEN_UNWRAP(pScreen, InstallColormap);
+
+ if (s->colormap != pMap) {
+ s->colormap = pMap;
+ s->colormap_changed = TRUE;
+ RootlessQueueRedisplay (pScreen);
+ }
+
+ pScreen->InstallColormap (pMap);
+
+ SCREEN_WRAP (pScreen, InstallColormap);
+}
+
+static void
+RootlessUninstallColormap (ColormapPtr pMap)
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ RootlessScreenRec *s = SCREENREC (pScreen);
+
+ SCREEN_UNWRAP(pScreen, UninstallColormap);
+
+ if (s->colormap == pMap)
+ s->colormap = NULL;
+
+ pScreen->UninstallColormap (pMap);
+
+ SCREEN_WRAP(pScreen, UninstallColormap);
+}
+
+static void
+RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ RootlessScreenRec *s = SCREENREC (pScreen);
+
+ SCREEN_UNWRAP(pScreen, StoreColors);
+
+ if (s->colormap == pMap && ndef > 0) {
+ s->colormap_changed = TRUE;
+ RootlessQueueRedisplay (pScreen);
+ }
+
+ pScreen->StoreColors (pMap, ndef, pdef);
+
+ SCREEN_WRAP(pScreen, StoreColors);
+}
+
+
+static CARD32
+RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
+{
+ RootlessScreenRec *screenRec = arg;
+
+ if (!screenRec->redisplay_queued) {
+ /* No update needed. Stop the timer. */
+
+ screenRec->redisplay_timer_set = FALSE;
+ return 0;
+ }
+
+ screenRec->redisplay_queued = FALSE;
+
+ /* Mark that we should redisplay before waiting for I/O next time */
+ screenRec->redisplay_expired = TRUE;
+
+ /* Reinstall the timer immediately, so we get as close to our
+ redisplay interval as possible. */
+
+ return ROOTLESS_REDISPLAY_DELAY;
+}
+
+
+/*
+ * RootlessQueueRedisplay
+ * Queue a redisplay after a timer delay to ensure we do not redisplay
+ * too frequently.
+ */
+void
+RootlessQueueRedisplay(ScreenPtr pScreen)
+{
+ RootlessScreenRec *screenRec = SCREENREC(pScreen);
+
+ screenRec->redisplay_queued = TRUE;
+
+ if (screenRec->redisplay_timer_set)
+ return;
+
+ screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
+ 0, ROOTLESS_REDISPLAY_DELAY,
+ RootlessRedisplayCallback,
+ screenRec);
+ screenRec->redisplay_timer_set = TRUE;
+}
+
+
+/*
+ * RootlessBlockHandler
+ * If the redisplay timer has expired, flush drawing before blocking
+ * on select().
+ */
+static void
+RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = pbdata;
+ RootlessScreenRec *screenRec = SCREENREC(pScreen);
+
+ if (screenRec->redisplay_expired) {
+ screenRec->redisplay_expired = FALSE;
+
+ RootlessRedisplayScreen(pScreen);
+ }
+}
+
+
+static void
+RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
+{
+ // nothing here
+}
+
+
+static Bool
+RootlessAllocatePrivates(ScreenPtr pScreen)
+{
+ RootlessScreenRec *s;
+
+ if (!dixRegisterPrivateKey(&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec)))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ s = malloc(sizeof(RootlessScreenRec));
+ if (! s) return FALSE;
+ SETSCREENREC(pScreen, s);
+
+ s->pixmap_data = NULL;
+ s->pixmap_data_size = 0;
+
+ s->redisplay_timer = NULL;
+ s->redisplay_timer_set = FALSE;
+
+ return TRUE;
+}
+
+
+static void
+RootlessWrap(ScreenPtr pScreen)
+{
+ RootlessScreenRec *s = SCREENREC(pScreen);
+
+#define WRAP(a) \
+ if (pScreen->a) { \
+ s->a = pScreen->a; \
+ } else { \
+ RL_DEBUG_MSG("null screen fn " #a "\n"); \
+ s->a = NULL; \
+ } \
+ pScreen->a = Rootless##a
+
+ WRAP(CreateScreenResources);
+ WRAP(CloseScreen);
+ WRAP(CreateGC);
+ WRAP(CopyWindow);
+ WRAP(GetImage);
+ WRAP(SourceValidate);
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(MoveWindow);
+ WRAP(PositionWindow);
+ WRAP(ResizeWindow);
+ WRAP(RestackWindow);
+ WRAP(ReparentWindow);
+ WRAP(ChangeBorderWidth);
+ WRAP(MarkOverlappedWindows);
+ WRAP(ValidateTree);
+ WRAP(ChangeWindowAttributes);
+ WRAP(InstallColormap);
+ WRAP(UninstallColormap);
+ WRAP(StoreColors);
+
+ WRAP(SetShape);
+
+ {
+ // Composite and Glyphs don't use normal screen wrapping
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ s->Composite = ps->Composite;
+ ps->Composite = RootlessComposite;
+ s->Glyphs = ps->Glyphs;
+ ps->Glyphs = RootlessGlyphs;
+ }
+
+ // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
+
+#undef WRAP
+}
+
+
+/*
+ * RootlessInit
+ * Called by the rootless implementation to initialize the rootless layer.
+ * Rootless wraps lots of stuff and needs a bunch of devPrivates.
+ */
+Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
+{
+ RootlessScreenRec *s;
+
+ if (!RootlessAllocatePrivates(pScreen))
+ return FALSE;
+
+ s = SCREENREC(pScreen);
+
+ s->imp = procs;
+ s->colormap = NULL;
+ s->redisplay_expired = FALSE;
+
+ RootlessWrap(pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
+ RootlessWakeupHandler,
+ (pointer) pScreen))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void RootlessUpdateRooted (Bool state) {
+ int i;
+
+ if (!state)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ RootlessDisableRoot (screenInfo.screens[i]);
+ }
+ else
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ RootlessEnableRoot (screenInfo.screens[i]);
+ }
+}
diff --git a/xorg-server/miext/rootless/rootlessValTree.c b/xorg-server/miext/rootless/rootlessValTree.c index 9aa881423..95bf20bad 100644 --- a/xorg-server/miext/rootless/rootlessValTree.c +++ b/xorg-server/miext/rootless/rootlessValTree.c @@ -1,621 +1,621 @@ -/* - * Calculate window clip lists for rootless mode - * - * This file is very closely based on mivaltree.c. - */ - -/* - * mivaltree.c -- - * Functions for recalculating window clip lists. Main function - * is miValidateTree. - * - -Copyright 1987, 1988, 1989, 1998 The Open Group - -All Rights Reserved. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - * - * Copyright 1987, 1988, 1989 by - * Digital Equipment Corporation, Maynard, Massachusetts, - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Digital not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - ******************************************************************/ - -/* The panoramix components contained the following notice */ -/***************************************************************** - -Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, -BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Digital Equipment Corporation -shall not be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization from Digital -Equipment Corporation. - -******************************************************************/ - /* - * Aug '86: Susan Angebranndt -- original code - * July '87: Adam de Boor -- substantially modified and commented - * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible. - * In particular, much improved code for window mapping and - * circulating. - * Bob Scheifler -- avoid miComputeClips for unmapped windows, - * valdata changes - */ -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stddef.h> /* For NULL */ -#include <X11/X.h> -#include "scrnintstr.h" -#include "validate.h" -#include "windowstr.h" -#include "mi.h" -#include "regionstr.h" -#include "mivalidate.h" - -#include "globals.h" - -int RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind); - -/* - * Compute the visibility of a shaped window - */ -static int -RootlessShapedWindowIn (RegionPtr universe, - RegionPtr bounding, BoxPtr rect, int x, int y) -{ - BoxRec box; - register BoxPtr boundBox; - int nbox; - Bool someIn, someOut; - register int t, x1, y1, x2, y2; - - nbox = RegionNumRects (bounding); - boundBox = RegionRects (bounding); - someIn = someOut = FALSE; - x1 = rect->x1; - y1 = rect->y1; - x2 = rect->x2; - y2 = rect->y2; - while (nbox--) - { - if ((t = boundBox->x1 + x) < x1) - t = x1; - box.x1 = t; - if ((t = boundBox->y1 + y) < y1) - t = y1; - box.y1 = t; - if ((t = boundBox->x2 + x) > x2) - t = x2; - box.x2 = t; - if ((t = boundBox->y2 + y) > y2) - t = y2; - box.y2 = t; - if (box.x1 > box.x2) - box.x2 = box.x1; - if (box.y1 > box.y2) - box.y2 = box.y1; - switch (RegionContainsRect(universe, &box)) - { - case rgnIN: - if (someOut) - return rgnPART; - someIn = TRUE; - break; - case rgnOUT: - if (someIn) - return rgnPART; - someOut = TRUE; - break; - default: - return rgnPART; - } - boundBox++; - } - if (someIn) - return rgnIN; - return rgnOUT; -} - -#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \ - HasBorder(w) && \ - (w)->backgroundState == ParentRelative) - - -/* - *----------------------------------------------------------------------- - * RootlessComputeClips -- - * Recompute the clipList, borderClip, exposed and borderExposed - * regions for pParent and its children. Only viewable windows are - * taken into account. - * - * Results: - * None. - * - * Side Effects: - * clipList, borderClip, exposed and borderExposed are altered. - * A VisibilityNotify event may be generated on the parent window. - * - *----------------------------------------------------------------------- - */ -static void -RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen, - RegionPtr universe, VTKind kind, RegionPtr exposed) -{ - int dx, - dy; - RegionRec childUniverse; - register WindowPtr pChild; - int oldVis, newVis; - BoxRec borderSize; - RegionRec childUnion; - Bool overlap; - RegionPtr borderVisible; - /* - * Figure out the new visibility of this window. - * The extent of the universe should be the same as the extent of - * the borderSize region. If the window is unobscured, this rectangle - * will be completely inside the universe (the universe will cover it - * completely). If the window is completely obscured, none of the - * universe will cover the rectangle. - */ - borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent); - borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent); - dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent); - if (dx > 32767) - dx = 32767; - borderSize.x2 = dx; - dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent); - if (dy > 32767) - dy = 32767; - borderSize.y2 = dy; - - oldVis = pParent->visibility; - switch (RegionContainsRect(universe, &borderSize)) - { - case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnPART: - newVis = VisibilityPartiallyObscured; - { - RegionPtr pBounding; - - if ((pBounding = wBoundingShape (pParent))) - { - switch (RootlessShapedWindowIn (universe, - pBounding, &borderSize, - pParent->drawable.x, - pParent->drawable.y)) - { - case rgnIN: - newVis = VisibilityUnobscured; - break; - case rgnOUT: - newVis = VisibilityFullyObscured; - break; - } - } - } - break; - default: - newVis = VisibilityFullyObscured; - break; - } - - pParent->visibility = newVis; - if (oldVis != newVis && - ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) - SendVisibilityNotify(pParent); - - dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x; - dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y; - - /* - * avoid computations when dealing with simple operations - */ - - switch (kind) { - case VTMap: - case VTStack: - case VTUnmap: - break; - case VTMove: - if ((oldVis == newVis) && - ((oldVis == VisibilityFullyObscured) || - (oldVis == VisibilityUnobscured))) - { - pChild = pParent; - while (1) - { - if (pChild->viewable) - { - if (pChild->visibility != VisibilityFullyObscured) - { - RegionTranslate(&pChild->borderClip, - dx, dy); - RegionTranslate(&pChild->clipList, - dx, dy); - pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER; - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pChild, dx, dy); - - } - if (pChild->valdata) - { - RegionNull(&pChild->valdata->after.borderExposed); - if (HasParentRelativeBorder(pChild)) - { - RegionSubtract(&pChild->valdata->after.borderExposed, - &pChild->borderClip, - &pChild->winSize); - } - RegionNull(&pChild->valdata->after.exposed); - } - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; - } - return; - } - /* fall through */ - default: - /* - * To calculate exposures correctly, we have to translate the old - * borderClip and clipList regions to the window's new location so there - * is a correspondence between pieces of the new and old clipping regions. - */ - if (dx || dy) - { - /* - * We translate the old clipList because that will be exposed or copied - * if gravity is right. - */ - RegionTranslate(&pParent->borderClip, dx, dy); - RegionTranslate(&pParent->clipList, dx, dy); - } - break; - case VTBroken: - RegionEmpty(&pParent->borderClip); - RegionEmpty(&pParent->clipList); - break; - } - - borderVisible = pParent->valdata->before.borderVisible; - RegionNull(&pParent->valdata->after.borderExposed); - RegionNull(&pParent->valdata->after.exposed); - - /* - * Since the borderClip must not be clipped by the children, we do - * the border exposure first... - * - * 'universe' is the window's borderClip. To figure the exposures, remove - * the area that used to be exposed from the new. - * This leaves a region of pieces that weren't exposed before. - */ - - if (HasBorder (pParent)) - { - if (borderVisible) - { - /* - * when the border changes shape, the old visible portions - * of the border will be saved by DIX in borderVisible -- - * use that region and destroy it - */ - RegionSubtract(exposed, universe, borderVisible); - RegionDestroy(borderVisible); - } - else - { - RegionSubtract(exposed, universe, &pParent->borderClip); - } - if (HasParentRelativeBorder(pParent) && (dx || dy)) { - RegionSubtract(&pParent->valdata->after.borderExposed, - universe, - &pParent->winSize); - } else { - RegionSubtract(&pParent->valdata->after.borderExposed, - exposed, &pParent->winSize); - } - - RegionCopy(&pParent->borderClip, universe); - - /* - * To get the right clipList for the parent, and to make doubly sure - * that no child overlaps the parent's border, we remove the parent's - * border from the universe before proceeding. - */ - - RegionIntersect(universe, universe, &pParent->winSize); - } - else - RegionCopy(&pParent->borderClip, universe); - - if ((pChild = pParent->firstChild) && pParent->mapped) - { - RegionNull(&childUniverse); - RegionNull(&childUnion); - if ((pChild->drawable.y < pParent->lastChild->drawable.y) || - ((pChild->drawable.y == pParent->lastChild->drawable.y) && - (pChild->drawable.x < pParent->lastChild->drawable.x))) - { - for (; pChild; pChild = pChild->nextSib) - { - if (pChild->viewable) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - else - { - for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib) - { - if (pChild->viewable) - RegionAppend(&childUnion, &pChild->borderSize); - } - } - RegionValidate(&childUnion, &overlap); - - for (pChild = pParent->firstChild; - pChild; - pChild = pChild->nextSib) - { - if (pChild->viewable) { - /* - * If the child is viewable, we want to remove its extents - * from the current universe, but we only re-clip it if - * it's been marked. - */ - if (pChild->valdata) { - /* - * Figure out the new universe from the child's - * perspective and recurse. - */ - RegionIntersect(&childUniverse, - universe, - &pChild->borderSize); - RootlessComputeClips (pChild, pScreen, &childUniverse, - kind, exposed); - } - /* - * Once the child has been processed, we remove its extents - * from the current universe, thus denying its space to any - * other sibling. - */ - if (overlap) - RegionSubtract(universe, universe, - &pChild->borderSize); - } - } - if (!overlap) - RegionSubtract(universe, universe, &childUnion); - RegionUninit(&childUnion); - RegionUninit(&childUniverse); - } /* if any children */ - - /* - * 'universe' now contains the new clipList for the parent window. - * - * To figure the exposure of the window we subtract the old clip from the - * new, just as for the border. - */ - - if (oldVis == VisibilityFullyObscured || - oldVis == VisibilityNotViewable) - { - RegionCopy(&pParent->valdata->after.exposed, universe); - } - else if (newVis != VisibilityFullyObscured && - newVis != VisibilityNotViewable) - { - RegionSubtract(&pParent->valdata->after.exposed, - universe, &pParent->clipList); - } - - /* HACK ALERT - copying contents of regions, instead of regions */ - { - RegionRec tmp; - - tmp = pParent->clipList; - pParent->clipList = *universe; - *universe = tmp; - } - -#ifdef NOTDEF - RegionCopy(&pParent->clipList, universe); -#endif - - pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER; - - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pParent, dx, dy); -} - -static void -RootlessTreeObscured(WindowPtr pParent) -{ - register WindowPtr pChild; - register int oldVis; - - pChild = pParent; - while (1) - { - if (pChild->viewable) - { - oldVis = pChild->visibility; - if (oldVis != (pChild->visibility = VisibilityFullyObscured) && - ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask)) - SendVisibilityNotify(pChild); - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - } - while (!pChild->nextSib && (pChild != pParent)) - pChild = pChild->parent; - if (pChild == pParent) - break; - pChild = pChild->nextSib; - } -} - -/* - *----------------------------------------------------------------------- - * RootlessMiValidateTree -- - * Recomputes the clip list for pParent and all its inferiors. - * - * Results: - * Always returns 1. - * - * Side Effects: - * The clipList, borderClip, exposed, and borderExposed regions for - * each marked window are altered. - * - * Notes: - * This routine assumes that all affected windows have been marked - * (valdata created) and their winSize and borderSize regions - * adjusted to correspond to their new positions. The borderClip and - * clipList regions should not have been touched. - * - * The top-most level is treated differently from all lower levels - * because pParent is unchanged. For the top level, we merge the - * regions taken up by the marked children back into the clipList - * for pParent, thus forming a region from which the marked children - * can claim their areas. For lower levels, where the old clipList - * and borderClip are invalid, we can't do this and have to do the - * extra operations done in miComputeClips, but this is much faster - * e.g. when only one child has moved... - * - *----------------------------------------------------------------------- - */ -/* - Quartz version: used for validate from root in rootless mode. - We need to make sure top-level windows don't clip each other, - and that top-level windows aren't clipped to the root window. -*/ -/*ARGSUSED*/ -// fixme this is ugly -// Xprint/ValTree.c doesn't work, but maybe that method can? -int -RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */ - WindowPtr pChild, /* First child of pRoot that was - * affected */ - VTKind kind /* What kind of configuration caused call */) -{ - RegionRec childClip; /* The new borderClip for the current - * child */ - RegionRec exposed; /* For intermediate calculations */ - register ScreenPtr pScreen; - register WindowPtr pWin; - - pScreen = pRoot->drawable.pScreen; - if (pChild == NullWindow) - pChild = pRoot->firstChild; - - RegionNull(&childClip); - RegionNull(&exposed); - - if (RegionBroken(&pRoot->clipList) && - !RegionBroken(&pRoot->borderClip)) - { - // fixme this might not work, but hopefully doesn't happen anyway. - kind = VTBroken; - RegionEmpty(&pRoot->clipList); - ErrorF("ValidateTree: BUSTED!\n"); - } - - /* - * Recursively compute the clips for all children of the root. - * They don't clip against each other or the root itself, so - * childClip is always reset to that child's size. - */ - - for (pWin = pChild; - pWin != NullWindow; - pWin = pWin->nextSib) - { - if (pWin->viewable) { - if (pWin->valdata) { - RegionCopy(&childClip, &pWin->borderSize); - RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed); - } else if (pWin->visibility == VisibilityNotViewable) { - RootlessTreeObscured(pWin); - } - } else { - if (pWin->valdata) { - RegionEmpty(&pWin->clipList); - if (pScreen->ClipNotify) - (* pScreen->ClipNotify) (pWin, 0, 0); - RegionEmpty(&pWin->borderClip); - pWin->valdata = NULL; - } - } - } - - RegionUninit(&childClip); - - /* The root is never clipped by its children, so nothing on the root - is ever exposed by moving or mapping its children. */ - RegionNull(&pRoot->valdata->after.exposed); - RegionNull(&pRoot->valdata->after.borderExposed); - - return 1; -} +/*
+ * Calculate window clip lists for rootless mode
+ *
+ * This file is very closely based on mivaltree.c.
+ */
+
+/*
+ * mivaltree.c --
+ * Functions for recalculating window clip lists. Main function
+ * is miValidateTree.
+ *
+
+Copyright 1987, 1988, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, Massachusetts,
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ ******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+ /*
+ * Aug '86: Susan Angebranndt -- original code
+ * July '87: Adam de Boor -- substantially modified and commented
+ * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
+ * In particular, much improved code for window mapping and
+ * circulating.
+ * Bob Scheifler -- avoid miComputeClips for unmapped windows,
+ * valdata changes
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stddef.h> /* For NULL */
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+
+#include "globals.h"
+
+int RootlessMiValidateTree (WindowPtr pRoot, WindowPtr pChild, VTKind kind);
+
+/*
+ * Compute the visibility of a shaped window
+ */
+static int
+RootlessShapedWindowIn (RegionPtr universe,
+ RegionPtr bounding, BoxPtr rect, int x, int y)
+{
+ BoxRec box;
+ register BoxPtr boundBox;
+ int nbox;
+ Bool someIn, someOut;
+ register int t, x1, y1, x2, y2;
+
+ nbox = RegionNumRects (bounding);
+ boundBox = RegionRects (bounding);
+ someIn = someOut = FALSE;
+ x1 = rect->x1;
+ y1 = rect->y1;
+ x2 = rect->x2;
+ y2 = rect->y2;
+ while (nbox--)
+ {
+ if ((t = boundBox->x1 + x) < x1)
+ t = x1;
+ box.x1 = t;
+ if ((t = boundBox->y1 + y) < y1)
+ t = y1;
+ box.y1 = t;
+ if ((t = boundBox->x2 + x) > x2)
+ t = x2;
+ box.x2 = t;
+ if ((t = boundBox->y2 + y) > y2)
+ t = y2;
+ box.y2 = t;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ switch (RegionContainsRect(universe, &box))
+ {
+ case rgnIN:
+ if (someOut)
+ return rgnPART;
+ someIn = TRUE;
+ break;
+ case rgnOUT:
+ if (someIn)
+ return rgnPART;
+ someOut = TRUE;
+ break;
+ default:
+ return rgnPART;
+ }
+ boundBox++;
+ }
+ if (someIn)
+ return rgnIN;
+ return rgnOUT;
+}
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+ HasBorder(w) && \
+ (w)->backgroundState == ParentRelative)
+
+
+/*
+ *-----------------------------------------------------------------------
+ * RootlessComputeClips --
+ * Recompute the clipList, borderClip, exposed and borderExposed
+ * regions for pParent and its children. Only viewable windows are
+ * taken into account.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * clipList, borderClip, exposed and borderExposed are altered.
+ * A VisibilityNotify event may be generated on the parent window.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+RootlessComputeClips (WindowPtr pParent, ScreenPtr pScreen,
+ RegionPtr universe, VTKind kind, RegionPtr exposed)
+{
+ int dx,
+ dy;
+ RegionRec childUniverse;
+ register WindowPtr pChild;
+ int oldVis, newVis;
+ BoxRec borderSize;
+ RegionRec childUnion;
+ Bool overlap;
+ RegionPtr borderVisible;
+ /*
+ * Figure out the new visibility of this window.
+ * The extent of the universe should be the same as the extent of
+ * the borderSize region. If the window is unobscured, this rectangle
+ * will be completely inside the universe (the universe will cover it
+ * completely). If the window is completely obscured, none of the
+ * universe will cover the rectangle.
+ */
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
+ if (dx > 32767)
+ dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
+ if (dy > 32767)
+ dy = 32767;
+ borderSize.y2 = dy;
+
+ oldVis = pParent->visibility;
+ switch (RegionContainsRect(universe, &borderSize))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (RootlessShapedWindowIn (universe,
+ pBounding, &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+
+ pParent->visibility = newVis;
+ if (oldVis != newVis &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+ SendVisibilityNotify(pParent);
+
+ dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+ dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+ /*
+ * avoid computations when dealing with simple operations
+ */
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (pChild->visibility != VisibilityFullyObscured)
+ {
+ RegionTranslate(&pChild->borderClip,
+ dx, dy);
+ RegionTranslate(&pChild->clipList,
+ dx, dy);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pChild, dx, dy);
+
+ }
+ if (pChild->valdata)
+ {
+ RegionNull(&pChild->valdata->after.borderExposed);
+ if (HasParentRelativeBorder(pChild))
+ {
+ RegionSubtract(&pChild->valdata->after.borderExposed,
+ &pChild->borderClip,
+ &pChild->winSize);
+ }
+ RegionNull(&pChild->valdata->after.exposed);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ /*
+ * To calculate exposures correctly, we have to translate the old
+ * borderClip and clipList regions to the window's new location so there
+ * is a correspondence between pieces of the new and old clipping regions.
+ */
+ if (dx || dy)
+ {
+ /*
+ * We translate the old clipList because that will be exposed or copied
+ * if gravity is right.
+ */
+ RegionTranslate(&pParent->borderClip, dx, dy);
+ RegionTranslate(&pParent->clipList, dx, dy);
+ }
+ break;
+ case VTBroken:
+ RegionEmpty(&pParent->borderClip);
+ RegionEmpty(&pParent->clipList);
+ break;
+ }
+
+ borderVisible = pParent->valdata->before.borderVisible;
+ RegionNull(&pParent->valdata->after.borderExposed);
+ RegionNull(&pParent->valdata->after.exposed);
+
+ /*
+ * Since the borderClip must not be clipped by the children, we do
+ * the border exposure first...
+ *
+ * 'universe' is the window's borderClip. To figure the exposures, remove
+ * the area that used to be exposed from the new.
+ * This leaves a region of pieces that weren't exposed before.
+ */
+
+ if (HasBorder (pParent))
+ {
+ if (borderVisible)
+ {
+ /*
+ * when the border changes shape, the old visible portions
+ * of the border will be saved by DIX in borderVisible --
+ * use that region and destroy it
+ */
+ RegionSubtract(exposed, universe, borderVisible);
+ RegionDestroy(borderVisible);
+ }
+ else
+ {
+ RegionSubtract(exposed, universe, &pParent->borderClip);
+ }
+ if (HasParentRelativeBorder(pParent) && (dx || dy)) {
+ RegionSubtract(&pParent->valdata->after.borderExposed,
+ universe,
+ &pParent->winSize);
+ } else {
+ RegionSubtract(&pParent->valdata->after.borderExposed,
+ exposed, &pParent->winSize);
+ }
+
+ RegionCopy(&pParent->borderClip, universe);
+
+ /*
+ * To get the right clipList for the parent, and to make doubly sure
+ * that no child overlaps the parent's border, we remove the parent's
+ * border from the universe before proceeding.
+ */
+
+ RegionIntersect(universe, universe, &pParent->winSize);
+ }
+ else
+ RegionCopy(&pParent->borderClip, universe);
+
+ if ((pChild = pParent->firstChild) && pParent->mapped)
+ {
+ RegionNull(&childUniverse);
+ RegionNull(&childUnion);
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ RegionAppend(&childUnion, &pChild->borderSize);
+ }
+ }
+ else
+ {
+ for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ if (pChild->viewable)
+ RegionAppend(&childUnion, &pChild->borderSize);
+ }
+ }
+ RegionValidate(&childUnion, &overlap);
+
+ for (pChild = pParent->firstChild;
+ pChild;
+ pChild = pChild->nextSib)
+ {
+ if (pChild->viewable) {
+ /*
+ * If the child is viewable, we want to remove its extents
+ * from the current universe, but we only re-clip it if
+ * it's been marked.
+ */
+ if (pChild->valdata) {
+ /*
+ * Figure out the new universe from the child's
+ * perspective and recurse.
+ */
+ RegionIntersect(&childUniverse,
+ universe,
+ &pChild->borderSize);
+ RootlessComputeClips (pChild, pScreen, &childUniverse,
+ kind, exposed);
+ }
+ /*
+ * Once the child has been processed, we remove its extents
+ * from the current universe, thus denying its space to any
+ * other sibling.
+ */
+ if (overlap)
+ RegionSubtract(universe, universe,
+ &pChild->borderSize);
+ }
+ }
+ if (!overlap)
+ RegionSubtract(universe, universe, &childUnion);
+ RegionUninit(&childUnion);
+ RegionUninit(&childUniverse);
+ } /* if any children */
+
+ /*
+ * 'universe' now contains the new clipList for the parent window.
+ *
+ * To figure the exposure of the window we subtract the old clip from the
+ * new, just as for the border.
+ */
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ RegionCopy(&pParent->valdata->after.exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ RegionSubtract(&pParent->valdata->after.exposed,
+ universe, &pParent->clipList);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = pParent->clipList;
+ pParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+#ifdef NOTDEF
+ RegionCopy(&pParent->clipList, universe);
+#endif
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+static void
+RootlessTreeObscured(WindowPtr pParent)
+{
+ register WindowPtr pChild;
+ register int oldVis;
+
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ oldVis = pChild->visibility;
+ if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
+ ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
+ SendVisibilityNotify(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * RootlessMiValidateTree --
+ * Recomputes the clip list for pParent and all its inferiors.
+ *
+ * Results:
+ * Always returns 1.
+ *
+ * Side Effects:
+ * The clipList, borderClip, exposed, and borderExposed regions for
+ * each marked window are altered.
+ *
+ * Notes:
+ * This routine assumes that all affected windows have been marked
+ * (valdata created) and their winSize and borderSize regions
+ * adjusted to correspond to their new positions. The borderClip and
+ * clipList regions should not have been touched.
+ *
+ * The top-most level is treated differently from all lower levels
+ * because pParent is unchanged. For the top level, we merge the
+ * regions taken up by the marked children back into the clipList
+ * for pParent, thus forming a region from which the marked children
+ * can claim their areas. For lower levels, where the old clipList
+ * and borderClip are invalid, we can't do this and have to do the
+ * extra operations done in miComputeClips, but this is much faster
+ * e.g. when only one child has moved...
+ *
+ *-----------------------------------------------------------------------
+ */
+/*
+ Quartz version: used for validate from root in rootless mode.
+ We need to make sure top-level windows don't clip each other,
+ and that top-level windows aren't clipped to the root window.
+*/
+/*ARGSUSED*/
+// fixme this is ugly
+// Xprint/ValTree.c doesn't work, but maybe that method can?
+int
+RootlessMiValidateTree (WindowPtr pRoot, /* Parent to validate */
+ WindowPtr pChild, /* First child of pRoot that was
+ * affected */
+ VTKind kind /* What kind of configuration caused call */)
+{
+ RegionRec childClip; /* The new borderClip for the current
+ * child */
+ RegionRec exposed; /* For intermediate calculations */
+ register ScreenPtr pScreen;
+ register WindowPtr pWin;
+
+ pScreen = pRoot->drawable.pScreen;
+ if (pChild == NullWindow)
+ pChild = pRoot->firstChild;
+
+ RegionNull(&childClip);
+ RegionNull(&exposed);
+
+ if (RegionBroken(&pRoot->clipList) &&
+ !RegionBroken(&pRoot->borderClip))
+ {
+ // fixme this might not work, but hopefully doesn't happen anyway.
+ kind = VTBroken;
+ RegionEmpty(&pRoot->clipList);
+ ErrorF("ValidateTree: BUSTED!\n");
+ }
+
+ /*
+ * Recursively compute the clips for all children of the root.
+ * They don't clip against each other or the root itself, so
+ * childClip is always reset to that child's size.
+ */
+
+ for (pWin = pChild;
+ pWin != NullWindow;
+ pWin = pWin->nextSib)
+ {
+ if (pWin->viewable) {
+ if (pWin->valdata) {
+ RegionCopy(&childClip, &pWin->borderSize);
+ RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+ } else if (pWin->visibility == VisibilityNotViewable) {
+ RootlessTreeObscured(pWin);
+ }
+ } else {
+ if (pWin->valdata) {
+ RegionEmpty(&pWin->clipList);
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pWin, 0, 0);
+ RegionEmpty(&pWin->borderClip);
+ pWin->valdata = NULL;
+ }
+ }
+ }
+
+ RegionUninit(&childClip);
+
+ /* The root is never clipped by its children, so nothing on the root
+ is ever exposed by moving or mapping its children. */
+ RegionNull(&pRoot->valdata->after.exposed);
+ RegionNull(&pRoot->valdata->after.borderExposed);
+
+ return 1;
+}
diff --git a/xorg-server/miext/rootless/rootlessWindow.c b/xorg-server/miext/rootless/rootlessWindow.c index 20fdaba8d..4c7f7b044 100644 --- a/xorg-server/miext/rootless/rootlessWindow.c +++ b/xorg-server/miext/rootless/rootlessWindow.c @@ -51,6 +51,12 @@ extern Bool no_configure_window; #include "rootlessCommon.h"
#include "rootlessWindow.h"
+#ifdef _MSC_VER
+#define inline __inline
+#include "xplugin.h"
+extern int darwinMainScreenX, darwinMainScreenY;
+#endif
+
#define SCREEN_TO_GLOBAL_X \
(pScreen->x + rootlessGlobalOffsetX)
#define SCREEN_TO_GLOBAL_Y \
@@ -683,7 +689,7 @@ RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, if (gResizeDeathCount == 1) {
/* Simple case, we only have a single source pixmap. */
- fbCopyRegion(&gResizeDeathPix[0]->drawable,
+ miCopyRegion(&gResizeDeathPix[0]->drawable,
&pScreen->GetWindowPixmap(pWin)->drawable, 0,
&rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
}
@@ -699,7 +705,7 @@ RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionNull(&clipped);
RegionIntersect(&rgnDst, &clip, &clipped);
- fbCopyRegion(&gResizeDeathPix[i]->drawable,
+ miCopyRegion(&gResizeDeathPix[i]->drawable,
&pScreen->GetWindowPixmap(pWin)->drawable, 0,
&clipped, dx, dy, fbCopyWindowProc, 0, 0);
@@ -780,7 +786,7 @@ RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) else {
RootlessStartDrawing(pWin);
- fbCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin,
+ miCopyRegion((DrawablePtr) pWin, (DrawablePtr) pWin,
0, &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
/* prgnSrc has been translated to dst position */
@@ -996,6 +1002,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity, }
else if (gravity) {
/* The general case. Just copy everything. */
+ BoxRec tmpBoxRec={oldX, oldY, oldX2, oldY2};
RootlessStartDrawing(pWin);
@@ -1004,7 +1011,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity, memcpy(gResizeDeathBits, winRec->pixelData,
winRec->bytesPerRow * winRec->height);
- gResizeDeathBounds[0] = (BoxRec) {oldX, oldY, oldX2, oldY2};
+ gResizeDeathBounds[0] = tmpBoxRec;
gResizeDeathPix[0]
= GetScratchPixmapHeader(pScreen, winRec->width,
winRec->height,
@@ -1041,7 +1048,8 @@ StartFrameResize(WindowPtr pWin, Bool gravity, window bits. */
if (need_window_source) {
- gResizeDeathBounds[0] = (BoxRec) {oldX, oldY, oldX2, oldY2};
+ BoxRec tmpBoxRec={oldX, oldY, oldX2, oldY2};
+ gResizeDeathBounds[0] = tmpBoxRec;
gResizeDeathPix[0]
= GetScratchPixmapHeader(pScreen, oldW, oldH,
winRec->win->drawable.depth,
diff --git a/xorg-server/miext/rootless/xplugin.h b/xorg-server/miext/rootless/xplugin.h new file mode 100644 index 000000000..7fdf6006e --- /dev/null +++ b/xorg-server/miext/rootless/xplugin.h @@ -0,0 +1,592 @@ +/* Xplugin.h -- windowing API for rootless X11 server + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. + + Note that these interfaces are provided solely for the use of the + X11 server. Any other uses are unsupported and strongly discouraged. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/Xplugin.h,v 1.2 2003/05/02 00:08:49 torrey Exp $ */ + +#ifndef XPLUGIN_H +#define XPLUGIN_H 1 + +#include <stdint.h> + +/* By default we use the X server definition of BoxRec to define xp_box, + so that the compiler can silently convert between the two. But if + XP_NO_X_HEADERS is defined, we'll define it ourselves. */ + +#ifndef XP_NO_X_HEADERS +# include "miscstruct.h" + typedef BoxRec xp_box; +#else + struct xp_box_struct { + short x1, y1, x2, y2; + }; + typedef struct xp_box_struct xp_box; +#endif + +typedef unsigned int xp_resource_id; +typedef xp_resource_id xp_window_id; +typedef xp_resource_id xp_surface_id; +typedef unsigned int xp_client_id; +typedef unsigned int xp_request_type; +typedef int xp_error; +typedef int xp_bool; + + +/* Error codes that the functions declared here may return. They all + numerically match their X equivalents, i.e. the XP_ can be dropped + if <X11/X.h> has been included. */ + +enum xp_error_enum { + XP_Success = 0, + XP_BadRequest = 1, + XP_BadValue = 2, + XP_BadWindow = 3, + XP_BadMatch = 8, + XP_BadAccess = 10, + XP_BadImplementation = 17, +}; + + +/* Event types generated by the plugin. */ + +enum xp_event_type_enum { + /* The global display configuration changed somehow. */ + XP_EVENT_DISPLAY_CHANGED = 1 << 0, + + /* A window changed state. Argument is xp_window_state_event */ + XP_EVENT_WINDOW_STATE_CHANGED = 1 << 1, + + /* An async request encountered an error. Argument is of type + xp_async_error_event */ + XP_EVENT_ASYNC_ERROR = 1 << 2, + + /* Sent when a surface is destroyed as a side effect of destroying + a window. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_DESTROYED = 1 << 3, + + /* Sent when any GL contexts pointing at the given surface need to + call xp_update_gl_context () to refresh their state (because the + window moved or was resized. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_CHANGED = 1 << 4, + + /* Sent when a window has been moved. Arg is of type xp_window_id. */ + XP_EVENT_WINDOW_MOVED = 1 << 5, +}; + +/* Function type used to receive events. */ + +typedef void (xp_event_fun) (unsigned int type, const void *arg, + unsigned int arg_size, void *user_data); + + +/* Operation types. Used when reporting errors asynchronously. */ + +enum xp_request_type_enum { + XP_REQUEST_NIL = 0, + XP_REQUEST_DESTROY_WINDOW = 1, + XP_REQUEST_CONFIGURE_WINDOW = 2, + XP_REQUEST_FLUSH_WINDOW = 3, + XP_REQUEST_COPY_WINDOW = 4, + XP_REQUEST_UNLOCK_WINDOW = 5, + XP_REQUEST_DISABLE_UPDATE = 6, + XP_REQUEST_REENABLE_UPDATE = 7, + XP_REQUEST_HIDE_CURSOR = 8, + XP_REQUEST_SHOW_CURSOR = 9, + XP_REQUEST_FRAME_DRAW = 10, +}; + +/* Structure used to report an error asynchronously. Passed as the "arg" + of an XP_EVENT_ASYNC_ERROR event. */ + +struct xp_async_error_event_struct { + xp_request_type request_type; + xp_resource_id id; + xp_error error; +}; + +typedef struct xp_async_error_event_struct xp_async_error_event; + + +/* Possible window states. */ + +enum xp_window_state_enum { + /* The window is not in the global list of possibly-visible windows. */ + XP_WINDOW_STATE_OFFSCREEN = 1 << 0, + + /* Parts of the window may be obscured by other windows. */ + XP_WINDOW_STATE_OBSCURED = 1 << 1, +}; + +/* Structure passed as argument of an XP_EVENT_WINDOW_STATE_CHANGED event. */ + +struct xp_window_state_event_struct { + xp_window_id id; + unsigned int state; +}; + +typedef struct xp_window_state_event_struct xp_window_state_event; + + +/* Function type used to supply a colormap for indexed drawables. */ + +typedef xp_error (xp_colormap_fun) (void *data, int first_color, + int n_colors, uint32_t *colors); + + +/* Window attributes structure. Used when creating and configuring windows. + Also used when configuring surfaces attached to windows. Functions that + take one of these structures also take a bit mask defining which + fields are set to meaningful values. */ + +enum xp_window_changes_enum { + XP_ORIGIN = 1 << 0, + XP_SIZE = 1 << 1, + XP_BOUNDS = XP_ORIGIN | XP_SIZE, + XP_SHAPE = 1 << 2, + XP_STACKING = 1 << 3, + XP_DEPTH = 1 << 4, + XP_COLORMAP = 1 << 5, + XP_WINDOW_LEVEL = 1 << 6, +}; + +struct xp_window_changes_struct { + /* XP_ORIGIN */ + int x, y; + + /* XP_SIZE */ + unsigned int width, height; + int bit_gravity; /* how to resize the backing store */ + + /* XP_SHAPE */ + int shape_nrects; /* -1 = remove shape */ + xp_box *shape_rects; + int shape_tx, shape_ty; /* translation for shape */ + + /* XP_STACKING */ + int stack_mode; + xp_window_id sibling; /* may be zero; in ABOVE/BELOW modes + it may specify a relative window */ + /* XP_DEPTH, window-only */ + unsigned int depth; + + /* XP_COLORMAP, window-only */ + xp_colormap_fun *colormap; + void *colormap_data; + + /* XP_WINDOW_LEVEL, window-only */ + int window_level; +}; + +typedef struct xp_window_changes_struct xp_window_changes; + +/* Values for bit_gravity field */ + +enum xp_bit_gravity_enum { + XP_GRAVITY_NONE = 0, /* no gravity, fill everything */ + XP_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */ + XP_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */ + XP_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */ + XP_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */ +}; + +/* Values for stack_mode field */ + +enum xp_window_stack_mode_enum { + XP_UNMAPPED = 0, /* remove the window */ + XP_MAPPED_ABOVE = 1, /* display the window on top */ + XP_MAPPED_BELOW = 2, /* display the window at bottom */ +}; + +/* Data formats for depth field and composite functions */ + +enum xp_depth_enum { + XP_DEPTH_NIL = 0, /* null source when compositing */ + XP_DEPTH_ARGB8888, + XP_DEPTH_RGB555, + XP_DEPTH_A8, /* for masks when compositing */ + XP_DEPTH_INDEX8, +}; + +/* Options that may be passed to the xp_init () function. */ + +enum xp_init_options_enum { + /* Don't mark that this process can be in the foreground. */ + XP_IN_BACKGROUND = 1 << 0, + + /* Deliver background pointer events to this process. */ + XP_BACKGROUND_EVENTS = 1 << 1, +}; + + + +/* Miscellaneous functions */ + +/* Initialize the plugin library. Only the copy/fill/composite functions + may be called without having previously called xp_init () */ + +extern xp_error xp_init (unsigned int options); + +/* Sets the current set of requested notifications to MASK. When any of + these arrive, CALLBACK will be invoked with CALLBACK-DATA. Note that + calling this function cancels any previously requested notifications + that aren't set in MASK. */ + +extern xp_error xp_select_events (unsigned int mask, + xp_event_fun *callback, + void *callback_data); + +/* Waits for all initiated operations to complete. */ + +extern xp_error xp_synchronize (void); + +/* Causes any display update initiated through the plugin libary to be + queued until update is reenabled. Note that calls to these functions + nest. */ + +extern xp_error xp_disable_update (void); +extern xp_error xp_reenable_update (void); + + + +/* Cursor functions. */ + +/* Installs the specified cursor. ARGB-DATA should point to 32-bit + premultiplied big-endian ARGB data. The HOT-X,HOT-Y parameters + specify the offset to the cursor's hot spot from its top-left + corner. */ + +extern xp_error xp_set_cursor (unsigned int width, unsigned int height, + unsigned int hot_x, unsigned int hot_y, + const uint32_t *argb_data, + unsigned int rowbytes); + +/* Hide and show the cursor if it's owned by the current process. Calls + to these functions nest. */ + +extern xp_error xp_hide_cursor (void); +extern xp_error xp_show_cursor (void); + + + +/* Window functions. */ + +/* Create a new window as defined by MASK and VALUES. MASK must contain + XP_BOUNDS or an error is raised. The id of the newly created window + is stored in *RET-ID if this function returns XP_Success. */ + +extern xp_error xp_create_window (unsigned int mask, + const xp_window_changes *values, + xp_window_id *ret_id); + +/* Destroys the window identified by ID. */ + +extern xp_error xp_destroy_window (xp_window_id id); + +/* Reconfigures the given window according to MASK and VALUES. */ + +extern xp_error xp_configure_window (xp_window_id id, unsigned int mask, + const xp_window_changes *values); + + +/* Returns true if NATIVE-ID is a window created by the plugin library. + If so and RET-ID is non-null, stores the id of the window in *RET-ID. */ + +extern xp_bool xp_lookup_native_window (unsigned int native_id, + xp_window_id *ret_id); + +/* If ID names a window created by the plugin library, stores it's native + window id in *RET-NATIVE-ID. */ + +extern xp_error xp_get_native_window (xp_window_id id, + unsigned int *ret_native_id); + + +/* Locks the rectangle IN-RECT (or, if null, the entire window) of the + given window's backing store. Any other non-null parameters are filled + in as follows: + + DEPTH = format of returned data. Currently either XP_DEPTH_ARGB8888 + or XP_DEPTH_RGB565 (possibly with 8 bit planar alpha). Data is + always stored in native byte order. + + BITS[0] = pointer to top-left pixel of locked color data + BITS[1] = pointer to top-left of locked alpha data, or null if window + has no alpha. If the alpha data is meshed, then BITS[1] = BITS[0]. + + ROWBYTES[0,1] = size in bytes of each row of color,alpha data + + OUT-RECT = rectangle specifying the current position and size of the + locked region relative to the window origin. + + Note that an error is raised when trying to lock an already locked + window. While the window is locked, the only operations that may + be performed on it are to modify, access or flush its marked region. */ + +extern xp_error xp_lock_window (xp_window_id id, + const xp_box *in_rect, + unsigned int *depth, + void *bits[2], + unsigned int rowbytes[2], + xp_box *out_rect); + +/* Mark that the region specified by SHAPE-NRECTS, SHAPE-RECTS, + SHAPE-TX, and SHAPE-TY in the specified window has been updated, and + will need to subsequently be redisplayed. */ + +extern xp_error xp_mark_window (xp_window_id id, int shape_nrects, + const xp_box *shape_rects, + int shape_tx, int shape_ty); + +/* Unlocks the specified window. If FLUSH is true, then any marked + regions are immediately redisplayed. Note that it's an error to + unlock an already unlocked window. */ + +extern xp_error xp_unlock_window (xp_window_id id, xp_bool flush); + +/* If anything is marked in the given window for redisplay, do it now. */ + +extern xp_error xp_flush_window (xp_window_id id); + +/* Moves the contents of the region DX,DY pixels away from that specified + by DST_RECTS and DST_NRECTS in the window with SRC-ID to the + destination region in the window DST-ID. Note that currently source + and destination windows must be the same. */ + +extern xp_error xp_copy_window (xp_window_id src_id, xp_window_id dst_id, + int dst_nrects, const xp_box *dst_rects, + int dx, int dy); + +/* Returns true if the given window has any regions marked for + redisplay. */ + +extern xp_bool xp_is_window_marked (xp_window_id id); + +/* If successful returns a superset of the region marked for update in + the given window. Use xp_free_region () to release the returned data. */ + +extern xp_error xp_get_marked_shape (xp_window_id id, + int *ret_nrects, xp_box **ret_rects); + +extern void xp_free_shape (int nrects, xp_box *rects); + +/* Searches for the first window below ABOVE-ID containing the point X,Y, + and returns it's window id in *RET-ID. If no window is found, *RET-ID + is set to zero. If ABOVE-ID is zero, finds the topmost window + containing the given point. */ + +extern xp_error xp_find_window (int x, int y, xp_window_id above_id, + xp_window_id *ret_id); + +/* Returns the current origin and size of the window ID in *BOUNDS-RET if + successful. */ +extern xp_error xp_get_window_bounds (xp_window_id id, xp_box *bounds_ret); + + + +/* Window surface functions. */ + +/* Create a new VRAM surface on the specified window. If successful, + returns the identifier of the new surface in *RET-SID. */ + +extern xp_error xp_create_surface (xp_window_id id, xp_surface_id *ret_sid); + +/* Destroys the specified surface. */ + +extern xp_error xp_destroy_surface (xp_surface_id sid); + +/* Reconfigures the specified surface as defined by MASK and VALUES. + Note that specifying XP_DEPTH is an error. */ + +extern xp_error xp_configure_surface (xp_surface_id sid, unsigned int mask, + const xp_window_changes *values); + +/* If successful, places the client identifier of the current process + in *RET-CLIENT. */ + +extern xp_error xp_get_client_id (xp_client_id *ret_client); + +/* Given a valid window,surface combination created by the current + process, attempts to allow the specified external client access + to that surface. If successful, returns two integers in RET-KEY + which the client can use to import the surface into their process. */ + +extern xp_error xp_export_surface (xp_window_id wid, xp_surface_id sid, + xp_client_id client, + unsigned int ret_key[2]); + +/* Given a two integer key returned from xp_export_surface (), tries + to import the surface into the current process. If successful the + local surface identifier is stored in *SID-RET. */ + +extern xp_error xp_import_surface (const unsigned int key[2], + xp_surface_id *sid_ret); + +/* If successful, stores the number of surfaces attached to the + specified window in *RET. */ + +extern xp_error xp_get_window_surface_count (xp_window_id id, + unsigned int *ret); + +/* Attaches the CGLContextObj CGL-CTX to the specified surface. */ + +extern xp_error xp_attach_gl_context (void *cgl_ctx, xp_surface_id sid); + +/* Updates the CGLContextObj CGL-CTX to reflect any recent changes to + the surface it's attached to. */ + +extern xp_error xp_update_gl_context (void *cgl_ctx); + + + +/* Window frame functions. */ + +/* Possible arguments to xp_frame_get_rect (). */ + +enum xp_frame_rect_enum { + XP_FRAME_RECT_TITLEBAR = 1, + XP_FRAME_RECT_TRACKING = 2, + XP_FRAME_RECT_GROWBOX = 3, +}; + +/* Classes of window frame. */ + +enum xp_frame_class_enum { + XP_FRAME_CLASS_DOCUMENT = 1 << 0, + XP_FRAME_CLASS_DIALOG = 1 << 1, + XP_FRAME_CLASS_MODAL_DIALOG = 1 << 2, + XP_FRAME_CLASS_SYSTEM_MODAL_DIALOG = 1 << 3, + XP_FRAME_CLASS_UTILITY = 1 << 4, + XP_FRAME_CLASS_TOOLBAR = 1 << 5, + XP_FRAME_CLASS_MENU = 1 << 6, + XP_FRAME_CLASS_SPLASH = 1 << 7, + XP_FRAME_CLASS_BORDERLESS = 1 << 8, +}; + +/* Attributes of window frames. */ + +enum xp_frame_attr_enum { + XP_FRAME_ACTIVE = 0x0001, + XP_FRAME_URGENT = 0x0002, + XP_FRAME_TITLE = 0x0004, + XP_FRAME_PRELIGHT = 0x0008, + XP_FRAME_SHADED = 0x0010, + XP_FRAME_CLOSE_BOX = 0x0100, + XP_FRAME_COLLAPSE = 0x0200, + XP_FRAME_ZOOM = 0x0400, + XP_FRAME_ANY_BUTTON = 0x0700, + XP_FRAME_CLOSE_BOX_CLICKED = 0x0800, + XP_FRAME_COLLAPSE_BOX_CLICKED = 0x1000, + XP_FRAME_ZOOM_BOX_CLICKED = 0x2000, + XP_FRAME_ANY_CLICKED = 0x3800, + XP_FRAME_GROW_BOX = 0x4000, +}; + +#define XP_FRAME_ATTR_IS_SET(a,b) (((a) & (b)) == (b)) +#define XP_FRAME_ATTR_IS_CLICKED(a,m) ((a) & ((m) << 3)) +#define XP_FRAME_ATTR_SET_CLICKED(a,m) ((a) |= ((m) << 3)) +#define XP_FRAME_ATTR_UNSET_CLICKED(a,m) ((a) &= ~((m) << 3)) + +#define XP_FRAME_POINTER_ATTRS (XP_FRAME_PRELIGHT \ + | XP_FRAME_ANY_BUTTON \ + | XP_FRAME_ANY_CLICKED) + +extern xp_error xp_frame_get_rect (int type, int class, const xp_box *outer, + const xp_box *inner, xp_box *ret); +extern xp_error xp_frame_hit_test (int class, int x, int y, + const xp_box *outer, + const xp_box *inner, int *ret); +extern xp_error xp_frame_draw (xp_window_id wid, int class, unsigned int attr, + const xp_box *outer, const xp_box *inner, + unsigned int title_len, + const unsigned char *title_bytes); + + + +/* Memory manipulation functions. */ + +enum xp_composite_op_enum { + XP_COMPOSITE_SRC = 0, + XP_COMPOSITE_OVER, +}; + +#define XP_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \ + (((op) << 24) | ((src_depth) << 16) \ + | ((mask_depth) << 8) | ((dest_depth) << 0)) + +#define XP_COMPOSITE_FUNCTION_OP(f) (((f) >> 24) & 255) +#define XP_COMPOSITE_FUNCTION_SRC_DEPTH(f) (((f) >> 16) & 255) +#define XP_COMPOSITE_FUNCTION_MASK_DEPTH(f) (((f) >> 8) & 255) +#define XP_COMPOSITE_FUNCTION_DEST_DEPTH(f) (((f) >> 0) & 255) + +/* Composite WIDTH by HEIGHT pixels from source and mask to destination + using a specified function (if source and destination overlap, + undefined behavior results). + + For SRC and DEST, the first element of the array is the color data. If + the second element is non-null it implies that there is alpha data + (which may be meshed or planar). Data without alpha is assumed to be + opaque. + + Passing a null SRC-ROWBYTES pointer implies that the data SRC points + to is a single element. + + Operations that are not supported will return XP_BadImplementation. */ + +extern xp_error xp_composite_pixels (unsigned int width, unsigned int height, + unsigned int function, + void *src[2], unsigned int src_rowbytes[2], + void *mask, unsigned int mask_rowbytes, + void *dest[2], unsigned int dest_rowbytes[2]); + +/* Fill HEIGHT rows of data starting at DST. Each row will have WIDTH + bytes filled with the 32-bit pattern VALUE. Each row is DST-ROWBYTES + wide in total. */ + +extern void xp_fill_bytes (unsigned int width, + unsigned int height, uint32_t value, + void *dst, unsigned int dst_rowbytes); + +/* Copy HEIGHT rows of bytes from SRC to DST. Each row will have WIDTH + bytes copied. SRC and DST may overlap, and the right thing will happen. */ + +extern void xp_copy_bytes (unsigned int width, unsigned int height, + const void *src, unsigned int src_rowbytes, + void *dst, unsigned int dst_rowbytes); + +/* Suggestions for the minimum number of bytes or pixels for which it + makes sense to use some of the xp_ functions */ + +extern unsigned int xp_fill_bytes_threshold, xp_copy_bytes_threshold, + xp_composite_area_threshold, xp_scroll_area_threshold; + + +#endif /* XPLUGIN_H */ + diff --git a/xorg-server/miext/shadow/makefile b/xorg-server/miext/shadow/makefile new file mode 100644 index 000000000..0a84b506c --- /dev/null +++ b/xorg-server/miext/shadow/makefile @@ -0,0 +1,25 @@ +LIBRARY = libshadow + +#INCLUDES = -I$(top_srcdir)/hw/xfree86/os-support + +CSRCS = shadow.c \ + shalloc.c \ + shpacked.c \ + shplanar8.c \ + shplanar.c \ + shrot16pack_180.c \ + shrot16pack_270.c \ + shrot16pack_270YX.c \ + shrot16pack_90.c \ + shrot16pack_90YX.c \ + shrot16pack.c \ + shrot32pack_180.c \ + shrot32pack_270.c \ + shrot32pack_90.c \ + shrot32pack.c \ + shrot8pack_180.c \ + shrot8pack_270.c \ + shrot8pack_90.c \ + shrot8pack.c \ + shrotate.c + diff --git a/xorg-server/miext/sync/makefile b/xorg-server/miext/sync/makefile new file mode 100644 index 000000000..007233627 --- /dev/null +++ b/xorg-server/miext/sync/makefile @@ -0,0 +1,4 @@ +LIBRARY = libsync
+
+CSRCS = \
+ misync.c
|