[glib] Allow interaction when unmounting mounts



commit 99a1c47343d09ab0485c2377e5c8c53e847d84dd
Author: David Zeuthen <davidz redhat com>
Date:   Sun Jul 5 21:59:38 2009 -0400

    Allow interaction when unmounting mounts
    
    For details, see bug 587482. The new api:
    
     - Provide new _with_operation() variants of all unmount and eject methods
    
     - Add GMountOperation::show-processes signal
       - this can be used to show processes blocking an unmount operation
    
     - Deprecate all unmount and eject methods
    
     - Add g_drive_can_start_degraded() method
       - this is to avoid auto-starting degraded drives
    
     - Make g_drive_stop() resp. g_file_stop_mountable() take a GMountOperation
       - these ops were recently added and not yet public API so it's fine
         to change how they work
    
     - Provide a way to poll mountable files, e.g. g_file_poll_mountable()
    
     - Add some missing file attributes for mountable files
      - G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE
        - needed for the GDU Nautilus extensions to format a volume
      - G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED:
        - mimics g_drive_can_start_degraded()
      - G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL:
        - mimics g_drive_can_poll_for_media()
      - G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC
        - mimics g_drive_is_media_check_automatic()

 docs/reference/gio/Makefile.am      |    2 +
 docs/reference/gio/gio-docs.xml     |    5 +-
 docs/reference/gio/gio-sections.txt |   19 +++
 gio/gdrive.c                        |  124 ++++++++++++++-
 gio/gdrive.h                        |   32 ++++-
 gio/gfile.c                         |  305 ++++++++++++++++++++++++++++++++++-
 gio/gfile.h                         |   66 ++++++++
 gio/gfileinfo.h                     |   43 +++++-
 gio/gio-marshal.list                |    1 +
 gio/gio.symbols                     |   47 ++++--
 gio/gmount.c                        |  186 +++++++++++++++++++++-
 gio/gmount.h                        |   48 ++++++-
 gio/gmountoperation.c               |   76 +++++++--
 gio/gmountoperation.h               |    6 +-
 gio/gvolume.c                       |   89 ++++++++++
 gio/gvolume.h                       |   23 +++
 16 files changed, 1027 insertions(+), 45 deletions(-)
---
diff --git a/docs/reference/gio/Makefile.am b/docs/reference/gio/Makefile.am
index 14d8f8a..40b4130 100644
--- a/docs/reference/gio/Makefile.am
+++ b/docs/reference/gio/Makefile.am
@@ -83,9 +83,11 @@ INCLUDES = \
 	-I$(top_srcdir)			\
 	-I$(top_srcdir)/glib		\
 	-I$(top_srcdir)/gobject		\
+	-I$(top_srcdir)/gio		\
 	-I$(top_builddir)		\
 	-I$(top_builddir)/glib		\
 	-I$(top_builddir)/gobject	\
+	-I$(top_builddir)/gio		\
 	$(GLIB_DEBUG_FLAGS)
 
 GTKDOC_LIBS = \
diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index 6df88da..c0345bc 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -24,8 +24,8 @@
         <xi:include href="xml/gfileattribute.xml"/>
     	<xi:include href="xml/gfileinfo.xml"/>
 	<xi:include href="xml/gfileenumerator.xml"/>
-	<xi:include href="xml/gmountoperation.xml"/>
 	<xi:include href="xml/gioerror.xml"/>
+	<xi:include href="xml/gmountoperation.xml"/>
     </chapter>
     <chapter id="file_mon">
     	<title>File System Monitoring</title>
@@ -145,6 +145,9 @@
   <index>
     <title id="index-all">Index</title>
   </index>
+  <index role="deprecated">
+    <title>Index of deprecated symbols</title>
+  </index>
   <index role="2.18">
     <title>Index of new symbols in 2.18</title>
   </index>
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 8f11172..f178a70 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -149,12 +149,18 @@ g_file_mount_mountable
 g_file_mount_mountable_finish
 g_file_unmount_mountable
 g_file_unmount_mountable_finish
+g_file_unmount_mountable_with_operation
+g_file_unmount_mountable_with_operation_finish
 g_file_eject_mountable
 g_file_eject_mountable_finish
+g_file_eject_mountable_with_operation
+g_file_eject_mountable_with_operation_finish
 g_file_start_mountable
 g_file_start_mountable_finish
 g_file_stop_mountable
 g_file_stop_mountable_finish
+g_file_poll_mountable
+g_file_poll_mountable_finish
 g_file_mount_enclosing_volume
 g_file_mount_enclosing_volume_finish
 g_file_monitor_directory
@@ -249,8 +255,12 @@ G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT
 G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT
 G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT
 G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE
+G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE
 G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL
+G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC
 G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START
+G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED
 G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP
 G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE
 G_FILE_ATTRIBUTE_TIME_MODIFIED
@@ -970,11 +980,15 @@ GMountMountFlags
 GMountUnmountFlags
 g_mount_unmount
 g_mount_unmount_finish
+g_mount_unmount_with_operation
+g_mount_unmount_with_operation_finish
 g_mount_remount
 g_mount_remount_finish
 g_mount_can_eject
 g_mount_eject
 g_mount_eject_finish
+g_mount_eject_with_operation
+g_mount_eject_with_operation_finish
 g_mount_guess_content_type
 g_mount_guess_content_type_finish
 g_mount_guess_content_type_sync
@@ -1008,6 +1022,8 @@ g_volume_mount_finish
 g_volume_can_eject
 g_volume_eject
 g_volume_eject_finish
+g_volume_eject_with_operation
+g_volume_eject_with_operation_finish
 G_VOLUME_IDENTIFIER_KIND_HAL_UDI
 G_VOLUME_IDENTIFIER_KIND_LABEL
 G_VOLUME_IDENTIFIER_KIND_NFS_MOUNT
@@ -1038,6 +1054,7 @@ g_drive_get_volumes
 g_drive_can_eject
 g_drive_get_start_stop_type
 g_drive_can_start
+g_drive_can_start_degraded
 g_drive_can_stop
 g_drive_can_poll_for_media
 g_drive_poll_for_media
@@ -1047,6 +1064,8 @@ g_drive_is_media_check_automatic
 g_drive_is_media_removable
 g_drive_eject
 g_drive_eject_finish
+g_drive_eject_with_operation
+g_drive_eject_with_operation_finish
 g_drive_start
 g_drive_start_finish
 g_drive_stop
diff --git a/gio/gdrive.c b/gio/gdrive.c
index 43909a3..a120c3d 100644
--- a/gio/gdrive.c
+++ b/gio/gdrive.c
@@ -386,6 +386,8 @@ g_drive_can_poll_for_media (GDrive *drive)
  * When the operation is finished, @callback will be called.
  * You can then call g_drive_eject_finish() to obtain the
  * result of the operation.
