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

« back to all changes in this revision

Viewing changes to xfixes/cursor.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
 * $Id: cursor.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
 
3
 *
 
4
 * Copyright Ā© 2002 Keith Packard
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
 
 
25
#ifdef HAVE_DIX_CONFIG_H
 
26
#include <dix-config.h>
 
27
#endif
 
28
 
 
29
#include "xfixesint.h"
 
30
#include "scrnintstr.h"
 
31
#include "cursorstr.h"
 
32
#include "dixevents.h"
 
33
#include "servermd.h"
 
34
#include "inputstr.h"
 
35
#include "windowstr.h"
 
36
 
 
37
static RESTYPE          CursorClientType;
 
38
static RESTYPE          CursorWindowType;
 
39
static int              CursorScreenPrivateIndex = -1;
 
40
static int              CursorGeneration;
 
41
static CursorPtr        CursorCurrent;
 
42
 
 
43
#define VERIFY_CURSOR(pCursor, cursor, client, access) { \
 
44
    pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \
 
45
                                        RT_CURSOR, (access)); \
 
46
    if (!pCursor) { \
 
47
        (client)->errorValue = (cursor); \
 
48
        return BadCursor; \
 
49
    } \
 
50
}
 
51
        
 
52
/*
 
53
 * There is a global list of windows selecting for cursor events
 
54
 */
 
55
 
 
56
typedef struct _CursorEvent *CursorEventPtr;
 
57
 
 
58
typedef struct _CursorEvent {
 
59
    CursorEventPtr      next;
 
60
    CARD32              eventMask;
 
61
    ClientPtr           pClient;
 
62
    WindowPtr           pWindow;
 
63
    XID                 clientResource;
 
64
} CursorEventRec;
 
65
 
 
66
static CursorEventPtr       cursorEvents;
 
67
 
 
68
/*
 
69
 * Wrap DisplayCursor to catch cursor change events
 
70
 */
 
71
 
 
72
typedef struct _CursorScreen {
 
73
    DisplayCursorProcPtr        DisplayCursor;
 
74
    CloseScreenProcPtr          CloseScreen;
 
75
} CursorScreenRec, *CursorScreenPtr;
 
76
 
 
77
#define GetCursorScreen(s)      ((CursorScreenPtr) ((s)->devPrivates[CursorScreenPrivateIndex].ptr))
 
78
#define GetCursorScreenIfSet(s) ((CursorScreenPrivateIndex != -1) ? GetCursorScreen(s) : NULL)
 
79
#define SetCursorScreen(s,p)    ((s)->devPrivates[CursorScreenPrivateIndex].ptr = (pointer) (p))
 
80
#define Wrap(as,s,elt,func)     (((as)->elt = (s)->elt), (s)->elt = func)
 
81
#define Unwrap(as,s,elt)        ((s)->elt = (as)->elt)
 
82
 
 
83
static Bool
 
84
CursorDisplayCursor (ScreenPtr pScreen,
 
85
                     CursorPtr pCursor)
 
86
{
 
87
    CursorScreenPtr     cs = GetCursorScreen(pScreen);
 
88
    Bool                ret;
 
89
 
 
90
    Unwrap (cs, pScreen, DisplayCursor);
 
91
    ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
 
92
    if (pCursor != CursorCurrent)
 
93
    {
 
94
        CursorEventPtr  e;
 
95
 
 
96
        CursorCurrent = pCursor;
 
97
        for (e = cursorEvents; e; e = e->next)
 
98
        {
 
99
            if (e->eventMask & XFixesDisplayCursorNotifyMask)
 
100
            {
 
101
                xXFixesCursorNotifyEvent        ev;
 
102
                ev.type = XFixesEventBase + XFixesCursorNotify;
 
103
                ev.subtype = XFixesDisplayCursorNotify;
 
104
                ev.sequenceNumber = e->pClient->sequence;
 
105
                ev.window = e->pWindow->drawable.id;
 
106
                ev.cursorSerial = pCursor->serialNumber;
 
107
                ev.timestamp = currentTime.milliseconds;
 
108
                ev.name = pCursor->name;
 
109
                WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
 
110
            }
 
111
        }
 
112
    }
 
113
    Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
 
114
    return ret;
 
115
}
 
