1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun * copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun * documentation, and that the name of Keith Packard not be used in
10*4882a593Smuzhiyun * advertising or publicity pertaining to distribution of the software without
11*4882a593Smuzhiyun * specific, written prior permission. Keith Packard makes no
12*4882a593Smuzhiyun * representations about the suitability of this software for any purpose. It
13*4882a593Smuzhiyun * is provided "as is" without express or implied warranty.
14*4882a593Smuzhiyun *
15*4882a593Smuzhiyun * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*4882a593Smuzhiyun * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17*4882a593Smuzhiyun * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19*4882a593Smuzhiyun * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20*4882a593Smuzhiyun * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21*4882a593Smuzhiyun * PERFORMANCE OF THIS SOFTWARE.
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun * Animated cursors for X. Not specific to Render in any way, but
26*4882a593Smuzhiyun * stuck there because Render has the other cool cursor extension.
27*4882a593Smuzhiyun * Besides, everyone has Render.
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * Implemented as a simple layer over the core cursor code; it
30*4882a593Smuzhiyun * creates composite cursors out of a set of static cursors and
31*4882a593Smuzhiyun * delta times between each image.
32*4882a593Smuzhiyun */
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
35*4882a593Smuzhiyun #include <dix-config.h>
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #include <X11/X.h>
39*4882a593Smuzhiyun #include <X11/Xmd.h>
40*4882a593Smuzhiyun #include "servermd.h"
41*4882a593Smuzhiyun #include "scrnintstr.h"
42*4882a593Smuzhiyun #include "dixstruct.h"
43*4882a593Smuzhiyun #include "cursorstr.h"
44*4882a593Smuzhiyun #include "dixfontstr.h"
45*4882a593Smuzhiyun #include "opaque.h"
46*4882a593Smuzhiyun #include "picturestr.h"
47*4882a593Smuzhiyun #include "inputstr.h"
48*4882a593Smuzhiyun #include "xace.h"
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun typedef struct _AnimCurElt {
51*4882a593Smuzhiyun CursorPtr pCursor; /* cursor to show */
52*4882a593Smuzhiyun CARD32 delay; /* in ms */
53*4882a593Smuzhiyun } AnimCurElt;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun typedef struct _AnimCur {
56*4882a593Smuzhiyun int nelt; /* number of elements in the elts array */
57*4882a593Smuzhiyun AnimCurElt *elts; /* actually allocated right after the structure */
58*4882a593Smuzhiyun OsTimerPtr timer;
59*4882a593Smuzhiyun } AnimCurRec, *AnimCurPtr;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun typedef struct _AnimScrPriv {
62*4882a593Smuzhiyun CloseScreenProcPtr CloseScreen;
63*4882a593Smuzhiyun CursorLimitsProcPtr CursorLimits;
64*4882a593Smuzhiyun DisplayCursorProcPtr DisplayCursor;
65*4882a593Smuzhiyun SetCursorPositionProcPtr SetCursorPosition;
66*4882a593Smuzhiyun RealizeCursorProcPtr RealizeCursor;
67*4882a593Smuzhiyun UnrealizeCursorProcPtr UnrealizeCursor;
68*4882a593Smuzhiyun RecolorCursorProcPtr RecolorCursor;
69*4882a593Smuzhiyun } AnimCurScreenRec, *AnimCurScreenPtr;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun static unsigned char empty[4];
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun static CursorBits animCursorBits = {
74*4882a593Smuzhiyun empty, empty, 2, 1, 1, 0, 0, 1
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun static DevPrivateKeyRec AnimCurScreenPrivateKeyRec;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun #define IsAnimCur(c) ((c) && ((c)->bits == &animCursorBits))
80*4882a593Smuzhiyun #define GetAnimCur(c) ((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE))))
81*4882a593Smuzhiyun #define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, &AnimCurScreenPrivateKeyRec))
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
84*4882a593Smuzhiyun #define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun static Bool
AnimCurCloseScreen(ScreenPtr pScreen)87*4882a593Smuzhiyun AnimCurCloseScreen(ScreenPtr pScreen)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
90*4882a593Smuzhiyun Bool ret;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun Unwrap(as, pScreen, CloseScreen);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun Unwrap(as, pScreen, CursorLimits);
95*4882a593Smuzhiyun Unwrap(as, pScreen, DisplayCursor);
96*4882a593Smuzhiyun Unwrap(as, pScreen, SetCursorPosition);
97*4882a593Smuzhiyun Unwrap(as, pScreen, RealizeCursor);
98*4882a593Smuzhiyun Unwrap(as, pScreen, UnrealizeCursor);
99*4882a593Smuzhiyun Unwrap(as, pScreen, RecolorCursor);
100*4882a593Smuzhiyun ret = (*pScreen->CloseScreen) (pScreen);
101*4882a593Smuzhiyun return ret;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static void
AnimCurCursorLimits(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor,BoxPtr pHotBox,BoxPtr pTopLeftBox)105*4882a593Smuzhiyun AnimCurCursorLimits(DeviceIntPtr pDev,
106*4882a593Smuzhiyun ScreenPtr pScreen,
107*4882a593Smuzhiyun CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun Unwrap(as, pScreen, CursorLimits);
112*4882a593Smuzhiyun if (IsAnimCur(pCursor)) {
113*4882a593Smuzhiyun AnimCurPtr ac = GetAnimCur(pCursor);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor,
116*4882a593Smuzhiyun pHotBox, pTopLeftBox);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun else {
119*4882a593Smuzhiyun (*pScreen->CursorLimits) (pDev, pScreen, pCursor, pHotBox, pTopLeftBox);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /*
125*4882a593Smuzhiyun * The cursor animation timer has expired, go display any relevant cursor changes
126*4882a593Smuzhiyun * and compute a new timeout value
127*4882a593Smuzhiyun */
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun static CARD32
AnimCurTimerNotify(OsTimerPtr timer,CARD32 now,void * arg)130*4882a593Smuzhiyun AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun DeviceIntPtr dev = arg;
133*4882a593Smuzhiyun ScreenPtr pScreen = dev->spriteInfo->anim.pScreen;
134*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun AnimCurPtr ac = GetAnimCur(dev->spriteInfo->sprite->current);
137*4882a593Smuzhiyun int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
138*4882a593Smuzhiyun DisplayCursorProcPtr DisplayCursor = pScreen->DisplayCursor;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun * Not a simple Unwrap/Wrap as this isn't called along the DisplayCursor
142*4882a593Smuzhiyun * wrapper chain.
143*4882a593Smuzhiyun */
144*4882a593Smuzhiyun pScreen->DisplayCursor = as->DisplayCursor;
145*4882a593Smuzhiyun (void) (*pScreen->DisplayCursor) (dev, pScreen, ac->elts[elt].pCursor);
146*4882a593Smuzhiyun as->DisplayCursor = pScreen->DisplayCursor;
147*4882a593Smuzhiyun pScreen->DisplayCursor = DisplayCursor;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun dev->spriteInfo->anim.elt = elt;
150*4882a593Smuzhiyun dev->spriteInfo->anim.pCursor = ac->elts[elt].pCursor;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun return ac->elts[elt].delay;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun static void
AnimCurCancelTimer(DeviceIntPtr pDev)156*4882a593Smuzhiyun AnimCurCancelTimer(DeviceIntPtr pDev)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun CursorPtr cur = pDev->spriteInfo->sprite ?
159*4882a593Smuzhiyun pDev->spriteInfo->sprite->current : NULL;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun if (IsAnimCur(cur))
162*4882a593Smuzhiyun TimerCancel(GetAnimCur(cur)->timer);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun static Bool
AnimCurDisplayCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)166*4882a593Smuzhiyun AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
169*4882a593Smuzhiyun Bool ret = TRUE;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun if (IsFloating(pDev))
172*4882a593Smuzhiyun return FALSE;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun Unwrap(as, pScreen, DisplayCursor);
175*4882a593Smuzhiyun if (IsAnimCur(pCursor)) {
176*4882a593Smuzhiyun if (pCursor != pDev->spriteInfo->sprite->current) {
177*4882a593Smuzhiyun AnimCurPtr ac = GetAnimCur(pCursor);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun AnimCurCancelTimer(pDev);
180*4882a593Smuzhiyun ret = (*pScreen->DisplayCursor) (pDev, pScreen,
181*4882a593Smuzhiyun ac->elts[0].pCursor);
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun if (ret) {
184*4882a593Smuzhiyun pDev->spriteInfo->anim.elt = 0;
185*4882a593Smuzhiyun pDev->spriteInfo->anim.pCursor = pCursor;
186*4882a593Smuzhiyun pDev->spriteInfo->anim.pScreen = pScreen;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun ac->timer = TimerSet(ac->timer, 0, ac->elts[0].delay,
189*4882a593Smuzhiyun AnimCurTimerNotify, pDev);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun else {
194*4882a593Smuzhiyun AnimCurCancelTimer(pDev);
195*4882a593Smuzhiyun pDev->spriteInfo->anim.pCursor = 0;
196*4882a593Smuzhiyun pDev->spriteInfo->anim.pScreen = 0;
197*4882a593Smuzhiyun ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
200*4882a593Smuzhiyun return ret;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun static Bool
AnimCurSetCursorPosition(DeviceIntPtr pDev,ScreenPtr pScreen,int x,int y,Bool generateEvent)204*4882a593Smuzhiyun AnimCurSetCursorPosition(DeviceIntPtr pDev,
205*4882a593Smuzhiyun ScreenPtr pScreen, int x, int y, Bool generateEvent)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
208*4882a593Smuzhiyun Bool ret;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun Unwrap(as, pScreen, SetCursorPosition);
211*4882a593Smuzhiyun if (pDev->spriteInfo->anim.pCursor) {
212*4882a593Smuzhiyun pDev->spriteInfo->anim.pScreen = pScreen;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
215*4882a593Smuzhiyun Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
216*4882a593Smuzhiyun return ret;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun static Bool
AnimCurRealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)220*4882a593Smuzhiyun AnimCurRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
223*4882a593Smuzhiyun Bool ret;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun Unwrap(as, pScreen, RealizeCursor);
226*4882a593Smuzhiyun if (IsAnimCur(pCursor))
227*4882a593Smuzhiyun ret = TRUE;
228*4882a593Smuzhiyun else
229*4882a593Smuzhiyun ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor);
230*4882a593Smuzhiyun Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
231*4882a593Smuzhiyun return ret;
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun static Bool
AnimCurUnrealizeCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor)235*4882a593Smuzhiyun AnimCurUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
236*4882a593Smuzhiyun {
237*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
238*4882a593Smuzhiyun Bool ret;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun Unwrap(as, pScreen, UnrealizeCursor);
241*4882a593Smuzhiyun if (IsAnimCur(pCursor)) {
242*4882a593Smuzhiyun AnimCurPtr ac = GetAnimCur(pCursor);
243*4882a593Smuzhiyun int i;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (pScreen->myNum == 0)
246*4882a593Smuzhiyun for (i = 0; i < ac->nelt; i++)
247*4882a593Smuzhiyun FreeCursor(ac->elts[i].pCursor, 0);
248*4882a593Smuzhiyun ret = TRUE;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun else
251*4882a593Smuzhiyun ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
252*4882a593Smuzhiyun Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
253*4882a593Smuzhiyun return ret;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun static void
AnimCurRecolorCursor(DeviceIntPtr pDev,ScreenPtr pScreen,CursorPtr pCursor,Bool displayed)257*4882a593Smuzhiyun AnimCurRecolorCursor(DeviceIntPtr pDev,
258*4882a593Smuzhiyun ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun Unwrap(as, pScreen, RecolorCursor);
263*4882a593Smuzhiyun if (IsAnimCur(pCursor)) {
264*4882a593Smuzhiyun AnimCurPtr ac = GetAnimCur(pCursor);
265*4882a593Smuzhiyun int i;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun for (i = 0; i < ac->nelt; i++)
268*4882a593Smuzhiyun (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor,
269*4882a593Smuzhiyun displayed &&
270*4882a593Smuzhiyun pDev->spriteInfo->anim.elt == i);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun else
273*4882a593Smuzhiyun (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed);
274*4882a593Smuzhiyun Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun Bool
AnimCurInit(ScreenPtr pScreen)278*4882a593Smuzhiyun AnimCurInit(ScreenPtr pScreen)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun AnimCurScreenPtr as;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN,
283*4882a593Smuzhiyun sizeof(AnimCurScreenRec)))
284*4882a593Smuzhiyun return FALSE;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun as = GetAnimCurScreen(pScreen);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
291*4882a593Smuzhiyun Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
292*4882a593Smuzhiyun Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
293*4882a593Smuzhiyun Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
294*4882a593Smuzhiyun Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
295*4882a593Smuzhiyun Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
296*4882a593Smuzhiyun return TRUE;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun int
AnimCursorCreate(CursorPtr * cursors,CARD32 * deltas,int ncursor,CursorPtr * ppCursor,ClientPtr client,XID cid)300*4882a593Smuzhiyun AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
301*4882a593Smuzhiyun CursorPtr *ppCursor, ClientPtr client, XID cid)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun CursorPtr pCursor;
304*4882a593Smuzhiyun int rc = BadAlloc, i;
305*4882a593Smuzhiyun AnimCurPtr ac;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++)
308*4882a593Smuzhiyun if (!GetAnimCurScreen(screenInfo.screens[i]))
309*4882a593Smuzhiyun return BadImplementation;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun for (i = 0; i < ncursor; i++)
312*4882a593Smuzhiyun if (IsAnimCur(cursors[i]))
313*4882a593Smuzhiyun return BadMatch;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE +
316*4882a593Smuzhiyun sizeof(AnimCurRec) +
317*4882a593Smuzhiyun ncursor * sizeof(AnimCurElt), 1);
318*4882a593Smuzhiyun if (!pCursor)
319*4882a593Smuzhiyun return rc;
320*4882a593Smuzhiyun dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR);
321*4882a593Smuzhiyun pCursor->bits = &animCursorBits;
322*4882a593Smuzhiyun pCursor->refcnt = 1;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun pCursor->foreRed = cursors[0]->foreRed;
325*4882a593Smuzhiyun pCursor->foreGreen = cursors[0]->foreGreen;
326*4882a593Smuzhiyun pCursor->foreBlue = cursors[0]->foreBlue;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun pCursor->backRed = cursors[0]->backRed;
329*4882a593Smuzhiyun pCursor->backGreen = cursors[0]->backGreen;
330*4882a593Smuzhiyun pCursor->backBlue = cursors[0]->backBlue;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun pCursor->id = cid;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun ac = GetAnimCur(pCursor);
335*4882a593Smuzhiyun ac->timer = TimerSet(NULL, 0, 0, AnimCurTimerNotify, NULL);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /* security creation/labeling check */
338*4882a593Smuzhiyun if (ac->timer)
339*4882a593Smuzhiyun rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor,
340*4882a593Smuzhiyun RT_NONE, NULL, DixCreateAccess);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun if (rc != Success) {
343*4882a593Smuzhiyun TimerFree(ac->timer);
344*4882a593Smuzhiyun dixFiniPrivates(pCursor, PRIVATE_CURSOR);
345*4882a593Smuzhiyun free(pCursor);
346*4882a593Smuzhiyun return rc;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun /*
350*4882a593Smuzhiyun * Fill in the AnimCurRec
351*4882a593Smuzhiyun */
352*4882a593Smuzhiyun animCursorBits.refcnt++;
353*4882a593Smuzhiyun ac->nelt = ncursor;
354*4882a593Smuzhiyun ac->elts = (AnimCurElt *) (ac + 1);
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun for (i = 0; i < ncursor; i++) {
357*4882a593Smuzhiyun ac->elts[i].pCursor = RefCursor(cursors[i]);
358*4882a593Smuzhiyun ac->elts[i].delay = deltas[i];
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun *ppCursor = pCursor;
362*4882a593Smuzhiyun return Success;
363*4882a593Smuzhiyun }
364