[glib] Bug 585591 – Starting/stopping drives



commit fae755e0568472a2c37e6a9d0ad0fde809749a1f
Author: David Zeuthen <davidz redhat com>
Date:   Mon Jun 15 10:53:41 2009 -0400

    Bug 585591 â?? Starting/stopping drives
    
    Add API for starting/stopping drives. This new API will enable
    GVolumeMonitor and GVfs implementations to add support for the
    following features
    
     1. Powering down external hard disk enclosures / drives
    
     2. Starting/stopping multi-disk devices (such as RAID/btrfs/ZFS)
    
     3. Connecting/disconnecting iSCSI devices
    
     4. Reacting to the user pressing e.g. the "remove drive" button on
        a IBM/Lenovo Ultrabay: http://www.thinkwiki.org/wiki/Ultrabay
    
    See the bug for the corresponding GVfs and Nautilus changes.

 docs/reference/gio/gio-sections.txt |   16 ++
 gio/gdrive.c                        |  259 ++++++++++++++++++++++++++++++++++-
 gio/gdrive.h                        |   57 ++++++++
 gio/gfile.c                         |  179 ++++++++++++++++++++++++
 gio/gfile.h                         |   41 ++++++
 gio/gfileinfo.h                     |   31 ++++
 gio/gio.symbols                     |   13 ++
 gio/gioenums.h                      |   39 ++++++
 gio/gunionvolumemonitor.c           |   12 ++
 gio/gvolumemonitor.c                |   18 +++
 gio/gvolumemonitor.h                |    5 +-
 11 files changed, 666 insertions(+), 4 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 278a9cd..8f11172 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -151,6 +151,10 @@ g_file_unmount_mountable
 g_file_unmount_mountable_finish
 g_file_eject_mountable
 g_file_eject_mountable_finish
+g_file_start_mountable
+g_file_start_mountable_finish
+g_file_stop_mountable
+g_file_stop_mountable_finish
 g_file_mount_enclosing_volume
 g_file_mount_enclosing_volume_finish
 g_file_monitor_directory
@@ -246,6 +250,9 @@ G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
 G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
 G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE
 G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP
+G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE
 G_FILE_ATTRIBUTE_TIME_MODIFIED
 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC
 G_FILE_ATTRIBUTE_TIME_ACCESS
@@ -1022,11 +1029,16 @@ g_volume_get_type
 <TITLE>GDrive</TITLE>
 GDrive
 GDriveIface
+GDriveStartFlags
+GDriveStartStopType
 g_drive_get_name
 g_drive_get_icon
 g_drive_has_volumes
 g_drive_get_volumes
 g_drive_can_eject
+g_drive_get_start_stop_type
+g_drive_can_start
+g_drive_can_stop
 g_drive_can_poll_for_media
 g_drive_poll_for_media
 g_drive_poll_for_media_finish
@@ -1035,6 +1047,10 @@ g_drive_is_media_check_automatic
 g_drive_is_media_removable
 g_drive_eject
 g_drive_eject_finish
+g_drive_start
+g_drive_start_finish
+g_drive_stop
+g_drive_stop_finish
 g_drive_enumerate_identifiers
 g_drive_get_identifier
 <SUBSECTION Standard>
diff --git a/gio/gdrive.c b/gio/gdrive.c
index 9450819..43909a3 100644
--- a/gio/gdrive.c
+++ b/gio/gdrive.c
@@ -32,12 +32,12 @@
 
 /**
  * SECTION:gdrive
- * @short_description: Virtual File System drive management
+ * @short_description: Drive management
  * @include: gio/gio.h
- * 
+ *
  * #GDrive - this represent a piece of hardware connected to the machine.
  * It's generally only created for removable hardware or hardware with
- * removable media. 
+ * removable media.
  *
  * #GDrive is a container class for #GVolume objects that stem from
  * the same piece of media. As such, #GDrive abstracts a drive with
@@ -50,6 +50,15 @@
  * as a poll for media operation is potententially expensive and may
  * spin up the drive creating noise.
  *
+ * #GDrive supports starting and stopping drives with authentication
+ * support for the former. This can be used to support a diverse set
+ * of use cases including connecting/disconnecting iSCSI devices,
+ * powering down external disk enclosures and starting/stopping
+ * multi-disk devices such as RAID devices. Note that the actual
+ * semantics and side-effects of starting/stopping a #GDrive may vary
+ * according to implementation. To choose the correct verbs in e.g. a
+ * file manager, use g_drive_get_start_stop_type().
+ *
  * For porting from GnomeVFS note that there is no equivalent of
  * #GDrive in that API.
  **/
