File: | dix/cursor.c |
Location: | line 412, column 13 |
Description: | Access to field 'refcnt' results in a dereference of a null pointer (loaded from variable 'sourcefont') |
1 | /*********************************************************** | |||
2 | ||||
3 | Copyright 1987, 1998 The Open Group | |||
4 | ||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
6 | documentation for any purpose is hereby granted without fee, provided that | |||
7 | the above copyright notice appear in all copies and that both that | |||
8 | copyright notice and this permission notice appear in supporting | |||
9 | documentation. | |||
10 | ||||
11 | The above copyright notice and this permission notice shall be included in | |||
12 | all copies or substantial portions of the Software. | |||
13 | ||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
20 | ||||
21 | Except as contained in this notice, the name of The Open Group shall not be | |||
22 | used in advertising or otherwise to promote the sale, use or other dealings | |||
23 | in this Software without prior written authorization from The Open Group. | |||
24 | ||||
25 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. | |||
26 | ||||
27 | All Rights Reserved | |||
28 | ||||
29 | Permission to use, copy, modify, and distribute this software and its | |||
30 | documentation for any purpose and without fee is hereby granted, | |||
31 | provided that the above copyright notice appear in all copies and that | |||
32 | both that copyright notice and this permission notice appear in | |||
33 | supporting documentation, and that the name of Digital not be | |||
34 | used in advertising or publicity pertaining to distribution of the | |||
35 | software without specific, written prior permission. | |||
36 | ||||
37 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||
38 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||
39 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||
40 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||
41 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||
42 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||
43 | SOFTWARE. | |||
44 | ||||
45 | ******************************************************************/ | |||
46 | ||||
47 | #ifdef HAVE_DIX_CONFIG_H1 | |||
48 | #include <dix-config.h> | |||
49 | #endif | |||
50 | ||||
51 | #include <X11/X.h> | |||
52 | #include <X11/Xmd.h> | |||
53 | #include "servermd.h" | |||
54 | #include "scrnintstr.h" | |||
55 | #include "dixstruct.h" | |||
56 | #include "cursorstr.h" | |||
57 | #include "dixfontstr.h" | |||
58 | #include "opaque.h" | |||
59 | #include "inputstr.h" | |||
60 | #include "xace.h" | |||
61 | ||||
62 | typedef struct _GlyphShare { | |||
63 | FontPtr font; | |||
64 | unsigned short sourceChar; | |||
65 | unsigned short maskChar; | |||
66 | CursorBitsPtr bits; | |||
67 | struct _GlyphShare *next; | |||
68 | } GlyphShare, *GlyphSharePtr; | |||
69 | ||||
70 | static GlyphSharePtr sharedGlyphs = (GlyphSharePtr) NULL((void*)0); | |||
71 | ||||
72 | DevScreenPrivateKeyRec cursorScreenDevPriv; | |||
73 | ||||
74 | static CARD32 cursorSerial; | |||
75 | ||||
76 | static void | |||
77 | FreeCursorBits(CursorBitsPtr bits) | |||
78 | { | |||
79 | if (--bits->refcnt > 0) | |||
80 | return; | |||
81 | free(bits->source); | |||
82 | free(bits->mask); | |||
83 | free(bits->argb); | |||
84 | dixFiniPrivates(bits, PRIVATE_CURSOR_BITS)_dixFiniPrivates((bits)->devPrivates,PRIVATE_CURSOR_BITS); | |||
85 | if (bits->refcnt == 0) { | |||
86 | GlyphSharePtr *prev, this; | |||
87 | ||||
88 | for (prev = &sharedGlyphs; | |||
89 | (this = *prev) && (this->bits != bits); prev = &this->next); | |||
90 | if (this) { | |||
91 | *prev = this->next; | |||
92 | CloseFont(this->font, (Font) 0); | |||
93 | free(this); | |||
94 | } | |||
95 | free(bits); | |||
96 | } | |||
97 | } | |||
98 | ||||
99 | /** | |||
100 | * To be called indirectly by DeleteResource; must use exactly two args. | |||
101 | * | |||
102 | * \param value must conform to DeleteType | |||
103 | */ | |||
104 | int | |||
105 | FreeCursor(void *value, XID cid) | |||
106 | { | |||
107 | int nscr; | |||
108 | CursorPtr pCurs = (CursorPtr) value; | |||
109 | ||||
110 | ScreenPtr pscr; | |||
111 | DeviceIntPtr pDev = NULL((void*)0); /* unused anyway */ | |||
112 | ||||
113 | ||||
114 | UnrefCursor(pCurs); | |||
115 | if (CursorRefCount(pCurs) != 0) | |||
116 | return Success0; | |||
117 | ||||
118 | BUG_WARN(CursorRefCount(pCurs) < 0)do { if (CursorRefCount(pCurs) < 0) { ErrorFSigSafe("BUG: triggered 'if (" "CursorRefCount(pCurs) < 0" ")'\n"); ErrorFSigSafe("BUG: %s:%u in %s()\n" , "cursor.c", 118, __func__); if (0) ErrorFSigSafe(((void*)0) ); xorg_backtrace(); } } while(0); | |||
119 | ||||
120 | for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { | |||
121 | pscr = screenInfo.screens[nscr]; | |||
122 | (void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); | |||
123 | } | |||
124 | FreeCursorBits(pCurs->bits); | |||
125 | dixFiniPrivates(pCurs, PRIVATE_CURSOR)_dixFiniPrivates((pCurs)->devPrivates,PRIVATE_CURSOR); | |||
126 | free(pCurs); | |||
127 | return Success0; | |||
128 | } | |||
129 | ||||
130 | CursorPtr | |||
131 | RefCursor(CursorPtr cursor) | |||
132 | { | |||
133 | if (cursor) | |||
134 | cursor->refcnt++; | |||
135 | return cursor; | |||
136 | } | |||
137 | ||||
138 | CursorPtr | |||
139 | UnrefCursor(CursorPtr cursor) | |||
140 | { | |||
141 | if (cursor) | |||
142 | cursor->refcnt--; | |||
143 | return cursor; | |||
144 | } | |||
145 | ||||
146 | int | |||
147 | CursorRefCount(const CursorPtr cursor) | |||
148 | { | |||
149 | return cursor ? cursor->refcnt : 0; | |||
150 | } | |||
151 | ||||
152 | ||||
153 | /* | |||
154 | * We check for empty cursors so that we won't have to display them | |||
155 | */ | |||
156 | static void | |||
157 | CheckForEmptyMask(CursorBitsPtr bits) | |||
158 | { | |||
159 | unsigned char *msk = bits->mask; | |||
160 | int n = BitmapBytePad(bits->width)(((int)((bits->width) + 32 - 1) >> 5) << 2) * bits->height; | |||
161 | ||||
162 | bits->emptyMask = FALSE0; | |||
163 | while (n--) | |||
164 | if (*(msk++) != 0) | |||
165 | return; | |||
166 | if (bits->argb) { | |||
167 | CARD32 *argb = bits->argb; | |||
168 | ||||
169 | n = bits->width * bits->height; | |||
170 | while (n--) | |||
171 | if (*argb++ & 0xff000000) | |||
172 | return; | |||
173 | } | |||
174 | bits->emptyMask = TRUE1; | |||
175 | } | |||
176 | ||||
177 | /** | |||
178 | * realize the cursor for every screen. Do not change the refcnt, this will be | |||
179 | * changed when ChangeToCursor actually changes the sprite. | |||
180 | * | |||
181 | * @return Success if all cursors realize on all screens, BadAlloc if realize | |||
182 | * failed for a device on a given screen. | |||
183 | */ | |||
184 | static int | |||
185 | RealizeCursorAllScreens(CursorPtr pCurs) | |||
186 | { | |||
187 | DeviceIntPtr pDev; | |||
188 | ScreenPtr pscr; | |||
189 | int nscr; | |||
190 | ||||
191 | for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { | |||
192 | pscr = screenInfo.screens[nscr]; | |||
193 | for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { | |||
194 | if (DevHasCursor(pDev)) { | |||
195 | if (!(*pscr->RealizeCursor) (pDev, pscr, pCurs)) { | |||
196 | /* Realize failed for device pDev on screen pscr. | |||
197 | * We have to assume that for all devices before, realize | |||
198 | * worked. We need to rollback all devices so far on the | |||
199 | * current screen and then all devices on previous | |||
200 | * screens. | |||
201 | */ | |||
202 | DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator */ | |||
203 | ||||
204 | while (pDevIt && pDevIt != pDev) { | |||
205 | if (DevHasCursor(pDevIt)) | |||
206 | (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); | |||
207 | pDevIt = pDevIt->next; | |||
208 | } | |||
209 | while (--nscr >= 0) { | |||
210 | pscr = screenInfo.screens[nscr]; | |||
211 | /* now unrealize all devices on previous screens */ | |||
212 | pDevIt = inputInfo.devices; | |||
213 | while (pDevIt) { | |||
214 | if (DevHasCursor(pDevIt)) | |||
215 | (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); | |||
216 | pDevIt = pDevIt->next; | |||
217 | } | |||
218 | (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); | |||
219 | } | |||
220 | return BadAlloc11; | |||
221 | } | |||
222 | } | |||
223 | } | |||
224 | } | |||
225 | ||||
226 | return Success0; | |||
227 | } | |||
228 | ||||
229 | /** | |||
230 | * does nothing about the resource table, just creates the data structure. | |||
231 | * does not copy the src and mask bits | |||
232 | * | |||
233 | * \param psrcbits server-defined padding | |||
234 | * \param pmaskbits server-defined padding | |||
235 | * \param argb no padding | |||
236 | */ | |||
237 | int | |||
238 | AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, | |||
239 | CARD32 *argb, CursorMetricPtr cm, | |||
240 | unsigned foreRed, unsigned foreGreen, unsigned foreBlue, | |||
241 | unsigned backRed, unsigned backGreen, unsigned backBlue, | |||
242 | CursorPtr *ppCurs, ClientPtr client, XID cid) | |||
243 | { | |||
244 | CursorBitsPtr bits; | |||
245 | CursorPtr pCurs; | |||
246 | int rc; | |||
247 | ||||
248 | *ppCurs = NULL((void*)0); | |||
249 | pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)) + CURSOR_BITS_SIZE(sizeof(CursorBits) + dixPrivatesSize(PRIVATE_CURSOR_BITS)), 1); | |||
250 | if (!pCurs) | |||
251 | return BadAlloc11; | |||
252 | ||||
253 | bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))); | |||
254 | dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR)_dixInitPrivates(&(pCurs)->devPrivates, (pCurs + 1), PRIVATE_CURSOR );; | |||
255 | dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS)_dixInitPrivates(&(bits)->devPrivates, (bits + 1), PRIVATE_CURSOR_BITS ); | |||
256 | bits->source = psrcbits; | |||
257 | bits->mask = pmaskbits; | |||
258 | bits->argb = argb; | |||
259 | bits->width = cm->width; | |||
260 | bits->height = cm->height; | |||
261 | bits->xhot = cm->xhot; | |||
262 | bits->yhot = cm->yhot; | |||
263 | pCurs->refcnt = 1; | |||
264 | bits->refcnt = -1; | |||
265 | CheckForEmptyMask(bits); | |||
266 | pCurs->bits = bits; | |||
267 | pCurs->serialNumber = ++cursorSerial; | |||
268 | pCurs->name = None0L; | |||
269 | ||||
270 | pCurs->foreRed = foreRed; | |||
271 | pCurs->foreGreen = foreGreen; | |||
272 | pCurs->foreBlue = foreBlue; | |||
273 | ||||
274 | pCurs->backRed = backRed; | |||
275 | pCurs->backGreen = backGreen; | |||
276 | pCurs->backBlue = backBlue; | |||
277 | ||||
278 | pCurs->id = cid; | |||
279 | ||||
280 | /* security creation/labeling check */ | |||
281 | rc = XaceHook(XACE_RESOURCE_ACCESS2, client, cid, RT_CURSOR((RESTYPE)5), | |||
282 | pCurs, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3)); | |||
283 | if (rc != Success0) | |||
284 | goto error; | |||
285 | ||||
286 | rc = RealizeCursorAllScreens(pCurs); | |||
287 | if (rc != Success0) | |||
288 | goto error; | |||
289 | ||||
290 | *ppCurs = pCurs; | |||
291 | return Success0; | |||
292 | ||||
293 | error: | |||
294 | FreeCursorBits(bits); | |||
295 | dixFiniPrivates(pCurs, PRIVATE_CURSOR)_dixFiniPrivates((pCurs)->devPrivates,PRIVATE_CURSOR); | |||
296 | free(pCurs); | |||
297 | ||||
298 | return rc; | |||
299 | } | |||
300 | ||||
301 | int | |||
302 | AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, | |||
303 | unsigned foreRed, unsigned foreGreen, unsigned foreBlue, | |||
304 | unsigned backRed, unsigned backGreen, unsigned backBlue, | |||
305 | CursorPtr *ppCurs, ClientPtr client, XID cid) | |||
306 | { | |||
307 | FontPtr sourcefont, maskfont; | |||
308 | unsigned char *srcbits; | |||
309 | unsigned char *mskbits; | |||
310 | CursorMetricRec cm; | |||
311 | int rc; | |||
312 | CursorBitsPtr bits; | |||
313 | CursorPtr pCurs; | |||
314 | GlyphSharePtr pShare; | |||
315 | ||||
316 | rc = dixLookupResourceByType((void **) &sourcefont, source, RT_FONT((RESTYPE)4), | |||
| ||||
317 | client, DixUseAccess(1<<24)); | |||
318 | if (rc != Success0) { | |||
319 | client->errorValue = source; | |||
320 | return rc; | |||
321 | } | |||
322 | rc = dixLookupResourceByType((void **) &maskfont, mask, RT_FONT((RESTYPE)4), client, | |||
323 | DixUseAccess(1<<24)); | |||
324 | if (rc != Success0 && mask != None0L) { | |||
325 | client->errorValue = mask; | |||
326 | return rc; | |||
327 | } | |||
328 | if (sourcefont != maskfont) | |||
329 | pShare = (GlyphSharePtr) NULL((void*)0); | |||
330 | else { | |||
331 | for (pShare = sharedGlyphs; | |||
332 | pShare && | |||
333 | ((pShare->font != sourcefont) || | |||
334 | (pShare->sourceChar != sourceChar) || | |||
335 | (pShare->maskChar != maskChar)); pShare = pShare->next); | |||
336 | } | |||
337 | if (pShare) { | |||
338 | pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)), 1); | |||
339 | if (!pCurs) | |||
340 | return BadAlloc11; | |||
341 | dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR)_dixInitPrivates(&(pCurs)->devPrivates, (pCurs + 1), PRIVATE_CURSOR );; | |||
342 | bits = pShare->bits; | |||
343 | bits->refcnt++; | |||
344 | } | |||
345 | else { | |||
346 | if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm)) { | |||
347 | client->errorValue = sourceChar; | |||
348 | return BadValue2; | |||
349 | } | |||
350 | if (!maskfont) { | |||
351 | long n; | |||
352 | unsigned char *mskptr; | |||
353 | ||||
354 | n = BitmapBytePad(cm.width)(((int)((cm.width) + 32 - 1) >> 5) << 2) * (long) cm.height; | |||
355 | mskptr = mskbits = malloc(n); | |||
356 | if (!mskptr) | |||
357 | return BadAlloc11; | |||
358 | while (--n >= 0) | |||
359 | *mskptr++ = ~0; | |||
360 | } | |||
361 | else { | |||
362 | if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm)) { | |||
363 | client->errorValue = maskChar; | |||
364 | return BadValue2; | |||
365 | } | |||
366 | if ((rc = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits))) | |||
367 | return rc; | |||
368 | } | |||
369 | if ((rc = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits))) { | |||
370 | free(mskbits); | |||
371 | return rc; | |||
372 | } | |||
373 | if (sourcefont != maskfont) { | |||
374 | pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)) + CURSOR_BITS_SIZE(sizeof(CursorBits) + dixPrivatesSize(PRIVATE_CURSOR_BITS)), 1); | |||
375 | if (pCurs) | |||
376 | bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR))); | |||
377 | else | |||
378 | bits = (CursorBitsPtr) NULL((void*)0); | |||
379 | } | |||
380 | else { | |||
381 | pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE(sizeof(CursorRec) + dixPrivatesSize(PRIVATE_CURSOR)), 1); | |||
382 | if (pCurs) | |||
383 | bits = (CursorBitsPtr) calloc(CURSOR_BITS_SIZE(sizeof(CursorBits) + dixPrivatesSize(PRIVATE_CURSOR_BITS)), 1); | |||
384 | else | |||
385 | bits = (CursorBitsPtr) NULL((void*)0); | |||
386 | } | |||
387 | if (!bits) { | |||
388 | free(pCurs); | |||
389 | free(mskbits); | |||
390 | free(srcbits); | |||
391 | return BadAlloc11; | |||
392 | } | |||
393 | dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR)_dixInitPrivates(&(pCurs)->devPrivates, (pCurs + 1), PRIVATE_CURSOR );; | |||
394 | dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS)_dixInitPrivates(&(bits)->devPrivates, (bits + 1), PRIVATE_CURSOR_BITS );; | |||
395 | bits->source = srcbits; | |||
396 | bits->mask = mskbits; | |||
397 | bits->argb = 0; | |||
398 | bits->width = cm.width; | |||
399 | bits->height = cm.height; | |||
400 | bits->xhot = cm.xhot; | |||
401 | bits->yhot = cm.yhot; | |||
402 | if (sourcefont != maskfont) | |||
403 | bits->refcnt = -1; | |||
404 | else { | |||
405 | bits->refcnt = 1; | |||
406 | pShare = malloc(sizeof(GlyphShare)); | |||
407 | if (!pShare) { | |||
408 | FreeCursorBits(bits); | |||
409 | return BadAlloc11; | |||
410 | } | |||
411 | pShare->font = sourcefont; | |||
412 | sourcefont->refcnt++; | |||
| ||||
413 | pShare->sourceChar = sourceChar; | |||
414 | pShare->maskChar = maskChar; | |||
415 | pShare->bits = bits; | |||
416 | pShare->next = sharedGlyphs; | |||
417 | sharedGlyphs = pShare; | |||
418 | } | |||
419 | } | |||
420 | ||||
421 | CheckForEmptyMask(bits); | |||
422 | pCurs->bits = bits; | |||
423 | pCurs->refcnt = 1; | |||
424 | pCurs->serialNumber = ++cursorSerial; | |||
425 | pCurs->name = None0L; | |||
426 | ||||
427 | pCurs->foreRed = foreRed; | |||
428 | pCurs->foreGreen = foreGreen; | |||
429 | pCurs->foreBlue = foreBlue; | |||
430 | ||||
431 | pCurs->backRed = backRed; | |||
432 | pCurs->backGreen = backGreen; | |||
433 | pCurs->backBlue = backBlue; | |||
434 | ||||
435 | pCurs->id = cid; | |||
436 | ||||
437 | /* security creation/labeling check */ | |||
438 | rc = XaceHook(XACE_RESOURCE_ACCESS2, client, cid, RT_CURSOR((RESTYPE)5), | |||
439 | pCurs, RT_NONE((RESTYPE)0), NULL((void*)0), DixCreateAccess(1<<3)); | |||
440 | if (rc != Success0) | |||
441 | goto error; | |||
442 | ||||
443 | rc = RealizeCursorAllScreens(pCurs); | |||
444 | if (rc != Success0) | |||
445 | goto error; | |||
446 | ||||
447 | *ppCurs = pCurs; | |||
448 | return Success0; | |||
449 | ||||
450 | error: | |||
451 | FreeCursorBits(bits); | |||
452 | dixFiniPrivates(pCurs, PRIVATE_CURSOR)_dixFiniPrivates((pCurs)->devPrivates,PRIVATE_CURSOR); | |||
453 | free(pCurs); | |||
454 | ||||
455 | return rc; | |||
456 | } | |||
457 | ||||
458 | /** CreateRootCursor | |||
459 | * | |||
460 | * look up the name of a font | |||
461 | * open the font | |||
462 | * add the font to the resource table | |||
463 | * make a cursor from the glyphs | |||
464 | * add the cursor to the resource table | |||
465 | *************************************************************/ | |||
466 | ||||
467 | CursorPtr | |||
468 | CreateRootCursor(char *unused1, unsigned int unused2) | |||
469 | { | |||
470 | CursorPtr curs; | |||
471 | FontPtr cursorfont; | |||
472 | int err; | |||
473 | XID fontID; | |||
474 | ||||
475 | fontID = FakeClientID(0); | |||
476 | err = OpenFont(serverClient, fontID, FontLoadAll0x000f | FontOpenSync0x0010, | |||
477 | (unsigned) strlen(defaultCursorFont), defaultCursorFont); | |||
478 | if (err != Success0) | |||
479 | return NullCursor((CursorPtr)((void*)0)); | |||
480 | ||||
481 | err = dixLookupResourceByType((void **) &cursorfont, fontID, RT_FONT((RESTYPE)4), | |||
482 | serverClient, DixReadAccess(1<<0)); | |||
483 | if (err != Success0) | |||
484 | return NullCursor((CursorPtr)((void*)0)); | |||
485 | if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, | |||
486 | &curs, serverClient, (XID) 0) != Success0) | |||
487 | return NullCursor((CursorPtr)((void*)0)); | |||
488 | ||||
489 | if (!AddResourceDarwin_X_AddResource(FakeClientID(0), RT_CURSOR((RESTYPE)5), (void *) curs)) | |||
490 | return NullCursor((CursorPtr)((void*)0)); | |||
491 | ||||
492 | return curs; | |||
493 | } |