1 /**************************************************************
3 * Xplugin cursor support
5 * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
6 * Copyright (c) 2002 Apple Computer, Inc.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
27 * Except as contained in this notice, the name(s) of the above copyright
28 * holders shall not be used in advertising or otherwise to promote the sale,
29 * use or other dealings in this Software without prior written authorization.
32 #include "sanitizedCarbon.h"
34 #ifdef HAVE_DIX_CONFIG_H
35 #include <dix-config.h>
40 #include "darwinEvents.h"
44 #include "scrnintstr.h"
45 #include "cursorstr.h"
46 #include "mipointrst.h"
47 #include "windowstr.h"
50 #include "dixevents.h"
55 QueryBestSizeProcPtr QueryBestSize
;
56 miPointerSpriteFuncPtr spriteFuncs
;
57 } QuartzCursorScreenRec
, *QuartzCursorScreenPtr
;
59 static DevPrivateKeyRec darwinCursorScreenKeyRec
;
60 #define darwinCursorScreenKey (&darwinCursorScreenKeyRec)
62 #define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
63 dixLookupPrivate(&pScreen->devPrivates, \
64 darwinCursorScreenKey))
67 load_cursor(CursorPtr src
, int screen
)
70 Bool free_data
= FALSE
;
75 uint32_t fg_color
, bg_color
;
78 uint32_t *drow
, *dptr
;
79 unsigned xcount
, ycount
;
83 width
= src
->bits
->width
;
84 height
= src
->bits
->height
;
85 hot_x
= src
->bits
->xhot
;
86 hot_y
= src
->bits
->yhot
;
89 if (src
->bits
->argb
!= NULL
) {
90 #if BITMAP_BIT_ORDER == MSBFirst
91 rowbytes
= src
->bits
->width
* sizeof(CARD32
);
92 data
= (uint32_t *)src
->bits
->argb
;
94 const uint32_t *be_data
= (uint32_t *)src
->bits
->argb
;
96 rowbytes
= src
->bits
->width
* sizeof(CARD32
);
97 data
= malloc(rowbytes
* src
->bits
->height
);
100 FatalError("Failed to allocate memory in %s\n", __func__
);
102 for (i
= 0; i
< (src
->bits
->width
* src
->bits
->height
); i
++)
103 data
[i
] = ntohl(be_data
[i
]);
109 fg_color
= 0xFF00 | (src
->foreRed
>> 8);
111 fg_color
|= src
->foreGreen
& 0xFF00;
112 fg_color
|= src
->foreBlue
>> 8;
114 bg_color
= 0xFF00 | (src
->backRed
>> 8);
116 bg_color
|= src
->backGreen
& 0xFF00;
117 bg_color
|= src
->backBlue
>> 8;
119 fg_color
= htonl(fg_color
);
120 bg_color
= htonl(bg_color
);
122 /* round up to 8 pixel boundary so we can convert whole bytes */
123 rowbytes
= ((src
->bits
->width
* 4) + 31) & ~31;
124 data
= malloc(rowbytes
* src
->bits
->height
);
127 FatalError("Failed to allocate memory in %s\n", __func__
);
130 if (!src
->bits
->emptyMask
) {
131 ycount
= src
->bits
->height
;
132 srow
= src
->bits
->source
;
133 mrow
= src
->bits
->mask
;
138 xcount
= bits_to_bytes(src
->bits
->width
);
150 for (i
= 0; i
< 8; i
++) {
151 #if BITMAP_BIT_ORDER == MSBFirst
153 *dptr
++ = (s
& 128) ? fg_color
: bg_color
;
160 *dptr
++ = (s
& 1) ? fg_color
: bg_color
;
169 srow
+= BitmapBytePad(src
->bits
->width
);
170 mrow
+= BitmapBytePad(src
->bits
->width
);
171 drow
= (uint32_t *)((char *)drow
+ rowbytes
);
175 memset(data
, 0, src
->bits
->height
* rowbytes
);
179 err
= xp_set_cursor(width
, height
, hot_x
, hot_y
, data
, rowbytes
);
182 return err
== Success
;
186 ===========================================================================
188 Pointer sprite functions
190 ===========================================================================
194 * QuartzRealizeCursor
195 * Convert the X cursor representation to native format if possible.
198 QuartzRealizeCursor(DeviceIntPtr pDev
, ScreenPtr pScreen
, CursorPtr pCursor
)
200 if (pCursor
== NULL
|| pCursor
->bits
== NULL
)
203 /* FIXME: cache ARGB8888 representation? */
209 * QuartzUnrealizeCursor
210 * Free the storage space associated with a realized cursor.
213 QuartzUnrealizeCursor(DeviceIntPtr pDev
, ScreenPtr pScreen
, CursorPtr pCursor
)
220 * Set the cursor sprite and position.
223 QuartzSetCursor(DeviceIntPtr pDev
, ScreenPtr pScreen
, CursorPtr pCursor
,
227 QuartzCursorScreenPtr ScreenPriv
= CURSOR_PRIV(pScreen
);
229 if (!XQuartzServerVisible
)
232 if (pCursor
== NULL
) {
233 if (ScreenPriv
->cursorVisible
) {
235 ScreenPriv
->cursorVisible
= FALSE
;
239 load_cursor(pCursor
, pScreen
->myNum
);
241 if (!ScreenPriv
->cursorVisible
) {
243 ScreenPriv
->cursorVisible
= TRUE
;
250 * Move the cursor. This is a noop for us.
253 QuartzMoveCursor(DeviceIntPtr pDev
, ScreenPtr pScreen
, int x
, int y
)
257 ===========================================================================
259 Pointer screen functions
261 ===========================================================================
265 * QuartzCursorOffScreen
268 QuartzCursorOffScreen(ScreenPtr
*pScreen
, int *x
, int *y
)
277 QuartzCrossScreen(ScreenPtr pScreen
, Bool entering
)
284 * Change the cursor position without generating an event or motion history.
285 * The input coordinates (x,y) are in pScreen-local X11 coordinates.
289 QuartzWarpCursor(DeviceIntPtr pDev
, ScreenPtr pScreen
, int x
, int y
)
291 if (XQuartzServerVisible
) {
294 sx
= pScreen
->x
+ darwinMainScreenX
;
295 sy
= pScreen
->y
+ darwinMainScreenY
;
297 CGWarpMouseCursorPosition(CGPointMake(sx
+ x
, sy
+ y
));
300 miPointerWarpCursor(pDev
, pScreen
, x
, y
);
301 miPointerUpdateSprite(pDev
);
304 static miPointerScreenFuncRec quartzScreenFuncsRec
= {
305 QuartzCursorOffScreen
,
311 ===========================================================================
313 Other screen functions
315 ===========================================================================
319 * QuartzCursorQueryBestSize
320 * Handle queries for best cursor size
323 QuartzCursorQueryBestSize(int class, unsigned short *width
,
324 unsigned short *height
, ScreenPtr pScreen
)
326 QuartzCursorScreenPtr ScreenPriv
= CURSOR_PRIV(pScreen
);
328 if (class == CursorShape
) {
329 /* FIXME: query window server? */
334 (*ScreenPriv
->QueryBestSize
)(class, width
, height
, pScreen
);
340 * Initialize cursor support
343 QuartzInitCursor(ScreenPtr pScreen
)
345 QuartzCursorScreenPtr ScreenPriv
;
346 miPointerScreenPtr PointPriv
;
348 /* initialize software cursor handling (always needed as backup) */
349 if (!miDCInitialize(pScreen
, &quartzScreenFuncsRec
))
352 if (!dixRegisterPrivateKey(&darwinCursorScreenKeyRec
, PRIVATE_SCREEN
, 0))
355 ScreenPriv
= calloc(1, sizeof(QuartzCursorScreenRec
));
356 if (ScreenPriv
== NULL
)
359 /* CURSOR_PRIV(pScreen) = ScreenPriv; */
360 dixSetPrivate(&pScreen
->devPrivates
, darwinCursorScreenKey
, ScreenPriv
);
362 /* override some screen procedures */
363 ScreenPriv
->QueryBestSize
= pScreen
->QueryBestSize
;
364 pScreen
->QueryBestSize
= QuartzCursorQueryBestSize
;
366 PointPriv
= dixLookupPrivate(&pScreen
->devPrivates
, miPointerScreenKey
);
368 ScreenPriv
->spriteFuncs
= PointPriv
->spriteFuncs
;
370 PointPriv
->spriteFuncs
->RealizeCursor
= QuartzRealizeCursor
;
371 PointPriv
->spriteFuncs
->UnrealizeCursor
= QuartzUnrealizeCursor
;
372 PointPriv
->spriteFuncs
->SetCursor
= QuartzSetCursor
;
373 PointPriv
->spriteFuncs
->MoveCursor
= QuartzMoveCursor
;
375 ScreenPriv
->cursorVisible
= TRUE
;
380 * QuartzSuspendXCursor
381 * X server is hiding. Restore the Aqua cursor.
384 QuartzSuspendXCursor(ScreenPtr pScreen
)
388 * QuartzResumeXCursor
389 * X server is showing. Restore the X cursor.
392 QuartzResumeXCursor(ScreenPtr pScreen
)
399 pWin
= GetSpriteWindow(darwinPointer
);
400 if (pWin
->drawable
.pScreen
!= pScreen
)
403 pCursor
= GetSpriteCursor(darwinPointer
);
407 QuartzSetCursor(darwinPointer
, pScreen
, pCursor
, /* x */ 0, /* y */ 0);