@@ -148,6 +157,23 @@ g_drive_base_init (gpointer g_class)
                     g_cclosure_marshal_VOID__VOID,
                     G_TYPE_NONE, 0);
 
+      /**
+      * GDrive::stop-button:
+      * @drive: a #GDrive.
+      *
+      * Emitted when the physical stop button (if any) of a drive has
+      * been pressed.
+      *
+      * Since: 2.22
+      **/
+      g_signal_new (I_("stop-button"),
+                    G_TYPE_DRIVE,
+                    G_SIGNAL_RUN_LAST,
+                    G_STRUCT_OFFSET (GDriveIface, stop_button),
+                    NULL, NULL,
+                    g_cclosure_marshal_VOID__VOID,
+                    G_TYPE_NONE, 0);
+
       initialized = TRUE;
     }
 }
@@ -542,6 +568,233 @@ g_drive_enumerate_identifiers (GDrive *drive)
   return (* iface->enumerate_identifiers) (drive);
 }
 
+/**
+ * g_drive_get_start_stop_type:
+ * @drive: a #GDrive.
+ *
+ * Gets a hint about how a drive can be started/stopped.
+ *
+ * Returns: A value from the #GDriveStartStopType enumeration.
+ *
+ * Since: 2.22
+ */
+GDriveStartStopType
+g_drive_get_start_stop_type (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->get_start_stop_type == NULL)
+    return G_DRIVE_START_STOP_TYPE_UNKNOWN;
+
+  return (* iface->get_start_stop_type) (drive);
+}
+
+
+/**
+ * g_drive_can_start:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be started.
+ *
+ * Returns: %TRUE if the @drive can be started, %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_can_start (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->can_start == NULL)
+    return FALSE;
+
+  return (* iface->can_start) (drive);
+}
+
+/**
+ * g_drive_start:
+ * @drive: a #GDrive.
+ * @flags: flags affecting the start operation.
+ * @start_operation: a #GMountOperation or %NULL to avoid user interaction.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback, or %NULL.
+ * @user_data: user data to pass to @callback
+ *
+ * Asynchronously starts a drive.
+ *
+ * When the operation is finished, @callback will be called.
+ * You can then call g_drive_start_finish() to obtain the
+ * result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_drive_start (GDrive              *drive,
+               GDriveStartFlags     flags,
+               GMountOperation     *start_operation,
+               GCancellable        *cancellable,
+               GAsyncReadyCallback  callback,
+               gpointer             user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->start == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement start"));
+      return;
+    }
+
+  (* iface->start) (drive, flags, start_operation, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_start_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes starting a drive.
+ *
+ * Returns: %TRUE if the drive has been started successfully,
+ *     %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_start_finish (GDrive         *drive,
+                      GAsyncResult   *result,
+                      GError        **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->start_finish) (drive, result, error);
+}
+
+/**
+ * g_drive_can_stop:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be stopped.
+ *
+ * Returns: %TRUE if the @drive can be stopped, %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_can_stop (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->can_stop == NULL)
+    return FALSE;
+
+  return (* iface->can_stop) (drive);
+}
+
+/**
+ * g_drive_stop:
+ * @drive: a #GDrive.
+ * @flags: flags affecting the unmount if required for stopping.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback, or %NULL.
+ * @user_data: user data to pass to @callback
+ *
+ * Asynchronously stops a drive.
+ *
+ * When the operation is finished, @callback will be called.
+ * You can then call g_drive_stop_finish() to obtain the
+ * result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_drive_stop (GDrive               *drive,
+              GMountUnmountFlags    flags,
+              GCancellable         *cancellable,
+              GAsyncReadyCallback   callback,
+              gpointer              user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->stop == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement stop"));
+      return;
+    }
+
+  (* iface->stop) (drive, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_stop_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes stopping a drive.
+ *
+ * Returns: %TRUE if the drive has been stopped successfully,
+ *     %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_stop_finish (GDrive        *drive,
+                     GAsyncResult  *result,
+                     GError       **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->stop_finish) (drive, result, error);
+}
 
 #define __G_DRIVE_C__
 #include "gioaliasdef.c"
diff --git a/gio/gdrive.h b/gio/gdrive.h
index e1bc321..4c932f6 100644
--- a/gio/gdrive.h
+++ b/gio/gdrive.h
@@ -60,6 +60,14 @@ G_BEGIN_DECLS
  *    the #GDrive doesn't have one.
  * @enumerate_identifiers: Returns an array strings listing the kinds
  *    of identifiers which the #GDrive has.
+ * @get_start_stop_type: Gets a #GDriveStartStopType with details about starting/stopping the drive. Since 2.22.
+ * @can_stop: Returns %TRUE if a #GDrive can be stopped. Since 2.22.
+ * @stop: Stops a #GDrive. Since 2.22.
+ * @stop_finish: Finishes a stop operation. Since 2.22.
+ * @can_start: Returns %TRUE if a #GDrive can be started. Since 2.22.
+ * @start: Starts a #GDrive. Since 2.22.
+ * @start_finish: Finishes a start operation. Since 2.22.
+ * @stop_button: Signal emitted when the physical stop button (if any) of a drive have been pressed. Since 2.22.
  *
  * Interface for creating #GDrive implementations.
  */