116
 
 
117
static Bool
 
118
CursorCloseScreen (int index, ScreenPtr pScreen)
 
119
{
 
120
    CursorScreenPtr     cs = GetCursorScreen (pScreen);
 
121
    Bool                ret;
 
122
 
 
123
    Unwrap (cs, pScreen, CloseScreen);
 
124
    Unwrap (cs, pScreen, DisplayCursor);
 
125
    ret = (*pScreen->CloseScreen) (index, pScreen);
 
126
    xfree (cs);
 
127
    if (index == 0)
 
128
        CursorScreenPrivateIndex = -1;
 
129
    return ret;
 
130
}
 
131
 
 
132
#define CursorAllEvents (XFixesDisplayCursorNotifyMask)
 
133
 
 
134
static int
 
135
XFixesSelectCursorInput (ClientPtr      pClient,
 
136
                         WindowPtr      pWindow,
 
137
                         CARD32         eventMask)
 
138
{
 
139
    CursorEventPtr      *prev, e;
 
140
 
 
141
    for (prev = &cursorEvents; (e = *prev); prev = &e->next)
 
142
    {
 
143
        if (e->pClient == pClient &&
 
144
            e->pWindow == pWindow)
 
145
        {
 
146
            break;
 
147
        }
 
148
    }
 
149
    if (!eventMask)
 
150
    {
 
151
        if (e)
 
152
        {
 
153
            FreeResource (e->clientResource, 0);
 
154
        }
 
155
        return Success;
 
156
    }
 
157
    if (!e)
 
158
    {
 
159
        e = (CursorEventPtr) xalloc (sizeof (CursorEventRec));
 
160
        if (!e)
 
161
            return BadAlloc;
 
162
 
 
163
        e->next = 0;
 
164
        e->pClient = pClient;
 
165
        e->pWindow = pWindow;
 
166
        e->clientResource = FakeClientID(pClient->index);
 
167
 
 
168
        /*
 
169
         * Add a resource hanging from the window to
 
170
         * catch window destroy
 
171
         */
 
172
        if (!LookupIDByType(pWindow->drawable.id, CursorWindowType))
 
173
            if (!AddResource (pWindow->drawable.id, CursorWindowType,
 
174
                              (pointer) pWindow))
 
175
            {
 
176
                xfree (e);
 
177
                return BadAlloc;
 
178
            }
 
179
 
 
180
        if (!AddResource (e->clientResource, CursorClientType, (pointer) e))
 
181
            return BadAlloc;
 
182
 
 
183
        *prev = e;
 
184
    }
 
185
    e->eventMask = eventMask;
 
186
    return Success;
 
187
}
 
188
 
 
189
int
 
190
ProcXFixesSelectCursorInput (ClientPtr client)
 
191
{
 
192
    REQUEST (xXFixesSelectCursorInputReq);
 
193
    WindowPtr   pWin;
 
194
 
 
195
    REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq);
 
196
    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
 
197
                                           SecurityReadAccess);
 
198
    if (!pWin)
 
199
        return(BadWindow);
 
200
    if (stuff->eventMask & ~CursorAllEvents)
 
201
    {
 
202
        client->errorValue = stuff->eventMask;
 
203
        return( BadValue );
 
204
    }
 
205
    return XFixesSelectCursorInput (client, pWin, stuff->eventMask);
 
206
}
 
207
 
 
208
static int
 
209
GetBit (unsigned char *line, int x)
 
210
{
 
211
    unsigned char   mask;
 
212
    
 
213
    if (screenInfo.bitmapBitOrder == LSBFirst)
 
214
        mask = (1 << (x & 7));
 
215
    else
 
216
        mask = (0x80 >> (x & 7));
 
217
    /* XXX assumes byte order is host byte order */
 
218
    line += (x >> 3);
 
219
    if (*line & mask)
 
220
        return 1;
 
221
    return 0;
 
222
}
 
