Revert "transmission: update from 2.13 to 2.22"
[tomato.git] / release / src / router / transmission / gtk / icons.c
blob453ee7cb4936311c439269d1e5ed678c560926fa
1 /*
2 * icons.[ch] written by Paolo Bacchilega, who writes:
3 * "There is no problem for me, you can license my code under whatever licence you wish :)"
5 * $Id: icons.c 11284 2010-10-01 20:22:51Z charles $
6 */
8 #include <string.h> /* strcmp */
9 #include <glib.h>
10 #include <gtk/gtk.h>
11 #include "icons.h"
13 #ifdef HAVE_GIO
14 #if GTK_CHECK_VERSION( 2, 12, 0 )
15 #define USE_GIO_ICONS
16 #endif
17 #endif
19 #ifdef USE_GIO_ICONS
20 #include <gio/gio.h>
21 #endif
23 #define VOID_PIXBUF_KEY "void-pixbuf"
25 #ifdef USE_GIO_ICONS
26 static const char *
27 get_static_string( const char *s )
29 static GStringChunk * static_strings = NULL;
31 if( s == NULL )
32 return NULL;
34 if( static_strings == NULL )
35 static_strings = g_string_chunk_new( 1024 );
37 return g_string_chunk_insert_const( static_strings, s );
39 #endif
42 typedef struct {
43 GtkIconTheme * icon_theme;
44 int icon_size;
45 GHashTable * cache;
46 } IconCache;
49 static IconCache *icon_cache[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
52 static GdkPixbuf*
53 create_void_pixbuf (int width,
54 int height)
56 GdkPixbuf *p;
58 p = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
59 TRUE,
61 width,
62 height);
63 gdk_pixbuf_fill( p, 0xFFFFFF00 );
65 return p;
69 static int
70 get_size_in_pixels( GtkWidget * widget,
71 GtkIconSize icon_size )
73 int width, height;
75 gtk_icon_size_lookup_for_settings( gtk_widget_get_settings( widget ),
76 icon_size,
77 &width,
78 &height );
79 return MAX( width, height );
83 static IconCache *
84 icon_cache_new (GtkWidget * for_widget, int icon_size)
86 IconCache * icon_cache;
88 g_return_val_if_fail( for_widget != NULL, NULL );
90 icon_cache = g_new0( IconCache, 1 );
91 icon_cache->icon_theme = gtk_icon_theme_get_for_screen( gtk_widget_get_screen( for_widget ));
92 icon_cache->icon_size = get_size_in_pixels( for_widget, icon_size );
93 icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
95 g_hash_table_insert( icon_cache->cache, (void*)VOID_PIXBUF_KEY, create_void_pixbuf( icon_cache->icon_size, icon_cache->icon_size ));
97 return icon_cache;
100 #ifdef USE_GIO_ICONS
101 static const char *
102 _icon_cache_get_icon_key( GIcon * icon )
104 const char * key = NULL;
106 if ( G_IS_THEMED_ICON( icon )) {
107 char ** icon_names;
108 char * name;
110 g_object_get( icon, "names", &icon_names, NULL );
111 name = g_strjoinv( ",", icon_names );
113 key = get_static_string( name );
115 g_free( name );
116 g_strfreev( icon_names );
118 else if ( G_IS_FILE_ICON( icon )) {
119 GFile * file;
120 char * filename;
122 file = g_file_icon_get_file( G_FILE_ICON( icon ));
123 filename = g_file_get_path( file );
125 key = get_static_string( filename );
127 g_free( filename );
128 g_object_unref( file );
131 return key;
135 static GdkPixbuf *
136 get_themed_icon_pixbuf( GThemedIcon * icon,
137 int size,
138 GtkIconTheme * icon_theme )
140 char ** icon_names = NULL;
141 GtkIconInfo * icon_info;
142 GdkPixbuf * pixbuf;
143 GError * error = NULL;
145 g_object_get( icon, "names", &icon_names, NULL );
147 icon_info = gtk_icon_theme_choose_icon( icon_theme, (const char **)icon_names, size, 0 );
148 if ( icon_info == NULL )
149 icon_info = gtk_icon_theme_lookup_icon( icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN );
151 pixbuf = gtk_icon_info_load_icon( icon_info, &error );
152 if ( pixbuf == NULL ) {
153 if( error && error->message )
154 g_warning( "could not load icon pixbuf: %s\n", error->message );
155 g_clear_error( &error );
158 gtk_icon_info_free( icon_info );
159 g_strfreev( icon_names );
161 return pixbuf;
165 static GdkPixbuf *
166 get_file_icon_pixbuf( GFileIcon * icon, int size )
168 GFile * file;
169 char * filename;
170 GdkPixbuf * pixbuf;
172 file = g_file_icon_get_file( icon );
173 filename = g_file_get_path( file );
174 pixbuf = gdk_pixbuf_new_from_file_at_size( filename, size, -1, NULL );
175 g_free( filename );
176 g_object_unref( file );
178 return pixbuf;
182 static GdkPixbuf *
183 _get_icon_pixbuf( GIcon * icon, int size, GtkIconTheme * theme )
185 if ( icon == NULL )
186 return NULL;
187 if ( G_IS_THEMED_ICON (icon) )
188 return get_themed_icon_pixbuf( G_THEMED_ICON( icon ), size, theme );
189 if ( G_IS_FILE_ICON (icon) )
190 return get_file_icon_pixbuf( G_FILE_ICON( icon ), size );
191 return NULL;
195 static GdkPixbuf *
196 icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
198 GIcon * icon;
199 const char * key = NULL;
200 GdkPixbuf * pixbuf;
202 icon = g_content_type_get_icon( mime_type );
203 key = _icon_cache_get_icon_key( icon );
205 if (key == NULL)
206 key = VOID_PIXBUF_KEY;
208 pixbuf = g_hash_table_lookup( icon_cache->cache, key );
209 if (pixbuf != NULL) {
210 g_object_ref( pixbuf );
211 g_object_unref( G_OBJECT( icon ) );
212 return pixbuf;
215 pixbuf = _get_icon_pixbuf( icon, icon_cache->icon_size, icon_cache->icon_theme );
216 if( pixbuf != NULL )
217 g_hash_table_insert( icon_cache->cache, (gpointer) key, g_object_ref( pixbuf ) );
219 g_object_unref( G_OBJECT( icon ) );
221 return pixbuf;
224 #else /* USE_GIO_ICONS */
226 static GdkPixbuf *
227 icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
229 GdkPixbuf * pixbuf;
230 const char * stock_name;
232 if( !strcmp( mime_type, UNKNOWN_MIME_TYPE ) )
233 stock_name = GTK_STOCK_MISSING_IMAGE;
234 else if( !strcmp( mime_type, DIRECTORY_MIME_TYPE ) )
235 stock_name = GTK_STOCK_DIRECTORY;
236 else
237 stock_name = GTK_STOCK_FILE;
239 pixbuf = g_hash_table_lookup( icon_cache->cache, stock_name );
241 if( pixbuf != NULL )
243 g_object_ref( pixbuf );
244 return pixbuf;
247 pixbuf = gtk_icon_theme_load_icon( icon_cache->icon_theme,
248 stock_name,
249 icon_cache->icon_size,
250 0, NULL );
251 g_hash_table_insert( icon_cache->cache, (gpointer) stock_name, g_object_ref( pixbuf ));
252 return pixbuf;
255 #endif
258 GdkPixbuf *
259 get_mime_type_icon( const char * mime_type,
260 GtkIconSize icon_size,
261 GtkWidget * for_widget )
263 int n;
265 switch ( icon_size ) {
266 case GTK_ICON_SIZE_MENU: n = 1; break;
267 case GTK_ICON_SIZE_SMALL_TOOLBAR: n = 2; break;
268 case GTK_ICON_SIZE_LARGE_TOOLBAR: n = 3; break;
269 case GTK_ICON_SIZE_BUTTON: n = 4; break;
270 case GTK_ICON_SIZE_DND: n = 5; break;
271 case GTK_ICON_SIZE_DIALOG: n = 6; break;
272 default /*GTK_ICON_SIZE_INVALID*/: n = 0; break;
275 if( icon_cache[n] == NULL )
276 icon_cache[n] = icon_cache_new( for_widget, icon_size );
278 return icon_cache_get_mime_type_icon( icon_cache[n], mime_type );
282 const char *
283 get_mime_type_from_filename( const char * file G_GNUC_UNUSED )
285 #ifdef USE_GIO_ICONS
286 char * tmp = g_content_type_guess( file, NULL, 0, NULL );
287 const char * ret = get_static_string( tmp );
288 g_free( tmp );
289 return ret;
290 #else
291 return "uncertain";
292 #endif