1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * pixbuf-cache.c: GLabels pixbuf cache module
8 * Copyright (C) 2003 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "pixbuf-cache.h"
30 /*========================================================*/
32 /*========================================================*/
40 /*========================================================*/
41 /* Private globals. */
42 /*========================================================*/
44 /*========================================================*/
45 /* Private function prototypes. */
46 /*========================================================*/
48 static void record_destroy (gpointer val);
50 static void add_name_to_list (gpointer key,
55 /*---------------------------------------------------------------------------*/
56 /* PRIVATE. Destroy cache record. */
57 /*---------------------------------------------------------------------------*/
59 record_destroy (gpointer val)
61 CacheRecord *record = (CacheRecord *)val;
63 g_return_if_fail (record);
66 g_object_unref (record->pixbuf);
70 /*****************************************************************************/
71 /* Create a new hash table to keep track of cached pixbufs. */
72 /*****************************************************************************/
74 gl_pixbuf_cache_new (void)
76 GHashTable *pixbuf_cache;
78 gl_debug (DEBUG_PIXBUF_CACHE, "START");
80 pixbuf_cache = g_hash_table_new_full (g_str_hash,
85 gl_debug (DEBUG_PIXBUF_CACHE, "END pixbuf_cache=%p", pixbuf_cache);
90 /*****************************************************************************/
91 /* Free up previously allocated hash table and its contents. */
92 /*****************************************************************************/
94 gl_pixbuf_cache_free (GHashTable *pixbuf_cache)
96 gl_debug (DEBUG_PIXBUF_CACHE, "START");
98 g_hash_table_destroy (pixbuf_cache);
100 gl_debug (DEBUG_PIXBUF_CACHE, "END");
103 /*****************************************************************************/
104 /* Add pixbuf to cache explicitly (not a reference). */
105 /*****************************************************************************/
107 gl_pixbuf_cache_add_pixbuf (GHashTable *pixbuf_cache,
111 CacheRecord *test_record, *record;
113 gl_debug (DEBUG_PIXBUF_CACHE, "START");
115 test_record = g_hash_table_lookup (pixbuf_cache, name);
116 if (test_record != NULL) {
117 /* pixbuf is already in the cache. */
118 gl_debug (DEBUG_PIXBUF_CACHE, "END already in cache");
122 record = g_new0 (CacheRecord, 1);
123 record->key = g_strdup (name);
124 record->references = 0; /* Nobody has referenced it yet. */
125 record->pixbuf = g_object_ref (G_OBJECT (pixbuf));
127 g_hash_table_insert (pixbuf_cache, record->key, record);
129 gl_debug (DEBUG_PIXBUF_CACHE, "END");
132 /*****************************************************************************/
133 /* Get pixbuf. If not in cache, read it and add to cache. */
134 /*****************************************************************************/
136 gl_pixbuf_cache_get_pixbuf (GHashTable *pixbuf_cache,
142 gl_debug (DEBUG_PIXBUF_CACHE, "START pixbuf_cache=%p", pixbuf_cache);
144 record = g_hash_table_lookup (pixbuf_cache, name);
146 if (record != NULL) {
147 record->references++;
148 gl_debug (DEBUG_PIXBUF_CACHE, "references=%d", record->references);
149 gl_debug (DEBUG_PIXBUF_CACHE, "END cached");
150 return record->pixbuf;
154 pixbuf = gdk_pixbuf_new_from_file (name, NULL);
155 if ( pixbuf != NULL) {
156 record = g_new0 (CacheRecord, 1);
157 record->key = g_strdup (name);
158 record->references = 1;
159 record->pixbuf = pixbuf;
161 g_hash_table_insert (pixbuf_cache, record->key, record);
164 gl_debug (DEBUG_PIXBUF_CACHE, "END");
169 /*****************************************************************************/
170 /* Remove pixbuf, but only if no references left. */
171 /*****************************************************************************/
173 gl_pixbuf_cache_remove_pixbuf (GHashTable *pixbuf_cache,
178 if (name == NULL) return;
180 gl_debug (DEBUG_PIXBUF_CACHE, "START");
182 record = g_hash_table_lookup (pixbuf_cache, name);
183 if (record == NULL) {
184 gl_debug (DEBUG_PIXBUF_CACHE, "END not in cache");
188 record->references--;
190 if ( record->references == 0 ) {
191 g_hash_table_remove (pixbuf_cache, name);
194 gl_debug (DEBUG_PIXBUF_CACHE, "END");
197 /*---------------------------------------------------------------------------*/
198 /* PRIVATE. Add a name to a GList while iterating over cache. */
199 /*---------------------------------------------------------------------------*/
201 add_name_to_list (gpointer key,
205 gchar *name = (gchar *)key;
206 GList **name_list = (GList **)user_data;
208 gl_debug (DEBUG_PIXBUF_CACHE, "START");
210 gl_debug (DEBUG_PIXBUF_CACHE, "adding name=%s", name);
212 *name_list = g_list_append (*name_list, g_strdup(name));
214 gl_debug (DEBUG_PIXBUF_CACHE, "END");
217 /*****************************************************************************/
218 /* Return a list of names for all pixbufs in the cache. */
219 /*****************************************************************************/
221 gl_pixbuf_cache_get_name_list (GHashTable *pixbuf_cache)
223 GList *name_list = NULL;
225 gl_debug (DEBUG_PIXBUF_CACHE, "START");
227 g_hash_table_foreach (pixbuf_cache, add_name_to_list, &name_list);
229 gl_debug (DEBUG_PIXBUF_CACHE, "END");
234 /*****************************************************************************/
235 /* Free up a list of pixbuf names. */
236 /*****************************************************************************/
238 gl_pixbuf_cache_free_name_list (GList *name_list)
242 gl_debug (DEBUG_PIXBUF_CACHE, "START");
244 for (p_name = name_list; p_name != NULL; p_name = p_name->next) {
245 g_free (p_name->data);
249 g_list_free (name_list);
251 gl_debug (DEBUG_PIXBUF_CACHE, "END");