GSettings: small internal refactor
[glib.git] / gio / gwin32mount.c
blob39931efaa580f4fd125a2e3dccecb5bc62a7a4f8
1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 * Copyright (C) 2008 Hans Breuer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Author: Alexander Larsson <alexl@redhat.com>
22 * David Zeuthen <davidz@redhat.com>
23 * Hans Breuer <hans@breuer.org>
26 #include "config.h"
28 #include <string.h>
29 #define WIN32_MEAN_AND_LEAN
30 #include <windows.h>
32 #include <glib.h>
33 #include "gwin32volumemonitor.h"
34 #include "gwin32mount.h"
35 #include "gmount.h"
36 #include "gfile.h"
37 #include "gmountprivate.h"
38 #include "gvolumemonitor.h"
39 #include "gthemedicon.h"
40 #include "gsimpleasyncresult.h"
41 #include "glibintl.h"
44 struct _GWin32Mount {
45 GObject parent;
47 GVolumeMonitor *volume_monitor;
49 GWin32Volume *volume; /* owned by volume monitor */
50 int drive_type;
52 /* why does all this stuff need to be duplicated? It is in volume already! */
53 char *name;
54 GIcon *icon;
55 GIcon *symbolic_icon;
56 char *mount_path;
58 gboolean can_eject;
61 static void g_win32_mount_mount_iface_init (GMountIface *iface);
63 #define g_win32_mount_get_type _g_win32_mount_get_type
64 G_DEFINE_TYPE_WITH_CODE (GWin32Mount, g_win32_mount, G_TYPE_OBJECT,
65 G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
66 g_win32_mount_mount_iface_init))
69 static void
70 g_win32_mount_finalize (GObject *object)
72 GWin32Mount *mount;
74 mount = G_WIN32_MOUNT (object);
76 if (mount->volume_monitor != NULL)
77 g_object_unref (mount->volume_monitor);
78 #if 0
79 if (mount->volume)
80 _g_win32_volume_unset_mount (mount->volume, mount);
81 #endif
82 /* TODO: g_warn_if_fail (volume->volume == NULL); */
84 if (mount->icon != NULL)
85 g_object_unref (mount->icon);
86 if (mount->symbolic_icon != NULL)
87 g_object_unref (mount->symbolic_icon);
89 g_free (mount->name);
90 g_free (mount->mount_path);
92 if (G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize)
93 (*G_OBJECT_CLASS (g_win32_mount_parent_class)->finalize) (object);
96 static void
97 g_win32_mount_class_init (GWin32MountClass *klass)
99 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
101 gobject_class->finalize = g_win32_mount_finalize;
104 static void
105 g_win32_mount_init (GWin32Mount *win32_mount)
109 static gchar *
110 _win32_get_displayname (const char *drive)
112 gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);
113 gchar *name = NULL;
114 SHFILEINFOW sfi;
115 if (SHGetFileInfoW(wdrive, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME))
116 name = g_utf16_to_utf8 (sfi.szDisplayName, -1, NULL, NULL, NULL);
118 g_free (wdrive);
119 return name ? name : g_strdup (drive);
123 * _g_win32_mount_new:
124 * @volume_monitor: a #GVolumeMonitor.
125 * @path: a win32 path.
126 * @volume: usually NULL
128 * Returns: a #GWin32Mount for the given win32 path.
130 GWin32Mount *
131 _g_win32_mount_new (GVolumeMonitor *volume_monitor,
132 const char *path,
133 GWin32Volume *volume)
135 GWin32Mount *mount;
136 const gchar *drive = path; //fixme
138 #if 0
139 /* No volume for mount: Ignore internal things */
140 if (volume == NULL && !g_win32_mount_guess_should_display (mount_entry))
141 return NULL;
142 #endif
144 mount = g_object_new (G_TYPE_WIN32_MOUNT, NULL);
145 mount->volume_monitor = volume_monitor != NULL ? g_object_ref (volume_monitor) : NULL;
146 mount->mount_path = g_strdup (path);
147 mount->drive_type = GetDriveType (drive);
148 mount->can_eject = FALSE; /* TODO */
149 mount->name = _win32_get_displayname (drive);
151 /* need to do this last */
152 mount->volume = volume;
153 #if 0
154 if (volume != NULL)
155 _g_win32_volume_set_mount (volume, mount);
156 #endif
157 return mount;
160 void
161 _g_win32_mount_unmounted (GWin32Mount *mount)
163 if (mount->volume != NULL)
165 #if 0
166 _g_win32_volume_unset_mount (mount->volume, mount);
167 #endif
168 mount->volume = NULL;
169 g_signal_emit_by_name (mount, "changed");
170 /* there's really no need to emit mount_changed on the volume monitor
171 * as we're going to be deleted.. */
175 void
176 _g_win32_mount_unset_volume (GWin32Mount *mount,
177 GWin32Volume *volume)
179 if (mount->volume == volume)
181 mount->volume = NULL;
182 /* TODO: Emit changed in idle to avoid locking issues */
183 g_signal_emit_by_name (mount, "changed");
184 if (mount->volume_monitor != NULL)
185 g_signal_emit_by_name (mount->volume_monitor, "mount-changed", mount);
189 static GFile *
190 g_win32_mount_get_root (GMount *mount)
192 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
194 return g_file_new_for_path (win32_mount->mount_path);
197 static const char *
198 _win32_drive_type_to_icon (int type, gboolean use_symbolic)
200 switch (type)
202 case DRIVE_REMOVABLE : return use_symbolic ? "drive-removable-media-symbolic" : "drive-removable-media";
203 case DRIVE_FIXED : return use_symbolic ? "drive-harddisk-symbolic" : "drive-harddisk";
204 case DRIVE_REMOTE : return use_symbolic ? "folder-remote-symbolic" : "folder-remote";
205 case DRIVE_CDROM : return use_symbolic ? "drive-optical-symbolic" : "drive-optical";
206 default : return use_symbolic ? "folder-symbolic" : "folder";
210 static GIcon *
211 g_win32_mount_get_icon (GMount *mount)
213 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
215 g_return_val_if_fail (win32_mount->mount_path != NULL, NULL);
217 /* lazy creation */
218 if (!win32_mount->icon)
220 SHFILEINFOW shfi;
221 wchar_t *wfn = g_utf8_to_utf16 (win32_mount->mount_path, -1, NULL, NULL, NULL);
223 if (SHGetFileInfoW (wfn, 0, &shfi, sizeof (shfi), SHGFI_ICONLOCATION))
225 gchar *name = g_utf16_to_utf8 (shfi.szDisplayName, -1, NULL, NULL, NULL);
226 gchar *id = g_strdup_printf ("%s,%i", name, shfi.iIcon);
227 win32_mount->icon = g_themed_icon_new (id);
228 g_free (name);
229 g_free (id);
231 else
233 win32_mount->icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, FALSE));
237 return g_object_ref (win32_mount->icon);
240 static GIcon *
241 g_win32_mount_get_symbolic_icon (GMount *mount)
243 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
245 g_return_val_if_fail (win32_mount->mount_path != NULL, NULL);
247 /* lazy creation */
248 if (!win32_mount->symbolic_icon)
250 win32_mount->symbolic_icon = g_themed_icon_new_with_default_fallbacks (_win32_drive_type_to_icon (win32_mount->drive_type, TRUE));
253 return g_object_ref (win32_mount->symbolic_icon);
256 static char *
257 g_win32_mount_get_uuid (GMount *mount)
259 return NULL;
262 static char *
263 g_win32_mount_get_name (GMount *mount)
265 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
267 return g_strdup (win32_mount->name);
270 static GDrive *
271 g_win32_mount_get_drive (GMount *mount)
273 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
275 if (win32_mount->volume != NULL)
276 return g_volume_get_drive (G_VOLUME (win32_mount->volume));
278 return NULL;
281 static GVolume *
282 g_win32_mount_get_volume (GMount *mount)
284 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
286 if (win32_mount->volume)
287 return G_VOLUME (g_object_ref (win32_mount->volume));
289 return NULL;
292 static gboolean
293 g_win32_mount_can_unmount (GMount *mount)
295 return FALSE;
298 static gboolean
299 g_win32_mount_can_eject (GMount *mount)
301 GWin32Mount *win32_mount = G_WIN32_MOUNT (mount);
302 return win32_mount->can_eject;
306 typedef struct {
307 GWin32Mount *win32_mount;
308 GAsyncReadyCallback callback;
309 gpointer user_data;
310 GCancellable *cancellable;
311 int error_fd;
312 GIOChannel *error_channel;
313 guint error_channel_source_id;
314 GString *error_string;
315 } UnmountEjectOp;
317 static void
318 g_win32_mount_unmount (GMount *mount,
319 GMountUnmountFlags flags,
320 GCancellable *cancellable,
321 GAsyncReadyCallback callback,
322 gpointer user_data)
326 static gboolean
327 g_win32_mount_unmount_finish (GMount *mount,
328 GAsyncResult *result,
329 GError **error)
331 return FALSE;
334 static void
335 g_win32_mount_eject (GMount *mount,
336 GMountUnmountFlags flags,
337 GCancellable *cancellable,
338 GAsyncReadyCallback callback,
339 gpointer user_data)
343 static gboolean
344 g_win32_mount_eject_finish (GMount *mount,
345 GAsyncResult *result,
346 GError **error)
348 return FALSE;
351 static void
352 g_win32_mount_mount_iface_init (GMountIface *iface)
354 iface->get_root = g_win32_mount_get_root;
355 iface->get_name = g_win32_mount_get_name;
356 iface->get_icon = g_win32_mount_get_icon;
357 iface->get_symbolic_icon = g_win32_mount_get_symbolic_icon;
358 iface->get_uuid = g_win32_mount_get_uuid;
359 iface->get_drive = g_win32_mount_get_drive;
360 iface->get_volume = g_win32_mount_get_volume;
361 iface->can_unmount = g_win32_mount_can_unmount;
362 iface->can_eject = g_win32_mount_can_eject;
363 iface->unmount = g_win32_mount_unmount;
364 iface->unmount_finish = g_win32_mount_unmount_finish;
365 iface->eject = g_win32_mount_eject;
366 iface->eject_finish = g_win32_mount_eject_finish;