3 * Copyright (C) 2003-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "pixbuf-cache.h"
28 /*========================================================*/
30 /*========================================================*/
39 /*========================================================*/
40 /* Private globals. */
41 /*========================================================*/
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);
71 /*****************************************************************************/
72 /* Create a new hash table to keep track of cached pixbufs. */
73 /*****************************************************************************/
75 gl_pixbuf_cache_new (void)
77 GHashTable *pixbuf_cache;
79 gl_debug (DEBUG_PIXBUF_CACHE, "START");
81 pixbuf_cache = g_hash_table_new_full (g_str_hash,
86 gl_debug (DEBUG_PIXBUF_CACHE, "END pixbuf_cache=%p", pixbuf_cache);
92 /*****************************************************************************/
93 /* Free up previously allocated hash table and its contents. */
94 /*****************************************************************************/
96 gl_pixbuf_cache_free (GHashTable *pixbuf_cache)
98 gl_debug (DEBUG_PIXBUF_CACHE, "START");
100 g_hash_table_destroy (pixbuf_cache);
102 gl_debug (DEBUG_PIXBUF_CACHE, "END");
106 /*****************************************************************************/
107 /* Add pixbuf to cache explicitly (not a reference). */
108 /*****************************************************************************/
110 gl_pixbuf_cache_add_pixbuf (GHashTable *pixbuf_cache,
114 CacheRecord *test_record, *record;
116 gl_debug (DEBUG_PIXBUF_CACHE, "START");
118 test_record = g_hash_table_lookup (pixbuf_cache, name);
119 if (test_record != NULL) {
120 /* pixbuf is already in the cache. */
121 gl_debug (DEBUG_PIXBUF_CACHE, "END already in cache");
125 record = g_new0 (CacheRecord, 1);
126 record->key = g_strdup (name);
127 record->references = 0; /* Nobody has referenced it yet. */
128 record->pixbuf = g_object_ref (G_OBJECT (pixbuf));
130 g_hash_table_insert (pixbuf_cache, record->key, record);
132 gl_debug (DEBUG_PIXBUF_CACHE, "END");
136 /*****************************************************************************/
137 /* Get pixbuf. If not in cache, read it and add to cache. */
138 /*****************************************************************************/
140 gl_pixbuf_cache_get_pixbuf (GHashTable *pixbuf_cache,
146 gl_debug (DEBUG_PIXBUF_CACHE, "START pixbuf_cache=%p", pixbuf_cache);
148 record = g_hash_table_lookup (pixbuf_cache, name);
150 if (record != NULL) {
151 record->references++;
152 gl_debug (DEBUG_PIXBUF_CACHE, "references=%d", record->references);
153 gl_debug (DEBUG_PIXBUF_CACHE, "END cached");
154 return record->pixbuf;
158 pixbuf = gdk_pixbuf_new_from_file (name, NULL);
159 if ( pixbuf != NULL) {
160 record = g_new0 (CacheRecord, 1);
161 record->key = g_strdup (name);
162 record->references = 1;
163 record->pixbuf = pixbuf;
165 g_hash_table_insert (pixbuf_cache, record->key, record);
168 gl_debug (DEBUG_PIXBUF_CACHE, "END");
174 /*****************************************************************************/
175 /* Remove pixbuf, but only if no references left. */
176 /*****************************************************************************/
178 gl_pixbuf_cache_remove_pixbuf (GHashTable *pixbuf_cache,
183 if (name == NULL) return;
185 gl_debug (DEBUG_PIXBUF_CACHE, "START");
187 record = g_hash_table_lookup (pixbuf_cache, name);
188 if (record == NULL) {
189 gl_debug (DEBUG_PIXBUF_CACHE, "END not in cache");
193 record->references--;
195 if ( record->references == 0 ) {
196 g_hash_table_remove (pixbuf_cache, name);
199 gl_debug (DEBUG_PIXBUF_CACHE, "END");
203 /*---------------------------------------------------------------------------*/
204 /* PRIVATE. Add a name to a GList while iterating over cache. */
205 /*---------------------------------------------------------------------------*/
207 add_name_to_list (gpointer key,
211 gchar *name = (gchar *)key;
212 GList **name_list = (GList **)user_data;
214 gl_debug (DEBUG_PIXBUF_CACHE, "START");
216 gl_debug (DEBUG_PIXBUF_CACHE, "adding name=%s", name);
218 *name_list = g_list_append (*name_list, g_strdup(name));
220 gl_debug (DEBUG_PIXBUF_CACHE, "END");
224 /*****************************************************************************/
225 /* Return a list of names for all pixbufs in the cache. */
226 /*****************************************************************************/
228 gl_pixbuf_cache_get_name_list (GHashTable *pixbuf_cache)
230 GList *name_list = NULL;
232 gl_debug (DEBUG_PIXBUF_CACHE, "START");
234 g_hash_table_foreach (pixbuf_cache, add_name_to_list, &name_list);
236 gl_debug (DEBUG_PIXBUF_CACHE, "END");
242 /*****************************************************************************/
243 /* Free up a list of pixbuf names. */
244 /*****************************************************************************/
246 gl_pixbuf_cache_free_name_list (GList *name_list)
250 gl_debug (DEBUG_PIXBUF_CACHE, "START");
252 for (p_name = name_list; p_name != NULL; p_name = p_name->next) {
253 g_free (p_name->data);
257 g_list_free (name_list);
259 gl_debug (DEBUG_PIXBUF_CACHE, "END");
266 * Local Variables: -- emacs
268 * c-basic-offset: 8 -- emacs
269 * tab-width: 8 -- emacs
270 * indent-tabs-mode: nil -- emacs