+ *
+ * Deprecated: 2.22: Use g_drive_eject_with_operation() instead.
  **/
 void
 g_drive_eject (GDrive              *drive,
@@ -422,6 +424,8 @@ g_drive_eject (GDrive              *drive,
  * 
  * Returns: %TRUE if the drive has been ejected successfully,
  *     %FALSE otherwise.
+ *
+ * Deprecated: 2.22: Use g_drive_eject_with_operation_finish() instead.
  **/
 gboolean
 g_drive_eject_finish (GDrive        *drive,
@@ -446,6 +450,91 @@ g_drive_eject_finish (GDrive        *drive,
 }
 
 /**
+ * g_drive_eject_with_operation:
+ * @drive: a #GDrive.
+ * @flags: flags affecting the unmount if required for eject
+ * @mount_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 passed to @callback.
+ *
+ * Ejects a drive. This is an asynchronous operation, and is
+ * finished by calling g_drive_eject_with_operation_finish() with the @drive
+ * and #GAsyncResult data returned in the @callback.
+ *
+ * Since: 2.22
+ **/
+void
+g_drive_eject_with_operation (GDrive              *drive,
+                              GMountUnmountFlags   flags,
+                              GMountOperation     *mount_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->eject == NULL && iface->eject_with_operation == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive),
+					   callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   /* Translators: This is an error
+					    * message for drive objects that
+					    * don't implement any of eject or eject_with_operation. */
+					   _("drive doesn't implement eject or eject_with_operation"));
+      return;
+    }
+
+  if (iface->eject_with_operation != NULL)
+    (* iface->eject_with_operation) (drive, flags, mount_operation, cancellable, callback, user_data);
+  else
+    (* iface->eject) (drive, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_eject_with_operation_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ *     ignore.
+ *
+ * Finishes ejecting a drive. If any errors occurred during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * Returns: %TRUE if the drive was successfully ejected. %FALSE otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_drive_eject_with_operation_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);
+  if (iface->eject_with_operation_finish != NULL)
+    return (* iface->eject_with_operation_finish) (drive, result, error);
+  else
+    return (* iface->eject_finish) (drive, result, error);
+}
+
+/**
  * g_drive_poll_for_media:
  * @drive: a #GDrive.
  * @cancellable: optional #GCancellable object, %NULL to ignore.
@@ -620,10 +709,35 @@ g_drive_can_start (GDrive *drive)
 }
 
 /**
+ * g_drive_can_start_degraded:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be started degraded.
+ *
+ * Returns: %TRUE if the @drive can be started degraded, %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_can_start_degraded (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->can_start_degraded == NULL)
+    return FALSE;
+
+  return (* iface->can_start_degraded) (drive);
+}
+
+/**
  * g_drive_start:
  * @drive: a #GDrive.
  * @flags: flags affecting the start operation.
- * @start_operation: a #GMountOperation or %NULL to avoid user interaction.
+ * @mount_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
@@ -639,7 +753,7 @@ g_drive_can_start (GDrive *drive)
 void
 g_drive_start (GDrive              *drive,
                GDriveStartFlags     flags,
-               GMountOperation     *start_operation,
+               GMountOperation     *mount_operation,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
@@ -658,7 +772,7 @@ g_drive_start (GDrive              *drive,
       return;
     }
 
-  (* iface->start) (drive, flags, start_operation, cancellable, callback, user_data);
+  (* iface->start) (drive, flags, mount_operation, cancellable, callback, user_data);
 }
 
 /**
@@ -725,6 +839,7 @@ g_drive_can_stop (GDrive *drive)
  * g_drive_stop:
  * @drive: a #GDrive.
  * @flags: flags affecting the unmount if required for stopping.
+ * @mount_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
@@ -740,6 +855,7 @@ g_drive_can_stop (GDrive *drive)
 void
 g_drive_stop (GDrive               *drive,
               GMountUnmountFlags    flags,
+              GMountOperation      *mount_operation,
               GCancellable         *cancellable,
               GAsyncReadyCallback   callback,
               gpointer              user_data)
@@ -758,7 +874,7 @@ g_drive_stop (GDrive               *drive,
       return;
     }
 
-  (* iface->stop) (drive, flags, cancellable, callback, user_data);
+  (* iface->stop) (drive, flags, mount_operation, cancellable, callback, user_data);
 }
 
 /**
diff --git a/gio/gdrive.h b/gio/gdrive.h
index 4c932f6..b4bfc03 100644
--- a/gio/gdrive.h
+++ b/gio/gdrive.h
@@ -65,9 +65,12 @@ G_BEGIN_DECLS
  * @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.
+ * @can_start_degraded: Returns %TRUE if a #GDrive can be started degraded. 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.
+ * @eject_with_operation: Starts ejecting a #GDrive using a #GMountOperation. Since 2.22.
+ * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
  *
  * Interface for creating #GDrive implementations.
  */
@@ -115,9 +118,10 @@ struct _GDriveIface
   GDriveStartStopType (* get_start_stop_type) (GDrive        *drive);
 
   gboolean (* can_start)                (GDrive              *drive);
+  gboolean (* can_start_degraded)       (GDrive              *drive);
   void     (* start)                    (GDrive              *drive,
                                          GDriveStartFlags     flags,
-                                         GMountOperation     *start_operation,
+                                         GMountOperation     *mount_operation,
                                          GCancellable        *cancellable,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data);
@@ -128,6 +132,7 @@ struct _GDriveIface
   gboolean (* can_stop)                 (GDrive              *drive);
   void     (* stop)                     (GDrive              *drive,
                                          GMountUnmountFlags   flags,
+                                         GMountOperation     *mount_operation,
                                          GCancellable        *cancellable,
                                          GAsyncReadyCallback  callback,
                                          gpointer             user_data);
@@ -137,6 +142,15 @@ struct _GDriveIface
   /* signal, not VFunc */
   void     (* stop_button)              (GDrive              *drive);
 
+  void        (* eject_with_operation)      (GDrive              *drive,
+                                             GMountUnmountFlags   flags,
+                                             GMountOperation     *mount_operation,
+                                             GCancellable        *cancellable,
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+  gboolean    (* eject_with_operation_finish) (GDrive            *drive,
+                                             GAsyncResult        *result,
+                                             GError             **error);
 };
 
 GType    g_drive_get_type                 (void) G_GNUC_CONST;
@@ -150,6 +164,7 @@ gboolean g_drive_has_media                (GDrive               *drive);
 gboolean g_drive_is_media_check_automatic (GDrive               *drive);
 gboolean g_drive_can_poll_for_media       (GDrive               *drive);
 gboolean g_drive_can_eject                (GDrive               *drive);
