summaryrefslogtreecommitdiff
path: root/daemon/gvfsbackendcomputer.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/gvfsbackendcomputer.c')
-rw-r--r--daemon/gvfsbackendcomputer.c162
1 files changed, 158 insertions, 4 deletions
diff --git a/daemon/gvfsbackendcomputer.c b/daemon/gvfsbackendcomputer.c
index c0d355f5..9783df6c 100644
--- a/daemon/gvfsbackendcomputer.c
+++ b/daemon/gvfsbackendcomputer.c
@@ -21,7 +21,6 @@
* Cosimo Cecchi <cosimoc@gnome.org>
*/
-
#include <config.h>
#include <sys/types.h>
@@ -66,6 +65,9 @@ typedef struct {
gboolean can_mount;
gboolean can_unmount;
gboolean can_eject;
+ gboolean can_start;
+ gboolean can_stop;
+ GDriveStartStopType start_stop_type;
GDrive *drive;
GVolume *volume;
@@ -133,7 +135,10 @@ computer_file_equal (ComputerFile *a,
if (a->can_mount != b->can_mount ||
a->can_unmount != b->can_unmount ||
- a->can_eject != b->can_eject)
+ a->can_eject != b->can_eject ||
+ a->can_start != b->can_start ||
+ a->can_stop != b->can_stop ||
+ a->start_stop_type != b->start_stop_type)
return FALSE;
return TRUE;
@@ -458,6 +463,11 @@ recompute_files (GVfsBackendComputer *backend)
if (file->drive)
{
+ file->can_start = g_drive_can_start (file->drive);
+ file->can_stop = g_drive_can_stop (file->drive);
+ file->start_stop_type = g_drive_get_start_stop_type (file->drive);
+ if (file->can_start)
+ file->can_mount = FALSE;
basename = g_drive_get_name (file->drive);
extension = ".drive";
}
@@ -650,6 +660,9 @@ file_info_from_file (ComputerFile *file,
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT, file->can_mount);
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT, file->can_unmount);
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT, file->can_eject);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_START, file->can_start);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_MOUNTABLE_CAN_STOP, file->can_stop);
+ g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_MOUNTABLE_START_STOP_TYPE, file->start_stop_type);
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
@@ -781,8 +794,6 @@ mount_volume_cb (GObject *source_object,
volume = G_VOLUME (source_object);
- /* TODO: We're leaking the GMountOperation here */
-
error = NULL;
if (g_volume_mount_finish (volume, res, &error))
{
@@ -910,6 +921,8 @@ try_mount_mountable (GVfsBackend *backend,
if (file->volume)
{
mount_op = g_mount_source_get_operation (mount_source);
+ /* free mount_op when job is completed */
+ g_object_set_data_full (G_OBJECT (job), "gvfs-backend-computer-mount-op", mount_op, g_object_unref);
g_volume_mount (file->volume,
0,
mount_op,
@@ -1133,6 +1146,145 @@ try_eject_mountable (GVfsBackend *backend,
return TRUE;
}
+
+static void
+drive_start_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsJobStartMountable *job = user_data;
+ GError *error;
+ GDrive *drive;
+
+ drive = G_DRIVE (source_object);
+
+ error = NULL;
+ if (g_drive_start_finish (drive, res, &error))
+ {
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ }
+ else
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+}
+
+static gboolean
+try_start_mountable (GVfsBackend *backend,
+ GVfsJobStartMountable *job,
+ const char *filename,
+ GMountSource *mount_source)
+{
+ ComputerFile *file;
+ GMountOperation *start_op;
+
+ file = lookup (G_VFS_BACKEND_COMPUTER (backend),
+ G_VFS_JOB (job), filename);
+
+ if (file == &root)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_MOUNTABLE_FILE,
+ _("Not a mountable file"));
+ }
+ else if (file != NULL)
+ {
+ if (file->drive != NULL)
+ {
+ start_op = g_mount_source_get_operation (mount_source);
+ /* free start_op when job is completed */
+ g_object_set_data_full (G_OBJECT (job), "gvfs-backend-computer-start-op", start_op, g_object_unref);
+ g_drive_start (file->drive,
+ 0,
+ start_op,
+ G_VFS_JOB (job)->cancellable,
+ drive_start_cb,
+ job);
+ }
+ else
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Can't start file"));
+ }
+ }
+ else
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Can't start file"));
+ }
+ return TRUE;
+}
+
+
+static void
+drive_stop_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsJobStopMountable *job = user_data;
+ GError *error;
+ GDrive *drive;
+
+ drive = G_DRIVE (source_object);
+
+ error = NULL;
+ if (g_drive_stop_finish (drive, res, &error))
+ {
+ g_vfs_job_succeeded (G_VFS_JOB (job));
+ }
+ else
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ }
+}
+
+static gboolean
+try_stop_mountable (GVfsBackend *backend,
+ GVfsJobStopMountable *job,
+ const char *filename,
+ GMountUnmountFlags flags)
+{
+ ComputerFile *file;
+
+ file = lookup (G_VFS_BACKEND_COMPUTER (backend),
+ G_VFS_JOB (job), filename);
+
+ if (file == &root)
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_MOUNTABLE_FILE,
+ _("Not a mountable file"));
+ }
+ else if (file != NULL)
+ {
+ if (file->drive != NULL)
+ {
+ g_drive_stop (file->drive,
+ flags,
+ G_VFS_JOB (job)->cancellable,
+ drive_stop_cb,
+ job);
+ }
+ else
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Can't stop file"));
+ }
+ }
+ else
+ {
+ g_vfs_job_failed (G_VFS_JOB (job), G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Can't stop file"));
+ }
+ return TRUE;
+}
+
static void
g_vfs_backend_computer_class_init (GVfsBackendComputerClass *klass)
{
@@ -1149,4 +1301,6 @@ g_vfs_backend_computer_class_init (GVfsBackendComputerClass *klass)
backend_class->try_mount_mountable = try_mount_mountable;
backend_class->try_unmount_mountable = try_unmount_mountable;
backend_class->try_eject_mountable = try_eject_mountable;
+ backend_class->try_start_mountable = try_start_mountable;
+ backend_class->try_stop_mountable = try_stop_mountable;
}