source: trunk/third/xscreensaver/hacks/xpm-pixmap.c @ 20148

Revision 20148, 7.6 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* xpm-pixmap.c --- converts XPM data to a Pixmap.
2 * xscreensaver, Copyright (c) 1998, 2001, 2002 Jamie Zawinski <jwz@jwz.org>
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.  No representations are made about the suitability of this
9 * software for any purpose.  It is provided "as is" without express or
10 * implied warranty.
11 */
12
13#ifdef HAVE_CONFIG_H
14# include "config.h"
15#endif
16
17#include <X11/Xlib.h>
18#include <stdlib.h>
19#include <stdio.h>
20
21#include "visual.h"  /* for screen_number() */
22
23extern char *progname;
24
25
26#if defined(HAVE_GDK_PIXBUF)
27
28# include <gdk-pixbuf/gdk-pixbuf.h>
29
30# ifdef HAVE_GTK2
31#  include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
32# else  /* !HAVE_GTK2 */
33#  include <gdk-pixbuf/gdk-pixbuf-xlib.h>
34# endif /* !HAVE_GTK2 */
35
36
37/* Returns a Pixmap structure containing the bits of the given XPM image.
38   This is the gdk_pixbuf version of this function.
39 */
40static Pixmap
41xpm_to_pixmap_1 (Display *dpy, Window window,
42                 int *width_ret, int *height_ret,
43                 Pixmap *mask_ret,
44                 const char *filename,
45                 char **xpm_data)
46{
47  GdkPixbuf *pb;
48  static int initted = 0;
49  XWindowAttributes xgwa;
50#ifdef HAVE_GTK2
51  GError *gerr = NULL;
52#endif /* HAVE_GTK2 */
53  XGetWindowAttributes (dpy, window, &xgwa);
54
55  if (!initted)
56    {
57#ifdef HAVE_GTK2
58      g_type_init ();
59#endif /* HAVE_GTK2 */
60      gdk_pixbuf_xlib_init (dpy, screen_number (xgwa.screen));
61      xlib_rgb_init (dpy, xgwa.screen);
62      initted = 1;
63    }
64
65  pb = (filename
66#ifdef HAVE_GTK2
67        ? gdk_pixbuf_new_from_file (filename, &gerr)
68#else  /* !HAVE_GTK2 */
69        ? gdk_pixbuf_new_from_file (filename)
70#endif /* !HAVE_GTK2 */
71        : gdk_pixbuf_new_from_xpm_data ((const char **) xpm_data));
72  if (pb)
73    {
74      int w = gdk_pixbuf_get_width (pb);
75      int h = gdk_pixbuf_get_height (pb);
76      Pixmap pixmap = 0;
77
78      /* #### Note that this always uses the default colormap!  Morons!
79              Owen says that in Gnome 2.0, I should try using
80              gdk_pixbuf_render_pixmap_and_mask_for_colormap() instead.
81              But I don't have Gnome 2.0 yet.
82       */
83      gdk_pixbuf_xlib_render_pixmap_and_mask (pb, &pixmap, mask_ret, 128);
84
85      if (!pixmap)
86        {
87          fprintf (stderr, "%s: out of memory (%d x %d)\n", progname, w, h);
88          exit (-1);
89        }
90      /* gdk_pixbuf_unref (pb);  -- #### does doing this free colors? */
91
92      if (width_ret)  *width_ret  = w;
93      if (height_ret) *height_ret = h;
94
95      return pixmap;
96    }
97  else if (filename)
98    {
99#ifdef HAVE_GTK2
100      fprintf (stderr, "%s: %s\n", progname, gerr->message);
101      g_error_free (gerr);
102#else /* !HAVE_GTK2 */
103      fprintf (stderr, "%s: unable to load %s\n", progname, filename);
104#endif /* !HAVE_GTK2 */
105      exit (-1);
106    }
107  else
108    {
109      fprintf (stderr, "%s: unable to initialize built-in images\n", progname);
110      exit (-1);
111    }
112}
113
114
115#elif defined(HAVE_XPM)
116
117#include <X11/Intrinsic.h>
118#include <X11/Xutil.h>
119#include <X11/xpm.h>
120
121#ifdef HAVE_XMU
122# ifndef VMS
123#  include <X11/Xmu/Drawing.h>
124#else  /* VMS */
125#  include <Xmu/Drawing.h>
126# endif /* VMS */
127#endif
128
129#undef countof
130#define countof(x) (sizeof((x))/sizeof((*x)))
131
132
133static int
134handle_xpm_error (const char *filename, int status)
135{
136  if (!filename) filename = "builtin";
137  switch (status)
138    {
139    case XpmSuccess:
140      return 0;
141      break;
142    case XpmColorError:
143      fprintf (stderr, "%s: %s: warning: color substitution performed\n",
144               progname, filename);
145      return 0;
146      break;
147    case XpmFileInvalid:
148      return 1;
149      break;
150    case XpmOpenFailed:
151      fprintf (stderr, "%s: %s: no such file\n", progname, filename);
152      break;
153    case XpmNoMemory:
154      fprintf (stderr, "%s: %s: out of memory\n", progname, filename);
155      break;
156    case XpmColorFailed:
157      fprintf (stderr, "%s: %s: color allocation failed\n",
158               progname, filename);
159      break;
160    default:
161      fprintf (stderr, "%s: %s: unknown XPM error %d\n", progname,
162               filename, status);
163      break;
164    }
165  exit (-1);
166}
167
168
169/* The libxpm version of this function...
170 */
171static Pixmap
172xpm_to_pixmap_1 (Display *dpy, Window window,
173                 int *width_ret, int *height_ret,
174                 Pixmap *mask_ret,
175                 const char *filename,
176                 char **xpm_data)
177{
178  Pixmap pixmap = 0;
179  XpmAttributes xpmattrs;
180  XpmImage xpm_image;
181  XpmInfo xpm_info;
182  int status;
183  XWindowAttributes xgwa;
184  XGetWindowAttributes (dpy, window, &xgwa);
185
186  memset (&xpm_image, 0, sizeof(xpm_image));
187  memset (&xpm_info, 0, sizeof(xpm_info));
188
189  if (filename)
190    {
191      xpm_data = 0;
192      status = XpmReadFileToData ((char *) filename, &xpm_data);
193      if (handle_xpm_error (filename, status))
194        goto TRY_XBM;
195    }
196
197  xpmattrs.valuemask = 0;
198
199# ifdef XpmCloseness
200  xpmattrs.valuemask |= XpmCloseness;
201  xpmattrs.closeness = 40000;
202# endif
203# ifdef XpmVisual
204  xpmattrs.valuemask |= XpmVisual;
205  xpmattrs.visual = xgwa.visual;
206# endif
207# ifdef XpmDepth
208  xpmattrs.valuemask |= XpmDepth;
209  xpmattrs.depth = xgwa.depth;
210# endif
211# ifdef XpmColormap
212  xpmattrs.valuemask |= XpmColormap;
213  xpmattrs.colormap = xgwa.colormap;
214# endif
215
216  status = XpmCreatePixmapFromData (dpy, window, xpm_data,
217                                    &pixmap, mask_ret, &xpmattrs);
218  if (handle_xpm_error (filename, status))
219    pixmap = 0;
220  else
221    {
222      if (width_ret)  *width_ret  = xpmattrs.width;
223      if (height_ret) *height_ret = xpmattrs.height;
224    }
225
226 TRY_XBM:
227
228#ifdef HAVE_XMU
229  if (! pixmap)
230    {
231      unsigned long fg = BlackPixelOfScreen (xgwa.screen);
232      unsigned long bg = WhitePixelOfScreen (xgwa.screen);
233      int xh, yh;
234      Pixmap b2;
235      pixmap = XmuLocateBitmapFile (xgwa.screen, filename,
236                                    0, 0, width_ret, height_ret, &xh, &yh);
237      if (! pixmap)
238        {
239          fprintf (stderr, "%s: couldn't find XBM %s\n", progname,
240                   filename);
241          exit (-1);
242        }
243      b2 = XmuCreatePixmapFromBitmap (dpy, window, pixmap,
244                                      *width_ret, *height_ret,
245                                      xgwa.depth, fg, bg);
246      XFreePixmap (dpy, pixmap);
247      pixmap = b2;
248
249      if (!pixmap)
250        {
251          fprintf (stderr, "%s: couldn't load XBM %s\n", progname, filename);
252          exit (-1);
253        }
254    }
255#else  /* !XMU */
256    {
257      fprintf (stderr,
258               "%s: your vendor doesn't ship the standard Xmu library.\n",
259               progname);
260      fprintf (stderr, "\tWe can't load XBM files without it.\n");
261      exit (-1);
262    }
263#endif /* !XMU */
264
265  return pixmap;
266}
267
268#else  /* !HAVE_XPM && !HAVE_GDK_PIXBUF */
269
270static Pixmap
271xpm_to_pixmap_1 (Display *dpy, Window window,
272                 int *width_ret, int *height_ret,
273                 Pixmap *mask_ret,
274                 const char *filename,
275                 char **xpm_data)
276{
277  fprintf(stderr, "%s: not compiled with XPM or Pixbuf support.\n", progname);
278  exit (-1);
279}
280
281#endif /* !HAVE_XPM */
282
283
284Pixmap
285xpm_data_to_pixmap (Display *dpy, Window window, char **xpm_data,
286                    int *width_ret, int *height_ret,
287                    Pixmap *mask_ret)
288{
289  return xpm_to_pixmap_1 (dpy, window, width_ret, height_ret, mask_ret,
290                          0, xpm_data);
291}
292
293
294Pixmap
295xpm_file_to_pixmap (Display *dpy, Window window, const char *filename,
296                    int *width_ret, int *height_ret,
297                    Pixmap *mask_ret)
298{
299  return xpm_to_pixmap_1 (dpy, window, width_ret, height_ret, mask_ret,
300                          filename, 0);
301}
Note: See TracBrowser for help on using the repository browser.