diff options
author | Hans Breuer <hans@breuer.org> | 2003-12-14 19:03:02 +0000 |
---|---|---|
committer | Hans Breuer <hans@src.gnome.org> | 2003-12-14 19:03:02 +0000 |
commit | 4acd98a8365558d494b82c4be3e037993680f9f4 (patch) | |
tree | 54e16f4ba4223ff46279b1cdebc5f2306c09a04d /gtk/gtkfilesystemwin32.c | |
parent | 6857ba492925975b3e490e06b1d86c67cac49ca4 (diff) | |
download | gtk+-4acd98a8365558d494b82c4be3e037993680f9f4.tar.gz |
handle GTK_DATADIR similar as the other filesystem placement 'constants'
2003-12-14 Hans Breuer <hans@breuer.org>
* gtk/gtkprivate.h gtk/gtkmain.c : handle GTK_DATADIR
similar as the other filesystem placement 'constants' (dynamic
resolving on win32)
* gtk/gtkfilechooserwidget.c : handle file system to win32
renaming here as will
* gtk/gtkfilesystemwin32.c : implement render_icon
* gtk/gtk.def gdk/gdk.def : updated externals
* gdk/win32/gdkdisplay-win32.c : make it compile without
<multimon.h> - i.e. even older sdk
* gdk/win32/gdkevents-win32.c : match resize_timer_proc
with TIMERPROC prototype
* gdk/win32/gdkwindow-win32.c : older msvc does not know
BITMAPV5HEADER (from win xp) either
* gtk/gtkimmodule.c : make it compile even if GTK_LOCALEDIR is
not defined
* tests/testfilechooser.c : recent GLib crashes on
g_print ("%s", NULL) so avoid this
Diffstat (limited to 'gtk/gtkfilesystemwin32.c')
-rw-r--r-- | gtk/gtkfilesystemwin32.c | 187 |
1 files changed, 184 insertions, 3 deletions
diff --git a/gtk/gtkfilesystemwin32.c b/gtk/gtkfilesystemwin32.c index 787f08b5fa..f233ffeb8a 100644 --- a/gtk/gtkfilesystemwin32.c +++ b/gtk/gtkfilesystemwin32.c @@ -22,6 +22,7 @@ #include "gtkfilesystemwin32.h" #include "gtkintl.h" #include "gtkstock.h" +#include "gtkiconfactory.h" #include <errno.h> #include <stdio.h> @@ -31,9 +32,11 @@ #ifdef G_OS_WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include <shellapi.h> /* ExtractAssociatedIcon */ #include <direct.h> #include <io.h> #define mkdir(p,m) _mkdir(p) +#include <gdk/win32/gdkwin32.h> /* gdk_win32_hdc_get */ #else #error "The implementation is win32 only yet." #endif /* G_OS_WIN32 */ @@ -118,6 +121,12 @@ static GtkFilePath * gtk_file_system_win32_uri_to_path (GtkFileSystem const gchar *uri); static GtkFilePath * gtk_file_system_win32_filename_to_path (GtkFileSystem *file_system, const gchar *filename); +static GdkPixbuf *gtk_file_system_win32_render_icon (GtkFileSystem *file_system, + const GtkFilePath *path, + GtkWidget *widget, + gint pixel_size, + GError **error); + static gboolean gtk_file_system_win32_add_bookmark (GtkFileSystem *file_system, const GtkFilePath *path, GError **error); @@ -224,6 +233,7 @@ gtk_file_system_win32_iface_init (GtkFileSystemIface *iface) iface->path_to_filename = gtk_file_system_win32_path_to_filename; iface->uri_to_path = gtk_file_system_win32_uri_to_path; iface->filename_to_path = gtk_file_system_win32_filename_to_path; + iface->render_icon = gtk_file_system_win32_render_icon; iface->add_bookmark = gtk_file_system_win32_add_bookmark; iface->remove_bookmark = gtk_file_system_win32_remove_bookmark; iface->list_bookmarks = gtk_file_system_win32_list_bookmarks; @@ -304,6 +314,7 @@ gtk_file_system_win32_get_root_info (GtkFileSystem *file_system, gtk_file_info_set_display_name (info, filename); } +#if 0 /* it's dead in GtkFileSystemUnix.c, too */ if (GTK_FILE_INFO_ICON & types) { switch (dt) @@ -326,6 +337,7 @@ gtk_file_system_win32_get_root_info (GtkFileSystem *file_system, g_assert_not_reached (); } } +#endif g_free (filename); return info; } @@ -633,7 +645,7 @@ bookmarks_serialize (GSList **bookmarks, { gchar *contents = NULL; gsize len = 0; - GList *entry; + GSList *entry; FILE *f; if (g_file_test (filename, G_FILE_TEST_EXISTS)) @@ -685,6 +697,168 @@ bookmarks_serialize (GSList **bookmarks, return ok; } +static GdkPixbuf* +extract_icon (const char* filename) +{ + GdkPixbuf *pixbuf = NULL; + WORD iicon; + HICON hicon; + + if (!filename || !filename[0]) + return NULL; + + hicon = ExtractAssociatedIcon (GetModuleHandle (NULL), filename, &iicon); + if (hicon > (HICON)1) + { + ICONINFO ii; + + if (GetIconInfo (hicon, &ii)) + { + SIZE size; + GdkPixmap *pixmap; + GdkGC *gc; + HDC hdc; + + if (!GetBitmapDimensionEx (ii.hbmColor, &size)) + g_warning ("GetBitmapDimensionEx failed."); + + if (size.cx < 1) size.cx = 32; + if (size.cy < 1) size.cy = 32; + + pixmap = gdk_pixmap_new (NULL, size.cx, size.cy, + gdk_screen_get_system_visual (gdk_screen_get_default ())->depth); + gc = gdk_gc_new (pixmap); + hdc = gdk_win32_hdc_get (GDK_DRAWABLE (pixmap), gc, 0); + + if (!DrawIcon (hdc, 0, 0, hicon)) + g_warning ("DrawIcon failed"); + + gdk_win32_hdc_release (GDK_DRAWABLE (pixmap), gc, 0); + + pixbuf = gdk_pixbuf_get_from_drawable ( + NULL, pixmap, + gdk_screen_get_system_colormap (gdk_screen_get_default ()), + 0, 0, 0, 0, size.cx, size.cy); + g_object_unref (pixmap); + g_object_unref (gc); + } + else + g_print ("GetIconInfo failed: %s\n", g_win32_error_message (GetLastError ())); + + if (!DestroyIcon (hicon)) + g_warning ("DestroyIcon failed"); + } + else + g_print ("ExtractAssociatedIcon failed: %s\n", g_win32_error_message (GetLastError ())); + + return pixbuf; +} + +static GtkIconSet * +win32_pseudo_mime_lookup (const char* name) +{ + static GHashTable *mime_hash = NULL; + GtkIconSet *is = NULL; + char *p = strrchr(name, '.'); + char *extension = p ? g_ascii_strdown (p, -1) : g_strdup (""); + + if (!mime_hash) + mime_hash = g_hash_table_new (g_str_hash, g_str_equal); + + /* do we already have it ? */ + is = g_hash_table_lookup (mime_hash, extension); + if (is) + { + g_free (extension); + return is; + } + /* create icon and set */ + { + GdkPixbuf *pixbuf = extract_icon (name); + if (pixbuf) + { + GtkIconSource* source = gtk_icon_source_new (); + + is = gtk_icon_set_new_from_pixbuf (pixbuf); + gtk_icon_source_set_pixbuf (source, pixbuf); + gtk_icon_set_add_source (is, source); + + gtk_icon_source_free (source); + } + + g_hash_table_insert (mime_hash, extension, is); + return is; + } +} + +static GdkPixbuf * +gtk_file_system_win32_render_icon (GtkFileSystem *file_system, + const GtkFilePath *path, + GtkWidget *widget, + gint pixel_size, + GError **error) +{ + GtkIconSet *icon_set = NULL; + const char* filename = gtk_file_path_get_string (path); + + /* handle drives with stock icons */ + if (filename_is_root (filename)) + { + gchar *filename2 = g_strconcat(filename, "\\", NULL); + DWORD dt = GetDriveType (filename2); + + switch (dt) + { + case DRIVE_REMOVABLE : + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_FLOPPY); + break; + case DRIVE_CDROM : + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_CDROM); + break; + case DRIVE_FIXED : /* need a hard disk icon */ + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_CDROM); + break; + default : + break; + } + g_free (filename2); + } + else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) + { + if (0 == strcmp (g_get_home_dir(), filename)) + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_HOME); + else + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_OPEN); + } + else if (g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE)) + { + /* don't lookup all executable icons */ + icon_set = gtk_style_lookup_icon_set (widget->style, GTK_STOCK_EXECUTE); + } + else if (g_file_test (filename, G_FILE_TEST_EXISTS)) + { + icon_set = win32_pseudo_mime_lookup (filename); + } + + if (!icon_set) + { + g_set_error (error, + GTK_FILE_SYSTEM_ERROR, + GTK_FILE_SYSTEM_ERROR_FAILED, + _("This file system does not support icons for everything")); + return NULL; + } + + // FIXME : I'd like to get from pixel_size (=20) back to + // icon size, which is an index, but there appears to be no way ? + return gtk_icon_set_render_icon (icon_set, + widget->style, + gtk_widget_get_direction (widget), + GTK_STATE_NORMAL, + GTK_ICON_SIZE_BUTTON, + widget, NULL); +} + static GSList *_bookmarks = NULL; static gboolean @@ -881,7 +1055,9 @@ filename_get_info (const gchar *filename, GError **error) { GtkFileInfo *info; +#if 0 /* it's dead in GtkFileSystemUnix.c, too */ GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR; +#endif WIN32_FILE_ATTRIBUTE_DATA wfad; if (!GetFileAttributesEx (filename, GetFileExInfoStandard, &wfad)) @@ -940,6 +1116,7 @@ filename_get_info (const gchar *filename, gtk_file_info_set_is_folder (info, !!(wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); } +#if 0 /* it's dead in GtkFileSystemUnix.c, too */ if (types & GTK_FILE_INFO_ICON) { if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) @@ -947,9 +1124,13 @@ filename_get_info (const gchar *filename, gtk_file_info_set_icon_type (info, icon_type); } +#endif - if ((types & GTK_FILE_INFO_MIME_TYPE) || - ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR)) + if ((types & GTK_FILE_INFO_MIME_TYPE) +#if 0 /* it's dead in GtkFileSystemUnix.c, too */ + || ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR) +#endif + ) { #if 0 const char *mime_type = xdg_mime_get_mime_type_for_file (filename); |