Commit 6a570ccb authored by Tor Lillqvist's avatar Tor Lillqvist Committed by Tor Lillqvist

Make it compile again. Doesn't work properly yet, though. There is lots of

2006-05-22  Tor Lillqvist  <tml@novell.com>

	* gtk/gtkfilesystemwin32.c: Make it compile again. Doesn't work
	properly yet, though. There is lots of commonality between this
	file and gtkfilesystemunix.c that should really be factored out.
parent 9c5eee4f
2006-05-22 Tor Lillqvist <tml@novell.com>
* gtk/gtkfilesystemwin32.c: Make it compile again. Doesn't work
properly yet, though. There is lots of commonality between this
file and gtkfilesystemunix.c that should really be factored out.
2006-05-19 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkpaned.c (gtk_paned_compute_position): Avoid warnings
......
2006-05-22 Tor Lillqvist <tml@novell.com>
* gtk/gtkfilesystemwin32.c: Make it compile again. Doesn't work
properly yet, though. There is lots of commonality between this
file and gtkfilesystemunix.c that should really be factored out.
2006-05-19 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkpaned.c (gtk_paned_compute_position): Avoid warnings
......
......@@ -20,8 +20,10 @@
*/
#include <config.h>
#include "gtkfilesystem.h"
#include "gtkfilesystemwin32.h"
#include "gtkicontheme.h"
#include "gtkintl.h"
#include "gtkstock.h"
#include "gtkiconfactory.h"
......@@ -35,16 +37,16 @@
#include <ctype.h>
#include <sys/types.h>
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include "gdk/win32/gdkwin32.h"
#undef STRICT
#include <shlobj.h>
#include <shellapi.h>
#else
#error "The implementation is Win32 only."
#endif /* G_OS_WIN32 */
#define BOOKMARKS_FILENAME ".gtk-bookmarks"
#define FOLDER_CACHE_LIFETIME 2 /* seconds */
typedef struct _GtkFileSystemWin32Class GtkFileSystemWin32Class;
......@@ -66,7 +68,18 @@ struct _GtkFileSystemWin32
guint timeout;
};
#define GTK_TYPE_FILE_FOLDER_WIN32 (gtk_file_folder_win32_get_type ())
/* Icon type, supplemented by MIME type
*/
typedef enum {
ICON_UNDECIDED, /* Only used while we have not yet computed the icon in a struct stat_info_entry */
ICON_NONE, /* "Could not compute the icon type" */
ICON_REGULAR, /* Use mime type for icon */
ICON_DIRECTORY,
ICON_EXECUTABLE
} IconType;
#define GTK_TYPE_FILE_FOLDER_WIN32 (_gtk_file_folder_win32_get_type ())
#define GTK_FILE_FOLDER_WIN32(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_FOLDER_WIN32, GtkFileFolderWin32))
#define GTK_IS_FILE_FOLDER_WIN32(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FOLDER_WIN32))
#define GTK_FILE_FOLDER_WIN32_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_FOLDER_WIN32, GtkFileFolderWin32Class))
......@@ -88,27 +101,51 @@ struct _GtkFileFolderWin32
GtkFileSystemWin32 *system_win32;
GtkFileInfoType types;
gchar *filename;
GHashTable *stat_info;
guint load_folder_id;
guint have_stat : 1;
guint have_mime_type : 1;
guint is_network_dir : 1;
guint is_finished_loading : 1;
time_t asof;
};
struct stat_info_entry {
WIN32_FILE_ATTRIBUTE_DATA wfad;
char *mime_type;
IconType icon_type;
gboolean hidden;
};
static GObjectClass *system_parent_class;
static GObjectClass *folder_parent_class;
static const GtkFileInfoType STAT_NEEDED_MASK = (GTK_FILE_INFO_IS_FOLDER |
GTK_FILE_INFO_MODIFICATION_TIME |
GTK_FILE_INFO_SIZE |
GTK_FILE_INFO_ICON);
static void gtk_file_system_win32_class_init (GtkFileSystemWin32Class *class);
static void gtk_file_system_win32_iface_init (GtkFileSystemIface *iface);
static void gtk_file_system_win32_init (GtkFileSystemWin32 *impl);
static void gtk_file_system_win32_finalize (GObject *object);
static GSList * gtk_file_system_win32_list_volumes (GtkFileSystem *file_system);
static GtkFileSystemVolume *gtk_file_system_win32_get_volume_for_path (GtkFileSystem *file_system,
const GtkFilePath *path);
static GtkFileFolder *gtk_file_system_win32_get_folder (GtkFileSystem *file_system,
static GtkFileSystemHandle *gtk_file_system_win32_get_folder (GtkFileSystem *file_system,
const GtkFilePath *path,
GtkFileInfoType types,
GError **error);
static gboolean gtk_file_system_win32_create_folder (GtkFileSystem *file_system,
const GtkFilePath *path,
GError **error);
GtkFileSystemGetFolderCallback callback,
gpointer data);
static GtkFileSystemHandle *gtk_file_system_win32_get_info (GtkFileSystem *file_system,
const GtkFilePath *path,
GtkFileInfoType types,
GtkFileSystemGetInfoCallback callback,
gpointer data);
static GtkFileSystemHandle *gtk_file_system_win32_create_folder (GtkFileSystem *file_system,
const GtkFilePath *path,
GtkFileSystemCreateFolderCallback callback,
gpointer data);
static void gtk_file_system_win32_cancel_operation (GtkFileSystemHandle *handle);
static void gtk_file_system_win32_volume_free (GtkFileSystem *file_system,
GtkFileSystemVolume *volume);
......@@ -116,16 +153,15 @@ static GtkFilePath *gtk_file_system_win32_volume_get_base_path (GtkFileSystem
GtkFileSystemVolume *volume);
static gboolean gtk_file_system_win32_volume_get_is_mounted (GtkFileSystem *file_system,
GtkFileSystemVolume *volume);
static gboolean gtk_file_system_win32_volume_mount (GtkFileSystem *file_system,
static GtkFileSystemHandle *gtk_file_system_win32_volume_mount (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GError **error);
GtkFileSystemVolumeMountCallback callback,
gpointer data);
static gchar * gtk_file_system_win32_volume_get_display_name (GtkFileSystem *file_system,
GtkFileSystemVolume *volume);
static GdkPixbuf * gtk_file_system_win32_volume_render_icon (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GtkWidget *widget,
gint pixel_size,
GError **error);
static gchar * gtk_file_system_win32_volume_get_icon_name (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GError **error);
static gboolean gtk_file_system_win32_get_parent (GtkFileSystem *file_system,
const GtkFilePath *path,
......@@ -149,11 +185,6 @@ 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_insert_bookmark (GtkFileSystem *file_system,
const GtkFilePath *path,
......@@ -162,28 +193,55 @@ static gboolean gtk_file_system_win32_insert_bookmark (GtkFileSystem
static gboolean gtk_file_system_win32_remove_bookmark (GtkFileSystem *file_system,
const GtkFilePath *path,
GError **error);
static GSList * gtk_file_system_win32_list_bookmarks (GtkFileSystem *file_system);
static GType gtk_file_folder_win32_get_type (void);
static void gtk_file_folder_win32_class_init (GtkFileFolderWin32Class *class);
static GSList *gtk_file_system_win32_list_bookmarks (GtkFileSystem *file_system);
static gchar *gtk_file_system_win32_get_bookmark_label (GtkFileSystem *file_system,
const GtkFilePath *path);
static void gtk_file_system_win32_set_bookmark_label (GtkFileSystem *file_system,
const GtkFilePath *path,
const gchar *label);
static void gtk_file_folder_win32_iface_init (GtkFileFolderIface *iface);
static void gtk_file_folder_win32_init (GtkFileFolderWin32 *impl);
static void gtk_file_folder_win32_finalize (GObject *object);
static GtkFileInfo * gtk_file_folder_win32_get_info (GtkFileFolder *folder,
static GtkFileInfo *gtk_file_folder_win32_get_info (GtkFileFolder *folder,
const GtkFilePath *path,
GError **error);
static gboolean gtk_file_folder_win32_list_children (GtkFileFolder *folder,
GSList **children,
GError **error);
static gchar * filename_from_path (const GtkFilePath *path);
static GtkFilePath * filename_to_path (const gchar *filename);
static gboolean gtk_file_folder_win32_is_finished_loading (GtkFileFolder *folder);
static gboolean filename_is_drive_root (const char *filename);
static gboolean filename_is_server_share (const char *filename);
static gboolean filename_is_some_root (const char *filename);
static GtkFileInfo * filename_get_info (const gchar *filename,
GtkFileInfoType types,
GError **error);
static GtkFilePath * filename_to_path (const gchar *filename);
static gboolean filename_is_root (const char *filename);
static gboolean filename_is_drive_root (const char *filename);
static gboolean filename_is_server_share (const char *filename);
static gboolean filename_is_some_root (const char *filename);
static gboolean stat_with_error (const char *filename,
WIN32_FILE_ATTRIBUTE_DATA *wfad,
GError **error);
static GtkFileInfo *create_file_info (GtkFileFolderWin32 *folder_win32,
const char *filename,
const char *basename,
GtkFileInfoType types,
WIN32_FILE_ATTRIBUTE_DATA *wfad,
const char *mime_type);
static gboolean fill_in_names (GtkFileFolderWin32 *folder_win32,
GError **error);
static void fill_in_stats (GtkFileFolderWin32 *folder_win32);
static void fill_in_mime_type (GtkFileFolderWin32 *folder_win32);
static gboolean cb_fill_in_stats (gpointer key,
gpointer value,
gpointer user_data);
static gboolean cb_fill_in_mime_type (gpointer key,
gpointer value,
gpointer user_data);
static char *get_parent_dir (const char *filename);
/* some info kept together for volumes */
struct _GtkFileSystemVolume
......@@ -195,43 +253,16 @@ struct _GtkFileSystemVolume
/*
* GtkFileSystemWin32
*/
GType
gtk_file_system_win32_get_type (void)
{
static GType file_system_win32_type = 0;
if (!file_system_win32_type)
{
static const GTypeInfo file_system_win32_info =
{
sizeof (GtkFileSystemWin32Class),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_file_system_win32_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkFileSystemWin32),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_file_system_win32_init,
};
static const GInterfaceInfo file_system_info =
{
(GInterfaceInitFunc) gtk_file_system_win32_iface_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
file_system_win32_type = g_type_register_static (G_TYPE_OBJECT,
I_("GtkFileSystemWin32"),
&file_system_win32_info, 0);
g_type_add_interface_static (file_system_win32_type,
GTK_TYPE_FILE_SYSTEM,
&file_system_info);
}
G_DEFINE_TYPE_WITH_CODE (GtkFileSystemWin32, gtk_file_system_win32, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_SYSTEM,
gtk_file_system_win32_iface_init));
return file_system_win32_type;
}
/*
* GtkFileFolderWin32
*/
G_DEFINE_TYPE_WITH_CODE (GtkFileFolderWin32, _gtk_file_folder_win32, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_FOLDER,
gtk_file_folder_win32_iface_init));
/**
* gtk_file_system_win32_new:
......@@ -253,8 +284,6 @@ gtk_file_system_win32_class_init (GtkFileSystemWin32Class *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
system_parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_file_system_win32_finalize;
}
......@@ -264,13 +293,15 @@ gtk_file_system_win32_iface_init (GtkFileSystemIface *iface)
iface->list_volumes = gtk_file_system_win32_list_volumes;
iface->get_volume_for_path = gtk_file_system_win32_get_volume_for_path;
iface->get_folder = gtk_file_system_win32_get_folder;
iface->get_info = gtk_file_system_win32_get_info;
iface->create_folder = gtk_file_system_win32_create_folder;
iface->cancel_operation = gtk_file_system_win32_cancel_operation;
iface->volume_free = gtk_file_system_win32_volume_free;
iface->volume_get_base_path = gtk_file_system_win32_volume_get_base_path;
iface->volume_get_is_mounted = gtk_file_system_win32_volume_get_is_mounted;
iface->volume_mount = gtk_file_system_win32_volume_mount;
iface->volume_get_display_name = gtk_file_system_win32_volume_get_display_name;
iface->volume_render_icon = gtk_file_system_win32_volume_render_icon;
iface->volume_get_icon_name = gtk_file_system_win32_volume_get_icon_name;
iface->get_parent = gtk_file_system_win32_get_parent;
iface->make_path = gtk_file_system_win32_make_path;
iface->parse = gtk_file_system_win32_parse;
......@@ -278,10 +309,11 @@ 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->insert_bookmark = gtk_file_system_win32_insert_bookmark;
iface->remove_bookmark = gtk_file_system_win32_remove_bookmark;
iface->list_bookmarks = gtk_file_system_win32_list_bookmarks;
iface->get_bookmark_label = gtk_file_system_win32_get_bookmark_label;
iface->set_bookmark_label = gtk_file_system_win32_set_bookmark_label;
}
static gboolean
......@@ -300,7 +332,9 @@ check_volumes (gpointer data)
static void
gtk_file_system_win32_init (GtkFileSystemWin32 *system_win32)
{
/* set up an idle handler for volume changes, every second should be enough */
/* Set up an idle handler for volume changes. Once a second should
* be enough.
*/
system_win32->timeout = g_timeout_add_full (0, 1000, check_volumes, system_win32, NULL);
system_win32->folder_hash = g_hash_table_new (g_str_hash, g_str_equal);
......@@ -318,7 +352,7 @@ gtk_file_system_win32_finalize (GObject *object)
/* FIXME: assert that the hash is empty? */
g_hash_table_destroy (system_win32->folder_hash);
system_parent_class->finalize (object);
G_OBJECT_CLASS (gtk_file_system_win32_parent_class)->finalize (object);
}
/* Lifted from GLib */
......@@ -338,18 +372,9 @@ get_special_folder (int csidl)
hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
if (hr == S_OK)
{
if (G_WIN32_HAVE_WIDECHAR_API ())
{
b = SHGetPathFromIDListW (pidl, path.wc);
if (b)
retval = g_utf16_to_utf8 (path.wc, -1, NULL, NULL, NULL);
}
else
{
b = SHGetPathFromIDListA (pidl, path.c);
if (b)
retval = g_locale_to_utf8 (path.c, -1, NULL, NULL, NULL);
}
b = SHGetPathFromIDListW (pidl, path.wc);
if (b)
retval = g_utf16_to_utf8 (path.wc, -1, NULL, NULL, NULL);
CoTaskMemFree (pidl);
}
return retval;
......@@ -426,288 +451,825 @@ gtk_file_system_win32_get_volume_for_path (GtkFileSystem *file_system,
vol->drive[0] = g_ascii_toupper (vol->drive[0]);
vol->drive_type = GetDriveType (vol->drive);
}
else if (G_WIN32_HAVE_WIDECHAR_API ())
else
{
wchar_t *wdrive = g_utf8_to_utf16 (vol->drive, -1, NULL, NULL, NULL);
vol->drive_type = GetDriveTypeW (wdrive);
g_free (wdrive);
}
else
{
gchar *cpdrive = g_locale_from_utf8 (vol->drive, -1, NULL, NULL, NULL);
vol->drive_type = GetDriveTypeA (cpdrive);
g_free (cpdrive);
}
}
return vol;
}
static GtkFileFolder *
gtk_file_system_win32_get_folder (GtkFileSystem *file_system,
const GtkFilePath *path,
GtkFileInfoType types,
GError **error)
static char *
remove_trailing_slash (const char *filename)
{
GtkFileSystemWin32 *system_win32;
GtkFileFolderWin32 *folder_win32;
gchar *filename;
int len;
system_win32 = GTK_FILE_SYSTEM_WIN32 (file_system);
len = strlen (filename);
filename = filename_from_path (path);
g_return_val_if_fail (filename != NULL, NULL);
if (len > 1 && filename[len - 1] == '/')
return g_strndup (filename, len - 1);
else
return g_memdup (filename, len + 1);
}
folder_win32 = g_hash_table_lookup (system_win32->folder_hash, filename);
/* Delay callback dispatching
*/
if (folder_win32)
return g_object_ref (folder_win32);
enum callback_types
{
CALLBACK_GET_INFO,
CALLBACK_GET_FOLDER,
CALLBACK_CREATE_FOLDER,
CALLBACK_VOLUME_MOUNT
};
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
{
gchar *display_filename = g_filename_display_name (filename);
g_set_error (error,
GTK_FILE_SYSTEM_ERROR,
GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
_("Error getting information for '%s': %s"),
display_filename,
g_strerror (ENOENT));
g_free (display_filename);
return NULL;
}
if (!g_file_test (filename, G_FILE_TEST_IS_DIR))
{
gchar *display_filename = g_filename_display_name (filename);
static void queue_callback (enum callback_types type, gpointer data);
g_set_error (error,
GTK_FILE_SYSTEM_ERROR,
GTK_FILE_SYSTEM_ERROR_NOT_FOLDER,
_("Error getting information for '%s': %s"),
display_filename,
g_strerror (ENOTDIR));
g_free (display_filename);
return NULL;
}
struct get_info_callback
{
GtkFileSystemGetInfoCallback callback;
GtkFileSystemHandle *handle;
GtkFileInfo *file_info;
GError *error;
gpointer data;
};
static inline void
dispatch_get_info_callback (struct get_info_callback *info)
{
(* info->callback) (info->handle, info->file_info, info->error, info->data);
if (info->file_info)
gtk_file_info_free (info->file_info);
folder_win32 = g_object_new (GTK_TYPE_FILE_FOLDER_WIN32, NULL);
folder_win32->system_win32 = system_win32;
folder_win32->filename = filename;
folder_win32->types = types;
if (info->error)
g_error_free (info->error);
g_hash_table_insert (system_win32->folder_hash, folder_win32->filename, folder_win32);
g_object_unref (info->handle);
return GTK_FILE_FOLDER (folder_win32);
g_free (info);
}
static gboolean
gtk_file_system_win32_create_folder (GtkFileSystem *file_system,
const GtkFilePath *path,
GError **error)
static inline void
queue_get_info_callback (GtkFileSystemGetInfoCallback callback,
GtkFileSystemHandle *handle,
GtkFileInfo *file_info,
GError *error,
gpointer data)
{
GtkFileSystemWin32 *system_win32;
gchar *filename;
gboolean result;
char *parent;
struct get_info_callback *info;
system_win32 = GTK_FILE_SYSTEM_WIN32 (file_system);
info = g_new (struct get_info_callback, 1);
info->callback = callback;
info->handle = handle;
info->file_info = file_info;
info->error = error;
info->data = data;
filename = filename_from_path (path);
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (g_path_is_absolute (filename), FALSE);
queue_callback (CALLBACK_GET_INFO, info);
}
result = g_mkdir (filename, 0777) == 0;
if (!result)
{
int save_errno = errno;
gchar *display_filename = g_filename_display_name (filename);
g_set_error (error,
GTK_FILE_SYSTEM_ERROR,
GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
_("Error creating directory '%s': %s"),
display_filename,
g_strerror (save_errno));
g_free (display_filename);
}
else if (!filename_is_some_root (filename))
{
parent = g_path_get_dirname (filename);
if (parent)
{
GtkFileFolderWin32 *folder_win32;
struct get_folder_callback
{
GtkFileSystemGetFolderCallback callback;
GtkFileSystemHandle *handle;
GtkFileFolder *folder;
GError *error;
gpointer data;
};
folder_win32 = g_hash_table_lookup (system_win32->folder_hash, parent);
if (folder_win32)
{
GSList *paths;
static inline void
dispatch_get_folder_callback (struct get_folder_callback *info)
{
(* info->callback) (info->handle, info->folder, info->error, info->data);
paths = g_slist_append (NULL, (GtkFilePath *) path);
g_signal_emit_by_name (folder_win32, "files-added", paths);
g_slist_free (paths);
}
g_free(parent);
}
}
if (info->error)
g_error_free (info->error);
g_free (filename);
g_object_unref (info->handle);
return result;
g_free (info);
}
static void
gtk_file_system_win32_volume_free (GtkFileSystem *file_system,
GtkFileSystemVolume *volume)
static inline void
queue_get_folder_callback (GtkFileSystemGetFolderCallback callback,
GtkFileSystemHandle *handle,
GtkFileFolder *folder,
GError *error,
gpointer data)
{
g_free (volume->drive);
g_free (volume);
struct get_folder_callback *info;
info = g_new (struct get_folder_callback, 1);
info->callback = callback;
info->handle = handle;
info->folder = folder;
info->error = error;
info->data = data;
queue_callback (CALLBACK_GET_FOLDER, info);
}
static GtkFilePath *
gtk_file_system_win32_volume_get_base_path (GtkFileSystem *file_system,
GtkFileSystemVolume *volume)
struct create_folder_callback
{
return (GtkFilePath *) g_strdup (volume->drive);
GtkFileSystemCreateFolderCallback callback;
GtkFileSystemHandle *handle;
GtkFilePath *path;
GError *error;
gpointer data;
};
static inline void
dispatch_create_folder_callback (struct create_folder_callback *info)
{
(* info->callback) (info->handle, info->path, info->error, info->data);
if (info->error)
g_error_free (info->error);
if (info->path)
gtk_file_path_free (info->path);
g_object_unref (info->handle);
g_free (info);
}
static gboolean
gtk_file_system_win32_volume_get_is_mounted (GtkFileSystem *file_system,
GtkFileSystemVolume *volume)
static inline void
queue_create_folder_callback (GtkFileSystemCreateFolderCallback callback,
GtkFileSystemHandle *handle,
const GtkFilePath *path,
GError *error,
gpointer data)
{
return TRUE;
struct create_folder_callback *info;
info = g_new (struct create_folder_callback, 1);
info->callback = callback;
info->handle = handle;
info->path = gtk_file_path_copy (path);
info->error = error;
info->data = data;
queue_callback (CALLBACK_CREATE_FOLDER, info);
}
static gboolean
gtk_file_system_win32_volume_mount (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GError **error)
struct volume_mount_callback
{
g_set_error (error,
GTK_FILE_SYSTEM_ERROR,
GTK_FILE_SYSTEM_ERROR_FAILED,
_("This file system does not support mounting"));
return FALSE;
GtkFileSystemVolumeMountCallback callback;
GtkFileSystemHandle *handle;
GtkFileSystemVolume *volume;
GError *error;
gpointer data;
};
static inline void
dispatch_volume_mount_callback (struct volume_mount_callback *info)
{
(* info->callback) (info->handle, info->volume, info->error, info->data);
if (info->error)
g_error_free (info->error);
g_object_unref (info->handle);
g_free (info);
}
static gchar *
gtk_file_system_win32_volume_get_display_name (GtkFileSystem *file_system,
GtkFileSystemVolume *volume)
static inline void
queue_volume_mount_callback (GtkFileSystemVolumeMountCallback callback,
GtkFileSystemHandle *handle,
GtkFileSystemVolume *volume,
GError *error,
gpointer data)
{
gchar *real_display_name;
struct volume_mount_callback *info;
g_return_val_if_fail (volume->drive != NULL, NULL);
info = g_new (struct volume_mount_callback, 1);
info->callback = callback;
info->handle = handle;
info->volume = volume;
info->error = error;
info->data = data;
if (filename_is_drive_root (volume->drive) &&
volume->drive_type == DRIVE_REMOTE)
real_display_name = g_strdup_printf (_("Network Drive (%s)"), volume->drive);
else if ((filename_is_drive_root (volume->drive) && volume->drive[0] >= 'C') ||
volume->drive_type != DRIVE_REMOVABLE)
queue_callback (CALLBACK_VOLUME_MOUNT, info);
}
struct callback_info
{
enum callback_types type;
union
{
struct get_info_callback *get_info;
struct get_folder_callback *get_folder;
struct create_folder_callback *create_folder;
struct volume_mount_callback *volume_mount;
} info;
};
static guint execute_callbacks_idle_id = 0;
static GSList *callbacks = NULL;
static gboolean
execute_callbacks_idle (gpointer data)
{
GSList *l;
GDK_THREADS_ENTER ();
for (l = callbacks; l; l = l->next)
{
gchar *name = NULL;
if (G_WIN32_HAVE_WIDECHAR_API ())
{
gunichar2 *wdrive = g_utf8_to_utf16 (volume->drive, -1, NULL, NULL, NULL);
gunichar2 wname[80];
if (GetVolumeInformationW (wdrive,