transmission: update from 2.13 to 2.22
[tomato.git] / release / src / router / transmission / gtk / icons.c
bloba3332ac1aea8317034519d362f1eebd7a6d8ff91
1 /*
2 * icons.[ch] written by Paolo Bacchilega, who writes:
3 * "There is no problem for me, you can license my code
4 * under whatever licence you wish :)"
6 * $Id: icons.c 11709 2011-01-19 13:48:47Z jordan $
7 */
9 #include <string.h> /* strcmp */
10 #include <glib.h>
11 #include <gtk/gtk.h>
12 #include "icons.h"
14 #ifdef HAVE_GIO
15 #if GTK_CHECK_VERSION( 2, 12, 0 )
16 #define USE_GIO_ICONS
17 #endif
18 #endif
20 #ifdef USE_GIO_ICONS
21 #include <gio/gio.h>
22 #endif
24 #define VOID_PIXBUF_KEY "void-pixbuf"
26 #ifdef USE_GIO_ICONS
27 static const char *
28 get_static_string( const char *s )
30 static GStringChunk * static_strings = NULL;
32 if( s == NULL )
33 return NULL;
35 if( static_strings == NULL )
36 static_strings = g_string_chunk_new( 1024 );
38 return g_string_chunk_insert_const( static_strings, s );
40 #endif
43 typedef struct {
44 GtkIconTheme * icon_theme;
45 int icon_size;
46 GHashTable * cache;
47 } IconCache;
50 static IconCache *icon_cache[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
53 static GdkPixbuf*
54 create_void_pixbuf (int width,
55 int height)
57 GdkPixbuf *p;
59 p = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
60 TRUE,
62 width,
63 height);
64 gdk_pixbuf_fill( p, 0xFFFFFF00 );
66 return p;
70 static int
71 get_size_in_pixels( GtkWidget * widget,
72 GtkIconSize icon_size )
74 int width, height;
76 gtk_icon_size_lookup_for_settings( gtk_widget_get_settings( widget ),
77 icon_size,
78 &width,
79 &height );
80 return MAX( width, height );
84 static IconCache *
85 icon_cache_new (GtkWidget * for_widget, int icon_size)
87 IconCache * icon_cache;
89 g_return_val_if_fail( for_widget != NULL, NULL );
91 icon_cache = g_new0( IconCache, 1 );
92 icon_cache->icon_theme = gtk_icon_theme_get_for_screen( gtk_widget_get_screen( for_widget ));
93 icon_cache->icon_size = get_size_in_pixels( for_widget, icon_size );
94 icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
96 g_hash_table_insert( icon_cache->cache, (void*)VOID_PIXBUF_KEY, create_void_pixbuf( icon_cache->icon_size, icon_cache->icon_size ));
98 return icon_cache;
101 #ifdef USE_GIO_ICONS
102 static const char *
103 _icon_cache_get_icon_key( GIcon * icon )
105 const char * key = NULL;
107 if ( G_IS_THEMED_ICON( icon )) {
108 char ** icon_names;
109 char * name;
111 g_object_get( icon, "names", &icon_names, NULL );
112 name = g_strjoinv( ",", icon_names );
114 key = get_static_string( name );
116 g_free( name );
117 g_strfreev( icon_names );
119 else if ( G_IS_FILE_ICON( icon )) {
120 GFile * file;
121 char * filename;
123 file = g_file_icon_get_file( G_FILE_ICON( icon ));
124 filename = g_file_get_path( file );
126 key = get_static_string( filename );
128 g_free( filename );
129 g_object_unref( file );
132 return key;
136 static GdkPixbuf *
137 get_themed_icon_pixbuf( GThemedIcon * icon,
138 int size,
139 GtkIconTheme * icon_theme )
141 char ** icon_names = NULL;
142 GtkIconInfo * icon_info;
143 GdkPixbuf * pixbuf;
144 GError * error = NULL;
146 g_object_get( icon, "names", &icon_names, NULL );
148 icon_info = gtk_icon_theme_choose_icon( icon_theme, (const char **)icon_names, size, 0 );
149 if ( icon_info == NULL )
150 icon_info = gtk_icon_theme_lookup_icon( icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN );
152 pixbuf = gtk_icon_info_load_icon( icon_info, &error );
153 if ( pixbuf == NULL ) {
154 if( error && error->message )
155 g_warning( "could not load icon pixbuf: %s\n", error->message );
156 g_clear_error( &error );
159 gtk_icon_info_free( icon_info );
160 g_strfreev( icon_names );
162 return pixbuf;
166 static GdkPixbuf *
167 get_file_icon_pixbuf( GFileIcon * icon, int size )
169 GFile * file;
170 char * filename;
171 GdkPixbuf * pixbuf;
173 file = g_file_icon_get_file( icon );
174 filename = g_file_get_path( file );
175 pixbuf = gdk_pixbuf_new_from_file_at_size( filename, size, -1, NULL );
176 g_free( filename );
177 g_object_unref( file );
179 return pixbuf;
183 static GdkPixbuf *
184 _get_icon_pixbuf( GIcon * icon, int size, GtkIconTheme * theme )
186 if ( icon == NULL )
187 return NULL;
188 if ( G_IS_THEMED_ICON (icon) )
189 return get_themed_icon_pixbuf( G_THEMED_ICON( icon ), size, theme );
190 if ( G_IS_FILE_ICON (icon) )
191 return get_file_icon_pixbuf( G_FILE_ICON( icon ), size );
192 return NULL;
196 static GdkPixbuf *
197 icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
199 GIcon * icon;
200 const char * key = NULL;
201 GdkPixbuf * pixbuf;
203 icon = g_content_type_get_icon( mime_type );
204 key = _icon_cache_get_icon_key( icon );
206 if (key == NULL)
207 key = VOID_PIXBUF_KEY;
209 pixbuf = g_hash_table_lookup( icon_cache->cache, key );
210 if (pixbuf != NULL) {
211 g_object_ref( pixbuf );
212 g_object_unref( G_OBJECT( icon ) );
213 return pixbuf;
216 pixbuf = _get_icon_pixbuf( icon, icon_cache->icon_size, icon_cache->icon_theme );
217 if( pixbuf != NULL )
218 g_hash_table_insert( icon_cache->cache, (gpointer) key, g_object_ref( pixbuf ) );
220 g_object_unref( G_OBJECT( icon ) );
222 return pixbuf;
225 #else /* USE_GIO_ICONS */
227 static GdkPixbuf *
228 icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
230 GdkPixbuf * pixbuf;
231 const char * stock_name;
233 if( !strcmp( mime_type, UNKNOWN_MIME_TYPE ) )
234 stock_name = GTK_STOCK_MISSING_IMAGE;
235 else if( !strcmp( mime_type, DIRECTORY_MIME_TYPE ) )
236 stock_name = GTK_STOCK_DIRECTORY;
237 else
238 stock_name = GTK_STOCK_FILE;
240 pixbuf = g_hash_table_lookup( icon_cache->cache, stock_name );
242 if( pixbuf != NULL )
244 g_object_ref( pixbuf );
245 return pixbuf;
248 pixbuf = gtk_icon_theme_load_icon( icon_cache->icon_theme,
249 stock_name,
250 icon_cache->icon_size,
251 0, NULL );
252 g_hash_table_insert( icon_cache->cache, (gpointer) stock_name, g_object_ref( pixbuf ));
253 return pixbuf;
256 #endif
259 GdkPixbuf *
260 gtr_get_mime_type_icon( const char * mime_type,
261 GtkIconSize icon_size,
262 GtkWidget * for_widget )
264 int n;
266 switch ( icon_size ) {
267 case GTK_ICON_SIZE_MENU: n = 1; break;
268 case GTK_ICON_SIZE_SMALL_TOOLBAR: n = 2; break;
269 case GTK_ICON_SIZE_LARGE_TOOLBAR: n = 3; break;
270 case GTK_ICON_SIZE_BUTTON: n = 4; break;
271 case GTK_ICON_SIZE_DND: n = 5; break;
272 case GTK_ICON_SIZE_DIALOG: n = 6; break;
273 default /*GTK_ICON_SIZE_INVALID*/: n = 0; break;
276 if( icon_cache[n] == NULL )
277 icon_cache[n] = icon_cache_new( for_widget, icon_size );
279 return icon_cache_get_mime_type_icon( icon_cache[n], mime_type );
283 const char *
284 gtr_get_mime_type_from_filename( const char * file G_GNUC_UNUSED )
286 #ifdef USE_GIO_ICONS
287 char * tmp = g_content_type_guess( file, NULL, 0, NULL );
288 const char * ret = get_static_string( tmp );
289 g_free( tmp );
290 return ret;
291 #else
292 return "uncertain";
293 #endif