#include #include #include GHashTable* mime2icon_table; GList* fileinfos; gchar* clean_content_type(gchar* string); int main (int argc, char **argv) { gtk_init(&argc, &argv); //g_thread_init (NULL); //g_type_init (); if (argc < 2) return -1; // set up datatypes mime2icon_table = g_hash_table_new(g_str_hash, g_str_equal); GError *error; GFile *file = g_file_new_for_path (argv[1]); if(!g_file_query_exists(file, NULL)) { printf("File %s does not exist!", argv[1]); return 1; } create_mappings(file); // so now we got: // mime2icon_table: A full mapping mime-type => base64 encoded PNG icon files // fileinfos An ordered list of files, better said, file info objects // containing all information about the files. // we can start constructing. if(g_list_length(fileinfos)) // directory non-empty construct(); } gboolean construct() { GHashTable* clean_mime = g_hash_table_new(g_str_hash, g_str_equal); // create CSS from mime2icon_table: GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, mime2icon_table); while(g_hash_table_iter_next(&iter, &key, &value)) { // create a clean mime type mapping gchar* clean_key = g_strdup(key); g_hash_table_insert(clean_mime, key, // g_strcanon modifies it argument, thus the duping (cloning) g_strcanon(clean_key, "-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", '_')); // print out CSS printf(".%s { background-image: url('data:image/png;base64,%s'); }\n", clean_key, (char*)value); } // foreach mime2icon // Create File listing: GList *e = g_list_first(fileinfos); GFileInfo* finf; for(e = g_list_first(fileinfos); e; e = g_list_next(e)) { finf = (GFileInfo*) e->data; // example for fully featured table: /* GTimeVal lastmod_t; g_file_info_get_modification_time(finf, &lastmod_t); GDate *lastmod = g_date_new(); g_date_set_time_val(lastmod, &lastmod_t); gchar lastmod_str[50]; g_date_strftime(lastmod_str, 49, "%m,%d,%y", lastmod); printf("%s" "%d%s%s\n", g_file_info_get_name(finf), (char*) g_hash_table_lookup(clean_mime, g_file_info_get_content_type(finf)), g_file_info_get_name(finf), (int) g_file_info_get_size(finf), lastmod_str, g_content_type_get_description(g_file_info_get_content_type(finf)) ); */ // simple lightweight, CSV format: mime;clean_mime;desc;filename fprintf(stderr, "%s;%s;%s;%s\n", g_file_info_get_content_type(finf), (char*) g_hash_table_lookup(clean_mime, g_file_info_get_content_type(finf)), g_content_type_get_description(g_file_info_get_content_type(finf)), g_file_info_get_name(finf) ); } // for files } // construct() gboolean create_mappings(GFile* file_or_directory) { GError* error; if(g_file_query_file_type(file_or_directory, 0, NULL) == G_FILE_TYPE_DIRECTORY) { GFileEnumerator* enumerate = g_file_enumerate_children(file_or_directory, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, &error); GFileInfo* file_info; while(file_info = g_file_enumerator_next_file(enumerate, NULL, &error)) { char* content_type = (char*) g_file_info_get_content_type(file_info); if(g_hash_table_lookup(mime2icon_table, content_type)) { // we already found out the icon for this mime-type // printf("Skipping %s\n", g_file_info_get_name(file_info)); continue; } else get_icon(file_info); // put filename on list fileinfos = g_list_append(fileinfos, file_info); } // for directory } else { // do one single step GFileInfo* file_info = g_file_query_info(file_or_directory, "standard::*", 0, NULL, &error); fileinfos = g_list_append(fileinfos, file_info); get_icon(file_info); } } gboolean get_icon(GFileInfo* file_info) { GError* error; GIcon *icon = g_file_info_get_icon (file_info); GtkIconTheme* theme = gtk_icon_theme_get_default(); GtkIconInfo* icon_info = gtk_icon_theme_lookup_by_gicon(theme, icon, 32, GTK_ICON_LOOKUP_GENERIC_FALLBACK || GTK_ICON_LOOKUP_FORCE_SIZE || GTK_ICON_LOOKUP_USE_BUILTIN /* as optional fallback */); GdkPixbuf* pixbuf; if(!icon_info) { // no icon found. STDOUT comment for CSS printf("/* %s - no icon found */\n", g_file_info_get_content_type(file_info)); // load some standard icon! pixbuf = gtk_icon_theme_load_icon(theme, "gtk-file", 32, GTK_ICON_LOOKUP_GENERIC_FALLBACK, &error); } else { // const gchar* filename = gtk_icon_info_get_filename(icon_info); pixbuf = gtk_icon_info_load_icon(icon_info, &error); } // render pixbuf with icon to PNG; perform base64 encoding. gchar* pngbuf; gsize pngbuf_len; gboolean ret = gdk_pixbuf_save_to_buffer(pixbuf, &pngbuf, &pngbuf_len, "png", &error, "compression", "9", NULL); gchar* pngencoding = g_base64_encode(pngbuf, pngbuf_len); // store pngencoding in hash table g_hash_table_insert(mime2icon_table, (char*) g_file_info_get_content_type(file_info), pngencoding); // debugging: //printf ("File: %s\nIcon Filename: %s\nBASE: %20.20s..\n", // g_file_info_get_name(file_info), filename, pngencoding); return TRUE; }