223
 
 
224
int
 
225
SProcXFixesSelectCursorInput (ClientPtr client)
 
226
{
 
227
    register int n;
 
228
    REQUEST(xXFixesSelectCursorInputReq);
 
229
 
 
230
    swaps(&stuff->length, n);
 
231
    swapl(&stuff->window, n);
 
232
    swapl(&stuff->eventMask, n);
 
233
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
234
}
 
235
    
 
236
void
 
237
SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
 
238
                          xXFixesCursorNotifyEvent *to)
 
239
{
 
240
    to->type = from->type;
 
241
    cpswaps (from->sequenceNumber, to->sequenceNumber);
 
242
    cpswapl (from->window, to->window);
 
243
    cpswapl (from->cursorSerial, to->cursorSerial);
 
244
    cpswapl (from->timestamp, to->timestamp);
 
245
    cpswapl (from->name, to->name);
 
246
}
 
247
 
 
248
static void
 
249
CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
 
250
{
 
251
    int width = pCursor->bits->width;
 
252
    int height = pCursor->bits->height;
 
253
    int npixels = width * height;
 
254
    
 
255
#ifdef ARGB_CURSOR
 
256
    if (pCursor->bits->argb)
 
257
        memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
 
258
    else
 
259
#endif
 
260
    {
 
261
        unsigned char   *srcLine = pCursor->bits->source;
 
262
        unsigned char   *mskLine = pCursor->bits->mask;
 
263
        int             stride = BitmapBytePad (width);
 
264
        int             x, y;
 
265
        CARD32          fg, bg;
 
266
        
 
267
        fg = (0xff000000 | 
 
268
              ((pCursor->foreRed & 0xff00) << 8) |
 
269
              (pCursor->foreGreen & 0xff00) |
 
270
              (pCursor->foreBlue >> 8));
 
271
        bg = (0xff000000 | 
 
272
              ((pCursor->backRed & 0xff00) << 8) |
 
273
              (pCursor->backGreen & 0xff00) |
 
274
              (pCursor->backBlue >> 8));
 
275
        for (y = 0; y < height; y++)
 
276
        {
 
277
            for (x = 0; x < width; x++)
 
278
            {
 
279
                if (GetBit (mskLine, x))
 
280
                {
 
281
                    if (GetBit (srcLine, x))
 
282
                        *image++ = fg;
 
283
                    else
 
284
                        *image++ = bg;
 
285
                }
 
286
                else
 
287
                    *image++ = 0;
 
288
            }
 
289
            srcLine += stride;
 
290
            mskLine += stride;
 
291
        }
 
292
    }
 
293
}
 
294
 
 
295
int
 
296
ProcXFixesGetCursorImage (ClientPtr client)
 
297
{
 
298
/*    REQUEST(xXFixesGetCursorImageReq); */
 
299
    xXFixesGetCursorImageReply  *rep;
 
300
    CursorPtr                   pCursor;
 
301
    CARD32                      *image;
 
302
    int                         npixels;
 
303
    int                         width, height;
 
304
    int                         x, y;
 
305
 
 
306
    REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
 
307
    pCursor = CursorCurrent;
 
308
    if (!pCursor)
 
309
        return BadCursor;
 
310
    GetSpritePosition (&x, &y);
 
311
    width = pCursor->bits->width;
 
312
    height = pCursor->bits->height;
 
313
    npixels = width * height;
 
314
    rep = xalloc (sizeof (xXFixesGetCursorImageReply) +
 
315
                  npixels * sizeof (CARD32));
 
316
    if (!rep)
 
317
        return BadAlloc;
 
318
 
 
319
    rep->type = X_Reply;
 
320
    rep->sequenceNumber = client->sequence;
 
321
    rep->length = npixels;
 
322
    rep->width = width;
 
323
    rep->height = height;
 
324
    rep->x = x;
 
325
    rep->y = y;
 
326
    rep->xhot = pCursor->bits->xhot;
 
327
    rep->yhot = pCursor->bits->yhot; 
 
328
    rep->cursorSerial = pCursor->serialNumber;
 
329
 
 
330
    image = (CARD32 *) (rep + 1);
 
331
    CopyCursorToImage (pCursor, image);
 
332
    if (client->swapped)
 
333
    {
 
334
        int n;
 
335
        swaps (&rep->sequenceNumber, n);
 
336
        swapl (&rep->length, n);
 
337
        swaps (&rep->x, n);
 
338
        swaps (&rep->y, n);
 
339
        swaps (&rep->width, n);
 
340
        swaps (&rep->height, n);
 
341
        swaps (&rep->xhot, n);
 
342
        swaps (&rep->yhot, n);
 
343
        swapl (&rep->cursorSerial, n);
 
344
        SwapLongs (image, npixels);
 
345
    }
 
346
    (void) WriteToClient(client, sizeof (xXFixesGetCursorImageReply) +
 
347
                         (npixels << 2), (char *) rep);
 
348
    xfree (rep);
 
349
    return client->noClientException;
 
350
}
 
