4 * cursor display routines - based on midispcur.c
8 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
10 * This is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This software is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this software; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 Copyright (c) 1989 X Consortium
30 Permission is hereby granted, free of charge, to any person obtaining a copy
31 of this software and associated documentation files (the "Software"), to deal
32 in the Software without restriction, including without limitation the rights
33 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34 copies of the Software, and to permit persons to whom the Software is
35 furnished to do so, subject to the following conditions:
37 The above copyright notice and this permission notice shall be included in
38 all copies or substantial portions of the Software.
40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
44 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
45 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47 Except as contained in this notice, the name of the X Consortium shall not be
48 used in advertising or otherwise to promote the sale, use or other dealings
49 in this Software without prior written authorization from the X Consortium.
56 # include "cursorstr.h"
57 # include "windowstr.h"
58 # include "regionstr.h"
59 # include "dixstruct.h"
60 # include "scrnintstr.h"
61 # include "servermd.h"
62 # include "mipointer.h"
64 # include "gcstruct.h"
66 extern WindowPtr *WindowTable;
68 /* per-screen private data */
70 static int rfbDCScreenIndex;
71 static unsigned long rfbDCGeneration = 0;
73 static Bool rfbDCCloseScreen();
76 GCPtr pSourceGC, pMaskGC;
77 GCPtr pSaveGC, pRestoreGC;
78 GCPtr pPixSourceGC, pPixMaskGC;
79 CloseScreenProcPtr CloseScreen;
81 } rfbDCScreenRec, *rfbDCScreenPtr;
83 /* per-cursor per-screen private data */
85 PixmapPtr sourceBits; /* source bits */
86 PixmapPtr maskBits; /* mask bits */
87 } rfbDCCursorRec, *rfbDCCursorPtr;
90 * sprite/cursor method table
93 static Bool rfbDCRealizeCursor(), rfbDCUnrealizeCursor();
94 static Bool rfbDCPutUpCursor(), rfbDCSaveUnderCursor();
95 static Bool rfbDCRestoreUnderCursor();
97 static rfbSpriteCursorFuncRec rfbDCFuncs = {
101 rfbDCSaveUnderCursor,
102 rfbDCRestoreUnderCursor,
106 rfbDCInitialize (pScreen, screenFuncs)
108 miPointerScreenFuncPtr screenFuncs;
110 rfbDCScreenPtr pScreenPriv;
112 if (rfbDCGeneration != serverGeneration)
114 rfbDCScreenIndex = AllocateScreenPrivateIndex ();
115 if (rfbDCScreenIndex < 0)
117 rfbDCGeneration = serverGeneration;
119 pScreenPriv = (rfbDCScreenPtr) xalloc (sizeof (rfbDCScreenRec));
124 * initialize the entire private structure to zeros
127 pScreenPriv->pSourceGC =
128 pScreenPriv->pMaskGC =
129 pScreenPriv->pSaveGC =
130 pScreenPriv->pRestoreGC =
131 pScreenPriv->pPixSourceGC =
132 pScreenPriv->pPixMaskGC = NULL;
134 pScreenPriv->pSave = NULL;
136 pScreenPriv->CloseScreen = pScreen->CloseScreen;
137 pScreen->CloseScreen = rfbDCCloseScreen;
139 pScreen->devPrivates[rfbDCScreenIndex].ptr = (pointer) pScreenPriv;
141 if (!rfbSpriteInitialize (pScreen, &rfbDCFuncs, screenFuncs))
143 xfree ((pointer) pScreenPriv);
149 #define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0)
150 #define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
153 rfbDCCloseScreen (index, pScreen)
156 rfbDCScreenPtr pScreenPriv;
158 pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
159 pScreen->CloseScreen = pScreenPriv->CloseScreen;
160 tossGC (pScreenPriv->pSourceGC);
161 tossGC (pScreenPriv->pMaskGC);
162 tossGC (pScreenPriv->pSaveGC);
163 tossGC (pScreenPriv->pRestoreGC);
164 tossGC (pScreenPriv->pPixSourceGC);
165 tossGC (pScreenPriv->pPixMaskGC);
166 tossPix (pScreenPriv->pSave);
167 xfree ((pointer) pScreenPriv);
168 return (*pScreen->CloseScreen) (index, pScreen);
172 rfbDCRealizeCursor (pScreen, pCursor)
176 if (pCursor->bits->refcnt <= 1)
177 pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
181 static rfbDCCursorPtr
182 rfbDCRealize (pScreen, pCursor)
186 rfbDCCursorPtr pPriv;
190 pPriv = (rfbDCCursorPtr) xalloc (sizeof (rfbDCCursorRec));
192 return (rfbDCCursorPtr)NULL;
193 pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
194 if (!pPriv->sourceBits)
196 xfree ((pointer) pPriv);
197 return (rfbDCCursorPtr)NULL;
199 pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
200 if (!pPriv->maskBits)
202 (*pScreen->DestroyPixmap) (pPriv->sourceBits);
203 xfree ((pointer) pPriv);
204 return (rfbDCCursorPtr)NULL;
206 pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
208 /* create the two sets of bits, clipping as appropriate */
210 pGC = GetScratchGC (1, pScreen);
213 (void) rfbDCUnrealizeCursor (pScreen, pCursor);
214 return (rfbDCCursorPtr)NULL;
217 ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
218 (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
219 0, 0, pCursor->bits->width, pCursor->bits->height,
220 0, XYPixmap, (char *)pCursor->bits->source);
222 ChangeGC (pGC, GCFunction, gcvals);
223 ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
224 (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
225 0, 0, pCursor->bits->width, pCursor->bits->height,
226 0, XYPixmap, (char *)pCursor->bits->mask);
228 /* mask bits -- pCursor->mask & ~pCursor->source */
230 ChangeGC (pGC, GCFunction, gcvals);
231 ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
232 (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
233 0, 0, pCursor->bits->width, pCursor->bits->height,
234 0, XYPixmap, (char *)pCursor->bits->mask);
235 gcvals[0] = GXandInverted;
236 ChangeGC (pGC, GCFunction, gcvals);
237 ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
238 (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
239 0, 0, pCursor->bits->width, pCursor->bits->height,
240 0, XYPixmap, (char *)pCursor->bits->source);
246 rfbDCUnrealizeCursor (pScreen, pCursor)
250 rfbDCCursorPtr pPriv;
252 pPriv = (rfbDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
253 if (pPriv && (pCursor->bits->refcnt <= 1))
255 (*pScreen->DestroyPixmap) (pPriv->sourceBits);
256 (*pScreen->DestroyPixmap) (pPriv->maskBits);
257 xfree ((pointer) pPriv);
258 pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
264 rfbDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask)
265 DrawablePtr pDrawable;
266 GCPtr sourceGC, maskGC;
269 rfbDCCursorPtr pPriv;
270 unsigned long source, mask;
274 if (sourceGC->fgPixel != source)
277 DoChangeGC (sourceGC, GCForeground, gcvals, 0);
279 if (sourceGC->serialNumber != pDrawable->serialNumber)
280 ValidateGC (pDrawable, sourceGC);
281 (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
282 if (maskGC->fgPixel != mask)
285 DoChangeGC (maskGC, GCForeground, gcvals, 0);
287 if (maskGC->serialNumber != pDrawable->serialNumber)
288 ValidateGC (pDrawable, maskGC);
289 (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
292 #define EnsureGC(gc,win) (gc || rfbDCMakeGC(&gc, win))
295 rfbDCMakeGC(ppGC, pWin)
303 gcvals[0] = IncludeInferiors;
305 pGC = CreateGC((DrawablePtr)pWin,
306 GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
308 (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
314 rfbDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
318 unsigned long source, mask;
320 rfbDCScreenPtr pScreenPriv;
321 rfbDCCursorPtr pPriv;
324 pPriv = (rfbDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
327 pPriv = rfbDCRealize(pScreen, pCursor);
331 pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
332 pWin = WindowTable[pScreen->myNum];
333 if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
335 if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
337 FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
338 pScreenPriv->pSourceGC = 0;
341 rfbDCPutBits ((DrawablePtr)pWin, pPriv,
342 pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
343 x, y, pCursor->bits->width, pCursor->bits->height,
349 rfbDCSaveUnderCursor (pScreen, x, y, w, h)
353 rfbDCScreenPtr pScreenPriv;
358 pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
359 pSave = pScreenPriv->pSave;
360 pWin = WindowTable[pScreen->myNum];
361 if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
364 (*pScreen->DestroyPixmap) (pSave);
365 pScreenPriv->pSave = pSave =
366 (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth);
370 if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
372 pGC = pScreenPriv->pSaveGC;
373 if (pSave->drawable.serialNumber != pGC->serialNumber)
374 ValidateGC ((DrawablePtr) pSave, pGC);
375 (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
381 rfbDCRestoreUnderCursor (pScreen, x, y, w, h)
385 rfbDCScreenPtr pScreenPriv;
390 pScreenPriv = (rfbDCScreenPtr) pScreen->devPrivates[rfbDCScreenIndex].ptr;
391 pSave = pScreenPriv->pSave;
392 pWin = WindowTable[pScreen->myNum];
395 if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
397 pGC = pScreenPriv->pRestoreGC;
398 if (pWin->drawable.serialNumber != pGC->serialNumber)
399 ValidateGC ((DrawablePtr) pWin, pGC);
400 (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,