4 * software sprite routines - based on misprite
8 * Copyright (C) 2002-2003 RealVNC Ltd.
9 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 /* $XConsortium: misprite.c,v 5.47 94/04/17 20:27:53 dpw Exp $ */
31 Copyright (c) 1989 X Consortium
33 Permission is hereby granted, free of charge, to any person obtaining a copy
34 of this software and associated documentation files (the "Software"), to deal
35 in the Software without restriction, including without limitation the rights
36 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37 copies of the Software, and to permit persons to whom the Software is
38 furnished to do so, subject to the following conditions:
40 The above copyright notice and this permission notice shall be included in
41 all copies or substantial portions of the Software.
43 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
47 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
48 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50 Except as contained in this notice, the name of the X Consortium shall not be
51 used in advertising or otherwise to promote the sale, use or other dealings
52 in this Software without prior written authorization from the X Consortium.
58 # include "pixmapstr.h"
61 # include "cursorstr.h"
63 # include "scrnintstr.h"
64 # include "colormapst.h"
65 # include "windowstr.h"
66 # include "gcstruct.h"
67 # include "mipointer.h"
68 # include "spritest.h"
69 # include "dixfontstr.h"
70 # include "fontstruct.h"
77 static int rfbSpriteScreenIndex;
78 static unsigned long rfbSpriteGeneration = 0;
80 static Bool rfbSpriteCloseScreen();
81 static void rfbSpriteGetImage();
82 static void rfbSpriteGetSpans();
83 static void rfbSpriteSourceValidate();
84 static Bool rfbSpriteCreateGC();
85 static void rfbSpriteInstallColormap();
86 static void rfbSpriteStoreColors();
88 static void rfbSpritePaintWindowBackground();
89 static void rfbSpritePaintWindowBorder();
90 static void rfbSpriteCopyWindow();
91 static void rfbSpriteClearToBackground();
93 static void rfbSpriteSaveDoomedAreas();
94 static RegionPtr rfbSpriteRestoreAreas();
95 static void rfbSpriteComputeSaved();
97 #define SCREEN_PROLOGUE(pScreen, field)\
99 ((rfbSpriteScreenPtr) (pScreen)->devPrivates[rfbSpriteScreenIndex].ptr)->field)
101 #define SCREEN_EPILOGUE(pScreen, field, wrapper)\
102 ((pScreen)->field = wrapper)
108 static int rfbSpriteGCIndex;
110 static void rfbSpriteValidateGC (), rfbSpriteCopyGC ();
111 static void rfbSpriteDestroyGC(), rfbSpriteChangeGC();
112 static void rfbSpriteChangeClip(), rfbSpriteDestroyClip();
113 static void rfbSpriteCopyClip();
115 static GCFuncs rfbSpriteGCFuncs = {
121 rfbSpriteDestroyClip,
125 #define GC_FUNC_PROLOGUE(pGC) \
126 rfbSpriteGCPtr pGCPriv = \
127 (rfbSpriteGCPtr) (pGC)->devPrivates[rfbSpriteGCIndex].ptr;\
128 (pGC)->funcs = pGCPriv->wrapFuncs; \
129 if (pGCPriv->wrapOps) \
130 (pGC)->ops = pGCPriv->wrapOps;
132 #define GC_FUNC_EPILOGUE(pGC) \
133 pGCPriv->wrapFuncs = (pGC)->funcs; \
134 (pGC)->funcs = &rfbSpriteGCFuncs; \
135 if (pGCPriv->wrapOps) \
137 pGCPriv->wrapOps = (pGC)->ops; \
138 (pGC)->ops = &rfbSpriteGCOps; \
145 static void rfbSpriteFillSpans(), rfbSpriteSetSpans();
146 static void rfbSpritePutImage();
147 static RegionPtr rfbSpriteCopyArea(), rfbSpriteCopyPlane();
148 static void rfbSpritePolyPoint(), rfbSpritePolylines();
149 static void rfbSpritePolySegment(), rfbSpritePolyRectangle();
150 static void rfbSpritePolyArc(), rfbSpriteFillPolygon();
151 static void rfbSpritePolyFillRect(), rfbSpritePolyFillArc();
152 static int rfbSpritePolyText8(), rfbSpritePolyText16();
153 static void rfbSpriteImageText8(), rfbSpriteImageText16();
154 static void rfbSpriteImageGlyphBlt(), rfbSpritePolyGlyphBlt();
155 static void rfbSpritePushPixels();
156 #ifdef NEED_LINEHELPER
157 static void rfbSpriteLineHelper();
160 static GCOps rfbSpriteGCOps = {
161 rfbSpriteFillSpans, rfbSpriteSetSpans, rfbSpritePutImage,
162 rfbSpriteCopyArea, rfbSpriteCopyPlane, rfbSpritePolyPoint,
163 rfbSpritePolylines, rfbSpritePolySegment, rfbSpritePolyRectangle,
164 rfbSpritePolyArc, rfbSpriteFillPolygon, rfbSpritePolyFillRect,
165 rfbSpritePolyFillArc, rfbSpritePolyText8, rfbSpritePolyText16,
166 rfbSpriteImageText8, rfbSpriteImageText16, rfbSpriteImageGlyphBlt,
167 rfbSpritePolyGlyphBlt, rfbSpritePushPixels
168 #ifdef NEED_LINEHELPER
169 , rfbSpriteLineHelper
174 * testing only -- remove cursor for every draw. Eventually,
175 * each draw operation will perform a bounding box check against
176 * the saved cursor area
179 #define GC_SETUP_CHEAP(pDrawable) \
180 rfbSpriteScreenPtr pScreenPriv = (rfbSpriteScreenPtr) \
181 (pDrawable)->pScreen->devPrivates[rfbSpriteScreenIndex].ptr; \
183 #define GC_SETUP(pDrawable, pGC) \
184 GC_SETUP_CHEAP(pDrawable) \
185 rfbSpriteGCPtr pGCPrivate = (rfbSpriteGCPtr) \
186 (pGC)->devPrivates[rfbSpriteGCIndex].ptr; \
187 GCFuncs *oldFuncs = pGC->funcs;
189 #define GC_SETUP_AND_CHECK(pDrawable, pGC) \
190 GC_SETUP(pDrawable, pGC); \
191 if (GC_CHECK((WindowPtr)pDrawable)) \
192 rfbSpriteRemoveCursor (pDrawable->pScreen);
194 #define GC_CHECK(pWin) \
195 (rfbScreen.cursorIsDrawn && \
196 (pScreenPriv->pCacheWin == pWin ? \
197 pScreenPriv->isInCacheWin : ( \
198 ((int) (pScreenPriv->pCacheWin = (pWin))) , \
199 (pScreenPriv->isInCacheWin = \
200 (pWin)->drawable.x < pScreenPriv->saved.x2 && \
201 pScreenPriv->saved.x1 < (pWin)->drawable.x + \
202 (int) (pWin)->drawable.width && \
203 (pWin)->drawable.y < pScreenPriv->saved.y2 && \
204 pScreenPriv->saved.y1 < (pWin)->drawable.y + \
205 (int) (pWin)->drawable.height &&\
206 RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \
207 &pScreenPriv->saved) != rgnOUT))))
209 #define GC_OP_PROLOGUE(pGC) { \
210 (pGC)->funcs = pGCPrivate->wrapFuncs; \
211 (pGC)->ops = pGCPrivate->wrapOps; \
214 #define GC_OP_EPILOGUE(pGC) { \
215 pGCPrivate->wrapOps = (pGC)->ops; \
216 (pGC)->funcs = oldFuncs; \
217 (pGC)->ops = &rfbSpriteGCOps; \
221 * pointer-sprite method table
224 static Bool rfbSpriteRealizeCursor (), rfbSpriteUnrealizeCursor ();
225 static void rfbSpriteSetCursor (), rfbSpriteMoveCursor ();
227 miPointerSpriteFuncRec rfbSpritePointerFuncs = {
228 rfbSpriteRealizeCursor,
229 rfbSpriteUnrealizeCursor,
235 * other misc functions
238 static void rfbSpriteRemoveCursor ();
241 * rfbSpriteInitialize -- called from device-dependent screen
242 * initialization proc after all of the function pointers have
243 * been stored in the screen structure.
247 rfbSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
249 rfbSpriteCursorFuncPtr cursorFuncs;
250 miPointerScreenFuncPtr screenFuncs;
252 rfbSpriteScreenPtr pPriv;
255 if (rfbSpriteGeneration != serverGeneration)
257 rfbSpriteScreenIndex = AllocateScreenPrivateIndex ();
258 if (rfbSpriteScreenIndex < 0)
260 rfbSpriteGeneration = serverGeneration;
261 rfbSpriteGCIndex = AllocateGCPrivateIndex ();
263 if (!AllocateGCPrivate(pScreen, rfbSpriteGCIndex, sizeof(rfbSpriteGCRec)))
265 pPriv = (rfbSpriteScreenPtr) xalloc (sizeof (rfbSpriteScreenRec));
268 if (!miPointerInitialize (pScreen, &rfbSpritePointerFuncs, screenFuncs,TRUE))
270 xfree ((pointer) pPriv);
273 for (pVisual = pScreen->visuals;
274 pVisual->vid != pScreen->rootVisual;
277 pPriv->pVisual = pVisual;
278 pPriv->CloseScreen = pScreen->CloseScreen;
279 pPriv->GetImage = pScreen->GetImage;
280 pPriv->GetSpans = pScreen->GetSpans;
281 pPriv->SourceValidate = pScreen->SourceValidate;
282 pPriv->CreateGC = pScreen->CreateGC;
283 pPriv->InstallColormap = pScreen->InstallColormap;
284 pPriv->StoreColors = pScreen->StoreColors;
286 pPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
287 pPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
288 pPriv->CopyWindow = pScreen->CopyWindow;
289 pPriv->ClearToBackground = pScreen->ClearToBackground;
291 pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
292 pPriv->RestoreAreas = pScreen->RestoreAreas;
294 pPriv->pCursor = NULL;
297 pPriv->pCacheWin = NullWindow;
298 pPriv->isInCacheWin = FALSE;
299 pPriv->checkPixels = TRUE;
300 pPriv->pInstalledMap = NULL;
301 pPriv->pColormap = NULL;
302 pPriv->funcs = cursorFuncs;
303 pPriv->colors[SOURCE_COLOR].red = 0;
304 pPriv->colors[SOURCE_COLOR].green = 0;
305 pPriv->colors[SOURCE_COLOR].blue = 0;
306 pPriv->colors[MASK_COLOR].red = 0;
307 pPriv->colors[MASK_COLOR].green = 0;
308 pPriv->colors[MASK_COLOR].blue = 0;
309 pScreen->devPrivates[rfbSpriteScreenIndex].ptr = (pointer) pPriv;
310 pScreen->CloseScreen = rfbSpriteCloseScreen;
311 pScreen->GetImage = rfbSpriteGetImage;
312 pScreen->GetSpans = rfbSpriteGetSpans;
313 pScreen->SourceValidate = rfbSpriteSourceValidate;
314 pScreen->CreateGC = rfbSpriteCreateGC;
315 pScreen->InstallColormap = rfbSpriteInstallColormap;
316 pScreen->StoreColors = rfbSpriteStoreColors;
318 pScreen->PaintWindowBackground = rfbSpritePaintWindowBackground;
319 pScreen->PaintWindowBorder = rfbSpritePaintWindowBorder;
320 pScreen->CopyWindow = rfbSpriteCopyWindow;
321 pScreen->ClearToBackground = rfbSpriteClearToBackground;
323 pScreen->SaveDoomedAreas = rfbSpriteSaveDoomedAreas;
324 pScreen->RestoreAreas = rfbSpriteRestoreAreas;
334 * CloseScreen wrapper -- unwrap everything, free the private data
335 * and call the wrapped function
339 rfbSpriteCloseScreen (i, pScreen)
342 rfbSpriteScreenPtr pScreenPriv;
344 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
346 pScreen->CloseScreen = pScreenPriv->CloseScreen;
347 pScreen->GetImage = pScreenPriv->GetImage;
348 pScreen->GetSpans = pScreenPriv->GetSpans;
349 pScreen->SourceValidate = pScreenPriv->SourceValidate;
350 pScreen->CreateGC = pScreenPriv->CreateGC;
351 pScreen->InstallColormap = pScreenPriv->InstallColormap;
352 pScreen->StoreColors = pScreenPriv->StoreColors;
354 pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
355 pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
356 pScreen->CopyWindow = pScreenPriv->CopyWindow;
357 pScreen->ClearToBackground = pScreenPriv->ClearToBackground;
359 pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
360 pScreen->RestoreAreas = pScreenPriv->RestoreAreas;
362 xfree ((pointer) pScreenPriv);
364 return (*pScreen->CloseScreen) (i, pScreen);
368 rfbSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
369 DrawablePtr pDrawable;
372 unsigned long planemask;
375 ScreenPtr pScreen = pDrawable->pScreen;
376 rfbSpriteScreenPtr pScreenPriv;
378 SCREEN_PROLOGUE (pScreen, GetImage);
380 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
382 if (pDrawable->type == DRAWABLE_WINDOW &&
383 rfbScreen.cursorIsDrawn &&
384 ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
386 rfbSpriteRemoveCursor (pScreen);
389 (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
390 format, planemask, pdstLine);
392 SCREEN_EPILOGUE (pScreen, GetImage, rfbSpriteGetImage);
396 rfbSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
397 DrawablePtr pDrawable;
404 ScreenPtr pScreen = pDrawable->pScreen;
405 rfbSpriteScreenPtr pScreenPriv;
407 SCREEN_PROLOGUE (pScreen, GetSpans);
409 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
411 if (pDrawable->type == DRAWABLE_WINDOW && rfbScreen.cursorIsDrawn)
413 register DDXPointPtr pts;
414 register int *widths;
422 for (pts = ppt, widths = pwidth, nPts = nspans;
426 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
427 pts->x+xorg,*widths))
429 rfbSpriteRemoveCursor (pScreen);
435 (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
437 SCREEN_EPILOGUE (pScreen, GetSpans, rfbSpriteGetSpans);
441 rfbSpriteSourceValidate (pDrawable, x, y, width, height)
442 DrawablePtr pDrawable;
443 int x, y, width, height;
445 ScreenPtr pScreen = pDrawable->pScreen;
446 rfbSpriteScreenPtr pScreenPriv;
448 SCREEN_PROLOGUE (pScreen, SourceValidate);
450 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
452 if (pDrawable->type == DRAWABLE_WINDOW && rfbScreen.cursorIsDrawn &&
453 ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
454 x, y, width, height))
456 rfbSpriteRemoveCursor (pScreen);
459 if (pScreen->SourceValidate)
460 (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
462 SCREEN_EPILOGUE (pScreen, SourceValidate, rfbSpriteSourceValidate);
466 rfbSpriteCreateGC (pGC)
469 ScreenPtr pScreen = pGC->pScreen;
471 rfbSpriteGCPtr pPriv;
473 SCREEN_PROLOGUE (pScreen, CreateGC);
475 pPriv = (rfbSpriteGCPtr)pGC->devPrivates[rfbSpriteGCIndex].ptr;
477 ret = (*pScreen->CreateGC) (pGC);
479 pPriv->wrapOps = NULL;
480 pPriv->wrapFuncs = pGC->funcs;
481 pGC->funcs = &rfbSpriteGCFuncs;
483 SCREEN_EPILOGUE (pScreen, CreateGC, rfbSpriteCreateGC);
489 rfbSpriteInstallColormap (pMap)
492 ScreenPtr pScreen = pMap->pScreen;
493 rfbSpriteScreenPtr pPriv;
495 pPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
497 SCREEN_PROLOGUE(pScreen, InstallColormap);
499 (*pScreen->InstallColormap) (pMap);
501 SCREEN_EPILOGUE(pScreen, InstallColormap, rfbSpriteInstallColormap);
503 pPriv->pInstalledMap = pMap;
504 if (pPriv->pColormap != pMap)
506 pPriv->checkPixels = TRUE;
507 if (rfbScreen.cursorIsDrawn)
508 rfbSpriteRemoveCursor (pScreen);
513 rfbSpriteStoreColors (pMap, ndef, pdef)
518 ScreenPtr pScreen = pMap->pScreen;
519 rfbSpriteScreenPtr pPriv;
524 pPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
526 SCREEN_PROLOGUE(pScreen, StoreColors);
528 (*pScreen->StoreColors) (pMap, ndef, pdef);
530 SCREEN_EPILOGUE(pScreen, StoreColors, rfbSpriteStoreColors);
532 if (pPriv->pColormap == pMap)
535 pVisual = pMap->pVisual;
536 if (pVisual->class == DirectColor)
538 /* Direct color - match on any of the subfields */
540 #define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
542 #define UpdateDAC(plane,dac,mask) {\
543 if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
544 pPriv->colors[plane].dac = pdef[i].dac; \
549 #define CheckDirect(plane) \
550 UpdateDAC(plane,red,redMask) \
551 UpdateDAC(plane,green,greenMask) \
552 UpdateDAC(plane,blue,blueMask)
554 for (i = 0; i < ndef; i++)
556 CheckDirect (SOURCE_COLOR)
557 CheckDirect (MASK_COLOR)
562 /* PseudoColor/GrayScale - match on exact pixel */
563 for (i = 0; i < ndef; i++)
565 if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
567 pPriv->colors[SOURCE_COLOR] = pdef[i];
571 if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
573 pPriv->colors[MASK_COLOR] = pdef[i];
581 pPriv->checkPixels = TRUE;
582 if (rfbScreen.cursorIsDrawn)
583 rfbSpriteRemoveCursor (pScreen);
589 rfbSpriteFindColors (pScreen)
592 rfbSpriteScreenPtr pScreenPriv = (rfbSpriteScreenPtr)
593 pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
595 xColorItem *sourceColor, *maskColor;
597 pCursor = pScreenPriv->pCursor;
598 sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
599 maskColor = &pScreenPriv->colors[MASK_COLOR];
600 if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
601 !(pCursor->foreRed == sourceColor->red &&
602 pCursor->foreGreen == sourceColor->green &&
603 pCursor->foreBlue == sourceColor->blue &&
604 pCursor->backRed == maskColor->red &&
605 pCursor->backGreen == maskColor->green &&
606 pCursor->backBlue == maskColor->blue))
608 pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
609 sourceColor->red = pCursor->foreRed;
610 sourceColor->green = pCursor->foreGreen;
611 sourceColor->blue = pCursor->foreBlue;
612 FakeAllocColor (pScreenPriv->pColormap, sourceColor);
613 maskColor->red = pCursor->backRed;
614 maskColor->green = pCursor->backGreen;
615 maskColor->blue = pCursor->backBlue;
616 FakeAllocColor (pScreenPriv->pColormap, maskColor);
617 /* "free" the pixels right away, don't let this confuse you */
618 FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
619 FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
621 pScreenPriv->checkPixels = FALSE;
625 * BackingStore wrappers
629 rfbSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
635 rfbSpriteScreenPtr pScreenPriv;
638 pScreen = pWin->drawable.pScreen;
640 SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
642 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
643 if (rfbScreen.cursorIsDrawn)
645 cursorBox = pScreenPriv->saved;
654 if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
655 rfbSpriteRemoveCursor (pScreen);
658 (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
660 SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, rfbSpriteSaveDoomedAreas);
664 rfbSpriteRestoreAreas (pWin, prgnExposed)
666 RegionPtr prgnExposed;
669 rfbSpriteScreenPtr pScreenPriv;
672 pScreen = pWin->drawable.pScreen;
674 SCREEN_PROLOGUE (pScreen, RestoreAreas);
676 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
677 if (rfbScreen.cursorIsDrawn)
679 if (RECT_IN_REGION( pScreen, prgnExposed, &pScreenPriv->saved) != rgnOUT)
680 rfbSpriteRemoveCursor (pScreen);
683 result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
685 SCREEN_EPILOGUE (pScreen, RestoreAreas, rfbSpriteRestoreAreas);
695 rfbSpritePaintWindowBackground (pWin, pRegion, what)
701 rfbSpriteScreenPtr pScreenPriv;
703 pScreen = pWin->drawable.pScreen;
705 SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
707 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
708 if (rfbScreen.cursorIsDrawn)
711 * If the cursor is on the same screen as the window, check the
712 * region to paint for the cursor and remove it as necessary
714 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
715 rfbSpriteRemoveCursor (pScreen);
718 (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
720 SCREEN_EPILOGUE (pScreen, PaintWindowBackground, rfbSpritePaintWindowBackground);
724 rfbSpritePaintWindowBorder (pWin, pRegion, what)
730 rfbSpriteScreenPtr pScreenPriv;
732 pScreen = pWin->drawable.pScreen;
734 SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
736 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
737 if (rfbScreen.cursorIsDrawn)
740 * If the cursor is on the same screen as the window, check the
741 * region to paint for the cursor and remove it as necessary
743 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
744 rfbSpriteRemoveCursor (pScreen);
747 (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
749 SCREEN_EPILOGUE (pScreen, PaintWindowBorder, rfbSpritePaintWindowBorder);
753 rfbSpriteCopyWindow (pWin, ptOldOrg, pRegion)
755 DDXPointRec ptOldOrg;
759 rfbSpriteScreenPtr pScreenPriv;
763 pScreen = pWin->drawable.pScreen;
765 SCREEN_PROLOGUE (pScreen, CopyWindow);
767 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
768 if (rfbScreen.cursorIsDrawn)
771 * check both the source and the destination areas. The given
772 * region is source relative, so offset the cursor box by
775 cursorBox = pScreenPriv->saved;
776 dx = pWin->drawable.x - ptOldOrg.x;
777 dy = pWin->drawable.y - ptOldOrg.y;
782 if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT ||
783 RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT)
784 rfbSpriteRemoveCursor (pScreen);
787 (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion);
789 SCREEN_EPILOGUE (pScreen, CopyWindow, rfbSpriteCopyWindow);
793 rfbSpriteClearToBackground (pWin, x, y, w, h, generateExposures)
797 Bool generateExposures;
800 rfbSpriteScreenPtr pScreenPriv;
803 pScreen = pWin->drawable.pScreen;
805 SCREEN_PROLOGUE (pScreen, ClearToBackground);
807 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
811 realw = (int) pWin->drawable.width - x;
813 realh = (int) pWin->drawable.height - y;
814 if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y,
817 rfbSpriteRemoveCursor (pScreen);
821 (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
823 SCREEN_EPILOGUE (pScreen, ClearToBackground, rfbSpriteClearToBackground);
831 rfbSpriteValidateGC (pGC, changes, pDrawable)
834 DrawablePtr pDrawable;
836 GC_FUNC_PROLOGUE (pGC);
838 (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
840 pGCPriv->wrapOps = NULL;
841 if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable)
846 pWin = (WindowPtr) pDrawable;
847 pRegion = &pWin->clipList;
848 if (pGC->subWindowMode == IncludeInferiors)
849 pRegion = &pWin->borderClip;
850 if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion))
851 pGCPriv->wrapOps = pGC->ops;
854 GC_FUNC_EPILOGUE (pGC);
858 rfbSpriteChangeGC (pGC, mask)
862 GC_FUNC_PROLOGUE (pGC);
864 (*pGC->funcs->ChangeGC) (pGC, mask);
866 GC_FUNC_EPILOGUE (pGC);
870 rfbSpriteCopyGC (pGCSrc, mask, pGCDst)
871 GCPtr pGCSrc, pGCDst;
874 GC_FUNC_PROLOGUE (pGCDst);
876 (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
878 GC_FUNC_EPILOGUE (pGCDst);
882 rfbSpriteDestroyGC (pGC)
885 GC_FUNC_PROLOGUE (pGC);
887 (*pGC->funcs->DestroyGC) (pGC);
889 GC_FUNC_EPILOGUE (pGC);
893 rfbSpriteChangeClip (pGC, type, pvalue, nrects)
899 GC_FUNC_PROLOGUE (pGC);
901 (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
903 GC_FUNC_EPILOGUE (pGC);
907 rfbSpriteCopyClip(pgcDst, pgcSrc)
908 GCPtr pgcDst, pgcSrc;
910 GC_FUNC_PROLOGUE (pgcDst);
912 (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
914 GC_FUNC_EPILOGUE (pgcDst);
918 rfbSpriteDestroyClip(pGC)
921 GC_FUNC_PROLOGUE (pGC);
923 (* pGC->funcs->DestroyClip)(pGC);
925 GC_FUNC_EPILOGUE (pGC);
933 rfbSpriteFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
934 DrawablePtr pDrawable;
936 int nInit; /* number of spans to fill */
937 DDXPointPtr pptInit; /* pointer to list of start points */
938 int *pwidthInit; /* pointer to list of n widths */
941 GC_SETUP(pDrawable, pGC);
943 if (GC_CHECK((WindowPtr) pDrawable))
945 register DDXPointPtr pts;
946 register int *widths;
949 for (pts = pptInit, widths = pwidthInit, nPts = nInit;
953 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
955 rfbSpriteRemoveCursor (pDrawable->pScreen);
961 GC_OP_PROLOGUE (pGC);
963 (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
965 GC_OP_EPILOGUE (pGC);
969 rfbSpriteSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
970 DrawablePtr pDrawable;
973 register DDXPointPtr ppt;
978 GC_SETUP(pDrawable, pGC);
980 if (GC_CHECK((WindowPtr) pDrawable))
982 register DDXPointPtr pts;
983 register int *widths;
986 for (pts = ppt, widths = pwidth, nPts = nspans;
990 if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
992 rfbSpriteRemoveCursor(pDrawable->pScreen);
998 GC_OP_PROLOGUE (pGC);
1000 (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
1002 GC_OP_EPILOGUE (pGC);
1006 rfbSpritePutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
1007 DrawablePtr pDrawable;
1017 GC_SETUP(pDrawable, pGC);
1019 if (GC_CHECK((WindowPtr) pDrawable))
1021 if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,
1024 rfbSpriteRemoveCursor (pDrawable->pScreen);
1028 GC_OP_PROLOGUE (pGC);
1030 (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits);
1032 GC_OP_EPILOGUE (pGC);
1036 rfbSpriteCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
1049 GC_SETUP(pDst, pGC);
1051 /* check destination/source overlap. */
1052 if (GC_CHECK((WindowPtr) pDst) &&
1053 (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1055 ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1057 rfbSpriteRemoveCursor (pDst->pScreen);
1060 GC_OP_PROLOGUE (pGC);
1062 rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
1065 GC_OP_EPILOGUE (pGC);
1071 rfbSpriteCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
1081 unsigned long plane;
1085 GC_SETUP(pDst, pGC);
1088 * check destination/source for overlap.
1090 if (GC_CHECK((WindowPtr) pDst) &&
1091 (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
1093 ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
1095 rfbSpriteRemoveCursor (pDst->pScreen);
1098 GC_OP_PROLOGUE (pGC);
1100 rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
1103 GC_OP_EPILOGUE (pGC);
1109 rfbSpritePolyPoint (pDrawable, pGC, mode, npt, pptInit)
1110 DrawablePtr pDrawable;
1112 int mode; /* Origin or Previous */
1119 register xPoint *pts;
1121 GC_SETUP (pDrawable, pGC);
1123 if (npt && GC_CHECK((WindowPtr) pDrawable))
1125 cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x;
1126 cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y;
1127 cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x;
1128 cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y;
1130 if (mode == CoordModePrevious)
1134 for (pts = pptInit, n = npt; n--; pts++)
1138 if (cursor.x1 <= t.x && t.x <= cursor.x2 &&
1139 cursor.y1 <= t.y && t.y <= cursor.y2)
1141 rfbSpriteRemoveCursor (pDrawable->pScreen);
1148 for (pts = pptInit, n = npt; n--; pts++)
1150 if (cursor.x1 <= pts->x && pts->x <= cursor.x2 &&
1151 cursor.y1 <= pts->y && pts->y <= cursor.y2)
1153 rfbSpriteRemoveCursor (pDrawable->pScreen);
1160 GC_OP_PROLOGUE (pGC);
1162 (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
1164 GC_OP_EPILOGUE (pGC);
1168 rfbSpritePolylines (pDrawable, pGC, mode, npt, pptInit)
1169 DrawablePtr pDrawable;
1173 DDXPointPtr pptInit;
1176 register DDXPointPtr pts;
1178 int x, y, x1, y1, x2, y2;
1182 GC_SETUP (pDrawable, pGC);
1184 if (npt && GC_CHECK((WindowPtr) pDrawable))
1186 cursor = &pScreenPriv->saved;
1187 lw = pGC->lineWidth;
1188 x = pptInit->x + pDrawable->x;
1189 y = pptInit->y + pDrawable->y;
1194 if (LINE_OVERLAP(cursor, x, y, x, y, extra))
1195 rfbSpriteRemoveCursor (pDrawable->pScreen);
1201 * mitered joins can project quite a way from
1202 * the line end; the 11 degree miter limit limits
1203 * this extension to 10.43 * lw / 2, rounded up
1204 * and converted to int yields 6 * lw
1206 if (pGC->joinStyle == JoinMiter)
1208 else if (pGC->capStyle == CapProjecting)
1210 for (pts = pptInit + 1, n = npt - 1; n--; pts++)
1214 if (mode == CoordModeOrigin)
1216 x2 = pDrawable->x + pts->x;
1217 y2 = pDrawable->y + pts->y;
1226 LINE_SORT(x1, y1, x2, y2);
1227 if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1229 rfbSpriteRemoveCursor (pDrawable->pScreen);
1235 GC_OP_PROLOGUE (pGC);
1237 (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit);
1239 GC_OP_EPILOGUE (pGC);
1243 rfbSpritePolySegment(pDrawable, pGC, nseg, pSegs)
1244 DrawablePtr pDrawable;
1250 register xSegment *segs;
1255 GC_SETUP(pDrawable, pGC);
1257 if (nseg && GC_CHECK((WindowPtr) pDrawable))
1259 cursor = &pScreenPriv->saved;
1260 extra = pGC->lineWidth >> 1;
1261 if (pGC->capStyle == CapProjecting)
1262 extra = pGC->lineWidth;
1263 for (segs = pSegs, n = nseg; n--; segs++)
1265 x1 = segs->x1 + pDrawable->x;
1266 y1 = segs->y1 + pDrawable->y;
1267 x2 = segs->x2 + pDrawable->x;
1268 y2 = segs->y2 + pDrawable->y;
1269 LINE_SORT(x1, y1, x2, y2);
1270 if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
1272 rfbSpriteRemoveCursor (pDrawable->pScreen);
1278 GC_OP_PROLOGUE (pGC);
1280 (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs);
1282 GC_OP_EPILOGUE (pGC);
1286 rfbSpritePolyRectangle(pDrawable, pGC, nrects, pRects)
1287 DrawablePtr pDrawable;
1292 register xRectangle *rects;
1298 GC_SETUP (pDrawable, pGC);
1300 if (GC_CHECK((WindowPtr) pDrawable))
1302 lw = pGC->lineWidth >> 1;
1303 cursor = &pScreenPriv->saved;
1304 for (rects = pRects, n = nrects; n--; rects++)
1306 x1 = rects->x + pDrawable->x;
1307 y1 = rects->y + pDrawable->y;
1308 x2 = x1 + (int)rects->width;
1309 y2 = y1 + (int)rects->height;
1310 if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) ||
1311 LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) ||
1312 LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) ||
1313 LINE_OVERLAP(cursor, x1, y1, x1, y2, lw))
1315 rfbSpriteRemoveCursor (pDrawable->pScreen);
1321 GC_OP_PROLOGUE (pGC);
1323 (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects);
1325 GC_OP_EPILOGUE (pGC);
1329 rfbSpritePolyArc(pDrawable, pGC, narcs, parcs)
1330 DrawablePtr pDrawable;
1338 register xArc *arcs;
1340 GC_SETUP (pDrawable, pGC);
1342 if (GC_CHECK((WindowPtr) pDrawable))
1344 lw = pGC->lineWidth >> 1;
1345 cursor = &pScreenPriv->saved;
1346 for (arcs = parcs, n = narcs; n--; arcs++)
1348 if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y,
1349 arcs->x - lw, arcs->y - lw,
1350 (int) arcs->width + pGC->lineWidth,
1351 (int) arcs->height + pGC->lineWidth))
1353 rfbSpriteRemoveCursor (pDrawable->pScreen);
1359 GC_OP_PROLOGUE (pGC);
1361 (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs);
1363 GC_OP_EPILOGUE (pGC);
1367 rfbSpriteFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
1368 register DrawablePtr pDrawable;
1374 int x, y, minx, miny, maxx, maxy;
1375 register DDXPointPtr pts;
1378 GC_SETUP (pDrawable, pGC);
1380 if (count && GC_CHECK((WindowPtr) pDrawable))
1385 minx = maxx = pts->x;
1386 miny = maxy = pts->y;
1390 if (mode == CoordModeOrigin)
1396 else if (pts->x > maxx)
1400 else if (pts->y > maxy)
1428 if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy))
1429 rfbSpriteRemoveCursor (pDrawable->pScreen);
1432 GC_OP_PROLOGUE (pGC);
1434 (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts);
1436 GC_OP_EPILOGUE (pGC);
1440 rfbSpritePolyFillRect(pDrawable, pGC, nrectFill, prectInit)
1441 DrawablePtr pDrawable;
1443 int nrectFill; /* number of rectangles to fill */
1444 xRectangle *prectInit; /* Pointer to first rectangle to fill */
1446 GC_SETUP(pDrawable, pGC);
1448 if (GC_CHECK((WindowPtr) pDrawable))
1451 register xRectangle *pRect;
1452 register int xorg, yorg;
1454 xorg = pDrawable->x;
1455 yorg = pDrawable->y;
1457 for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) {
1458 if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){
1459 rfbSpriteRemoveCursor(pDrawable->pScreen);
1465 GC_OP_PROLOGUE (pGC);
1467 (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit);
1469 GC_OP_EPILOGUE (pGC);
1473 rfbSpritePolyFillArc(pDrawable, pGC, narcs, parcs)
1474 DrawablePtr pDrawable;
1479 GC_SETUP(pDrawable, pGC);
1481 if (GC_CHECK((WindowPtr) pDrawable))
1485 register xArc *arcs;
1487 cursor = &pScreenPriv->saved;
1489 for (arcs = parcs, n = narcs; n--; arcs++)
1491 if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y,
1493 (int) arcs->width, (int) arcs->height))
1495 rfbSpriteRemoveCursor (pDrawable->pScreen);
1501 GC_OP_PROLOGUE (pGC);
1503 (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs);
1505 GC_OP_EPILOGUE (pGC);
1509 * general Poly/Image text function. Extract glyph information,
1510 * compute bounding box and remove cursor if it is overlapped.
1514 rfbSpriteTextOverlap (pDraw, font, x, y, n, charinfo, imageblt, w, cursorBox)
1519 CharInfoPtr *charinfo;
1524 ExtentInfoRec extents;
1529 if (FONTMINBOUNDS(font,characterWidth) >= 0)
1531 /* compute an approximate (but covering) bounding box */
1532 if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0))
1533 extents.overallLeft = charinfo[0]->metrics.leftSideBearing;
1535 extents.overallLeft = 0;
1537 extents.overallRight = w - charinfo[n-1]->metrics.characterWidth;
1539 extents.overallRight = FONTMAXBOUNDS(font,characterWidth)
1541 if (imageblt && (charinfo[n-1]->metrics.characterWidth >
1542 charinfo[n-1]->metrics.rightSideBearing))
1543 extents.overallRight += charinfo[n-1]->metrics.characterWidth;
1545 extents.overallRight += charinfo[n-1]->metrics.rightSideBearing;
1546 if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
1547 extents.overallAscent = FONTASCENT(font);
1549 extents.overallAscent = FONTMAXBOUNDS(font, ascent);
1550 if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
1551 extents.overallDescent = FONTDESCENT(font);
1553 extents.overallDescent = FONTMAXBOUNDS(font,descent);
1554 if (!BOX_OVERLAP(cursorBox,
1555 x + extents.overallLeft,
1556 y - extents.overallAscent,
1557 x + extents.overallRight,
1558 y + extents.overallDescent))
1560 else if (imageblt && w)
1562 /* if it does overlap, fall through and compute exactly, because
1563 * taking down the cursor is expensive enough to make this worth it
1566 QueryGlyphExtents(font, charinfo, n, &extents);
1569 if (extents.overallWidth > extents.overallRight)
1570 extents.overallRight = extents.overallWidth;
1571 if (extents.overallWidth < extents.overallLeft)
1572 extents.overallLeft = extents.overallWidth;
1573 if (extents.overallLeft > 0)
1574 extents.overallLeft = 0;
1575 if (extents.fontAscent > extents.overallAscent)
1576 extents.overallAscent = extents.fontAscent;
1577 if (extents.fontDescent > extents.overallDescent)
1578 extents.overallDescent = extents.fontDescent;
1580 return (BOX_OVERLAP(cursorBox,
1581 x + extents.overallLeft,
1582 y - extents.overallAscent,
1583 x + extents.overallRight,
1584 y + extents.overallDescent));
1588 * values for textType:
1593 #define TT_IMAGE16 3
1596 rfbSpriteText (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox)
1601 unsigned long count;
1603 FontEncoding fontEncoding;
1607 CharInfoPtr *charinfo;
1608 register CharInfoPtr *info;
1612 void (*drawFunc)() = 0;
1616 imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
1618 charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
1622 GetGlyphs(pGC->font, count, (unsigned char *)chars,
1623 fontEncoding, &i, charinfo);
1624 n = (unsigned int)i;
1627 for (info = charinfo; i--; info++)
1628 w += (*info)->metrics.characterWidth;
1631 if (rfbSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox))
1632 rfbSpriteRemoveCursor(pDraw->pScreen);
1634 #ifdef AVOID_GLYPHBLT
1636 * On displays like Apollos, which do not optimize the GlyphBlt functions because they
1637 * convert fonts to their internal form in RealizeFont and optimize text directly, we
1638 * want to invoke the text functions here, not the GlyphBlt functions.
1643 drawFunc = (void (*)())pGC->ops->PolyText8;
1646 drawFunc = pGC->ops->ImageText8;
1649 drawFunc = (void (*)())pGC->ops->PolyText16;
1652 drawFunc = pGC->ops->ImageText16;
1655 (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);
1656 #else /* don't AVOID_GLYPHBLT */
1658 * On the other hand, if the device does use GlyphBlt ultimately to do text, we
1659 * don't want to slow it down by invoking the text functions and having them call
1660 * GetGlyphs all over again, so we go directly to the GlyphBlt functions here.
1662 drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt;
1663 (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
1664 #endif /* AVOID_GLYPHBLT */
1666 DEALLOCATE_LOCAL(charinfo);
1671 rfbSpritePolyText8(pDrawable, pGC, x, y, count, chars)
1672 DrawablePtr pDrawable;
1680 GC_SETUP (pDrawable, pGC);
1682 GC_OP_PROLOGUE (pGC);
1684 if (GC_CHECK((WindowPtr) pDrawable))
1685 ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars,
1686 Linear8Bit, TT_POLY8, &pScreenPriv->saved);
1688 ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
1690 GC_OP_EPILOGUE (pGC);
1695 rfbSpritePolyText16(pDrawable, pGC, x, y, count, chars)
1696 DrawablePtr pDrawable;
1700 unsigned short *chars;
1704 GC_SETUP(pDrawable, pGC);
1706 GC_OP_PROLOGUE (pGC);
1708 if (GC_CHECK((WindowPtr) pDrawable))
1709 ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1711 FONTLASTROW(pGC->font) == 0 ?
1712 Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved);
1714 ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
1716 GC_OP_EPILOGUE (pGC);
1721 rfbSpriteImageText8(pDrawable, pGC, x, y, count, chars)
1722 DrawablePtr pDrawable;
1728 GC_SETUP(pDrawable, pGC);
1730 GC_OP_PROLOGUE (pGC);
1732 if (GC_CHECK((WindowPtr) pDrawable))
1733 (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1734 chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved);
1736 (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
1738 GC_OP_EPILOGUE (pGC);
1742 rfbSpriteImageText16(pDrawable, pGC, x, y, count, chars)
1743 DrawablePtr pDrawable;
1747 unsigned short *chars;
1749 GC_SETUP(pDrawable, pGC);
1751 GC_OP_PROLOGUE (pGC);
1753 if (GC_CHECK((WindowPtr) pDrawable))
1754 (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
1756 FONTLASTROW(pGC->font) == 0 ?
1757 Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved);
1759 (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
1761 GC_OP_EPILOGUE (pGC);
1765 rfbSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1766 DrawablePtr pDrawable;
1769 unsigned int nglyph;
1770 CharInfoPtr *ppci; /* array of character info */
1771 pointer pglyphBase; /* start of array of glyphs */
1773 GC_SETUP(pDrawable, pGC);
1775 GC_OP_PROLOGUE (pGC);
1777 if (GC_CHECK((WindowPtr) pDrawable) &&
1778 rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved))
1780 rfbSpriteRemoveCursor(pDrawable->pScreen);
1782 (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1784 GC_OP_EPILOGUE (pGC);
1788 rfbSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
1789 DrawablePtr pDrawable;
1792 unsigned int nglyph;
1793 CharInfoPtr *ppci; /* array of character info */
1794 pointer pglyphBase; /* start of array of glyphs */
1796 GC_SETUP (pDrawable, pGC);
1798 GC_OP_PROLOGUE (pGC);
1800 if (GC_CHECK((WindowPtr) pDrawable) &&
1801 rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved))
1803 rfbSpriteRemoveCursor(pDrawable->pScreen);
1805 (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
1807 GC_OP_EPILOGUE (pGC);
1811 rfbSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y)
1814 DrawablePtr pDrawable;
1817 GC_SETUP(pDrawable, pGC);
1819 if (GC_CHECK((WindowPtr) pDrawable) &&
1820 ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h))
1822 rfbSpriteRemoveCursor (pDrawable->pScreen);
1825 GC_OP_PROLOGUE (pGC);
1827 (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
1829 GC_OP_EPILOGUE (pGC);
1832 #ifdef NEED_LINEHELPER
1834 * I don't expect this routine will ever be called, as the GC
1835 * will have been unwrapped for the line drawing
1839 rfbSpriteLineHelper()
1841 FatalError("rfbSpriteLineHelper called\n");
1846 * miPointer interface routines
1850 rfbSpriteRealizeCursor (pScreen, pCursor)
1854 rfbSpriteScreenPtr pScreenPriv;
1856 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1857 if (pCursor == pScreenPriv->pCursor)
1858 pScreenPriv->checkPixels = TRUE;
1859 return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
1863 rfbSpriteUnrealizeCursor (pScreen, pCursor)
1867 rfbSpriteScreenPtr pScreenPriv;
1869 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1870 return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
1874 rfbSpriteSetCursor (pScreen, pCursor, x, y)
1878 rfbSpriteScreenPtr pScreenPriv;
1879 rfbClientPtr cl, nextCl;
1882 = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1884 if (pScreenPriv->x == x &&
1885 pScreenPriv->y == y &&
1886 pScreenPriv->pCursor == pCursor &&
1887 !pScreenPriv->checkPixels)
1892 if (rfbScreen.cursorIsDrawn)
1893 rfbSpriteRemoveCursor (pScreen);
1897 pScreenPriv->pCursor = pCursor;
1899 for (cl = rfbClientHead; cl; cl = nextCl) {
1901 if (REGION_NOTEMPTY(pScreen,&cl->requestedRegion)) {
1902 /* cursorIsDrawn is guaranteed to be FALSE here, so we definitely
1903 want to send a screen update to the client, even if that's only
1904 putting up the cursor */
1905 rfbSendFramebufferUpdate(cl);
1911 rfbSpriteMoveCursor (pScreen, x, y)
1915 rfbSpriteScreenPtr pScreenPriv;
1917 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1918 rfbSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
1922 * undraw/draw cursor
1926 rfbSpriteRemoveCursor (pScreen)
1929 rfbSpriteScreenPtr pScreenPriv;
1932 = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1934 rfbScreen.dontSendFramebufferUpdate = TRUE;
1935 rfbScreen.cursorIsDrawn = FALSE;
1936 pScreenPriv->pCacheWin = NullWindow;
1937 if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
1938 pScreenPriv->saved.x1,
1939 pScreenPriv->saved.y1,
1940 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
1941 pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
1943 rfbScreen.cursorIsDrawn = TRUE;
1945 rfbScreen.dontSendFramebufferUpdate = FALSE;
1950 rfbSpriteRestoreCursor (pScreen)
1953 rfbSpriteScreenPtr pScreenPriv;
1958 = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
1959 pCursor = pScreenPriv->pCursor;
1961 if (rfbScreen.cursorIsDrawn || !pCursor)
1964 rfbScreen.dontSendFramebufferUpdate = TRUE;
1966 rfbSpriteComputeSaved (pScreen);
1968 x = pScreenPriv->x - (int)pCursor->bits->xhot;
1969 y = pScreenPriv->y - (int)pCursor->bits->yhot;
1970 if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
1971 pScreenPriv->saved.x1,
1972 pScreenPriv->saved.y1,
1973 pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
1974 pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
1976 if (pScreenPriv->checkPixels)
1977 rfbSpriteFindColors (pScreen);
1978 if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
1979 pScreenPriv->colors[SOURCE_COLOR].pixel,
1980 pScreenPriv->colors[MASK_COLOR].pixel))
1981 rfbScreen.cursorIsDrawn = TRUE;
1984 rfbScreen.dontSendFramebufferUpdate = FALSE;
1988 * compute the desired area of the screen to save
1992 rfbSpriteComputeSaved (pScreen)
1995 rfbSpriteScreenPtr pScreenPriv;
1999 pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr;
2000 pCursor = pScreenPriv->pCursor;
2001 x = pScreenPriv->x - (int)pCursor->bits->xhot;
2002 y = pScreenPriv->y - (int)pCursor->bits->yhot;
2003 w = pCursor->bits->width;
2004 h = pCursor->bits->height;
2005 pScreenPriv->saved.x1 = x;
2006 pScreenPriv->saved.y1 = y;
2007 pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w;
2008 pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h;