diff options
author | Keith Packard <keithp@keithp.com> | 2004-08-07 01:23:07 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2004-08-07 01:23:07 +0000 |
commit | 1e694d2b51a954d1bc4afdde390723e9a1a5b9bf (patch) | |
tree | ba554e8ab002199ce3c12b0639432245fd70faa8 /mi | |
parent | 45fde3b041c071ae5a604cefbbfa4da5c1e828f8 (diff) |
Fix minor timestamp lossage in mieq.
Replace miSprite implementation with Damage-based one. Otherwise damage and
misprite conflict causing looping.
Change pScreen usage around a bit to eliminate warnings
Diffstat (limited to 'mi')
-rw-r--r-- | mi/mieq.c | 2 | ||||
-rw-r--r-- | mi/misprite.c | 1750 | ||||
-rw-r--r-- | mi/mispritest.h | 56 |
3 files changed, 162 insertions, 1646 deletions
@@ -123,6 +123,8 @@ mieqEnqueue (e) miEventQueue.events[oldtail].event.u.keyButtonPointer.time = miEventQueue.lastEventTime; } + miEventQueue.lastEventTime = + miEventQueue.events[oldtail].event.u.keyButtonPointer.time; miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen; } diff --git a/mi/misprite.c b/mi/misprite.c index 260a4dac0..df19784e0 100644 --- a/mi/misprite.c +++ b/mi/misprite.c @@ -51,6 +51,14 @@ in this Software without prior written authorization from The Open Group. #ifdef RENDER # include "mipict.h" #endif +# include "damage.h" + +#define SPRITE_DEBUG_ENABLE 0 +#if SPRITE_DEBUG_ENABLE +#define SPRITE_DEBUG(x) ErrorF x +#else +#define SPRITE_DEBUG(x) +#endif /* * screen wrappers @@ -68,7 +76,9 @@ static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax, char *pdstStart); static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y, int width, int height); -static Bool miSpriteCreateGC(GCPtr pGC); +static void miSpriteCopyWindow (WindowPtr pWindow, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); static void miSpriteBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadMask); @@ -76,45 +86,9 @@ static void miSpriteInstallColormap(ColormapPtr pMap); static void miSpriteStoreColors(ColormapPtr pMap, int ndef, xColorItem *pdef); -static void miSpritePaintWindowBackground(WindowPtr pWin, - RegionPtr pRegion, int what); -static void miSpritePaintWindowBorder(WindowPtr pWin, - RegionPtr pRegion, int what); -static void miSpriteCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, - RegionPtr pRegion); -static void miSpriteClearToBackground(WindowPtr pWin, int x, int y, - int w, int h, - Bool generateExposures); - -#ifdef RENDER -static void miSpriteComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height); - -static void miSpriteGlyphs(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs); -#endif - static void miSpriteSaveDoomedAreas(WindowPtr pWin, RegionPtr pObscured, int dx, int dy); -static RegionPtr miSpriteRestoreAreas(WindowPtr pWin, RegionPtr pRgnExposed); static void miSpriteComputeSaved(ScreenPtr pScreen); #define SCREEN_PROLOGUE(pScreen, field)\ @@ -125,169 +99,6 @@ static void miSpriteComputeSaved(ScreenPtr pScreen); ((pScreen)->field = wrapper) /* - * GC func wrappers - */ - -static int miSpriteGCIndex; - -static void miSpriteValidateGC(GCPtr pGC, unsigned long stateChanges, - DrawablePtr pDrawable); -static void miSpriteCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); -static void miSpriteDestroyGC(GCPtr pGC); -static void miSpriteChangeGC(GCPtr pGC, unsigned long mask); -static void miSpriteChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); -static void miSpriteDestroyClip(GCPtr pGC); -static void miSpriteCopyClip(GCPtr pgcDst, GCPtr pgcSrc); - -static GCFuncs miSpriteGCFuncs = { - miSpriteValidateGC, - miSpriteChangeGC, - miSpriteCopyGC, - miSpriteDestroyGC, - miSpriteChangeClip, - miSpriteDestroyClip, - miSpriteCopyClip, -}; - -#define GC_FUNC_PROLOGUE(pGC) \ - miSpriteGCPtr pGCPriv = \ - (miSpriteGCPtr) (pGC)->devPrivates[miSpriteGCIndex].ptr;\ - (pGC)->funcs = pGCPriv->wrapFuncs; \ - if (pGCPriv->wrapOps) \ - (pGC)->ops = pGCPriv->wrapOps; - -#define GC_FUNC_EPILOGUE(pGC) \ - pGCPriv->wrapFuncs = (pGC)->funcs; \ - (pGC)->funcs = &miSpriteGCFuncs; \ - if (pGCPriv->wrapOps) \ - { \ - pGCPriv->wrapOps = (pGC)->ops; \ - (pGC)->ops = &miSpriteGCOps; \ - } - -/* - * GC op wrappers - */ - -static void miSpriteFillSpans(DrawablePtr pDrawable, GCPtr pGC, - int nInit, DDXPointPtr pptInit, - int *pwidthInit, int fSorted); -static void miSpriteSetSpans(DrawablePtr pDrawable, GCPtr pGC, - char *psrc, DDXPointPtr ppt, int *pwidth, - int nspans, int fSorted); -static void miSpritePutImage(DrawablePtr pDrawable, GCPtr pGC, - int depth, int x, int y, int w, int h, - int leftPad, int format, char *pBits); -static RegionPtr miSpriteCopyArea(DrawablePtr pSrc, DrawablePtr pDst, - GCPtr pGC, int srcx, int srcy, int w, - int h, int dstx, int dsty); -static RegionPtr miSpriteCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, - GCPtr pGC, int srcx, int srcy, int w, - int h, int dstx, int dsty, - unsigned long plane); -static void miSpritePolyPoint(DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, xPoint *pptInit); -static void miSpritePolylines(DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit); -static void miSpritePolySegment(DrawablePtr pDrawable, GCPtr pGC, - int nseg, xSegment *pSegs); -static void miSpritePolyRectangle(DrawablePtr pDrawable, GCPtr pGC, - int nrects, xRectangle *pRects); -static void miSpritePolyArc(DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *parcs); -static void miSpriteFillPolygon(DrawablePtr pDrawable, GCPtr pGC, - int shape, int mode, int count, - DDXPointPtr pPts); -static void miSpritePolyFillRect(DrawablePtr pDrawable, GCPtr pGC, - int nrectFill, xRectangle *prectInit); -static void miSpritePolyFillArc(DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *parcs); -static int miSpritePolyText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char *chars); -static int miSpritePolyText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, - unsigned short *chars); -static void miSpriteImageText8(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, char *chars); -static void miSpriteImageText16(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, int count, - unsigned short *chars); -static void miSpriteImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase); -static void miSpritePolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase); -static void miSpritePushPixels(GCPtr pGC, PixmapPtr pBitMap, - DrawablePtr pDst, int w, int h, - int x, int y); -#ifdef NEED_LINEHELPER -static void miSpriteLineHelper(void); -#endif - -static GCOps miSpriteGCOps = { - miSpriteFillSpans, miSpriteSetSpans, miSpritePutImage, - miSpriteCopyArea, miSpriteCopyPlane, miSpritePolyPoint, - miSpritePolylines, miSpritePolySegment, miSpritePolyRectangle, - miSpritePolyArc, miSpriteFillPolygon, miSpritePolyFillRect, - miSpritePolyFillArc, miSpritePolyText8, miSpritePolyText16, - miSpriteImageText8, miSpriteImageText16, miSpriteImageGlyphBlt, - miSpritePolyGlyphBlt, miSpritePushPixels -#ifdef NEED_LINEHELPER - , miSpriteLineHelper -#endif -}; - -/* - * testing only -- remove cursor for every draw. Eventually, - * each draw operation will perform a bounding box check against - * the saved cursor area - */ - -#define GC_SETUP_CHEAP(pDrawable) \ - miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr) \ - (pDrawable)->pScreen->devPrivates[miSpriteScreenIndex].ptr; \ - -#define GC_SETUP(pDrawable, pGC) \ - GC_SETUP_CHEAP(pDrawable) \ - miSpriteGCPtr pGCPrivate = (miSpriteGCPtr) \ - (pGC)->devPrivates[miSpriteGCIndex].ptr; \ - GCFuncs *oldFuncs = pGC->funcs; - -#define GC_SETUP_AND_CHECK(pDrawable, pGC) \ - GC_SETUP(pDrawable, pGC); \ - if (GC_CHECK((WindowPtr)pDrawable)) \ - miSpriteRemoveCursor (pDrawable->pScreen); - -#define GC_CHECK(pWin) \ - (pScreenPriv->isUp && \ - (pScreenPriv->pCacheWin == pWin ? \ - pScreenPriv->isInCacheWin : ( \ - (pScreenPriv->pCacheWin = (pWin)), \ - (pScreenPriv->isInCacheWin = \ - (pWin)->drawable.x < pScreenPriv->saved.x2 && \ - pScreenPriv->saved.x1 < (pWin)->drawable.x + \ - (int) (pWin)->drawable.width && \ - (pWin)->drawable.y < pScreenPriv->saved.y2 && \ - pScreenPriv->saved.y1 < (pWin)->drawable.y + \ - (int) (pWin)->drawable.height &&\ - RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \ - &pScreenPriv->saved) != rgnOUT)))) - -#define GC_OP_PROLOGUE(pGC) { \ - (pGC)->funcs = pGCPrivate->wrapFuncs; \ - (pGC)->ops = pGCPrivate->wrapOps; \ - } - -#define GC_OP_EPILOGUE(pGC) { \ - pGCPrivate->wrapOps = (pGC)->ops; \ - (pGC)->funcs = oldFuncs; \ - (pGC)->ops = &miSpriteGCOps; \ - } - -/* * pointer-sprite method table */ @@ -311,6 +122,22 @@ miPointerSpriteFuncRec miSpritePointerFuncs = { static void miSpriteRemoveCursor(ScreenPtr pScreen); static void miSpriteRestoreCursor(ScreenPtr pScreen); +static void +miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) +{ + ScreenPtr pScreen = closure; + miSpriteScreenPtr pScreenPriv; + + pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; + + if (pScreenPriv->isUp && + RECT_IN_REGION (pScreen, pRegion, &pScreenPriv->saved) != rgnOUT) + { + SPRITE_DEBUG(("Damage remove\n")); + miSpriteRemoveCursor (pScreen); + } +} + /* * miSpriteInitialize -- called from device-dependent screen * initialization proc after all of the function pointers have @@ -323,101 +150,88 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs) miSpriteCursorFuncPtr cursorFuncs; miPointerScreenFuncPtr screenFuncs; { - miSpriteScreenPtr pPriv; + miSpriteScreenPtr pScreenPriv; VisualPtr pVisual; -#ifdef RENDER - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); -#endif + if (!DamageSetup (pScreen)) + return FALSE; + if (miSpriteGeneration != serverGeneration) { miSpriteScreenIndex = AllocateScreenPrivateIndex (); if (miSpriteScreenIndex < 0) return FALSE; miSpriteGeneration = serverGeneration; - miSpriteGCIndex = AllocateGCPrivateIndex (); } - if (!AllocateGCPrivate(pScreen, miSpriteGCIndex, sizeof(miSpriteGCRec))) - return FALSE; - pPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec)); - if (!pPriv) + + pScreenPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec)); + if (!pScreenPriv) return FALSE; + + pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage, + (DamageDestroyFunc) 0, + DamageReportRawRegion, + TRUE, + pScreen, + (void *) pScreen); + if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE)) { - xfree ((pointer) pPriv); + xfree ((pointer) pScreenPriv); return FALSE; } for (pVisual = pScreen->visuals; pVisual->vid != pScreen->rootVisual; pVisual++) ; - pPriv->pVisual = pVisual; - pPriv->CloseScreen = pScreen->CloseScreen; - pPriv->GetImage = pScreen->GetImage; - pPriv->GetSpans = pScreen->GetSpans; - pPriv->SourceValidate = pScreen->SourceValidate; - pPriv->CreateGC = pScreen->CreateGC; - pPriv->BlockHandler = pScreen->BlockHandler; - pPriv->InstallColormap = pScreen->InstallColormap; - pPriv->StoreColors = pScreen->StoreColors; - - pPriv->PaintWindowBackground = pScreen->PaintWindowBackground; - pPriv->PaintWindowBorder = pScreen->PaintWindowBorder; - pPriv->CopyWindow = pScreen->CopyWindow; - pPriv->ClearToBackground = pScreen->ClearToBackground; - - pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas; - pPriv->RestoreAreas = pScreen->RestoreAreas; -#ifdef RENDER - if (ps) - { - pPriv->Composite = ps->Composite; - pPriv->Glyphs = ps->Glyphs; - } -#endif + pScreenPriv->pVisual = pVisual; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreenPriv->GetImage = pScreen->GetImage; + pScreenPriv->GetSpans = pScreen->GetSpans; + pScreenPriv->SourceValidate = pScreen->SourceValidate; + + pScreenPriv->CopyWindow = pScreen->CopyWindow; + + pScreenPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas; + + pScreenPriv->InstallColormap = pScreen->InstallColormap; + pScreenPriv->StoreColors = pScreen->StoreColors; + + pScreenPriv->BlockHandler = pScreen->BlockHandler; + + pScreenPriv->pCursor = NULL; + pScreenPriv->x = 0; + pScreenPriv->y = 0; + pScreenPriv->isUp = FALSE; + pScreenPriv->shouldBeUp = FALSE; + pScreenPriv->pCacheWin = NullWindow; + pScreenPriv->isInCacheWin = FALSE; + pScreenPriv->checkPixels = TRUE; + pScreenPriv->pInstalledMap = NULL; + pScreenPriv->pColormap = NULL; + pScreenPriv->funcs = cursorFuncs; + pScreenPriv->colors[SOURCE_COLOR].red = 0; + pScreenPriv->colors[SOURCE_COLOR].green = 0; + pScreenPriv->colors[SOURCE_COLOR].blue = 0; + pScreenPriv->colors[MASK_COLOR].red = 0; + pScreenPriv->colors[MASK_COLOR].green = 0; + pScreenPriv->colors[MASK_COLOR].blue = 0; + pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv; - pPriv->pCursor = NULL; - pPriv->x = 0; - pPriv->y = 0; - pPriv->isUp = FALSE; - pPriv->shouldBeUp = FALSE; - pPriv->pCacheWin = NullWindow; - pPriv->isInCacheWin = FALSE; - pPriv->checkPixels = TRUE; - pPriv->pInstalledMap = NULL; - pPriv->pColormap = NULL; - pPriv->funcs = cursorFuncs; - pPriv->colors[SOURCE_COLOR].red = 0; - pPriv->colors[SOURCE_COLOR].green = 0; - pPriv->colors[SOURCE_COLOR].blue = 0; - pPriv->colors[MASK_COLOR].red = 0; - pPriv->colors[MASK_COLOR].green = 0; - pPriv->colors[MASK_COLOR].blue = 0; - pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pPriv; pScreen->CloseScreen = miSpriteCloseScreen; pScreen->GetImage = miSpriteGetImage; pScreen->GetSpans = miSpriteGetSpans; pScreen->SourceValidate = miSpriteSourceValidate; - pScreen->CreateGC = miSpriteCreateGC; - pScreen->BlockHandler = miSpriteBlockHandler; - pScreen->InstallColormap = miSpriteInstallColormap; - pScreen->StoreColors = miSpriteStoreColors; - - pScreen->PaintWindowBackground = miSpritePaintWindowBackground; - pScreen->PaintWindowBorder = miSpritePaintWindowBorder; + pScreen->CopyWindow = miSpriteCopyWindow; - pScreen->ClearToBackground = miSpriteClearToBackground; - + pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas; - pScreen->RestoreAreas = miSpriteRestoreAreas; -#ifdef RENDER - if (ps) - { - ps->Composite = miSpriteComposite; - ps->Glyphs = miSpriteGlyphs; - } -#endif + + pScreen->InstallColormap = miSpriteInstallColormap; + pScreen->StoreColors = miSpriteStoreColors; + pScreen->BlockHandler = miSpriteBlockHandler; + return TRUE; } @@ -436,9 +250,6 @@ miSpriteCloseScreen (i, pScreen) ScreenPtr pScreen; { miSpriteScreenPtr pScreenPriv; -#ifdef RENDER - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); -#endif pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; @@ -446,25 +257,14 @@ miSpriteCloseScreen (i, pScreen) pScreen->GetImage = pScreenPriv->GetImage; pScreen->GetSpans = pScreenPriv->GetSpans; pScreen->SourceValidate = pScreenPriv->SourceValidate; - pScreen->CreateGC = pScreenPriv->CreateGC; pScreen->BlockHandler = pScreenPriv->BlockHandler; pScreen->InstallColormap = pScreenPriv->InstallColormap; pScreen->StoreColors = pScreenPriv->StoreColors; - pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground; - pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder; - pScreen->CopyWindow = pScreenPriv->CopyWindow; - pScreen->ClearToBackground = pScreenPriv->ClearToBackground; - pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas; - pScreen->RestoreAreas = pScreenPriv->RestoreAreas; -#ifdef RENDER - if (ps) - { - ps->Composite = pScreenPriv->Composite; - ps->Glyphs = pScreenPriv->Glyphs; - } -#endif + miSpriteIsUpFALSE (pScreen, pScreenPriv); + DamageDestroy (pScreenPriv->pDamage); + xfree ((pointer) pScreenPriv); return (*pScreen->CloseScreen) (i, pScreen); @@ -489,6 +289,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine) pScreenPriv->isUp && ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h)) { + SPRITE_DEBUG (("GetImage remove\n")); miSpriteRemoveCursor (pScreen); } @@ -532,6 +333,7 @@ miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart) if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg, pts->x+xorg,*widths)) { + SPRITE_DEBUG (("GetSpans remove\n")); miSpriteRemoveCursor (pScreen); break; } @@ -559,6 +361,7 @@ miSpriteSourceValidate (pDrawable, x, y, width, height) ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y, x, y, width, height)) { + SPRITE_DEBUG (("SourceValidate remove\n")); miSpriteRemoveCursor (pScreen); } @@ -568,27 +371,27 @@ miSpriteSourceValidate (pDrawable, x, y, width, height) SCREEN_EPILOGUE (pScreen, SourceValidate, miSpriteSourceValidate); } -static Bool -miSpriteCreateGC (pGC) - GCPtr pGC; +static void +miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) { - ScreenPtr pScreen = pGC->pScreen; - Bool ret; - miSpriteGCPtr pPriv; - - SCREEN_PROLOGUE (pScreen, CreateGC); + ScreenPtr pScreen = pWindow->drawable.pScreen; + miSpriteScreenPtr pScreenPriv; - pPriv = (miSpriteGCPtr)pGC->devPrivates[miSpriteGCIndex].ptr; - - ret = (*pScreen->CreateGC) (pGC); - - pPriv->wrapOps = NULL; - pPriv->wrapFuncs = pGC->funcs; - pGC->funcs = &miSpriteGCFuncs; + SCREEN_PROLOGUE (pScreen, CopyWindow); - SCREEN_EPILOGUE (pScreen, CreateGC, miSpriteCreateGC); + pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; + /* + * Damage will take care of destination check + */ + if (pScreenPriv->isUp && + RECT_IN_REGION (pScreen, prgnSrc, &pScreenPriv->saved) != rgnOUT) + { + SPRITE_DEBUG (("CopyWindow remove\n")); + miSpriteRemoveCursor (pScreen); + } - return ret; + (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc); + SCREEN_EPILOGUE (pScreen, CopyWindow, miSpriteCopyWindow); } static void @@ -610,7 +413,10 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask) SCREEN_EPILOGUE(pScreen, BlockHandler, miSpriteBlockHandler); if (!pPriv->isUp && pPriv->shouldBeUp) + { + SPRITE_DEBUG (("BlockHandler restore\n")); miSpriteRestoreCursor (pScreen); + } } static void @@ -787,1322 +593,6 @@ miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy) SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, miSpriteSaveDoomedAreas); } -static RegionPtr -miSpriteRestoreAreas (pWin, prgnExposed) - WindowPtr pWin; - RegionPtr prgnExposed; -{ - ScreenPtr pScreen; - miSpriteScreenPtr pScreenPriv; - RegionPtr result; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE (pScreen, RestoreAreas); - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pScreenPriv->isUp) - { - if (RECT_IN_REGION( pScreen, prgnExposed, &pScreenPriv->saved) != rgnOUT) - miSpriteRemoveCursor (pScreen); - } - - result = (*pScreen->RestoreAreas) (pWin, prgnExposed); - - SCREEN_EPILOGUE (pScreen, RestoreAreas, miSpriteRestoreAreas); - - return result; -} - -/* - * Window wrappers - */ - -static void -miSpritePaintWindowBackground (pWin, pRegion, what) - WindowPtr pWin; - RegionPtr pRegion; - int what; -{ - ScreenPtr pScreen; - miSpriteScreenPtr pScreenPriv; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE (pScreen, PaintWindowBackground); - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pScreenPriv->isUp) - { - /* - * If the cursor is on the same screen as the window, check the - * region to paint for the cursor and remove it as necessary - */ - if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT) - miSpriteRemoveCursor (pScreen); - } - - (*pScreen->PaintWindowBackground) (pWin, pRegion, what); - - SCREEN_EPILOGUE (pScreen, PaintWindowBackground, miSpritePaintWindowBackground); -} - -static void -miSpritePaintWindowBorder (pWin, pRegion, what) - WindowPtr pWin; - RegionPtr pRegion; - int what; -{ - ScreenPtr pScreen; - miSpriteScreenPtr pScreenPriv; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE (pScreen, PaintWindowBorder); - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pScreenPriv->isUp) - { - /* - * If the cursor is on the same screen as the window, check the - * region to paint for the cursor and remove it as necessary - */ - if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT) - miSpriteRemoveCursor (pScreen); - } - - (*pScreen->PaintWindowBorder) (pWin, pRegion, what); - - SCREEN_EPILOGUE (pScreen, PaintWindowBorder, miSpritePaintWindowBorder); -} - -static void -miSpriteCopyWindow (pWin, ptOldOrg, pRegion) - WindowPtr pWin; - DDXPointRec ptOldOrg; - RegionPtr pRegion; -{ - ScreenPtr pScreen; - miSpriteScreenPtr pScreenPriv; - BoxRec cursorBox; - int dx, dy; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE (pScreen, CopyWindow); - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (pScreenPriv->isUp) - { - /* - * check both the source and the destination areas. The given - * region is source relative, so offset the cursor box by - * the delta position - */ - cursorBox = pScreenPriv->saved; - dx = pWin->drawable.x - ptOldOrg.x; - dy = pWin->drawable.y - ptOldOrg.y; - cursorBox.x1 -= dx; - cursorBox.x2 -= dx; - cursorBox.y1 -= dy; - cursorBox.y2 -= dy; - if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT || - RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT) - miSpriteRemoveCursor (pScreen); - } - - (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion); - - SCREEN_EPILOGUE (pScreen, CopyWindow, miSpriteCopyWindow); -} - -static void -miSpriteClearToBackground (pWin, x, y, w, h, generateExposures) - WindowPtr pWin; - int x,y; - int w,h; - Bool generateExposures; -{ - ScreenPtr pScreen; - miSpriteScreenPtr pScreenPriv; - int realw, realh; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE (pScreen, ClearToBackground); - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (GC_CHECK(pWin)) - { - if (!(realw = w)) - realw = (int) pWin->drawable.width - x; - if (!(realh = h)) - realh = (int) pWin->drawable.height - y; - if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y, - x, y, realw, realh)) - { - miSpriteRemoveCursor (pScreen); - } - } - - (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); - - SCREEN_EPILOGUE (pScreen, ClearToBackground, miSpriteClearToBackground); -} - -/* - * GC Func wrappers - */ - -static void -miSpriteValidateGC (pGC, changes, pDrawable) - GCPtr pGC; - unsigned long changes; - DrawablePtr pDrawable; -{ - GC_FUNC_PROLOGUE (pGC); - - (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); - - pGCPriv->wrapOps = NULL; - if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable) - { - WindowPtr pWin; - RegionPtr pRegion; - - pWin = (WindowPtr) pDrawable; - pRegion = &pWin->clipList; - if (pGC->subWindowMode == IncludeInferiors) - pRegion = &pWin->borderClip; - if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) - pGCPriv->wrapOps = pGC->ops; - } - - GC_FUNC_EPILOGUE (pGC); -} - -static void -miSpriteChangeGC (pGC, mask) - GCPtr pGC; - unsigned long mask; -{ - GC_FUNC_PROLOGUE (pGC); - - (*pGC->funcs->ChangeGC) (pGC, mask); - - GC_FUNC_EPILOGUE (pGC); -} - -static void -miSpriteCopyGC (pGCSrc, mask, pGCDst) - GCPtr pGCSrc, pGCDst; - unsigned long mask; -{ - GC_FUNC_PROLOGUE (pGCDst); - - (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - - GC_FUNC_EPILOGUE (pGCDst); -} - -static void -miSpriteDestroyGC (pGC) - GCPtr pGC; -{ - GC_FUNC_PROLOGUE (pGC); - - (*pGC->funcs->DestroyGC) (pGC); - - GC_FUNC_EPILOGUE (pGC); -} - -static void -miSpriteChangeClip (pGC, type, pvalue, nrects) - GCPtr pGC; - int type; - pointer pvalue; - int nrects; -{ - GC_FUNC_PROLOGUE (pGC); - - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - - GC_FUNC_EPILOGUE (pGC); -} - -static void -miSpriteCopyClip(pgcDst, pgcSrc) - GCPtr pgcDst, pgcSrc; -{ - GC_FUNC_PROLOGUE (pgcDst); - - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - - GC_FUNC_EPILOGUE (pgcDst); -} - -static void -miSpriteDestroyClip(pGC) - GCPtr pGC; -{ - GC_FUNC_PROLOGUE (pGC); - - (* pGC->funcs->DestroyClip)(pGC); - - GC_FUNC_EPILOGUE (pGC); -} - -/* - * GC Op wrappers - */ - -static void -miSpriteFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) - DrawablePtr pDrawable; - GCPtr pGC; - int nInit; /* number of spans to fill */ - DDXPointPtr pptInit; /* pointer to list of start points */ - int *pwidthInit; /* pointer to list of n widths */ - int fSorted; -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - register DDXPointPtr pts; - register int *widths; - register int nPts; - - for (pts = pptInit, widths = pwidthInit, nPts = nInit; - nPts--; - pts++, widths++) - { - if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpriteSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted) - DrawablePtr pDrawable; - GCPtr pGC; - char *psrc; - register DDXPointPtr ppt; - int *pwidth; - int nspans; - int fSorted; -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - register DDXPointPtr pts; - register int *widths; - register int nPts; - - for (pts = ppt, widths = pwidth, nPts = nspans; - nPts--; - pts++, widths++) - { - if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths)) - { - miSpriteRemoveCursor(pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits) - DrawablePtr pDrawable; - GCPtr pGC; - int depth; - int x; - int y; - int w; - int h; - int leftPad; - int format; - char *pBits; -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, - x,y,w,h)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits); - - GC_OP_EPILOGUE (pGC); -} - -static RegionPtr -miSpriteCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty) - DrawablePtr pSrc; - DrawablePtr pDst; - GCPtr pGC; - int srcx; - int srcy; - int w; - int h; - int dstx; - int dsty; -{ - RegionPtr rgn; - - GC_SETUP(pDst, pGC); - - /* check destination/source overlap. */ - if (GC_CHECK((WindowPtr) pDst) && - (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) || - ((pDst == pSrc) && - ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h)))) - { - miSpriteRemoveCursor (pDst->pScreen); - } - - GC_OP_PROLOGUE (pGC); - - rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty); - - GC_OP_EPILOGUE (pGC); - - return rgn; -} - -static RegionPtr -miSpriteCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane) - DrawablePtr pSrc; - DrawablePtr pDst; - register GCPtr pGC; - int srcx, - srcy; - int w, - h; - int dstx, - dsty; - unsigned long plane; -{ - RegionPtr rgn; - - GC_SETUP(pDst, pGC); - - /* - * check destination/source for overlap. - */ - if (GC_CHECK((WindowPtr) pDst) && - (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) || - ((pDst == pSrc) && - ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h)))) - { - miSpriteRemoveCursor (pDst->pScreen); - } - - GC_OP_PROLOGUE (pGC); - - rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, - dstx, dsty, plane); - - GC_OP_EPILOGUE (pGC); - - return rgn; -} - -static void -miSpritePolyPoint (pDrawable, pGC, mode, npt, pptInit) - DrawablePtr pDrawable; - GCPtr pGC; - int mode; /* Origin or Previous */ - int npt; - xPoint *pptInit; -{ - xPoint t; - int n; - BoxRec cursor; - register xPoint *pts; - - GC_SETUP (pDrawable, pGC); - - if (npt && GC_CHECK((WindowPtr) pDrawable)) - { - cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x; - cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y; - cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x; - cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y; - - if (mode == CoordModePrevious) - { - t.x = 0; - t.y = 0; - for (pts = pptInit, n = npt; n--; pts++) - { - t.x += pts->x; - t.y += pts->y; - if (cursor.x1 <= t.x && t.x <= cursor.x2 && - cursor.y1 <= t.y && t.y <= cursor.y2) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - else - { - for (pts = pptInit, n = npt; n--; pts++) - { - if (cursor.x1 <= pts->x && pts->x <= cursor.x2 && - cursor.y1 <= pts->y && pts->y <= cursor.y2) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolylines (pDrawable, pGC, mode, npt, pptInit) - DrawablePtr pDrawable; - GCPtr pGC; - int mode; - int npt; - DDXPointPtr pptInit; -{ - BoxPtr cursor; - register DDXPointPtr pts; - int n; - int x, y, x1, y1, x2, y2; - int lw; - int extra; - - GC_SETUP (pDrawable, pGC); - - if (npt && GC_CHECK((WindowPtr) pDrawable)) - { - cursor = &pScreenPriv->saved; - lw = pGC->lineWidth; - x = pptInit->x + pDrawable->x; - y = pptInit->y + pDrawable->y; - - if (npt == 1) - { - extra = lw >> 1; - if (LINE_OVERLAP(cursor, x, y, x, y, extra)) - miSpriteRemoveCursor (pDrawable->pScreen); - } - else - { - extra = lw >> 1; - /* - * mitered joins can project quite a way from - * the line end; the 11 degree miter limit limits - * this extension to 10.43 * lw / 2, rounded up - * and converted to int yields 6 * lw - */ - if (pGC->joinStyle == JoinMiter) - extra = 6 * lw; - else if (pGC->capStyle == CapProjecting) - extra = lw; - for (pts = pptInit + 1, n = npt - 1; n--; pts++) - { - x1 = x; - y1 = y; - if (mode == CoordModeOrigin) - { - x2 = pDrawable->x + pts->x; - y2 = pDrawable->y + pts->y; - } - else - { - x2 = x + pts->x; - y2 = y + pts->y; - } - x = x2; - y = y2; - LINE_SORT(x1, y1, x2, y2); - if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - } - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolySegment(pDrawable, pGC, nseg, pSegs) - DrawablePtr pDrawable; - GCPtr pGC; - int nseg; - xSegment *pSegs; -{ - int n; - register xSegment *segs; - BoxPtr cursor; - int x1, y1, x2, y2; - int extra; - - GC_SETUP(pDrawable, pGC); - - if (nseg && GC_CHECK((WindowPtr) pDrawable)) - { - cursor = &pScreenPriv->saved; - extra = pGC->lineWidth >> 1; - if (pGC->capStyle == CapProjecting) - extra = pGC->lineWidth; - for (segs = pSegs, n = nseg; n--; segs++) - { - x1 = segs->x1 + pDrawable->x; - y1 = segs->y1 + pDrawable->y; - x2 = segs->x2 + pDrawable->x; - y2 = segs->y2 + pDrawable->y; - LINE_SORT(x1, y1, x2, y2); - if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolyRectangle(pDrawable, pGC, nrects, pRects) - DrawablePtr pDrawable; - GCPtr pGC; - int nrects; - xRectangle *pRects; -{ - register xRectangle *rects; - BoxPtr cursor; - int lw; - int n; - int x1, y1, x2, y2; - - GC_SETUP (pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - lw = pGC->lineWidth >> 1; - cursor = &pScreenPriv->saved; - for (rects = pRects, n = nrects; n--; rects++) - { - x1 = rects->x + pDrawable->x; - y1 = rects->y + pDrawable->y; - x2 = x1 + (int)rects->width; - y2 = y1 + (int)rects->height; - if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) || - LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) || - LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) || - LINE_OVERLAP(cursor, x1, y1, x1, y2, lw)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolyArc(pDrawable, pGC, narcs, parcs) - DrawablePtr pDrawable; - register GCPtr pGC; - int narcs; - xArc *parcs; -{ - BoxPtr cursor; - int lw; - int n; - register xArc *arcs; - - GC_SETUP (pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - lw = pGC->lineWidth >> 1; - cursor = &pScreenPriv->saved; - for (arcs = parcs, n = narcs; n--; arcs++) - { - if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y, - arcs->x - lw, arcs->y - lw, - (int) arcs->width + pGC->lineWidth, - (int) arcs->height + pGC->lineWidth)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpriteFillPolygon(pDrawable, pGC, shape, mode, count, pPts) - register DrawablePtr pDrawable; - register GCPtr pGC; - int shape, mode; - int count; - DDXPointPtr pPts; -{ - int x, y, minx, miny, maxx, maxy; - register DDXPointPtr pts; - int n; - - GC_SETUP (pDrawable, pGC); - - if (count && GC_CHECK((WindowPtr) pDrawable)) - { - x = pDrawable->x; - y = pDrawable->y; - pts = pPts; - minx = maxx = pts->x; - miny = maxy = pts->y; - pts++; - n = count - 1; - - if (mode == CoordModeOrigin) - { - for (; n--; pts++) - { - if (pts->x < minx) - minx = pts->x; - else if (pts->x > maxx) - maxx = pts->x; - if (pts->y < miny) - miny = pts->y; - else if (pts->y > maxy) - maxy = pts->y; - } - minx += x; - miny += y; - maxx += x; - maxy += y; - } - else - { - x += minx; - y += miny; - minx = maxx = x; - miny = maxy = y; - for (; n--; pts++) - { - x += pts->x; - y += pts->y; - if (x < minx) - minx = x; - else if (x > maxx) - maxx = x; - if (y < miny) - miny = y; - else if (y > maxy) - maxy = y; - } - } - if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy)) - miSpriteRemoveCursor (pDrawable->pScreen); - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolyFillRect(pDrawable, pGC, nrectFill, prectInit) - DrawablePtr pDrawable; - GCPtr pGC; - int nrectFill; /* number of rectangles to fill */ - xRectangle *prectInit; /* Pointer to first rectangle to fill */ -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - register int nRect; - register xRectangle *pRect; - register int xorg, yorg; - - xorg = pDrawable->x; - yorg = pDrawable->y; - - for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) { - if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){ - miSpriteRemoveCursor(pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolyFillArc(pDrawable, pGC, narcs, parcs) - DrawablePtr pDrawable; - GCPtr pGC; - int narcs; - xArc *parcs; -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - { - register int n; - BoxPtr cursor; - register xArc *arcs; - - cursor = &pScreenPriv->saved; - - for (arcs = parcs, n = narcs; n--; arcs++) - { - if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y, - arcs->x, arcs->y, - (int) arcs->width, (int) arcs->height)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - break; - } - } - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs); - - GC_OP_EPILOGUE (pGC); -} - -/* - * general Poly/Image text function. Extract glyph information, - * compute bounding box and remove cursor if it is overlapped. - */ - -static Bool -miSpriteTextOverlap ( - DrawablePtr pDraw, - FontPtr font, - int x, - int y, - unsigned int n, - CharInfoPtr *charinfo, - Bool imageblt, - unsigned int w, - BoxPtr cursorBox) -{ - ExtentInfoRec extents; - - x += pDraw->x; - y += pDraw->y; - - if (FONTMINBOUNDS(font,characterWidth) >= 0) - { - /* compute an approximate (but covering) bounding box */ - if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0)) - extents.overallLeft = charinfo[0]->metrics.leftSideBearing; - else - extents.overallLeft = 0; - if (w) - extents.overallRight = w - charinfo[n-1]->metrics.characterWidth; - else - extents.overallRight = FONTMAXBOUNDS(font,characterWidth) - * (n - 1); - if (imageblt && (charinfo[n-1]->metrics.characterWidth > - charinfo[n-1]->metrics.rightSideBearing)) - extents.overallRight += charinfo[n-1]->metrics.characterWidth; - else - extents.overallRight += charinfo[n-1]->metrics.rightSideBearing; - if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent)) - extents.overallAscent = FONTASCENT(font); - else - extents.overallAscent = FONTMAXBOUNDS(font, ascent); - if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent)) - extents.overallDescent = FONTDESCENT(font); - else - extents.overallDescent = FONTMAXBOUNDS(font,descent); - if (!BOX_OVERLAP(cursorBox, - x + extents.overallLeft, - y - extents.overallAscent, - x + extents.overallRight, - y + extents.overallDescent)) - return FALSE; - else if (imageblt && w) - return TRUE; - /* if it does overlap, fall through and compute exactly, because - * taking down the cursor is expensive enough to make this worth it - */ - } - 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; - } - return (BOX_OVERLAP(cursorBox, - x + extents.overallLeft, - y - extents.overallAscent, - x + extents.overallRight, - y + extents.overallDescent)); -} - -/* - * values for textType: - */ -#define TT_POLY8 0 -#define TT_IMAGE8 1 -#define TT_POLY16 2 -#define TT_IMAGE16 3 - -static int -miSpriteText ( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - unsigned long count, - char *chars, - FontEncoding fontEncoding, - Bool textType, - BoxPtr cursorBox) -{ - CharInfoPtr *charinfo; - register CharInfoPtr *info; - unsigned long i; - unsigned int n; - int w; - - Bool imageblt; - - imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); - - charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(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) { - if (miSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox)) - miSpriteRemoveCursor(pDraw->pScreen); - -#ifdef AVOID_GLYPHBLT - /* - * On displays like Apollos, which do not optimize the GlyphBlt functions because they - * convert fonts to their internal form in RealizeFont and optimize text directly, we - * want to invoke the text functions here, not the GlyphBlt functions. - */ - switch (textType) - { - case TT_POLY8: - (*pGC->ops->PolyText8)(pDraw, pGC, x, y, (int)count, chars); - break; - case TT_IMAGE8: - (*pGC->ops->ImageText8)(pDraw, pGC, x, y, (int)count, chars); - break; - case TT_POLY16: - (*pGC->ops->PolyText16)(pDraw, pGC, x, y, (int)count, - (unsigned short *)chars); - break; - case TT_IMAGE16: - (*pGC->ops->ImageText16)(pDraw, pGC, x, y, (int)count, - (unsigned short *)chars); - break; - } -#else /* don't AVOID_GLYPHBLT */ - /* - * On the other hand, if the device does use GlyphBlt ultimately to do text, we - * don't want to slow it down by invoking the text functions and having them call - * GetGlyphs all over again, so we go directly to the GlyphBlt functions here. - */ - if (imageblt) { - (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); - } else { - (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, n, charinfo, - FONTGLYPHS(pGC->font)); - } -#endif /* AVOID_GLYPHBLT */ - } - DEALLOCATE_LOCAL(charinfo); - return x + w; -} - -static int -miSpritePolyText8(pDrawable, pGC, x, y, count, chars) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - int count; - char *chars; -{ - int ret; - - GC_SETUP (pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, - Linear8Bit, TT_POLY8, &pScreenPriv->saved); - else - ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); - - GC_OP_EPILOGUE (pGC); - return ret; -} - -static int -miSpritePolyText16(pDrawable, pGC, x, y, count, chars) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - int count; - unsigned short *chars; -{ - int ret; - - GC_SETUP(pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, - (char *)chars, - FONTLASTROW(pGC->font) == 0 ? - Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved); - else - ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); - - GC_OP_EPILOGUE (pGC); - return ret; -} - -static void -miSpriteImageText8(pDrawable, pGC, x, y, count, chars) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - int count; - char *chars; -{ - GC_SETUP(pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, - chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved); - else - (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpriteImageText16(pDrawable, pGC, x, y, count, chars) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - int count; - unsigned short *chars; -{ - GC_SETUP(pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable)) - (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, - (char *)chars, - FONTLASTROW(pGC->font) == 0 ? - Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved); - else - (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - unsigned int nglyph; - CharInfoPtr *ppci; /* array of character info */ - pointer pglyphBase; /* start of array of glyphs */ -{ - GC_SETUP(pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable) && - miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved)) - { - miSpriteRemoveCursor(pDrawable->pScreen); - } - (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) - DrawablePtr pDrawable; - GCPtr pGC; - int x, y; - unsigned int nglyph; - CharInfoPtr *ppci; /* array of character info */ - pointer pglyphBase; /* start of array of glyphs */ -{ - GC_SETUP (pDrawable, pGC); - - GC_OP_PROLOGUE (pGC); - - if (GC_CHECK((WindowPtr) pDrawable) && - miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved)) - { - miSpriteRemoveCursor(pDrawable->pScreen); - } - (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - - GC_OP_EPILOGUE (pGC); -} - -static void -miSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y) - GCPtr pGC; - PixmapPtr pBitMap; - DrawablePtr pDrawable; - int w, h, x, y; -{ - GC_SETUP(pDrawable, pGC); - - if (GC_CHECK((WindowPtr) pDrawable) && - ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h)) - { - miSpriteRemoveCursor (pDrawable->pScreen); - } - - GC_OP_PROLOGUE (pGC); - - (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); - - GC_OP_EPILOGUE (pGC); -} - -#ifdef NEED_LINEHELPER -/* - * I don't expect this routine will ever be called, as the GC - * will have been unwrapped for the line drawing - */ - -static void -miSpriteLineHelper() -{ - FatalError("miSpriteLineHelper called\n"); -} -#endif - -#ifdef RENDER - -# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) - -static void -miSpritePictureOverlap (PicturePtr pPict, - INT16 x, - INT16 y, - CARD16 w, - CARD16 h) -{ - if (pPict->pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pWin = (WindowPtr) (pPict->pDrawable); - miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr) - pPict->pDrawable->pScreen->devPrivates[miSpriteScreenIndex].ptr; - if (GC_CHECK(pWin)) - { - if (pPict->repeat) - { - x = mod(x,pWin->drawable.width); - y = mod(y,pWin->drawable.height); - } - if (ORG_OVERLAP (&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y, - x, y, w, h)) - miSpriteRemoveCursor (pWin->drawable.pScreen); - } - } -} - -#define PICTURE_PROLOGUE(ps, pScreenPriv, field) \ - ps->field = pScreenPriv->field - -#define PICTURE_EPILOGUE(ps, field, wrap) \ - ps->field = wrap - -static void -miSpriteComposite(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); - miSpriteScreenPtr pScreenPriv; - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - PICTURE_PROLOGUE(ps, pScreenPriv, Composite); - miSpritePictureOverlap (pSrc, xSrc, ySrc, width, height); - if (pMask) - miSpritePictureOverlap (pMask, xMask, yMask, width, height); - miSpritePictureOverlap (pDst, xDst, yDst, width, height); - - (*ps->Composite) (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - - PICTURE_EPILOGUE(ps, Composite, miSpriteComposite); -} - -static void -miSpriteGlyphs(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); - miSpriteScreenPtr pScreenPriv; - - pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - PICTURE_PROLOGUE(ps, pScreenPriv, Glyphs); - if (pSrc->pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pSrcWin = (WindowPtr) (pSrc->pDrawable); - - if (GC_CHECK(pSrcWin)) - miSpriteRemoveCursor (pScreen); - } - if (pDst->pDrawable->type == DRAWABLE_WINDOW) - { - WindowPtr pDstWin = (WindowPtr) (pDst->pDrawable); - - if (GC_CHECK(pDstWin)) - { - BoxRec extents; - - miGlyphExtents (nlist, list, glyphs, &extents); - if (BOX_OVERLAP(&pScreenPriv->saved, - extents.x1 + pDstWin->drawable.x, - extents.y1 + pDstWin->drawable.y, - extents.x2 + pDstWin->drawable.x, - extents.y2 + pDstWin->drawable.y)) - { - miSpriteRemoveCursor (pScreen); - } - } - } - - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - - PICTURE_EPILOGUE (ps, Glyphs, miSpriteGlyphs); -} -#endif - /* * miPointer interface routines */ @@ -2186,7 +676,8 @@ miSpriteSetCursor (pScreen, pCursor, x, y) pScreenPriv->saved.y2 - pScreenPriv->saved.y1 ) { - pScreenPriv->isUp = FALSE; + DamageDrawInternal (pScreen, TRUE); + miSpriteIsUpFALSE (pScreen, pScreenPriv); if (!(sx >= pScreenPriv->saved.x1 && sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 && sy >= pScreenPriv->saved.y1 && @@ -2218,15 +709,20 @@ miSpriteSetCursor (pScreen, pCursor, x, y) sy - pScreenPriv->saved.y1, pScreenPriv->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[MASK_COLOR].pixel); - pScreenPriv->isUp = TRUE; + miSpriteIsUpTRUE (pScreen, pScreenPriv); + DamageDrawInternal (pScreen, FALSE); } else { + SPRITE_DEBUG (("SetCursor remove\n")); miSpriteRemoveCursor (pScreen); } } if (!pScreenPriv->isUp && pScreenPriv->pCursor) + { + SPRITE_DEBUG (("SetCursor restore\n")); miSpriteRestoreCursor (pScreen); + } } static void @@ -2250,8 +746,9 @@ miSpriteRemoveCursor (pScreen) { miSpriteScreenPtr pScreenPriv; + DamageDrawInternal (pScreen, TRUE); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; - pScreenPriv->isUp = FALSE; + miSpriteIsUpFALSE (pScreen, pScreenPriv); pScreenPriv->pCacheWin = NullWindow; if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen, pScreenPriv->saved.x1, @@ -2259,8 +756,9 @@ miSpriteRemoveCursor (pScreen) pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) { - pScreenPriv->isUp = TRUE; + miSpriteIsUpTRUE (pScreen, pScreenPriv); } + DamageDrawInternal (pScreen, FALSE); } /* @@ -2276,6 +774,7 @@ miSpriteRestoreCursor (pScreen) int x, y; CursorPtr pCursor; + DamageDrawInternal (pScreen, TRUE); miSpriteComputeSaved (pScreen); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pCursor = pScreenPriv->pCursor; @@ -2292,8 +791,11 @@ miSpriteRestoreCursor (pScreen) if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y, pScreenPriv->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[MASK_COLOR].pixel)) - pScreenPriv->isUp = TRUE; + { + miSpriteIsUpTRUE (pScreen, pScreenPriv); + } } + DamageDrawInternal (pScreen, FALSE); } /* diff --git a/mi/mispritest.h b/mi/mispritest.h index e438dd7d2..7312d2476 100644 --- a/mi/mispritest.h +++ b/mi/mispritest.h @@ -32,58 +32,68 @@ in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/programs/Xserver/mi/mispritest.h,v 1.4 2001/01/17 22:37:07 dawes Exp $ */ +#ifndef _MISPRITEST_H_ +#define _MISPRITEST_H_ + # include "misprite.h" #ifdef RENDER # include "picturestr.h" #endif +# include "damage.h" /* * per screen information */ typedef struct { + /* screen procedures */ CloseScreenProcPtr CloseScreen; GetImageProcPtr GetImage; GetSpansProcPtr GetSpans; SourceValidateProcPtr SourceValidate; - CreateGCProcPtr CreateGC; - ScreenBlockHandlerProcPtr BlockHandler; - InstallColormapProcPtr InstallColormap; - StoreColorsProcPtr StoreColors; - PaintWindowBackgroundProcPtr PaintWindowBackground; - PaintWindowBorderProcPtr PaintWindowBorder; + + /* window procedures */ CopyWindowProcPtr CopyWindow; - ClearToBackgroundProcPtr ClearToBackground; + + /* backing store procedures */ SaveDoomedAreasProcPtr SaveDoomedAreas; - RestoreAreasProcPtr RestoreAreas; -#ifdef RENDER - CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; -#endif + + /* colormap procedures */ + InstallColormapProcPtr InstallColormap; + StoreColorsProcPtr StoreColors; + + /* os layer procedures */ + ScreenBlockHandlerProcPtr BlockHandler; CursorPtr pCursor; - int x; + int x; /* cursor hotspot */ int y; - BoxRec saved; - Bool isUp; - Bool shouldBeUp; - WindowPtr pCacheWin; + BoxRec saved; /* saved area from the screen */ + Bool isUp; /* cursor in frame buffer */ + Bool shouldBeUp; /* cursor should be displayed */ + WindowPtr pCacheWin; /* window the cursor last seen in */ Bool isInCacheWin; - Bool checkPixels; + Bool checkPixels; /* check colormap collision */ xColorItem colors[2]; ColormapPtr pInstalledMap; ColormapPtr pColormap; VisualPtr pVisual; miSpriteCursorFuncPtr funcs; + DamagePtr pDamage; /* damage tracking structure */ } miSpriteScreenRec, *miSpriteScreenPtr; #define SOURCE_COLOR 0 #define MASK_COLOR 1 -typedef struct { - GCFuncs *wrapFuncs; - GCOps *wrapOps; -} miSpriteGCRec, *miSpriteGCPtr; +#define miSpriteIsUpTRUE(pScreen, pScreenPriv) if (!pScreenPriv->isUp) { \ + pScreenPriv->isUp = TRUE; \ + DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ +} + +#define miSpriteIsUpFALSE(pScreen, pScreenPriv) if (pScreenPriv->isUp) { \ + DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \ + pScreenPriv->isUp = FALSE; \ +} /* * Overlap BoxPtr and Box elements @@ -116,3 +126,5 @@ typedef struct { #define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \ BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2)) + +#endif /* _MISPRITEST_H_ */ |