b047774b50d63ad64528603d7828db5f64f6f7e6
[platform/upstream/glib.git] / gio / gdrive.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 "gdrive.h"
26 #include "gsimpleasyncresult.h"
27 #include "glibintl.h"
28
29 #include "gioalias.h"
30
31 /**
32  * SECTION:gdrive
33  * @short_description: Virtual File System drive management
34  * @include: gio.h
35  * 
36  * #GDrive is a container class for #GVolume objects that stem from
37  * the same piece of media. As such, #GDrive abstracts a drive with
38  * (or without) removable media and provides operations for querying
39  * whether media is available, determing whether media change is
40  * automatically detected and ejecting the media.
41  *
42  * If the #GDrive reports that media isn't automatically detected, one
43  * can poll for media; typically one should not do this periodically
44  * as a poll for media operation is potententially expensive and may
45  * spin up the drive creating noise.
46  *
47  * For porting from GnomeVFS note that there is no equivalent of
48  * #GDrive in that API.
49  **/
50
51 static void g_drive_base_init (gpointer g_class);
52 static void g_drive_class_init (gpointer g_class,
53                                  gpointer class_data);
54
55 GType
56 g_drive_get_type (void)
57 {
58   static GType drive_type = 0;
59
60   if (! drive_type)
61     {
62       static const GTypeInfo drive_info =
63       {
64         sizeof (GDriveIface), /* class_size */
65         g_drive_base_init,   /* base_init */
66         NULL,           /* base_finalize */
67         g_drive_class_init,
68         NULL,           /* class_finalize */
69         NULL,           /* class_data */
70         0,
71         0,              /* n_preallocs */
72         NULL
73       };
74
75       drive_type =
76         g_type_register_static (G_TYPE_INTERFACE, I_("GDrive"),
77                                 &drive_info, 0);
78
79       g_type_interface_add_prerequisite (drive_type, G_TYPE_OBJECT);
80     }
81
82   return drive_type;
83 }
84
85 static void
86 g_drive_class_init (gpointer g_class,
87                     gpointer class_data)
88 {
89 }
90
91 static void
92 g_drive_base_init (gpointer g_class)
93 {
94   static gboolean initialized = FALSE;
95
96   if (! initialized)
97     {
98       /**
99       * GDrive::changed:
100       * @drive: a #GDrive.
101       * 
102       * Emitted when the drive's state has changed.
103       **/
104       g_signal_new (I_("changed"),
105                     G_TYPE_DRIVE,
106                     G_SIGNAL_RUN_LAST,
107                     G_STRUCT_OFFSET (GDriveIface, changed),
108                     NULL, NULL,
109                     g_cclosure_marshal_VOID__VOID,
110                     G_TYPE_NONE, 0);
111
112       /**
113       * GDrive::disconnected:
114       * @drive: a #GDrive.
115       * 
116       * This signal is emitted when the #GDrive have been
117       * disconnected. If the recipient is holding references to the
118       * object they should release them so the object can be
119       * finalized.
120       **/
121       g_signal_new (I_("disconnected"),
122                     G_TYPE_DRIVE,
123                     G_SIGNAL_RUN_LAST,
124                     G_STRUCT_OFFSET (GDriveIface, disconnected),
125                     NULL, NULL,
126                     g_cclosure_marshal_VOID__VOID,
127                     G_TYPE_NONE, 0);
128
129       /**
130       * GDrive::eject-button:
131       * @drive: a #GDrive.
132       * 
133       * Emitted when the physical eject button (if any) of a drive have been pressed.
134       * 
135       **/
136       g_signal_new (I_("eject-button"),
137                     G_TYPE_DRIVE,
138                     G_SIGNAL_RUN_LAST,
139                     G_STRUCT_OFFSET (GDriveIface, eject_button),
140                     NULL, NULL,
141                     g_cclosure_marshal_VOID__VOID,
142                     G_TYPE_NONE, 0);
143
144       initialized = TRUE;
145     }
146 }
147
148 /**
149  * g_drive_get_name:
150  * @drive: a #GDrive.
151  * 
152  * Gets the name of @drive.
153  *
154  * Returns: a string containing @drive's name. The returned 
155  *     string should be freed when no longer needed.
156  **/
157 char *
158 g_drive_get_name (GDrive *drive)
159 {
160   GDriveIface *iface;
161
162   g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
163
164   iface = G_DRIVE_GET_IFACE (drive);
165
166   return (* iface->get_name) (drive);
167 }
168
169 /**
170  * g_drive_get_icon:
171  * @drive: a #GDrive.
172  * 
173  * Gets the icon for @drive.
174  * 
175  * Returns: #GIcon for the @drive.
176  **/
177 GIcon *
178 g_drive_get_icon (GDrive *drive)
179 {
180   GDriveIface *iface;
181   
182   g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
183
184   iface = G_DRIVE_GET_IFACE (drive);
185
186   return (* iface->get_icon) (drive);
187 }
188
189 /**
190  * g_drive_has_volumes:
191  * @drive: a #GDrive.
192  * 
193  * Check if @drive has any mountable volumes.
194  * 
195  * Returns: %TRUE if the @drive contains volumes, %FALSE otherwise.
196  **/
197 gboolean
198 g_drive_has_volumes (GDrive *drive)
199 {
200   GDriveIface *iface;
201
202   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
203
204   iface = G_DRIVE_GET_IFACE (drive);
205
206   return (* iface->has_volumes) (drive);
207 }
208
209 /**
210  * g_drive_get_volumes:
211  * @drive: a #GDrive.
212  * 
213  * Get a list of mountable volumes for @drive.
214  * 
215  * Returns: #GList containing any #GVolume<!---->s on the given @drive.
216  **/
217 GList *
218 g_drive_get_volumes (GDrive *drive)
219 {
220   GDriveIface *iface;
221
222   g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
223
224   iface = G_DRIVE_GET_IFACE (drive);
225
226   return (* iface->get_volumes) (drive);
227 }
228
229 /**
230  * g_drive_is_media_check_automatic:
231  * @drive: a #GDrive.
232  * 
233  * Checks if @drive is capabable of automatically detecting media changes.
234  * 
235  * Returns: %TRUE if the @drive is capabable of automatically detecting media changes, %FALSE otherwise.
236  **/
237 gboolean
238 g_drive_is_media_check_automatic (GDrive *drive)
239 {
240   GDriveIface *iface;
241
242   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
243
244   iface = G_DRIVE_GET_IFACE (drive);
245
246   return (* iface->is_media_check_automatic) (drive);
247 }
248
249 /**
250  * g_drive_is_media_removable:
251  * @drive: a #GDrive.
252  * 
253  * Checks if the @drive supports removable media.
254  * 
255  * Returns: %TRUE if @drive supports removable media, %FALSE otherwise.
256  **/
257 gboolean
258 g_drive_is_media_removable (GDrive *drive)
259 {
260   GDriveIface *iface;
261
262   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
263
264   iface = G_DRIVE_GET_IFACE (drive);
265
266   return (* iface->is_media_removable) (drive);
267 }
268
269 /**
270  * g_drive_has_media:
271  * @drive: a #GDrive.
272  * 
273  * Checks if the @drive has media. Note that the OS may not be polling
274  * the drive for media changes; see g_drive_is_media_check_automatic()
275  * for more details.
276  * 
277  * Returns: %TRUE if @drive has media, %FALSE otherwise.
278  **/
279 gboolean
280 g_drive_has_media (GDrive *drive)
281 {
282   GDriveIface *iface;
283
284   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
285
286   iface = G_DRIVE_GET_IFACE (drive);
287
288   return (* iface->has_media) (drive);
289 }
290
291 /**
292  * g_drive_can_eject:
293  * @drive: pointer to a #GDrive.
294  * 
295  * Checks if a drive can be ejected.
296  * 
297  * Returns: %TRUE if the @drive can be ejected. %FALSE otherwise.
298  **/
299 gboolean
300 g_drive_can_eject (GDrive *drive)
301 {
302   GDriveIface *iface;
303
304   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
305
306   iface = G_DRIVE_GET_IFACE (drive);
307
308   if (iface->can_eject == NULL)
309     return FALSE;
310
311   return (* iface->can_eject) (drive);
312 }
313
314 /**
315  * g_drive_can_poll_for_media:
316  * @drive: a #GDrive.
317  * 
318  * Checks if a drive can be polled for media changes.
319  * 
320  * Returns: %TRUE if the @drive can be polled for media changes. %FALSE otherwise.
321  **/
322 gboolean
323 g_drive_can_poll_for_media (GDrive *drive)
324 {
325   GDriveIface *iface;
326
327   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
328
329   iface = G_DRIVE_GET_IFACE (drive);
330
331   if (iface->poll_for_media == NULL)
332     return FALSE;
333
334   return (* iface->can_poll_for_media) (drive);
335 }
336
337 /**
338  * g_drive_eject:
339  * @drive: a #GDrive.
340  * @cancellable: optional #GCancellable object, %NULL to ignore.
341  * @callback: a #GAsyncReadyCallback.
342  * @user_data: a #gpointer.
343  * 
344  * Ejects a drive.
345  * 
346  **/
347 void
348 g_drive_eject (GDrive              *drive,
349                GCancellable        *cancellable,
350                GAsyncReadyCallback  callback,
351                gpointer             user_data)
352 {
353   GDriveIface *iface;
354
355   g_return_if_fail (G_IS_DRIVE (drive));
356
357   iface = G_DRIVE_GET_IFACE (drive);
358
359   if (iface->eject == NULL)
360     {
361       g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
362                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
363                                            _("drive doesn't implement eject"));
364       
365       return;
366     }
367   
368   (* iface->eject) (drive, cancellable, callback, user_data);
369 }
370
371 /**
372  * g_drive_eject_finish
373  * @drive: a #GDrive.
374  * @result: a #GAsyncResult.
375  * @error: a #GError.
376  * 
377  * Finishes ejecting a drive.
378  * 
379  * Returns: %TRUE if the drive has been ejected successfully,
380  * %FALSE otherwise.
381  **/
382 gboolean
383 g_drive_eject_finish (GDrive        *drive,
384                       GAsyncResult  *result,
385                       GError       **error)
386 {
387   GDriveIface *iface;
388
389   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
390   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
391
392   if (G_IS_SIMPLE_ASYNC_RESULT (result))
393     {
394       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
395       if (g_simple_async_result_propagate_error (simple, error))
396         return FALSE;
397     }
398   
399   iface = G_DRIVE_GET_IFACE (drive);
400   
401   return (* iface->eject_finish) (drive, result, error);
402 }
403
404 /**
405  * g_drive_poll_for_media:
406  * @drive: a #GDrive.
407  * @cancellable: optional #GCancellable object, %NULL to ignore.
408  * @callback: a #GAsyncReadyCallback.
409  * @user_data: a #gpointer.
410  * 
411  * Polls @drive to see if media has been inserted or removed.
412  * 
413  **/
414 void
415 g_drive_poll_for_media (GDrive              *drive,
416                         GCancellable        *cancellable,
417                         GAsyncReadyCallback  callback,
418                         gpointer             user_data)
419 {
420   GDriveIface *iface;
421
422   g_return_if_fail (G_IS_DRIVE (drive));
423
424   iface = G_DRIVE_GET_IFACE (drive);
425
426   if (iface->poll_for_media == NULL)
427     {
428       g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
429                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
430                                            _("drive doesn't implement polling for media"));
431       
432       return;
433     }
434   
435   (* iface->poll_for_media) (drive, cancellable, callback, user_data);
436 }
437
438 /**
439  * g_drive_poll_for_media_finish
440  * @drive: a #GDrive.
441  * @result: a #GAsyncResult.
442  * @error: a #GError.
443  * 
444  * Finishes poll_for_mediaing a drive.
445  * 
446  * Returns: %TRUE if the drive has been poll_for_mediaed successfully,
447  * %FALSE otherwise.
448  **/
449 gboolean
450 g_drive_poll_for_media_finish (GDrive        *drive,
451                                GAsyncResult  *result,
452                                GError       **error)
453 {
454   GDriveIface *iface;
455
456   g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
457   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
458
459   if (G_IS_SIMPLE_ASYNC_RESULT (result))
460     {
461       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
462       if (g_simple_async_result_propagate_error (simple, error))
463         return FALSE;
464     }
465   
466   iface = G_DRIVE_GET_IFACE (drive);
467   
468   return (* iface->poll_for_media_finish) (drive, result, error);
469 }
470
471 #define __G_DRIVE_C__
472 #include "gioaliasdef.c"