4 * machine independent software sprite routines
7 /* $XConsortium: misprite.c,v 5.47 94/04/17 20:27:53 dpw Exp $ */
8 /* $XFree86: xc/programs/Xserver/mi/misprite.c,v 3.0 1996/08/25 14:13:56 dawes Exp $ */
12 Copyright (c) 1989 X Consortium
14 Permission is hereby granted, free of charge, to any person obtaining a copy
15 of this software and associated documentation files (the "Software"), to deal
16 in the Software without restriction, including without limitation the rights
17 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 copies of the Software, and to permit persons to whom the Software is
19 furnished to do so, subject to the following conditions:
21 The above copyright notice and this permission notice shall be included in
22 all copies or substantial portions of the Software.
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
28 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 Except as contained in this notice, the name of the X Consortium shall not be
32 used in advertising or otherwise to promote the sale, use or other dealings
33 in this Software without prior written authorization from the X Consortium.
39 # include "pixmapstr.h"
42 # include "cursorstr.h"
44 # include "scrnintstr.h"
45 # include "colormapst.h"
46 # include "windowstr.h"
47 # include "gcstruct.h"
48 # include "mipointer.h"
49 # include "mispritest.h"
50 # include "dixfontstr.h"
51 # include "fontstruct.h"
57 static int miSpriteScreenIndex;
58 static unsigned long miSpriteGeneration = 0;
60 static Bool miSpriteCloseScreen();
61 static void miSpriteGetImage();
62 static void miSpriteGetSpans();
63 static void miSpriteSourceValidate();
64 static Bool miSpriteCreateGC();
65 static void miSpriteBlockHandler();
66 static void miSpriteInstallColormap();
67 static void miSpriteStoreColors();
69 static void miSpritePaintWindowBackground();
70 static void miSpritePaintWindowBorder();
71 static void miSpriteCopyWindow();
72 static void miSpriteClearToBackground();
74 static void miSpriteSaveDoomedAreas();
75 static RegionPtr miSpriteRestoreAreas();
76 static void miSpriteComputeSaved();
78 #define SCREEN_PROLOGUE(pScreen, field)\
80 ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
82 #define SCREEN_EPILOGUE(pScreen, field, wrapper)\
83 ((pScreen)->field = wrapper)
89 static int miSpriteGCIndex;
91 static void miSpriteValidateGC (), miSpriteCopyGC ();
92 static void miSpriteDestroyGC(), miSpriteChangeGC();
93 static void miSpriteChangeClip(), miSpriteDestroyClip();
94 static void miSpriteCopyClip();
96 static GCFuncs miSpriteGCFuncs = {
106 #define GC_FUNC_PROLOGUE(pGC) \
107 miSpriteGCPtr pGCPriv = \
108 (miSpriteGCPtr) (pGC)->devPrivates[miSpriteGCIndex].ptr;\
109 (pGC)->funcs = pGCPriv->wrapFuncs; \
110 if (pGCPriv->wrapOps) \
111 (pGC)->ops = pGCPriv->wrapOps;
113 #define GC_FUNC_EPILOGUE(pGC) \
114 pGCPriv->wrapFuncs = (pGC)->funcs; \
115 (pGC)->funcs = &miSpriteGCFuncs; \
116 if (pGCPriv->wrapOps) \
118 pGCPriv->wrapOps = (pGC)->ops; \
119 (pGC)->ops = &miSpriteGCOps; \
126 static void miSpriteFillSpans(), miSpriteSetSpans();
127 static void miSpritePutImage();
128 static RegionPtr miSpriteCopyArea(), miSpriteCopyPlane();
129 static void miSpritePolyPoint(), miSpritePolylines();
130 static void miSpritePolySegment(), miSpritePolyRectangle();
131 static void miSpritePolyArc(), miSpriteFillPolygon();
132 static void miSpritePolyFillRect(), miSpritePolyFillArc();
133 static int miSpritePolyText8(), miSpritePolyText16();
134 static void miSpriteImageText8(), miSpriteImageText16();
135 static void miSpriteImageGlyphBlt(), miSpritePolyGlyphBlt();
136 static void miSpritePushPixels();
137 #ifdef NEED_LINEHELPER
138 static void miSpriteLineHelper();
141 static GCOps miSpriteGCOps = {
142 miSpriteFillSpans, miSpriteSetSpans, miSpritePutImage,
143 miSpriteCopyArea, miSpriteCopyPlane, miSpritePolyPoint,
144 miSpritePolylines, miSpritePolySegment, miSpritePolyRectangle,
145 miSpritePolyArc, miSpriteFillPolygon, miSpritePolyFillRect,
146 miSpritePolyFillArc, miSpritePolyText8, miSpritePolyText16,
147 miSpriteImageText8, miSpriteImageText16, miSpriteImageGlyphBlt,
148 miSpritePolyGlyphBlt, miSpritePushPixels
149 #ifdef NEED_LINEHELPER
155 * testing only -- remove cursor for every draw. Eventually,
156 * each draw operation will perform a bounding box check against
157 * the saved cursor area
160 #define GC_SETUP_CHEAP(pDrawable) \
161 miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr) \
162 (pDrawable)->pScreen->devPrivates[miSpriteScreenIndex].ptr; \
164 #define GC_SETUP(pDrawable, pGC) \
165 GC_SETUP_CHEAP(pDrawable) \
166 miSpriteGCPtr pGCPrivate = (miSpriteGCPtr) \
167 (pGC)->devPrivates[miSpriteGCIndex].ptr; \
168 GCFuncs *oldFuncs = pGC->funcs;
170 #define GC_SETUP_AND_CHECK(pDrawable, pGC) \
171 GC_SETUP(pDrawable, pGC); \
172 if (GC_CHECK((WindowPtr)pDrawable)) \
173 miSpriteRemoveCursor (pDrawable->pScreen);
175 #define GC_CHECK(pWin) \
176 (pScreenPriv->isUp && \
177 (pScreenPriv->pCacheWin == pWin ? \
178 pScreenPriv->isInCacheWin : ( \
179 (pScreenPriv->pCacheWin = (pWin)), \
180 (pScreenPriv->isInCacheWin = \
181 (pWin)->drawable.x < pScreenPriv->saved.x2 && \
182 pScreenPriv->saved.x1 < (pWin)->drawable.x + \
183 (int) (pWin)->drawable.width && \
184 (pWin)->drawable.y < pScreenPriv->saved.y2 && \
185 pScreenPriv->saved.y1 < (pWin)->drawable.y + \
186 (int) (pWin)->drawable.height &&\
187 RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \
188 &pScreenPriv->saved) != rgnOUT))))
190 #define GC_OP_PROLOGUE(pGC) { \
191 (pGC)->funcs = pGCPrivate->wrapFuncs; \
192 (pGC)->ops = pGCPrivate->wrapOps; \
195 #define GC_OP_EPILOGUE(pGC) { \
196 pGCPrivate->wrapOps = (pGC)->ops; \
197 (pGC)->funcs = oldFuncs; \
198 (pGC)->ops = &miSpriteGCOps; \
202 * pointer-sprite method table
205 static Bool miSpriteRealizeCursor (), miSpriteUnrealizeCursor ();
206 static void miSpriteSetCursor (), miSpriteMoveCursor ();
208 miPointerSpriteFuncRec miSpritePointerFuncs = {
209 miSpriteRealizeCursor,
210 miSpriteUnrealizeCursor,
216 * other misc functions
219 static void miSpriteRemoveCursor (), miSpriteRestoreCursor();
222 * miSpriteInitialize -- called from device-dependent screen
223 * initialization proc after all of the function pointers have
224 * been stored in the screen structure.
228 miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
230 miSpriteCursorFuncPtr cursorFuncs;
231 miPointerScreenFuncPtr screenFuncs;
233 miSpriteScreenPtr pPriv;
236 if (miSpriteGeneration != serverGeneration)
238 miSpriteScreenIndex = AllocateScreenPrivateIndex ();
239 if (miSpriteScreenIndex < 0)
241 miSpriteGeneration = serverGeneration;
242 miSpriteGCIndex = AllocateGCPrivateIndex ();
244 if (!AllocateGCPrivate(pScreen, miSpriteGCIndex, sizeof(miSpriteGCRec)))
246 pPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec));
249 if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
251 xfree ((pointer) pPriv);
254 for (pVisual = pScreen->visuals;
255 pVisual->vid != pScreen->rootVisual;
258 pPriv->pVisual = pVisual;
259 pPriv->CloseScreen = pScreen->CloseScreen;
260 pPriv->GetImage = pScreen->GetImage;
261 pPriv->GetSpans = pScreen->GetSpans;
262 pPriv->SourceValidate = pScreen->SourceValidate;
263 pPriv->CreateGC = pScreen->CreateGC;
264 pPriv->BlockHandler = pScreen->BlockHandler;
265 pPriv->InstallColormap = pScreen->InstallColormap;
266 pPriv->StoreColors = pScreen->StoreColors;
268 pPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
269 pPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
270 pPriv->CopyWindow = pScreen->CopyWindow;
271 pPriv->ClearToBackground = pScreen->ClearToBackground;
273 pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
274 pPriv->RestoreAreas = pScreen->RestoreAreas;
276 pPriv->pCursor = NULL;
280 pPriv->shouldBeUp = FALSE;
281 pPriv->pCacheWin = NullWindow;
282 pPriv->isInCacheWin = FALSE;
283 pPriv->checkPixels = TRUE;
284 pPriv->pInstalledMap = NULL;
285 pPriv->pColormap = NULL;
286 pPriv->funcs = cursorFuncs;
287 pPriv->colors[SOURCE_COLOR].red = 0;
288 pPriv->colors[SOURCE_COLOR].green = 0;
289 pPriv->colors[SOURCE_COLOR].blue = 0;
290 pPriv->colors[MASK_COLOR].red = 0;
291 pPriv->colors[MASK_COLOR].green = 0;
292 pPriv->colors[MASK_COLOR].blue = 0;
293 pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pPriv;
294 pScreen->CloseScreen = miSpriteCloseScreen;
295 pScreen->GetImage = miSpriteGetImage;
296 pScreen->GetSpans = miSpriteGetSpans;
297 pScreen->SourceValidate = miSpriteSourceValidate;
298 pScreen->CreateGC = miSpriteCreateGC;
299 pScreen->BlockHandler = miSpriteBlockHandler;
300 pScreen->InstallColormap = miSpriteInstallColormap;
301 pScreen->StoreColors = miSpriteStoreColors;
303 pScreen->PaintWindowBackground = miSpritePaintWindowBackground;
304 pScreen->PaintWindowBorder = miSpritePaintWindowBorder;
305 pScreen->CopyWindow = miSpriteCopyWindow;
306 pScreen->ClearToBackground = miSpriteClearToBackground;
308 pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas;
309 pScreen->RestoreAreas = miSpriteRestoreAreas;
319 * CloseScreen wrapper -- unwrap everything, free the private data
320 * and call the wrapped function
324 miSpriteCloseScreen (i, pScreen)
327 miSpriteScreenPtr pScreenPriv;
329 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
331 pScreen->CloseScreen = pScreenPriv->CloseScreen;
332 pScreen->GetImage = pScreenPriv->GetImage;
333 pScreen->GetSpans = pScreenPriv->GetSpans;
334 pScreen->SourceValidate = pScreenPriv->SourceValidate;
335 pScreen->CreateGC = pScreenPriv->CreateGC;
336 pScreen->BlockHandler = pScreenPriv->BlockHandler;
337 pScreen->InstallColormap = pScreenPriv->InstallColormap;
338 pScreen->StoreColors = pScreenPriv->StoreColors;
340 pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
341 pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
342 pScreen->CopyWindow = pScreenPriv->CopyWindow;
343 pScreen->ClearToBackground = pScreenPriv->ClearToBackground;
345 pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
346 pScreen->RestoreAreas = pScreenPriv->RestoreAreas;
348 xfree ((pointer) pScreenPriv);
350 return (*pScreen->CloseScreen) (i, pScreen);
354 miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
355 DrawablePtr pDrawable;
358 unsigned long planemask;
361 ScreenPtr pScreen = pDrawable->pScreen;
362 miSpriteScreenPtr pScreenPriv;
364 SCREEN_PROLOGUE (pScreen, GetImage);
366 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
368 if (pDrawable->type == DRAWABLE_WINDOW &&
370 ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
372 miSpriteRemoveCursor (pScreen);
375 (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
376 format, planemask, pdstLine);
378 SCREEN_EPILOGUE (pScreen, GetImage, miSpriteGetImage);
382 miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
383 DrawablePtr pDrawable;
390 ScreenPtr pScreen = pDrawable->pScreen;
391 miSpriteScreenPtr pScreenPriv;
393 SCREEN_PROLOGUE (pScreen, GetSpans);
395 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
397 if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
399 register DDXPointPtr pts;
400 register int *widths;
408 for (pts = ppt, widths = pwidth, nPts = nspans;
412 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
413 pts->x+xorg,*widths))
415 miSpriteRemoveCursor (pScreen);
421 (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
423 SCREEN_EPILOGUE (pScreen, GetSpans, miSpriteGetSpans);
427 miSpriteSourceValidate (pDrawable, x, y, width, height)
428 DrawablePtr pDrawable;
429 int x, y, width, height;
431 ScreenPtr pScreen = pDrawable->pScreen;
432 miSpriteScreenPtr pScreenPriv;
434 SCREEN_PROLOGUE (pScreen, SourceValidate);
436 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
438 if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
439 ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
440 x, y, width, height))
442 miSpriteRemoveCursor (pScreen);
445 if (pScreen->SourceValidate)
446 (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
448 SCREEN_EPILOGUE (pScreen, SourceValidate, miSpriteSourceValidate);
452 miSpriteCreateGC (pGC)
455 ScreenPtr pScreen = pGC->pScreen;
459 SCREEN_PROLOGUE (pScreen, CreateGC);
461 pPriv = (miSpriteGCPtr)pGC->devPrivates[miSpriteGCIndex].ptr;
463 ret = (*pScreen->CreateGC) (pGC);
465 pPriv->wrapOps = NULL;
466 pPriv->wrapFuncs = pGC->funcs;
467 pGC->funcs = &miSpriteGCFuncs;
469 SCREEN_EPILOGUE (pScreen, CreateGC, miSpriteCreateGC);
475 miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
481 ScreenPtr pScreen = screenInfo.screens[i];
482 miSpriteScreenPtr pPriv;
484 pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
486 SCREEN_PROLOGUE(pScreen, BlockHandler);
488 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
490 SCREEN_EPILOGUE(pScreen, BlockHandler, miSpriteBlockHandler);
492 if (!pPriv->isUp && pPriv->shouldBeUp)
493 miSpriteRestoreCursor (pScreen);
497 miSpriteInstallColormap (pMap)
500 ScreenPtr pScreen = pMap->pScreen;
501 miSpriteScreenPtr pPriv;
503 pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
505 SCREEN_PROLOGUE(pScreen, InstallColormap);
507 (*pScreen->InstallColormap) (pMap);
509 SCREEN_EPILOGUE(pScreen, InstallColormap, miSpriteInstallColormap);
511 pPriv->pInstalledMap = pMap;
512 if (pPriv->pColormap != pMap)
514 pPriv->checkPixels = TRUE;
516 miSpriteRemoveCursor (pScreen);
521 miSpriteStoreColors (pMap, ndef, pdef)
526 ScreenPtr pScreen = pMap->pScreen;
527 miSpriteScreenPtr pPriv;
532 pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
534 SCREEN_PROLOGUE(pScreen, StoreColors);
536 (*pScreen->StoreColors) (pMap, ndef, pdef);
538 SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
540 if (pPriv->pColormap == pMap)
543 pVisual = pMap->pVisual;
544 if (pVisual->class == DirectColor)
546 /* Direct color - match on any of the subfields */
548 #define MaskMatch(a,b,mask) ((a) & (pVisual->mask) == (b) & (pVisual->mask))
550 #define UpdateDAC(plane,dac,mask) {\
551 if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
552 pPriv->colors[plane].dac = pdef[i].dac; \
557 #define CheckDirect(plane) \
558 UpdateDAC(plane,red,redMask) \
559 UpdateDAC(plane,green,greenMask) \
560 UpdateDAC(plane,blue,blueMask)
562 for (i = 0; i < ndef; i++)
564 CheckDirect (SOURCE_COLOR)
565 CheckDirect (MASK_COLOR)
570 /* PseudoColor/GrayScale - match on exact pixel */
571 for (i = 0; i < ndef; i++)
573 if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
575 pPriv->colors[SOURCE_COLOR] = pdef[i];
579 if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
581 pPriv->colors[MASK_COLOR] = pdef[i];
589 pPriv->checkPixels = TRUE;
591 miSpriteRemoveCursor (pScreen);
597 miSpriteFindColors (pScreen)
600 miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
601 pScreen->devPrivates[miSpriteScreenIndex].ptr;
603 xColorItem *sourceColor, *maskColor;
605 pCursor = pScreenPriv->pCursor;
606 sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
607 maskColor = &pScreenPriv->colors[MASK_COLOR];
608 if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
609 !(pCursor->foreRed == sourceColor->red &&
610 pCursor->foreGreen == sourceColor->green &&
611 pCursor->foreBlue == sourceColor->blue &&
612 pCursor->backRed == maskColor->red &&
613 pCursor->backGreen == maskColor->green &&
614 pCursor->backBlue == maskColor->blue))
616 pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
617 sourceColor->red = pCursor->foreRed;
618 sourceColor->green = pCursor->foreGreen;
619 sourceColor->blue = pCursor->foreBlue;
620 FakeAllocColor (pScreenPriv->pColormap, sourceColor);
621 maskColor->red = pCursor->backRed;
622 maskColor->green = pCursor->backGreen;
623 maskColor->blue = pCursor->backBlue;
624 FakeAllocColor (pScreenPriv->pColormap, maskColor);
625 /* "free" the pixels right away, don't let this confuse you */
626 FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
627 FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
629 pScreenPriv->checkPixels = FALSE;
633 * BackingStore wrappers
637 miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
643 miSpriteScreenPtr pScreenPriv;
646 pScreen = pWin->drawable.pScreen;
648 SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
650 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
651 if (pScreenPriv->isUp)
653 cursorBox = pScreenPriv->saved;
662 if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
663 miSpriteRemoveCursor (pScreen);
666 (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
668 SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, miSpriteSaveDoomedAreas);
672 miSpriteRestoreAreas (pWin, prgnExposed)
674 RegionPtr prgnExposed;
677 miSpriteScreenPtr pScreenPriv;
680 pScreen = pWin->drawable.pScreen;
682 SCREEN_PROLOGUE (pScreen, RestoreAreas);
684 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
685 if (pScreenPriv->isUp)
687 if (RECT_IN_REGION( pScreen, prgnExposed, &pScreenPriv->saved) != rgnOUT)
688 miSpriteRemoveCursor (pScreen);
691 result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
693 SCREEN_EPILOGUE (pScreen, RestoreAreas, miSpriteRestoreAreas);
703 miSpritePaintWindowBackground (pWin, pRegion, what)
709 miSpriteScreenPtr pScreenPriv;
711 pScreen = pWin->drawable.pScreen;
713 SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
715 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
716 if (pScreenPriv->isUp)
719 * If the cursor is on the same screen as the window, check the
720 * region to paint for the cursor and remove it as necessary
722 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
723 miSpriteRemoveCursor (pScreen);
726 (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
728 SCREEN_EPILOGUE (pScreen, PaintWindowBackground, miSpritePaintWindowBackground);
732 miSpritePaintWindowBorder (pWin, pRegion, what)
738 miSpriteScreenPtr pScreenPriv;
740 pScreen = pWin->drawable.pScreen;
742 SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
744 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
745 if (pScreenPriv->isUp)
748 * If the cursor is on the same screen as the window, check the
749 * region to paint for the cursor and remove it as necessary
751 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
752 miSpriteRemoveCursor (pScreen);
755 (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
757 SCREEN_EPILOGUE (pScreen, PaintWindowBorder, miSpritePaintWindowBorder);
761 miSpriteCopyWindow (pWin, ptOldOrg, pRegion)
763 DDXPointRec ptOldOrg;
767 miSpriteScreenPtr pScreenPriv;
771 pScreen = pWin->drawable.pScreen;
773 SCREEN_PROLOGUE (pScreen, CopyWindow);
775 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
776 if (pScreenPriv->isUp)
779 * check both the source and the destination areas. The given
780 * region is source relative, so offset the cursor box by
783 cursorBox = pScreenPriv->saved;
784 dx = pWin->drawable.x - ptOldOrg.x;
785 dy = pWin->drawable.y - ptOldOrg.y;
790 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT ||
791 RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT)
792 miSpriteRemoveCursor (pScreen);
795 (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion);
797 SCREEN_EPILOGUE (pScreen, CopyWindow, miSpriteCopyWindow);
801 miSpriteClearToBackground (pWin, x, y, w, h, generateExposures)
805 Bool generateExposures;
808 miSpriteScreenPtr pScreenPriv;
811 pScreen = pWin->drawable.pScreen;
813 SCREEN_PROLOGUE (pScreen, ClearToBackground);
815 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
819 realw = (int) pWin->drawable.width - x;
821 realh = (int) pWin->drawable.height - y;
822 if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y,
825 miSpriteRemoveCursor (pScreen);
829 (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
831 SCREEN_EPILOGUE (pScreen, ClearToBackground, miSpriteClearToBackground);
839 miSpriteValidateGC (pGC, changes, pDrawable)
842 DrawablePtr pDrawable;
844 GC_FUNC_PROLOGUE (pGC);
846 (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
848 pGCPriv->wrapOps = NULL;
849 if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable)
854 pWin = (WindowPtr) pDrawable;
855 pRegion = &pWin->clipList;
856 if (pGC->subWindowMode == IncludeInferiors)
857 pRegion = &pWin->borderClip;
858 if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion))
859 pGCPriv->wrapOps = pGC->ops;
862 GC_FUNC_EPILOGUE (pGC);
866 miSpriteChangeGC (pGC, mask)
870 GC_FUNC_PROLOGUE (pGC);
872 (*pGC->funcs->ChangeGC) (pGC, mask);
874 GC_FUNC_EPILOGUE (pGC);
878 miSpriteCopyGC (pGCSrc, mask, pGCDst)
879 GCPtr pGCSrc, pGCDst;
882 GC_FUNC_PROLOGUE (pGCDst);
884 (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
886 GC_FUNC_EPILOGUE (pGCDst);
890 miSpriteDestroyGC (pGC)
893 GC_FUNC_PROLOGUE (pGC);
895 (*pGC->funcs->DestroyGC) (pGC);
897 GC_FUNC_EPILOGUE (pGC);
901 miSpriteChangeClip (pGC, type, pvalue, nrects)
907 GC_FUNC_PROLOGUE (pGC);
909 (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
911 GC_FUNC_EPILOGUE (pGC);
915 miSpriteCopyClip(pgcDst, pgcSrc)
916 GCPtr pgcDst, pgcSrc;
918 GC_FUNC_PROLOGUE (pgcDst);
920 (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
922 GC_FUNC_EPILOGUE (pgcDst);
926 miSpriteDestroyClip(pGC)
929 GC_FUNC_PROLOGUE (pGC);
931 (* pGC->funcs->DestroyClip)(pGC);
933 GC_FUNC_EPILOGUE (pGC);
941 miSpriteFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
942 DrawablePtr pDrawable;
944 int nInit; /* number of spans to fill */
945 DDXPointPtr pptInit; /* pointer to list of start points */
946 int *pwidthInit; /* pointer to list of n widths */
949 GC_SETUP(pDrawable, pGC);
951 if (GC_CHECK((WindowPtr) pDrawable))
953 register DDXPointPtr pts;
954 register int *widths;
957 for (pts = pptInit, widths = pwidthInit, nPts = nInit;
961 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
963 miSpriteRemoveCursor (pDrawable->pScreen);
969 GC_OP_PROLOGUE (pGC);
971 (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
973 GC_OP_EPILOGUE (pGC);
977 miSpriteSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
978 DrawablePtr pDrawable;
981 register DDXPointPtr ppt;
986 GC_SETUP(pDrawable, pGC);
988 if (GC_CHECK((WindowPtr) pDrawable))
990 register DDXPointPtr pts;
991 register int *widths;
994 for (pts = ppt, widths = pwidth, nPts = nspans;
998 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
1000 miSpriteRemoveCursor(pDrawable->pScreen);
1006 GC_OP_PROLOGUE (pGC);
1008 (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
1010 GC_OP_EPILOGUE (pGC);
1014 miSpritePutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
1015 DrawablePtr pDrawable;
1025 GC_SETUP(pDrawable, pGC);
1027 if (GC_CHECK((WindowPtr) pDrawable))
1029 if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,
1032 miSpriteRemoveCursor (pDrawable->pScreen);
1036 GC_OP_PROLOGUE (pGC);
1038 (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits);
1040 GC_OP_EPILOGUE (pGC);
1044 miSpriteCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
1057 GC_SETUP(pDst, pGC);
1059 /* check destination/source overlap. */
1060 if (GC_CHECK((WindowPtr) pDst) &&
1061 (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1063 ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1065 miSpriteRemoveCursor (pDst->pScreen);
1068 GC_OP_PROLOGUE (pGC);
1070 rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
1073 GC_OP_EPILOGUE (pGC);
1079 miSpriteCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
1089 unsigned long plane;
1093 GC_SETUP(pDst, pGC);
1096 * check destination/source for overlap.
1098 if (GC_CHECK((WindowPtr) pDst) &&
1099 (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1101 ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1103 miSpriteRemoveCursor (pDst->pScreen);
1106 GC_OP_PROLOGUE (pGC);
1108 rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
1111 GC_OP_EPILOGUE (pGC);
1117 miSpritePolyPoint (pDrawable, pGC, mode, npt, pptInit)
1118 DrawablePtr pDrawable;
1120 int mode; /* Origin or Previous */
1127 register xPoint *pts;
1129 GC_SETUP (pDrawable, pGC);
1131 if (npt && GC_CHECK((WindowPtr) pDrawable))
1133 cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x;
1134 cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y;
1135 cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x;
1136 cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y;
1138 if (mode == CoordModePrevious)
1142 for (pts = pptInit, n = npt; n--; pts++)
1146 if (cursor.x1 <= t.x && t.x <= cursor.x2 &&
1147 cursor.y1 <= t.y && t.y <= cursor.y2)
1149 miSpriteRemoveCursor (pDrawable->pScreen);
1156 for (pts = pptInit, n = npt; n--; pts++)
1158 if (cursor.x1 <= pts->x && pts->x <= cursor.x2 &&
1159 cursor.y1 <= pts->y && pts->y <= cursor.y2)
1161 miSpriteRemoveCursor (pDrawable->pScreen);
1168 GC_OP_PROLOGUE (pGC);
1170 (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
1172 GC_OP_EPILOGUE (pGC);
1176 miSpritePolylines (pDrawable, pGC, mode, npt, pptInit)
1177 DrawablePtr pDrawable;
1181 DDXPointPtr pptInit;
1184 register DDXPointPtr pts;
1186 int x, y, x1, y1, x2, y2;
1190 GC_SETUP (pDrawable, pGC);
1192 if (npt && GC_CHECK((WindowPtr) pDrawable))
1194 cursor = &pScreenPriv->saved;
1195 lw = pGC->lineWidth;
1196 x = pptInit->x + pDrawable->x;
1197 y = pptInit->y + pDrawable->y;
1202 if (LINE_OVERLAP(cursor, x, y, x, y, extra))
1203 miSpriteRemoveCursor (pDrawable->pScreen);
1209 * mitered joins can project quite a way from
1210 * the line end; the 11 degree miter limit limits
1211 * this extension to 10.43 * lw / 2, rounded up
1212 * and converted to int yields 6 * lw
1214 if (pGC->joinStyle == JoinMiter)
1216 else if (pGC->capStyle == CapProjecting)
1218 for (pts = pptInit + 1, n = npt - 1; n--; pts++)
1222 if (mode == CoordModeOrigin)
1224 x2 = pDrawable->x + pts->x;
1225 y2 = pDrawable->y + pts->y;
1234 LINE_SORT(x1, y1, x2, y2);
1235 if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1237 miSpriteRemoveCursor (pDrawable->pScreen);
1243 GC_OP_PROLOGUE (pGC);
1245 (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit);
1247 GC_OP_EPILOGUE (pGC);
1251 miSpritePolySegment(pDrawable, pGC, nseg, pSegs)
1252 DrawablePtr pDrawable;
1258 register xSegment *segs;
1263 GC_SETUP(pDrawable, pGC);
1265 if (nseg && GC_CHECK((WindowPtr) pDrawable))
1267 cursor = &pScreenPriv->saved;
1268 extra = pGC->lineWidth >> 1;
1269 if (pGC->capStyle == CapProjecting)
1270 extra = pGC->lineWidth;
1271 for (segs = pSegs, n = nseg; n--; segs++)
1273 x1 = segs->x1 + pDrawable->x;
1274 y1 = segs->y1 + pDrawable->y;
1275 x2 = segs->x2 + pDrawable->x;
1276 y2 = segs->y2 + pDrawable->y;
1277 LINE_SORT(x1, y1, x2, y2);
1278 if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1280 miSpriteRemoveCursor (pDrawable->pScreen);
1286 GC_OP_PROLOGUE (pGC);
1288 (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs);
1290 GC_OP_EPILOGUE (pGC);
1294 miSpritePolyRectangle(pDrawable, pGC, nrects, pRects)
1295 DrawablePtr pDrawable;
1300 register xRectangle *rects;
1306 GC_SETUP (pDrawable, pGC);
1308 if (GC_CHECK((WindowPtr) pDrawable))
1310 lw = pGC->lineWidth >> 1;
1311 cursor = &pScreenPriv->saved;
1312 for (rects = pRects, n = nrects; n--; rects++)
1314 x1 = rects->x + pDrawable->x;
1315 y1 = rects->y + pDrawable->y;
1316 x2 = x1 + (int)rects->width;
1317 y2 = y1 + (int)rects->height;
1318 if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) ||
1319 LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) ||
1320 LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) ||
1321 LINE_OVERLAP(cursor, x1, y1, x1, y2, lw))
1323 miSpriteRemoveCursor (pDrawable->pScreen);
1329 GC_OP_PROLOGUE (pGC);
1331 (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects);
1333 GC_OP_EPILOGUE (pGC);
1337 miSpritePolyArc(pDrawable, pGC, narcs, parcs)
1338 DrawablePtr pDrawable;
1346 register xArc *arcs;
1348 GC_SETUP (pDrawable, pGC);
1350 if (GC_CHECK((WindowPtr) pDrawable))
1352 lw = pGC->lineWidth >> 1;
1353 cursor = &pScreenPriv->saved;
1354 for (arcs = parcs, n = narcs; n--; arcs++)
1356 if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y,
1357 arcs->x - lw, arcs->y - lw,
1358 (int) arcs->width + pGC->lineWidth,
1359 (int) arcs->height + pGC->lineWidth))
1361 miSpriteRemoveCursor (pDrawable->pScreen);
1367 GC_OP_PROLOGUE (pGC);
1369 (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs);
1371 GC_OP_EPILOGUE (pGC);
1375 miSpriteFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
1376 register DrawablePtr pDrawable;
1382 int x, y, minx, miny, maxx, maxy;
1383 register DDXPointPtr pts;
1386 GC_SETUP (pDrawable, pGC);
1388 if (count && GC_CHECK((WindowPtr) pDrawable))
1393 minx = maxx = pts->x;
1394 miny = maxy = pts->y;
1398 if (mode == CoordModeOrigin)
1404 else if (pts->x > maxx)
1408 else if (pts->y > maxy)
1436 if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy))
1437 miSpriteRemoveCursor (pDrawable->pScreen);
1440 GC_OP_PROLOGUE (pGC);
1442 (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts);
1444 GC_OP_EPILOGUE (pGC);
1448 miSpritePolyFillRect(pDrawable, pGC, nrectFill, prectInit)
1449 DrawablePtr pDrawable;
1451 int nrectFill; /* number of rectangles to fill */
1452 xRectangle *prectInit; /* Pointer to first rectangle to fill */
1454 GC_SETUP(pDrawable, pGC);
1456 if (GC_CHECK((WindowPtr) pDrawable))
1459 register xRectangle *pRect;
1460 register int xorg, yorg;
1462 xorg = pDrawable->x;
1463 yorg = pDrawable->y;
1465 for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) {
1466 if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){
1467 miSpriteRemoveCursor(pDrawable->pScreen);
1473 GC_OP_PROLOGUE (pGC);
1475 (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit);
1477 GC_OP_EPILOGUE (pGC);
1481 miSpritePolyFillArc(pDrawable, pGC, narcs, parcs)
1482 DrawablePtr pDrawable;
1487 GC_SETUP(pDrawable, pGC);
1489 if (GC_CHECK((WindowPtr) pDrawable))
1493 register xArc *arcs;
1495 cursor = &pScreenPriv->saved;
1497 for (arcs = parcs, n = narcs; n--; arcs++)
1499 if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y,
1501 (int) arcs->width, (int) arcs->height))
1503 miSpriteRemoveCursor (pDrawable->pScreen);
1509 GC_OP_PROLOGUE (pGC);
1511 (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs);
1513 GC_OP_EPILOGUE (pGC);
1517 * general Poly/Image text function. Extract glyph information,
1518 * compute bounding box and remove cursor if it is overlapped.
1522 miSpriteTextOverlap (pDraw, font, x, y, n, charinfo, imageblt, w, cursorBox)
1527 CharInfoPtr *charinfo;
1532 ExtentInfoRec extents;
1537 if (FONTMINBOUNDS(font,characterWidth) >= 0)
1539 /* compute an approximate (but covering) bounding box */
1540 if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0))
1541 extents.overallLeft = charinfo[0]->metrics.leftSideBearing;
1543 extents.overallLeft = 0;
1545 extents.overallRight = w - charinfo[n-1]->metrics.characterWidth;
1547 extents.overallRight = FONTMAXBOUNDS(font,characterWidth)
1549 if (imageblt && (charinfo[n-1]->metrics.characterWidth >
1550 charinfo[n-1]->metrics.rightSideBearing))
1551 extents.overallRight += charinfo[n-1]->metrics.characterWidth;
1553 extents.overallRight += charinfo[n-1]->metrics.rightSideBearing;
1554 if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
1555 extents.overallAscent = FONTASCENT(font);
1557 extents.overallAscent = FONTMAXBOUNDS(font, ascent);
1558 if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
1559 extents.overallDescent = FONTDESCENT(font);
1561 extents.overallDescent = FONTMAXBOUNDS(font,descent);
1562 if (!BOX_OVERLAP(cursorBox,
1563 x + extents.overallLeft,
1564 y - extents.overallAscent,
1565 x + extents.overallRight,
1566 y + extents.overallDescent))
1568 else if (imageblt && w)
1570 /* if it does overlap, fall through and compute exactly, because
1571 * taking down the cursor is expensive enough to make this worth it
1574 QueryGlyphExtents(font, charinfo, n, &extents);
1577 if (extents.overallWidth > extents.overallRight)
1578 extents.overallRight = extents.overallWidth;
1579 if (extents.overallWidth < extents.overallLeft)
1580 extents.overallLeft = extents.overallWidth;
1581 if (extents.overallLeft > 0)
1582 extents.overallLeft = 0;
1583 if (extents.fontAscent > extents.overallAscent)
1584 extents.overallAscent = extents.fontAscent;
1585 if (extents.fontDescent > extents.overallDescent)
1586 extents.overallDescent = extents.fontDescent;
1588 return (BOX_OVERLAP(cursorBox,
1589 x + extents.overallLeft,
1590 y - extents.overallAscent,
1591 x + extents.overallRight,
1592 y + extents.overallDescent));
1596 * values for textType:
1601 #define TT_IMAGE16 3
1604 miSpriteText (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox)
1609 unsigned long count;
1611 FontEncoding fontEncoding;
1615 CharInfoPtr *charinfo;
1616 register CharInfoPtr *info;
1624 imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
1626 charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
1630 GetGlyphs(pGC->font, count, (unsigned char *)chars,
1631 fontEncoding, &i, charinfo);
1632 n = (unsigned int)i;
1635 for (info = charinfo; i--; info++)
1636 w += (*info)->metrics.characterWidth;
1639 if (miSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox))
1640 miSpriteRemoveCursor(pDraw->pScreen);
1642 #ifdef AVOID_GLYPHBLT
1644 * On displays like Apollos, which do not optimize the GlyphBlt functions because they
1645 * convert fonts to their internal form in RealizeFont and optimize text directly, we
1646 * want to invoke the text functions here, not the GlyphBlt functions.
1651 drawFunc = (void (*)())pGC->ops->PolyText8;
1654 drawFunc = pGC->ops->ImageText8;
1657 drawFunc = (void (*)())pGC->ops->PolyText16;
1660 drawFunc = pGC->ops->ImageText16;
1663 (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);
1664 #else /* don't AVOID_GLYPHBLT */
1666 * On the other hand, if the device does use GlyphBlt ultimately to do text, we
1667 * don't want to slow it down by invoking the text functions and having them call
1668 * GetGlyphs all over again, so we go directly to the GlyphBlt functions here.
1670 drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt;
1671 (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
1672 #endif /* AVOID_GLYPHBLT */
1674 DEALLOCATE_LOCAL(charinfo);
1679 miSpritePolyText8(pDrawable, pGC, x, y, count, chars)
1680 DrawablePtr pDrawable;
1688 GC_SETUP (pDrawable, pGC);
1690 GC_OP_PROLOGUE (pGC);
1692 if (GC_CHECK((WindowPtr) pDrawable))
1693 ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars,
1694 Linear8Bit, TT_POLY8, &pScreenPriv->saved);
1696 ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
1698 GC_OP_EPILOGUE (pGC);
1703 miSpritePolyText16(pDrawable, pGC, x, y, count, chars)
1704 DrawablePtr pDrawable;
1708 unsigned short *chars;
1712 GC_SETUP(pDrawable, pGC);
1714 GC_OP_PROLOGUE (pGC);
1716 if (GC_CHECK((WindowPtr) pDrawable))
1717 ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1719 FONTLASTROW(pGC->font) == 0 ?
1720 Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved);
1722 ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
1724 GC_OP_EPILOGUE (pGC);
1729 miSpriteImageText8(pDrawable, pGC, x, y, count, chars)
1730 DrawablePtr pDrawable;
1736 GC_SETUP(pDrawable, pGC);
1738 GC_OP_PROLOGUE (pGC);
1740 if (GC_CHECK((WindowPtr) pDrawable))
1741 (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1742 chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved);
1744 (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
1746 GC_OP_EPILOGUE (pGC);
1750 miSpriteImageText16(pDrawable, pGC, x, y, count, chars)
1751 DrawablePtr pDrawable;
1755 unsigned short *chars;
1757 GC_SETUP(pDrawable, pGC);
1759 GC_OP_PROLOGUE (pGC);
1761 if (GC_CHECK((WindowPtr) pDrawable))
1762 (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1764 FONTLASTROW(pGC->font) == 0 ?
1765 Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved);
1767 (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
1769 GC_OP_EPILOGUE (pGC);
1773 miSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1774 DrawablePtr pDrawable;
1777 unsigned int nglyph;
1778 CharInfoPtr *ppci; /* array of character info */
1779 pointer pglyphBase; /* start of array of glyphs */
1781 GC_SETUP(pDrawable, pGC);
1783 GC_OP_PROLOGUE (pGC);
1785 if (GC_CHECK((WindowPtr) pDrawable) &&
1786 miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved))
1788 miSpriteRemoveCursor(pDrawable->pScreen);
1790 (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1792 GC_OP_EPILOGUE (pGC);
1796 miSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1797 DrawablePtr pDrawable;
1800 unsigned int nglyph;
1801 CharInfoPtr *ppci; /* array of character info */
1802 pointer pglyphBase; /* start of array of glyphs */
1804 GC_SETUP (pDrawable, pGC);
1806 GC_OP_PROLOGUE (pGC);
1808 if (GC_CHECK((WindowPtr) pDrawable) &&
1809 miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved))
1811 miSpriteRemoveCursor(pDrawable->pScreen);
1813 (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1815 GC_OP_EPILOGUE (pGC);
1819 miSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y)
1822 DrawablePtr pDrawable;
1825 GC_SETUP(pDrawable, pGC);
1827 if (GC_CHECK((WindowPtr) pDrawable) &&
1828 ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h))
1830 miSpriteRemoveCursor (pDrawable->pScreen);
1833 GC_OP_PROLOGUE (pGC);
1835 (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
1837 GC_OP_EPILOGUE (pGC);
1840 #ifdef NEED_LINEHELPER
1842 * I don't expect this routine will ever be called, as the GC
1843 * will have been unwrapped for the line drawing
1847 miSpriteLineHelper()
1849 FatalError("miSpriteLineHelper called\n");
1854 * miPointer interface routines
1857 #define SPRITE_PAD 8
1860 miSpriteRealizeCursor (pScreen, pCursor)
1864 miSpriteScreenPtr pScreenPriv;
1866 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
1867 if (pCursor == pScreenPriv->pCursor)
1868 pScreenPriv->checkPixels = TRUE;
1869 return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
1873 miSpriteUnrealizeCursor (pScreen, pCursor)
1877 miSpriteScreenPtr pScreenPriv;
1879 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
1880 return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
1884 miSpriteSetCursor (pScreen, pCursor, x, y)
1888 miSpriteScreenPtr pScreenPriv;
1890 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
1891 pScreenPriv->shouldBeUp = TRUE;
1892 if (pScreenPriv->x == x &&
1893 pScreenPriv->y == y &&
1894 pScreenPriv->pCursor == pCursor &&
1895 !pScreenPriv->checkPixels)
1901 pScreenPriv->shouldBeUp = FALSE;
1902 if (pScreenPriv->isUp)
1903 miSpriteRemoveCursor (pScreen);
1904 pScreenPriv->pCursor = 0;
1909 pScreenPriv->pCacheWin = NullWindow;
1910 if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
1912 pScreenPriv->pCursor = pCursor;
1913 miSpriteFindColors (pScreen);
1915 if (pScreenPriv->isUp) {
1918 * check to see if the old saved region
1919 * encloses the new sprite, in which case we use
1920 * the flicker-free MoveCursor primitive.
1922 sx = pScreenPriv->x - (int)pCursor->bits->xhot;
1923 sy = pScreenPriv->y - (int)pCursor->bits->yhot;
1924 if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
1925 sx < pScreenPriv->saved.x2 &&
1926 sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
1927 sy < pScreenPriv->saved.y2 &&
1928 (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
1929 pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
1930 (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
1931 pScreenPriv->saved.y2 - pScreenPriv->saved.y1
1934 pScreenPriv->isUp = FALSE;
1935 if (!(sx >= pScreenPriv->saved.x1 &&
1936 sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
1937 sy >= pScreenPriv->saved.y1 &&
1938 sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
1940 int oldx1, oldy1, dx, dy;
1942 oldx1 = pScreenPriv->saved.x1;
1943 oldy1 = pScreenPriv->saved.y1;
1944 dx = oldx1 - (sx - SPRITE_PAD);
1945 dy = oldy1 - (sy - SPRITE_PAD);
1946 pScreenPriv->saved.x1 -= dx;
1947 pScreenPriv->saved.y1 -= dy;
1948 pScreenPriv->saved.x2 -= dx;
1949 pScreenPriv->saved.y2 -= dy;
1950 (void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
1951 pScreenPriv->saved.x1,
1952 pScreenPriv->saved.y1,
1953 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
1954 pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
1957 (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
1958 pScreenPriv->saved.x1,
1959 pScreenPriv->saved.y1,
1960 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
1961 pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
1962 sx - pScreenPriv->saved.x1,
1963 sy - pScreenPriv->saved.y1,
1964 pScreenPriv->colors[SOURCE_COLOR].pixel,
1965 pScreenPriv->colors[MASK_COLOR].pixel);
1966 pScreenPriv->isUp = TRUE;
1970 miSpriteRemoveCursor (pScreen);
1973 if (!pScreenPriv->isUp && pScreenPriv->pCursor)
1974 miSpriteRestoreCursor (pScreen);
1978 miSpriteMoveCursor (pScreen, x, y)
1982 miSpriteScreenPtr pScreenPriv;
1984 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
1985 miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
1989 * undraw/draw cursor
1993 miSpriteRemoveCursor (pScreen)
1996 miSpriteScreenPtr pScreenPriv;
1998 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
1999 pScreenPriv->isUp = FALSE;
2000 pScreenPriv->pCacheWin = NullWindow;
2001 if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
2002 pScreenPriv->saved.x1,
2003 pScreenPriv->saved.y1,
2004 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2005 pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
2007 pScreenPriv->isUp = TRUE;
2012 * Called from the block handler, restores the cursor
2013 * before waiting for something to do.
2017 miSpriteRestoreCursor (pScreen)
2020 miSpriteScreenPtr pScreenPriv;
2024 miSpriteComputeSaved (pScreen);
2025 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
2026 pCursor = pScreenPriv->pCursor;
2027 x = pScreenPriv->x - (int)pCursor->bits->xhot;
2028 y = pScreenPriv->y - (int)pCursor->bits->yhot;
2029 if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
2030 pScreenPriv->saved.x1,
2031 pScreenPriv->saved.y1,
2032 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
2033 pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
2035 if (pScreenPriv->checkPixels)
2036 miSpriteFindColors (pScreen);
2037 if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
2038 pScreenPriv->colors[SOURCE_COLOR].pixel,
2039 pScreenPriv->colors[MASK_COLOR].pixel))
2040 pScreenPriv->isUp = TRUE;
2045 * compute the desired area of the screen to save
2049 miSpriteComputeSaved (pScreen)
2052 miSpriteScreenPtr pScreenPriv;
2057 pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
2058 pCursor = pScreenPriv->pCursor;
2059 x = pScreenPriv->x - (int)pCursor->bits->xhot;
2060 y = pScreenPriv->y - (int)pCursor->bits->yhot;
2061 w = pCursor->bits->width;
2062 h = pCursor->bits->height;
2065 pScreenPriv->saved.x1 = x - wpad;
2066 pScreenPriv->saved.y1 = y - hpad;
2067 pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
2068 pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;