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);