351
 
 
352
int
 
353
SProcXFixesGetCursorImage (ClientPtr client)
 
354
{
 
355
    int n;
 
356
    REQUEST(xXFixesGetCursorImageReq);
 
357
    swaps (&stuff->length, n);
 
358
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
359
}
 
360
 
 
361
int
 
362
ProcXFixesSetCursorName (ClientPtr client)
 
363
{
 
364
    CursorPtr pCursor;
 
365
    char *tchar;
 
366
    REQUEST(xXFixesSetCursorNameReq);
 
367
    Atom atom;
 
368
 
 
369
    REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
 
370
    VERIFY_CURSOR(pCursor, stuff->cursor, client, SecurityWriteAccess);
 
371
    tchar = (char *) &stuff[1];
 
372
    atom = MakeAtom (tchar, stuff->nbytes, TRUE);
 
373
    if (atom == BAD_RESOURCE)
 
374
        return BadAlloc;
 
375
    
 
376
    pCursor->name = atom;
 
377
    return(client->noClientException);
 
378
}
 
379
 
 
380
int
 
381
SProcXFixesSetCursorName (ClientPtr client)
 
382
{
 
383
    int n;
 
384
    REQUEST(xXFixesSetCursorNameReq);
 
385
 
 
386
    swaps (&stuff->length, n);
 
387
    REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
 
388
    swapl (&stuff->cursor, n);
 
389
    swaps (&stuff->nbytes, n);
 
390
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
391
}
 
392
 
 
393
int
 
394
ProcXFixesGetCursorName (ClientPtr client)
 
395
{
 
396
    CursorPtr                   pCursor;
 
397
    xXFixesGetCursorNameReply   reply;
 
398
    REQUEST(xXFixesGetCursorNameReq);
 
399
    char *str;
 
400
    int len;
 
401
 
 
402
    REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
 
403
    VERIFY_CURSOR(pCursor, stuff->cursor, client, SecurityReadAccess);
 
404
    if (pCursor->name)
 
405
        str = NameForAtom (pCursor->name);
 
406
    else
 
407
        str = "";
 
408
    len = strlen (str);
 
409
    
 
410
    reply.type = X_Reply;
 
411
    reply.length = (len + 3) >> 2;
 
412
    reply.sequenceNumber = client->sequence;
 
413
    reply.atom = pCursor->name;
 
414
    reply.nbytes = len;
 
415
    if (client->swapped)
 
416
    {
 
417
        int n;
 
418
        swaps (&reply.sequenceNumber, n);
 
419
        swapl (&reply.length, n);
 
420
        swapl (&reply.atom, n);
 
421
        swaps (&reply.nbytes, n);
 
422
    }
 
423
    WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
 
424
    (void)WriteToClient(client, len, str);
 
425
    
 
426
    return(client->noClientException);
 
427
}
 
428
 
 
429
int
 
430
SProcXFixesGetCursorName (ClientPtr client)
 
