1 /* GTK - The GIMP Toolkit
2 * gtkfilesystemunix.c: Default implementation of GtkFileSystem for UNIX-like systems
3 * Copyright (C) 2003, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "gtkfilesystem.h"
22 #include "gtkfilesystemunix.h"
29 #include <sys/types.h>
32 #define WIN32_LEAN_AND_MEAN
36 #define mkdir(p,m) _mkdir(p)
38 #error "The implementation is win32 only yet."
39 #endif /* G_OS_WIN32 */
41 typedef struct _GtkFileSystemUnixClass GtkFileSystemUnixClass;
43 #define GTK_FILE_SYSTEM_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_UNIX, GtkFileSystemUnixClass))
44 #define GTK_IS_FILE_SYSTEM_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_UNIX))
45 #define GTK_FILE_SYSTEM_UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_SYSTEM_UNIX, GtkFileSystemUnixClass))
47 struct _GtkFileSystemUnixClass
49 GObjectClass parent_class;
52 struct _GtkFileSystemUnix
54 GObject parent_instance;
57 #define GTK_TYPE_FILE_FOLDER_UNIX (gtk_file_folder_unix_get_type ())
58 #define GTK_FILE_FOLDER_UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnix))
59 #define GTK_IS_FILE_FOLDER_UNIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FOLDER_UNIX))
60 #define GTK_FILE_FOLDER_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnixClass))
61 #define GTK_IS_FILE_FOLDER_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_FOLDER_UNIX))
62 #define GTK_FILE_FOLDER_UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnixClass))
64 typedef struct _GtkFileFolderUnix GtkFileFolderUnix;
65 typedef struct _GtkFileFolderUnixClass GtkFileFolderUnixClass;
67 struct _GtkFileFolderUnixClass
69 GObjectClass parent_class;
72 struct _GtkFileFolderUnix
74 GObject parent_instance;
76 GtkFileInfoType types;
80 static GObjectClass *system_parent_class;
81 static GObjectClass *folder_parent_class;
83 static void gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class);
84 static void gtk_file_system_unix_iface_init (GtkFileSystemIface *iface);
85 static void gtk_file_system_unix_init (GtkFileSystemUnix *impl);
86 static void gtk_file_system_unix_finalize (GObject *object);
88 static GSList * gtk_file_system_unix_list_roots (GtkFileSystem *file_system);
89 static GtkFileInfo * gtk_file_system_unix_get_root_info (GtkFileSystem *file_system,
90 const GtkFilePath *path,
91 GtkFileInfoType types,
93 static GtkFileFolder *gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
94 const GtkFilePath *path,
95 GtkFileInfoType types,
97 static gboolean gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
98 const GtkFilePath *path,
100 static gboolean gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
101 const GtkFilePath *path,
102 GtkFilePath **parent,
104 static GtkFilePath * gtk_file_system_unix_make_path (GtkFileSystem *file_system,
105 const GtkFilePath *base_path,
106 const gchar *display_name,
108 static gboolean gtk_file_system_unix_parse (GtkFileSystem *file_system,
109 const GtkFilePath *base_path,
111 GtkFilePath **folder,
115 static gchar * gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
116 const GtkFilePath *path);
117 static gchar * gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
118 const GtkFilePath *path);
119 static GtkFilePath *gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
121 static GtkFilePath *gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
122 const gchar *filename);
124 static gboolean gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
125 const GtkFilePath *path,
127 static gboolean gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
128 const GtkFilePath *path,
130 static GSList * gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system);
132 static GType gtk_file_folder_unix_get_type (void);
133 static void gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class);
134 static void gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface);
135 static void gtk_file_folder_unix_init (GtkFileFolderUnix *impl);
136 static void gtk_file_folder_unix_finalize (GObject *object);
138 static GtkFileInfo *gtk_file_folder_unix_get_info (GtkFileFolder *folder,
139 const GtkFilePath *path,
141 static gboolean gtk_file_folder_unix_list_children (GtkFileFolder *folder,
145 static gchar * filename_from_path (const GtkFilePath *path);
146 static GtkFilePath *filename_to_path (const gchar *filename);
148 static gboolean filename_is_root (const char *filename);
149 static GtkFileInfo *filename_get_info (const gchar *filename,
150 GtkFileInfoType types,
157 gtk_file_system_unix_get_type (void)
159 static GType file_system_unix_type = 0;
161 if (!file_system_unix_type)
163 static const GTypeInfo file_system_unix_info =
165 sizeof (GtkFileSystemUnixClass),
166 NULL, /* base_init */
167 NULL, /* base_finalize */
168 (GClassInitFunc) gtk_file_system_unix_class_init,
169 NULL, /* class_finalize */
170 NULL, /* class_data */
171 sizeof (GtkFileSystemUnix),
173 (GInstanceInitFunc) gtk_file_system_unix_init,
176 static const GInterfaceInfo file_system_info =
178 (GInterfaceInitFunc) gtk_file_system_unix_iface_init, /* interface_init */
179 NULL, /* interface_finalize */
180 NULL /* interface_data */
183 file_system_unix_type = g_type_register_static (G_TYPE_OBJECT,
185 &file_system_unix_info, 0);
186 g_type_add_interface_static (file_system_unix_type,
187 GTK_TYPE_FILE_SYSTEM,
191 return file_system_unix_type;
195 * gtk_file_system_unix_new:
197 * Creates a new #GtkFileSystemUnix object. #GtkFileSystemUnix
198 * implements the #GtkFileSystem interface with direct access to
199 * the filesystem using Unix/Linux API calls
201 * Return value: the new #GtkFileSystemUnix object
204 gtk_file_system_unix_new (void)
206 return g_object_new (GTK_TYPE_FILE_SYSTEM_UNIX, NULL);
210 gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class)
212 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
214 system_parent_class = g_type_class_peek_parent (class);
216 gobject_class->finalize = gtk_file_system_unix_finalize;
220 gtk_file_system_unix_iface_init (GtkFileSystemIface *iface)
222 iface->list_roots = gtk_file_system_unix_list_roots;
223 iface->get_folder = gtk_file_system_unix_get_folder;
224 iface->get_root_info = gtk_file_system_unix_get_root_info;
225 iface->create_folder = gtk_file_system_unix_create_folder;
226 iface->get_parent = gtk_file_system_unix_get_parent;
227 iface->make_path = gtk_file_system_unix_make_path;
228 iface->parse = gtk_file_system_unix_parse;
229 iface->path_to_uri = gtk_file_system_unix_path_to_uri;
230 iface->path_to_filename = gtk_file_system_unix_path_to_filename;
231 iface->uri_to_path = gtk_file_system_unix_uri_to_path;
232 iface->filename_to_path = gtk_file_system_unix_filename_to_path;
233 iface->add_bookmark = gtk_file_system_unix_add_bookmark;
234 iface->remove_bookmark = gtk_file_system_unix_remove_bookmark;
235 iface->list_bookmarks = gtk_file_system_unix_list_bookmarks;
239 gtk_file_system_unix_init (GtkFileSystemUnix *system_unix)
244 gtk_file_system_unix_finalize (GObject *object)
246 system_parent_class->finalize (object);
250 gtk_file_system_unix_list_roots (GtkFileSystem *file_system)
257 len = GetLogicalDriveStrings(sizeof(drives), drives);
260 g_warning("No drive strings available!");
263 while ((len = strlen(p)) != 0)
266 if (p[0] != 'a' && p[0] != 'b')
268 //FIXME: gtk_fie_path_compare is case sensitive, we are not
269 p[0] = toupper (p[0]);
270 /* needed without the backslash */
272 list = g_slist_append (list, gtk_file_path_new_dup (p));
280 gtk_file_system_unix_get_root_info (GtkFileSystem *file_system,
281 const GtkFilePath *path,
282 GtkFileInfoType types,
285 /* needed _with_ the trailing backslash */
286 gchar *filename = g_strconcat(gtk_file_path_get_string (path), "\\", NULL);
288 DWORD dt = GetDriveType (filename);
290 info = filename_get_info (filename, types, error);
292 /* additional info */
293 if (GTK_FILE_INFO_DISPLAY_NAME & types)
295 gchar display_name[80];
297 if (GetVolumeInformation (filename,
298 display_name, sizeof(display_name),
299 NULL, /* serial number */
300 NULL, /* max. component length */
302 NULL, 0)) /* fs type like FAT, NTFS */
304 gchar* real_display_name = g_strconcat (display_name, " (", filename, ")", NULL);
306 gtk_file_info_set_display_name (info, real_display_name);
307 g_free (real_display_name);
310 gtk_file_info_set_display_name (info, filename);
313 if (GTK_FILE_INFO_ICON & types)
317 case DRIVE_REMOVABLE :
318 //gtk_file_info_set_icon_type (info, GTK_STOCK_FLOPPY);
321 //gtk_file_info_set_icon_type (info, GTK_STOCK_CDROM);
324 //FIXME: need a network stock icon
326 //FIXME: need a hard disk stock icon
328 //FIXME: need a ram stock icon
329 //gtk_file_info_set_icon_type (info, GTK_STOCK_OPEN);
332 g_assert_not_reached ();
339 static GtkFileFolder *
340 gtk_file_system_unix_get_folder (GtkFileSystem *file_system,
341 const GtkFilePath *path,
342 GtkFileInfoType types,
345 GtkFileFolderUnix *folder_unix;
348 filename = filename_from_path (path);
349 g_return_val_if_fail (filename != NULL, NULL);
351 folder_unix = g_object_new (GTK_TYPE_FILE_FOLDER_UNIX, NULL);
352 folder_unix->filename = filename;
353 folder_unix->types = types;
355 return GTK_FILE_FOLDER (folder_unix);
359 gtk_file_system_unix_create_folder (GtkFileSystem *file_system,
360 const GtkFilePath *path,
366 filename = filename_from_path (path);
367 g_return_val_if_fail (filename != NULL, FALSE);
369 result = mkdir (filename, 0777) != 0;
373 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
375 GTK_FILE_SYSTEM_ERROR,
376 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
377 _("error creating directory '%s': %s"),
378 filename_utf8 ? filename_utf8 : "???",
380 g_free (filename_utf8);
389 gtk_file_system_unix_get_parent (GtkFileSystem *file_system,
390 const GtkFilePath *path,
391 GtkFilePath **parent,
394 gchar *filename = filename_from_path (path);
395 g_return_val_if_fail (filename != NULL, FALSE);
397 if (filename_is_root (filename))
403 gchar *parent_filename = g_path_get_dirname (filename);
404 *parent = filename_to_path (parent_filename);
405 g_free (parent_filename);
414 gtk_file_system_unix_make_path (GtkFileSystem *file_system,
415 const GtkFilePath *base_path,
416 const gchar *display_name,
419 gchar *base_filename;
421 gchar *full_filename;
422 GError *tmp_error = NULL;
425 base_filename = filename_from_path (base_path);
426 g_return_val_if_fail (base_filename != NULL, NULL);
428 filename = g_filename_from_utf8 (display_name, -1, NULL, NULL, &tmp_error);
432 GTK_FILE_SYSTEM_ERROR,
433 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
437 g_error_free (tmp_error);
438 g_free (base_filename);
443 full_filename = g_build_filename (base_filename, filename, NULL);
444 result = filename_to_path (full_filename);
445 g_free (base_filename);
447 g_free (full_filename);
452 /* If this was a publically exported function, it should return
453 * a dup'ed result, but we make it modify-in-place for efficiency
454 * here, and because it works for us.
457 canonicalize_filename (gchar *filename)
460 gboolean last_was_slash = FALSE;
467 if (*p == G_DIR_SEPARATOR)
470 *q++ = G_DIR_SEPARATOR;
472 last_was_slash = TRUE;
476 if (last_was_slash && *p == '.')
478 if (*(p + 1) == G_DIR_SEPARATOR ||
481 if (*(p + 1) == '\0')
486 else if (*(p + 1) == '.' &&
487 (*(p + 2) == G_DIR_SEPARATOR ||
490 if (q > filename + 1)
493 while (q > filename + 1 &&
494 *(q - 1) != G_DIR_SEPARATOR)
498 if (*(p + 2) == '\0')
506 last_was_slash = FALSE;
512 last_was_slash = FALSE;
519 if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
526 gtk_file_system_unix_parse (GtkFileSystem *file_system,
527 const GtkFilePath *base_path,
529 GtkFilePath **folder,
535 gboolean result = FALSE;
537 base_filename = filename_from_path (base_path);
538 g_return_val_if_fail (base_filename != NULL, FALSE);
540 last_slash = strrchr (str, G_DIR_SEPARATOR);
543 *folder = gtk_file_path_copy (base_path);
544 *file_part = g_strdup (str);
551 GError *tmp_error = NULL;
553 if (last_slash == str)
554 folder_part = g_strdup ("/");
556 folder_part = g_filename_from_utf8 (str, last_slash - str,
557 NULL, NULL, &tmp_error);
562 GTK_FILE_SYSTEM_ERROR,
563 GTK_FILE_SYSTEM_ERROR_BAD_FILENAME,
566 g_error_free (tmp_error);
570 if (folder_part[1] == ':')
571 folder_path = folder_part;
574 folder_path = g_build_filename (base_filename, folder_part, NULL);
575 g_free (folder_part);
578 canonicalize_filename (folder_path);
580 *folder = filename_to_path (folder_path);
581 *file_part = g_strdup (last_slash + 1);
583 g_free (folder_path);
589 g_free (base_filename);
595 gtk_file_system_unix_path_to_uri (GtkFileSystem *file_system,
596 const GtkFilePath *path)
598 return g_filename_to_uri (gtk_file_path_get_string (path), NULL, NULL);
602 gtk_file_system_unix_path_to_filename (GtkFileSystem *file_system,
603 const GtkFilePath *path)
605 return g_strdup (gtk_file_path_get_string (path));
609 gtk_file_system_unix_uri_to_path (GtkFileSystem *file_system,
612 gchar *filename = g_filename_from_uri (uri, NULL, NULL);
614 return gtk_file_path_new_steal (filename);
620 gtk_file_system_unix_filename_to_path (GtkFileSystem *file_system,
621 const gchar *filename)
623 return gtk_file_path_new_dup (filename);
627 bookmarks_serialize (GSList **bookmarks,
634 GSList *list = *bookmarks;
636 filename = g_build_filename (g_get_home_dir (), ".gtk-bookmarks", NULL);
640 gchar *contents = NULL;
645 if (g_file_test (filename, G_FILE_TEST_EXISTS))
647 if (g_file_get_contents (filename, &contents, &len, error))
649 gchar **lines = g_strsplit (contents, "\n", -1);
652 for (i = 0; lines[i] != NULL; i++)
654 if (lines[i][0] && !g_slist_find_custom (list, lines[i], strcmp))
655 list = g_slist_append (list, g_strdup (lines[i]));
662 if (ok && (f = fopen (filename, "wb")) != NULL)
664 for (entry = list; entry != NULL; entry = entry->next)
666 gchar *line = entry->data;
668 if (strcmp (line, uri) != 0)
681 else if (ok && error)
684 GTK_FILE_SYSTEM_ERROR,
685 GTK_FILE_SYSTEM_ERROR_FAILED,
686 _("Bookmark saving failed (%s)"),
694 static GSList *_bookmarks = NULL;
697 gtk_file_system_unix_add_bookmark (GtkFileSystem *file_system,
698 const GtkFilePath *path,
701 gchar *uri = gtk_file_system_unix_path_to_uri (file_system, path);
702 gboolean ret = bookmarks_serialize (&_bookmarks, uri, TRUE, error);
709 gtk_file_system_unix_remove_bookmark (GtkFileSystem *file_system,
710 const GtkFilePath *path,
713 gchar *uri = gtk_file_system_unix_path_to_uri (file_system, path);
714 gboolean ret = bookmarks_serialize (&_bookmarks, uri, FALSE, error);
720 gtk_file_system_unix_list_bookmarks (GtkFileSystem *file_system)
725 if (bookmarks_serialize (&_bookmarks, "", FALSE, NULL))
729 for (entry = _bookmarks; entry != NULL; entry = entry->next)
731 GtkFilePath *path = gtk_file_system_unix_uri_to_path (
732 file_system, (gchar *)entry->data);
734 list = g_slist_append (list, path);
745 gtk_file_folder_unix_get_type (void)
747 static GType file_folder_unix_type = 0;
749 if (!file_folder_unix_type)
751 static const GTypeInfo file_folder_unix_info =
753 sizeof (GtkFileFolderUnixClass),
754 NULL, /* base_init */
755 NULL, /* base_finalize */
756 (GClassInitFunc) gtk_file_folder_unix_class_init,
757 NULL, /* class_finalize */
758 NULL, /* class_data */
759 sizeof (GtkFileFolderUnix),
761 (GInstanceInitFunc) gtk_file_folder_unix_init,
764 static const GInterfaceInfo file_folder_info =
766 (GInterfaceInitFunc) gtk_file_folder_unix_iface_init, /* interface_init */
767 NULL, /* interface_finalize */
768 NULL /* interface_data */
771 file_folder_unix_type = g_type_register_static (G_TYPE_OBJECT,
773 &file_folder_unix_info, 0);
774 g_type_add_interface_static (file_folder_unix_type,
775 GTK_TYPE_FILE_FOLDER,
779 return file_folder_unix_type;
783 gtk_file_folder_unix_class_init (GtkFileFolderUnixClass *class)
785 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
787 folder_parent_class = g_type_class_peek_parent (class);
789 gobject_class->finalize = gtk_file_folder_unix_finalize;
793 gtk_file_folder_unix_iface_init (GtkFileFolderIface *iface)
795 iface->get_info = gtk_file_folder_unix_get_info;
796 iface->list_children = gtk_file_folder_unix_list_children;
800 gtk_file_folder_unix_init (GtkFileFolderUnix *impl)
805 gtk_file_folder_unix_finalize (GObject *object)
807 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (object);
809 g_free (folder_unix->filename);
811 folder_parent_class->finalize (object);
815 gtk_file_folder_unix_get_info (GtkFileFolder *folder,
816 const GtkFilePath *path,
819 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
824 filename = filename_from_path (path);
825 g_return_val_if_fail (filename != NULL, NULL);
828 dirname = g_path_get_dirname (filename);
829 g_return_val_if_fail (strcmp (dirname, folder_unix->filename) == 0, NULL);
833 info = filename_get_info (filename, folder_unix->types, error);
841 gtk_file_folder_unix_list_children (GtkFileFolder *folder,
845 GtkFileFolderUnix *folder_unix = GTK_FILE_FOLDER_UNIX (folder);
846 GError *tmp_error = NULL;
851 dir = g_dir_open (folder_unix->filename, 0, &tmp_error);
855 GTK_FILE_SYSTEM_ERROR,
856 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
860 g_error_free (tmp_error);
867 const gchar *filename = g_dir_read_name (dir);
873 fullname = g_build_filename (folder_unix->filename, filename, NULL);
874 *children = g_slist_prepend (*children, filename_to_path (fullname));
880 *children = g_slist_reverse (*children);
886 filename_get_info (const gchar *filename,
887 GtkFileInfoType types,
891 GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR;
892 WIN32_FILE_ATTRIBUTE_DATA wfad;
894 if (!GetFileAttributesEx (filename, GetFileExInfoStandard, &wfad))
896 gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
898 GTK_FILE_SYSTEM_ERROR,
899 GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
900 _("error getting information for '%s': %s"),
901 filename_utf8 ? filename_utf8 : "???",
902 g_win32_error_message (GetLastError ()));
903 g_free (filename_utf8);
908 info = gtk_file_info_new ();
910 if (filename_is_root (filename))
912 if (types & GTK_FILE_INFO_DISPLAY_NAME)
913 gtk_file_info_set_display_name (info, filename);
915 if (types & GTK_FILE_INFO_IS_HIDDEN)
916 gtk_file_info_set_is_hidden (info, FALSE);
920 gchar *basename = g_path_get_basename (filename);
922 if (types & GTK_FILE_INFO_DISPLAY_NAME)
924 gchar *display_name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
926 display_name = g_strescape (basename, NULL);
928 gtk_file_info_set_display_name (info, display_name);
930 g_free (display_name);
933 if (types & GTK_FILE_INFO_IS_HIDDEN)
935 /* unix convention ... */
936 gboolean is_hidden = basename[0] == '.';
937 /* ... _and_ windoze attribute */
938 is_hidden = is_hidden || !!(wfad.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
939 gtk_file_info_set_is_hidden (info, is_hidden);
945 if (types & GTK_FILE_INFO_IS_FOLDER)
947 gtk_file_info_set_is_folder (info, !!(wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
950 if (types & GTK_FILE_INFO_ICON)
952 if (wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
953 icon_type = GTK_FILE_ICON_DIRECTORY;
955 gtk_file_info_set_icon_type (info, icon_type);
958 if ((types & GTK_FILE_INFO_MIME_TYPE) ||
959 ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR))
962 const char *mime_type = xdg_mime_get_mime_type_for_file (filename);
963 gtk_file_info_set_mime_type (info, mime_type);
965 if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
966 (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
967 (strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
968 strcmp (mime_type, "application/x-executable") == 0 ||
969 strcmp (mime_type, "application/x-shellscript") == 0))
970 gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
974 if (types & GTK_FILE_INFO_MODIFICATION_TIME)
976 GtkFileTime time = wfad.ftLastWriteTime.dwLowDateTime
977 | ((guint64)wfad.ftLastWriteTime.dwHighDateTime) << 32;
978 /* 100-nanosecond intervals since January 1, 1601, urgh! */
979 time /= 10000000I64; /* now seconds */
980 time -= 134774I64 * 24 * 3600; /* good old unix time */
981 gtk_file_info_set_modification_time (info, time);
984 if (types & GTK_FILE_INFO_SIZE)
986 gint64 size = wfad.nFileSizeLow | ((guint64)wfad.nFileSizeHigh) << 32;
987 gtk_file_info_set_size (info, size);
994 filename_from_path (const GtkFilePath *path)
996 return g_strdup (gtk_file_path_get_string (path));
1000 filename_to_path (const char *filename)
1002 return gtk_file_path_new_dup (filename);
1006 filename_is_root (const char *filename)
1008 guint len = strlen(filename);
1010 /* accept both forms */
1012 return ( (len == 2 && filename[1] == ':')
1013 || (len == 3 && filename[1] == ':' && filename[2] == '\\'));