+#ifndef G_DISABLE_DEPRECATED
 void     g_drive_eject                    (GDrive               *drive,
 					   GMountUnmountFlags    flags,
                                            GCancellable         *cancellable,
@@ -158,6 +173,7 @@ void     g_drive_eject                    (GDrive               *drive,
 gboolean g_drive_eject_finish             (GDrive               *drive,
                                            GAsyncResult         *result,
                                            GError              **error);
+#endif
 void     g_drive_poll_for_media           (GDrive               *drive,
                                            GCancellable         *cancellable,
                                            GAsyncReadyCallback   callback,
@@ -172,9 +188,10 @@ char **  g_drive_enumerate_identifiers    (GDrive              *drive);
 GDriveStartStopType g_drive_get_start_stop_type (GDrive        *drive);
 
 gboolean g_drive_can_start                (GDrive              *drive);
+gboolean g_drive_can_start_degraded       (GDrive              *drive);
 void     g_drive_start                    (GDrive              *drive,
                                            GDriveStartFlags     flags,
-                                           GMountOperation     *start_operation,
+                                           GMountOperation     *mount_operation,
                                            GCancellable        *cancellable,
                                            GAsyncReadyCallback  callback,
                                            gpointer             user_data);
@@ -185,6 +202,7 @@ gboolean g_drive_start_finish             (GDrive               *drive,
 gboolean g_drive_can_stop                 (GDrive               *drive);
 void     g_drive_stop                     (GDrive               *drive,
 					   GMountUnmountFlags    flags,
+                                           GMountOperation      *mount_operation,
                                            GCancellable         *cancellable,
                                            GAsyncReadyCallback   callback,
                                            gpointer              user_data);
@@ -192,6 +210,16 @@ gboolean g_drive_stop_finish              (GDrive               *drive,
                                            GAsyncResult         *result,
                                            GError              **error);
 
+void        g_drive_eject_with_operation      (GDrive              *drive,
+                                               GMountUnmountFlags   flags,
+                                               GMountOperation     *mount_operation,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data);
+gboolean    g_drive_eject_with_operation_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 1a95f94..54a41c0 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -109,8 +109,8 @@
  * take a very long time to finish, and blocking may leave an application
  * unusable. Notable cases include:
  * g_file_mount_mountable() to mount a mountable file.
- * g_file_unmount_mountable() to unmount a mountable file.
- * g_file_eject_mountable() to eject a mountable file.
+ * g_file_unmount_mountable_with_operation() to unmount a mountable file.
+ * g_file_eject_mountable_with_operation() to eject a mountable file.
  * 
  * <para id="gfile-etag"><indexterm><primary>entity tag</primary></indexterm>
  * One notable feature of #GFile<!-- -->s are entity tags, or "etags" for 
@@ -4164,6 +4164,8 @@ g_file_mount_mountable_finish (GFile         *file,
  *
  * When the operation is finished, @callback will be called. You can then call
  * g_file_unmount_mountable_finish() to get the result of the operation.
+ *
+ * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation() instead.
  **/
 void
 g_file_unmount_mountable (GFile               *file,
@@ -4209,6 +4211,8 @@ g_file_unmount_mountable (GFile               *file,
  *
  * Returns: %TRUE if the operation finished successfully. %FALSE
  * otherwise.
+ *
+ * Deprecated: 2.22: Use g_file_unmount_mountable_with_operation_finish() instead.
  **/
 gboolean
 g_file_unmount_mountable_finish (GFile         *file,
@@ -4232,6 +4236,106 @@ g_file_unmount_mountable_finish (GFile         *file,
 }
 
 /**
+ * g_file_unmount_mountable_with_operation:
+ * @file: input #GFile.
+ * @flags: flags affecting the operation
+ * @mount_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
+ *
+ * Unmounts 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_unmount_mountable_finish() to get the result of the operation.
+ *
+ * Since: 2.22
+ **/
+void
+g_file_unmount_mountable_with_operation (GFile               *file,
+                                         GMountUnmountFlags   flags,
+                                         GMountOperation     *mount_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->unmount_mountable == NULL && iface->unmount_mountable_with_operation == 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;
+    }
+
+  if (iface->unmount_mountable_with_operation != NULL)
+    (* iface->unmount_mountable_with_operation) (file,
+                                                 flags,
+                                                 mount_operation,
+                                                 cancellable,
+                                                 callback,
+                                                 user_data);
+  else
+    (* iface->unmount_mountable) (file,
+                                  flags,
+                                  cancellable,
+                                  callback,
+                                  user_data);
+}
+
+/**
+ * g_file_unmount_mountable_with_operation_finish:
+ * @file: input #GFile.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an unmount operation, see g_file_unmount_mountable_with_operation() for details.
+ *
+ * Finish an asynchronous unmount operation that was started
+ * with g_file_unmount_mountable_with_operation().
+ *
+ * Returns: %TRUE if the operation finished successfully. %FALSE
+ * otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_file_unmount_mountable_with_operation_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);
+  if (iface->unmount_mountable_with_operation_finish != NULL)
+    return (* iface->unmount_mountable_with_operation_finish) (file, result, error);
+  else
+    return (* iface->unmount_mountable_finish) (file, result, error);
+}
+
+/**
  * g_file_eject_mountable:
  * @file: input #GFile.
  * @flags: flags affecting the operation
@@ -4247,6 +4351,8 @@ g_file_unmount_mountable_finish (GFile         *file,
  * 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. 
+ *
+ * Deprecated: 2.22: Use g_file_eject_mountable_with_operation() instead.
  **/
 void
 g_file_eject_mountable (GFile               *file,
@@ -4290,6 +4396,8 @@ g_file_eject_mountable (GFile               *file,
  * 
  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
  * otherwise.
+ *
+ * Deprecated: 2.22: Use g_file_eject_mountable_with_operation_finish() instead.
  **/
 gboolean
 g_file_eject_mountable_finish (GFile         *file,
@@ -4313,6 +4421,104 @@ g_file_eject_mountable_finish (GFile         *file,
 }
 
 /**
+ * g_file_eject_mountable_with_operation:
+ * @file: input #GFile.
+ * @flags: flags affecting the operation
+ * @mount_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 an asynchronous eject on a mountable.
+ * When this operation has completed, @callback will be called with
+ * @user_user data, and the operation can be finalized with
+ * g_file_eject_mountable_with_operation_finish().
+ *
+ * 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.
+ *
+ * Since: 2.22
+ **/
+void
+g_file_eject_mountable_with_operation (GFile               *file,
+                                       GMountUnmountFlags   flags,
+                                       GMountOperation     *mount_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->eject_mountable == NULL && iface->eject_mountable_with_operation == 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;
+    }
+
+  if (iface->eject_mountable_with_operation != NULL)
+    (* iface->eject_mountable_with_operation) (file,
+                                               flags,
+                                               mount_operation,
+                                               cancellable,
+                                               callback,
+                                               user_data);
+  else
+    (* iface->eject_mountable) (file,
+                                flags,
+                                cancellable,
+                                callback,
+                                user_data);
+}
+
+/**
+ * g_file_eject_mountable_with_operation_finish:
+ * @file: input #GFile.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous eject operation started by
+ * g_file_eject_mountable_with_operation().
+ *
+ * Returns: %TRUE if the @file was ejected successfully. %FALSE
+ * otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_file_eject_mountable_with_operation_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);
+  if (iface->eject_mountable_with_operation_finish != NULL)
+    return (* iface->eject_mountable_with_operation_finish) (file, result, error);
+  else
+    return (* iface->eject_mountable_finish) (file, result, error);
+}
+
+/**
  * g_file_monitor_directory:
  * @file: input #GFile.
  * @flags: a set of #GFileMonitorFlags.
@@ -6668,6 +6874,7 @@ g_file_start_mountable_finish (GFile                      *file,
  * g_file_stop_mountable:
  * @file: input #GFile.
  * @flags: flags affecting the operation
+ * @mount_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
@@ -6686,6 +6893,7 @@ g_file_start_mountable_finish (GFile                      *file,
 void
 g_file_stop_mountable (GFile                      *file,
                        GMountUnmountFlags          flags,
+                       GMountOperation            *mount_operation,
                        GCancellable               *cancellable,
                        GAsyncReadyCallback         callback,
                        gpointer                    user_data)
@@ -6709,6 +6917,7 @@ g_file_stop_mountable (GFile                      *file,
 
   (* iface->stop_mountable) (file,
                              flags,
+                             mount_operation,
                              cancellable,
                              callback,
                              user_data);
@@ -6752,6 +6961,90 @@ g_file_stop_mountable_finish (GFile                      *file,
 }
 
 /**
+ * g_file_poll_mountable:
+ * @file: input #GFile.
+ * @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
+ *
+ * Polls 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_mount_mountable_finish() to get the result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_file_poll_mountable (GFile                      *file,
+                       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->poll_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->poll_mountable) (file,
+                             cancellable,
+                             callback,
+                             user_data);
+}
+
+/**
+ * g_file_poll_mountable_finish:
+ * @file: input #GFile.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes a poll operation. See g_file_poll_mountable() for details.
+ *
+ * Finish an asynchronous poll operation that was polled
+ * with g_file_poll_mountable().
+ *
+ * Returns: %TRUE if the operation finished successfully. %FALSE
+ * otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_file_poll_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->poll_mountable_finish) (file, result, error);
+}
+
+/**
  * g_file_supports_thread_contexts:
  * @file: a #GFile.
  *
@@ -6768,12 +7061,12 @@ g_file_stop_mountable_finish (GFile                      *file,
 gboolean
 g_file_supports_thread_contexts (GFile *file)
 {
-  GFileIface *iface;
+ GFileIface *iface;
 
-  g_return_val_if_fail (G_IS_FILE (file), FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
 
-  iface = G_FILE_GET_IFACE (file);
-  return iface->supports_thread_contexts;
+ iface = G_FILE_GET_IFACE (file);
+ return iface->supports_thread_contexts;
 }
 
 #define __G_FILE_C__
diff --git a/gio/gfile.h b/gio/gfile.h
index 1df47c6..4e5bfe6 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -145,6 +145,12 @@ typedef struct _GFileIface    		GFileIface;
  * @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.
+ * @unmount_mountable_with_operation: Unmounts a mountable object using a #GMountOperation. Since 2.22.
+ * @unmount_mountable_with_operation_finish: Finishes an unmount operation using a #GMountOperation. Since 2.22.
+ * @eject_mountable_with_operation: Ejects a mountable object using a #GMountOperation. Since 2.22.
+ * @eject_mountable_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
+ * @poll_mountable: Polls a mountable object for media changes. Since 2.22.
+ * @poll_mountable_finish: Finishes an poll operation for media changes. Since 2.22.
  *
  * An interface for writing VFS file handles.
  **/
@@ -499,13 +505,43 @@ struct _GFileIface
 
   void                (* stop_mountable)              (GFile                *file,
                                                        GMountUnmountFlags    flags,
+                                                       GMountOperation      *mount_operation,
                                                        GCancellable         *cancellable,
                                                        GAsyncReadyCallback   callback,
                                                        gpointer              user_data);
   gboolean            (* stop_mountable_finish)       (GFile                *file,
                                                        GAsyncResult         *result,
                                                        GError              **error);
+
   gboolean            supports_thread_contexts;
+
+  void                (* unmount_mountable_with_operation) (GFile           *file,
+                                                       GMountUnmountFlags    flags,
+                                                       GMountOperation      *mount_operation,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+  gboolean            (* unmount_mountable_with_operation_finish) (GFile    *file,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+
+  void                (* eject_mountable_with_operation) (GFile             *file,
+                                                       GMountUnmountFlags    flags,
+                                                       GMountOperation      *mount_operation,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+  gboolean            (* eject_mountable_with_operation_finish) (GFile      *file,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+
+  void                (* poll_mountable)              (GFile                *file,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+  gboolean            (* poll_mountable_finish)       (GFile                *file,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
 };
 
 GType                   g_file_get_type                   (void) G_GNUC_CONST;
@@ -830,6 +866,7 @@ void                    g_file_mount_mountable            (GFile
 GFile *                 g_file_mount_mountable_finish     (GFile                      *file,
 							   GAsyncResult               *result,
 							   GError                    **error);
+#ifndef G_DISABLE_DEPRECATED
 void                    g_file_unmount_mountable          (GFile                      *file,
 							   GMountUnmountFlags          flags,
 							   GCancellable               *cancellable,
@@ -838,6 +875,17 @@ void                    g_file_unmount_mountable          (GFile
 gboolean                g_file_unmount_mountable_finish   (GFile                      *file,
 							   GAsyncResult               *result,
 							   GError                    **error);
+#endif
+void                    g_file_unmount_mountable_with_operation (GFile                *file,
+							   GMountUnmountFlags          flags,
+							   GMountOperation            *mount_operation,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
+gboolean                g_file_unmount_mountable_with_operation_finish (GFile         *file,
+							   GAsyncResult               *result,
+							   GError                    **error);
+#ifndef G_DISABLE_DEPRECATED
 void                    g_file_eject_mountable            (GFile                      *file,
 							   GMountUnmountFlags          flags,
 							   GCancellable               *cancellable,
@@ -846,6 +894,16 @@ void                    g_file_eject_mountable            (GFile
 gboolean                g_file_eject_mountable_finish     (GFile                      *file,
 							   GAsyncResult               *result,
 							   GError                    **error);
+#endif
+void                    g_file_eject_mountable_with_operation (GFile                  *file,
+							   GMountUnmountFlags          flags,
+							   GMountOperation            *mount_operation,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
+gboolean                g_file_eject_mountable_with_operation_finish (GFile           *file,
+							   GAsyncResult               *result,
+							   GError                    **error);
 
 gboolean                g_file_copy_attributes            (GFile                      *source,
 							   GFile                      *destination,
@@ -878,6 +936,7 @@ gboolean                g_file_start_mountable_finish     (GFile
 							   GError                    **error);
 void                    g_file_stop_mountable             (GFile                      *file,
 							   GMountUnmountFlags          flags,
+                                                           GMountOperation            *mount_operation,
 							   GCancellable               *cancellable,
 							   GAsyncReadyCallback         callback,
 							   gpointer                    user_data);
@@ -885,6 +944,13 @@ gboolean                g_file_stop_mountable_finish      (GFile
 							   GAsyncResult               *result,
 							   GError                    **error);
 
+void                    g_file_poll_mountable             (GFile                      *file,
+							   GCancellable               *cancellable,
+							   GAsyncReadyCallback         callback,
+							   gpointer                    user_data);
+gboolean                g_file_poll_mountable_finish      (GFile                      *file,
+							   GAsyncResult               *result,
+							   GError                    **error);
 
 /* Utilities */
 
diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h
index 3fc5217..9ff5381 100644
--- a/gio/gfileinfo.h
+++ b/gio/gfileinfo.h
@@ -363,6 +363,16 @@ typedef struct _GFileInfoClass   GFileInfoClass;
 #define G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE "mountable::unix-device" /* uint32 */
 
 /**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE:
+ *
+ * A key in the "mountable" namespace for getting the unix device file.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_STRING.
+ *
+ * Since: 2.22.
+ **/
+#define G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE_FILE "mountable::unix-device-file" /* string */
+
+/**
  * G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI:
  *
  * A key in the "mountable" namespace for getting the HAL UDI for the mountable
@@ -374,13 +384,24 @@ typedef struct _GFileInfoClass   GFileInfoClass;
  * 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.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
  *
  * Since: 2.22
  */
 #define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START "mountable::can-start"     /* boolean */
 
 /**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED:
+ *
+ * A key in the "mountable" namespace for checking if a file (of type G_FILE_TYPE_MOUNTABLE) can be started
+ * degraded.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START_DEGRADED "mountable::can-start-degraded"     /* 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.
@@ -400,6 +421,26 @@ typedef struct _GFileInfoClass   GFileInfoClass;
  */
 #define G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE "mountable::start-stop-type" /* uint32 (GDriveStartStopType) */
 
+/**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL:
+ *
+ * A key in the "mountable" namespace for checking if a file (of type G_FILE_TYPE_MOUNTABLE) can be polled.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_POLL "mountable::can-poll"      /* boolean */
+
+/**
+ * G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC:
+ *
+ * A key in the "mountable" namespace for checking if a file (of type G_FILE_TYPE_MOUNTABLE)
+ * is automatically polled for media.
+ * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN.
+ *
+ * Since: 2.22
+ */
+#define G_FILE_ATTRIBUTE_MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC "mountable::is-media-check-automatic"      /* boolean */
 
 /* Time attributes */
 
diff --git a/gio/gio-marshal.list b/gio/gio-marshal.list
index ee0d2e3..269ec35 100644
--- a/gio/gio-marshal.list
+++ b/gio/gio-marshal.list
@@ -3,3 +3,4 @@ VOID:STRING,BOXED
 VOID:BOOLEAN,POINTER
 VOID:OBJECT,OBJECT,ENUM
 BOOLEAN:OBJECT,OBJECT
+VOID:STRING,BOXED,BOXED
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 6a11ad9..166b677 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -208,19 +208,24 @@ g_drive_has_media
 g_drive_is_media_check_automatic
 g_drive_can_poll_for_media
 g_drive_can_eject
-g_drive_eject
-g_drive_eject_finish
+g_drive_eject_with_operation
+g_drive_eject_with_operation_finish
 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_can_start_degraded
 g_drive_start
 g_drive_start_finish
 g_drive_can_stop
 g_drive_stop
 g_drive_stop_finish
+#ifndef G_DISABLE_DEPRECATED
+g_drive_eject
+g_drive_eject_finish
+#endif
 #endif
 #endif
 
@@ -313,10 +318,10 @@ g_file_mount_enclosing_volume
 g_file_mount_enclosing_volume_finish
 g_file_mount_mountable
 g_file_mount_mountable_finish
-g_file_unmount_mountable
-g_file_unmount_mountable_finish
-g_file_eject_mountable
-g_file_eject_mountable_finish
+g_file_unmount_mountable_with_operation
+g_file_unmount_mountable_with_operation_finish
+g_file_eject_mountable_with_operation
+g_file_eject_mountable_with_operation_finish
 g_file_copy_attributes
 g_file_monitor_directory
 g_file_monitor_file
@@ -344,6 +349,14 @@ g_file_start_mountable_finish
 g_file_stop_mountable
 g_file_stop_mountable_finish
 g_file_supports_thread_contexts
+g_file_poll_mountable
+g_file_poll_mountable_finish
+#ifndef G_DISABLE_DEPRECATED
+g_file_unmount_mountable
+g_file_unmount_mountable_finish
+g_file_eject_mountable
+g_file_eject_mountable_finish
+#endif
 #endif
 #endif
 
@@ -785,10 +798,10 @@ g_mount_get_volume
 g_mount_get_drive 
 g_mount_can_unmount 
 g_mount_can_eject 
-g_mount_unmount 
-g_mount_unmount_finish 
-g_mount_eject 
-g_mount_eject_finish 
+g_mount_unmount_with_operation
+g_mount_unmount_with_operation_finish
+g_mount_eject_with_operation
+g_mount_eject_with_operation_finish
 g_mount_remount 
 g_mount_remount_finish 
 g_mount_guess_content_type
@@ -797,6 +810,12 @@ g_mount_guess_content_type_sync
 g_mount_is_shadowed
 g_mount_shadow
 g_mount_unshadow
+#ifndef G_DISABLE_DEPRECATED
+g_mount_unmount 
+g_mount_unmount_finish 
+g_mount_eject 
+g_mount_eject_finish 
+#endif
 #endif
 #endif
 
@@ -813,11 +832,15 @@ g_volume_can_mount
 g_volume_can_eject
 g_volume_mount 
 g_volume_mount_finish 
-g_volume_eject 
-g_volume_eject_finish
+g_volume_eject_with_operation
+g_volume_eject_with_operation_finish
 g_volume_get_identifier
 g_volume_enumerate_identifiers
 g_volume_get_activation_root
+#ifndef G_DISABLE_DEPRECATED
+g_volume_eject 
+g_volume_eject_finish
+#endif
 #endif
 #endif
 
diff --git a/gio/gmount.c b/gio/gmount.c
index e4753c4..124583c 100644
--- a/gio/gmount.c
+++ b/gio/gmount.c
@@ -53,13 +53,13 @@
  * Unmounting a #GMount instance is an asynchronous operation. For
  * more information about asynchronous operations, see #GAsyncReady
  * and #GSimpleAsyncReady. To unmount a #GMount instance, first call
- * g_mount_unmount() with (at least) the #GMount instance and a
+ * g_mount_unmount_with_operation() with (at least) the #GMount instance and a
  * #GAsyncReadyCallback.  The callback will be fired when the
  * operation has resolved (either with success or failure), and a
  * #GAsyncReady structure will be passed to the callback.  That
- * callback should then call g_mount_unmount_finish() with the #GMount
+ * callback should then call g_mount_unmount_with_operation_finish() with the #GMount
  * and the #GAsyncReady data to see if the operation was completed
- * successfully.  If an @error is present when g_mount_unmount_finish() 
+ * successfully.  If an @error is present when g_mount_unmount_with_operation_finish() 
  * is called, then it will be filled with any error information.
  **/
 
@@ -351,6 +351,8 @@ g_mount_can_eject (GMount *mount)
  * Unmounts a mount. This is an asynchronous operation, and is 
  * finished by calling g_mount_unmount_finish() with the @mount 
  * and #GAsyncResult data returned in the @callback.
+ *
+ * Deprecated: 2.22: Use g_mount_unmount_with_operation() instead.
  **/
 void
 g_mount_unmount (GMount              *mount,
@@ -392,6 +394,8 @@ g_mount_unmount (GMount              *mount,
  * @error will be set to contain the errors and %FALSE will be returned.
  * 
  * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
+ *
+ * Deprecated: 2.22: Use g_mount_unmount_with_operation_finish() instead.
  **/
 gboolean
 g_mount_unmount_finish (GMount        *mount,
@@ -426,6 +430,8 @@ g_mount_unmount_finish (GMount        *mount,
  * Ejects a mount. This is an asynchronous operation, and is 
  * finished by calling g_mount_eject_finish() with the @mount 
  * and #GAsyncResult data returned in the @callback.
+ *
+ * Deprecated: 2.22: Use g_mount_eject_with_operation() instead.
  **/
 void
 g_mount_eject (GMount              *mount,
@@ -467,6 +473,8 @@ g_mount_eject (GMount              *mount,
  * @error will be set to contain the errors and %FALSE will be returned.
  * 
  * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
+ *
+ * Deprecated: 2.22: Use g_mount_eject_with_operation_finish() instead.
  **/
 gboolean
 g_mount_eject_finish (GMount        *mount,
@@ -490,6 +498,178 @@ g_mount_eject_finish (GMount        *mount,
 }
 
 /**
+ * g_mount_unmount_with_operation:
+ * @mount: a #GMount.
+ * @flags: flags affecting the operation
+ * @mount_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 passed to @callback.
+ *
+ * Unmounts a mount. This is an asynchronous operation, and is
+ * finished by calling g_mount_unmount_with_operation_finish() with the @mount 
+ * and #GAsyncResult data returned in the @callback.
+ *
+ * Since: 2.22
+ **/
+void
+g_mount_unmount_with_operation (GMount              *mount,
+                                GMountUnmountFlags   flags,
+                                GMountOperation     *mount_operation,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
+{
+  GMountIface *iface;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  iface = G_MOUNT_GET_IFACE (mount);
+
+  if (iface->unmount == NULL && iface->unmount_with_operation == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (mount),
+					   callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   /* Translators: This is an error
+					    * message for mount objects that
+					    * don't implement any of unmount or unmount_with_operation. */
+					   _("mount doesn't implement unmount or unmount_with_operation"));
+
+      return;
+    }
+
+  if (iface->unmount_with_operation != NULL)
+    (* iface->unmount_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
+  else
+    (* iface->unmount) (mount, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_mount_unmount_with_operation_finish:
+ * @mount: a #GMount.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ *     ignore.
+ *
+ * Finishes unmounting a mount. If any errors occurred during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_mount_unmount_with_operation_finish (GMount        *mount,
+                                       GAsyncResult  *result,
+                                       GError       **error)
+{
+  GMountIface *iface;
+
+  g_return_val_if_fail (G_IS_MOUNT (mount), 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_MOUNT_GET_IFACE (mount);
+  if (iface->unmount_with_operation_finish != NULL)
+    return (* iface->unmount_with_operation_finish) (mount, result, error);
+  else
+    return (* iface->unmount_finish) (mount, result, error);
+}
+
+
+/**
+ * g_mount_eject_with_operation:
+ * @mount: a #GMount.
+ * @flags: flags affecting the unmount if required for eject
+ * @mount_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 passed to @callback.
+ *
+ * Ejects a mount. This is an asynchronous operation, and is
+ * finished by calling g_mount_eject_with_operation_finish() with the @mount
+ * and #GAsyncResult data returned in the @callback.
+ *
+ * Since: 2.22
+ **/
+void
+g_mount_eject_with_operation (GMount              *mount,
+                              GMountUnmountFlags   flags,
+                              GMountOperation     *mount_operation,
+                              GCancellable        *cancellable,
+                              GAsyncReadyCallback  callback,
+                              gpointer             user_data)
+{
+  GMountIface *iface;
+
+  g_return_if_fail (G_IS_MOUNT (mount));
+
+  iface = G_MOUNT_GET_IFACE (mount);
+
+  if (iface->eject == NULL && iface->eject_with_operation == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (mount),
+					   callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   /* Translators: This is an error
+					    * message for mount objects that
+					    * don't implement any of eject or eject_with_operation. */
+					   _("mount doesn't implement eject or eject_with_operation"));
+      return;
+    }
+
+  if (iface->eject_with_operation != NULL)
+    (* iface->eject_with_operation) (mount, flags, mount_operation, cancellable, callback, user_data);
+  else
+    (* iface->eject) (mount, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_mount_eject_with_operation_finish:
+ * @mount: a #GMount.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ *     ignore.
+ *
+ * Finishes ejecting a mount. If any errors occurred during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_mount_eject_with_operation_finish (GMount        *mount,
+                                     GAsyncResult  *result,
+                                     GError       **error)
+{
+  GMountIface *iface;
+
+  g_return_val_if_fail (G_IS_MOUNT (mount), 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_MOUNT_GET_IFACE (mount);
+  if (iface->eject_with_operation_finish != NULL)
+    return (* iface->eject_with_operation_finish) (mount, result, error);
+  else
+    return (* iface->eject_finish) (mount, result, error);
+}
+
+/**
  * g_mount_remount:
  * @mount: a #GMount.
  * @flags: flags affecting the operation
diff --git a/gio/gmount.h b/gio/gmount.h
index 41d092e..18e9229 100644
--- a/gio/gmount.h
+++ b/gio/gmount.h
@@ -64,6 +64,10 @@ typedef struct _GMountIface    GMountIface;
  *     type guessing. This operation was added in 2.18.
  * @guess_content_type_finish: Finishes a contenet type guessing operation. Added in 2.18.
  * @guess_content_type_sync: Synchronous variant of @guess_content_type. Added in 2.18
+ * @unmount_with_operation: Starts unmounting a #GMount using a #GMountOperation. Since 2.22.
+ * @unmount_with_operation_finish: Finishes an unmounting operation using a #GMountOperation. Since 2.22.
+ * @eject_with_operation: Starts ejecting a #GMount using a #GMountOperation. Since 2.22.
+ * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
  *
  * Interface for implementing operations for mounts.
  **/
@@ -128,8 +132,28 @@ struct _GMountIface
                                              GCancellable        *cancellable,
                                              GError             **error);
 
-  /* yet more signals */
+  /* Signal, not VFunc */
   void        (* pre_unmount)               (GMount              *mount);
+
+  void        (* unmount_with_operation)    (GMount              *mount,
+                                             GMountUnmountFlags   flags,
+                                             GMountOperation     *mount_operation,
+                                             GCancellable        *cancellable,
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+  gboolean    (* unmount_with_operation_finish) (GMount          *mount,
+                                             GAsyncResult        *result,
+                                             GError             **error);
+
+  void        (* eject_with_operation)      (GMount              *mount,
+                                             GMountUnmountFlags   flags,
+                                             GMountOperation     *mount_operation,
+                                             GCancellable        *cancellable,
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+  gboolean    (* eject_with_operation_finish) (GMount            *mount,
+                                             GAsyncResult        *result,
+                                             GError             **error);
 };
 
 GType       g_mount_get_type                  (void) G_GNUC_CONST;
@@ -143,6 +167,7 @@ GDrive    * g_mount_get_drive                 (GMount              *mount);
 gboolean    g_mount_can_unmount               (GMount              *mount);
 gboolean    g_mount_can_eject                 (GMount              *mount);
 
+#ifndef G_DISABLE_DEPRECATED
 void        g_mount_unmount                   (GMount              *mount,
                                                GMountUnmountFlags   flags,
                                                GCancellable        *cancellable,
@@ -160,6 +185,7 @@ void        g_mount_eject                     (GMount              *mount,
 gboolean    g_mount_eject_finish              (GMount              *mount,
                                                GAsyncResult        *result,
                                                GError             **error);
+#endif
 
 void        g_mount_remount                   (GMount              *mount,
                                                GMountMountFlags     flags,
@@ -188,6 +214,26 @@ gboolean    g_mount_is_shadowed               (GMount              *mount);
 void        g_mount_shadow                    (GMount              *mount);
 void        g_mount_unshadow                  (GMount              *mount);
 
+void        g_mount_unmount_with_operation    (GMount              *mount,
+                                               GMountUnmountFlags   flags,
+                                               GMountOperation     *mount_operation,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data);
+gboolean    g_mount_unmount_with_operation_finish (GMount          *mount,
+                                               GAsyncResult        *result,
+                                               GError             **error);
+
+void        g_mount_eject_with_operation      (GMount              *mount,
+                                               GMountUnmountFlags   flags,
+                                               GMountOperation     *mount_operation,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data);
+gboolean    g_mount_eject_with_operation_finish (GMount            *mount,
+                                               GAsyncResult        *result,
+                                               GError             **error);
+
 G_END_DECLS
 
 #endif /* __G_MOUNT_H__ */
diff --git a/gio/gmountoperation.c b/gio/gmountoperation.c
index 18311f9..35927d4 100644
--- a/gio/gmountoperation.c
+++ b/gio/gmountoperation.c
@@ -31,25 +31,27 @@
 
 #include "gioalias.h"
 
-/** 
+/**
  * SECTION:gmountoperation
- * @short_description: Authentication methods for mountable locations
+ * @short_description: Object used for authentication and user interaction
  * @include: gio/gio.h
  *
- * #GMountOperation provides a mechanism for authenticating mountable 
- * operations, such as loop mounting files, hard drive partitions or 
- * server locations. 
+ * #GMountOperation provides a mechanism for interacting with the user.
+ * It can be used for authenticating mountable operations, such as loop
+ * mounting files, hard drive partitions or server locations. It can
+ * also be used to ask the user questions or show a list of applications
+ * preventing unmount or eject operations from completing.
  *
- * Mounting operations are handed a #GMountOperation that then can use 
- * if they require any privileges or authentication for their volumes 
- * to be mounted (e.g. a hard disk partition or an encrypted filesystem), 
- * or if they are implementing a remote server protocol which requires 
- * user credentials such as FTP or WebDAV.
+ * Note that #GMountOperation is used for more than just #GMount
+ * objects â?? for example it is also used in g_drive_start() and
+ * g_drive_stop().
  *
- * Users should instantiate a subclass of this that implements all
- * the various callbacks to show the required dialogs, such as 
- * #GtkMountOperation.
- **/
+ * Users should instantiate a subclass of this that implements all the
+ * various callbacks to show the required dialogs, such as
+ * #GtkMountOperation. If no user interaction is desired (for example
+ * when automounting filesystems at login time), usually %NULL can be
+ * passed, see each method taking a #GMountOperation for details.
+ */
 
 G_DEFINE_TYPE (GMountOperation, g_mount_operation, G_TYPE_OBJECT);
 
@@ -58,6 +60,7 @@ enum {
   ASK_QUESTION,
   REPLY,
   ABORTED,
+  SHOW_PROCESSES,
   LAST_SIGNAL
 };
 
@@ -227,6 +230,18 @@ ask_question (GMountOperation *op,
 }
 
 static void
+show_processes (GMountOperation      *op,
+                const gchar          *message,
+                GArray               *processes,
+                const gchar          *choices[])
+{
+  g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+		   reply_non_handled_in_idle,
+		   g_object_ref (op),
+		   g_object_unref);
+}
+
+static void
 g_mount_operation_class_init (GMountOperationClass *klass)
 {
   GObjectClass *object_class;
@@ -240,6 +255,7 @@ g_mount_operation_class_init (GMountOperationClass *klass)
   
   klass->ask_password = ask_password;
   klass->ask_question = ask_question;
+  klass->show_processes = show_processes;
   
   /**
    * GMountOperation::ask-password:
@@ -326,6 +342,38 @@ g_mount_operation_class_init (GMountOperationClass *klass)
 		  G_TYPE_NONE, 0);
 
   /**
+   * GMountOperation::show-processes:
+   * @op: a #GMountOperation.
+   * @message: string containing a message to display to the user.
+   * @processes: an array of #GPid for processes blocking the operation.
+   * @choices: an array of strings for each possible choice.
+   *
+   * Emitted when one or more processes are blocking an operation
+   * e.g. unmounting/ejecting a #GMount or stopping a #GDrive.
+   *
+   * Note that this signal may be emitted several times to update the
+   * list of blocking processes as processes close files. The
+   * application should only respond with g_mount_operation_reply() to
+   * the latest signal (setting #GMountOperation:choice to the choice
+   * the user made).
+   *
+   * If the message contains a line break, the first line should be
+   * presented as a heading. For example, it may be used as the
+   * primary text in a #GtkMessageDialog.
+   *
+   * Since: 2.22
+   */
+  signals[SHOW_PROCESSES] =
+    g_signal_new (I_("show-processes"),
+		  G_TYPE_FROM_CLASS (object_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GMountOperationClass, show_processes),
+		  NULL, NULL,
+		  _gio_marshal_VOID__STRING_BOXED_BOXED,
+		  G_TYPE_NONE, 3,
+		  G_TYPE_STRING, G_TYPE_ARRAY, G_TYPE_STRV);
+
+  /**
    * GMountOperation:username:
    *
    * The user name that is used for authentication when carrying out
diff --git a/gio/gmountoperation.h b/gio/gmountoperation.h
index e6ba51a..8432b80 100644
--- a/gio/gmountoperation.h
+++ b/gio/gmountoperation.h
@@ -75,6 +75,11 @@ struct _GMountOperationClass
 
   void (* aborted)      (GMountOperation       *op);
 
+  void (* show_processes) (GMountOperation      *op,
+                           const gchar          *message,
+                           GArray               *processes,
+                           const gchar          *choices[]);
+
   /*< private >*/
   /* Padding for future expansion */
   void (*_g_reserved1) (void);
@@ -87,7 +92,6 @@ struct _GMountOperationClass
   void (*_g_reserved8) (void);
   void (*_g_reserved9) (void);
   void (*_g_reserved10) (void);
-  void (*_g_reserved11) (void);
 };
 
 GType             g_mount_operation_get_type      (void) G_GNUC_CONST;
diff --git a/gio/gvolume.c b/gio/gvolume.c
index 6e3f8b7..c58679c 100644
--- a/gio/gvolume.c
+++ b/gio/gvolume.c
@@ -429,6 +429,8 @@ g_volume_mount_finish (GVolume       *volume,
  * Ejects a volume. This is an asynchronous operation, and is
  * finished by calling g_volume_eject_finish() with the @volume
  * and #GAsyncResult returned in the @callback.
+ *
+ * Deprecated: 2.22: Use g_volume_eject_with_operation() instead.
  **/
 void
 g_volume_eject (GVolume             *volume,
@@ -465,6 +467,8 @@ g_volume_eject (GVolume             *volume,
  * @error will be set to contain the errors and %FALSE will be returned.
  * 
  * Returns: %TRUE, %FALSE if operation failed.
+ *
+ * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead.
  **/
 gboolean
 g_volume_eject_finish (GVolume       *volume,
@@ -488,6 +492,91 @@ g_volume_eject_finish (GVolume       *volume,
 }
 
 /**
+ * g_volume_eject_with_operation:
+ * @volume: a #GVolume.
+ * @flags: flags affecting the unmount if required for eject
+ * @mount_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 passed to @callback.
+ *
+ * Ejects a volume. This is an asynchronous operation, and is
+ * finished by calling g_volume_eject_with_operation_finish() with the @volume
+ * and #GAsyncResult data returned in the @callback.
+ *
+ * Since: 2.22
+ **/
+void
+g_volume_eject_with_operation (GVolume              *volume,
+                               GMountUnmountFlags   flags,
+                               GMountOperation     *mount_operation,
+                               GCancellable        *cancellable,
+                               GAsyncReadyCallback  callback,
+                               gpointer             user_data)
+{
+  GVolumeIface *iface;
+
+  g_return_if_fail (G_IS_VOLUME (volume));
+
+  iface = G_VOLUME_GET_IFACE (volume);
+
+  if (iface->eject == NULL && iface->eject_with_operation == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (volume),
+					   callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   /* Translators: This is an error
+					    * message for volume objects that
+					    * don't implement any of eject or eject_with_operation. */
+					   _("volume doesn't implement eject or eject_with_operation"));
+      return;
+    }
+
+  if (iface->eject_with_operation != NULL)
+    (* iface->eject_with_operation) (volume, flags, mount_operation, cancellable, callback, user_data);
+  else
+    (* iface->eject) (volume, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_volume_eject_with_operation_finish:
+ * @volume: a #GVolume.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ *     ignore.
+ *
+ * Finishes ejecting a volume. If any errors occurred during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * Returns: %TRUE if the volume was successfully ejected. %FALSE otherwise.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_volume_eject_with_operation_finish (GVolume        *volume,
+                                      GAsyncResult  *result,
+                                      GError       **error)
+{
+  GVolumeIface *iface;
+
+  g_return_val_if_fail (G_IS_VOLUME (volume), 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_VOLUME_GET_IFACE (volume);
+  if (iface->eject_with_operation_finish != NULL)
+    return (* iface->eject_with_operation_finish) (volume, result, error);
+  else
+    return (* iface->eject_finish) (volume, result, error);
+}
+
+/**
  * g_volume_get_identifier:
  * @volume: a #GVolume
  * @kind: the kind of identifier to return
diff --git a/gio/gvolume.h b/gio/gvolume.h
index f81faad..5496d26 100644
--- a/gio/gvolume.h
+++ b/gio/gvolume.h
@@ -99,6 +99,8 @@ G_BEGIN_DECLS
  * @should_automount: Returns %TRUE if the #GVolume should be automatically mounted.
  * @get_activation_root: Returns the activation root for the #GVolume if it is known in advance or %NULL if
  *   it is not known.
+ * @eject_with_operation: Starts ejecting a #GVolume using a #GMountOperation. Since 2.22.
+ * @eject_with_operation_finish: Finishes an eject operation using a #GMountOperation. Since 2.22.
  *
  * Interface for implementing operations for mountable volumes.
  **/
@@ -148,6 +150,15 @@ struct _GVolumeIface
 
   GFile     * (* get_activation_root)   (GVolume             *volume);
 
+  void        (* eject_with_operation)      (GVolume             *volume,
+                                             GMountUnmountFlags   flags,
+                                             GMountOperation     *mount_operation,
+                                             GCancellable        *cancellable,
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+  gboolean    (* eject_with_operation_finish) (GVolume           *volume,
+                                             GAsyncResult        *result,
+                                             GError             **error);
 };
 
 GType    g_volume_get_type              (void) G_GNUC_CONST;
@@ -169,6 +180,7 @@ void     g_volume_mount                 (GVolume              *volume,
 gboolean g_volume_mount_finish          (GVolume              *volume,
 					 GAsyncResult         *result,
 					 GError              **error);
+#ifndef G_DISABLE_DEPRECATED
 void     g_volume_eject                 (GVolume              *volume,
 					 GMountUnmountFlags    flags,
 					 GCancellable         *cancellable,
@@ -177,12 +189,23 @@ void     g_volume_eject                 (GVolume              *volume,
 gboolean g_volume_eject_finish          (GVolume              *volume,
 					 GAsyncResult         *result,
 					 GError              **error);
+#endif
 char *   g_volume_get_identifier        (GVolume              *volume,
 					 const char           *kind);
 char **  g_volume_enumerate_identifiers (GVolume              *volume);
 
 GFile *  g_volume_get_activation_root   (GVolume              *volume);
 
+void        g_volume_eject_with_operation     (GVolume             *volume,
+                                               GMountUnmountFlags   flags,
+                                               GMountOperation     *mount_operation,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data);
+gboolean    g_volume_eject_with_operation_finish (GVolume          *volume,
+                                               GAsyncResult        *result,
+                                               GError             **error);
+
 G_END_DECLS
 
 #endif /* __G_VOLUME_H__ */



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