431
{
 
432
    int n;
 
433
    REQUEST(xXFixesSetCursorNameReq);
 
434
 
 
435
    swaps (&stuff->length, n);
 
436
    REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
 
437
    swapl (&stuff->cursor, n);
 
438
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
439
}
 
440
 
 
441
int
 
442
ProcXFixesGetCursorImageAndName (ClientPtr client)
 
443
{
 
444
/*    REQUEST(xXFixesGetCursorImageAndNameReq); */
 
445
    xXFixesGetCursorImageAndNameReply   *rep;
 
446
    CursorPtr                   pCursor;
 
447
    CARD32                      *image;
 
448
    int                         npixels;
 
449
    char                        *name;
 
450
    int                         nbytes, nbytesRound;
 
451
    int                         width, height;
 
452
    int                         x, y;
 
453
 
 
454
    REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
 
455
    pCursor = CursorCurrent;
 
456
    if (!pCursor)
 
457
        return BadCursor;
 
458
    GetSpritePosition (&x, &y);
 
459
    width = pCursor->bits->width;
 
460
    height = pCursor->bits->height;
 
461
    npixels = width * height;
 
462
    name = pCursor->name ? NameForAtom (pCursor->name) : "";
 
463
    nbytes = strlen (name);
 
464
    nbytesRound = (nbytes + 3) & ~3;
 
465
    rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) +
 
466
                  npixels * sizeof (CARD32) + nbytesRound);
 
467
    if (!rep)
 
468
        return BadAlloc;
 
469
 
 
470
    rep->type = X_Reply;
 
471
    rep->sequenceNumber = client->sequence;
 
472
    rep->length = npixels + (nbytesRound >> 2);
 
473
    rep->width = width;
 
474
    rep->height = height;
 
475
    rep->x = x;
 
476
    rep->y = y;
 
477
    rep->xhot = pCursor->bits->xhot;
 
478
    rep->yhot = pCursor->bits->yhot; 
 
479
    rep->cursorSerial = pCursor->serialNumber;
 
480
    rep->cursorName = pCursor->name;
 
481
    rep->nbytes = nbytes;
 
482
 
 
483
    image = (CARD32 *) (rep + 1);
 
484
    CopyCursorToImage (pCursor, image);
 
485
    memcpy ((image + npixels), name, nbytes);
 
486
    if (client->swapped)
 
487
    {
 
488
        int n;
 
489
        swaps (&rep->sequenceNumber, n);
 
490
        swapl (&rep->length, n);
 
491
        swaps (&rep->x, n);
 
492
        swaps (&rep->y, n);
 
493
        swaps (&rep->width, n);
 
494
        swaps (&rep->height, n);
 
495
        swaps (&rep->xhot, n);
 
496
        swaps (&rep->yhot, n);
 
497
        swapl (&rep->cursorSerial, n);
 
498
        swapl (&rep->cursorName, n);
 
499
        swaps (&rep->nbytes, n);
 
500
        SwapLongs (image, npixels);
 
501
    }
 
502
    (void) WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) +
 
503
                         (npixels << 2) + nbytesRound, (char *) rep);
 
504
    xfree (rep);
 
505
    return client->noClientException;
 
506
}
 
507
 
 
508
int
 
509
SProcXFixesGetCursorImageAndName (ClientPtr client)
 
510
{
 
511
    int n;
 
512
    REQUEST(xXFixesGetCursorImageAndNameReq);
 
513
    swaps (&stuff->length, n);
 
514
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
515
}
 
516
 
 
517
/*
 
518
 * Find every cursor reference in the system, ask testCursor
 
519
 * whether it should be replaced with a reference to pCursor.
 
520
 */
 
521
 
 
522
typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure);
 
523
 
 
524
typedef struct {
 
525
    RESTYPE type;
 
526
    TestCursorFunc testCursor;
 
527
    CursorPtr pNew;
 
528
    pointer closure;
 
529
} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
 
530
 
 
531
static const RESTYPE    CursorRestypes[] = {
 
532
    RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR
 
533
};
 
534
 
 
535
#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
 
536
 
 
537
static Bool
 
538
ReplaceCursorLookup (pointer value, XID id, pointer closure)
 
