Bug Summary

File:cursor.c
Location:line 445, column 9
Description:Assigned value is garbage or undefined

Annotated Source Code

1/*
2 * Copyright © 2002 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include "xcursorint.h"
24#include <X11/Xlibint.h>
25#include <X11/Xutil.h>
26
27XcursorCursors *
28XcursorCursorsCreate (Display *dpy, int size)
29{
30 XcursorCursors *cursors;
31
32 cursors = malloc (sizeof (XcursorCursors) +
33 size * sizeof (Cursor));
34 if (!cursors)
35 return NULL((void*)0);
36 cursors->ref = 1;
37 cursors->dpy = dpy;
38 cursors->ncursor = 0;
39 cursors->cursors = (Cursor *) (cursors + 1);
40 return cursors;
41}
42
43void
44XcursorCursorsDestroy (XcursorCursors *cursors)
45{
46 int n;
47
48 if (!cursors)
49 return;
50
51 --cursors->ref;
52 if (cursors->ref > 0)
53 return;
54
55 for (n = 0; n < cursors->ncursor; n++)
56 XFreeCursor (cursors->dpy, cursors->cursors[n]);
57 free (cursors);
58}
59
60XcursorAnimate *
61XcursorAnimateCreate (XcursorCursors *cursors)
62{
63 XcursorAnimate *animate;
64
65 animate = malloc (sizeof (XcursorAnimate));
66 if (!animate)
67 return NULL((void*)0);
68 animate->cursors = cursors;
69 cursors->ref++;
70 animate->sequence = 0;
71 return animate;
72}
73
74void
75XcursorAnimateDestroy (XcursorAnimate *animate)
76{
77 if (!animate)
78 return;
79
80 XcursorCursorsDestroy (animate->cursors);
81 free (animate);
82}
83
84Cursor
85XcursorAnimateNext (XcursorAnimate *animate)
86{
87 Cursor cursor = animate->cursors->cursors[animate->sequence++];
88
89 if (animate->sequence >= animate->cursors->ncursor)
90 animate->sequence = 0;
91 return cursor;
92}
93
94static int
95nativeByteOrder (void)
96{
97 int x = 1;
98
99 return (*((char *) &x) == 1) ? LSBFirst0 : MSBFirst1;
100}
101
102static XcursorUInt
103_XcursorPixelBrightness (XcursorPixel p)
104{
105 XcursorPixel alpha = p >> 24;
106 XcursorPixel r, g, b;
107
108 if (!alpha)
109 return 0;
110 r = ((p >> 8) & 0xff00) / alpha;
111 if (r > 0xff) r = 0xff;
112 g = ((p >> 0) & 0xff00) / alpha;
113 if (g > 0xff) g = 0xff;
114 b = ((p << 8) & 0xff00) / alpha;
115 if (b > 0xff) b = 0xff;
116 return (r * 153 + g * 301 + b * 58) >> 9;
117}
118
119static unsigned short
120_XcursorDivideAlpha (XcursorUInt value, XcursorUInt alpha)
121{
122 if (!alpha)
123 return 0;
124 value = value * 255 / alpha;
125 if (value > 255)
126 value = 255;
127 return value | (value << 8);
128}
129
130static void
131_XcursorPixelToColor (XcursorPixel p, XColor *color)
132{
133 XcursorPixel alpha = p >> 24;
134
135 color->pixel = 0;
136 color->red = _XcursorDivideAlpha ((p >> 16) & 0xff, alpha);
137 color->green = _XcursorDivideAlpha ((p >> 8) & 0xff, alpha);
138 color->blue = _XcursorDivideAlpha ((p >> 0) & 0xff, alpha);
139 color->flags = DoRed(1<<0)|DoGreen(1<<1)|DoBlue(1<<2);
140}
141
142#undef DEBUG_IMAGE
143#ifdef DEBUG_IMAGE
144static void
145_XcursorDumpImage (XImage *image)
146{
147 FILE *f = fopen ("/tmp/images", "a");
148 int x, y;
149 if (!f)
150 return;
151 fprintf (f, "%d x %x\n", image->width, image->height);
152 for (y = 0; y < image->height; y++)
153 {
154 for (x = 0; x < image->width; x++)
155 fprintf (f, "%c", XGetPixel (image, x, y)((*((image)->f.get_pixel))((image), (x), (y))) ? '*' : ' ');
156 fprintf (f, "\n");
157 }
158 fflush (f);
159 fclose (f);
160}
161
162static void
163_XcursorDumpColor (XColor *color, char *name)
164{
165 FILE *f = fopen ("/tmp/images", "a");
166 fprintf (f, "%s: %x %x %x\n", name,
167 color->red, color->green, color->blue);
168 fflush (f);
169 fclose (f);
170}
171#endif
172
173static int
174_XcursorCompareRed (const void *a, const void *b)
175{
176 const XcursorPixel *ap = a, *bp = b;
177
178 return (int) (((*ap >> 16) & 0xff) - ((*bp >> 16) & 0xff));
179}
180
181static int
182_XcursorCompareGreen (const void *a, const void *b)
183{
184 const XcursorPixel *ap = a, *bp = b;
185
186 return (int) (((*ap >> 8) & 0xff) - ((*bp >> 8) & 0xff));
187}
188
189static int
190_XcursorCompareBlue (const void *a, const void *b)
191{
192 const XcursorPixel *ap = a, *bp = b;
193
194 return (int) (((*ap >> 0) & 0xff) - ((*bp >> 0) & 0xff));
195}
196
197static XcursorPixel
198_XcursorAverageColor (XcursorPixel *pixels, int npixels)
199{
200 XcursorPixel p;
201 XcursorPixel red, green, blue;
202 int n = npixels;
203
204 if (n < 1)
205 return 0;
206
207 blue = green = red = 0;
208 while (n--)
209 {
210 p = *pixels++;
211 red += (p >> 16) & 0xff;
212 green += (p >> 8) & 0xff;
213 blue += (p >> 0) & 0xff;
214 }
215 return (0xffU << 24) | ((red/npixels) << 16) | ((green/npixels) << 8) | (blue/npixels);
216}
217
218typedef struct XcursorCoreCursor {
219 XImage *src_image;
220 XImage *msk_image;
221 XColor on_color;
222 XColor off_color;
223} XcursorCoreCursor;
224
225static Boolint
226_XcursorHeckbertMedianCut (const XcursorImage *image, XcursorCoreCursor *core)
227{
228 XImage *src_image = core->src_image, *msk_image = core->msk_image;
229 unsigned int npixels = image->width * image->height;
230 int ncolors;
231 int n;
232 XcursorPixel *po, *pn, *pc;
233 XcursorPixel p;
234 XcursorPixel red, green, blue, alpha;
235 XcursorPixel max_red, min_red, max_green, min_green, max_blue, min_blue;
236 XcursorPixel *temp, *pixels, *colors;
237 int split;
238 XcursorPixel leftColor, centerColor, rightColor;
239 int (*compare) (const void *, const void *);
240 int x, y;
241
242 /*
243 * Temp space for converted image and converted colors
244 */
245 temp = malloc (npixels * sizeof (XcursorPixel) * 2);
246 if (!temp)
247 return False0;
248
249 pixels = temp;
250 colors = pixels + npixels;
251
252 /*
253 * Convert to 2-value alpha and build
254 * array of opaque color values and an
255 */
256 po = image->pixels;
257 pn = pixels;
258 pc = colors;
259 max_blue = max_green = max_red = 0;
260 min_blue = min_green = min_red = 255;
261 n = npixels;
262 while (n--)
263 {
264 p = *po++;
265 alpha = (p >> 24) & 0xff;
266 red = (p >> 16) & 0xff;
267 green = (p >> 8) & 0xff;
268 blue = (p >> 0) & 0xff;
269 if (alpha >= 0x80)
270 {
271 red = red * 255 / alpha;
272 green = green * 255 / alpha;
273 blue = blue * 255 / alpha;
274 if (red < min_red) min_red = red;
275 if (red > max_red) max_red = red;
276 if (green < min_green) min_green = green;
277 if (green > max_green) max_green = green;
278 if (blue < min_blue) min_blue = blue;
279 if (blue > max_blue) max_blue = blue;
280 p = ((0xffU << 24) | (red << 16) |
281 (green << 8) | (blue << 0));
282 *pc++ = p;
283 }
284 else
285 p = 0;
286 *pn++ = p;
287 }
288 ncolors = pc - colors;
289
290 /*
291 * Compute longest dimension and sort
292 */
293 if ((max_green - min_green) >= (max_red - min_red) &&
294 (max_green - min_green) >= (max_blue - min_blue))
295 compare = _XcursorCompareGreen;
296 else if ((max_red - min_red) >= (max_blue - min_blue))
297 compare = _XcursorCompareRed;
298 else
299 compare = _XcursorCompareBlue;
300 qsort (colors, ncolors, sizeof (XcursorPixel), compare);
301 /*
302 * Compute average colors on both sides of the cut
303 */
304 split = ncolors >> 1;
305 leftColor = _XcursorAverageColor (colors, split);
306 centerColor = colors[split];
307 rightColor = _XcursorAverageColor (colors + split, ncolors - split);
308 /*
309 * Select best color for each pixel
310 */
311 pn = pixels;
312 for (y = 0; y < image->height; y++)
313 for (x = 0; x < image->width; x++)
314 {
315 p = *pn++;
316 if (p & 0xff000000)
317 {
318 XPutPixel (msk_image, x, y, 1)((*((msk_image)->f.put_pixel))((msk_image), (x), (y), (1))
)
;
319 if ((*compare) (&p, &centerColor) >= 0)
320 XPutPixel (src_image, x, y, 0)((*((src_image)->f.put_pixel))((src_image), (x), (y), (0))
)
;
321 else
322 XPutPixel (src_image, x, y, 1)((*((src_image)->f.put_pixel))((src_image), (x), (y), (1))
)
;
323 }
324 else
325 {
326 XPutPixel (msk_image, x, y, 0)((*((msk_image)->f.put_pixel))((msk_image), (x), (y), (0))
)
;
327 XPutPixel (src_image, x, y, 0)((*((src_image)->f.put_pixel))((src_image), (x), (y), (0))
)
;
328 }
329 }
330 free (temp);
331 _XcursorPixelToColor (rightColor, &core->off_color);
332 _XcursorPixelToColor (leftColor, &core->on_color);
333 return True1;
334}
335
336#if 0
337#define DITHER_DIM2 4
338static XcursorPixel orderedDither[4][4] = {
339 { 1, 9, 3, 11 },
340 { 13, 5, 15, 7 },
341 { 4, 12, 2, 10 },
342 { 16, 8, 14, 6 }
343};
344#else
345#define DITHER_DIM2 2
346static XcursorPixel orderedDither[2][2] = {
347 { 1, 3, },
348 { 4, 2, },
349};
350#endif
351
352#define DITHER_SIZE((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
353
354static Boolint
355_XcursorBayerOrderedDither (const XcursorImage *image, XcursorCoreCursor *core)
356{
357 int x, y;
358 XcursorPixel *pixel, p;
359 XcursorPixel a, i, d;
360
361 pixel = image->pixels;
362 for (y = 0; y < image->height; y++)
363 for (x = 0; x < image->width; x++)
364 {
365 p = *pixel++;
366 a = ((p >> 24) * DITHER_SIZE((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) + 127) / 255;
367 i = (_XcursorPixelBrightness (p) * DITHER_SIZE((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) + 127) / 255;
368 d = orderedDither[y&(DITHER_DIM2-1)][x&(DITHER_DIM2-1)];
369 if (a > d)
370 {
371 XPutPixel (core->msk_image, x, y, 1)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (1)))
;
372 if (i > d)
373 XPutPixel (core->src_image, x, y, 0)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (0)))
; /* white */
374 else
375 XPutPixel (core->src_image, x, y, 1)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (1)))
; /* black */
376 }
377 else
378 {
379 XPutPixel (core->msk_image, x, y, 0)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (0)))
;
380 XPutPixel (core->src_image, x, y, 0)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (0)))
;
381 }
382 }
383 core->on_color.red = 0;
384 core->on_color.green = 0;
385 core->on_color.blue = 0;
386 core->off_color.red = 0xffff;
387 core->off_color.green = 0xffff;
388 core->off_color.blue = 0xffff;
389 return True1;
390}
391
392static Boolint
393_XcursorFloydSteinberg (const XcursorImage *image, XcursorCoreCursor *core)
394{
395 int *aPicture, *iPicture, *aP, *iP;
396 XcursorPixel *pixel, p;
397 int aR, iR, aA, iA;
398 unsigned int npixels = image->width * image->height;
399 int n;
400 int right = 1;
401 int belowLeft = image->width - 1;
402 int below = image->width;
403 int belowRight = image->width + 1;
404 int iError, aError;
405 int iErrorRight, aErrorRight;
406 int iErrorBelowLeft, aErrorBelowLeft;
407 int iErrorBelow, aErrorBelow;
408 int iErrorBelowRight, aErrorBelowRight;
409 int x, y;
410 int max_inten, min_inten, mean_inten;
411
412 iPicture = malloc (npixels * sizeof (int) * 2);
413 if (!iPicture)
18
Assuming 'iPicture' is non-null
19
Taking false branch
414 return False0;
415 aPicture = iPicture + npixels;
416
417 /*
418 * Compute raw gray and alpha arrays
419 */
420 pixel = image->pixels;
421 iP = iPicture;
422 aP = aPicture;
423 n = npixels;
424 max_inten = 0;
425 min_inten = 0xff;
426 while (n--)
20
Loop condition is false. Execution continues on line 438
427 {
428 p = *pixel++;
429 *aP++ = (int) (p >> 24);
430 iR = (int) _XcursorPixelBrightness (p);
431 if (iR > max_inten) max_inten = iR;
432 if (iR < min_inten) min_inten = iR;
433 *iP++ = iR;
434 }
435 /*
436 * Draw the image while diffusing the error
437 */
438 iP = iPicture;
439 aP = aPicture;
440 mean_inten = (max_inten + min_inten + 1) >> 1;
441 for (y = 0; y < image->height; y++)
21
Loop condition is true. Entering loop body
442 for (x = 0; x < image->width; x++)
22
Loop condition is true. Entering loop body
443 {
444 aR = *aP;
445 iR = *iP;
23
Assigned value is garbage or undefined
446 if (aR >= 0x80)
447 {
448 XPutPixel (core->msk_image, x, y, 1)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (1)))
;
449 aA = 0xff;
450 }
451 else
452 {
453 XPutPixel (core->msk_image, x, y, 0)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (0)))
;
454 aA = 0x00;
455 }
456 if (iR >= mean_inten)
457 {
458 XPutPixel (core->src_image, x, y, 0)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (0)))
;
459 iA = max_inten;
460 }
461 else
462 {
463 XPutPixel (core->src_image, x, y, 1)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (1)))
;
464 iA = min_inten;
465 }
466 iError = iR - iA;
467 aError = aR - aA;
468 iErrorRight = (iError * 7) >> 4;
469 iErrorBelowLeft = (iError * 3) >> 4;
470 iErrorBelow = (iError * 5) >> 4;
471 iErrorBelowRight = (iError - iErrorRight -
472 iErrorBelowLeft - iErrorBelow);
473 aErrorRight = (aError * 7) >> 4;
474 aErrorBelowLeft = (aError * 3) >> 4;
475 aErrorBelow = (aError * 5) >> 4;
476 aErrorBelowRight = (aError - aErrorRight -
477 aErrorBelowLeft - aErrorBelow);
478 if (x < image->width - 1)
479 {
480 iP[right] += iErrorRight;
481 aP[right] += aErrorRight;
482 }
483 if (y < image->height - 1)
484 {
485 if (x)
486 {
487 iP[belowLeft] += iErrorBelowLeft;
488 aP[belowLeft] += aErrorBelowLeft;
489 }
490 iP[below] += iErrorBelow;
491 aP[below] += aErrorBelow;
492 if (x < image->width - 1)
493 {
494 iP[belowRight] += iErrorBelowRight;
495 aP[belowRight] += aErrorBelowRight;
496 }
497 }
498 aP++;
499 iP++;
500 }
501 free (iPicture);
502 core->on_color.red =
503 core->on_color.green =
504 core->on_color.blue = (min_inten | min_inten << 8);
505 core->off_color.red =
506 core->off_color.green =
507 core->off_color.blue = (max_inten | max_inten << 8);
508 return True1;
509}
510
511static Boolint
512_XcursorThreshold (const XcursorImage *image, XcursorCoreCursor *core)
513{
514 XcursorPixel *pixel, p;
515 int x, y;
516
517 /*
518 * Draw the image, picking black for dark pixels and white for light
519 */
520 pixel = image->pixels;
521 for (y = 0; y < image->height; y++)
522 for (x = 0; x < image->width; x++)
523 {
524 p = *pixel++;
525 if ((p >> 24) >= 0x80)
526 {
527 XPutPixel (core->msk_image, x, y, 1)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (1)))
;
528 if (_XcursorPixelBrightness (p) > 0x80)
529 XPutPixel (core->src_image, x, y, 0)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (0)))
;
530 else
531 XPutPixel (core->src_image, x, y, 1)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (1)))
;
532 }
533 else
534 {
535 XPutPixel (core->msk_image, x, y, 0)((*((core->msk_image)->f.put_pixel))((core->msk_image
), (x), (y), (0)))
;
536 XPutPixel (core->src_image, x, y, 0)((*((core->src_image)->f.put_pixel))((core->src_image
), (x), (y), (0)))
;
537 }
538 }
539 core->on_color.red =
540 core->on_color.green =
541 core->on_color.blue = 0;
542 core->off_color.red =
543 core->off_color.green =
544 core->off_color.blue = 0xffff;
545 return True1;
546}
547
548Cursor
549XcursorImageLoadCursor (Display *dpy, const XcursorImage *image)
550{
551 Cursor cursor;
552
553#if RENDER_MAJOR0 > 0 || RENDER_MINOR11 >= 5
554 if (XcursorSupportsARGB (dpy))
13
Taking false branch
555 {
556 XImage ximage;
557 int screen = DefaultScreen (dpy)(((_XPrivDisplay)(dpy))->default_screen);
558 Pixmap pixmap;
559 Picture picture;
560 GC gc;
561 XRenderPictFormat *format;
562
563 ximage.width = image->width;
564 ximage.height = image->height;
565 ximage.xoffset = 0;
566 ximage.format = ZPixmap2;
567 ximage.data = (char *) image->pixels;
568 ximage.byte_order = nativeByteOrder ();
569 ximage.bitmap_unit = 32;
570 ximage.bitmap_bit_order = ximage.byte_order;
571 ximage.bitmap_pad = 32;
572 ximage.depth = 32;
573 ximage.bits_per_pixel = 32;
574 ximage.bytes_per_line = image->width * 4;
575 ximage.red_mask = 0xff0000;
576 ximage.green_mask = 0x00ff00;
577 ximage.blue_mask = 0x0000ff;
578 ximage.obdata = NULL((void*)0);
579 if (!XInitImage (&ximage))
580 return None0L;
581 pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen)((&((_XPrivDisplay)(dpy))->screens[screen])->root),
582 image->width, image->height, 32);
583 gc = XCreateGC (dpy, pixmap, 0, NULL((void*)0));
584 XPutImage (dpy, pixmap, gc, &ximage,
585 0, 0, 0, 0, image->width, image->height);
586 XFreeGC (dpy, gc);
587 format = XRenderFindStandardFormat (dpy, PictStandardARGB320);
588 picture = XRenderCreatePicture (dpy, pixmap, format, 0, NULL((void*)0));
589 XFreePixmap (dpy, pixmap);
590 cursor = XRenderCreateCursor (dpy, picture,
591 image->xhot, image->yhot);
592 XRenderFreePicture (dpy, picture);
593 }
594 else
595#endif
596 {
597 XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
598 int screen = DefaultScreen (dpy)(((_XPrivDisplay)(dpy))->default_screen);
599 XcursorCoreCursor core;
600 Pixmap src_pixmap, msk_pixmap;
601 GC gc;
602 XGCValues gcv;
603
604 if (!info)
14
Assuming 'info' is non-null
15
Taking false branch
605 return 0;
606
607 core.src_image = XCreateImage (dpy, NULL((void*)0), 1, ZPixmap2,
608 0, NULL((void*)0), image->width, image->height,
609 32, 0);
610 core.src_image->data = Xmalloc (image->height *malloc(((image->height * core.src_image->bytes_per_line
) == 0 ? 1 : (image->height * core.src_image->bytes_per_line
)))
611 core.src_image->bytes_per_line)malloc(((image->height * core.src_image->bytes_per_line
) == 0 ? 1 : (image->height * core.src_image->bytes_per_line
)))
;
612 core.msk_image = XCreateImage (dpy, NULL((void*)0), 1, ZPixmap2,
613 0, NULL((void*)0), image->width, image->height,
614 32, 0);
615 core.msk_image->data = Xmalloc (image->height *malloc(((image->height * core.msk_image->bytes_per_line
) == 0 ? 1 : (image->height * core.msk_image->bytes_per_line
)))
616 core.msk_image->bytes_per_line)malloc(((image->height * core.msk_image->bytes_per_line
) == 0 ? 1 : (image->height * core.msk_image->bytes_per_line
)))
;
617
618 switch (info->dither) {
16
Control jumps to 'case XcursorDitherDiffuse:' at line 631
619 case XcursorDitherThreshold:
620 if (!_XcursorThreshold (image, &core))
621 return 0;
622 break;
623 case XcursorDitherMedian:
624 if (!_XcursorHeckbertMedianCut (image, &core))
625 return 0;
626 break;
627 case XcursorDitherOrdered:
628 if (!_XcursorBayerOrderedDither (image, &core))
629 return 0;
630 break;
631 case XcursorDitherDiffuse:
632 if (!_XcursorFloydSteinberg (image, &core))
17
Calling '_XcursorFloydSteinberg'
633 return 0;
634 break;
635 default:
636 return 0;
637 }
638
639 /*
640 * Create the cursor
641 */
642 src_pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen)((&((_XPrivDisplay)(dpy))->screens[screen])->root),
643 image->width, image->height, 1);
644 msk_pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen)((&((_XPrivDisplay)(dpy))->screens[screen])->root),
645 image->width, image->height, 1);
646 gcv.foreground = 1;
647 gcv.background = 0;
648 gc = XCreateGC (dpy, src_pixmap,
649 GCForeground(1L<<2)|GCBackground(1L<<3),
650 &gcv);
651 XPutImage (dpy, src_pixmap, gc, core.src_image,
652 0, 0, 0, 0, image->width, image->height);
653
654 XPutImage (dpy, msk_pixmap, gc, core.msk_image,
655 0, 0, 0, 0, image->width, image->height);
656 XFreeGC (dpy, gc);
657
658#ifdef DEBUG_IMAGE
659 _XcursorDumpColor (&core.on_color, "on_color");
660 _XcursorDumpColor (&core.off_color, "off_color");
661 _XcursorDumpImage (core.src_image);
662 _XcursorDumpImage (core.msk_image);
663#endif
664 XDestroyImage (core.src_image)((*((core.src_image)->f.destroy_image))((core.src_image)));
665 XDestroyImage (core.msk_image)((*((core.msk_image)->f.destroy_image))((core.msk_image)));
666
667 cursor = XCreatePixmapCursor (dpy, src_pixmap, msk_pixmap,
668 &core.on_color, &core.off_color,
669 image->xhot, image->yhot);
670 XFreePixmap (dpy, src_pixmap);
671 XFreePixmap (dpy, msk_pixmap);
672 }
673 return cursor;
674}
675
676XcursorCursors *
677XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images)
678{
679 XcursorCursors *cursors = XcursorCursorsCreate (dpy, images->nimage);
680 int n;
681
682 if (!cursors)
4
Taking false branch
683 return NULL((void*)0);
684 for (n = 0; n < images->nimage; n++)
5
Loop condition is true. Entering loop body
7
Loop condition is true. Entering loop body
9
Loop condition is true. Entering loop body
11
Loop condition is true. Entering loop body
685 {
686 cursors->cursors[n] = XcursorImageLoadCursor (dpy, images->images[n]);
12
Calling 'XcursorImageLoadCursor'
687 if (!cursors->cursors[n])
6
Taking false branch
8
Taking false branch
10
Taking false branch
688 {
689 XcursorCursorsDestroy (cursors);
690 return NULL((void*)0);
691 }
692 cursors->ncursor++;
693 }
694 return cursors;
695}
696
697Cursor
698XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images)
699{
700 Cursor cursor;
701 if (images->nimage == 1 || !XcursorSupportsAnim (dpy))
702 cursor = XcursorImageLoadCursor (dpy, images->images[0]);
703 else
704 {
705 XcursorCursors *cursors = XcursorImagesLoadCursors (dpy, images);
706 XAnimCursor *anim;
707 int n;
708
709 if (!cursors)
710 return 0;
711 anim = malloc (cursors->ncursor * sizeof (XAnimCursor));
712 if (!anim)
713 {
714 XcursorCursorsDestroy (cursors);
715 return 0;
716 }
717 for (n = 0; n < cursors->ncursor; n++)
718 {
719 anim[n].cursor = cursors->cursors[n];
720 anim[n].delay = images->images[n]->delay;
721 }
722 cursor = XRenderCreateAnimCursor (dpy, cursors->ncursor, anim);
723 XcursorCursorsDestroy(cursors);
724 free (anim);
725 }
726#if defined HAVE_XFIXES1 && XFIXES_MAJOR5 >= 2
727 if (images->name)
728 XFixesSetCursorName (dpy, cursor, images->name);
729#endif
730 return cursor;
731}
732
733
734Cursor
735XcursorFilenameLoadCursor (Display *dpy, const char *file)
736{
737 int size = XcursorGetDefaultSize (dpy);
738 XcursorImages *images = XcursorFilenameLoadImages (file, size);
739 Cursor cursor;
740
741 if (!images)
742 return None0L;
743 cursor = XcursorImagesLoadCursor (dpy, images);
744 XcursorImagesDestroy (images);
745 return cursor;
746}
747
748XcursorCursors *
749XcursorFilenameLoadCursors (Display *dpy, const char *file)
750{
751 int size = XcursorGetDefaultSize (dpy);
752 XcursorImages *images = XcursorFilenameLoadImages (file, size);
753 XcursorCursors *cursors;
754
755 if (!images)
1
Assuming 'images' is non-null
2
Taking false branch
756 return NULL((void*)0);
757 cursors = XcursorImagesLoadCursors (dpy, images);
3
Calling 'XcursorImagesLoadCursors'
758 XcursorImagesDestroy (images);
759 return cursors;
760}
761
762/*
763 * Stolen from XCreateGlyphCursor (which we cruelly override)
764 */
765
766Cursor
767_XcursorCreateGlyphCursor(Display *dpy,
768 Font source_font,
769 Font mask_font,
770 unsigned int source_char,
771 unsigned int mask_char,
772 XColor _Xconstconst *foreground,
773 XColor _Xconstconst *background)
774{
775 Cursor cid;
776 register xCreateGlyphCursorReq *req;
777
778 LockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->lock_display
)(dpy)
;
779 GetReq(CreateGlyphCursor, req)req = (xCreateGlyphCursorReq *) _XGetRequest(dpy, 94, 32);
780 cid = req->cid = XAllocID(dpy)((*((_XPrivDisplay)(dpy))->resource_alloc)((dpy)));
781 req->source = source_font;
782 req->mask = mask_font;
783 req->sourceChar = source_char;
784 req->maskChar = mask_char;
785 req->foreRed = foreground->red;
786 req->foreGreen = foreground->green;
787 req->foreBlue = foreground->blue;
788 req->backRed = background->red;
789 req->backGreen = background->green;
790 req->backBlue = background->blue;
791 UnlockDisplay(dpy)if ((dpy)->lock_fns) (*(dpy)->lock_fns->unlock_display
)(dpy)
;
792 SyncHandle()if (dpy->synchandler) (*dpy->synchandler)(dpy);
793 return (cid);
794}
795
796/*
797 * Stolen from XCreateFontCursor (which we cruelly override)
798 */
799
800Cursor
801_XcursorCreateFontCursor (Display *dpy, unsigned int shape)
802{
803 static XColor _Xconstconst foreground = { 0, 0, 0, 0 }; /* black */
804 static XColor _Xconstconst background = { 0, 65535, 65535, 65535 }; /* white */
805
806 /*
807 * the cursor font contains the shape glyph followed by the mask
808 * glyph; so character position 0 contains a shape, 1 the mask for 0,
809 * 2 a shape, etc. <X11/cursorfont.h> contains hash define names
810 * for all of these.
811 */
812
813 if (dpy->cursor_font == None0L)
814 {
815 dpy->cursor_font = XLoadFont (dpy, CURSORFONT"cursor");
816 if (dpy->cursor_font == None0L)
817 return None0L;
818 }
819
820 return _XcursorCreateGlyphCursor (dpy, dpy->cursor_font, dpy->cursor_font,
821 shape, shape + 1, &foreground, &background);
822}
823