r240: Tidied up the pixmap code - now uses ImLib functions if possible.
[rox-filer.git] / ROX-Filer / src / pixmaps.c
blobf16938412ab95d6b2ee1577e5f078509e57b7e89
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* pixmaps.c - code for handling pixmaps */
25 * 2000/04/11 Imlib support added
26 * Christiansen Merel <c.merel@wanadoo.fr>
29 #include "config.h"
30 #define PIXMAPS_C
32 /* Remove pixmaps from the cache when they haven't been accessed for
33 * this period of time (seconds).
36 #define PIXMAP_PURGE_TIME 1200
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <errno.h>
42 #include <gtk/gtk.h>
43 #include <gdk/gdkprivate.h> /* XXX - find another way to do this */
44 #include "collection.h"
45 #ifdef HAVE_IMLIB
46 # include <gdk_imlib.h>
47 #endif
49 #include "fscache.h"
50 #include "support.h"
51 #include "gui_support.h"
52 #include "pixmaps.h"
54 GFSCache *pixmap_cache = NULL;
56 static char * bad_xpm[] = {
57 "12 12 3 1",
58 " c #000000000000",
59 ". c #FFFF00000000",
60 "X c #FFFFFFFFFFFF",
61 " ",
62 " ..XXXXXX.. ",
63 " ...XXXX... ",
64 " X...XX...X ",
65 " XX......XX ",
66 " XXX....XXX ",
67 " XXX....XXX ",
68 " XX......XX ",
69 " X...XX...X ",
70 " ...XXXX... ",
71 " ..XXXXXX.. ",
72 " "};
74 MaskedPixmap *default_pixmap[LAST_DEFAULT_PIXMAP];
76 /* Static prototypes */
78 static MaskedPixmap *load_pixmap(char *name);
79 static void load_default_pixmaps(void);
80 static MaskedPixmap *load(char *pathname, gpointer data);
81 static void ref(MaskedPixmap *mp, gpointer data);
82 static void unref(MaskedPixmap *mp, gpointer data);
83 static int getref(MaskedPixmap *mp);
84 static gint purge(gpointer data);
85 static MaskedPixmap *image_from_file(char *path);
86 static MaskedPixmap *get_bad_image(void);
89 /****************************************************************
90 * EXTERNAL INTERFACE *
91 ****************************************************************/
93 void pixmaps_init(void)
95 #ifdef HAVE_IMLIB
96 gdk_imlib_init();
97 #endif
99 pixmap_cache = g_fscache_new((GFSLoadFunc) load,
100 (GFSRefFunc) ref,
101 (GFSRefFunc) unref,
102 (GFSGetRefFunc) getref,
103 NULL, /* Update func */
104 NULL);
106 gtk_timeout_add(10000, purge, NULL);
108 load_default_pixmaps();
111 /* 'name' is relative to APP_DIR. Always returns with a valid image. */
112 MaskedPixmap *load_pixmap(char *name)
114 MaskedPixmap *retval;
116 retval = image_from_file(make_path(getenv("APP_DIR"), name)->str);
117 if (!retval)
118 retval = get_bad_image();
119 return retval;
122 /* Load all the standard pixmaps */
123 static void load_default_pixmaps(void)
125 default_pixmap[TYPE_ERROR] = load_pixmap("pixmaps/error.xpm");
126 default_pixmap[TYPE_UNKNOWN] = load_pixmap("pixmaps/unknown.xpm");
127 default_pixmap[TYPE_SYMLINK] = load_pixmap("pixmaps/symlink.xpm");
128 default_pixmap[TYPE_FILE] = load_pixmap("pixmaps/file.xpm");
129 default_pixmap[TYPE_DIRECTORY] = load_pixmap("pixmaps/directory.xpm");
130 default_pixmap[TYPE_CHAR_DEVICE] = load_pixmap("pixmaps/char.xpm");
131 default_pixmap[TYPE_BLOCK_DEVICE] = load_pixmap("pixmaps/block.xpm");
132 default_pixmap[TYPE_PIPE] = load_pixmap("pixmaps/pipe.xpm");
133 default_pixmap[TYPE_SOCKET] = load_pixmap("pixmaps/socket.xpm");
135 default_pixmap[TYPE_UNMOUNTED] = load_pixmap("pixmaps/mount.xpm");
136 default_pixmap[TYPE_MOUNTED] = load_pixmap("pixmaps/mounted.xpm");
137 default_pixmap[TYPE_MULTIPLE] = load_pixmap("pixmaps/multiple.xpm");
138 default_pixmap[TYPE_EXEC_FILE] = load_pixmap("pixmaps/exec.xpm");
139 default_pixmap[TYPE_APPDIR] = load_pixmap("pixmaps/application.xpm");
141 default_pixmap[TOOLBAR_UP_ICON] = load_pixmap("pixmaps/up.xpm");
142 default_pixmap[TOOLBAR_HOME_ICON] = load_pixmap("pixmaps/home.xpm");
143 default_pixmap[TOOLBAR_REFRESH_ICON] =
144 load_pixmap("pixmaps/refresh.xpm");
147 void pixmap_ref(MaskedPixmap *mp)
149 ref(mp, pixmap_cache->user_data);
152 void pixmap_unref(MaskedPixmap *mp)
154 unref(mp, pixmap_cache->user_data);
157 /****************************************************************
158 * INTERNAL FUNCTIONS *
159 ****************************************************************/
161 /* Load the image 'path' and return a pointer to the resulting
162 * MaskedPixmap. NULL on failure.
164 static MaskedPixmap *image_from_file(char *path)
166 MaskedPixmap *mp;
167 GdkPixmap *pixmap;
168 GdkBitmap *mask;
169 int width;
170 int height;
171 #ifdef HAVE_IMLIB
172 GdkImlibImage *image;
174 image = gdk_imlib_load_image(path);
175 if (!image)
176 return NULL;
178 if (!gdk_imlib_render(image, image->rgb_width, image->rgb_height))
180 gdk_imlib_kill_image(image);
181 return NULL;
184 pixmap = image->pixmap;
185 mask = image->shape_mask;
186 width = image->width;
187 height = image->height;
188 #else
189 pixmap = gdk_pixmap_colormap_create_from_xpm(NULL,
190 gtk_widget_get_default_colormap(),
191 &mask,
193 path);
195 if (!pixmap)
196 return NULL;
197 width = ((GdkPixmapPrivate *) mp->pixmap)->width;
198 height = ((GdkPixmapPrivate *) mp->pixmap)->height;
199 #endif
201 mp = g_new(MaskedPixmap, 1);
202 mp->ref = 1;
203 #ifdef HAVE_IMLIB
204 mp->image = image;
205 #endif
206 mp->pixmap = pixmap;
207 mp->mask = mask;
208 mp->width = width;
209 mp->height = height;
211 return mp;
214 /* Return a pointer to the (static) bad image. The ref counter will ensure
215 * that the image is never freed.
217 static MaskedPixmap *get_bad_image(void)
219 static MaskedPixmap *image = NULL;
221 if (!image)
223 image = g_new(MaskedPixmap, 1);
224 image->ref = 1;
226 image->pixmap= gdk_pixmap_colormap_create_from_xpm_d(NULL,
227 gtk_widget_get_default_colormap(),
228 &image->mask, NULL, bad_xpm);
229 #ifdef HAVE_IMLIB
230 image->image = NULL;
231 #endif
234 image->ref++;
235 image->width = ((GdkPixmapPrivate *) image->pixmap)->width;
236 image->height = ((GdkPixmapPrivate *) image->pixmap)->height;
238 return image;
241 static MaskedPixmap *load(char *pathname, gpointer user_data)
243 return image_from_file(pathname);
246 static void ref(MaskedPixmap *mp, gpointer data)
248 /* printf("[ ref %p %d->%d ]\n", mp, mp->ref, mp->ref + 1); */
250 if (mp)
251 mp->ref++;
254 static void unref(MaskedPixmap *mp, gpointer data)
256 /* printf("[ unref %p %d->%d ]\n", mp, mp->ref, mp->ref - 1); */
258 if (mp && --mp->ref == 0)
260 #ifdef HAVE_IMLIB
261 if (mp->image)
262 gdk_imlib_destroy_image(mp->image);
263 else
264 #endif
266 gdk_pixmap_unref(mp->pixmap);
267 gdk_bitmap_unref(mp->mask);
269 g_free(mp);
273 static int getref(MaskedPixmap *mp)
275 return mp->ref;
278 /* Called now and then to clear out old pixmaps */
279 static gint purge(gpointer data)
281 g_fscache_purge(pixmap_cache, PIXMAP_PURGE_TIME);
283 return TRUE;