~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/darwin/quartz/xpr/xprCursor.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************
 
2
 *
 
3
 * Xplugin cursor support
 
4
 *
 
5
 **************************************************************/
 
6
/*
 
7
 * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
 
8
 * Copyright (c) 2002 Apple Computer, Inc.
 
9
 *                 All Rights Reserved.
 
10
 *
 
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:
 
17
 *
 
18
 * The above copyright notice and this permission notice shall be included in
 
19
 * all copies or substantial portions of the Software.
 
20
 *
 
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.
 
28
 *
 
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.
 
32
 */
 
33
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprCursor.c,v 1.1 2003/04/30 23:15:42 torrey Exp $ */
 
34
 
 
35
#include "quartzCommon.h"
 
36
#include "xpr.h"
 
37
#include "darwin.h"
 
38
#include "Xplugin.h"
 
39
 
 
40
#include "mi.h"
 
41
#include "scrnintstr.h"
 
42
#include "cursorstr.h"
 
43
#include "mipointrst.h"
 
44
#include "windowstr.h"
 
45
#include "globals.h"
 
46
#include "servermd.h"
 
47
#include "dixevents.h"
 
48
 
 
49
typedef struct {
 
50
    int                     cursorVisible;
 
51
    QueryBestSizeProcPtr    QueryBestSize;
 
52
    miPointerSpriteFuncPtr  spriteFuncs;
 
53
} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
 
54
 
 
55
static int darwinCursorScreenIndex = -1;
 
56
static unsigned long darwinCursorGeneration = 0;
 
57
 
 
58
#define CURSOR_PRIV(pScreen) \
 
