1
/**************************************************************
3
* Xplugin cursor support
5
**************************************************************/
7
* Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
8
* Copyright (c) 2002 Apple Computer, Inc.
11
* Permission is hereby granted, free of charge, to any person obtaining a
12
* copy of this software and associated documentation files (the "Software"),
13
* to deal in the Software without restriction, including without limitation
14
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
* and/or sell copies of the Software, and to permit persons to whom the
16
* Software is furnished to do so, subject to the following conditions:
18
* The above copyright notice and this permission notice shall be included in
19
* all copies or substantial portions of the Software.
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
* DEALINGS IN THE SOFTWARE.
29
* Except as contained in this notice, the name(s) of the above copyright
30
* holders shall not be used in advertising or otherwise to promote the sale,
31
* use or other dealings in this Software without prior written authorization.
33
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprCursor.c,v 1.1 2003/04/30 23:15:42 torrey Exp $ */
35
#include "quartzCommon.h"
41
#include "scrnintstr.h"
42
#include "cursorstr.h"
43
#include "mipointrst.h"
44
#include "windowstr.h"
47
#include "dixevents.h"
51
QueryBestSizeProcPtr QueryBestSize;
52
miPointerSpriteFuncPtr spriteFuncs;
53
} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
55
static int darwinCursorScreenIndex = -1;
56
static unsigned long darwinCursorGeneration = 0;
58
#define CURSOR_PRIV(pScreen) \
59
((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
63
load_cursor(CursorPtr src, int screen)
70
uint32_t fg_color, bg_color;
73
uint32_t *drow, *dptr;
74
unsigned xcount, ycount;
78
width = src->bits->width;
79
height = src->bits->height;
80
hot_x = src->bits->xhot;
81
hot_y = src->bits->yhot;
84
if (src->bits->argb != NULL)
86
rowbytes = src->bits->width * sizeof(CARD32);
87
data = (uint32_t *) src->bits->argb;
92
fg_color = 0xFF00 | (src->foreRed >> 8);
94
fg_color |= src->foreGreen & 0xFF00;
95
fg_color |= src->foreBlue >> 8;
97
bg_color = 0xFF00 | (src->backRed >> 8);
99
bg_color |= src->backGreen & 0xFF00;
100
bg_color |= src->backBlue >> 8;
102
fg_color = htonl(fg_color);
103
bg_color = htonl(bg_color);
105
/* round up to 8 pixel boundary so we can convert whole bytes */
106
rowbytes = ((src->bits->width * 4) + 31) & ~31;
107
data = alloca(rowbytes * src->bits->height);
109
if (!src->bits->emptyMask)
111
ycount = src->bits->height;
112
srow = src->bits->source; mrow = src->bits->mask;
117
xcount = (src->bits->width + 7) / 8;
118
sptr = srow; mptr = mrow;
126
s = *sptr++; m = *mptr++;
127
for (i = 0; i < 8; i++)
129
#if BITMAP_BIT_ORDER == MSBFirst
131
*dptr++ = (s & 128) ? fg_color : bg_color;
137
*dptr++ = (s & 1) ? fg_color : bg_color;
145
srow += BitmapBytePad(src->bits->width);
146
mrow += BitmapBytePad(src->bits->width);
147
drow = (uint32_t *) ((char *) drow + rowbytes);
152
memset(data, 0, src->bits->height * rowbytes);
156
err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
157
return err == Success;
162
===========================================================================
164
Pointer sprite functions
166
===========================================================================
170
* QuartzRealizeCursor
171
* Convert the X cursor representation to native format if possible.
174
QuartzRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
176
if(pCursor == NULL || pCursor->bits == NULL)
179
/* FIXME: cache ARGB8888 representation? */
186
* QuartzUnrealizeCursor
187
* Free the storage space associated with a realized cursor.
190
QuartzUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
198
* Set the cursor sprite and position.
201
QuartzSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
203
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
205
if (!quartzServerVisible)
210
if (ScreenPriv->cursorVisible)
213
ScreenPriv->cursorVisible = FALSE;
218
load_cursor(pCursor, pScreen->myNum);
220
if (!ScreenPriv->cursorVisible)
223
ScreenPriv->cursorVisible = TRUE;
231
* Move the cursor. This is a noop for us.
234
QuartzMoveCursor(ScreenPtr pScreen, int x, int y)
239
static miPointerSpriteFuncRec quartzSpriteFuncsRec = {
241
QuartzUnrealizeCursor,
248
===========================================================================
250
Pointer screen functions
252
===========================================================================
256
* QuartzCursorOffScreen
259
QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
269
QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
277
* Change the cursor position without generating an event or motion history.
278
* The input coordinates (x,y) are in pScreen-local X11 coordinates.
282
QuartzWarpCursor(ScreenPtr pScreen, int x, int y)
284
static Bool neverMoved = TRUE;
288
/* Don't move the cursor the first time. This is the
289
jump-to-center initialization, and it's annoying. */
294
if (quartzServerVisible)
298
sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
299
sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
301
CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
304
miPointerWarpCursor(pScreen, x, y);
309
static miPointerScreenFuncRec quartzScreenFuncsRec = {
310
QuartzCursorOffScreen,
319
===========================================================================
321
Other screen functions
323
===========================================================================
327
* QuartzCursorQueryBestSize
328
* Handle queries for best cursor size
331
QuartzCursorQueryBestSize(int class, unsigned short *width,
332
unsigned short *height, ScreenPtr pScreen)
334
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
336
if (class == CursorShape)
338
/* FIXME: query window server? */
344
(*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
350
* Initialize cursor support
353
QuartzInitCursor(ScreenPtr pScreen)
355
QuartzCursorScreenPtr ScreenPriv;
356
miPointerScreenPtr PointPriv;
358
/* initialize software cursor handling (always needed as backup) */
359
if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
362
/* allocate private storage for this screen's QuickDraw cursor info */
363
if (darwinCursorGeneration != serverGeneration)
365
if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
368
darwinCursorGeneration = serverGeneration;
371
ScreenPriv = xcalloc(1, sizeof(QuartzCursorScreenRec));
372
if (ScreenPriv == NULL)
375
CURSOR_PRIV(pScreen) = ScreenPriv;
377
/* override some screen procedures */
378
ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
379
pScreen->QueryBestSize = QuartzCursorQueryBestSize;
381
PointPriv = (miPointerScreenPtr) pScreen->devPrivates[miPointerScreenIndex].ptr;
383
ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
384
PointPriv->spriteFuncs = &quartzSpriteFuncsRec;
386
ScreenPriv->cursorVisible = TRUE;
392
* QuartzSuspendXCursor
393
* X server is hiding. Restore the Aqua cursor.
396
QuartzSuspendXCursor(ScreenPtr pScreen)
402
* QuartzResumeXCursor
403
* X server is showing. Restore the X cursor.
406
QuartzResumeXCursor(ScreenPtr pScreen, int x, int y)
411
pWin = GetSpriteWindow();
412
if (pWin->drawable.pScreen != pScreen)
415
pCursor = GetSpriteCursor();
419
QuartzSetCursor(pScreen, pCursor, x, y);