/* xscreensaver, Copyright (c) 2001-2014 Jamie Zawinski <jwz@jwz.org>
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation. No representations are made about the suitability of this
* software for any purpose. It is provided "as is" without express or
/* I implemented this subset of libXPM here because I don't want the
xscreensaver daemon to depend on libXPM for two reasons: first,
because I want the logo to show up even if libXPM is not installed
on the system; and second, I don't want to have to security-audit
libXPM. The fewer libraries that are linked into the xscreensaver
daemon, the more likely to be secure it is.
Also, the Cocoa port uses this code since libXPM isn't available
extern const char *progname
;
union { int i
; char c
[sizeof(int)]; } u
;
static const char hex
[128] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
0, 10,11,12,13,14,15,0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10,11,12,13,14,15,0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
minixpm_to_ximage (Display
*dpy
, Visual
*visual
, Colormap colormap
, int depth
,
unsigned long transparent_color
,
const char * const * data
,
int *width_ret
, int *height_ret
,
unsigned long **pixels_ret
, int *npixels_ret
,
unsigned char **mask_ret
)
int w
, w8
, h
, ncolors
, nbytes
;
int x
, y
, i
, pixel_count
;
memset (cmap
, 0, sizeof(cmap
)); /* avoid warnings */
if (4 != sscanf ((const char *) *data
,
"%d %d %d %d %c", &w
, &h
, &ncolors
, &nbytes
, &c
)) {
fprintf (stderr
, "%s: unparsable XPM header\n", progname
);
if (ncolors
< 1 || ncolors
> 255) {
fprintf (stderr
, "%s: XPM: ncolors is %d\n", progname
, ncolors
);
fprintf (stderr
, "%s: %d-byte XPM files not supported\n",
for (i
= 0; i
< ncolors
; i
++)
const char *line
= *data
;
while (*line
== ' ' || *line
== '\t')
if (!which
) continue; /* whitespace at end of line */
if (which
!= 'c' && which
!= 'm') {
fprintf (stderr
, "%s: unknown XPM pixel type '%c' in \"%s\"\n",
while (*line
== ' ' || *line
== '\t')
if (!strncasecmp(line
, "None", 4))
else if (!strncasecmp(line
, "white", 5))
else if (!strncasecmp(line
, "black", 5))
fprintf (stderr
, "%s: unparsable XPM color spec: \"%s\"\n",
r
= (hex
[(int) line
[0]] << 4) | hex
[(int) line
[1]]; line
+= 2;
g
= (hex
[(int) line
[0]] << 4) | hex
[(int) line
[1]]; line
+= 2;
b
= (hex
[(int) line
[0]] << 4) | hex
[(int) line
[1]]; line
+= 2;
if (depth
== 1) transparent_color
= 1;
pixels
= (unsigned long *) calloc (ncolors
+1, sizeof(*pixels
));
for (i
= 0; i
< ncolors
; i
++)
if (cmap
[i
].cr
== -1) /* transparent */
rmap
[(int) cmap
[i
].byte
] = 255;
color
.flags
= DoRed
|DoGreen
|DoBlue
;
color
.red
= (cmap
[i
].cr
<< 8) | cmap
[i
].cr
;
color
.green
= (cmap
[i
].cg
<< 8) | cmap
[i
].cg
;
color
.blue
= (cmap
[i
].cb
<< 8) | cmap
[i
].cb
;
!XAllocColor (dpy
, colormap
, &color
))
color
.red
= (cmap
[i
].mr
<< 8) | cmap
[i
].mr
;
color
.green
= (cmap
[i
].mg
<< 8) | cmap
[i
].mg
;
color
.blue
= (cmap
[i
].mb
<< 8) | cmap
[i
].mb
;
if (!XAllocColor (dpy
, colormap
, &color
)) {
fprintf (stderr
, "%s: unable to allocate XPM color\n",
pixels
[pixel_count
] = color
.pixel
;
rmap
[(int) cmap
[i
].byte
] = pixel_count
;
ximage
= XCreateImage (dpy
, visual
, depth
,
(depth
== 1 ? XYBitmap
: ZPixmap
),
if (pixels
) free (pixels
);
ximage
->bitmap_bit_order
=
(bigendian() ? MSBFirst
: LSBFirst
);
ximage
->data
= (char *) calloc (ximage
->height
, ximage
->bytes_per_line
);
if (pixels
) free (pixels
);
*mask_ret
= (unsigned char *) malloc (s
);
memset (*mask_ret
, 255, s
);
const char *line
= *data
++;
int p
= rmap
[(int) *line
];
XPutPixel (ximage
, x
, y
, (p
== 255 ? transparent_color
: pixels
[p
]));
if (p
== 255 && mask_ret
)
(*mask_ret
)[(y
* w8
) + (x
>> 3)] &= (~(1 << (x
& 7)));
*npixels_ret
= pixel_count
;