Add "default location" support to GMount
[platform/upstream/glib.git] / gio / gmount.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* GIO - GLib Input, Output and Streaming Library
4  * 
5  * Copyright (C) 2006-2008 Red Hat, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Author: Alexander Larsson <alexl@redhat.com>
23  *         David Zeuthen <davidz@redhat.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include "gmount.h"
31 #include "gmountprivate.h"
32 #include "gasyncresult.h"
33 #include "gsimpleasyncresult.h"
34 #include "gioerror.h"
35 #include "glibintl.h"
36
37 #include "gioalias.h"
38
39 /**
40  * SECTION:gmount
41  * @short_description: Mount management
42  * @include: gio/gio.h
43  * @see also: GVolume, GUnixMount
44  *
45  * The #GMount interface represents user-visible mounts. Note, when 
46  * porting from GnomeVFS, #GMount is the moral equivalent of #GnomeVFSVolume.
47  *
48  * #GMount is a "mounted" filesystem that you can access. Mounted is in
49  * quotes because it's not the same as a unix mount, it might be a gvfs
50  * mount, but you can still access the files on it if you use GIO. Might or
51  * might not be related to a volume object.
52  * 
53  * Unmounting a #GMount instance is an asynchronous operation. For
54  * more information about asynchronous operations, see #GAsyncReady
55  * and #GSimpleAsyncReady. To unmount a #GMount instance, first call
56  * g_mount_unmount_with_operation() with (at least) the #GMount instance and a
57  * #GAsyncReadyCallback.  The callback will be fired when the
58  * operation has resolved (either with success or failure), and a
59  * #GAsyncReady structure will be passed to the callback.  That
60  * callback should then call g_mount_unmount_with_operation_finish() with the #GMount
61  * and the #GAsyncReady data to see if the operation was completed
62  * successfully.  If an @error is present when g_mount_unmount_with_operation_finish() 
63  * is called, then it will be filled with any error information.
64  **/
65
66 static void g_mount_base_init (gpointer g_class);
67 static void g_mount_class_init (gpointer g_class,
68                                 gpointer class_data);
69
70 GType
71 g_mount_get_type (void)
72 {
73   static volatile gsize g_define_type_id__volatile = 0;
74
75   if (g_once_init_enter (&g_define_type_id__volatile))
76     {
77       const GTypeInfo mount_info =
78       {
79         sizeof (GMountIface), /* class_size */
80         g_mount_base_init,   /* base_init */
81         NULL,           /* base_finalize */
82         g_mount_class_init,
83         NULL,           /* class_finalize */
84         NULL,           /* class_data */
85         0,
86         0,              /* n_preallocs */
87         NULL
88       };
89       GType g_define_type_id =
90         g_type_register_static (G_TYPE_INTERFACE, I_("GMount"),
91                                 &mount_info, 0);
92
93       g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
94
95       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
96     }
97
98   return g_define_type_id__volatile;
99 }
100
101 static void
102 g_mount_class_init (gpointer g_class,
103                     gpointer class_data)
104 {
105 }
106
107 static void
108 g_mount_base_init (gpointer g_class)
109 {
110   static gboolean initialized = FALSE;
111
112   if (! initialized)
113     {
114      /**
115       * GMount::changed:
116       * @mount: the object on which the signal is emitted
117       * 
118       * Emitted when the mount has been changed.
119       **/
120       g_signal_new (I_("changed"),
121                     G_TYPE_MOUNT,
122                     G_SIGNAL_RUN_LAST,
123                     G_STRUCT_OFFSET (GMountIface, changed),
124                     NULL, NULL,
125                     g_cclosure_marshal_VOID__VOID,
126                     G_TYPE_NONE, 0);
127
128      /**
129       * GMount::unmounted:
130       * @mount: the object on which the signal is emitted
131       * 
132       * This signal is emitted when the #GMount have been
133       * unmounted. If the recipient is holding references to the
134       * object they should release them so the object can be
135       * finalized.
136       **/
137       g_signal_new (I_("unmounted"),
138                     G_TYPE_MOUNT,
139                     G_SIGNAL_RUN_LAST,
140                     G_STRUCT_OFFSET (GMountIface, unmounted),
141                     NULL, NULL,
142                     g_cclosure_marshal_VOID__VOID,
143                     G_TYPE_NONE, 0);
144      /**
145       * GMount::pre-unmount:
146       * @mount: the object on which the signal is emitted
147       *
148       * This signal is emitted when the #GMount is about to be
149       * unmounted.
150       *
151       * Since: 2.22
152       **/
153       g_signal_new (I_("pre-unmount"),
154                     G_TYPE_MOUNT,
155                     G_SIGNAL_RUN_LAST,
156                     G_STRUCT_OFFSET (GMountIface, pre_unmount),
157                     NULL, NULL,
158                     g_cclosure_marshal_VOID__VOID,
159                     G_TYPE_NONE, 0);
160
161       initialized = TRUE;
162     }
163 }
164
165 /**
166  * g_mount_get_root:
167  * @mount: a #GMount.
168  * 
169  * Gets the root directory on @mount.
170  * 
171  * Returns: a #GFile. 
172  *      The returned object should be unreffed with 
173  *      g_object_unref() when no longer needed.
174  **/
175 GFile *
176 g_mount_get_root (GMount *mount)
177 {
178   GMountIface *iface;
179
180   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
181
182   iface = G_MOUNT_GET_IFACE (mount);
183
184   return (* iface->get_root) (mount);
185 }
186
187 /**
188  * g_mount_get_default_location:
189  * @mount: a #GMount.
190  *
191  * Gets the default location of @mount. The default location of the given
192  * @mount is a path that reflects the main entry point for the user (e.g.
193  * the home directory, or the root of the volume).
194  *
195  * Returns: a #GFile.
196  *      The returned object should be unreffed with
197  *      g_object_unref() when no longer needed.
198  **/
199 GFile *
200 g_mount_get_default_location (GMount *mount)
201 {
202   GMountIface *iface;
203   GFile       *file;
204
205   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
206
207   iface = G_MOUNT_GET_IFACE (mount);
208   
209   /* Fallback to get_root when default_location () is not available */
210   if (iface->get_default_location)
211     file = (* iface->get_default_location) (mount);
212   else
213     file = (* iface->get_root) (mount);
214
215   return file;
216 }
217
218 /**
219  * g_mount_get_name:
220  * @mount: a #GMount.
221  * 
222  * Gets the name of @mount.
223  * 
224  * Returns: the name for the given @mount. 
225  *     The returned string should be freed with g_free()
226  *     when no longer needed.
227  **/
228 char *
229 g_mount_get_name (GMount *mount)
230 {
231   GMountIface *iface;
232
233   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
234
235   iface = G_MOUNT_GET_IFACE (mount);
236
237   return (* iface->get_name) (mount);
238 }
239
240 /**
241  * g_mount_get_icon:
242  * @mount: a #GMount.
243  * 
244  * Gets the icon for @mount.
245  * 
246  * Returns: a #GIcon.
247  *      The returned object should be unreffed with 
248  *      g_object_unref() when no longer needed.
249  **/
250 GIcon *
251 g_mount_get_icon (GMount *mount)
252 {
253   GMountIface *iface;
254
255   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
256
257   iface = G_MOUNT_GET_IFACE (mount);
258
259   return (* iface->get_icon) (mount);
260 }
261
262 /**
263  * g_mount_get_uuid:
264  * @mount: a #GMount.
265  * 
266  * Gets the UUID for the @mount. The reference is typically based on
267  * the file system UUID for the mount in question and should be
268  * considered an opaque string. Returns %NULL if there is no UUID
269  * available.
270  * 
271  * Returns: the UUID for @mount or %NULL if no UUID can be computed.
272  *     The returned string should be freed with g_free()
273  *     when no longer needed.
274  **/
275 char *
276 g_mount_get_uuid (GMount *mount)
277 {
278   GMountIface *iface;
279
280   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
281
282   iface = G_MOUNT_GET_IFACE (mount);
283
284   return (* iface->get_uuid) (mount);
285 }
286
287 /**
288  * g_mount_get_volume:
289  * @mount: a #GMount.
290  * 
291  * Gets the volume for the @mount.
292  * 
293  * Returns: a #GVolume or %NULL if @mount is not associated with a volume.
294  *      The returned object should be unreffed with 
295  *      g_object_unref() when no longer needed.
296  **/
297 GVolume *
298 g_mount_get_volume (GMount *mount)
299 {
300   GMountIface *iface;
301
302   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
303
304   iface = G_MOUNT_GET_IFACE (mount);
305
306   return (* iface->get_volume) (mount);
307 }
308
309 /**
310  * g_mount_get_drive:
311  * @mount: a #GMount.
312  * 
313  * Gets the drive for the @mount.
314  *
315  * This is a convenience method for getting the #GVolume and then
316  * using that object to get the #GDrive.
317  * 
318  * Returns: a #GDrive or %NULL if @mount is not associated with a volume or a drive.
319  *      The returned object should be unreffed with 
320  *      g_object_unref() when no longer needed.
321  **/
322 GDrive *
323 g_mount_get_drive (GMount *mount)
324 {
325   GMountIface *iface;
326
327   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
328
329   iface = G_MOUNT_GET_IFACE (mount);
330
331   return (* iface->get_drive) (mount);
332 }
333
334 /**
335  * g_mount_can_unmount: 
336  * @mount: a #GMount.
337  * 
338  * Checks if @mount can be mounted.
339  * 
340  * Returns: %TRUE if the @mount can be unmounted.
341  **/
342 gboolean
343 g_mount_can_unmount (GMount *mount)
344 {
345   GMountIface *iface;
346
347   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
348
349   iface = G_MOUNT_GET_IFACE (mount);
350
351   return (* iface->can_unmount) (mount);
352 }
353
354 /**
355  * g_mount_can_eject: 
356  * @mount: a #GMount.
357  * 
358  * Checks if @mount can be eject.
359  * 
360  * Returns: %TRUE if the @mount can be ejected.
361  **/
362 gboolean
363 g_mount_can_eject (GMount *mount)
364 {
365   GMountIface *iface;
366
367   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
368
369   iface = G_MOUNT_GET_IFACE (mount);
370
371   return (* iface->can_eject) (mount);
372 }
373
374 /**
375  * g_mount_unmount:
376  * @mount: a #GMount.
377  * @flags: flags affecting the operation
378  * @cancellable: optional #GCancellable object, %NULL to ignore.
379  * @callback: a #GAsyncReadyCallback, or %NULL.
380  * @user_data: user data passed to @callback.
381  * 
382  * Unmounts a mount. This is an asynchronous operation, and is 
383  * finished by calling g_mount_unmount_finish() with the @mount 
384  * and #GAsyncResult data returned in the @callback.
385  *
386  * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead.
387  **/
388 void
389 g_mount_unmount (GMount              *mount,
390                  GMountUnmountFlags   flags,
391                  GCancellable        *cancellable,
392                  GAsyncReadyCallback  callback,
393                  gpointer             user_data)
394 {
395   GMountIface *iface;
396
397   g_return_if_fail (G_IS_MOUNT (mount));
398   
399   iface = G_MOUNT_GET_IFACE (mount);
400
401   if (iface->unmount == NULL)
402     {
403       g_simple_async_report_error_in_idle (G_OBJECT (mount),
404                                            callback, user_data,
405                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
406                                            /* Translators: This is an error
407                                             * message for mount objects that
408                                             * don't implement unmount. */
409                                            _("mount doesn't implement unmount"));
410
411       return;
412     }
413   
414   (* iface->unmount) (mount, flags, cancellable, callback, user_data);
415 }
416
417 /**
418  * g_mount_unmount_finish:
419  * @mount: a #GMount.
420  * @result: a #GAsyncResult.
421  * @error: a #GError location to store the error occuring, or %NULL to 
422  *     ignore.
423  * 
424  * Finishes unmounting a mount. If any errors occurred during the operation, 
425  * @error will be set to contain the errors and %FALSE will be returned.
426  * 
427  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
428  *
429  * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead.
430  **/
431 gboolean
432 g_mount_unmount_finish (GMount        *mount,
433                         GAsyncResult  *result,
434                         GError       **error)
435 {
436   GMountIface *iface;
437
438   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
439   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
440
441   if (G_IS_SIMPLE_ASYNC_RESULT (result))
442     {
443       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
444       if (g_simple_async_result_propagate_error (simple, error))
445         return FALSE;
446     }
447   
448   iface = G_MOUNT_GET_IFACE (mount);
449   return (* iface->unmount_finish) (mount, result, error);
450 }
451
452
453 /**
454  * g_mount_eject:
455  * @mount: a #GMount.
456  * @flags: flags affecting the unmount if required for eject
457  * @cancellable: optional #GCancellable object, %NULL to ignore.
458  * @callback: a #GAsyncReadyCallback, or %NULL.
459  * @user_data: user data passed to @callback.
460  * 
461  * Ejects a mount. This is an asynchronous operation, and is 
462  * finished by calling g_mount_eject_finish() with the @mount 
463  * and #GAsyncResult data returned in the @callback.
464  *
465  * Deprecated: 2.22: Use g_mount_eject_with_operation() instead.
466  **/
467 void
468 g_mount_eject (GMount              *mount,
469                GMountUnmountFlags   flags,
470                GCancellable        *cancellable,
471                GAsyncReadyCallback  callback,
472                gpointer             user_data)
473 {
474   GMountIface *iface;
475
476   g_return_if_fail (G_IS_MOUNT (mount));
477   
478   iface = G_MOUNT_GET_IFACE (mount);
479
480   if (iface->eject == NULL)
481     {
482       g_simple_async_report_error_in_idle (G_OBJECT (mount),
483                                            callback, user_data,
484                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
485                                            /* Translators: This is an error
486                                             * message for mount objects that
487                                             * don't implement eject. */
488                                            _("mount doesn't implement eject"));
489       
490       return;
491     }
492   
493   (* iface->eject) (mount, flags, cancellable, callback, user_data);
494 }
495
496 /**
497  * g_mount_eject_finish:
498  * @mount: a #GMount.
499  * @result: a #GAsyncResult.
500  * @error: a #GError location to store the error occuring, or %NULL to 
501  *     ignore.
502  * 
503  * Finishes ejecting a mount. If any errors occurred during the operation, 
504  * @error will be set to contain the errors and %FALSE will be returned.
505  * 
506  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
507  *
508  * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead.
509  **/
510 gboolean
511 g_mount_eject_finish (GMount        *mount,
512                       GAsyncResult  *result,
513                       GError       **error)
514 {
515   GMountIface *iface;
516
517   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
518   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
519
520   if (G_IS_SIMPLE_ASYNC_RESULT (result))
521     {
522       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
523       if (g_simple_async_result_propagate_error (simple, error))
524         return FALSE;
525     }
526   
527   iface = G_MOUNT_GET_IFACE (mount);
528   return (* iface->eject_finish) (mount, result, error);
529 }
530
531 /**
532  * g_mount_unmount_with_operation:
533  * @mount: a #GMount.
534  * @flags: flags affecting the operation
535  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
536  * @cancellable: optional #GCancellable object, %NULL to ignore.
537  * @callback: a #GAsyncReadyCallback, or %NULL.
538  * @user_data: user data passed to @callback.
539  *
540  * Unmounts a mount. This is an asynchronous operation, and is
541  * finished by calling g_mount_unmount_with_operation_finish() with the @mount 
542  * and #GAsyncResult data returned in the @callback.
543  *
544  * Since: 2.22
545  **/
546 void
547 g_mount_unmount_with_operation (GMount              *mount,
548                                 GMountUnmountFlags   flags,
549                                 GMountOperation     *mount_operation,
550                                 GCancellable        *cancellable,
551                                 GAsyncReadyCallback  callback,
552                                 gpointer             user_data)
553 {
554   GMountIface *iface;
555
556   g_return_if_fail (G_IS_MOUNT (mount));
557
558   iface = G_MOUNT_GET_IFACE (mount);
559
560   if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
561     {
562       g_simple_async_report_error_in_idle (G_OBJECT (mount),
563                                            callback, user_data,
564                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
565                                            /* Translators: This is an error
566                                             * message for mount objects that
567                                             * don't implement any of unmount or unmount_with_operation. */
568                                            _("mount doesn't implement unmount or unmount_with_operation"));
569
570       return;
571     }
572
573   if (iface->unmount_with_operation != NULL)
574     (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
575   else
576     (* iface->unmount) (mount, flags, cancellable, callback, user_data);
577 }
578
579 /**
580  * g_mount_unmount_with_operation_finish:
581  * @mount: a #GMount.
582  * @result: a #GAsyncResult.
583  * @error: a #GError location to store the error occuring, or %NULL to
584  *     ignore.
585  *
586  * Finishes unmounting a mount. If any errors occurred during the operation,
587  * @error will be set to contain the errors and %FALSE will be returned.
588  *
589  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
590  *
591  * Since: 2.22
592  **/
593 gboolean
594 g_mount_unmount_with_operation_finish (GMount        *mount,
595                                        GAsyncResult  *result,
596                                        GError       **error)
597 {
598   GMountIface *iface;
599
600   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
601   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
602
603   if (G_IS_SIMPLE_ASYNC_RESULT (result))
604     {
605       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
606       if (g_simple_async_result_propagate_error (simple, error))
607         return FALSE;
608     }
609
610   iface = G_MOUNT_GET_IFACE (mount);
611   if (iface->unmount_with_operation_finish != NULL)
612     return (* iface->unmount_with_operation_finish) (mount, result, error);
613   else
614     return (* iface->unmount_finish) (mount, result, error);
615 }
616
617
618 /**
619  * g_mount_eject_with_operation:
620  * @mount: a #GMount.
621  * @flags: flags affecting the unmount if required for eject
622  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
623  * @cancellable: optional #GCancellable object, %NULL to ignore.
624  * @callback: a #GAsyncReadyCallback, or %NULL.
625  * @user_data: user data passed to @callback.
626  *
627  * Ejects a mount. This is an asynchronous operation, and is
628  * finished by calling g_mount_eject_with_operation_finish() with the @mount
629  * and #GAsyncResult data returned in the @callback.
630  *
631  * Since: 2.22
632  **/
633 void
634 g_mount_eject_with_operation (GMount              *mount,
635                               GMountUnmountFlags   flags,
636                               GMountOperation     *mount_operation,
637                               GCancellable        *cancellable,
638                               GAsyncReadyCallback  callback,
639                               gpointer             user_data)
640 {
641   GMountIface *iface;
642
643   g_return_if_fail (G_IS_MOUNT (mount));
644
645   iface = G_MOUNT_GET_IFACE (mount);
646
647   if (iface->eject == NULL && iface->eject_with_operation == NULL)
648     {
649       g_simple_async_report_error_in_idle (G_OBJECT (mount),
650                                            callback, user_data,
651                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
652                                            /* Translators: This is an error
653                                             * message for mount objects that
654                                             * don't implement any of eject or eject_with_operation. */
655                                            _("mount doesn't implement eject or eject_with_operation"));
656       return;
657     }
658
659   if (iface->eject_with_operation != NULL)
660     (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
661   else
662     (* iface->eject) (mount, flags, cancellable, callback, user_data);
663 }
664
665 /**
666  * g_mount_eject_with_operation_finish:
667  * @mount: a #GMount.
668  * @result: a #GAsyncResult.
669  * @error: a #GError location to store the error occuring, or %NULL to
670  *     ignore.
671  *
672  * Finishes ejecting a mount. If any errors occurred during the operation,
673  * @error will be set to contain the errors and %FALSE will be returned.
674  *
675  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
676  *
677  * Since: 2.22
678  **/
679 gboolean
680 g_mount_eject_with_operation_finish (GMount        *mount,
681                                      GAsyncResult  *result,
682                                      GError       **error)
683 {
684   GMountIface *iface;
685
686   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
687   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
688
689   if (G_IS_SIMPLE_ASYNC_RESULT (result))
690     {
691       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
692       if (g_simple_async_result_propagate_error (simple, error))
693         return FALSE;
694     }
695
696   iface = G_MOUNT_GET_IFACE (mount);
697   if (iface->eject_with_operation_finish != NULL)
698     return (* iface->eject_with_operation_finish) (mount, result, error);
699   else
700     return (* iface->eject_finish) (mount, result, error);
701 }
702
703 /**
704  * g_mount_remount:
705  * @mount: a #GMount.
706  * @flags: flags affecting the operation
707  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
708  * @cancellable: optional #GCancellable object, %NULL to ignore.
709  * @callback: a #GAsyncReadyCallback, or %NULL.
710  * @user_data: user data passed to @callback.
711  * 
712  * Remounts a mount. This is an asynchronous operation, and is 
713  * finished by calling g_mount_remount_finish() with the @mount 
714  * and #GAsyncResults data returned in the @callback.
715  *
716  * Remounting is useful when some setting affecting the operation
717  * of the volume has been changed, as these may need a remount to
718  * take affect. While this is semantically equivalent with unmounting
719  * and then remounting not all backends might need to actually be
720  * unmounted.
721  **/
722 void
723 g_mount_remount (GMount              *mount,
724                  GMountMountFlags     flags,
725                  GMountOperation     *mount_operation,
726                  GCancellable        *cancellable,
727                  GAsyncReadyCallback  callback,
728                  gpointer             user_data)
729 {
730   GMountIface *iface;
731
732   g_return_if_fail (G_IS_MOUNT (mount));
733   
734   iface = G_MOUNT_GET_IFACE (mount);
735
736   if (iface->remount == NULL)
737     { 
738       g_simple_async_report_error_in_idle (G_OBJECT (mount),
739                                            callback, user_data,
740                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
741                                            /* Translators: This is an error
742                                             * message for mount objects that
743                                             * don't implement remount. */
744                                            _("mount doesn't implement remount"));
745       
746       return;
747     }
748   
749   (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
750 }
751
752 /**
753  * g_mount_remount_finish:
754  * @mount: a #GMount.
755  * @result: a #GAsyncResult.
756  * @error: a #GError location to store the error occuring, or %NULL to 
757  *     ignore.
758  * 
759  * Finishes remounting a mount. If any errors occurred during the operation, 
760  * @error will be set to contain the errors and %FALSE will be returned.
761  * 
762  * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise.
763  **/
764 gboolean
765 g_mount_remount_finish (GMount        *mount,
766                         GAsyncResult  *result,
767                         GError       **error)
768 {
769   GMountIface *iface;
770
771   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
772   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
773
774   if (G_IS_SIMPLE_ASYNC_RESULT (result))
775     {
776       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
777       if (g_simple_async_result_propagate_error (simple, error))
778         return FALSE;
779     }
780   
781   iface = G_MOUNT_GET_IFACE (mount);
782   return (* iface->remount_finish) (mount, result, error);
783 }
784
785 /**
786  * g_mount_guess_content_type:
787  * @mount: a #GMount
788  * @force_rescan: Whether to force a rescan of the content. 
789  *     Otherwise a cached result will be used if available
790  * @cancellable: optional #GCancellable object, %NULL to ignore
791  * @callback: a #GAsyncReadyCallback
792  * @user_data: user data passed to @callback
793  * 
794  * Tries to guess the type of content stored on @mount. Returns one or
795  * more textual identifiers of well-known content types (typically
796  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
797  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
798  * specification for more on x-content types.
799  *
800  * This is an asynchronous operation (see
801  * g_mount_guess_content_type_sync() for the synchronous version), and
802  * is finished by calling g_mount_guess_content_type_finish() with the
803  * @mount and #GAsyncResult data returned in the @callback.
804  *
805  * Since: 2.18
806  */
807 void
808 g_mount_guess_content_type (GMount              *mount,
809                             gboolean             force_rescan,
810                             GCancellable        *cancellable,
811                             GAsyncReadyCallback  callback,
812                             gpointer             user_data)
813 {
814   GMountIface *iface;
815
816   g_return_if_fail (G_IS_MOUNT (mount));
817
818   iface = G_MOUNT_GET_IFACE (mount);
819
820   if (iface->guess_content_type == NULL)
821     {
822       g_simple_async_report_error_in_idle (G_OBJECT (mount),
823                                            callback, user_data,
824                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
825                                            /* Translators: This is an error
826                                             * message for mount objects that
827                                             * don't implement content type guessing. */
828                                            _("mount doesn't implement content type guessing"));
829
830       return;
831     }
832   
833   (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
834 }
835
836 /**
837  * g_mount_guess_content_type_finish:
838  * @mount: a #GMount
839  * @result: a #GAsyncResult
840  * @error: a #GError location to store the error occuring, or %NULL to 
841  *     ignore
842  * 
843  * Finishes guessing content types of @mount. If any errors occured
844  * during the operation, @error will be set to contain the errors and
845  * %FALSE will be returned. In particular, you may get an 
846  * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content 
847  * guessing.
848  * 
849  * Returns: a %NULL-terminated array of content types or %NULL on error. 
850  *     Caller should free this array with g_strfreev() when done with it.
851  *
852  * Since: 2.18
853  **/
854 gchar **
855 g_mount_guess_content_type_finish (GMount        *mount,
856                                    GAsyncResult  *result,
857                                    GError       **error)
858 {
859   GMountIface *iface;
860
861   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
862   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
863
864   if (G_IS_SIMPLE_ASYNC_RESULT (result))
865     {
866       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
867       if (g_simple_async_result_propagate_error (simple, error))
868         return FALSE;
869     }
870   
871   iface = G_MOUNT_GET_IFACE (mount);
872   return (* iface->guess_content_type_finish) (mount, result, error);
873 }
874
875 /**
876  * g_mount_guess_content_type_sync:
877  * @mount: a #GMount
878  * @force_rescan: Whether to force a rescan of the content.
879  *     Otherwise a cached result will be used if available
880  * @cancellable: optional #GCancellable object, %NULL to ignore
881  * @error: a #GError location to store the error occuring, or %NULL to
882  *     ignore
883  *
884  * Tries to guess the type of content stored on @mount. Returns one or
885  * more textual identifiers of well-known content types (typically
886  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
887  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
888  * specification for more on x-content types.
889  *
890  * This is an synchronous operation and as such may block doing IO;
891  * see g_mount_guess_content_type() for the asynchronous version.
892  *
893  * Returns: a %NULL-terminated array of content types or %NULL on error.
894  *     Caller should free this array with g_strfreev() when done with it.
895  *
896  * Since: 2.18
897  */
898 char **
899 g_mount_guess_content_type_sync (GMount              *mount,
900                                  gboolean             force_rescan,
901                                  GCancellable        *cancellable,
902                                  GError             **error)
903 {
904   GMountIface *iface;
905
906   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
907
908   iface = G_MOUNT_GET_IFACE (mount);
909
910   if (iface->guess_content_type_sync == NULL)
911     {
912       g_set_error_literal (error,
913                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
914                            /* Translators: This is an error
915                             * message for mount objects that
916                             * don't implement content type guessing. */
917                            _("mount doesn't implement synchronous content type guessing"));
918
919       return NULL;
920     }
921
922   return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
923 }
924
925 G_LOCK_DEFINE_STATIC (priv_lock);
926
927 /* only access this structure when holding priv_lock */
928 typedef struct
929 {
930   gint shadow_ref_count;
931 } GMountPrivate;
932
933 static void
934 free_private (GMountPrivate *private)
935 {
936   G_LOCK (priv_lock);
937   g_free (private);
938   G_UNLOCK (priv_lock);
939 }
940
941 /* may only be called when holding priv_lock */
942 static GMountPrivate *
943 get_private (GMount *mount)
944 {
945   GMountPrivate *private;
946
947   private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
948   if (G_LIKELY (private != NULL))
949     goto out;
950
951   private = g_new0 (GMountPrivate, 1);
952   g_object_set_data_full (G_OBJECT (mount),
953                           "g-mount-private",
954                           private,
955                           (GDestroyNotify) free_private);
956
957  out:
958   return private;
959 }
960
961 /**
962  * g_mount_is_shadowed:
963  * @mount: A #GMount.
964  *
965  * Determines if @mount is shadowed. Applications or libraries should
966  * avoid displaying @mount in the user interface if it is shadowed.
967  *
968  * A mount is said to be shadowed if there exists one or more user
969  * visible objects (currently #GMount objects) with a root that is
970  * inside the root of @mount.
971  *
972  * One application of shadow mounts is when exposing a single file
973  * system that is used to address several logical volumes. In this
974  * situation, a #GVolumeMonitor implementation would create two
975  * #GVolume objects (for example, one for the camera functionality of
976  * the device and one for a SD card reader on the device) with
977  * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
978  * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
979  * underlying mount (with root
980  * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
981  * #GVolumeMonitor implementation would create two #GMount objects
982  * (each with their root matching the corresponding volume activation
983  * root) that would shadow the original mount.
984  *
985  * The proxy monitor in GVfs 2.26 and later, automatically creates and
986  * manage shadow mounts (and shadows the underlying mount) if the
987  * activation root on a #GVolume is set.
988  *
989  * Returns: %TRUE if @mount is shadowed.
990  *
991  * Since: 2.20
992  **/
993 gboolean
994 g_mount_is_shadowed (GMount *mount)
995 {
996   GMountPrivate *priv;
997   gboolean ret;
998
999   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
1000
1001   G_LOCK (priv_lock);
1002   priv = get_private (mount);
1003   ret = (priv->shadow_ref_count > 0);
1004   G_UNLOCK (priv_lock);
1005
1006   return ret;
1007 }
1008
1009 /**
1010  * g_mount_shadow:
1011  * @mount: A #GMount.
1012  *
1013  * Increments the shadow count on @mount. Usually used by
1014  * #GVolumeMonitor implementations when creating a shadow mount for
1015  * @mount, see g_mount_is_shadowed() for more information. The caller
1016  * will need to emit the #GMount::changed signal on @mount manually.
1017  *
1018  * Since: 2.20
1019  **/
1020 void
1021 g_mount_shadow (GMount *mount)
1022 {
1023   GMountPrivate *priv;
1024
1025   g_return_if_fail (G_IS_MOUNT (mount));
1026
1027   G_LOCK (priv_lock);
1028   priv = get_private (mount);
1029   priv->shadow_ref_count += 1;
1030   G_UNLOCK (priv_lock);
1031 }
1032
1033 /**
1034  * g_mount_unshadow:
1035  * @mount: A #GMount.
1036  *
1037  * Decrements the shadow count on @mount. Usually used by
1038  * #GVolumeMonitor implementations when destroying a shadow mount for
1039  * @mount, see g_mount_is_shadowed() for more information. The caller
1040  * will need to emit the #GMount::changed signal on @mount manually.
1041  *
1042  * Since: 2.20
1043  **/
1044 void
1045 g_mount_unshadow (GMount *mount)
1046 {
1047   GMountPrivate *priv;
1048
1049   g_return_if_fail (G_IS_MOUNT (mount));
1050
1051   G_LOCK (priv_lock);
1052   priv = get_private (mount);
1053   priv->shadow_ref_count -= 1;
1054   if (priv->shadow_ref_count < 0)
1055     g_warning ("Shadow ref count on GMount is negative");
1056   G_UNLOCK (priv_lock);
1057 }
1058
1059 #define __G_MOUNT_C__
1060 #include "gioaliasdef.c"