+++ /dev/null
-/*
- * misprite.c
- *
- * machine independent software sprite routines
- */
-
-/* $XConsortium: misprite.c,v 5.47 94/04/17 20:27:53 dpw Exp $ */
-/* $XFree86: xc/programs/Xserver/mi/misprite.c,v 3.0 1996/08/25 14:13:56 dawes Exp $ */
-
-/*
-
-Copyright (c) 1989 X Consortium
-
-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
-X CONSORTIUM 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 X Consortium 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 X Consortium.
-*/
-
-# include "X.h"
-# include "Xproto.h"
-# include "misc.h"
-# include "pixmapstr.h"
-# include "input.h"
-# include "mi.h"
-# include "cursorstr.h"
-# include "font.h"
-# include "scrnintstr.h"
-# include "colormapst.h"
-# include "windowstr.h"
-# include "gcstruct.h"
-# include "mipointer.h"
-# include "mispritest.h"
-# include "dixfontstr.h"
-# include "fontstruct.h"
-
-/*
- * screen wrappers
- */
-
-static int miSpriteScreenIndex;
-static unsigned long miSpriteGeneration = 0;
-
-static Bool miSpriteCloseScreen();
-static void miSpriteGetImage();
-static void miSpriteGetSpans();
-static void miSpriteSourceValidate();
-static Bool miSpriteCreateGC();
-static void miSpriteBlockHandler();
-static void miSpriteInstallColormap();
-static void miSpriteStoreColors();
-
-static void miSpritePaintWindowBackground();
-static void miSpritePaintWindowBorder();
-static void miSpriteCopyWindow();
-static void miSpriteClearToBackground();
-
-static void miSpriteSaveDoomedAreas();
-static RegionPtr miSpriteRestoreAreas();
-static void miSpriteComputeSaved();
-
-#define SCREEN_PROLOGUE(pScreen, field)\
- ((pScreen)->field = \
- ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
-
-#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
- ((pScreen)->field = wrapper)
-
-/*
- * GC func wrappers
- */
-
-static int miSpriteGCIndex;
-
-static void miSpriteValidateGC (), miSpriteCopyGC ();
-static void miSpriteDestroyGC(), miSpriteChangeGC();
-static void miSpriteChangeClip(), miSpriteDestroyClip();
-static void miSpriteCopyClip();
-
-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(), miSpriteSetSpans();
-static void miSpritePutImage();
-static RegionPtr miSpriteCopyArea(), miSpriteCopyPlane();
-static void miSpritePolyPoint(), miSpritePolylines();
-static void miSpritePolySegment(), miSpritePolyRectangle();
-static void miSpritePolyArc(), miSpriteFillPolygon();
-static void miSpritePolyFillRect(), miSpritePolyFillArc();
-static int miSpritePolyText8(), miSpritePolyText16();
-static void miSpriteImageText8(), miSpriteImageText16();
-static void miSpriteImageGlyphBlt(), miSpritePolyGlyphBlt();
-static void miSpritePushPixels();
-#ifdef NEED_LINEHELPER
-static void miSpriteLineHelper();
-#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
- */
-
-static Bool miSpriteRealizeCursor (), miSpriteUnrealizeCursor ();
-static void miSpriteSetCursor (), miSpriteMoveCursor ();
-
-miPointerSpriteFuncRec miSpritePointerFuncs = {
- miSpriteRealizeCursor,
- miSpriteUnrealizeCursor,
- miSpriteSetCursor,
- miSpriteMoveCursor,
-};
-
-/*
- * other misc functions
- */
-
-static void miSpriteRemoveCursor (), miSpriteRestoreCursor();
-
-/*
- * miSpriteInitialize -- called from device-dependent screen
- * initialization proc after all of the function pointers have
- * been stored in the screen structure.
- */
-
-Bool
-miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
- ScreenPtr pScreen;
- miSpriteCursorFuncPtr cursorFuncs;
- miPointerScreenFuncPtr screenFuncs;
-{
- miSpriteScreenPtr pPriv;
- VisualPtr pVisual;
-
- 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)
- return FALSE;
- if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
- {
- xfree ((pointer) pPriv);
- 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;
-
- 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;
-
- return TRUE;
-}
-
-/*
- * Screen wrappers
- */
-
-/*
- * CloseScreen wrapper -- unwrap everything, free the private data
- * and call the wrapped function
- */
-
-static Bool
-miSpriteCloseScreen (i, pScreen)
- ScreenPtr pScreen;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- 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;
-
- xfree ((pointer) pScreenPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void
-miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
- DrawablePtr pDrawable;
- int sx, sy, w, h;
- unsigned int format;
- unsigned long planemask;
- char *pdstLine;
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- miSpriteScreenPtr pScreenPriv;
-
- SCREEN_PROLOGUE (pScreen, GetImage);
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- if (pDrawable->type == DRAWABLE_WINDOW &&
- pScreenPriv->isUp &&
- ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
- {
- miSpriteRemoveCursor (pScreen);
- }
-
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
- format, planemask, pdstLine);
-
- SCREEN_EPILOGUE (pScreen, GetImage, miSpriteGetImage);
-}
-
-static void
-miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
- DrawablePtr pDrawable;
- int wMax;
- DDXPointPtr ppt;
- int *pwidth;
- int nspans;
- char *pdstStart;
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- miSpriteScreenPtr pScreenPriv;
-
- SCREEN_PROLOGUE (pScreen, GetSpans);
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
- {
- register DDXPointPtr pts;
- register int *widths;
- register int nPts;
- register int xorg,
- yorg;
-
- xorg = pDrawable->x;
- yorg = pDrawable->y;
-
- for (pts = ppt, widths = pwidth, nPts = nspans;
- nPts--;
- pts++, widths++)
- {
- if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
- pts->x+xorg,*widths))
- {
- miSpriteRemoveCursor (pScreen);
- break;
- }
- }
- }
-
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-
- SCREEN_EPILOGUE (pScreen, GetSpans, miSpriteGetSpans);
-}
-
-static void
-miSpriteSourceValidate (pDrawable, x, y, width, height)
- DrawablePtr pDrawable;
- int x, y, width, height;
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- miSpriteScreenPtr pScreenPriv;
-
- SCREEN_PROLOGUE (pScreen, SourceValidate);
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
- ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
- x, y, width, height))
- {
- miSpriteRemoveCursor (pScreen);
- }
-
- if (pScreen->SourceValidate)
- (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
-
- SCREEN_EPILOGUE (pScreen, SourceValidate, miSpriteSourceValidate);
-}
-
-static Bool
-miSpriteCreateGC (pGC)
- GCPtr pGC;
-{
- ScreenPtr pScreen = pGC->pScreen;
- Bool ret;
- miSpriteGCPtr pPriv;
-
- SCREEN_PROLOGUE (pScreen, CreateGC);
-
- pPriv = (miSpriteGCPtr)pGC->devPrivates[miSpriteGCIndex].ptr;
-
- ret = (*pScreen->CreateGC) (pGC);
-
- pPriv->wrapOps = NULL;
- pPriv->wrapFuncs = pGC->funcs;
- pGC->funcs = &miSpriteGCFuncs;
-
- SCREEN_EPILOGUE (pScreen, CreateGC, miSpriteCreateGC);
-
- return ret;
-}
-
-static void
-miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
- int i;
- pointer blockData;
- OSTimePtr pTimeout;
- pointer pReadmask;
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- miSpriteScreenPtr pPriv;
-
- pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- SCREEN_PROLOGUE(pScreen, BlockHandler);
-
- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-
- SCREEN_EPILOGUE(pScreen, BlockHandler, miSpriteBlockHandler);
-
- if (!pPriv->isUp && pPriv->shouldBeUp)
- miSpriteRestoreCursor (pScreen);
-}
-
-static void
-miSpriteInstallColormap (pMap)
- ColormapPtr pMap;
-{
- ScreenPtr pScreen = pMap->pScreen;
- miSpriteScreenPtr pPriv;
-
- pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- SCREEN_PROLOGUE(pScreen, InstallColormap);
-
- (*pScreen->InstallColormap) (pMap);
-
- SCREEN_EPILOGUE(pScreen, InstallColormap, miSpriteInstallColormap);
-
- pPriv->pInstalledMap = pMap;
- if (pPriv->pColormap != pMap)
- {
- pPriv->checkPixels = TRUE;
- if (pPriv->isUp)
- miSpriteRemoveCursor (pScreen);
- }
-}
-
-static void
-miSpriteStoreColors (pMap, ndef, pdef)
- ColormapPtr pMap;
- int ndef;
- xColorItem *pdef;
-{
- ScreenPtr pScreen = pMap->pScreen;
- miSpriteScreenPtr pPriv;
- int i;
- int updated;
- VisualPtr pVisual;
-
- pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
-
- SCREEN_PROLOGUE(pScreen, StoreColors);
-
- (*pScreen->StoreColors) (pMap, ndef, pdef);
-
- SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
-
- if (pPriv->pColormap == pMap)
- {
- updated = 0;
- pVisual = pMap->pVisual;
- if (pVisual->class == DirectColor)
- {
- /* Direct color - match on any of the subfields */
-
-#define MaskMatch(a,b,mask) ((a) & (pVisual->mask) == (b) & (pVisual->mask))
-
-#define UpdateDAC(plane,dac,mask) {\
- if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
- pPriv->colors[plane].dac = pdef[i].dac; \
- updated = 1; \
- } \
-}
-
-#define CheckDirect(plane) \
- UpdateDAC(plane,red,redMask) \
- UpdateDAC(plane,green,greenMask) \
- UpdateDAC(plane,blue,blueMask)
-
- for (i = 0; i < ndef; i++)
- {
- CheckDirect (SOURCE_COLOR)
- CheckDirect (MASK_COLOR)
- }
- }
- else
- {
- /* PseudoColor/GrayScale - match on exact pixel */
- for (i = 0; i < ndef; i++)
- {
- if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
- {
- pPriv->colors[SOURCE_COLOR] = pdef[i];
- if (++updated == 2)
- break;
- }
- if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
- {
- pPriv->colors[MASK_COLOR] = pdef[i];
- if (++updated == 2)
- break;
- }
- }
- }
- if (updated)
- {
- pPriv->checkPixels = TRUE;
- if (pPriv->isUp)
- miSpriteRemoveCursor (pScreen);
- }
- }
-}
-
-static void
-miSpriteFindColors (pScreen)
- ScreenPtr pScreen;
-{
- miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
- pScreen->devPrivates[miSpriteScreenIndex].ptr;
- CursorPtr pCursor;
- xColorItem *sourceColor, *maskColor;
-
- pCursor = pScreenPriv->pCursor;
- sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
- maskColor = &pScreenPriv->colors[MASK_COLOR];
- if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
- !(pCursor->foreRed == sourceColor->red &&
- pCursor->foreGreen == sourceColor->green &&
- pCursor->foreBlue == sourceColor->blue &&
- pCursor->backRed == maskColor->red &&
- pCursor->backGreen == maskColor->green &&
- pCursor->backBlue == maskColor->blue))
- {
- pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
- sourceColor->red = pCursor->foreRed;
- sourceColor->green = pCursor->foreGreen;
- sourceColor->blue = pCursor->foreBlue;
- FakeAllocColor (pScreenPriv->pColormap, sourceColor);
- maskColor->red = pCursor->backRed;
- maskColor->green = pCursor->backGreen;
- maskColor->blue = pCursor->backBlue;
- FakeAllocColor (pScreenPriv->pColormap, maskColor);
- /* "free" the pixels right away, don't let this confuse you */
- FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
- FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
- }
- pScreenPriv->checkPixels = FALSE;
-}
-
-/*
- * BackingStore wrappers
- */
-
-static void
-miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
- WindowPtr pWin;
- RegionPtr pObscured;
- int dx, dy;
-{
- ScreenPtr pScreen;
- miSpriteScreenPtr pScreenPriv;
- BoxRec cursorBox;
-
- pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- if (pScreenPriv->isUp)
- {
- cursorBox = pScreenPriv->saved;
-
- if (dx || dy)
- {
- cursorBox.x1 += dx;
- cursorBox.y1 += dy;
- cursorBox.x2 += dx;
- cursorBox.y2 += dy;
- }
- if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
- miSpriteRemoveCursor (pScreen);
- }
-
- (*pScreen->SaveDoomedAreas) (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;
- short x,y;
- unsigned short 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;
- Mask 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 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 (pDraw, font, x, y, n, charinfo, imageblt, w, cursorBox)
- DrawablePtr pDraw;
- FontPtr font;
- int x, 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 (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox)
- DrawablePtr pDraw;
- GCPtr pGC;
- int x,
- 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;
- void (*drawFunc)();
-
- 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:
- drawFunc = (void (*)())pGC->ops->PolyText8;
- break;
- case TT_IMAGE8:
- drawFunc = pGC->ops->ImageText8;
- break;
- case TT_POLY16:
- drawFunc = (void (*)())pGC->ops->PolyText16;
- break;
- case TT_IMAGE16:
- drawFunc = pGC->ops->ImageText16;
- break;
- }
- (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);
-#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.
- */
- drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt;
- (*drawFunc) (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
-
-/*
- * miPointer interface routines
- */
-
-#define SPRITE_PAD 8
-
-static Bool
-miSpriteRealizeCursor (pScreen, pCursor)
- ScreenPtr pScreen;
- CursorPtr pCursor;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- if (pCursor == pScreenPriv->pCursor)
- pScreenPriv->checkPixels = TRUE;
- return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
-}
-
-static Bool
-miSpriteUnrealizeCursor (pScreen, pCursor)
- ScreenPtr pScreen;
- CursorPtr pCursor;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
-}
-
-static void
-miSpriteSetCursor (pScreen, pCursor, x, y)
- ScreenPtr pScreen;
- CursorPtr pCursor;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- pScreenPriv->shouldBeUp = TRUE;
- if (pScreenPriv->x == x &&
- pScreenPriv->y == y &&
- pScreenPriv->pCursor == pCursor &&
- !pScreenPriv->checkPixels)
- {
- return;
- }
- if (!pCursor)
- {
- pScreenPriv->shouldBeUp = FALSE;
- if (pScreenPriv->isUp)
- miSpriteRemoveCursor (pScreen);
- pScreenPriv->pCursor = 0;
- return;
- }
- pScreenPriv->x = x;
- pScreenPriv->y = y;
- pScreenPriv->pCacheWin = NullWindow;
- if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
- {
- pScreenPriv->pCursor = pCursor;
- miSpriteFindColors (pScreen);
- }
- if (pScreenPriv->isUp) {
- int sx, sy;
- /*
- * check to see if the old saved region
- * encloses the new sprite, in which case we use
- * the flicker-free MoveCursor primitive.
- */
- sx = pScreenPriv->x - (int)pCursor->bits->xhot;
- sy = pScreenPriv->y - (int)pCursor->bits->yhot;
- if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
- sx < pScreenPriv->saved.x2 &&
- sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
- sy < pScreenPriv->saved.y2 &&
- (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
- pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
- (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
- pScreenPriv->saved.y2 - pScreenPriv->saved.y1
- )
- {
- pScreenPriv->isUp = FALSE;
- if (!(sx >= pScreenPriv->saved.x1 &&
- sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
- sy >= pScreenPriv->saved.y1 &&
- sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
- {
- int oldx1, oldy1, dx, dy;
-
- oldx1 = pScreenPriv->saved.x1;
- oldy1 = pScreenPriv->saved.y1;
- dx = oldx1 - (sx - SPRITE_PAD);
- dy = oldy1 - (sy - SPRITE_PAD);
- pScreenPriv->saved.x1 -= dx;
- pScreenPriv->saved.y1 -= dy;
- pScreenPriv->saved.x2 -= dx;
- pScreenPriv->saved.y2 -= dy;
- (void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
- pScreenPriv->saved.x1,
- pScreenPriv->saved.y1,
- pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
- pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
- dx, dy);
- }
- (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
- pScreenPriv->saved.x1,
- pScreenPriv->saved.y1,
- pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
- pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
- sx - pScreenPriv->saved.x1,
- sy - pScreenPriv->saved.y1,
- pScreenPriv->colors[SOURCE_COLOR].pixel,
- pScreenPriv->colors[MASK_COLOR].pixel);
- pScreenPriv->isUp = TRUE;
- }
- else
- {
- miSpriteRemoveCursor (pScreen);
- }
- }
- if (!pScreenPriv->isUp && pScreenPriv->pCursor)
- miSpriteRestoreCursor (pScreen);
-}
-
-static void
-miSpriteMoveCursor (pScreen, x, y)
- ScreenPtr pScreen;
- int x, y;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
-}
-
-/*
- * undraw/draw cursor
- */
-
-static void
-miSpriteRemoveCursor (pScreen)
- ScreenPtr pScreen;
-{
- miSpriteScreenPtr pScreenPriv;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- pScreenPriv->isUp = FALSE;
- pScreenPriv->pCacheWin = NullWindow;
- if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
- pScreenPriv->saved.x1,
- pScreenPriv->saved.y1,
- pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
- pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
- {
- pScreenPriv->isUp = TRUE;
- }
-}
-
-/*
- * Called from the block handler, restores the cursor
- * before waiting for something to do.
- */
-
-static void
-miSpriteRestoreCursor (pScreen)
- ScreenPtr pScreen;
-{
- miSpriteScreenPtr pScreenPriv;
- int x, y;
- CursorPtr pCursor;
-
- miSpriteComputeSaved (pScreen);
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- pCursor = pScreenPriv->pCursor;
- x = pScreenPriv->x - (int)pCursor->bits->xhot;
- y = pScreenPriv->y - (int)pCursor->bits->yhot;
- if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
- pScreenPriv->saved.x1,
- pScreenPriv->saved.y1,
- pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
- pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
- {
- if (pScreenPriv->checkPixels)
- miSpriteFindColors (pScreen);
- if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
- pScreenPriv->colors[SOURCE_COLOR].pixel,
- pScreenPriv->colors[MASK_COLOR].pixel))
- pScreenPriv->isUp = TRUE;
- }
-}
-
-/*
- * compute the desired area of the screen to save
- */
-
-static void
-miSpriteComputeSaved (pScreen)
- ScreenPtr pScreen;
-{
- miSpriteScreenPtr pScreenPriv;
- int x, y, w, h;
- int wpad, hpad;
- CursorPtr pCursor;
-
- pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
- pCursor = pScreenPriv->pCursor;
- x = pScreenPriv->x - (int)pCursor->bits->xhot;
- y = pScreenPriv->y - (int)pCursor->bits->yhot;
- w = pCursor->bits->width;
- h = pCursor->bits->height;
- wpad = SPRITE_PAD;
- hpad = SPRITE_PAD;
- pScreenPriv->saved.x1 = x - wpad;
- pScreenPriv->saved.y1 = y - hpad;
- pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
- pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
-}