Lots of cleanups to fvwm-menu-desktop
[fvwm.git] / libs / Picture.c
blobb7e1134379ca90dbbb45c2303471e787f4d5a4f8
1 /* -*-c-*- */
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This module is all original code
19 * by Rob Nation
20 * Copyright 1993, Robert Nation
21 * You may use this code for any purpose, as long as the original
22 * copyright remains in the source code and all documentation
25 Changed 02/12/97 by Dan Espen:
26 - added routines to determine color closeness, for color use reduction.
27 Some of the logic comes from pixy2, so the copyright is below.
30 * Copyright 1996, Romano Giannetti. No guarantees or warantees or anything
31 * are provided or implied in any way whatsoever. Use this program at your
32 * own risk. Permission to use this program for any purpose is given,
33 * as long as the copyright is kept intact.
35 * Romano Giannetti - Dipartimento di Ingegneria dell'Informazione
36 * via Diotisalvi, 2 PISA
37 * mailto:romano@iet.unipi.it
38 * http://www.iet.unipi.it/~romano
44 * Routines to handle initialization, loading, and removing of xpm's or mono-
45 * icon images.
49 #include "config.h"
51 #include <stdio.h>
52 #include <signal.h>
53 #include <ctype.h>
55 #include "ftime.h"
57 #include <X11/Xlib.h>
58 #include <X11/Xutil.h>
59 #include <X11/Intrinsic.h>
61 #include "fvwmlib.h"
62 #include "System.h"
63 #include "Colorset.h"
64 #include "Picture.h"
65 #include "PictureUtils.h"
66 #include "Fsvg.h"
68 static FvwmPicture *FvwmPictureList=NULL;
70 FvwmPicture *PGetFvwmPicture(
71 Display *dpy, Window win, char *ImagePath, const char *name,
72 FvwmPictureAttributes fpa)
74 char *path = PictureFindImageFile(name, ImagePath, R_OK);
75 FvwmPicture *p;
77 if (path == NULL)
79 return NULL;
81 p = PImageLoadFvwmPictureFromFile(dpy, win, path, fpa);
82 if (p == NULL)
84 free(path);
87 return p;
90 void PFreeFvwmPictureData(FvwmPicture *p)
92 if (!p)
94 return;
96 if (p->alloc_pixels != NULL)
98 free(p->alloc_pixels);
100 if(p->name!=NULL)
102 free(p->name);
104 free(p);
106 return;
109 FvwmPicture *PCacheFvwmPicture(
110 Display *dpy, Window win, char *ImagePath, const char *name,
111 FvwmPictureAttributes fpa)
113 char *path;
114 char *real_path;
115 FvwmPicture *p = FvwmPictureList;
117 /* First find the full pathname */
118 if ((path = PictureFindImageFile(name, ImagePath, R_OK)) == NULL)
120 return NULL;
122 /* Remove any svg rendering options from real_path */
123 if (USE_SVG && *path == ':' &&
124 (real_path = strchr(path + 1, ':')))
126 real_path++;
128 else
130 real_path = path;
133 /* See if the picture is already cached */
134 while (p)
136 register char *p1, *p2;
138 for (p1 = path, p2 = p->name; *p1 && *p2; ++p1, ++p2)
140 if (*p1 != *p2)
142 break;
146 /* If we have found a picture with the wanted name and stamp */
147 if (!*p1 && !*p2 && !isFileStampChanged(&p->stamp, real_path)
148 && PICTURE_FPA_AGREE(p,fpa))
150 p->count++; /* Put another weight on the picture */
151 free(path);
152 return p;
154 p=p->next;
157 /* Not previously cached, have to load it ourself. Put it first in list
159 p = PImageLoadFvwmPictureFromFile(dpy, win, path, fpa);
160 if(p)
162 p->next=FvwmPictureList;
163 FvwmPictureList=p;
165 else
167 free(path);
170 return p;
173 void PDestroyFvwmPicture(Display *dpy, FvwmPicture *p)
175 FvwmPicture *q = FvwmPictureList;
177 if (!p)
179 return;
181 /* Remove a weight */
182 if(--(p->count)>0)
184 /* still too heavy? */
185 return;
188 /* Let it fly */
189 if (p->alloc_pixels != NULL)
191 if (p->nalloc_pixels != 0)
193 PictureFreeColors(
194 dpy, Pcmap, p->alloc_pixels, p->nalloc_pixels,
195 0, p->no_limit);
197 free(p->alloc_pixels);
199 if(p->name!=NULL)
201 free(p->name);
203 if(p->picture!=None)
205 XFreePixmap(dpy,p->picture);
207 if(p->mask!=None)
209 XFreePixmap(dpy,p->mask);
211 if(p->alpha != None)
213 XFreePixmap(dpy, p->alpha);
215 /* Link it out of the list (it might not be there) */
216 if(p==q) /* in head? simple */
218 FvwmPictureList = p->next;
220 else
222 while(q && q->next!=p) /* fast forward until end or found */
224 q = q->next;
226 if(q) /* not end? means we found it in there, possibly at end */
228 q->next = p->next; /* link around it */
231 free(p);
233 return;
236 FvwmPicture *PLoadFvwmPictureFromPixmap(
237 Display *dpy, Window win, char *name, Pixmap pixmap,
238 Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels,
239 Pixel *alloc_pixels, int no_limit)
241 FvwmPicture *q;
243 q = (FvwmPicture*)safemalloc(sizeof(FvwmPicture));
244 memset(q, 0, sizeof(FvwmPicture));
245 q->count = 1;
246 q->name = name;
247 q->next = NULL;
248 q->stamp = pixmap;
249 q->picture = pixmap;
250 q->mask = mask;
251 q->alpha = alpha;
252 q->width = width;
253 q->height = height;
254 q->depth = Pdepth;
255 q->nalloc_pixels = nalloc_pixels;
256 q->alloc_pixels = alloc_pixels;
257 q->no_limit = no_limit;
258 return q;
261 FvwmPicture *PCacheFvwmPictureFromPixmap(
262 Display *dpy, Window win, char *name, Pixmap pixmap,
263 Pixmap mask, Pixmap alpha, int width, int height, int nalloc_pixels,
264 Pixel *alloc_pixels, int no_limit)
266 FvwmPicture *p = FvwmPictureList;
268 /* See if the picture is already cached */
269 for(; p != NULL; p = p->next)
271 #if 0
272 /* at th present time no good way to cache a pixmap */
273 if (!strcmp(p->name,name))
275 p->count++;
276 return p;
278 #endif
281 /* Not previously cached, have to load. Put it first in list */
282 p = PLoadFvwmPictureFromPixmap(
283 dpy, win, name, pixmap, mask, alpha, width, height,
284 nalloc_pixels, alloc_pixels, no_limit);
285 if(p)
287 p->next = FvwmPictureList;
288 FvwmPictureList = p;
291 return p;
294 FvwmPicture *PCloneFvwmPicture(FvwmPicture *pic)
296 if (pic != NULL)
298 pic->count++;
301 return pic;
304 void PicturePrintImageCache(int verbose)
306 FvwmPicture *p;
307 unsigned int count = 0;
308 unsigned int hits = 0;
309 unsigned int num_alpha = 0;
310 unsigned int num_mask = 0;
312 fflush(stderr);
313 fflush(stdout);
314 fprintf(stderr, "fvwm info on Image cache:\n");
316 for (p = FvwmPictureList; p != NULL; p = p->next)
318 int num_pixmaps = 1;
319 if (p->mask != None)
321 num_mask++;
322 num_pixmaps++;
324 if (p->alpha != None)
326 num_alpha++;
327 num_pixmaps++;
329 if (verbose > 0)
331 fprintf(stderr,
332 "Image: %s (%d pixmaps; used %d times)\n",
333 p->name, num_pixmaps, p->count);
335 count++;
336 hits += p->count-1;
339 fprintf(stderr, "%u images in cache (%d reuses) "
340 "(%u masks, %u alpha channels => %u pixmaps)\n",
341 count, hits, num_mask, num_alpha, count + num_mask + num_alpha);
342 fflush(stderr);