~brandontschaefer/+junk/break-x

« back to all changes in this revision

Viewing changes to hw/xquartz/xpr/xprCursor.c

  • Committer: Brandon Schaefer
  • Date: 2014-09-30 19:38:40 UTC
  • Revision ID: brandon.schaefer@canonical.com-20140930193840-a65z6qk8ze02cgsb
* Init commit to back this up

Show diffs side-by-side

added added

removed removed

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