539
{
 
540
    ReplaceCursorLookupPtr  rcl = (ReplaceCursorLookupPtr) closure;
 
541
    WindowPtr               pWin;
 
542
    GrabPtr                 pGrab;
 
543
    CursorPtr               pCursor = 0, *pCursorRef = 0;
 
544
    XID                     cursor = 0;
 
545
 
 
546
    switch (rcl->type) {
 
547
    case RT_WINDOW:
 
548
        pWin = (WindowPtr) value;
 
549
        if (pWin->optional)
 
550
        {
 
551
            pCursorRef = &pWin->optional->cursor;
 
552
            pCursor = *pCursorRef;
 
553
        }
 
554
        break;
 
555
    case RT_PASSIVEGRAB:
 
556
        pGrab = (GrabPtr) value;
 
557
        pCursorRef = &pGrab->cursor;
 
558
        pCursor = *pCursorRef;
 
559
        break;
 
560
    case RT_CURSOR:
 
561
        pCursorRef = 0;
 
562
        pCursor = (CursorPtr) value;
 
563
        cursor = id;
 
564
        break;
 
565
    }
 
566
    if (pCursor && pCursor != rcl->pNew)
 
567
    {
 
568
        if ((*rcl->testCursor) (pCursor, rcl->closure))
 
569
        {
 
570
            rcl->pNew->refcnt++;
 
571
            /* either redirect reference or update resource database */
 
572
            if (pCursorRef)
 
573
                *pCursorRef = rcl->pNew;
 
574
            else
 
575
                ChangeResourceValue (id, RT_CURSOR, rcl->pNew);
 
576
            FreeCursor (pCursor, cursor);
 
577
        }
 
578
    }
 
579
    return FALSE;   /* keep walking */
 
580
}
 
581
 
 
582
static void
 
583
ReplaceCursor (CursorPtr pCursor,
 
584
               TestCursorFunc testCursor,
 
585
               pointer closure)
 
586
{
 
587
    int clientIndex;
 
588
    int resIndex;
 
589
    ReplaceCursorLookupRec  rcl;
 
590
    
 
591
    /* 
 
592
     * Cursors exist only in the resource database, windows and grabs.
 
593
     * All of these are always pointed at by the resource database.  Walk
 
594
     * the whole thing looking for cursors
 
595
     */
 
596
    rcl.testCursor = testCursor;
 
597
    rcl.pNew = pCursor;
 
598
    rcl.closure = closure;
 
599
 
 
600
    /* for each client */
 
601
    for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++)
 
602
    {
 
603
        if (!clients[clientIndex])
 
604
            continue;
 
605
        for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++)
 
606
        {
 
607
            rcl.type = CursorRestypes[resIndex];
 
608
            /*
 
609
             * This function walks the entire client resource database
 
610
             */
 
611
            LookupClientResourceComplex (clients[clientIndex], 
 
612
                                         rcl.type, 
 
613
                                         ReplaceCursorLookup,
 
614
                                         (pointer) &rcl);
 
615
        }
 
616
    }
 
617
    /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
 
618
    WindowHasNewCursor (WindowTable[0]);
 
619
}
 
620
 
 
621
static Bool 
 
622
TestForCursor (CursorPtr pCursor, pointer closure)
 
623
{
 
624
    return (pCursor == (CursorPtr) closure);
 
625
}
 
626
 
 
627
int
 
628
ProcXFixesChangeCursor (ClientPtr client)
 
629
{
 
630
    CursorPtr   pSource, pDestination;
 
631
    REQUEST(xXFixesChangeCursorReq);
 
632
 
 
633
    REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
 
634
    VERIFY_CURSOR (pSource, stuff->source, client, SecurityReadAccess);
 
635
    VERIFY_CURSOR (pDestination, stuff->destination, client, SecurityWriteAccess);
 
636
 
 
637
    ReplaceCursor (pSource, TestForCursor, (pointer) pDestination);
 
638
    return (client->noClientException);
 
639
}
 
640
 
 
641
int
 
