* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
* David Zeuthen <davidz@redhat.com>
*/
-#include <config.h>
+#include "config.h"
#include "gmount.h"
#include "gvolume.h"
-#include "gsimpleasyncresult.h"
+#include "gthemedicon.h"
+#include "gasyncresult.h"
+#include "gtask.h"
+#include "gioerror.h"
#include "glibintl.h"
-#include "gioalias.h"
/**
* SECTION:gvolume
* @short_description: Volume management
- * @include: gio.h
+ * @include: gio/gio.h
*
* The #GVolume interface represents user-visible objects that can be
* mounted. Note, when porting from GnomeVFS, #GVolume is the moral
* equivalent of #GnomeVFSDrive.
*
* Mounting a #GVolume instance is an asynchronous operation. For more
- * information about asynchronous operations, see #GAsyncReady and
- * #GSimpleAsyncReady. To mount a #GVolume, first call
- * g_volume_mount() with (at least) the #GVolume instance, optionally
- * a #GMountOperation object and a #GAsyncReadyCallback.
+ * information about asynchronous operations, see #GAsyncResult and
+ * #GTask. To mount a #GVolume, first call g_volume_mount() with (at
+ * least) the #GVolume instance, optionally a #GMountOperation object
+ * and a #GAsyncReadyCallback.
*
* Typically, one will only want to pass %NULL for the
* #GMountOperation if automounting all volumes when a desktop session
* successfully. If an @error is present when g_volume_mount_finish()
* is called, then it will be filled with any error information.
*
- * <para id="volume-identifier">
- * It is sometimes necessary to directly access the underlying
+ * ## Volume Identifiers # {#volume-identifier}
+ *
+ * It is sometimes necessary to directly access the underlying
* operating system object behind a volume (e.g. for passing a volume
* to an application via the commandline). For this purpose, GIO
* allows to obtain an 'identifier' for the volume. There can be
* different kinds of identifiers, such as Hal UDIs, filesystem labels,
- * traditional Unix devices (e.g. <filename>/dev/sda2</filename>),
- * uuids. GIO uses predefind strings as names for the different kinds
- * of identifiers: #G_VOLUME_IDENTIFIER_KIND_HAL_UDI,
- * #G_VOLUME_IDENTIFIER_KIND_LABEL, etc. Use g_volume_get_identifier()
- * to obtain an identifier for a volume.
- * </para>
- **/
-
-static void g_volume_base_init (gpointer g_class);
-static void g_volume_class_init (gpointer g_class,
- gpointer class_data);
-
-GType
-g_volume_get_type (void)
-{
- static GType volume_type = 0;
-
- if (! volume_type)
- {
- static const GTypeInfo volume_info =
- {
- sizeof (GVolumeIface), /* class_size */
- g_volume_base_init, /* base_init */
- NULL, /* base_finalize */
- g_volume_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- volume_type =
- g_type_register_static (G_TYPE_INTERFACE, I_("GVolume"),
- &volume_info, 0);
-
- g_type_interface_add_prerequisite (volume_type, G_TYPE_OBJECT);
- }
-
- return volume_type;
-}
+ * traditional Unix devices (e.g. `/dev/sda2`), UUIDs. GIO uses predefined
+ * strings as names for the different kinds of identifiers:
+ * #G_VOLUME_IDENTIFIER_KIND_HAL_UDI, #G_VOLUME_IDENTIFIER_KIND_LABEL, etc.
+ * Use g_volume_get_identifier() to obtain an identifier for a volume.
+ *
+ *
+ * Note that #G_VOLUME_IDENTIFIER_KIND_HAL_UDI will only be available
+ * when the gvfs hal volume monitor is in use. Other volume monitors
+ * will generally be able to provide the #G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE
+ * identifier, which can be used to obtain a hal device by means of
+ * libhal_manager_find_device_string_match().
+ */
-static void
-g_volume_class_init (gpointer g_class,
- gpointer class_data)
-{
-}
+typedef GVolumeIface GVolumeInterface;
+G_DEFINE_INTERFACE(GVolume, g_volume, G_TYPE_OBJECT)
static void
-g_volume_base_init (gpointer g_class)
+g_volume_default_init (GVolumeInterface *iface)
{
- static gboolean initialized = FALSE;
-
- if (! initialized)
- {
- /**
- * GVolume::changed:
- *
- * Emitted when the volume has been changed.
- **/
- g_signal_new (I_("changed"),
- G_TYPE_VOLUME,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVolumeIface, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /**
- * GVolume::removed:
- *
- * This signal is emitted when the #GVolume have been removed. If
- * the recipient is holding references to the object they should
- * release them so the object can be finalized.
- **/
- g_signal_new (I_("removed"),
- G_TYPE_VOLUME,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GVolumeIface, removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- initialized = TRUE;
- }
+ /**
+ * GVolume::changed:
+ *
+ * Emitted when the volume has been changed.
+ */
+ g_signal_new (I_("changed"),
+ G_TYPE_VOLUME,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeIface, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * GVolume::removed:
+ *
+ * This signal is emitted when the #GVolume have been removed. If
+ * the recipient is holding references to the object they should
+ * release them so the object can be finalized.
+ */
+ g_signal_new (I_("removed"),
+ G_TYPE_VOLUME,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeIface, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
/**
* g_volume_get_name:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Gets the name of @volume.
*
* Returns: the name for the given @volume. The returned string should
- * be freed when no longer needed.
- **/
+ * be freed with g_free() when no longer needed.
+ */
char *
g_volume_get_name (GVolume *volume)
{
/**
* g_volume_get_icon:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Gets the icon for @volume.
*
- * Returns: a #GIcon.
- **/
+ * Returns: (transfer full): a #GIcon.
+ * The returned object should be unreffed with g_object_unref()
+ * when no longer needed.
+ */
GIcon *
g_volume_get_icon (GVolume *volume)
{
}
/**
+ * g_volume_get_symbolic_icon:
+ * @volume: a #GVolume
+ *
+ * Gets the symbolic icon for @volume.
+ *
+ * Returns: (transfer full): a #GIcon.
+ * The returned object should be unreffed with g_object_unref()
+ * when no longer needed.
+ *
+ * Since: 2.34
+ */
+GIcon *
+g_volume_get_symbolic_icon (GVolume *volume)
+{
+ GVolumeIface *iface;
+ GIcon *ret;
+
+ g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
+
+ iface = G_VOLUME_GET_IFACE (volume);
+
+ if (iface->get_symbolic_icon != NULL)
+ ret = iface->get_symbolic_icon (volume);
+ else
+ ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic");
+
+ return ret;
+
+}
+
+/**
* g_volume_get_uuid:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Gets the UUID for the @volume. The reference is typically based on
* the file system UUID for the volume in question and should be
* available.
*
* Returns: the UUID for @volume or %NULL if no UUID can be computed.
- **/
+ * The returned string should be freed with g_free()
+ * when no longer needed.
+ */
char *
g_volume_get_uuid (GVolume *volume)
{
/**
* g_volume_get_drive:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Gets the drive for the @volume.
*
- * Returns: a #GDrive or %NULL if @volume is not associated with a drive.
- **/
+ * Returns: (transfer full): a #GDrive or %NULL if @volume is not
+ * associated with a drive. The returned object should be unreffed
+ * with g_object_unref() when no longer needed.
+ */
GDrive *
g_volume_get_drive (GVolume *volume)
{
/**
* g_volume_get_mount:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Gets the mount for the @volume.
*
- * Returns: a #GMount or %NULL if @volume isn't mounted.
- **/
+ * Returns: (transfer full): a #GMount or %NULL if @volume isn't mounted.
+ * The returned object should be unreffed with g_object_unref()
+ * when no longer needed.
+ */
GMount *
g_volume_get_mount (GVolume *volume)
{
/**
* g_volume_can_mount:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Checks if a volume can be mounted.
*
- * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
- **/
+ * Returns: %TRUE if the @volume can be mounted. %FALSE otherwise
+ */
gboolean
g_volume_can_mount (GVolume *volume)
{
/**
* g_volume_can_eject:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
*
* Checks if a volume can be ejected.
*
- * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise.
- **/
+ * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise
+ */
gboolean
g_volume_can_eject (GVolume *volume)
{
*
* Returns whether the volume should be automatically mounted.
*
- * Returns: %TRUE if the volume should be automatically mounted.
+ * Returns: %TRUE if the volume should be automatically mounted
*/
gboolean
g_volume_should_automount (GVolume *volume)
/**
* g_volume_mount:
- * @volume: a #GVolume.
- * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @callback: a #GAsyncReadyCallback, or %NULL.
- * @user_data: a #gpointer.
+ * @volume: a #GVolume
+ * @flags: flags affecting the operation
+ * @mount_operation: (allow-none): a #GMountOperation or %NULL to avoid user interaction
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
+ * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL
+ * @user_data: user data that gets passed to @callback
*
- * Mounts a volume.
- **/
+ * Mounts a volume. This is an asynchronous operation, and is
+ * finished by calling g_volume_mount_finish() with the @volume
+ * and #GAsyncResult returned in the @callback.
+ *
+ * Virtual: mount_fn
+ */
void
-g_volume_mount (GVolume *volume,
+g_volume_mount (GVolume *volume,
+ GMountMountFlags flags,
GMountOperation *mount_operation,
GCancellable *cancellable,
GAsyncReadyCallback callback,
if (iface->mount_fn == NULL)
{
- g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
- G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("volume doesn't implement mount"));
-
+ g_task_report_new_error (volume, callback, user_data,
+ g_volume_mount,
+ G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("volume doesn't implement mount"));
return;
}
- (* iface->mount_fn) (volume, mount_operation, cancellable, callback, user_data);
+ (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data);
}
/**
* g_volume_mount_finish:
- * @volume: pointer to a #GVolume.
- * @result: a #GAsyncResult.
- * @error: a #GError.
+ * @volume: a #GVolume
+ * @result: a #GAsyncResult
+ * @error: a #GError location to store an error, or %NULL to ignore
*
- * Finishes mounting a volume.
+ * Finishes mounting a volume. If any errors occurred during the operation,
+ * @error will be set to contain the errors and %FALSE will be returned.
+ *
+ * If the mount operation succeeded, g_volume_get_mount() on @volume
+ * is guaranteed to return the mount right after calling this
+ * function; there's no need to listen for the 'mount-added' signal on
+ * #GVolumeMonitor.
*
- * Returns: %TRUE, %FALSE if operation failed.
- **/
+ * Returns: %TRUE, %FALSE if operation failed
+ */
gboolean
-g_volume_mount_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
+g_volume_mount_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;
- }
+ if (g_async_result_legacy_propagate_error (result, error))
+ return FALSE;
+ else if (g_async_result_is_tagged (result, g_volume_mount))
+ return g_task_propagate_boolean (G_TASK (result), error);
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->mount_finish) (volume, result, error);
/**
* g_volume_eject:
- * @volume: a #GVolume.
+ * @volume: a #GVolume
* @flags: flags affecting the unmount if required for eject
- * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @callback: a #GAsyncReadyCallback, or %NULL.
- * @user_data: a #gpointer.
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
+ * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL
+ * @user_data: user data that gets passed to @callback
*
- * Ejects a 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,
+g_volume_eject (GVolume *volume,
GMountUnmountFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
if (iface->eject == NULL)
{
- g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
- G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
- _("volume doesn't implement eject"));
-
+ g_task_report_new_error (volume, callback, user_data,
+ g_volume_eject_with_operation,
+ G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("volume doesn't implement eject"));
return;
}
/**
* g_volume_eject_finish:
- * @volume: pointer to a #GVolume.
- * @result: a #GAsyncResult.
- * @error: a #GError.
+ * @volume: pointer to a #GVolume
+ * @result: a #GAsyncResult
+ * @error: a #GError location to store an error, or %NULL to ignore
*
- * Finishes ejecting a volume.
+ * 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, %FALSE if operation failed.
+ * Returns: %TRUE, %FALSE if operation failed
+ *
+ * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead.
**/
gboolean
-g_volume_eject_finish (GVolume *volume,
- GAsyncResult *result,
- GError **error)
+g_volume_eject_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;
- }
+ if (g_async_result_legacy_propagate_error (result, error))
+ return FALSE;
+ if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
+ return g_task_propagate_boolean (G_TASK (result), error);
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->eject_finish) (volume, result, error);
}
/**
+ * g_volume_eject_with_operation:
+ * @volume: a #GVolume
+ * @flags: flags affecting the unmount if required for eject
+ * @mount_operation: (allow-none): a #GMountOperation or %NULL to
+ * avoid user interaction
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
+ * @callback: (allow-none): 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_task_report_new_error (volume, callback, user_data,
+ g_volume_eject_with_operation,
+ 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 occurring, or %NULL
+ *
+ * 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_async_result_legacy_propagate_error (result, error))
+ return FALSE;
+ else if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
+ return g_task_propagate_boolean (G_TASK (result), error);
+
+ 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
*
* Gets the identifier of the given kind for @volume.
- * See the <link linkend="volume-identifier">introduction</link>
- * for more information about volume identifiers.
+ * See the [introduction][volume-identifier] for more
+ * information about volume identifiers.
*
* Returns: a newly allocated string containing the
- * requested identfier, or %NULL if the #GVolume
- * doesn't have this kind of identifier
+ * requested identfier, or %NULL if the #GVolume
+ * doesn't have this kind of identifier
*/
char *
g_volume_get_identifier (GVolume *volume,
* g_volume_enumerate_identifiers:
* @volume: a #GVolume
*
- * Gets the kinds of <link linkend="volume-identifier">identifiers</link>
- * that @volume has. Use g_volume_get_identifer() to obtain
- * the identifiers themselves.
+ * Gets the kinds of [identifiers][volume-identifier] that @volume has.
+ * Use g_volume_get_identifier() to obtain the identifiers themselves.
*
- * Returns: a %NULL-terminated array of strings containing
- * kinds of identifiers. Use g_strfreev() to free.
+ * Returns: (array zero-terminated=1) (transfer full): a %NULL-terminated array
+ * of strings containing kinds of identifiers. Use g_strfreev() to free.
*/
char **
g_volume_enumerate_identifiers (GVolume *volume)
return (* iface->enumerate_identifiers) (volume);
}
+/**
+ * g_volume_get_activation_root:
+ * @volume: a #GVolume
+ *
+ * Gets the activation root for a #GVolume if it is known ahead of
+ * mount time. Returns %NULL otherwise. If not %NULL and if @volume
+ * is mounted, then the result of g_mount_get_root() on the
+ * #GMount object obtained from g_volume_get_mount() will always
+ * either be equal or a prefix of what this function returns. In
+ * other words, in code
+ *
+ * |[<!-- language="C" -->
+ * GMount *mount;
+ * GFile *mount_root
+ * GFile *volume_activation_root;
+ *
+ * mount = g_volume_get_mount (volume); // mounted, so never NULL
+ * mount_root = g_mount_get_root (mount);
+ * volume_activation_root = g_volume_get_activation_root (volume); // assume not NULL
+ * ]|
+ * then the expression
+ * |[<!-- language="C" -->
+ * (g_file_has_prefix (volume_activation_root, mount_root) ||
+ g_file_equal (volume_activation_root, mount_root))
+ * ]|
+ * will always be %TRUE.
+ *
+ * Activation roots are typically used in #GVolumeMonitor
+ * implementations to find the underlying mount to shadow, see
+ * g_mount_is_shadowed() for more details.
+ *
+ * Returns: (nullable) (transfer full): the activation root of @volume
+ * or %NULL. Use g_object_unref() to free.
+ *
+ * Since: 2.18
+ */
+GFile *
+g_volume_get_activation_root (GVolume *volume)
+{
+ GVolumeIface *iface;
+
+ g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
+ iface = G_VOLUME_GET_IFACE (volume);
+
+ if (iface->get_activation_root == NULL)
+ return NULL;
+
+ return (* iface->get_activation_root) (volume);
+}
+
+/**
+ * g_volume_get_sort_key:
+ * @volume: a #GVolume
+ *
+ * Gets the sort key for @volume, if any.
+ *
+ * Returns: Sorting key for @volume or %NULL if no such key is available
+ *
+ * Since: 2.32
+ */
+const gchar *
+g_volume_get_sort_key (GVolume *volume)
+{
+ const gchar *ret = NULL;
+ GVolumeIface *iface;
+
+ g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
+
+ iface = G_VOLUME_GET_IFACE (volume);
+ if (iface->get_sort_key != NULL)
+ ret = iface->get_sort_key (volume);
-#define __G_VOLUME_C__
-#include "gioaliasdef.c"
+ return ret;
+}