1*4882a593Smuzhiyun /**************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Xplugin cursor support
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
6*4882a593Smuzhiyun * Copyright (c) 2002 Apple Computer, Inc.
7*4882a593Smuzhiyun * All Rights Reserved.
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
10*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
11*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
12*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
14*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
17*4882a593Smuzhiyun * all copies or substantial portions of the Software.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22*4882a593Smuzhiyun * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * Except as contained in this notice, the name(s) of the above copyright
28*4882a593Smuzhiyun * holders shall not be used in advertising or otherwise to promote the sale,
29*4882a593Smuzhiyun * use or other dealings in this Software without prior written authorization.
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include "sanitizedCarbon.h"
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
35*4882a593Smuzhiyun #include <dix-config.h>
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #include "quartz.h"
39*4882a593Smuzhiyun #include "xpr.h"
40*4882a593Smuzhiyun #include "darwinEvents.h"
41*4882a593Smuzhiyun #include <Xplugin.h>
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #include "mi.h"
44*4882a593Smuzhiyun #include "scrnintstr.h"
45*4882a593Smuzhiyun #include "cursorstr.h"
46*4882a593Smuzhiyun #include "mipointrst.h"
47*4882a593Smuzhiyun #include "windowstr.h"
48*4882a593Smuzhiyun #include "globals.h"
49*4882a593Smuzhiyun #include "servermd.h"
50*4882a593Smuzhiyun #include "dixevents.h"
51*4882a593Smuzhiyun #include "x-hash.h"
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun typedef struct {
54*4882a593Smuzhiyun int cursorVisible;
55*4882a593Smuzhiyun QueryBestSizeProcPtr QueryBestSize;
56*4882a593Smuzhiyun miPointerSpriteFuncPtr spriteFuncs;
57*4882a593Smuzhiyun } QuartzCursorScreenRec, *QuartzCursorScreenPtr;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun static DevPrivateKeyRec darwinCursorScreenKeyRec;
60*4882a593Smuzhiyun #define darwinCursorScreenKey (&darwinCursorScreenKeyRec)
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun #define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
63*4882a593Smuzhiyun dixLookupPrivate(&pScreen->devPrivates, \
64*4882a593Smuzhiyun darwinCursorScreenKey))
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun static Bool
load_cursor(CursorPtr src,int screen)67*4882a593Smuzhiyun load_cursor(CursorPtr src, int screen)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun uint32_t *data;
70*4882a593Smuzhiyun Bool free_data = FALSE;
71*4882a593Smuzhiyun uint32_t rowbytes;
72*4882a593Smuzhiyun int width, height;
73*4882a593Smuzhiyun int hot_x, hot_y;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun uint32_t fg_color, bg_color;
76*4882a593Smuzhiyun uint8_t *srow, *sptr;
77*4882a593Smuzhiyun uint8_t *mrow, *mptr;
78*4882a593Smuzhiyun uint32_t *drow, *dptr;
79*4882a593Smuzhiyun unsigned xcount, ycount;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun xp_error err;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun width = src->bits->width;
84*4882a593Smuzhiyun height = src->bits->height;
85*4882a593Smuzhiyun hot_x = src->bits->xhot;
86*4882a593Smuzhiyun hot_y = src->bits->yhot;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun if (src->bits->argb != NULL) {
89*4882a593Smuzhiyun #if BITMAP_BIT_ORDER == MSBFirst
90*4882a593Smuzhiyun rowbytes = src->bits->width * sizeof(CARD32);
91*4882a593Smuzhiyun data = (uint32_t *)src->bits->argb;
92*4882a593Smuzhiyun #else
93*4882a593Smuzhiyun const uint32_t *be_data = (uint32_t *)src->bits->argb;
94*4882a593Smuzhiyun unsigned i;
95*4882a593Smuzhiyun rowbytes = src->bits->width * sizeof(CARD32);
96*4882a593Smuzhiyun data = malloc(rowbytes * src->bits->height);
97*4882a593Smuzhiyun free_data = TRUE;
98*4882a593Smuzhiyun if (!data) {
99*4882a593Smuzhiyun FatalError("Failed to allocate memory in %s\n", __func__);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun for (i = 0; i < (src->bits->width * src->bits->height); i++)
102*4882a593Smuzhiyun data[i] = ntohl(be_data[i]);
103*4882a593Smuzhiyun #endif
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun else
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun fg_color = 0xFF00 | (src->foreRed >> 8);
108*4882a593Smuzhiyun fg_color <<= 16;
109*4882a593Smuzhiyun fg_color |= src->foreGreen & 0xFF00;
110*4882a593Smuzhiyun fg_color |= src->foreBlue >> 8;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun bg_color = 0xFF00 | (src->backRed >> 8);
113*4882a593Smuzhiyun bg_color <<= 16;
114*4882a593Smuzhiyun bg_color |= src->backGreen & 0xFF00;
115*4882a593Smuzhiyun bg_color |= src->backBlue >> 8;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun fg_color = htonl(fg_color);
118*4882a593Smuzhiyun bg_color = htonl(bg_color);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* round up to 8 pixel boundary so we can convert whole bytes */
121*4882a593Smuzhiyun rowbytes = ((src->bits->width * 4) + 31) & ~31;
122*4882a593Smuzhiyun data = malloc(rowbytes * src->bits->height);
123*4882a593Smuzhiyun free_data = TRUE;
124*4882a593Smuzhiyun if (!data) {
125*4882a593Smuzhiyun FatalError("Failed to allocate memory in %s\n", __func__);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun if (!src->bits->emptyMask) {
129*4882a593Smuzhiyun ycount = src->bits->height;
130*4882a593Smuzhiyun srow = src->bits->source;
131*4882a593Smuzhiyun mrow = src->bits->mask;
132*4882a593Smuzhiyun drow = data;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun while (ycount-- > 0)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun xcount = bits_to_bytes(src->bits->width);
137*4882a593Smuzhiyun sptr = srow;
138*4882a593Smuzhiyun mptr = mrow;
139*4882a593Smuzhiyun dptr = drow;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun while (xcount-- > 0)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun uint8_t s, m;
144*4882a593Smuzhiyun int i;
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun s = *sptr++;
147*4882a593Smuzhiyun m = *mptr++;
148*4882a593Smuzhiyun for (i = 0; i < 8; i++) {
149*4882a593Smuzhiyun #if BITMAP_BIT_ORDER == MSBFirst
150*4882a593Smuzhiyun if (m & 128)
151*4882a593Smuzhiyun *dptr++ = (s & 128) ? fg_color : bg_color;
152*4882a593Smuzhiyun else
153*4882a593Smuzhiyun *dptr++ = 0;
154*4882a593Smuzhiyun s <<= 1;
155*4882a593Smuzhiyun m <<= 1;
156*4882a593Smuzhiyun #else
157*4882a593Smuzhiyun if (m & 1)
158*4882a593Smuzhiyun *dptr++ = (s & 1) ? fg_color : bg_color;
159*4882a593Smuzhiyun else
160*4882a593Smuzhiyun *dptr++ = 0;
161*4882a593Smuzhiyun s >>= 1;
162*4882a593Smuzhiyun m >>= 1;
163*4882a593Smuzhiyun #endif
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun srow += BitmapBytePad(src->bits->width);
168*4882a593Smuzhiyun mrow += BitmapBytePad(src->bits->width);
169*4882a593Smuzhiyun drow = (uint32_t *)((char *)drow + rowbytes);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun else {
173*4882a593Smuzhiyun memset(data, 0, src->bits->height * rowbytes);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
178*4882a593Smuzhiyun if (free_data)
179*4882a593Smuzhiyun free(data);
180*4882a593Smuzhiyun return err == Success;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /*
184*4882a593Smuzhiyun ===========================================================================
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun Pointer sprite functions
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun ===========================================================================
189*4882a593Smuzhiyun */
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun /*
192*4882a593Smuzhiyun * QuartzRealizeCursor
193*4882a593Smuzhiyun * Convert the X cursor representation to native format if possible.
194*4882a593Smuzhiyun */
195*4882a593Smuzhiyun static Bool
QuartzRealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)196*4882a593Smuzhiyun QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun if (pCursor == NULL || pCursor->bits == NULL)
199*4882a593Smuzhiyun return FALSE;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* FIXME: cache ARGB8888 representation? */
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun return TRUE;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun /*
207*4882a593Smuzhiyun * QuartzUnrealizeCursor
208*4882a593Smuzhiyun * Free the storage space associated with a realized cursor.
209*4882a593Smuzhiyun */
210*4882a593Smuzhiyun static Bool
QuartzUnrealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)211*4882a593Smuzhiyun QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun return TRUE;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /*
217*4882a593Smuzhiyun * QuartzSetCursor
218*4882a593Smuzhiyun * Set the cursor sprite and position.
219*4882a593Smuzhiyun */
220*4882a593Smuzhiyun static void
QuartzSetCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor,int x,int y)221*4882a593Smuzhiyun QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
222*4882a593Smuzhiyun int x,
223*4882a593Smuzhiyun int y)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (!XQuartzServerVisible)
228*4882a593Smuzhiyun return;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (pCursor == NULL) {
231*4882a593Smuzhiyun if (ScreenPriv->cursorVisible) {
232*4882a593Smuzhiyun xp_hide_cursor();
233*4882a593Smuzhiyun ScreenPriv->cursorVisible = FALSE;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun else {
237*4882a593Smuzhiyun load_cursor(pCursor, pScreen->myNum);
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (!ScreenPriv->cursorVisible) {
240*4882a593Smuzhiyun xp_show_cursor();
241*4882a593Smuzhiyun ScreenPriv->cursorVisible = TRUE;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /*
247*4882a593Smuzhiyun * QuartzMoveCursor
248*4882a593Smuzhiyun * Move the cursor. This is a noop for us.
249*4882a593Smuzhiyun */
250*4882a593Smuzhiyun static void
QuartzMoveCursor(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y)251*4882a593Smuzhiyun QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
252*4882a593Smuzhiyun {}
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun /*
255*4882a593Smuzhiyun ===========================================================================
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun Pointer screen functions
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun ===========================================================================
260*4882a593Smuzhiyun */
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun /*
263*4882a593Smuzhiyun * QuartzCursorOffScreen
264*4882a593Smuzhiyun */
265*4882a593Smuzhiyun static Bool
QuartzCursorOffScreen(ScreenPtr * pScreen,int * x,int * y)266*4882a593Smuzhiyun QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun return FALSE;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /*
272*4882a593Smuzhiyun * QuartzCrossScreen
273*4882a593Smuzhiyun */
274*4882a593Smuzhiyun static void
QuartzCrossScreen(ScreenPtr pScreen,Bool entering)275*4882a593Smuzhiyun QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun return;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * QuartzWarpCursor
282*4882a593Smuzhiyun * Change the cursor position without generating an event or motion history.
283*4882a593Smuzhiyun * The input coordinates (x,y) are in pScreen-local X11 coordinates.
284*4882a593Smuzhiyun *
285*4882a593Smuzhiyun */
286*4882a593Smuzhiyun static void
QuartzWarpCursor(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y)287*4882a593Smuzhiyun QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun if (XQuartzServerVisible) {
290*4882a593Smuzhiyun int sx, sy;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun sx = pScreen->x + darwinMainScreenX;
293*4882a593Smuzhiyun sy = pScreen->y + darwinMainScreenY;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun miPointerWarpCursor(pDev, pScreen, x, y);
299*4882a593Smuzhiyun miPointerUpdateSprite(pDev);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun static miPointerScreenFuncRec quartzScreenFuncsRec = {
303*4882a593Smuzhiyun QuartzCursorOffScreen,
304*4882a593Smuzhiyun QuartzCrossScreen,
305*4882a593Smuzhiyun QuartzWarpCursor,
306*4882a593Smuzhiyun };
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun /*
309*4882a593Smuzhiyun ===========================================================================
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun Other screen functions
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun ===========================================================================
314*4882a593Smuzhiyun */
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun /*
317*4882a593Smuzhiyun * QuartzCursorQueryBestSize
318*4882a593Smuzhiyun * Handle queries for best cursor size
319*4882a593Smuzhiyun */
320*4882a593Smuzhiyun static void
QuartzCursorQueryBestSize(int class,unsigned short * width,unsigned short * height,ScreenPtr pScreen)321*4882a593Smuzhiyun QuartzCursorQueryBestSize(int class, unsigned short *width,
322*4882a593Smuzhiyun unsigned short *height, ScreenPtr pScreen)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun if (class == CursorShape) {
327*4882a593Smuzhiyun /* FIXME: query window server? */
328*4882a593Smuzhiyun *width = 32;
329*4882a593Smuzhiyun *height = 32;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun else {
332*4882a593Smuzhiyun (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /*
337*4882a593Smuzhiyun * QuartzInitCursor
338*4882a593Smuzhiyun * Initialize cursor support
339*4882a593Smuzhiyun */
340*4882a593Smuzhiyun Bool
QuartzInitCursor(ScreenPtr pScreen)341*4882a593Smuzhiyun QuartzInitCursor(ScreenPtr pScreen)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun QuartzCursorScreenPtr ScreenPriv;
344*4882a593Smuzhiyun miPointerScreenPtr PointPriv;
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun /* initialize software cursor handling (always needed as backup) */
347*4882a593Smuzhiyun if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
348*4882a593Smuzhiyun return FALSE;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&darwinCursorScreenKeyRec, PRIVATE_SCREEN, 0))
351*4882a593Smuzhiyun return FALSE;
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec));
354*4882a593Smuzhiyun if (ScreenPriv == NULL)
355*4882a593Smuzhiyun return FALSE;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun /* CURSOR_PRIV(pScreen) = ScreenPriv; */
358*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun /* override some screen procedures */
361*4882a593Smuzhiyun ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
362*4882a593Smuzhiyun pScreen->QueryBestSize = QuartzCursorQueryBestSize;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor;
369*4882a593Smuzhiyun PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor;
370*4882a593Smuzhiyun PointPriv->spriteFuncs->SetCursor = QuartzSetCursor;
371*4882a593Smuzhiyun PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun ScreenPriv->cursorVisible = TRUE;
374*4882a593Smuzhiyun return TRUE;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /*
378*4882a593Smuzhiyun * QuartzSuspendXCursor
379*4882a593Smuzhiyun * X server is hiding. Restore the Aqua cursor.
380*4882a593Smuzhiyun */
381*4882a593Smuzhiyun void
QuartzSuspendXCursor(ScreenPtr pScreen)382*4882a593Smuzhiyun QuartzSuspendXCursor(ScreenPtr pScreen)
383*4882a593Smuzhiyun {}
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun /*
386*4882a593Smuzhiyun * QuartzResumeXCursor
387*4882a593Smuzhiyun * X server is showing. Restore the X cursor.
388*4882a593Smuzhiyun */
389*4882a593Smuzhiyun void
QuartzResumeXCursor(ScreenPtr pScreen)390*4882a593Smuzhiyun QuartzResumeXCursor(ScreenPtr pScreen)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun WindowPtr pWin;
393*4882a593Smuzhiyun CursorPtr pCursor;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /* TODO: Tablet? */
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun pWin = GetSpriteWindow(darwinPointer);
398*4882a593Smuzhiyun if (pWin->drawable.pScreen != pScreen)
399*4882a593Smuzhiyun return;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun pCursor = GetSpriteCursor(darwinPointer);
402*4882a593Smuzhiyun if (pCursor == NULL)
403*4882a593Smuzhiyun return;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0);
406*4882a593Smuzhiyun }
407