642
SProcXFixesChangeCursor (ClientPtr client)
 
643
{
 
644
    int n;
 
645
    REQUEST(xXFixesChangeCursorReq);
 
646
 
 
647
    swaps (&stuff->length, n);
 
648
    REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
 
649
    swapl (&stuff->source, n);
 
650
    swapl (&stuff->destination, n);
 
651
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
652
}
 
653
 
 
654
static Bool
 
655
TestForCursorName (CursorPtr pCursor, pointer closure)
 
656
{
 
657
    return (pCursor->name == (Atom) closure);
 
658
}
 
659
 
 
660
int
 
661
ProcXFixesChangeCursorByName (ClientPtr client)
 
662
{
 
663
    CursorPtr   pSource;
 
664
    Atom        name;
 
665
    char        *tchar;
 
666
    REQUEST(xXFixesChangeCursorByNameReq);
 
667
 
 
668
    REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes);
 
669
    VERIFY_CURSOR(pSource, stuff->source, client, SecurityReadAccess);
 
670
    tchar = (char *) &stuff[1];
 
671
    name = MakeAtom (tchar, stuff->nbytes, FALSE);
 
672
    if (name)
 
673
        ReplaceCursor (pSource, TestForCursorName, (pointer) name);
 
674
    return (client->noClientException);
 
675
}
 
676
 
 
677
int
 
678
SProcXFixesChangeCursorByName (ClientPtr client)
 
679
{
 
680
    int n;
 
681
    REQUEST(xXFixesChangeCursorByNameReq);
 
682
 
 
683
    swaps (&stuff->length, n);
 
684
    REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq);
 
685
    swapl (&stuff->source, n);
 
686
    swaps (&stuff->nbytes, n);
 
687
    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 
688
}
 
689
 
 
690
static int
 
691
CursorFreeClient (pointer data, XID id)
 
692
{
 
693
    CursorEventPtr      old = (CursorEventPtr) data;
 
694
    CursorEventPtr      *prev, e;
 
695
    
 
696
    for (prev = &cursorEvents; (e = *prev); prev = &e->next)
 
697
    {
 
698
        if (e == old)
 
699
        {
 
700
            *prev = e->next;
 
701
            xfree (e);
 
702
            break;
 
703
        }
 
704
    }
 
705
    return 1;
 
706
}
 
707
 
 
708
static int
 
709
CursorFreeWindow (pointer data, XID id)
 
710
{
 
711
    WindowPtr           pWindow = (WindowPtr) data;
 
712
    CursorEventPtr      e, next;
 
713
 
 
714
    for (e = cursorEvents; e; e = next)
 
715
    {
 
716
        next = e->next;
 
717
        if (e->pWindow == pWindow)
 
718
        {
 
719
            FreeResource (e->clientResource, 0);
 
720
        }
 
721
    }
 
722
    return 1;
 
723
}
 
724
 
 
725
Bool
 
726
XFixesCursorInit (void)
 
727
{
 
728
    int i;
 
729
    
 
730
    if (CursorGeneration != serverGeneration)
 
731
    {
 
732
        CursorScreenPrivateIndex = AllocateScreenPrivateIndex ();
 
733
        if (CursorScreenPrivateIndex < 0)
 
734
            return FALSE;
 
735
        CursorGeneration = serverGeneration;
 
736
    }
 
737
    for (i = 0; i < screenInfo.numScreens; i++)
 
738
    {
 
739
        ScreenPtr       pScreen = screenInfo.screens[i];
 
740
        CursorScreenPtr cs;
 
741
 
 
742
        cs = (CursorScreenPtr) xalloc (sizeof (CursorScreenRec));
 
743
        if (!cs)
 
744
            return FALSE;
 
745
        Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
 
746
        Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
 
747
        SetCursorScreen (pScreen, cs);
 
748
    }
 
749
    CursorClientType = CreateNewResourceType(CursorFreeClient);
 
750
    CursorWindowType = CreateNewResourceType(CursorFreeWindow);
 
751
    return CursorClientType && CursorWindowType;
 
752
}
 
753