70005828e05446055ae9b3017d061c826eafaed3
[platform/upstream/glib.git] / gio / gvolume.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  *         David Zeuthen <davidz@redhat.com>
22  */
23
24 #include "config.h"
25 #include "gmount.h"
26 #include "gvolume.h"
27 #include "gasyncresult.h"
28 #include "gsimpleasyncresult.h"
29 #include "gioerror.h"
30 #include "glibintl.h"
31
32 #include "gioalias.h"
33
34 /**
35  * SECTION:gvolume
36  * @short_description: Volume management
37  * @include: gio/gio.h
38  * 
39  * The #GVolume interface represents user-visible objects that can be
40  * mounted. Note, when porting from GnomeVFS, #GVolume is the moral
41  * equivalent of #GnomeVFSDrive.
42  *
43  * Mounting a #GVolume instance is an asynchronous operation. For more
44  * information about asynchronous operations, see #GAsyncReady and
45  * #GSimpleAsyncReady. To mount a #GVolume, first call
46  * g_volume_mount() with (at least) the #GVolume instance, optionally
47  * a #GMountOperation object and a #GAsyncReadyCallback. 
48  *
49  * Typically, one will only want to pass %NULL for the
50  * #GMountOperation if automounting all volumes when a desktop session
51  * starts since it's not desirable to put up a lot of dialogs asking
52  * for credentials.
53  *
54  * The callback will be fired when the operation has resolved (either
55  * with success or failure), and a #GAsyncReady structure will be
56  * passed to the callback.  That callback should then call
57  * g_volume_mount_finish() with the #GVolume instance and the
58  * #GAsyncReady data to see if the operation was completed
59  * successfully.  If an @error is present when g_volume_mount_finish()
60  * is called, then it will be filled with any error information.
61  *
62  * <para id="volume-identifier">
63  * It is sometimes necessary to directly access the underlying 
64  * operating system object behind a volume (e.g. for passing a volume
65  * to an application via the commandline). For this purpose, GIO
66  * allows to obtain an 'identifier' for the volume. There can be
67  * different kinds of identifiers, such as Hal UDIs, filesystem labels,
68  * traditional Unix devices (e.g. <filename>/dev/sda2</filename>),
69  * uuids. GIO uses predefind strings as names for the different kinds
70  * of identifiers: #G_VOLUME_IDENTIFIER_KIND_HAL_UDI, 
71  * #G_VOLUME_IDENTIFIER_KIND_LABEL, etc. Use g_volume_get_identifier() 
72  * to obtain an identifier for a volume.
73  * </para>
74  **/
75
76 static void g_volume_base_init (gpointer g_class);
77 static void g_volume_class_init (gpointer g_class,
78                                  gpointer class_data);
79
80 GType
81 g_volume_get_type (void)
82 {
83   static GType volume_type = 0;
84
85   if (! volume_type)
86     {
87       static const GTypeInfo volume_info =
88       {
89         sizeof (GVolumeIface), /* class_size */
90         g_volume_base_init,   /* base_init */
91         NULL,           /* base_finalize */
92         g_volume_class_init,
93         NULL,           /* class_finalize */
94         NULL,           /* class_data */
95         0,
96         0,              /* n_preallocs */
97         NULL
98       };
99
100       volume_type =
101         g_type_register_static (G_TYPE_INTERFACE, I_("GVolume"),
102                                 &volume_info, 0);
103
104       g_type_interface_add_prerequisite (volume_type, G_TYPE_OBJECT);
105     }
106
107   return volume_type;
108 }
109
110 static void
111 g_volume_class_init (gpointer g_class,
112                      gpointer class_data)
113 {
114 }
115
116 static void
117 g_volume_base_init (gpointer g_class)
118 {
119   static gboolean initialized = FALSE;
120
121   if (! initialized)
122     {
123      /**
124       * GVolume::changed:
125       * 
126       * Emitted when the volume has been changed.
127       **/
128       g_signal_new (I_("changed"),
129                     G_TYPE_VOLUME,
130                     G_SIGNAL_RUN_LAST,
131                     G_STRUCT_OFFSET (GVolumeIface, changed),
132                     NULL, NULL,
133                     g_cclosure_marshal_VOID__VOID,
134                     G_TYPE_NONE, 0);
135
136      /**
137       * GVolume::removed:
138       * 
139       * This signal is emitted when the #GVolume have been removed. If
140       * the recipient is holding references to the object they should
141       * release them so the object can be finalized.
142       **/
143       g_signal_new (I_("removed"),
144                     G_TYPE_VOLUME,
145                     G_SIGNAL_RUN_LAST,
146                     G_STRUCT_OFFSET (GVolumeIface, removed),
147                     NULL, NULL,
148                     g_cclosure_marshal_VOID__VOID,
149                     G_TYPE_NONE, 0);
150
151       initialized = TRUE;
152     }
153 }
154
155 /**
156  * g_volume_get_name:
157  * @volume: a #GVolume.
158  * 
159  * Gets the name of @volume.
160  * 
161  * Returns: the name for the given @volume. The returned string should 
162  * be freed when no longer needed.
163  **/
164 char *
165 g_volume_get_name (GVolume *volume)
166 {
167   GVolumeIface *iface;
168
169   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
170
171   iface = G_VOLUME_GET_IFACE (volume);
172
173   return (* iface->get_name) (volume);
174 }
175
176 /**
177  * g_volume_get_icon:
178  * @volume: a #GVolume.
179  * 
180  * Gets the icon for @volume.
181  * 
182  * Returns: a #GIcon.
183  **/
184 GIcon *
185 g_volume_get_icon (GVolume *volume)
186 {
187   GVolumeIface *iface;
188
189   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
190
191   iface = G_VOLUME_GET_IFACE (volume);
192
193   return (* iface->get_icon) (volume);
194 }
195
196 /**
197  * g_volume_get_uuid:
198  * @volume: a #GVolume.
199  * 
200  * Gets the UUID for the @volume. The reference is typically based on
201  * the file system UUID for the volume in question and should be
202  * considered an opaque string. Returns %NULL if there is no UUID
203  * available.
204  * 
205  * Returns: the UUID for @volume or %NULL if no UUID can be computed.
206  **/
207 char *
208 g_volume_get_uuid (GVolume *volume)
209 {
210   GVolumeIface *iface;
211
212   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
213
214   iface = G_VOLUME_GET_IFACE (volume);
215
216   return (* iface->get_uuid) (volume);
217 }
218   
219 /**
220  * g_volume_get_drive:
221  * @volume: a #GVolume.
222  * 
223  * Gets the drive for the @volume.
224  * 
225  * Returns: a #GDrive or %NULL if @volume is not associated with a drive.
226  **/
227 GDrive *
228 g_volume_get_drive (GVolume *volume)
229 {
230   GVolumeIface *iface;
231
232   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
233
234   iface = G_VOLUME_GET_IFACE (volume);
235
236   return (* iface->get_drive) (volume);
237 }
238
239 /**
240  * g_volume_get_mount:
241  * @volume: a #GVolume.
242  * 
243  * Gets the mount for the @volume.
244  * 
245  * Returns: a #GMount or %NULL if @volume isn't mounted.
246  **/
247 GMount *
248 g_volume_get_mount (GVolume *volume)
249 {
250   GVolumeIface *iface;
251
252   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
253
254   iface = G_VOLUME_GET_IFACE (volume);
255
256   return (* iface->get_mount) (volume);
257 }
258
259
260 /**
261  * g_volume_can_mount:
262  * @volume: a #GVolume.
263  * 
264  * Checks if a volume can be mounted.
265  * 
266  * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
267  **/
268 gboolean
269 g_volume_can_mount (GVolume *volume)
270 {
271   GVolumeIface *iface;
272
273   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
274
275   iface = G_VOLUME_GET_IFACE (volume);
276
277   if (iface->can_mount == NULL)
278     return FALSE;
279
280   return (* iface->can_mount) (volume);
281 }
282
283 /**
284  * g_volume_can_eject:
285  * @volume: a #GVolume.
286  * 
287  * Checks if a volume can be ejected.
288  * 
289  * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise.
290  **/
291 gboolean
292 g_volume_can_eject (GVolume *volume)
293 {
294   GVolumeIface *iface;
295
296   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
297
298   iface = G_VOLUME_GET_IFACE (volume);
299
300   if (iface->can_eject == NULL)
301     return FALSE;
302
303   return (* iface->can_eject) (volume);
304 }
305
306 /**
307  * g_volume_should_automount:
308  * @volume: a #GVolume
309  *
310  * Returns whether the volume should be automatically mounted.
311  * 
312  * Returns: %TRUE if the volume should be automatically mounted.
313  */
314 gboolean
315 g_volume_should_automount (GVolume *volume)
316 {
317   GVolumeIface *iface;
318
319   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
320
321   iface = G_VOLUME_GET_IFACE (volume);
322
323   if (iface->should_automount == NULL)
324     return FALSE;
325
326   return (* iface->should_automount) (volume);
327 }
328
329
330 /**
331  * g_volume_mount:
332  * @volume: a #GVolume.
333  * @flags: flags affecting the operation
334  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
335  * @cancellable: optional #GCancellable object, %NULL to ignore.
336  * @callback: a #GAsyncReadyCallback, or %NULL.
337  * @user_data: a #gpointer.
338  * 
339  * Mounts a volume.
340  **/
341 void
342 g_volume_mount (GVolume    *volume,
343                 GMountMountFlags     flags,
344                 GMountOperation     *mount_operation,
345                 GCancellable        *cancellable,
346                 GAsyncReadyCallback  callback,
347                 gpointer             user_data)
348 {
349   GVolumeIface *iface;
350
351   g_return_if_fail (G_IS_VOLUME (volume));
352
353   iface = G_VOLUME_GET_IFACE (volume);
354
355   if (iface->mount_fn == NULL)
356     {
357       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
358                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
359                                            _("volume doesn't implement mount"));
360       
361       return;
362     }
363   
364   (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data);
365 }
366
367 /**
368  * g_volume_mount_finish:
369  * @volume: pointer to a #GVolume.
370  * @result: a #GAsyncResult.
371  * @error: a #GError.
372  * 
373  * Finishes mounting a volume.
374  * 
375  * Returns: %TRUE, %FALSE if operation failed.
376  **/
377 gboolean
378 g_volume_mount_finish (GVolume  *volume,
379                        GAsyncResult      *result,
380                        GError           **error)
381 {
382   GVolumeIface *iface;
383
384   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
385   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
386
387   if (G_IS_SIMPLE_ASYNC_RESULT (result))
388     {
389       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
390       if (g_simple_async_result_propagate_error (simple, error))
391         return FALSE;
392     }
393   
394   iface = G_VOLUME_GET_IFACE (volume);
395   return (* iface->mount_finish) (volume, result, error);
396 }
397
398 /**
399  * g_volume_eject:
400  * @volume: a #GVolume.
401  * @flags: flags affecting the unmount if required for eject
402  * @cancellable: optional #GCancellable object, %NULL to ignore.
403  * @callback: a #GAsyncReadyCallback, or %NULL.
404  * @user_data: a #gpointer.
405  * 
406  * Ejects a volume.
407  **/
408 void
409 g_volume_eject (GVolume    *volume,
410                 GMountUnmountFlags   flags,
411                 GCancellable        *cancellable,
412                 GAsyncReadyCallback  callback,
413                 gpointer             user_data)
414 {
415   GVolumeIface *iface;
416
417   g_return_if_fail (G_IS_VOLUME (volume));
418
419   iface = G_VOLUME_GET_IFACE (volume);
420
421   if (iface->eject == NULL)
422     {
423       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
424                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
425                                            _("volume doesn't implement eject"));
426       
427       return;
428     }
429   
430   (* iface->eject) (volume, flags, cancellable, callback, user_data);
431 }
432
433 /**
434  * g_volume_eject_finish:
435  * @volume: pointer to a #GVolume.
436  * @result: a #GAsyncResult.
437  * @error: a #GError.
438  * 
439  * Finishes ejecting a volume.
440  * 
441  * Returns: %TRUE, %FALSE if operation failed.
442  **/
443 gboolean
444 g_volume_eject_finish (GVolume  *volume,
445                        GAsyncResult      *result,
446                        GError           **error)
447 {
448   GVolumeIface *iface;
449
450   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
451   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
452
453   if (G_IS_SIMPLE_ASYNC_RESULT (result))
454     {
455       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
456       if (g_simple_async_result_propagate_error (simple, error))
457         return FALSE;
458     }
459   
460   iface = G_VOLUME_GET_IFACE (volume);
461   return (* iface->eject_finish) (volume, result, error);
462 }
463
464 /**
465  * g_volume_get_identifier:
466  * @volume: a #GVolume
467  * @kind: the kind of identifier to return
468  *
469  * Gets the identifier of the given kind for @volume. 
470  * See the <link linkend="volume-identifier">introduction</link>
471  * for more information about volume identifiers.
472  *
473  * Returns: a newly allocated string containing the
474  *   requested identfier, or %NULL if the #GVolume
475  *   doesn't have this kind of identifier
476  */
477 char *
478 g_volume_get_identifier (GVolume    *volume,
479                          const char *kind)
480 {
481   GVolumeIface *iface;
482
483   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
484   g_return_val_if_fail (kind != NULL, NULL);
485
486   iface = G_VOLUME_GET_IFACE (volume);
487
488   if (iface->get_identifier == NULL)
489     return NULL;
490   
491   return (* iface->get_identifier) (volume, kind);
492 }
493
494 /**
495  * g_volume_enumerate_identifiers:
496  * @volume: a #GVolume
497  * 
498  * Gets the kinds of <link linkend="volume-identifier">identifiers</link>
499  * that @volume has. Use g_volume_get_identifer() to obtain 
500  * the identifiers themselves.
501  *
502  * Returns: a %NULL-terminated array of strings containing
503  *   kinds of identifiers. Use g_strfreev() to free.
504  */
505 char **
506 g_volume_enumerate_identifiers (GVolume *volume)
507 {
508   GVolumeIface *iface;
509
510   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
511   iface = G_VOLUME_GET_IFACE (volume);
512
513   if (iface->enumerate_identifiers == NULL)
514     return NULL;
515   
516   return (* iface->enumerate_identifiers) (volume);
517 }
518
519
520 #define __G_VOLUME_C__
521 #include "gioaliasdef.c"