GdkPixbuf* vfs_app_desktop_get_icon( VFSAppDesktop* app, int size, gboolean use_fallback ) { GtkIconTheme* theme; char *icon_name = NULL, *suffix; GdkPixbuf* icon = NULL; if( app->icon_name ) { if( g_path_is_absolute( app->icon_name) ) { icon = gdk_pixbuf_new_from_file_at_scale( app->icon_name, size, size, TRUE, NULL ); } else { theme = gtk_icon_theme_get_default(); suffix = strchr( app->icon_name, '.' ); if( suffix ) /* has file extension, it's a basename of icon file */ { /* try to find it in pixmaps dirs */ icon = load_icon_file( app->icon_name, size ); if( G_UNLIKELY( ! icon ) ) /* unfortunately, not found */ { /* Let's remove the suffix, and see if this name can match an icon in current icon theme */ icon_name = g_strndup( app->icon_name, (suffix - app->icon_name) ); icon = vfs_load_icon( theme, icon_name, size ); g_free( icon_name ); } } else /* no file extension, it could be an icon name in the icon theme */ { icon = vfs_load_icon( theme, app->icon_name, size ); } } } if( G_UNLIKELY( ! icon ) && use_fallback ) /* fallback to generic icon */ { theme = gtk_icon_theme_get_default(); icon = vfs_load_icon( theme, "application-x-executable", size ); if( G_UNLIKELY( ! icon ) ) /* fallback to generic icon */ { icon = vfs_load_icon( theme, "gnome-mime-application-x-executable", size ); } } return icon; }
void replace_icon(const wstring& pe_path, const wstring& ico_path) { list<IconRsrc> icons; RsrcModule module(pe_path); list<RsrcId> group_ids = enum_rsrc_names(module.handle(), RT_GROUP_ICON); for_each(group_ids.cbegin(), group_ids.cend(), [&] (const RsrcId& id) { list<WORD> lang_ids = enum_rsrc_langs(module.handle(), RT_GROUP_ICON, id); for_each(lang_ids.cbegin(), lang_ids.cend(), [&] (WORD lang_id) { icons.push_back(load_icon_rsrc(module.handle(), id, lang_id)); }); }); module.close(); ResourceUpdate rupdate(pe_path); // delete existing icons for_each(icons.cbegin(), icons.cend(), [&] (const IconRsrc& icon) { for_each (icon.images.cbegin(), icon.images.cend(), [&] (const IconImageRsrc& image) { rupdate.update(RT_ICON, MAKEINTRESOURCE(image.id), image.lang_id, nullptr, 0); }); rupdate.update(RT_GROUP_ICON, icon.id, icon.lang_id, nullptr, 0); }); WORD lang_id; if (!icons.empty()) lang_id = icons.front().lang_id; else lang_id = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); IconFile icon_file = load_icon_file(ico_path); IconRsrc icon_rsrc; icon_rsrc.lang_id = lang_id; for_each(icon_file.cbegin(), icon_file.cend(), [&] (const IconImage& image) { IconImageRsrc image_rsrc; image_rsrc.lang_id = lang_id; image_rsrc.image = image; icon_rsrc.images.push_back(image_rsrc); }); // drop first icon (all languages) if (!icons.empty()) { RsrcId id = icons.front().id; while (!icons.empty() && icons.front().id == id) icons.pop_front(); } icons.push_front(icon_rsrc); // renumber resource ids WORD icon_id = 1; WORD image_id = 1; for_each(icons.begin(), icons.end(), [&] (IconRsrc& icon) { if (icon.id.is_int()) { icon.id = MAKEINTRESOURCE(icon_id); icon_id++; } for_each(icon.images.begin(), icon.images.end(), [&] (IconImageRsrc& image) { image.id = image_id; image_id++; }); }); // write new icons for_each(icons.cbegin(), icons.cend(), [&] (const IconRsrc& icon) { Buffer<unsigned char> buf(sizeof(IconGroupHeader) + icon.images.size() * sizeof(IconGroupEntry)); IconGroupHeader* header = reinterpret_cast<IconGroupHeader*>(buf.data()); header->reserved = 0; header->type = 1; header->count = static_cast<WORD>(icon.images.size()); unsigned offset = sizeof(IconGroupHeader); for_each (icon.images.cbegin(), icon.images.cend(), [&] (const IconImageRsrc& image) { IconGroupEntry* entry = reinterpret_cast<IconGroupEntry*>(buf.data() + offset); entry->width = image.image.width; entry->height = image.image.height; entry->color_cnt = image.image.color_cnt; entry->reserved = 0; entry->plane_cnt = image.image.plane_cnt; entry->bit_cnt = image.image.bit_cnt; entry->size = static_cast<DWORD>(image.image.bitmap.size()); entry->id = image.id; rupdate.update(RT_ICON, MAKEINTRESOURCE(image.id), image.lang_id, image.image.bitmap.data(), static_cast<DWORD>(image.image.bitmap.size())); offset += sizeof(IconGroupEntry); }); rupdate.update(RT_GROUP_ICON, icon.id, icon.lang_id, buf.data(), static_cast<DWORD>(buf.size())); }); rupdate.finalize(); }