Rework how volumes, drives and volume monitoring is done. Previosly the

2007-12-11  David Zeuthen  <davidz@redhat.com>

	Rework how volumes, drives and volume monitoring is
	done. Previosly the model was

	 GDrive <1-1> GVolume

	where a GDrive instance represented a mount point and a GVolume
	instance represented a mounted file system. This patch changes it
	the model to

		GDrive <1-N> GVolume <1-1> GMount

	where GMount now serves the purpose of the old GVolume and the new
	GVolume serves the purpose of the old GDrive. In addition the new
	GDrive interface is used to represent a collection of GVolume
	instances (typically partitions) and also contains utility to query
	the state of the physical drive the GDrive object represents (such
	as checking for media, polling the drive, ejecting the media etc.).

	Also implement mounting and unmounting in the Unix volume monitor
	backend. A subquent patch will introduce GDrive support for ejection
	of media.

	* Makefile.am:
	* gdrive.c: (g_drive_is_media_check_automatic),
	(g_drive_is_media_removable), (g_drive_has_media),
	(g_drive_can_poll_for_media), (g_drive_eject),
	(g_drive_eject_finish), (g_drive_poll_for_media),
	(g_drive_poll_for_media_finish):
	* gdrive.h:
	* gfile.c: (g_file_find_enclosing_mount):
	* gfile.h:
	* gio.symbols:
	* glocaldirectorymonitor.c:
	(g_local_directory_monitor_constructor), (mounts_changed):
	* glocalfile.c: (get_mount_info),
	(g_local_file_find_enclosing_mount),
	(g_local_file_file_iface_init):
	* gnativevolumemonitor.h:
	* gunionvolumemonitor.c: (get_mounts), (get_volumes),
	(get_connected_drives), (g_union_volume_monitor_class_init),
	(child_volume_added), (child_volume_removed),
	(child_volume_changed), (child_mount_added), (child_mount_removed),
	(child_mount_pre_unmount), (child_mount_changed),
	(child_drive_changed), (g_union_volume_monitor_add_monitor),
	(g_union_volume_monitor_remove_monitor),
	(_g_mount_get_for_mount_path):
	* gunixmounts.c: (g_unix_is_mount_path_system_internal),
	(guess_system_internal), (_g_get_unix_mounts),
	(_g_get_unix_mount_points), (g_get_unix_mount_at),
	(g_unix_mount_free), (g_unix_mount_compare),
	(g_unix_mount_get_mount_path), (g_unix_mount_get_device_path),
	(g_unix_mount_get_fs_type), (g_unix_mount_is_readonly),
	(g_unix_mount_is_system_internal), (g_unix_mount_guess_type),
	(type_to_icon), (g_unix_mount_guess_name),
	(g_unix_mount_guess_icon), (g_unix_mount_point_guess_name),
	(g_unix_mount_point_guess_icon), (_canonicalize_filename),
	(_resolve_symlink), (_resolve_dev_root):
	* gunixmounts.h:
	* gunixvolume.c: (g_unix_volume_finalize), (_g_unix_volume_new),
	(_g_unix_volume_disconnected), (_g_unix_volume_set_mount),
	(_g_unix_volume_unset_mount), (g_unix_volume_get_icon),
	(g_unix_volume_get_name), (g_unix_volume_can_mount),
	(g_unix_volume_get_drive), (g_unix_volume_get_mount),
	(_g_unix_volume_has_mount_path), (mount_cb), (mount_read_error),
	(g_unix_volume_mount), (g_unix_volume_mount_finish),
	(g_unix_volume_volume_iface_init):
	* gunixvolume.h:
	* gunixvolumemonitor.c: (g_unix_volume_monitor_finalize),
	(get_mounts), (get_volumes), (get_connected_drives),
	(get_mount_for_mount_path), (g_unix_volume_monitor_class_init),
	(mountpoints_changed), (mounts_changed),
	(g_unix_volume_monitor_init),
	(_g_unix_volume_monitor_lookup_volume_for_mount_path),
	(find_mount_by_mountpath), (update_volumes), (update_mounts):
	* gunixvolumemonitor.h:
	* gvolume.c: (g_volume_get_mount), (g_volume_can_mount),
	(g_volume_mount), (g_volume_mount_finish):
	* gvolume.h:
	* gvolumemonitor.c: (g_volume_monitor_class_init),
	(g_volume_monitor_get_connected_drives),
	(g_volume_monitor_get_volumes), (g_volume_monitor_get_mounts):
	* gvolumemonitor.h:


