]> git.sur5r.net Git - glabels/blob - src/pixbuf-cache.c
Imported Upstream version 3.0.0
[glabels] / src / pixbuf-cache.c
1 /*
2  *  pixbuf-cache.c
3  *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
23 #include "pixbuf-cache.h"
24
25 #include "debug.h"
26
27
28 /*========================================================*/
29 /* Private types.                                         */
30 /*========================================================*/
31
32 typedef struct {
33         gchar     *key;
34         guint      references;
35         GdkPixbuf *pixbuf;
36 } CacheRecord;
37
38
39 /*========================================================*/
40 /* Private globals.                                       */
41 /*========================================================*/
42
43
44 /*========================================================*/
45 /* Private function prototypes.                           */
46 /*========================================================*/
47
48 static void  record_destroy   (gpointer val);
49
50 static void  add_name_to_list (gpointer key,
51                                gpointer val,
52                                gpointer user_data);
53
54
55 /*---------------------------------------------------------------------------*/
56 /* PRIVATE.  Destroy cache record.                                           */
57 /*---------------------------------------------------------------------------*/
58 static void
59 record_destroy (gpointer val)
60 {
61         CacheRecord *record = (CacheRecord *)val;
62
63         g_return_if_fail (record);
64
65         g_free (record->key);
66         g_object_unref (record->pixbuf);
67         g_free (record);
68 }
69
70
71 /*****************************************************************************/
72 /* Create a new hash table to keep track of cached pixbufs.                  */
73 /*****************************************************************************/
74 GHashTable *
75 gl_pixbuf_cache_new (void)
76 {
77         GHashTable *pixbuf_cache;
78
79         gl_debug (DEBUG_PIXBUF_CACHE, "START");
80
81         pixbuf_cache = g_hash_table_new_full (g_str_hash,
82                                               g_str_equal,
83                                               NULL,
84                                               record_destroy);
85
86         gl_debug (DEBUG_PIXBUF_CACHE, "END pixbuf_cache=%p", pixbuf_cache);
87
88         return pixbuf_cache;
89 }
90
91
92 /*****************************************************************************/
93 /* Free up previously allocated hash table and its contents.                 */
94 /*****************************************************************************/
95 void
96 gl_pixbuf_cache_free (GHashTable *pixbuf_cache)
97 {
98         gl_debug (DEBUG_PIXBUF_CACHE, "START");
99
100         g_hash_table_destroy (pixbuf_cache);
101
102         gl_debug (DEBUG_PIXBUF_CACHE, "END");
103 }
104
105
106 /*****************************************************************************/
107 /* Add pixbuf to cache explicitly (not a reference).                         */
108 /*****************************************************************************/
109 void
110 gl_pixbuf_cache_add_pixbuf (GHashTable *pixbuf_cache,
111                             gchar      *name,
112                             GdkPixbuf  *pixbuf)
113 {
114         CacheRecord *test_record, *record;
115
116         gl_debug (DEBUG_PIXBUF_CACHE, "START");
117
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");
122                 return;
123         }
124
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));
129
130         g_hash_table_insert (pixbuf_cache, record->key, record);
131
132         gl_debug (DEBUG_PIXBUF_CACHE, "END");
133 }
134
135
136 /*****************************************************************************/
137 /* Get pixbuf.  If not in cache, read it and add to cache.                   */
138 /*****************************************************************************/
139 GdkPixbuf *
140 gl_pixbuf_cache_get_pixbuf (GHashTable *pixbuf_cache,
141                             gchar      *name)
142 {
143         CacheRecord *record;
144         GdkPixbuf   *pixbuf;
145
146         gl_debug (DEBUG_PIXBUF_CACHE, "START pixbuf_cache=%p", pixbuf_cache);
147
148         record = g_hash_table_lookup (pixbuf_cache, name);
149
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;
155         }
156
157
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;
164
165                 g_hash_table_insert (pixbuf_cache, record->key, record);
166         }
167
168         gl_debug (DEBUG_PIXBUF_CACHE, "END");
169
170         return pixbuf;
171 }
172
173
174 /*****************************************************************************/
175 /* Remove pixbuf, but only if no references left.                            */
176 /*****************************************************************************/
177 void
178 gl_pixbuf_cache_remove_pixbuf (GHashTable *pixbuf_cache,
179                                gchar      *name)
180 {
181         CacheRecord *record;
182
183         if (name == NULL) return;
184
185         gl_debug (DEBUG_PIXBUF_CACHE, "START");
186
187         record = g_hash_table_lookup (pixbuf_cache, name);
188         if (record == NULL) {
189                 gl_debug (DEBUG_PIXBUF_CACHE, "END not in cache");
190                 return;
191         }
192
193         record->references--;
194
195         if ( record->references == 0 ) {
196                 g_hash_table_remove (pixbuf_cache, name);
197         }
198
199         gl_debug (DEBUG_PIXBUF_CACHE, "END");
200 }
201
202
203 /*---------------------------------------------------------------------------*/
204 /* PRIVATE.  Add a name to a GList while iterating over cache.               */
205 /*---------------------------------------------------------------------------*/
206 static void
207 add_name_to_list (gpointer key,
208                   gpointer val,
209                   gpointer user_data)
210 {
211         gchar     *name       = (gchar *)key;
212         GList     **name_list = (GList **)user_data;
213
214         gl_debug (DEBUG_PIXBUF_CACHE, "START");
215
216         gl_debug (DEBUG_PIXBUF_CACHE, "adding name=%s", name);
217
218         *name_list = g_list_append (*name_list, g_strdup(name));
219
220         gl_debug (DEBUG_PIXBUF_CACHE, "END");
221 }
222
223
224 /*****************************************************************************/
225 /* Return a list of names for all pixbufs in the cache.                      */
226 /*****************************************************************************/
227 GList *
228 gl_pixbuf_cache_get_name_list (GHashTable *pixbuf_cache)
229 {
230         GList *name_list = NULL;
231
232         gl_debug (DEBUG_PIXBUF_CACHE, "START");
233
234         g_hash_table_foreach (pixbuf_cache, add_name_to_list, &name_list);
235
236         gl_debug (DEBUG_PIXBUF_CACHE, "END");
237
238         return name_list;
239 }
240
241
242 /*****************************************************************************/
243 /* Free up a list of pixbuf names.                                           */
244 /*****************************************************************************/
245 void
246 gl_pixbuf_cache_free_name_list (GList *name_list)
247 {
248         GList *p_name;
249
250         gl_debug (DEBUG_PIXBUF_CACHE, "START");
251
252         for (p_name = name_list; p_name != NULL; p_name = p_name->next) {
253                 g_free (p_name->data);
254                 p_name->data = NULL;
255         }
256
257         g_list_free (name_list);
258
259         gl_debug (DEBUG_PIXBUF_CACHE, "END");
260 }
261
262
263
264
265 /*
266  * Local Variables:       -- emacs
267  * mode: C                -- emacs
268  * c-basic-offset: 8      -- emacs
269  * tab-width: 8           -- emacs
270  * indent-tabs-mode: nil  -- emacs
271  * End:                   -- emacs
272  */