4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2001, the ROX-Filer team.
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)
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
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 */
27 /* Remove pixmaps from the cache when they haven't been accessed for
28 * this period of time (seconds).
31 #define PIXMAP_PURGE_TIME 1200
38 #include <gdk-pixbuf/gdk-pixbuf.h>
39 #include "collection.h"
45 #include "gui_support.h"
49 GFSCache
*pixmap_cache
= NULL
;
51 static char * bad_xpm
[] = {
69 MaskedPixmap
*im_error
;
70 MaskedPixmap
*im_unknown
;
71 MaskedPixmap
*im_symlink
;
73 MaskedPixmap
*im_unmounted
;
74 MaskedPixmap
*im_mounted
;
75 MaskedPixmap
*im_multiple
;
76 MaskedPixmap
*im_exec_file
;
77 MaskedPixmap
*im_appdir
;
79 MaskedPixmap
*im_help
;
81 /* Static prototypes */
83 static void load_default_pixmaps(void);
84 static MaskedPixmap
*load(char *pathname
, gpointer data
);
85 static void ref(MaskedPixmap
*mp
, gpointer data
);
86 static void unref(MaskedPixmap
*mp
, gpointer data
);
87 static int getref(MaskedPixmap
*mp
);
88 static gint
purge(gpointer data
);
89 static MaskedPixmap
*image_from_file(char *path
);
90 static MaskedPixmap
*get_bad_image(void);
91 static MaskedPixmap
*image_from_pixbuf(GdkPixbuf
*pixbuf
);
92 static GdkPixbuf
*scale_pixbuf(GdkPixbuf
*src
, int max_w
, int max_h
);
95 /****************************************************************
96 * EXTERNAL INTERFACE *
97 ****************************************************************/
99 void pixmaps_init(void)
102 gtk_widget_push_visual(gdk_rgb_get_visual());
103 gtk_widget_push_colormap(gdk_rgb_get_cmap());
105 pixmap_cache
= g_fscache_new((GFSLoadFunc
) load
,
108 (GFSGetRefFunc
) getref
,
109 NULL
, /* Update func */
112 gtk_timeout_add(10000, purge
, NULL
);
114 load_default_pixmaps();
117 /* 'name' is relative to app_dir. Always returns with a valid image. */
118 MaskedPixmap
*load_pixmap(char *name
)
120 MaskedPixmap
*retval
;
122 retval
= image_from_file(make_path(app_dir
, name
)->str
);
124 retval
= get_bad_image();
128 /* Load all the standard pixmaps */
129 static void load_default_pixmaps(void)
131 im_error
= load_pixmap("pixmaps/error.xpm");
132 im_unknown
= load_pixmap("pixmaps/unknown.xpm");
133 im_symlink
= load_pixmap("pixmaps/symlink.xpm");
135 im_unmounted
= load_pixmap("pixmaps/mount.xpm");
136 im_mounted
= load_pixmap("pixmaps/mounted.xpm");
137 im_multiple
= load_pixmap("pixmaps/multiple.xpm");
138 im_exec_file
= load_pixmap("pixmaps/exec.xpm");
139 im_appdir
= load_pixmap("pixmaps/application.xpm");
141 im_help
= load_pixmap("pixmaps/help.xpm");
144 void pixmap_ref(MaskedPixmap
*mp
)
149 void pixmap_unref(MaskedPixmap
*mp
)
154 void pixmap_make_huge(MaskedPixmap
*mp
)
161 gdk_pixbuf_render_pixmap_and_mask(mp
->huge_pixbuf
,
170 gdk_pixmap_ref(mp
->pixmap
);
172 gdk_bitmap_ref(mp
->mask
);
173 mp
->huge_pixmap
= mp
->pixmap
;
174 mp
->huge_mask
= mp
->mask
;
177 void pixmap_make_small(MaskedPixmap
*mp
)
186 sm
= scale_pixbuf(mp
->huge_pixbuf
, SMALL_WIDTH
, SMALL_HEIGHT
);
190 gdk_pixbuf_render_pixmap_and_mask(sm
,
194 gdk_pixbuf_unref(sm
);
201 gdk_pixmap_ref(mp
->pixmap
);
203 gdk_bitmap_ref(mp
->mask
);
204 mp
->sm_pixmap
= mp
->pixmap
;
205 mp
->sm_mask
= mp
->mask
;
208 /****************************************************************
209 * INTERNAL FUNCTIONS *
210 ****************************************************************/
212 /* Load the image 'path' and return a pointer to the resulting
213 * MaskedPixmap. NULL on failure.
215 static MaskedPixmap
*image_from_file(char *path
)
220 pixbuf
= gdk_pixbuf_new_from_file(path
);
224 image
= image_from_pixbuf(pixbuf
);
225 gdk_pixbuf_unref(pixbuf
);
230 /* Scale src down to fit in max_w, max_h and return the new pixbuf.
231 * If src is small enough, then ref it and return that.
233 static GdkPixbuf
*scale_pixbuf(GdkPixbuf
*src
, int max_w
, int max_h
)
237 w
= gdk_pixbuf_get_width(src
);
238 h
= gdk_pixbuf_get_height(src
);
240 if (w
<= max_w
&& h
<= max_h
)
247 float scale_x
= ((float) w
) / max_w
;
248 float scale_y
= ((float) h
) / max_h
;
249 float scale
= MAX(scale_x
, scale_y
);
251 return gdk_pixbuf_scale_simple(src
,
254 GDK_INTERP_BILINEAR
);
258 /* Turn a full-size pixbuf into a MaskedPixmap */
259 static MaskedPixmap
*image_from_pixbuf(GdkPixbuf
*full_size
)
262 GdkPixbuf
*huge_pixbuf
, *normal_pixbuf
;
266 g_return_val_if_fail(full_size
!= NULL
, NULL
);
268 huge_pixbuf
= scale_pixbuf(full_size
, HUGE_WIDTH
, HUGE_HEIGHT
);
269 g_return_val_if_fail(huge_pixbuf
!= NULL
, NULL
);
270 normal_pixbuf
= scale_pixbuf(huge_pixbuf
, ICON_WIDTH
, ICON_HEIGHT
);
271 g_return_val_if_fail(normal_pixbuf
!= NULL
, NULL
);
273 gdk_pixbuf_render_pixmap_and_mask(normal_pixbuf
, &pixmap
, &mask
, 128);
274 gdk_pixbuf_unref(normal_pixbuf
);
278 gdk_pixbuf_unref(huge_pixbuf
);
282 mp
= g_new(MaskedPixmap
, 1);
286 mp
->huge_pixbuf
= huge_pixbuf
;
288 mp
->huge_pixmap
= NULL
;
289 mp
->huge_mask
= NULL
;
291 mp
->sm_pixmap
= NULL
;
297 /* Return a pointer to the (static) bad image. The ref counter will ensure
298 * that the image is never freed.
300 static MaskedPixmap
*get_bad_image(void)
302 static MaskedPixmap
*image
= NULL
;
306 image
= g_new(MaskedPixmap
, 1);
309 image
->pixmap
= gdk_pixmap_colormap_create_from_xpm_d(NULL
,
310 gtk_widget_get_default_colormap(),
311 &image
->mask
, NULL
, bad_xpm
);
312 image
->huge_pixbuf
= NULL
;
314 image
->huge_pixmap
= NULL
;
315 image
->huge_mask
= NULL
;
316 image
->sm_pixmap
= NULL
;
317 image
->sm_mask
= NULL
;
325 static MaskedPixmap
*load(char *pathname
, gpointer user_data
)
327 MaskedPixmap
*retval
;
329 retval
= image_from_file(pathname
);
331 return retval
? retval
: get_bad_image();
334 static void ref(MaskedPixmap
*mp
, gpointer data
)
336 /* printf("[ ref %p %d->%d ]\n", mp, mp->ref, mp->ref + 1); */
342 static void unref(MaskedPixmap
*mp
, gpointer data
)
344 /* printf("[ unref %p %d->%d ]\n", mp, mp->ref, mp->ref - 1); */
346 if (mp
&& --mp
->ref
== 0)
350 gdk_pixbuf_unref(mp
->huge_pixbuf
);
354 gdk_pixmap_unref(mp
->huge_pixmap
);
356 gdk_bitmap_unref(mp
->huge_mask
);
359 gdk_pixmap_unref(mp
->pixmap
);
361 gdk_bitmap_unref(mp
->mask
);
364 gdk_pixmap_unref(mp
->sm_pixmap
);
366 gdk_bitmap_unref(mp
->sm_mask
);
372 static int getref(MaskedPixmap
*mp
)
374 return mp
? mp
->ref
: 0;
377 /* Called now and then to clear out old pixmaps */
378 static gint
purge(gpointer data
)
380 g_fscache_purge(pixmap_cache
, PIXMAP_PURGE_TIME
);