svn path=/trunk/; revision=6095
This commit is contained in:
David Zeuthen
2007-12-11 21:23:55 +00:00
committed by David Zeuthen
parent c2643afd24
commit 3ca9fd4dbb
29 changed files with 2408 additions and 1283 deletions

View File

@@ -18,46 +18,42 @@
* Boston, MA 02111-1307, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
* David Zeuthen <davidz@redhat.com>
*/
#include <config.h>
#include "gmount.h"
#include "gvolume.h"
#include "gvolumeprivate.h"
#include "gsimpleasyncresult.h"
#include "glibintl.h"
#include "gioalias.h"
/**
* SECTION:gvolume
* @short_description: mounted volume management
* SECTION:volume
* @short_description: volume management
*
* Class for managing mounted volumes.
*
* Unmounting volumes is an asynchronous operation. For more information about
* asynchronous operations, see #GAsyncReady and #GSimpleAsyncReady. To unmount a volume,
* first call g_volume_unmount() with (at least) the volume 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_volume_unmount_finish() with
* the volume and the #GAsyncReady data to see if the operation was completed successfully.
* If an @error is present when g_volume_unmount_finish() is called, then it will
* be filled with any error information.
*
* Ejecting volumes is also an asynchronous operation.
* To eject a volume, call g_volume_eject() with (at least) the volume to eject
* and a #GAsyncReadyCallback. The callback will be fired when the eject operation
* has resolved (either with success or failure), and a #GAsyncReady structure will
* be passed to the callback. That callback should then call g_volume_eject_finish()
* with the volume and the #GAsyncReady data to determine if the operation was completed
* successfully. If an @error is present when g_volume_eject_finish() is called, then
* it will be filled with any error information.
* 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 instane, a
* #GMountOperation object 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_volume_mount_finish()
* with the #GVolume instance and the #GAsyncReady data to see if the
* operation was completed successfully. If an @error is present when
* g_volume_mount_finish() is called, then it will be filled with any
* error information.
**/
static void g_volume_base_init (gpointer g_class);
static void g_volume_class_init (gpointer g_class,
gpointer class_data);
gpointer class_data);
GType
g_volume_get_type (void)
@@ -91,7 +87,7 @@ g_volume_get_type (void)
static void
g_volume_class_init (gpointer g_class,
gpointer class_data)
gpointer class_data)
{
}
@@ -119,26 +115,6 @@ g_volume_base_init (gpointer g_class)
}
}
/**
* g_volume_get_root:
* @volume: a #GVolume.
*
* Gets the root directory on @volume.
*
* Returns: a #GFile.
**/
GFile *
g_volume_get_root (GVolume *volume)
{
GVolumeIface *iface;
g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->get_root) (volume);
}
/**
* g_volume_get_name:
* @volume: a #GVolume.
@@ -186,7 +162,7 @@ g_volume_get_icon (GVolume *volume)
*
* Gets the drive for the @volume.
*
* Returns: a #GDrive.
* Returns: a #GDrive or %NULL if @volume is not associated with a drive.
**/
GDrive *
g_volume_get_drive (GVolume *volume)
@@ -201,15 +177,36 @@ g_volume_get_drive (GVolume *volume)
}
/**
* g_volume_can_unmount:
* g_volume_get_mount:
* @volume: a #GVolume.
*
* Checks if @volume can be mounted.
* Gets the mount for the @volume.
*
* Returns: %TRUE if the @volume can be unmounted.
* Returns: a #GMount or %NULL if @volume isn't mounted.
**/
GMount *
g_volume_get_mount (GVolume *volume)
{
GVolumeIface *iface;
g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->get_mount) (volume);
}
/**
* g_volume_can_mount:
* @volume: a #GVolume.
*
* Checks if a volume can be mounted.
*
* Returns: %TRUE if the @volume can be mounted. %FALSE otherwise.
**/
gboolean
g_volume_can_unmount (GVolume *volume)
g_volume_can_mount (GVolume *volume)
{
GVolumeIface *iface;
@@ -217,81 +214,62 @@ g_volume_can_unmount (GVolume *volume)
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->can_unmount) (volume);
if (iface->can_mount == NULL)
return FALSE;
return (* iface->can_mount) (volume);
}
/**
* g_volume_can_eject:
* @volume: a #GVolume.
*
* Checks if @volume can be ejected.
*
* Returns: %TRUE if the @volume can be ejected.
**/
gboolean
g_volume_can_eject (GVolume *volume)
{
GVolumeIface *iface;
g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->can_eject) (volume);
}
/**
* g_volume_unmount:
* g_volume_mount:
* @volume: a #GVolume.
* @mount_operation: a #GMountOperation.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
* @user_data: user data passed to @callback.
* @user_data: a #gpointer.
*
* Unmounts a volume. This is an asynchronous operation, and is
* finished by calling g_volume_unmount_finish() with the @volume
* and #GAsyncResults data returned in the @callback.
* Mounts a volume.
**/
void
g_volume_unmount (GVolume *volume,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
g_volume_mount (GVolume *volume,
GMountOperation *mount_operation,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GVolumeIface *iface;
g_return_if_fail (G_IS_VOLUME (volume));
g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_VOLUME_GET_IFACE (volume);
if (iface->unmount == NULL)
if (iface->mount_fn == NULL)
{
g_simple_async_report_error_in_idle (G_OBJECT (volume),
callback, user_data,
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 unmount"));
_("volume doesn't implement mount"));
return;
}
(* iface->unmount) (volume, cancellable, callback, user_data);
(* iface->mount_fn) (volume, mount_operation, cancellable, callback, user_data);
}
/**
* g_volume_unmount_finish:
* @volume: a #GVolume.
* g_volume_mount_finish:
* @volume: pointer to a #GVolume.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* ignore.
* @error: a #GError.
*
* Finishes unmounting a volume. If any errors occured during the operation,
* @error will be set to contain the errors and %FALSE will be returned.
* Finishes mounting a volume.
*
* Returns: %TRUE if the volume was successfully unmounted. %FALSE otherwise.
* Returns: %TRUE, %FALSE if operation failed.
**/
gboolean
g_volume_unmount_finish (GVolume *volume,
GAsyncResult *result,
GError **error)
g_volume_mount_finish (GVolume *volume,
GAsyncResult *result,
GError **error)
{
GVolumeIface *iface;
@@ -306,76 +284,7 @@ g_volume_unmount_finish (GVolume *volume,
}
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->unmount_finish) (volume, result, error);
}
/**
* g_volume_eject:
* @volume: a #GVolume.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
* @user_data: user data passed to @callback.
*
* Ejects a volume. This is an asynchronous operation, and is
* finished by calling g_volume_eject_finish() from the @callback
* with the @volume and #GAsyncResults returned in the callback.
**/
void
g_volume_eject (GVolume *volume,
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)
{
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"));
return;
}
(* iface->eject) (volume, cancellable, callback, user_data);
}
/**
* g_volume_eject_finish:
* @volume: a #GVolume.
* @result: a #GAsyncResult.
* @error: a #GError location to store the error occuring, or %NULL to
* ignore.
*
* Finishes ejecting the volume. If any errors occured 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.
**/
gboolean
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;
}
iface = G_VOLUME_GET_IFACE (volume);
return (* iface->eject_finish) (volume, result, error);
return (* iface->mount_finish) (volume, result, error);
}
#define __G_VOLUME_C__