@@ -103,6 +111,32 @@ struct _GDriveIface
   char *   (* get_identifier)           (GDrive              *drive,
                                          const char          *kind);
   char **  (* enumerate_identifiers)    (GDrive              *drive);
+
+  GDriveStartStopType (* get_start_stop_type) (GDrive        *drive);
+
+  gboolean (* can_start)                (GDrive              *drive);
+  void     (* start)                    (GDrive              *drive,
+                                         GDriveStartFlags     flags,
+                                         GMountOperation     *start_operation,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  gboolean (* start_finish)             (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+
+  gboolean (* can_stop)                 (GDrive              *drive);
+  void     (* stop)                     (GDrive              *drive,
+                                         GMountUnmountFlags   flags,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  gboolean (* stop_finish)              (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+  /* signal, not VFunc */
+  void     (* stop_button)              (GDrive              *drive);
+
 };
 
 GType    g_drive_get_type                 (void) G_GNUC_CONST;
@@ -135,6 +169,29 @@ char *   g_drive_get_identifier           (GDrive              *drive,
 					   const char          *kind);
 char **  g_drive_enumerate_identifiers    (GDrive              *drive);
 
+GDriveStartStopType g_drive_get_start_stop_type (GDrive        *drive);
+
+gboolean g_drive_can_start                (GDrive              *drive);
+void     g_drive_start                    (GDrive              *drive,
+                                           GDriveStartFlags     flags,
+                                           GMountOperation     *start_operation,
+                                           GCancellable        *cancellable,
+                                           GAsyncReadyCallback  callback,
+                                           gpointer             user_data);
+gboolean g_drive_start_finish             (GDrive               *drive,
+                                           GAsyncResult         *result,
+                                           GError              **error);
+
+gboolean g_drive_can_stop                 (GDrive               *drive);
+void     g_drive_stop                     (GDrive               *drive,
+					   GMountUnmountFlags    flags,
+                                           GCancellable         *cancellable,
+                                           GAsyncReadyCallback   callback,
+                                           gpointer              user_data);
+gboolean g_drive_stop_finish              (GDrive               *drive,
+                                           GAsyncResult         *result,
+                                           GError              **error);
+
 G_END_DECLS
 
 #endif /* __G_DRIVE_H__ */
diff --git a/gio/gfile.c b/gio/gfile.c
index d91bda9..ccb0402 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -6572,5 +6572,184 @@ g_file_replace_contents_finish (GFile         *file,
   return TRUE;
 }
 
+/**
+ * g_file_start_mountable:
+ * @file: input #GFile.
+ * @flags: flags affecting the operation
+ * @start_operation: a #GMountOperation, or %NULL to avoid user interaction.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
+ * @user_data: the data to pass to callback function
+ *
+ * Starts a file of type G_FILE_TYPE_MOUNTABLE.
+ * Using @start_operation, you can request callbacks when, for instance,
+ * passwords are needed during authentication.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * g_file_mount_mountable_finish() to get the result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_file_start_mountable (GFile                      *file,
+                        GDriveStartFlags            flags,
+                        GMountOperation            *start_operation,
+                        GCancellable               *cancellable,
+                        GAsyncReadyCallback         callback,
+                        gpointer                    user_data)
+{
+  GFileIface *iface;
+
+  g_return_if_fail (G_IS_FILE (file));
+
+  iface = G_FILE_GET_IFACE (file);
+
+  if (iface->start_mountable == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (file),
+					   callback,
+					   user_data,
+					   G_IO_ERROR,
+					   G_IO_ERROR_NOT_SUPPORTED,
+					   _("Operation not supported"));
+      return;
+    }
+
+  (* iface->start_mountable) (file,
+			      flags,
+			      start_operation,
+			      cancellable,
+			      callback,
+			      user_data);
+}
+
+/**
+ * g_file_start_mountable_finish:
+ * @file: input #GFile.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes a start operation. See g_file_start_mountable() for details.
+ *
+ * Finish an asynchronous start operation that was started
+ * with g_file_start_mountable().
+ *
+ * Returns: %TRUE if the operation finished successfully. %FALSE
+ * otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_file_start_mountable_finish (GFile                      *file,
+                               GAsyncResult               *result,
+                               GError                    **error)
+{
+  GFileIface *iface;
+
+  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_FILE_GET_IFACE (file);
+  return (* iface->start_mountable_finish) (file, result, error);
+}
+
+/**
+ * g_file_stop_mountable:
+ * @file: input #GFile.
+ * @flags: flags affecting the operation
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied, or %NULL.
+ * @user_data: the data to pass to callback function
+ *
+ * Stops a file of type G_FILE_TYPE_MOUNTABLE.
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * g_file_stop_mountable_finish() to get the result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_file_stop_mountable (GFile                      *file,
+                       GMountUnmountFlags          flags,
+                       GCancellable               *cancellable,
+                       GAsyncReadyCallback         callback,
+                       gpointer                    user_data)
+{
+  GFileIface *iface;
+
+  g_return_if_fail (G_IS_FILE (file));
+
+  iface = G_FILE_GET_IFACE (file);
+
+  if (iface->stop_mountable == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (file),
+					   callback,
+					   user_data,
+					   G_IO_ERROR,
+					   G_IO_ERROR_NOT_SUPPORTED,
+					   _("Operation not supported"));
+      return;
+    }
+
+  (* iface->stop_mountable) (file,
+                             flags,
+                             cancellable,
+                             callback,
+                             user_data);
+}
+
+/**
+ * g_file_stop_mountable_finish:
+ * @file: input #GFile.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an stop operation, see g_file_stop_mountable() for details.
+ *
+ * Finish an asynchronous stop operation that was started
+ * with g_file_stop_mountable().
+ *
+ * Returns: %TRUE if the operation finished successfully. %FALSE
+ * otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_file_stop_mountable_finish (GFile                      *file,
+                              GAsyncResult               *result,
+                              GError                    **error)
+{
+  GFileIface *iface;
+
+  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_FILE_GET_IFACE (file);
+  return (* iface->stop_mountable_finish) (file, result, error);
+}
+
 #define __G_FILE_C__
 #include "gioaliasdef.c"
diff --git a/gio/gfile.h b/gio/gfile.h
index aeb372e..3707c82 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -141,6 +141,10 @@ typedef struct _GFileIface    		GFileIface;
  * @replace_readwrite: Replaces file read/write. Since 2.22.
  * @replace_readwrite_async: Asynchronously replaces file read/write. Since 2.22.
  * @replace_readwrite_finish: Finishes an asynchronous replace read/write. Since 2.22.
+ * @start_mountable: Starts a mountable object. Since 2.22.
+ * @start_mountable_finish: Finishes an start operation. Since 2.22.
+ * @stop_mountable: Stops a mountable. Since 2.22.
+ * @stop_mountable_finish: Finishes an stop operation. Since 2.22.
  *
  * An interface for writing VFS file handles.
  **/
@@ -482,6 +486,25 @@ struct _GFileIface
   GFileIOStream *     (* replace_readwrite_finish)    (GFile                *file,
                                                        GAsyncResult         *res,
                                                        GError              **error);
+
+  void                (* start_mountable)             (GFile                *file,
+                                                       GDriveStartFlags      flags,
+                                                       GMountOperation      *start_operation,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+  gboolean            (* start_mountable_finish)      (GFile                *file,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+
+  void                (* stop_mountable)              (GFile                *file,
+                                                       GMountUnmountFlags    flags,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+  gboolean            (* stop_mountable_finish)       (GFile                *file,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
 };
 
 GType                   g_file_get_type                   (void) G_GNUC_CONST;
@@ -843,6 +866,24 @@ GFileMonitor*           g_file_monitor                    (GFile
 							   GCancellable           *cancellable,
 							   GError                **error);
 
+void                    g_file_start_mountable            (GFile                      *file,
+							   GDriveStartFlags            flags,
+							   GMountOperation            *start_operation,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
+gboolean                g_file_start_mountable_finish     (GFile                      *file,
+							   GAsyncResult               *result,
+							   GError                    **error);
+void                    g_file_stop_mountable             (GFile                      *file,
+							   GMountUnmountFlags          flags,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
+gboolean                g_file_stop_mountable_finish      (GFile                      *file,
+							   GAsyncResult               *result,
+							   GError                    **error);
+
 
 /* Utilities */
 
diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h
index 9c3907e..0d0c49c 100644
--- a/gio/gfileinfo.h
+++ b/gio/gfileinfo.h
@@ -370,6 +370,37 @@ typedef struct _GFileInfoClass   GFileInfoClass;
  **/
 #define G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI "mountable::hal-udi"         /* string */
 
+/**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START:
+ *
+ * A key in the "mountable" namespace for checking if a file (of type G_FILE_TYPE_MOUNTABLE) can be started.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START "mountable::can-start"     /* boolean */
+
+/**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP:
+ *
+ * A key in the "mountable" namespace for checking if a file (of type G_FILE_TYPE_MOUNTABLE) can be stopped.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP "mountable::can-stop"      /* boolean */
+
+/**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE:
+ *
+ * A key in the "mountable" namespace for getting the #GDriveStartStopType.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_UINT32.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE "mountable::start-stop-type" /* uint32 (GDriveStartStopType) */
+
+
 /* Time attributes */
 
 /**
diff --git a/gio/gio.symbols b/gio/gio.symbols
index a0e96dd..1eaf373 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -214,6 +214,13 @@ g_drive_poll_for_media
 g_drive_poll_for_media_finish
 g_drive_get_identifier
 g_drive_enumerate_identifiers
+g_drive_get_start_stop_type
+g_drive_can_start
+g_drive_start
+g_drive_start_finish
+g_drive_can_stop
+g_drive_stop
+g_drive_stop_finish
 #endif
 #endif
 
@@ -332,6 +339,10 @@ g_file_open_readwrite_finish
 g_file_replace_readwrite
 g_file_replace_readwrite_async
 g_file_replace_readwrite_finish
+g_file_start_mountable
+g_file_start_mountable_finish
+g_file_stop_mountable
+g_file_stop_mountable_finish
 #endif
 #endif
 
@@ -863,6 +874,8 @@ g_filesystem_preview_type_get_type G_GNUC_CONST
 g_io_error_enum_get_type G_GNUC_CONST
 g_mount_mount_flags_get_type G_GNUC_CONST
 g_mount_operation_result_get_type G_GNUC_CONST
+g_drive_start_flags_get_type G_GNUC_CONST
+g_drive_start_stop_type_get_type G_GNUC_CONST
 g_output_stream_splice_flags_get_type G_GNUC_CONST
 g_ask_password_flags_get_type G_GNUC_CONST
 g_password_save_get_type G_GNUC_CONST
diff --git a/gio/gioenums.h b/gio/gioenums.h
index af68078..f061172 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -198,6 +198,45 @@ typedef enum {
   G_MOUNT_UNMOUNT_FORCE = (1 << 0)
 } GMountUnmountFlags;
 
+/**
+ * GDriveStartFlags:
+ * @G_DRIVE_START_NONE: No flags set.
+ *
+ * Flags used when starting a drive.
+ *
+ * Since: 2.22
+ */
+typedef enum {
+  G_DRIVE_START_NONE = 0
+} GDriveStartFlags;
+
+/**
+ * GDriveStartStopType:
+ * @G_DRIVE_START_STOP_TYPE_UNKNOWN: Unknown or drive doesn't support
+ *    start/stop.
+ * @G_DRIVE_START_STOP_TYPE_SHUTDOWN: The stop method will physically
+ *    shut down the drive and e.g. power down the port the drive is
+ *    attached to.
+ * @G_DRIVE_START_STOP_TYPE_NETWORK: The start/stop methods are used
+ *    for connecting/disconnect to the drive over the network.
+ * @G_DRIVE_START_STOP_TYPE_MULTIDISK: The start/stop methods will
+ *    assemble/disassemble a virtual drive from several physical
+ *    drives.
+ * @G_DRIVE_START_STOP_TYPE_PASSWORD: The start/stop methods will
+ *    unlock/lock the disk (for example using the ATA <quote>SECURITY
+ *    UNLOCK DEVICE</quote> command)
+ *
+ * Enumeration describing how a drive can be started/stopped.
+ *
+ * Since: 2.22
+ */
+typedef enum {
+  G_DRIVE_START_STOP_TYPE_UNKNOWN,
+  G_DRIVE_START_STOP_TYPE_SHUTDOWN,
+  G_DRIVE_START_STOP_TYPE_NETWORK,
+  G_DRIVE_START_STOP_TYPE_MULTIDISK,
+  G_DRIVE_START_STOP_TYPE_PASSWORD
+} GDriveStartStopType;
 
 /**
  * GFileCopyFlags:
diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c
index 12ef95c..d70b4e6 100644
--- a/gio/gunionvolumemonitor.c
+++ b/gio/gunionvolumemonitor.c
@@ -363,6 +363,16 @@ child_drive_eject_button (GVolumeMonitor      *child_monitor,
 }
 
 static void
+child_drive_stop_button (GVolumeMonitor      *child_monitor,
+                         GDrive             *child_drive,
+                         GUnionVolumeMonitor *union_monitor)
+{
+  g_signal_emit_by_name (union_monitor,
+                         "drive-stop-button",
+                         child_drive);
+}
+
+static void
 g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor,
                                     GVolumeMonitor      *volume_monitor)
 {
@@ -384,6 +394,7 @@ g_union_volume_monitor_add_monitor (GUnionVolumeMonitor *union_monitor,
   g_signal_connect (volume_monitor, "drive-disconnected", (GCallback)child_drive_disconnected, union_monitor);
   g_signal_connect (volume_monitor, "drive-changed", (GCallback)child_drive_changed, union_monitor);
   g_signal_connect (volume_monitor, "drive-eject-button", (GCallback)child_drive_eject_button, union_monitor);
+  g_signal_connect (volume_monitor, "drive-stop-button", (GCallback)child_drive_stop_button, union_monitor);
 }
 
 static void
@@ -409,6 +420,7 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor,
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_disconnected, union_monitor);
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_eject_button, union_monitor);
+  g_signal_handlers_disconnect_by_func (child_monitor, child_drive_stop_button, union_monitor);
 }
 
 static GType
diff --git a/gio/gvolumemonitor.c b/gio/gvolumemonitor.c
index 3265fe4..168a174 100644
--- a/gio/gvolumemonitor.c
+++ b/gio/gvolumemonitor.c
@@ -57,6 +57,7 @@ enum {
   DRIVE_DISCONNECTED,
   DRIVE_CHANGED,
   DRIVE_EJECT_BUTTON,
+  DRIVE_STOP_BUTTON,
   LAST_SIGNAL
 };
 
@@ -247,6 +248,23 @@ g_volume_monitor_class_init (GVolumeMonitorClass *klass)
                                               g_cclosure_marshal_VOID__OBJECT,
                                               G_TYPE_NONE, 1, G_TYPE_DRIVE);
 
+  /**
+   * GVolumeMonitor::drive-stop-button:
+   * @volume_monitor: The volume monitor emitting the signal.
+   * @drive: the drive where the stop button was pressed
+   *
+   * Emitted when the stop button is pressed on @drive.
+   *
+   * Since: 2.22
+   **/
+  signals[DRIVE_STOP_BUTTON] = g_signal_new (I_("drive-stop-button"),
+                                             G_TYPE_VOLUME_MONITOR,
+                                             G_SIGNAL_RUN_LAST,
+                                             G_STRUCT_OFFSET (GVolumeMonitorClass, drive_stop_button),
+                                             NULL, NULL,
+                                             g_cclosure_marshal_VOID__OBJECT,
+                                             G_TYPE_NONE, 1, G_TYPE_DRIVE);
+
 }
 
 static void
diff --git a/gio/gvolumemonitor.h b/gio/gvolumemonitor.h
index 4d286f1..9e3bd80 100644
--- a/gio/gvolumemonitor.h
+++ b/gio/gvolumemonitor.h
@@ -117,6 +117,10 @@ struct _GVolumeMonitorClass
   void      (* drive_eject_button)   (GVolumeMonitor *volume_monitor,
                                       GDrive         *drive);
 
+  /* signal added in 2.21 */
+  void      (* drive_stop_button)   (GVolumeMonitor *volume_monitor,
+                                     GDrive         *drive);
+
   /*< private >*/
   /* Padding for future expansion */
   void (*_g_reserved1) (void);
@@ -125,7 +129,6 @@ struct _GVolumeMonitorClass
   void (*_g_reserved4) (void);
   void (*_g_reserved5) (void);
   void (*_g_reserved6) (void);
-  void (*_g_reserved7) (void);
 };
 
 GType           g_volume_monitor_get_type             (void) G_GNUC_CONST;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]