Add g_drive_get_identifier and g_drive_enumerate_identifiers
[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 "gsimpleasyncresult.h"
28 #include "glibintl.h"
29
30 #include "gioalias.h"
31
32 /**
33  * SECTION:gvolume
34  * @short_description: Volume management
35  * @include: gio.h
36  * 
37  * The #GVolume interface represents user-visible objects that can be
38  * mounted. Note, when porting from GnomeVFS, #GVolume is the moral
39  * equivalent of #GnomeVFSDrive.
40  *
41  * Mounting a #GVolume instance is an asynchronous operation. For more
42  * information about asynchronous operations, see #GAsyncReady and
43  * #GSimpleAsyncReady. To mount a #GVolume, first call
44  * g_volume_mount() with (at least) the #GVolume instance, optionally
45  * a #GMountOperation object and a #GAsyncReadyCallback. 
46  *
47  * Typically, one will only want to pass %NULL for the
48  * #GMountOperation if automounting all volumes when a desktop session
49  * starts since it's not desirable to put up a lot of dialogs asking
50  * for credentials.
51  *
52  * The callback will be fired when the operation has resolved (either
53  * with success or failure), and a #GAsyncReady structure will be
54  * passed to the callback.  That callback should then call
55  * g_volume_mount_finish() with the #GVolume instance and the
56  * #GAsyncReady data to see if the operation was completed
57  * successfully.  If an @error is present when g_volume_mount_finish()
58  * is called, then it will be filled with any error information.
59  **/
60
61 static void g_volume_base_init (gpointer g_class);
62 static void g_volume_class_init (gpointer g_class,
63                                  gpointer class_data);
64
65 GType
66 g_volume_get_type (void)
67 {
68   static GType volume_type = 0;
69
70   if (! volume_type)
71     {
72       static const GTypeInfo volume_info =
73       {
74         sizeof (GVolumeIface), /* class_size */
75         g_volume_base_init,   /* base_init */
76         NULL,           /* base_finalize */
77         g_volume_class_init,
78         NULL,           /* class_finalize */
79         NULL,           /* class_data */
80         0,
81         0,              /* n_preallocs */
82         NULL
83       };
84
85       volume_type =
86         g_type_register_static (G_TYPE_INTERFACE, I_("GVolume"),
87                                 &volume_info, 0);
88
89       g_type_interface_add_prerequisite (volume_type, G_TYPE_OBJECT);
90     }
91
92   return volume_type;
93 }
94
95 static void
96 g_volume_class_init (gpointer g_class,
97                      gpointer class_data)
98 {
99 }
100
101 static void
102 g_volume_base_init (gpointer g_class)
103 {
104   static gboolean initialized = FALSE;
105
106   if (! initialized)
107     {
108      /**
109       * GVolume::changed:
110       * 
111       * Emitted when the volume has been changed.
112       **/
113       g_signal_new (I_("changed"),
114                     G_TYPE_VOLUME,
115                     G_SIGNAL_RUN_LAST,
116                     G_STRUCT_OFFSET (GVolumeIface, changed),
117                     NULL, NULL,
118                     g_cclosure_marshal_VOID__VOID,
119                     G_TYPE_NONE, 0);
120
121      /**
122       * GVolume::removed:
123       * 
124       * This signal is emitted when the #GVolume have been removed. If
125       * the recipient is holding references to the object they should
126       * release them so the object can be finalized.
127       **/
128       g_signal_new (I_("removed"),
129                     G_TYPE_VOLUME,
130                     G_SIGNAL_RUN_LAST,
131                     G_STRUCT_OFFSET (GVolumeIface, removed),
132                     NULL, NULL,
133                     g_cclosure_marshal_VOID__VOID,
134                     G_TYPE_NONE, 0);
135
136       initialized = TRUE;
137     }
138 }
139
140 /**
141  * g_volume_get_name:
142  * @volume: a #GVolume.
143  * 
144  * Gets the name of @volume.
145  * 
146  * Returns: the name for the given @volume. The returned string should 
147  * be freed when no longer needed.
148  **/
149 char *
150 g_volume_get_name (GVolume *volume)
151 {
152   GVolumeIface *iface;
153
154   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
155
156   iface = G_VOLUME_GET_IFACE (volume);
157
158   return (* iface->get_name) (volume);
159 }
160
161 /**
162  * g_volume_get_icon:
163  * @volume: a #GVolume.
164  * 
165  * Gets the icon for @volume.
166  * 
167  * Returns: a #GIcon.
168  **/
169 GIcon *
170 g_volume_get_icon (GVolume *volume)
171 {
172   GVolumeIface *iface;
173
174   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
175
176   iface = G_VOLUME_GET_IFACE (volume);
177
178   return (* iface->get_icon) (volume);
179 }
180
181 /**
182  * g_volume_get_uuid:
183  * @volume: a #GVolume.
184  * 
185  * Gets the UUID for the @volume. The reference is typically based on
186  * the file system UUID for the volume in question and should be
187  * considered an opaque string. Returns %NULL if there is no UUID
188  * available.
189  * 
190  * Returns: the UUID for @volume or %NULL if no UUID can be computed.
191  **/
192 char *
193 g_volume_get_uuid (GVolume *volume)
194 {
195   GVolumeIface *iface;
196
197   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
198
199   iface = G_VOLUME_GET_IFACE (volume);
200
201   return (* iface->get_uuid) (volume);
202 }
203   
204 /**
205  * g_volume_get_drive:
206  * @volume: a #GVolume.
207  * 
208  * Gets the drive for the @volume.
209  * 
210  * Returns: a #GDrive or %NULL if @volume is not associated with a drive.
211  **/
212 GDrive *
213 g_volume_get_drive (GVolume *volume)
214 {
215   GVolumeIface *iface;
216
217   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
218
219   iface = G_VOLUME_GET_IFACE (volume);
220
221   return (* iface->get_drive) (volume);
222 }
223
224 /**
225  * g_volume_get_mount:
226  * @volume: a #GVolume.
227  * 
228  * Gets the mount for the @volume.
229  * 
230  * Returns: a #GMount or %NULL if @volume isn't mounted.
231  **/
232 GMount *
233 g_volume_get_mount (GVolume *volume)
234 {
235   GVolumeIface *iface;
236
237   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
238
239   iface = G_VOLUME_GET_IFACE (volume);
240
241   return (* iface->get_mount) (volume);
242 }
243
244
245 /**
246  * g_volume_can_mount:
247  * @volume: a #GVolume.
248  * 
249  * Checks if a volume can be mounted.
250  * 
251  * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
252  **/
253 gboolean
254 g_volume_can_mount (GVolume *volume)
255 {
256   GVolumeIface *iface;
257
258   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
259
260   iface = G_VOLUME_GET_IFACE (volume);
261
262   if (iface->can_mount == NULL)
263     return FALSE;
264
265   return (* iface->can_mount) (volume);
266 }
267
268 /**
269  * g_volume_can_eject:
270  * @volume: a #GVolume.
271  * 
272  * Checks if a volume can be ejected.
273  * 
274  * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise.
275  **/
276 gboolean
277 g_volume_can_eject (GVolume *volume)
278 {
279   GVolumeIface *iface;
280
281   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
282
283   iface = G_VOLUME_GET_IFACE (volume);
284
285   if (iface->can_eject == NULL)
286     return FALSE;
287
288   return (* iface->can_eject) (volume);
289 }
290
291 /**
292  * g_volume_mount:
293  * @volume: a #GVolume.
294  * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
295  * @cancellable: optional #GCancellable object, %NULL to ignore.
296  * @callback: a #GAsyncReadyCallback, or %NULL.
297  * @user_data: a #gpointer.
298  * 
299  * Mounts a volume.
300  **/
301 void
302 g_volume_mount (GVolume    *volume,
303                 GMountOperation     *mount_operation,
304                 GCancellable        *cancellable,
305                 GAsyncReadyCallback  callback,
306                 gpointer             user_data)
307 {
308   GVolumeIface *iface;
309
310   g_return_if_fail (G_IS_VOLUME (volume));
311
312   iface = G_VOLUME_GET_IFACE (volume);
313
314   if (iface->mount_fn == NULL)
315     {
316       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
317                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
318                                            _("volume doesn't implement mount"));
319       
320       return;
321     }
322   
323   (* iface->mount_fn) (volume, mount_operation, cancellable, callback, user_data);
324 }
325
326 /**
327  * g_volume_mount_finish:
328  * @volume: pointer to a #GVolume.
329  * @result: a #GAsyncResult.
330  * @error: a #GError.
331  * 
332  * Finishes mounting a volume.
333  * 
334  * Returns: %TRUE, %FALSE if operation failed.
335  **/
336 gboolean
337 g_volume_mount_finish (GVolume  *volume,
338                        GAsyncResult      *result,
339                        GError           **error)
340 {
341   GVolumeIface *iface;
342
343   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
344   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
345
346   if (G_IS_SIMPLE_ASYNC_RESULT (result))
347     {
348       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
349       if (g_simple_async_result_propagate_error (simple, error))
350         return FALSE;
351     }
352   
353   iface = G_VOLUME_GET_IFACE (volume);
354   return (* iface->mount_finish) (volume, result, error);
355 }
356
357 /**
358  * g_volume_eject:
359  * @volume: a #GVolume.
360  * @flags: flags affecting the unmount if required for eject
361  * @cancellable: optional #GCancellable object, %NULL to ignore.
362  * @callback: a #GAsyncReadyCallback, or %NULL.
363  * @user_data: a #gpointer.
364  * 
365  * Ejects a volume.
366  **/
367 void
368 g_volume_eject (GVolume    *volume,
369                 GMountUnmountFlags   flags,
370                 GCancellable        *cancellable,
371                 GAsyncReadyCallback  callback,
372                 gpointer             user_data)
373 {
374   GVolumeIface *iface;
375
376   g_return_if_fail (G_IS_VOLUME (volume));
377
378   iface = G_VOLUME_GET_IFACE (volume);
379
380   if (iface->eject == NULL)
381     {
382       g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
383                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
384                                            _("volume doesn't implement eject"));
385       
386       return;
387     }
388   
389   (* iface->eject) (volume, flags, cancellable, callback, user_data);
390 }
391
392 /**
393  * g_volume_eject_finish:
394  * @volume: pointer to a #GVolume.
395  * @result: a #GAsyncResult.
396  * @error: a #GError.
397  * 
398  * Finishes ejecting a volume.
399  * 
400  * Returns: %TRUE, %FALSE if operation failed.
401  **/
402 gboolean
403 g_volume_eject_finish (GVolume  *volume,
404                        GAsyncResult      *result,
405                        GError           **error)
406 {
407   GVolumeIface *iface;
408
409   g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
410   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
411
412   if (G_IS_SIMPLE_ASYNC_RESULT (result))
413     {
414       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
415       if (g_simple_async_result_propagate_error (simple, error))
416         return FALSE;
417     }
418   
419   iface = G_VOLUME_GET_IFACE (volume);
420   return (* iface->eject_finish) (volume, result, error);
421 }
422
423 char *
424 g_volume_get_identifier (GVolume              *volume,
425                          const char          *kind)
426 {
427   GVolumeIface *iface;
428
429   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
430   g_return_val_if_fail (kind != NULL, NULL);
431
432   iface = G_VOLUME_GET_IFACE (volume);
433
434   if (iface->get_identifier == NULL)
435     return NULL;
436   
437   return (* iface->get_identifier) (volume, kind);
438 }
439
440 char **
441 g_volume_enumerate_identifiers (GVolume *volume)
442 {
443   GVolumeIface *iface;
444
445   g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
446   iface = G_VOLUME_GET_IFACE (volume);
447
448   if (iface->enumerate_identifiers == NULL)
449     return NULL;
450   
451   return (* iface->enumerate_identifiers) (volume);
452 }
453
454
455 #define __G_VOLUME_C__
456 #include "gioaliasdef.c"