1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * midispcur.c
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * machine independent cursor display routines
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun /*
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun Copyright 1989, 1998 The Open Group
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
12*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
13*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
14*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
15*4882a593Smuzhiyun documentation.
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
18*4882a593Smuzhiyun all copies or substantial portions of the Software.
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
28*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
29*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
33*4882a593Smuzhiyun #include <dix-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include <X11/X.h>
37*4882a593Smuzhiyun #include "misc.h"
38*4882a593Smuzhiyun #include "input.h"
39*4882a593Smuzhiyun #include "cursorstr.h"
40*4882a593Smuzhiyun #include "windowstr.h"
41*4882a593Smuzhiyun #include "regionstr.h"
42*4882a593Smuzhiyun #include "dixstruct.h"
43*4882a593Smuzhiyun #include "scrnintstr.h"
44*4882a593Smuzhiyun #include "servermd.h"
45*4882a593Smuzhiyun #include "mipointer.h"
46*4882a593Smuzhiyun #include "misprite.h"
47*4882a593Smuzhiyun #include "gcstruct.h"
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #include "picturestr.h"
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #include "inputstr.h"
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /* per-screen private data */
54*4882a593Smuzhiyun static DevPrivateKeyRec miDCScreenKeyRec;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define miDCScreenKey (&miDCScreenKeyRec)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun static DevScreenPrivateKeyRec miDCDeviceKeyRec;
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #define miDCDeviceKey (&miDCDeviceKeyRec)
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun static Bool miDCCloseScreen(ScreenPtr pScreen);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* per device private data */
65*4882a593Smuzhiyun typedef struct {
66*4882a593Smuzhiyun GCPtr pSourceGC, pMaskGC;
67*4882a593Smuzhiyun GCPtr pSaveGC, pRestoreGC;
68*4882a593Smuzhiyun PixmapPtr pSave;
69*4882a593Smuzhiyun PicturePtr pRootPicture;
70*4882a593Smuzhiyun } miDCBufferRec, *miDCBufferPtr;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun #define miGetDCDevice(dev, screen) \
73*4882a593Smuzhiyun ((DevHasCursor(dev)) ? \
74*4882a593Smuzhiyun (miDCBufferPtr)dixLookupScreenPrivate(&dev->devPrivates, miDCDeviceKey, screen) : \
75*4882a593Smuzhiyun (miDCBufferPtr)dixLookupScreenPrivate(&GetMaster(dev, MASTER_POINTER)->devPrivates, miDCDeviceKey, screen))
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun * The core pointer buffer will point to the index of the virtual pointer
79*4882a593Smuzhiyun * in the pCursorBuffers array.
80*4882a593Smuzhiyun */
81*4882a593Smuzhiyun typedef struct {
82*4882a593Smuzhiyun CloseScreenProcPtr CloseScreen;
83*4882a593Smuzhiyun PixmapPtr sourceBits; /* source bits */
84*4882a593Smuzhiyun PixmapPtr maskBits; /* mask bits */
85*4882a593Smuzhiyun PicturePtr pPicture;
86*4882a593Smuzhiyun CursorPtr pCursor;
87*4882a593Smuzhiyun } miDCScreenRec, *miDCScreenPtr;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #define miGetDCScreen(s) ((miDCScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miDCScreenKey)))
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun Bool
miDCInitialize(ScreenPtr pScreen,miPointerScreenFuncPtr screenFuncs)92*4882a593Smuzhiyun miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun miDCScreenPtr pScreenPriv;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&miDCScreenKeyRec, PRIVATE_SCREEN, 0) ||
97*4882a593Smuzhiyun !dixRegisterScreenPrivateKey(&miDCDeviceKeyRec, pScreen, PRIVATE_DEVICE,
98*4882a593Smuzhiyun 0))
99*4882a593Smuzhiyun return FALSE;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun pScreenPriv = calloc(1, sizeof(miDCScreenRec));
102*4882a593Smuzhiyun if (!pScreenPriv)
103*4882a593Smuzhiyun return FALSE;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun pScreenPriv->CloseScreen = pScreen->CloseScreen;
106*4882a593Smuzhiyun pScreen->CloseScreen = miDCCloseScreen;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, miDCScreenKey, pScreenPriv);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if (!miSpriteInitialize(pScreen, screenFuncs)) {
111*4882a593Smuzhiyun free((void *) pScreenPriv);
112*4882a593Smuzhiyun return FALSE;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun return TRUE;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun static void
miDCSwitchScreenCursor(ScreenPtr pScreen,CursorPtr pCursor,PixmapPtr sourceBits,PixmapPtr maskBits,PicturePtr pPicture)118*4882a593Smuzhiyun miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBits, PixmapPtr maskBits, PicturePtr pPicture)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (pScreenPriv->sourceBits)
123*4882a593Smuzhiyun (*pScreen->DestroyPixmap)(pScreenPriv->sourceBits);
124*4882a593Smuzhiyun pScreenPriv->sourceBits = sourceBits;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (pScreenPriv->maskBits)
127*4882a593Smuzhiyun (*pScreen->DestroyPixmap)(pScreenPriv->maskBits);
128*4882a593Smuzhiyun pScreenPriv->maskBits = maskBits;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun if (pScreenPriv->pPicture)
131*4882a593Smuzhiyun FreePicture(pScreenPriv->pPicture, 0);
132*4882a593Smuzhiyun pScreenPriv->pPicture = pPicture;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun pScreenPriv->pCursor = pCursor;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun static Bool
miDCCloseScreen(ScreenPtr pScreen)138*4882a593Smuzhiyun miDCCloseScreen(ScreenPtr pScreen)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun miDCScreenPtr pScreenPriv;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun pScreenPriv = (miDCScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
143*4882a593Smuzhiyun miDCScreenKey);
144*4882a593Smuzhiyun pScreen->CloseScreen = pScreenPriv->CloseScreen;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
147*4882a593Smuzhiyun free((void *) pScreenPriv);
148*4882a593Smuzhiyun return (*pScreen->CloseScreen) (pScreen);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun Bool
miDCRealizeCursor(ScreenPtr pScreen,CursorPtr pCursor)152*4882a593Smuzhiyun miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun return TRUE;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun #define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun static PicturePtr
miDCMakePicture(PicturePtr * ppPicture,DrawablePtr pDraw,WindowPtr pWin)160*4882a593Smuzhiyun miDCMakePicture(PicturePtr * ppPicture, DrawablePtr pDraw, WindowPtr pWin)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun PictFormatPtr pFormat;
163*4882a593Smuzhiyun XID subwindow_mode = IncludeInferiors;
164*4882a593Smuzhiyun PicturePtr pPicture;
165*4882a593Smuzhiyun int error;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun pFormat = PictureWindowFormat(pWin);
168*4882a593Smuzhiyun if (!pFormat)
169*4882a593Smuzhiyun return 0;
170*4882a593Smuzhiyun pPicture = CreatePicture(0, pDraw, pFormat,
171*4882a593Smuzhiyun CPSubwindowMode, &subwindow_mode,
172*4882a593Smuzhiyun serverClient, &error);
173*4882a593Smuzhiyun *ppPicture = pPicture;
174*4882a593Smuzhiyun return pPicture;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun static Bool
miDCRealize(ScreenPtr pScreen,CursorPtr pCursor)178*4882a593Smuzhiyun miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
181*4882a593Smuzhiyun GCPtr pGC;
182*4882a593Smuzhiyun ChangeGCVal gcvals;
183*4882a593Smuzhiyun PixmapPtr sourceBits, maskBits;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (pScreenPriv->pCursor == pCursor)
186*4882a593Smuzhiyun return TRUE;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun if (pCursor->bits->argb) {
189*4882a593Smuzhiyun PixmapPtr pPixmap;
190*4882a593Smuzhiyun PictFormatPtr pFormat;
191*4882a593Smuzhiyun int error;
192*4882a593Smuzhiyun PicturePtr pPicture;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
195*4882a593Smuzhiyun if (!pFormat)
196*4882a593Smuzhiyun return FALSE;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
199*4882a593Smuzhiyun pCursor->bits->height, 32,
200*4882a593Smuzhiyun CREATE_PIXMAP_USAGE_SCRATCH);
201*4882a593Smuzhiyun if (!pPixmap)
202*4882a593Smuzhiyun return FALSE;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun pGC = GetScratchGC(32, pScreen);
205*4882a593Smuzhiyun if (!pGC) {
206*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pPixmap);
207*4882a593Smuzhiyun return FALSE;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun ValidateGC(&pPixmap->drawable, pGC);
210*4882a593Smuzhiyun (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32,
211*4882a593Smuzhiyun 0, 0, pCursor->bits->width,
212*4882a593Smuzhiyun pCursor->bits->height,
213*4882a593Smuzhiyun 0, ZPixmap, (char *) pCursor->bits->argb);
214*4882a593Smuzhiyun FreeScratchGC(pGC);
215*4882a593Smuzhiyun pPicture = CreatePicture(0, &pPixmap->drawable,
216*4882a593Smuzhiyun pFormat, 0, 0, serverClient, &error);
217*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pPixmap);
218*4882a593Smuzhiyun if (!pPicture)
219*4882a593Smuzhiyun return FALSE;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun miDCSwitchScreenCursor(pScreen, pCursor, NULL, NULL, pPicture);
222*4882a593Smuzhiyun return TRUE;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
226*4882a593Smuzhiyun pCursor->bits->height, 1, 0);
227*4882a593Smuzhiyun if (!sourceBits)
228*4882a593Smuzhiyun return FALSE;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
231*4882a593Smuzhiyun pCursor->bits->height, 1, 0);
232*4882a593Smuzhiyun if (!maskBits) {
233*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (sourceBits);
234*4882a593Smuzhiyun return FALSE;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* create the two sets of bits, clipping as appropriate */
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun pGC = GetScratchGC(1, pScreen);
240*4882a593Smuzhiyun if (!pGC) {
241*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (sourceBits);
242*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (maskBits);
243*4882a593Smuzhiyun return FALSE;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun ValidateGC((DrawablePtr) sourceBits, pGC);
247*4882a593Smuzhiyun (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1,
248*4882a593Smuzhiyun 0, 0, pCursor->bits->width, pCursor->bits->height,
249*4882a593Smuzhiyun 0, XYPixmap, (char *) pCursor->bits->source);
250*4882a593Smuzhiyun gcvals.val = GXand;
251*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCFunction, &gcvals);
252*4882a593Smuzhiyun ValidateGC((DrawablePtr) sourceBits, pGC);
253*4882a593Smuzhiyun (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1,
254*4882a593Smuzhiyun 0, 0, pCursor->bits->width, pCursor->bits->height,
255*4882a593Smuzhiyun 0, XYPixmap, (char *) pCursor->bits->mask);
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun /* mask bits -- pCursor->mask & ~pCursor->source */
258*4882a593Smuzhiyun gcvals.val = GXcopy;
259*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCFunction, &gcvals);
260*4882a593Smuzhiyun ValidateGC((DrawablePtr) maskBits, pGC);
261*4882a593Smuzhiyun (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1,
262*4882a593Smuzhiyun 0, 0, pCursor->bits->width, pCursor->bits->height,
263*4882a593Smuzhiyun 0, XYPixmap, (char *) pCursor->bits->mask);
264*4882a593Smuzhiyun gcvals.val = GXandInverted;
265*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCFunction, &gcvals);
266*4882a593Smuzhiyun ValidateGC((DrawablePtr) maskBits, pGC);
267*4882a593Smuzhiyun (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1,
268*4882a593Smuzhiyun 0, 0, pCursor->bits->width, pCursor->bits->height,
269*4882a593Smuzhiyun 0, XYPixmap, (char *) pCursor->bits->source);
270*4882a593Smuzhiyun FreeScratchGC(pGC);
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun miDCSwitchScreenCursor(pScreen, pCursor, sourceBits, maskBits, NULL);
273*4882a593Smuzhiyun return TRUE;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun Bool
miDCUnrealizeCursor(ScreenPtr pScreen,CursorPtr pCursor)277*4882a593Smuzhiyun miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun if (pCursor == pScreenPriv->pCursor)
282*4882a593Smuzhiyun miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
283*4882a593Smuzhiyun return TRUE;
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun static void
miDCPutBits(DrawablePtr pDrawable,GCPtr sourceGC,GCPtr maskGC,int x_org,int y_org,unsigned w,unsigned h,unsigned long source,unsigned long mask)287*4882a593Smuzhiyun miDCPutBits(DrawablePtr pDrawable,
288*4882a593Smuzhiyun GCPtr sourceGC,
289*4882a593Smuzhiyun GCPtr maskGC,
290*4882a593Smuzhiyun int x_org,
291*4882a593Smuzhiyun int y_org,
292*4882a593Smuzhiyun unsigned w, unsigned h, unsigned long source, unsigned long mask)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun miDCScreenPtr pScreenPriv = dixLookupPrivate(&pDrawable->pScreen->devPrivates, miDCScreenKey);
295*4882a593Smuzhiyun ChangeGCVal gcval;
296*4882a593Smuzhiyun int x, y;
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun if (sourceGC->fgPixel != source) {
299*4882a593Smuzhiyun gcval.val = source;
300*4882a593Smuzhiyun ChangeGC(NullClient, sourceGC, GCForeground, &gcval);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun if (sourceGC->serialNumber != pDrawable->serialNumber)
303*4882a593Smuzhiyun ValidateGC(pDrawable, sourceGC);
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun if (sourceGC->miTranslate) {
306*4882a593Smuzhiyun x = pDrawable->x + x_org;
307*4882a593Smuzhiyun y = pDrawable->y + y_org;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun else {
310*4882a593Smuzhiyun x = x_org;
311*4882a593Smuzhiyun y = y_org;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun (*sourceGC->ops->PushPixels) (sourceGC, pScreenPriv->sourceBits, pDrawable, w, h,
315*4882a593Smuzhiyun x, y);
316*4882a593Smuzhiyun if (maskGC->fgPixel != mask) {
317*4882a593Smuzhiyun gcval.val = mask;
318*4882a593Smuzhiyun ChangeGC(NullClient, maskGC, GCForeground, &gcval);
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun if (maskGC->serialNumber != pDrawable->serialNumber)
321*4882a593Smuzhiyun ValidateGC(pDrawable, maskGC);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun if (maskGC->miTranslate) {
324*4882a593Smuzhiyun x = pDrawable->x + x_org;
325*4882a593Smuzhiyun y = pDrawable->y + y_org;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun else {
328*4882a593Smuzhiyun x = x_org;
329*4882a593Smuzhiyun y = y_org;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun (*maskGC->ops->PushPixels) (maskGC, pScreenPriv->maskBits, pDrawable, w, h, x, y);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun static GCPtr
miDCMakeGC(WindowPtr pWin)336*4882a593Smuzhiyun miDCMakeGC(WindowPtr pWin)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun GCPtr pGC;
339*4882a593Smuzhiyun int status;
340*4882a593Smuzhiyun XID gcvals[2];
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun gcvals[0] = IncludeInferiors;
343*4882a593Smuzhiyun gcvals[1] = FALSE;
344*4882a593Smuzhiyun pGC = CreateGC((DrawablePtr) pWin,
345*4882a593Smuzhiyun GCSubwindowMode | GCGraphicsExposures, gcvals, &status,
346*4882a593Smuzhiyun (XID) 0, serverClient);
347*4882a593Smuzhiyun return pGC;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun Bool
miDCPutUpCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor,int x,int y,unsigned long source,unsigned long mask)351*4882a593Smuzhiyun miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
352*4882a593Smuzhiyun int x, int y, unsigned long source, unsigned long mask)
353*4882a593Smuzhiyun {
354*4882a593Smuzhiyun miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
355*4882a593Smuzhiyun miDCBufferPtr pBuffer;
356*4882a593Smuzhiyun WindowPtr pWin;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun if (!miDCRealize(pScreen, pCursor))
359*4882a593Smuzhiyun return FALSE;
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun pWin = pScreen->root;
362*4882a593Smuzhiyun pBuffer = miGetDCDevice(pDev, pScreen);
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun if (pScreenPriv->pPicture) {
365*4882a593Smuzhiyun if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
366*4882a593Smuzhiyun return FALSE;
367*4882a593Smuzhiyun CompositePicture(PictOpOver,
368*4882a593Smuzhiyun pScreenPriv->pPicture,
369*4882a593Smuzhiyun NULL,
370*4882a593Smuzhiyun pBuffer->pRootPicture,
371*4882a593Smuzhiyun 0, 0, 0, 0,
372*4882a593Smuzhiyun x, y, pCursor->bits->width, pCursor->bits->height);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun else
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun miDCPutBits((DrawablePtr) pWin,
377*4882a593Smuzhiyun pBuffer->pSourceGC, pBuffer->pMaskGC,
378*4882a593Smuzhiyun x, y, pCursor->bits->width, pCursor->bits->height,
379*4882a593Smuzhiyun source, mask);
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun return TRUE;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun Bool
miDCSaveUnderCursor(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y,int w,int h)385*4882a593Smuzhiyun miDCSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
386*4882a593Smuzhiyun int x, int y, int w, int h)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun miDCBufferPtr pBuffer;
389*4882a593Smuzhiyun PixmapPtr pSave;
390*4882a593Smuzhiyun WindowPtr pWin;
391*4882a593Smuzhiyun GCPtr pGC;
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun pBuffer = miGetDCDevice(pDev, pScreen);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun pSave = pBuffer->pSave;
396*4882a593Smuzhiyun pWin = pScreen->root;
397*4882a593Smuzhiyun if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) {
398*4882a593Smuzhiyun if (pSave)
399*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pSave);
400*4882a593Smuzhiyun pBuffer->pSave = pSave =
401*4882a593Smuzhiyun (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0);
402*4882a593Smuzhiyun if (!pSave)
403*4882a593Smuzhiyun return FALSE;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun pGC = pBuffer->pSaveGC;
407*4882a593Smuzhiyun if (pSave->drawable.serialNumber != pGC->serialNumber)
408*4882a593Smuzhiyun ValidateGC((DrawablePtr) pSave, pGC);
409*4882a593Smuzhiyun (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
410*4882a593Smuzhiyun x, y, w, h, 0, 0);
411*4882a593Smuzhiyun return TRUE;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun Bool
miDCRestoreUnderCursor(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y,int w,int h)415*4882a593Smuzhiyun miDCRestoreUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
416*4882a593Smuzhiyun int x, int y, int w, int h)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun miDCBufferPtr pBuffer;
419*4882a593Smuzhiyun PixmapPtr pSave;
420*4882a593Smuzhiyun WindowPtr pWin;
421*4882a593Smuzhiyun GCPtr pGC;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun pBuffer = miGetDCDevice(pDev, pScreen);
424*4882a593Smuzhiyun pSave = pBuffer->pSave;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun pWin = pScreen->root;
427*4882a593Smuzhiyun if (!pSave)
428*4882a593Smuzhiyun return FALSE;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun pGC = pBuffer->pRestoreGC;
431*4882a593Smuzhiyun if (pWin->drawable.serialNumber != pGC->serialNumber)
432*4882a593Smuzhiyun ValidateGC((DrawablePtr) pWin, pGC);
433*4882a593Smuzhiyun (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
434*4882a593Smuzhiyun 0, 0, w, h, x, y);
435*4882a593Smuzhiyun return TRUE;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun Bool
miDCDeviceInitialize(DeviceIntPtr pDev,ScreenPtr pScreen)439*4882a593Smuzhiyun miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun miDCBufferPtr pBuffer;
442*4882a593Smuzhiyun WindowPtr pWin;
443*4882a593Smuzhiyun int i;
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun if (!DevHasCursor(pDev))
446*4882a593Smuzhiyun return TRUE;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
449*4882a593Smuzhiyun pScreen = screenInfo.screens[i];
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun pBuffer = calloc(1, sizeof(miDCBufferRec));
452*4882a593Smuzhiyun if (!pBuffer)
453*4882a593Smuzhiyun goto failure;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen,
456*4882a593Smuzhiyun pBuffer);
457*4882a593Smuzhiyun pWin = pScreen->root;
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun pBuffer->pSourceGC = miDCMakeGC(pWin);
460*4882a593Smuzhiyun if (!pBuffer->pSourceGC)
461*4882a593Smuzhiyun goto failure;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun pBuffer->pMaskGC = miDCMakeGC(pWin);
464*4882a593Smuzhiyun if (!pBuffer->pMaskGC)
465*4882a593Smuzhiyun goto failure;
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun pBuffer->pSaveGC = miDCMakeGC(pWin);
468*4882a593Smuzhiyun if (!pBuffer->pSaveGC)
469*4882a593Smuzhiyun goto failure;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun pBuffer->pRestoreGC = miDCMakeGC(pWin);
472*4882a593Smuzhiyun if (!pBuffer->pRestoreGC)
473*4882a593Smuzhiyun goto failure;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun pBuffer->pRootPicture = NULL;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun /* (re)allocated lazily depending on the cursor size */
478*4882a593Smuzhiyun pBuffer->pSave = NULL;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun return TRUE;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun failure:
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun miDCDeviceCleanup(pDev, pScreen);
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun return FALSE;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun void
miDCDeviceCleanup(DeviceIntPtr pDev,ScreenPtr pScreen)491*4882a593Smuzhiyun miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
492*4882a593Smuzhiyun {
493*4882a593Smuzhiyun miDCBufferPtr pBuffer;
494*4882a593Smuzhiyun int i;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun if (DevHasCursor(pDev)) {
497*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
498*4882a593Smuzhiyun pScreen = screenInfo.screens[i];
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun pBuffer = miGetDCDevice(pDev, pScreen);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun if (pBuffer) {
503*4882a593Smuzhiyun if (pBuffer->pSourceGC)
504*4882a593Smuzhiyun FreeGC(pBuffer->pSourceGC, (GContext) 0);
505*4882a593Smuzhiyun if (pBuffer->pMaskGC)
506*4882a593Smuzhiyun FreeGC(pBuffer->pMaskGC, (GContext) 0);
507*4882a593Smuzhiyun if (pBuffer->pSaveGC)
508*4882a593Smuzhiyun FreeGC(pBuffer->pSaveGC, (GContext) 0);
509*4882a593Smuzhiyun if (pBuffer->pRestoreGC)
510*4882a593Smuzhiyun FreeGC(pBuffer->pRestoreGC, (GContext) 0);
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun /* If a pRootPicture was allocated for a root window, it
513*4882a593Smuzhiyun * is freed when that root window is destroyed, so don't
514*4882a593Smuzhiyun * free it again here. */
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun if (pBuffer->pSave)
517*4882a593Smuzhiyun (*pScreen->DestroyPixmap) (pBuffer->pSave);
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun free(pBuffer);
520*4882a593Smuzhiyun dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen,
521*4882a593Smuzhiyun NULL);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun }
526