Allow interaction when unmounting mounts
[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_name:
189  * @mount: a #GMount.
190  * 
191  * Gets the name of @mount.
192  * 
193  * Returns: the name for the given @mount. 
194  *     The returned string should be freed with g_free()
195  *     when no longer needed.
196  **/
197 char *
198 g_mount_get_name (GMount *mount)
199 {
200   GMountIface *iface;
201
202   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
203
204   iface = G_MOUNT_GET_IFACE (mount);
205
206   return (* iface->get_name) (mount);
207 }
208
209 /**
210  * g_mount_get_icon:
211  * @mount: a #GMount.
212  * 
213  * Gets the icon for @mount.
214  * 
215  * Returns: a #GIcon.
216  *      The returned object should be unreffed with 
217  *      g_object_unref() when no longer needed.
218  **/
219 GIcon *
220 g_mount_get_icon (GMount *mount)
221 {
222   GMountIface *iface;
223
224   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
225
226   iface = G_MOUNT_GET_IFACE (mount);
227
228   return (* iface->get_icon) (mount);
229 }
230
231 /**
232  * g_mount_get_uuid:
233  * @mount: a #GMount.
234  * 
235  * Gets the UUID for the @mount. The reference is typically based on
236  * the file system UUID for the mount in question and should be
237  * considered an opaque string. Returns %NULL if there is no UUID
238  * available.
239  * 
240  * Returns: the UUID for @mount or %NULL if no UUID can be computed.
241  *     The returned string should be freed with g_free()
242  *     when no longer needed.
243  **/
244 char *
245 g_mount_get_uuid (GMount *mount)
246 {
247   GMountIface *iface;
248
249   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
250
251   iface = G_MOUNT_GET_IFACE (mount);
252
253   return (* iface->get_uuid) (mount);
254 }
255
256 /**
257  * g_mount_get_volume:
258  * @mount: a #GMount.
259  * 
260  * Gets the volume for the @mount.
261  * 
262  * Returns: a #GVolume or %NULL if @mount is not associated with a volume.
263  *      The returned object should be unreffed with 
264  *      g_object_unref() when no longer needed.
265  **/
266 GVolume *
267 g_mount_get_volume (GMount *mount)
268 {
269   GMountIface *iface;
270
271   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
272
273   iface = G_MOUNT_GET_IFACE (mount);
274
275   return (* iface->get_volume) (mount);
276 }
277
278 /**
279  * g_mount_get_drive:
280  * @mount: a #GMount.
281  * 
282  * Gets the drive for the @mount.
283  *
284  * This is a convenience method for getting the #GVolume and then
285  * using that object to get the #GDrive.
286  * 
287  * Returns: a #GDrive or %NULL if @mount is not associated with a volume or a drive.
288  *      The returned object should be unreffed with 
289  *      g_object_unref() when no longer needed.
290  **/
291 GDrive *
292 g_mount_get_drive (GMount *mount)
293 {
294   GMountIface *iface;
295
296   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
297
298   iface = G_MOUNT_GET_IFACE (mount);
299
300   return (* iface->get_drive) (mount);
301 }
302
303 /**
304  * g_mount_can_unmount: 
305  * @mount: a #GMount.
306  * 
307  * Checks if @mount can be mounted.
308  * 
309  * Returns: %TRUE if the @mount can be unmounted.
310  **/
311 gboolean
312 g_mount_can_unmount (GMount *mount)
313 {
314   GMountIface *iface;
315
316   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
317
318   iface = G_MOUNT_GET_IFACE (mount);
319
320   return (* iface->can_unmount) (mount);
321 }
322
323 /**
324  * g_mount_can_eject: 
325  * @mount: a #GMount.
326  * 
327  * Checks if @mount can be eject.
328  * 
329  * Returns: %TRUE if the @mount can be ejected.
330  **/
331 gboolean
332 g_mount_can_eject (GMount *mount)
333 {
334   GMountIface *iface;
335
336   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
337
338   iface = G_MOUNT_GET_IFACE (mount);
339
340   return (* iface->can_eject) (mount);
341 }
342
343 /**
344  * g_mount_unmount:
345  * @mount: a #GMount.
346  * @flags: flags affecting the operation
347  * @cancellable: optional #GCancellable object, %NULL to ignore.
348  * @callback: a #GAsyncReadyCallback, or %NULL.
349  * @user_data: user data passed to @callback.
350  * 
351  * Unmounts a mount. This is an asynchronous operation, and is 
352  * finished by calling g_mount_unmount_finish() with the @mount 
353  * and #GAsyncResult data returned in the @callback.
354  *
355  * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead.
356  **/
357 void
358 g_mount_unmount (GMount              *mount,
359                  GMountUnmountFlags   flags,
360                  GCancellable        *cancellable,
361                  GAsyncReadyCallback  callback,
362                  gpointer             user_data)
363 {
364   GMountIface *iface;
365
366   g_return_if_fail (G_IS_MOUNT (mount));
367   
368   iface = G_MOUNT_GET_IFACE (mount);
369
370   if (iface->unmount == NULL)
371     {
372       g_simple_async_report_error_in_idle (G_OBJECT (mount),
373                                            callback, user_data,
374                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
375                                            /* Translators: This is an error
376                                             * message for mount objects that
377                                             * don't implement unmount. */
378                                            _("mount doesn't implement unmount"));
379
380       return;
381     }
382   
383   (* iface->unmount) (mount, flags, cancellable, callback, user_data);
384 }
385
386 /**
387  * g_mount_unmount_finish:
388  * @mount: a #GMount.
389  * @result: a #GAsyncResult.
390  * @error: a #GError location to store the error occuring, or %NULL to 
391  *     ignore.
392  * 
393  * Finishes unmounting a mount. If any errors occurred during the operation, 
394  * @error will be set to contain the errors and %FALSE will be returned.
395  * 
396  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
397  *
398  * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead.
399  **/
400 gboolean
401 g_mount_unmount_finish (GMount        *mount,
402                         GAsyncResult  *result,
403                         GError       **error)
404 {
405   GMountIface *iface;
406
407   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
408   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
409
410   if (G_IS_SIMPLE_ASYNC_RESULT (result))
411     {
412       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
413       if (g_simple_async_result_propagate_error (simple, error))
414         return FALSE;
415     }
416   
417   iface = G_MOUNT_GET_IFACE (mount);
418   return (* iface->unmount_finish) (mount, result, error);
419 }
420
421
422 /**
423  * g_mount_eject:
424  * @mount: a #GMount.
425  * @flags: flags affecting the unmount if required for eject
426  * @cancellable: optional #GCancellable object, %NULL to ignore.
427  * @callback: a #GAsyncReadyCallback, or %NULL.
428  * @user_data: user data passed to @callback.
429  * 
430  * Ejects a mount. This is an asynchronous operation, and is 
431  * finished by calling g_mount_eject_finish() with the @mount 
432  * and #GAsyncResult data returned in the @callback.
433  *
434  * Deprecated: 2.22: Use g_mount_eject_with_operation() instead.
435  **/
436 void
437 g_mount_eject (GMount              *mount,
438                GMountUnmountFlags   flags,
439                GCancellable        *cancellable,
440                GAsyncReadyCallback  callback,
441                gpointer             user_data)
442 {
443   GMountIface *iface;
444
445   g_return_if_fail (G_IS_MOUNT (mount));
446   
447   iface = G_MOUNT_GET_IFACE (mount);
448
449   if (iface->eject == NULL)
450     {
451       g_simple_async_report_error_in_idle (G_OBJECT (mount),
452                                            callback, user_data,
453                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
454                                            /* Translators: This is an error
455                                             * message for mount objects that
456                                             * don't implement eject. */
457                                            _("mount doesn't implement eject"));
458       
459       return;
460     }
461   
462   (* iface->eject) (mount, flags, cancellable, callback, user_data);
463 }
464
465 /**
466  * g_mount_eject_finish:
467  * @mount: a #GMount.
468  * @result: a #GAsyncResult.
469  * @error: a #GError location to store the error occuring, or %NULL to 
470  *     ignore.
471  * 
472  * Finishes ejecting a mount. If any errors occurred during the operation, 
473  * @error will be set to contain the errors and %FALSE will be returned.
474  * 
475  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
476  *
477  * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead.
478  **/
479 gboolean
480 g_mount_eject_finish (GMount        *mount,
481                       GAsyncResult  *result,
482                       GError       **error)
483 {
484   GMountIface *iface;
485
486   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
487   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
488
489   if (G_IS_SIMPLE_ASYNC_RESULT (result))
490     {
491       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
492       if (g_simple_async_result_propagate_error (simple, error))
493         return FALSE;
494     }
495   
496   iface = G_MOUNT_GET_IFACE (mount);
497   return (* iface->eject_finish) (mount, result, error);
498 }
499
500 /**
501  * g_mount_unmount_with_operation:
502  * @mount: a #GMount.
503  * @flags: flags affecting the operation
504  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
505  * @cancellable: optional #GCancellable object, %NULL to ignore.
506  * @callback: a #GAsyncReadyCallback, or %NULL.
507  * @user_data: user data passed to @callback.
508  *
509  * Unmounts a mount. This is an asynchronous operation, and is
510  * finished by calling g_mount_unmount_with_operation_finish() with the @mount 
511  * and #GAsyncResult data returned in the @callback.
512  *
513  * Since: 2.22
514  **/
515 void
516 g_mount_unmount_with_operation (GMount              *mount,
517                                 GMountUnmountFlags   flags,
518                                 GMountOperation     *mount_operation,
519                                 GCancellable        *cancellable,
520                                 GAsyncReadyCallback  callback,
521                                 gpointer             user_data)
522 {
523   GMountIface *iface;
524
525   g_return_if_fail (G_IS_MOUNT (mount));
526
527   iface = G_MOUNT_GET_IFACE (mount);
528
529   if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
530     {
531       g_simple_async_report_error_in_idle (G_OBJECT (mount),
532                                            callback, user_data,
533                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
534                                            /* Translators: This is an error
535                                             * message for mount objects that
536                                             * don't implement any of unmount or unmount_with_operation. */
537                                            _("mount doesn't implement unmount or unmount_with_operation"));
538
539       return;
540     }
541
542   if (iface->unmount_with_operation != NULL)
543     (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
544   else
545     (* iface->unmount) (mount, flags, cancellable, callback, user_data);
546 }
547
548 /**
549  * g_mount_unmount_with_operation_finish:
550  * @mount: a #GMount.
551  * @result: a #GAsyncResult.
552  * @error: a #GError location to store the error occuring, or %NULL to
553  *     ignore.
554  *
555  * Finishes unmounting a mount. If any errors occurred during the operation,
556  * @error will be set to contain the errors and %FALSE will be returned.
557  *
558  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
559  *
560  * Since: 2.22
561  **/
562 gboolean
563 g_mount_unmount_with_operation_finish (GMount        *mount,
564                                        GAsyncResult  *result,
565                                        GError       **error)
566 {
567   GMountIface *iface;
568
569   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
570   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
571
572   if (G_IS_SIMPLE_ASYNC_RESULT (result))
573     {
574       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
575       if (g_simple_async_result_propagate_error (simple, error))
576         return FALSE;
577     }
578
579   iface = G_MOUNT_GET_IFACE (mount);
580   if (iface->unmount_with_operation_finish != NULL)
581     return (* iface->unmount_with_operation_finish) (mount, result, error);
582   else
583     return (* iface->unmount_finish) (mount, result, error);
584 }
585
586
587 /**
588  * g_mount_eject_with_operation:
589  * @mount: a #GMount.
590  * @flags: flags affecting the unmount if required for eject
591  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
592  * @cancellable: optional #GCancellable object, %NULL to ignore.
593  * @callback: a #GAsyncReadyCallback, or %NULL.
594  * @user_data: user data passed to @callback.
595  *
596  * Ejects a mount. This is an asynchronous operation, and is
597  * finished by calling g_mount_eject_with_operation_finish() with the @mount
598  * and #GAsyncResult data returned in the @callback.
599  *
600  * Since: 2.22
601  **/
602 void
603 g_mount_eject_with_operation (GMount              *mount,
604                               GMountUnmountFlags   flags,
605                               GMountOperation     *mount_operation,
606                               GCancellable        *cancellable,
607                               GAsyncReadyCallback  callback,
608                               gpointer             user_data)
609 {
610   GMountIface *iface;
611
612   g_return_if_fail (G_IS_MOUNT (mount));
613
614   iface = G_MOUNT_GET_IFACE (mount);
615
616   if (iface->eject == NULL && iface->eject_with_operation == NULL)
617     {
618       g_simple_async_report_error_in_idle (G_OBJECT (mount),
619                                            callback, user_data,
620                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
621                                            /* Translators: This is an error
622                                             * message for mount objects that
623                                             * don't implement any of eject or eject_with_operation. */
624                                            _("mount doesn't implement eject or eject_with_operation"));
625       return;
626     }
627
628   if (iface->eject_with_operation != NULL)
629     (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
630   else
631     (* iface->eject) (mount, flags, cancellable, callback, user_data);
632 }
633
634 /**
635  * g_mount_eject_with_operation_finish:
636  * @mount: a #GMount.
637  * @result: a #GAsyncResult.
638  * @error: a #GError location to store the error occuring, or %NULL to
639  *     ignore.
640  *
641  * Finishes ejecting a mount. If any errors occurred during the operation,
642  * @error will be set to contain the errors and %FALSE will be returned.
643  *
644  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
645  *
646  * Since: 2.22
647  **/
648 gboolean
649 g_mount_eject_with_operation_finish (GMount        *mount,
650                                      GAsyncResult  *result,
651                                      GError       **error)
652 {
653   GMountIface *iface;
654
655   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
656   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
657
658   if (G_IS_SIMPLE_ASYNC_RESULT (result))
659     {
660       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
661       if (g_simple_async_result_propagate_error (simple, error))
662         return FALSE;
663     }
664
665   iface = G_MOUNT_GET_IFACE (mount);
666   if (iface->eject_with_operation_finish != NULL)
667     return (* iface->eject_with_operation_finish) (mount, result, error);
668   else
669     return (* iface->eject_finish) (mount, result, error);
670 }
671
672 /**
673  * g_mount_remount:
674  * @mount: a #GMount.
675  * @flags: flags affecting the operation
676  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
677  * @cancellable: optional #GCancellable object, %NULL to ignore.
678  * @callback: a #GAsyncReadyCallback, or %NULL.
679  * @user_data: user data passed to @callback.
680  * 
681  * Remounts a mount. This is an asynchronous operation, and is 
682  * finished by calling g_mount_remount_finish() with the @mount 
683  * and #GAsyncResults data returned in the @callback.
684  *
685  * Remounting is useful when some setting affecting the operation
686  * of the volume has been changed, as these may need a remount to
687  * take affect. While this is semantically equivalent with unmounting
688  * and then remounting not all backends might need to actually be
689  * unmounted.
690  **/
691 void
692 g_mount_remount (GMount              *mount,
693                  GMountMountFlags     flags,
694                  GMountOperation     *mount_operation,
695                  GCancellable        *cancellable,
696                  GAsyncReadyCallback  callback,
697                  gpointer             user_data)
698 {
699   GMountIface *iface;
700
701   g_return_if_fail (G_IS_MOUNT (mount));
702   
703   iface = G_MOUNT_GET_IFACE (mount);
704
705   if (iface->remount == NULL)
706     { 
707       g_simple_async_report_error_in_idle (G_OBJECT (mount),
708                                            callback, user_data,
709                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
710                                            /* Translators: This is an error
711                                             * message for mount objects that
712                                             * don't implement remount. */
713                                            _("mount doesn't implement remount"));
714       
715       return;
716     }
717   
718   (* iface->remount) (mount, flags, mount_operation, cancellable, callback, user_data);
719 }
720
721 /**
722  * g_mount_remount_finish:
723  * @mount: a #GMount.
724  * @result: a #GAsyncResult.
725  * @error: a #GError location to store the error occuring, or %NULL to 
726  *     ignore.
727  * 
728  * Finishes remounting a mount. If any errors occurred during the operation, 
729  * @error will be set to contain the errors and %FALSE will be returned.
730  * 
731  * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise.
732  **/
733 gboolean
734 g_mount_remount_finish (GMount        *mount,
735                         GAsyncResult  *result,
736                         GError       **error)
737 {
738   GMountIface *iface;
739
740   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
741   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
742
743   if (G_IS_SIMPLE_ASYNC_RESULT (result))
744     {
745       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
746       if (g_simple_async_result_propagate_error (simple, error))
747         return FALSE;
748     }
749   
750   iface = G_MOUNT_GET_IFACE (mount);
751   return (* iface->remount_finish) (mount, result, error);
752 }
753
754 /**
755  * g_mount_guess_content_type:
756  * @mount: a #GMount
757  * @force_rescan: Whether to force a rescan of the content. 
758  *     Otherwise a cached result will be used if available
759  * @cancellable: optional #GCancellable object, %NULL to ignore
760  * @callback: a #GAsyncReadyCallback
761  * @user_data: user data passed to @callback
762  * 
763  * Tries to guess the type of content stored on @mount. Returns one or
764  * more textual identifiers of well-known content types (typically
765  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
766  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
767  * specification for more on x-content types.
768  *
769  * This is an asynchronous operation (see
770  * g_mount_guess_content_type_sync() for the synchronous version), and
771  * is finished by calling g_mount_guess_content_type_finish() with the
772  * @mount and #GAsyncResult data returned in the @callback.
773  *
774  * Since: 2.18
775  */
776 void
777 g_mount_guess_content_type (GMount              *mount,
778                             gboolean             force_rescan,
779                             GCancellable        *cancellable,
780                             GAsyncReadyCallback  callback,
781                             gpointer             user_data)
782 {
783   GMountIface *iface;
784
785   g_return_if_fail (G_IS_MOUNT (mount));
786
787   iface = G_MOUNT_GET_IFACE (mount);
788
789   if (iface->guess_content_type == NULL)
790     {
791       g_simple_async_report_error_in_idle (G_OBJECT (mount),
792                                            callback, user_data,
793                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
794                                            /* Translators: This is an error
795                                             * message for mount objects that
796                                             * don't implement content type guessing. */
797                                            _("mount doesn't implement content type guessing"));
798
799       return;
800     }
801   
802   (* iface->guess_content_type) (mount, force_rescan, cancellable, callback, user_data);
803 }
804
805 /**
806  * g_mount_guess_content_type_finish:
807  * @mount: a #GMount
808  * @result: a #GAsyncResult
809  * @error: a #GError location to store the error occuring, or %NULL to 
810  *     ignore
811  * 
812  * Finishes guessing content types of @mount. If any errors occured
813  * during the operation, @error will be set to contain the errors and
814  * %FALSE will be returned. In particular, you may get an 
815  * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content 
816  * guessing.
817  * 
818  * Returns: a %NULL-terminated array of content types or %NULL on error. 
819  *     Caller should free this array with g_strfreev() when done with it.
820  *
821  * Since: 2.18
822  **/
823 gchar **
824 g_mount_guess_content_type_finish (GMount        *mount,
825                                    GAsyncResult  *result,
826                                    GError       **error)
827 {
828   GMountIface *iface;
829
830   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
831   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
832
833   if (G_IS_SIMPLE_ASYNC_RESULT (result))
834     {
835       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
836       if (g_simple_async_result_propagate_error (simple, error))
837         return FALSE;
838     }
839   
840   iface = G_MOUNT_GET_IFACE (mount);
841   return (* iface->guess_content_type_finish) (mount, result, error);
842 }
843
844 /**
845  * g_mount_guess_content_type_sync:
846  * @mount: a #GMount
847  * @force_rescan: Whether to force a rescan of the content.
848  *     Otherwise a cached result will be used if available
849  * @cancellable: optional #GCancellable object, %NULL to ignore
850  * @error: a #GError location to store the error occuring, or %NULL to
851  *     ignore
852  *
853  * Tries to guess the type of content stored on @mount. Returns one or
854  * more textual identifiers of well-known content types (typically
855  * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 
856  * memory cards. See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
857  * specification for more on x-content types.
858  *
859  * This is an synchronous operation and as such may block doing IO;
860  * see g_mount_guess_content_type() for the asynchronous version.
861  *
862  * Returns: a %NULL-terminated array of content types or %NULL on error.
863  *     Caller should free this array with g_strfreev() when done with it.
864  *
865  * Since: 2.18
866  */
867 char **
868 g_mount_guess_content_type_sync (GMount              *mount,
869                                  gboolean             force_rescan,
870                                  GCancellable        *cancellable,
871                                  GError             **error)
872 {
873   GMountIface *iface;
874
875   g_return_val_if_fail (G_IS_MOUNT (mount), NULL);
876
877   iface = G_MOUNT_GET_IFACE (mount);
878
879   if (iface->guess_content_type_sync == NULL)
880     {
881       g_set_error_literal (error,
882                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
883                            /* Translators: This is an error
884                             * message for mount objects that
885                             * don't implement content type guessing. */
886                            _("mount doesn't implement synchronous content type guessing"));
887
888       return NULL;
889     }
890
891   return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
892 }
893
894 G_LOCK_DEFINE_STATIC (priv_lock);
895
896 /* only access this structure when holding priv_lock */
897 typedef struct
898 {
899   gint shadow_ref_count;
900 } GMountPrivate;
901
902 static void
903 free_private (GMountPrivate *private)
904 {
905   G_LOCK (priv_lock);
906   g_free (private);
907   G_UNLOCK (priv_lock);
908 }
909
910 /* may only be called when holding priv_lock */
911 static GMountPrivate *
912 get_private (GMount *mount)
913 {
914   GMountPrivate *private;
915
916   private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
917   if (G_LIKELY (private != NULL))
918     goto out;
919
920   private = g_new0 (GMountPrivate, 1);
921   g_object_set_data_full (G_OBJECT (mount),
922                           "g-mount-private",
923                           private,
924                           (GDestroyNotify) free_private);
925
926  out:
927   return private;
928 }
929
930 /**
931  * g_mount_is_shadowed:
932  * @mount: A #GMount.
933  *
934  * Determines if @mount is shadowed. Applications or libraries should
935  * avoid displaying @mount in the user interface if it is shadowed.
936  *
937  * A mount is said to be shadowed if there exists one or more user
938  * visible objects (currently #GMount objects) with a root that is
939  * inside the root of @mount.
940  *
941  * One application of shadow mounts is when exposing a single file
942  * system that is used to address several logical volumes. In this
943  * situation, a #GVolumeMonitor implementation would create two
944  * #GVolume objects (for example, one for the camera functionality of
945  * the device and one for a SD card reader on the device) with
946  * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
947  * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
948  * underlying mount (with root
949  * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
950  * #GVolumeMonitor implementation would create two #GMount objects
951  * (each with their root matching the corresponding volume activation
952  * root) that would shadow the original mount.
953  *
954  * The proxy monitor in GVfs 2.26 and later, automatically creates and
955  * manage shadow mounts (and shadows the underlying mount) if the
956  * activation root on a #GVolume is set.
957  *
958  * Returns: %TRUE if @mount is shadowed.
959  *
960  * Since: 2.20
961  **/
962 gboolean
963 g_mount_is_shadowed (GMount *mount)
964 {
965   GMountPrivate *priv;
966   gboolean ret;
967
968   g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
969
970   G_LOCK (priv_lock);
971   priv = get_private (mount);
972   ret = (priv->shadow_ref_count > 0);
973   G_UNLOCK (priv_lock);
974
975   return ret;
976 }
977
978 /**
979  * g_mount_shadow:
980  * @mount: A #GMount.
981  *
982  * Increments the shadow count on @mount. Usually used by
983  * #GVolumeMonitor implementations when creating a shadow mount for
984  * @mount, see g_mount_is_shadowed() for more information. The caller
985  * will need to emit the #GMount::changed signal on @mount manually.
986  *
987  * Since: 2.20
988  **/
989 void
990 g_mount_shadow (GMount *mount)
991 {
992   GMountPrivate *priv;
993
994   g_return_if_fail (G_IS_MOUNT (mount));
995
996   G_LOCK (priv_lock);
997   priv = get_private (mount);
998   priv->shadow_ref_count += 1;
999   G_UNLOCK (priv_lock);
1000 }
1001
1002 /**
1003  * g_mount_unshadow:
1004  * @mount: A #GMount.
1005  *
1006  * Decrements the shadow count on @mount. Usually used by
1007  * #GVolumeMonitor implementations when destroying a shadow mount for
1008  * @mount, see g_mount_is_shadowed() for more information. The caller
1009  * will need to emit the #GMount::changed signal on @mount manually.
1010  *
1011  * Since: 2.20
1012  **/
1013 void
1014 g_mount_unshadow (GMount *mount)
1015 {
1016   GMountPrivate *priv;
1017
1018   g_return_if_fail (G_IS_MOUNT (mount));
1019
1020   G_LOCK (priv_lock);
1021   priv = get_private (mount);
1022   priv->shadow_ref_count -= 1;
1023   if (priv->shadow_ref_count < 0)
1024     g_warning ("Shadow ref count on GMount is negative");
1025   G_UNLOCK (priv_lock);
1026 }
1027
1028 #define __G_MOUNT_C__
1029 #include "gioaliasdef.c"