59
    ((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
 
60
 
 
61
 
 
62
static Bool
 
63
load_cursor(CursorPtr src, int screen)
 
64
{
 
65
    uint32_t *data;
 
66
    uint32_t rowbytes;
 
67
    int width, height;
 
68
    int hot_x, hot_y;
 
69
 
 
70
    uint32_t fg_color, bg_color;
 
71
    uint8_t *srow, *sptr;
 
72
    uint8_t *mrow, *mptr;
 
73
    uint32_t *drow, *dptr;
 
74
    unsigned xcount, ycount;
 
75
 
 
76
    xp_error err;
 
77
 
 
78
    width = src->bits->width;
 
79
    height = src->bits->height;
 
80
    hot_x = src->bits->xhot;
 
81
    hot_y = src->bits->yhot;
 
82
 
 
83
#ifdef ARGB_CURSOR
 
84
    if (src->bits->argb != NULL)
 
85
    {
 
86
        rowbytes = src->bits->width * sizeof(CARD32);
 
87
        data = (uint32_t *) src->bits->argb;
 
88
    }
 
89
    else
 
90
#endif
 
91
    {
 
92
        fg_color = 0xFF00 | (src->foreRed >> 8);
 
93
        fg_color <<= 16;
 
94
        fg_color |= src->foreGreen & 0xFF00;
 
95
        fg_color |= src->foreBlue >> 8;
 
96
 
 
97
        bg_color = 0xFF00 | (src->backRed >> 8);
 
98
        bg_color <<= 16;
 
99
        bg_color |= src->backGreen & 0xFF00;
 
100
        bg_color |= src->backBlue >> 8;
 
101
 
 
102
        fg_color = htonl(fg_color);
 
103
        bg_color = htonl(bg_color);
 
104
 
 
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);
 
108
 
 
109
        if (!src->bits->emptyMask)
 
110
        {
 
111
            ycount = src->bits->height;
 
112
            srow = src->bits->source; mrow = src->bits->mask;
 
113
            drow = data;
 
114
 
 
115
            while (ycount-- > 0)
 
116
            {
 
117
                xcount = (src->bits->width + 7) / 8;
 
118
                sptr = srow; mptr = mrow;
 
119
                dptr = drow;
 
120
 
 
121
                while (xcount-- > 0)
 
122
                {
 
123
                    uint8_t s, m;
 
124
                    int i;
 
125
 
 
126
                    s = *sptr++; m = *mptr++;
 
127
                    for (i = 0; i < 8; i++)
 
128
                    {
 
129
#if BITMAP_BIT_ORDER == MSBFirst
 
130
                        if (m & 128)
 
131
                            *dptr++ = (s & 128) ? fg_color : bg_color;
 
132
                        else
 
133
                            *dptr++ = 0;
 
134
                        s <<= 1; m <<= 1;
 
135
#else
 
136
                        if (m & 1)
 
137
                            *dptr++ = (s & 1) ? fg_color : bg_color;
 
138
                        else
 
139
                            *dptr++ = 0;
 
140
                        s >>= 1; m >>= 1;
 
141
#endif
 
142
                    }
 
143
                }
 
144
 
 
145
                srow += BitmapBytePad(src->bits->width);
 
146
                mrow += BitmapBytePad(src->bits->width);
 
147
                drow = (uint32_t *) ((char *) drow + rowbytes);
 
148
            }
 
149
        }
 
150
        else
 
151
        {
 
152
            memset(data, 0, src->bits->height * rowbytes);
 
153
        }
 
154
    }
 
155
 
 
156
    err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
 
157
    return err == Success;
 
158
}
 
159
 
 
160
 
 
161
/*
 
162
===========================================================================
 
163
 
 
164
 Pointer sprite functions
 
165
 
 
166
===========================================================================
 
167
*/
 
168
 
 
169
/*
 
170
 * QuartzRealizeCursor
 
171
 *  Convert the X cursor representation to native format if possible.
 
172
 */
 
173
static Bool
 
174
QuartzRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
 
175
{
 
176
    if(pCursor == NULL || pCursor->bits == NULL)
 
177
        return FALSE;
 
178
 
 
179
    /* FIXME: cache ARGB8888 representation? */
 
180
 
 
181
    return TRUE;
 
182
}
 
183
 
 
184
 
 
185
/*
 
186
 * QuartzUnrealizeCursor
 
187
 *  Free the storage space associated with a realized cursor.
 
188
 */
 
189
static Bool
 
190
QuartzUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
 
191
{
 
192
    return TRUE;
 
193
}
 
194
 
 
195
 
 
196
/*
 
197
 * QuartzSetCursor
 
198
 *  Set the cursor sprite and position.
 
199
 */
 
200
static void
 
201
QuartzSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
 
202
{
 
203
    QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
 
204
 
 
205
    if (!quartzServerVisible)
 
206
        return;
 
207
 
 
208
    if (pCursor == NULL)
 
209
    {
 
210
        if (ScreenPriv->cursorVisible)
 
211
        {
 
212
            xp_hide_cursor();
 
213
            ScreenPriv->cursorVisible = FALSE;
 
214
        }
 
215
    }
 
216
    else
 
217
    {
 
218
        load_cursor(pCursor, pScreen->myNum);
 
219
 
 
220
        if (!ScreenPriv->cursorVisible)
 
221
        {
 
222
            xp_show_cursor();
 
223
            ScreenPriv->cursorVisible = TRUE;
 
224
        }
 
225
    }
 
226
}
 
227
 
 
228
 
 
229
/*
 
230
 * QuartzMoveCursor
 
231
 *  Move the cursor. This is a noop for us.
 
232
 */
 
233
static void
 
234
QuartzMoveCursor(ScreenPtr pScreen, int x, int y)
 
235
{
 
236
}
 
237
 
 
238
 
 
239
static miPointerSpriteFuncRec quartzSpriteFuncsRec = {
 
240
    QuartzRealizeCursor,
 
241
    QuartzUnrealizeCursor,
 
242
    QuartzSetCursor,
 
243
    QuartzMoveCursor
 
244
};
 
245
 
 
246
 
 
247
/*
 
248
===========================================================================
 
249
 
 
250
 Pointer screen functions
 
251
 
 
252
===========================================================================
 
253
*/
 
254
 
 
255
/*
 
256
 * QuartzCursorOffScreen
 
257
 */
 
258
static Bool
 
259
QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
 
260
{
 
261
    return FALSE;
 
262
}
 
263
 
 
264
 
 
265
/*
 
266
 * QuartzCrossScreen
 
267
 */
 
268
static void
 
269
QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
 
270
{
 
271
    return;
 
272
}
 
273
 
 
274
 
 
275
/*
 
276
 * QuartzWarpCursor
 
277
 *  Change the cursor position without generating an event or motion history.
 
278
 *  The input coordinates (x,y) are in pScreen-local X11 coordinates.
 
279
 *
 
280
 */
 
281
static void
 
282
QuartzWarpCursor(ScreenPtr pScreen, int x, int y)
 
283
{
 
284
    static Bool neverMoved = TRUE;
 
285
 
 
286
    if (neverMoved)
 
287
    {
 
288
        /* Don't move the cursor the first time. This is the
 
289
           jump-to-center initialization, and it's annoying. */
 
290
        neverMoved = FALSE;
 
291
        return;
 
292
    }
 
293
 
 
294
    if (quartzServerVisible)
 
295
    {
 
296
        int sx, sy;
 
297
 
 
298
        sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
 
299
        sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
 
300
 
 
301
        CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
 
302
    }
 
303
 
 
304
    miPointerWarpCursor(pScreen, x, y);
 
305
    miPointerUpdate();
 
306
}
 
307
 
 
308
 
 
309
static miPointerScreenFuncRec quartzScreenFuncsRec = {
 
310
    QuartzCursorOffScreen,
 
311
    QuartzCrossScreen,
 
312
    QuartzWarpCursor,
 
313
    DarwinEQPointerPost,
 
314
    DarwinEQSwitchScreen
 
315
};
 
316
 
 
317
 
 
318
/*
 
319
===========================================================================
 
320
 
 
321
 Other screen functions
 
322
 
 
323
===========================================================================
 
324
*/
 
325
 
 
326
/*
 
327
 * QuartzCursorQueryBestSize
 
328
 *  Handle queries for best cursor size
 
329
 */
 
330
static void
 
331
QuartzCursorQueryBestSize(int class, unsigned short *width,
 
332
                          unsigned short *height, ScreenPtr pScreen)
 
333
{
 
334
    QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
 
335
 
 
336
    if (class == CursorShape)
 
337
    {
 
338
        /* FIXME: query window server? */
 
339
        *width = 32;
 
340
        *height = 32;
 
341
    }
 
342
    else
 
343
    {
 
344
        (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
 
345
    }
 
346
}
 
347
 
 
348
/*
 
349
 * QuartzInitCursor
 
350
 *  Initialize cursor support
 
351
 */
 
352
Bool
 
353
QuartzInitCursor(ScreenPtr pScreen)
 
354
{
 
355
    QuartzCursorScreenPtr ScreenPriv;
 
356
    miPointerScreenPtr PointPriv;
 
357
 
 
358
    /* initialize software cursor handling (always needed as backup) */
 
359
    if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
 
360
        return FALSE;
 
361
 
 
362
    /* allocate private storage for this screen's QuickDraw cursor info */
 
363
    if (darwinCursorGeneration != serverGeneration)
 
364
    {
 
365
        if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
 
366
            return FALSE;
 
367
 
 
368
        darwinCursorGeneration = serverGeneration;
 
369
    }
 
370
 
 
371
    ScreenPriv = xcalloc(1, sizeof(QuartzCursorScreenRec));
 
372
    if (ScreenPriv == NULL)
 
373
        return FALSE;
 
374
 
 
375
    CURSOR_PRIV(pScreen) = ScreenPriv;
 
376
 
 
377
    /* override some screen procedures */
 
378
    ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
 
379
    pScreen->QueryBestSize = QuartzCursorQueryBestSize;
 
380
 
 
381
    PointPriv = (miPointerScreenPtr) pScreen->devPrivates[miPointerScreenIndex].ptr;
 
382
 
 
383
    ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
 
384
    PointPriv->spriteFuncs = &quartzSpriteFuncsRec;
 
385
 
 
386
    ScreenPriv->cursorVisible = TRUE;
 
387
    return TRUE;
 
388
}
 
389
 
 
390
 
 
391
/*
 
392
 * QuartzSuspendXCursor
 
393
 *  X server is hiding. Restore the Aqua cursor.
 
394
 */
 
395
void
 
396
QuartzSuspendXCursor(ScreenPtr pScreen)
 
397
{
 
398
}
 
399
 
 
400
 
 
401
/*
 
402
 * QuartzResumeXCursor
 
403
 *  X server is showing. Restore the X cursor.
 
404
 */
 
405
void
 
406
QuartzResumeXCursor(ScreenPtr pScreen, int x, int y)
 
407
{
 
408
    WindowPtr pWin;
 
409
    CursorPtr pCursor;
 
410
 
 
411
    pWin = GetSpriteWindow();
 
412
    if (pWin->drawable.pScreen != pScreen)
 
413
        return;
 
414
 
 
415
    pCursor = GetSpriteCursor();
 
416
    if (pCursor == NULL)
 
417
        return;
 
418
 
 
419
    QuartzSetCursor(pScreen, pCursor, x, y);
 
420
}