[gvfs/wip/udisks2] Implement rudimentary parts of the udisks2 volume monitor
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/udisks2] Implement rudimentary parts of the udisks2 volume monitor
- Date: Tue, 27 Sep 2011 17:02:21 +0000 (UTC)
commit 11855863742f7c3ac9a83a8d22fc824d29e2fd17
Author: David Zeuthen <davidz redhat com>
Date: Tue Sep 27 13:01:18 2011 -0400
Implement rudimentary parts of the udisks2 volume monitor
Still a lot of stuff missing.
Signed-off-by: David Zeuthen <davidz redhat com>
monitor/udisks2/Makefile.am | 8 +-
monitor/udisks2/gvfsudisks2drive.c | 449 ++++++++++++++
monitor/udisks2/gvfsudisks2drive.h | 51 ++
monitor/udisks2/gvfsudisks2mount.c | 512 ++++++++++++++++
monitor/udisks2/gvfsudisks2mount.h | 57 ++
monitor/udisks2/gvfsudisks2volume.c | 541 +++++++++++++++++
monitor/udisks2/gvfsudisks2volume.h | 64 ++
monitor/udisks2/gvfsudisks2volumemonitor.c | 892 +++++++++++++++++++++++++++-
monitor/udisks2/gvfsudisks2volumemonitor.h | 11 +-
9 files changed, 2560 insertions(+), 25 deletions(-)
---
diff --git a/monitor/udisks2/Makefile.am b/monitor/udisks2/Makefile.am
index 5c0ed40..890b252 100644
--- a/monitor/udisks2/Makefile.am
+++ b/monitor/udisks2/Makefile.am
@@ -3,14 +3,12 @@ NULL =
libexec_PROGRAMS = gvfs-udisks2-volume-monitor
-# gvfsudisks2drive.c gvfsudisks2drive.h \
-# gvfsudisks2volume.c gvfsudisks2volume.h \
-# gvfsudisks2mount.c gvfsudisks2mount.h \
-#
-
gvfs_udisks2_volume_monitor_SOURCES = \
udisks2volumemonitordaemon.c \
gvfsudisks2volumemonitor.c gvfsudisks2volumemonitor.h \
+ gvfsudisks2drive.c gvfsudisks2drive.h \
+ gvfsudisks2volume.c gvfsudisks2volume.h \
+ gvfsudisks2mount.c gvfsudisks2mount.h \
$(NULL)
gvfs_udisks2_volume_monitor_CFLAGS = \
diff --git a/monitor/udisks2/gvfsudisks2drive.c b/monitor/udisks2/gvfsudisks2drive.c
new file mode 100644
index 0000000..d5e3a38
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2drive.c
@@ -0,0 +1,449 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#include "gvfsudisks2volumemonitor.h"
+#include "gvfsudisks2drive.h"
+#include "gvfsudisks2volume.h"
+
+typedef struct _GVfsUDisks2DriveClass GVfsUDisks2DriveClass;
+
+struct _GVfsUDisks2DriveClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GVfsUDisks2Drive
+{
+ GObject parent;
+
+ GVfsUDisks2VolumeMonitor *monitor; /* owned by volume monitor */
+ GList *volumes; /* entries in list are owned by volume monitor */
+
+ UDisksDrive *udisks_drive;
+
+ GIcon *icon;
+ gchar *name;
+ gchar *device_file;
+ dev_t dev;
+ gboolean is_media_removable;
+ gboolean has_media;
+ gboolean can_eject;
+};
+
+static void gvfs_udisks2_drive_drive_iface_init (GDriveIface *iface);
+
+static void on_udisks_drive_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
+
+G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Drive, gvfs_udisks2_drive, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_DRIVE, gvfs_udisks2_drive_drive_iface_init))
+
+static void
+gvfs_udisks2_drive_finalize (GObject *object)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (object);
+ GList *l;
+
+ for (l = drive->volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = l->data;
+ gvfs_udisks2_volume_unset_drive (volume, drive);
+ }
+
+ if (drive->udisks_drive != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (drive->udisks_drive, on_udisks_drive_notify, drive);
+ g_object_unref (drive->udisks_drive);
+ }
+
+ if (drive->icon != NULL)
+ g_object_unref (drive->icon);
+ g_free (drive->name);
+ g_free (drive->device_file);
+
+ G_OBJECT_CLASS (gvfs_udisks2_drive_parent_class)->finalize (object);
+}
+
+static void
+gvfs_udisks2_drive_class_init (GVfsUDisks2DriveClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gvfs_udisks2_drive_finalize;
+}
+
+static void
+gvfs_udisks2_drive_init (GVfsUDisks2Drive *gdu_drive)
+{
+}
+
+static void
+emit_changed (GVfsUDisks2Drive *drive)
+{
+ g_signal_emit_by_name (drive, "changed");
+ g_signal_emit_by_name (drive->monitor, "drive-changed", drive);
+}
+
+static gboolean
+update_drive (GVfsUDisks2Drive *drive)
+{
+ gboolean changed;
+ GIcon *old_icon;
+ gchar *old_name;
+ gchar *old_device_file;
+ dev_t old_dev;
+ gboolean old_is_media_removable;
+ gboolean old_has_media;
+ gboolean old_can_eject;
+ UDisksBlock *block;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* save old values */
+
+ old_is_media_removable = drive->is_media_removable;
+ old_has_media = drive->has_media;
+ old_can_eject = drive->can_eject;
+
+ old_name = g_strdup (drive->name);
+ old_device_file = g_strdup (drive->device_file);
+ old_dev = drive->dev;
+ old_icon = drive->icon != NULL ? g_object_ref (drive->icon) : NULL;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* reset */
+
+ drive->is_media_removable = drive->has_media = drive->can_eject = FALSE;
+ g_free (drive->name); drive->name = NULL;
+ g_free (drive->device_file); drive->device_file = NULL;
+ drive->dev = 0;
+ g_clear_object (&drive->icon);
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* in with the new */
+
+ block = udisks_client_get_block_for_drive (gvfs_udisks2_volume_monitor_get_udisks_client (drive->monitor),
+ drive->udisks_drive,
+ FALSE);
+ if (block != NULL)
+ {
+ drive->device_file = udisks_block_dup_device (block);
+ drive->dev = makedev (udisks_block_get_major (block), udisks_block_get_minor (block));
+ g_object_unref (block);
+ }
+
+ drive->is_media_removable = udisks_drive_get_media_removable (drive->udisks_drive);
+ if (drive->is_media_removable)
+ {
+ drive->has_media = (udisks_drive_get_size (drive->udisks_drive) > 0);
+ drive->can_eject = TRUE;
+ }
+ else
+ {
+ drive->has_media = TRUE;
+ drive->can_eject = FALSE;
+ }
+
+ udisks_util_get_drive_info (drive->udisks_drive,
+ NULL, /* drive_name */
+ &drive->name,
+ &drive->icon,
+ NULL, /* media_desc */
+ NULL); /* media_icon */
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* fallbacks */
+
+ /* Never use empty/blank names (#582772) */
+ if (drive->name == NULL || strlen (drive->name) == 0)
+ {
+ if (drive->device_file != NULL)
+ drive->name = g_strdup_printf (_("Unnamed Drive (%s)"), drive->device_file);
+ else
+ drive->name = g_strdup (_("Unnamed Drive"));
+ }
+ if (drive->icon == NULL)
+ drive->icon = g_themed_icon_new ("drive-removable-media");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* compute whether something changed */
+ changed = !((old_is_media_removable == drive->is_media_removable) &&
+ (old_has_media == drive->has_media) &&
+ (old_can_eject == drive->can_eject) &&
+ (g_strcmp0 (old_name, drive->name) == 0) &&
+ (g_strcmp0 (old_device_file, drive->device_file) == 0) &&
+ (old_dev == drive->dev) &&
+ g_icon_equal (old_icon, drive->icon)
+ );
+
+ /* free old values */
+ g_free (old_name);
+ g_free (old_device_file);
+ if (old_icon != NULL)
+ g_object_unref (old_icon);
+
+ /*g_debug ("in update_drive(); has_media=%d changed=%d", drive->has_media, changed);*/
+
+ return changed;
+}
+
+static void
+on_udisks_drive_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (user_data);
+ if (update_drive (drive))
+ emit_changed (drive);
+}
+
+GVfsUDisks2Drive *
+gvfs_udisks2_drive_new (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksDrive *udisks_drive)
+{
+ GVfsUDisks2Drive *drive;
+
+ drive = g_object_new (GVFS_TYPE_UDISKS2_DRIVE, NULL);
+ drive->monitor = monitor;
+
+ drive->udisks_drive = g_object_ref (udisks_drive);
+ g_signal_connect (drive->udisks_drive,
+ "notify",
+ G_CALLBACK (on_udisks_drive_notify),
+ drive);
+
+ update_drive (drive);
+
+ return drive;
+}
+
+void
+gvfs_udisks2_drive_disconnected (GVfsUDisks2Drive *drive)
+{
+ GList *l, *volumes;
+
+ volumes = drive->volumes;
+ drive->volumes = NULL;
+ for (l = volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = l->data;
+ gvfs_udisks2_volume_unset_drive (volume, drive);
+ }
+ g_list_free (volumes);
+}
+
+void
+gvfs_udisks2_drive_set_volume (GVfsUDisks2Drive *drive,
+ GVfsUDisks2Volume *volume)
+{
+ if (g_list_find (drive->volumes, volume) == NULL)
+ {
+ drive->volumes = g_list_prepend (drive->volumes, volume);
+ emit_changed (drive);
+ }
+}
+
+void
+gvfs_udisks2_drive_unset_volume (GVfsUDisks2Drive *drive,
+ GVfsUDisks2Volume *volume)
+{
+ GList *l;
+ l = g_list_find (drive->volumes, volume);
+ if (l != NULL)
+ {
+ drive->volumes = g_list_delete_link (drive->volumes, l);
+ emit_changed (drive);
+ }
+}
+
+static GIcon *
+gvfs_udisks2_drive_get_icon (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ return drive->icon != NULL ? g_object_ref (drive->icon) : NULL;
+}
+
+static char *
+gvfs_udisks2_drive_get_name (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ return g_strdup (drive->name);
+}
+
+static GList *
+gvfs_udisks2_drive_get_volumes (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ GList *l;
+ l = g_list_copy (drive->volumes);
+ g_list_foreach (l, (GFunc) g_object_ref, NULL);
+ return l;
+}
+
+static gboolean
+gvfs_udisks2_drive_has_volumes (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ gboolean res;
+ res = drive->volumes != NULL;
+ return res;
+}
+
+static gboolean
+gvfs_udisks2_drive_is_media_removable (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ return drive->is_media_removable;
+}
+
+static gboolean
+gvfs_udisks2_drive_has_media (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ return drive->has_media;
+}
+
+static gboolean
+gvfs_udisks2_drive_is_media_check_automatic (GDrive *_drive)
+{
+ return TRUE;
+}
+
+static gboolean
+gvfs_udisks2_drive_can_eject (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ return drive->can_eject;
+}
+
+static gboolean
+gvfs_udisks2_drive_can_poll_for_media (GDrive *_drive)
+{
+ return FALSE;
+}
+
+static gboolean
+gvfs_udisks2_drive_can_start (GDrive *_drive)
+{
+ return FALSE;
+}
+
+static gboolean
+gvfs_udisks2_drive_can_start_degraded (GDrive *_drive)
+{
+ return FALSE;
+}
+
+static gboolean
+gvfs_udisks2_drive_can_stop (GDrive *_drive)
+{
+ return FALSE;
+}
+
+static GDriveStartStopType
+gvfs_udisks2_drive_get_start_stop_type (GDrive *_drive)
+{
+ return G_DRIVE_START_STOP_TYPE_UNKNOWN;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static char *
+gvfs_udisks2_drive_get_identifier (GDrive *_drive,
+ const gchar *kind)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ gchar *ret = NULL;
+
+ if (drive->device_file != NULL)
+ {
+ if (g_strcmp0 (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
+ ret = g_strdup (drive->device_file);
+ }
+ return ret;
+}
+
+static gchar **
+gvfs_udisks2_drive_enumerate_identifiers (GDrive *_drive)
+{
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (_drive);
+ GPtrArray *p;
+
+ p = g_ptr_array_new ();
+ if (drive->device_file != NULL)
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
+ g_ptr_array_add (p, NULL);
+
+ return (gchar **) g_ptr_array_free (p, FALSE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gvfs_udisks2_drive_drive_iface_init (GDriveIface *iface)
+{
+ iface->get_name = gvfs_udisks2_drive_get_name;
+ iface->get_icon = gvfs_udisks2_drive_get_icon;
+ iface->has_volumes = gvfs_udisks2_drive_has_volumes;
+ iface->get_volumes = gvfs_udisks2_drive_get_volumes;
+ iface->is_media_removable = gvfs_udisks2_drive_is_media_removable;
+ iface->has_media = gvfs_udisks2_drive_has_media;
+ iface->is_media_check_automatic = gvfs_udisks2_drive_is_media_check_automatic;
+ iface->can_eject = gvfs_udisks2_drive_can_eject;
+ iface->can_poll_for_media = gvfs_udisks2_drive_can_poll_for_media;
+ iface->get_identifier = gvfs_udisks2_drive_get_identifier;
+ iface->enumerate_identifiers = gvfs_udisks2_drive_enumerate_identifiers;
+ iface->get_start_stop_type = gvfs_udisks2_drive_get_start_stop_type;
+ iface->can_start = gvfs_udisks2_drive_can_start;
+ iface->can_start_degraded = gvfs_udisks2_drive_can_start_degraded;
+ iface->can_stop = gvfs_udisks2_drive_can_stop;
+
+#if 0
+ iface->eject = gvfs_udisks2_drive_eject;
+ iface->eject_finish = gvfs_udisks2_drive_eject_finish;
+ iface->eject_with_operation = gvfs_udisks2_drive_eject_with_operation;
+ iface->eject_with_operation_finish = gvfs_udisks2_drive_eject_with_operation_finish;
+ iface->poll_for_media = gvfs_udisks2_drive_poll_for_media;
+ iface->poll_for_media_finish = gvfs_udisks2_drive_poll_for_media_finish;
+ iface->start = gvfs_udisks2_drive_start;
+ iface->start_finish = gvfs_udisks2_drive_start_finish;
+ iface->stop = gvfs_udisks2_drive_stop;
+ iface->stop_finish = gvfs_udisks2_drive_stop_finish;
+#endif
+}
+
+UDisksDrive *
+gvfs_udisks2_drive_get_udisks_drive (GVfsUDisks2Drive *drive)
+{
+ return drive->udisks_drive;
+}
diff --git a/monitor/udisks2/gvfsudisks2drive.h b/monitor/udisks2/gvfsudisks2drive.h
new file mode 100644
index 0000000..57a9255
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2drive.h
@@ -0,0 +1,51 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GVFS_UDISKS2_DRIVE_H__
+#define __GVFS_UDISKS2_DRIVE_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include "gvfsudisks2volumemonitor.h"
+
+G_BEGIN_DECLS
+
+#define GVFS_TYPE_UDISKS2_DRIVE (gvfs_udisks2_drive_get_type ())
+#define GVFS_UDISKS2_DRIVE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVFS_TYPE_UDISKS2_DRIVE, GVfsUDisks2Drive))
+#define GVFS_IS_UDISKS2_DRIVE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVFS_TYPE_UDISKS2_DRIVE))
+
+GType gvfs_udisks2_drive_get_type (void) G_GNUC_CONST;
+GVfsUDisks2Drive *gvfs_udisks2_drive_new (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksDrive *udisks_drive);
+void gvfs_udisks2_drive_disconnected (GVfsUDisks2Drive *drive);
+
+void gvfs_udisks2_drive_set_volume (GVfsUDisks2Drive *drive,
+ GVfsUDisks2Volume *volume);
+void gvfs_udisks2_drive_unset_volume (GVfsUDisks2Drive *drive,
+ GVfsUDisks2Volume *volume);
+UDisksDrive *gvfs_udisks2_drive_get_udisks_drive (GVfsUDisks2Drive *drive);
+
+G_END_DECLS
+
+#endif /* __GVFS_UDISKS2_DRIVE_H__ */
diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c
new file mode 100644
index 0000000..6f049bb
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2mount.c
@@ -0,0 +1,512 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+
+#include <gvfsmountinfo.h>
+
+#ifdef HAVE_GUDEV
+#include <gudev/gudev.h>
+#endif
+
+#include "gvfsudisks2volumemonitor.h"
+#include "gvfsudisks2mount.h"
+#include "gvfsudisks2volume.h"
+
+#define BUSY_UNMOUNT_NUM_ATTEMPTS 5
+#define BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS 100
+
+typedef struct _GVfsUDisks2MountClass GVfsUDisks2MountClass;
+struct _GVfsUDisks2MountClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GVfsUDisks2Mount
+{
+ GObject parent;
+
+ GVfsUDisks2VolumeMonitor *monitor; /* owned by volume monitor */
+ GVfsUDisks2Volume *volume; /* owned by volume monitor */
+
+ /* the following members are set in update_mount() */
+ GFile *root;
+ GIcon *icon;
+ gchar *name;
+ gchar *uuid;
+ gchar *device_file;
+ gchar *mount_path;
+ gboolean can_unmount;
+ gchar *mount_entry_name;
+ GIcon *mount_entry_icon;
+
+ gboolean is_burn_mount;
+
+ GIcon *autorun_icon;
+ gboolean searched_for_autorun;
+
+ gchar *xdg_volume_info_name;
+ GIcon *xdg_volume_info_icon;
+ gboolean searched_for_xdg_volume_info;
+
+ gchar *bdmv_volume_info_name;
+ GIcon *bdmv_volume_info_icon;
+ gboolean searched_for_bdmv_volume_info;
+};
+
+static gboolean update_mount (GVfsUDisks2Mount *mount);
+
+static void gvfs_udisks2_mount_mount_iface_init (GMountIface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Mount, gvfs_udisks2_mount, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_MOUNT,
+ gvfs_udisks2_mount_mount_iface_init))
+
+static void on_volume_changed (GVolume *volume, gpointer user_data);
+
+static void
+gvfs_udisks2_mount_finalize (GObject *object)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (object);
+
+ if (mount->volume != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (mount->volume, on_volume_changed, mount);
+ gvfs_udisks2_volume_unset_mount (mount->volume, mount);
+ }
+
+ if (mount->root != NULL)
+ g_object_unref (mount->root);
+ if (mount->icon != NULL)
+ g_object_unref (mount->icon);
+ g_free (mount->name);
+ g_free (mount->uuid);
+ g_free (mount->device_file);
+ g_free (mount->mount_path);
+
+ g_free (mount->mount_entry_name);
+ if (mount->mount_entry_icon != NULL)
+ g_object_unref (mount->mount_entry_icon);
+
+ if (mount->autorun_icon != NULL)
+ g_object_unref (mount->autorun_icon);
+
+ g_free (mount->xdg_volume_info_name);
+ if (mount->xdg_volume_info_icon != NULL)
+ g_object_unref (mount->xdg_volume_info_icon);
+
+ G_OBJECT_CLASS (gvfs_udisks2_mount_parent_class)->finalize (object);
+}
+
+static void
+gvfs_udisks2_mount_class_init (GVfsUDisks2MountClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gvfs_udisks2_mount_finalize;
+}
+
+static void
+gvfs_udisks2_mount_init (GVfsUDisks2Mount *mount)
+{
+}
+
+static void
+emit_changed (GVfsUDisks2Mount *mount)
+{
+ g_signal_emit_by_name (mount, "changed");
+ g_signal_emit_by_name (mount->monitor, "mount-changed", mount);
+}
+
+static void
+got_autorun_info_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (user_data);
+ mount->autorun_icon = g_vfs_mount_info_query_autorun_info_finish (G_FILE (source_object), res, NULL);
+ if (update_mount (mount))
+ emit_changed (mount);
+ g_object_unref (mount);
+}
+
+static void
+got_xdg_volume_info_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (user_data);
+ mount->xdg_volume_info_icon = g_vfs_mount_info_query_xdg_volume_info_finish (G_FILE (source_object),
+ res,
+ &(mount->xdg_volume_info_name),
+ NULL);
+ if (update_mount (mount))
+ emit_changed (mount);
+ g_object_unref (mount);
+}
+
+static void
+got_bdmv_volume_info_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (user_data);
+ mount->bdmv_volume_info_icon = g_vfs_mount_info_query_bdmv_volume_info_finish (G_FILE (source_object),
+ res,
+ &(mount->bdmv_volume_info_name),
+ NULL);
+ if (update_mount (mount))
+ emit_changed (mount);
+ g_object_unref (mount);
+}
+
+static gboolean
+update_mount (GVfsUDisks2Mount *mount)
+{
+ gboolean changed;
+ gboolean old_can_unmount;
+ gchar *old_name;
+ GIcon *old_icon;
+
+ /* save old values */
+ old_can_unmount = mount->can_unmount;
+ old_name = g_strdup (mount->name);
+ old_icon = mount->icon != NULL ? g_object_ref (mount->icon) : NULL;
+
+ /* in with the new */
+ if (mount->volume != NULL)
+ {
+ mount->can_unmount = TRUE;
+
+ if (mount->icon != NULL)
+ g_object_unref (mount->icon);
+
+ /* icon order of preference: bdmv, xdg, autorun, probed */
+ if (mount->bdmv_volume_info_icon != NULL)
+ mount->icon = g_object_ref (mount->bdmv_volume_info_icon);
+ else if (mount->xdg_volume_info_icon != NULL)
+ mount->icon = g_object_ref (mount->xdg_volume_info_icon);
+ else if (mount->autorun_icon != NULL)
+ mount->icon = g_object_ref (mount->autorun_icon);
+ else
+ mount->icon = g_volume_get_icon (G_VOLUME (mount->volume));
+
+ g_free (mount->name);
+
+ /* name order of preference : bdmv, xdg, probed */
+ if (mount->bdmv_volume_info_name != NULL)
+ mount->name = g_strdup (mount->bdmv_volume_info_name);
+ else if (mount->xdg_volume_info_name != NULL)
+ mount->name = g_strdup (mount->xdg_volume_info_name);
+ else
+ mount->name = g_volume_get_name (G_VOLUME (mount->volume));
+ }
+ else
+ {
+ mount->can_unmount = TRUE;
+
+ if (mount->icon != NULL)
+ g_object_unref (mount->icon);
+
+ /* icon order of preference: bdmv, xdg, autorun, probed */
+ if (mount->bdmv_volume_info_icon != NULL)
+ mount->icon = g_object_ref (mount->bdmv_volume_info_icon);
+ else if (mount->xdg_volume_info_icon != NULL)
+ mount->icon = g_object_ref (mount->xdg_volume_info_icon);
+ else if (mount->autorun_icon != NULL)
+ mount->icon = g_object_ref (mount->autorun_icon);
+ else
+ mount->icon = mount->mount_entry_icon != NULL ? g_object_ref (mount->mount_entry_icon) : NULL;
+
+ g_free (mount->name);
+
+ /* name order of preference: bdmv, xdg, probed */
+ if (mount->bdmv_volume_info_name != NULL)
+ mount->name = g_strdup (mount->bdmv_volume_info_name);
+ else if (mount->xdg_volume_info_name != NULL)
+ mount->name = g_strdup (mount->xdg_volume_info_name);
+ else
+ mount->name = g_strdup (mount->mount_entry_name);
+ }
+
+ /* compute whether something changed */
+ changed = !((old_can_unmount == mount->can_unmount) &&
+ (g_strcmp0 (old_name, mount->name) == 0) &&
+ g_icon_equal (old_icon, mount->icon));
+
+ /* free old values */
+ g_free (old_name);
+ if (old_icon != NULL)
+ g_object_unref (old_icon);
+
+ /*g_debug ("in update_mount(), changed=%d", changed);*/
+
+ /* search for BDMV */
+ if (!mount->searched_for_bdmv_volume_info)
+ {
+ mount->searched_for_bdmv_volume_info = TRUE;
+ g_vfs_mount_info_query_bdmv_volume_info (mount->root,
+ NULL,
+ got_bdmv_volume_info_cb,
+ g_object_ref (mount));
+ }
+
+ /* search for .xdg-volume-info */
+ if (!mount->searched_for_xdg_volume_info)
+ {
+ mount->searched_for_xdg_volume_info = TRUE;
+ g_vfs_mount_info_query_xdg_volume_info (mount->root,
+ NULL,
+ got_xdg_volume_info_cb,
+ g_object_ref (mount));
+ }
+
+ /* search for autorun.inf */
+ if (!mount->searched_for_autorun)
+ {
+ mount->searched_for_autorun = TRUE;
+ g_vfs_mount_info_query_autorun_info (mount->root,
+ NULL,
+ got_autorun_info_cb,
+ g_object_ref (mount));
+ }
+
+ return changed;
+}
+
+static void
+on_volume_changed (GVolume *volume,
+ gpointer user_data)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (user_data);
+ if (update_mount (mount))
+ emit_changed (mount);
+}
+
+GVfsUDisks2Mount *
+gvfs_udisks2_mount_new (GVfsUDisks2VolumeMonitor *monitor,
+ GUnixMountEntry *mount_entry,
+ GVfsUDisks2Volume *volume)
+{
+ GVfsUDisks2Mount *mount = NULL;
+
+ /* Ignore internal mounts unless there's a volume */
+ if (volume == NULL && (mount_entry != NULL && !g_unix_mount_guess_should_display (mount_entry)))
+ goto out;
+
+ mount = g_object_new (GVFS_TYPE_UDISKS2_MOUNT, NULL);
+ mount->monitor = monitor;
+
+ if (mount_entry != NULL)
+ {
+ /* No ref on GUnixMountEntry so save values for later use */
+ mount->mount_entry_name = g_unix_mount_guess_name (mount_entry);
+ mount->mount_entry_icon = g_unix_mount_guess_icon (mount_entry);
+ mount->device_file = g_strdup (g_unix_mount_get_device_path (mount_entry));
+ mount->mount_path = g_strdup (g_unix_mount_get_mount_path (mount_entry));
+ mount->root = g_file_new_for_path (mount->mount_path);
+ }
+ else
+ {
+ /* burn:/// mount (the only mounts we support with mount_entry == NULL) */
+ mount->device_file = NULL;
+ mount->mount_path = NULL;
+ mount->root = g_file_new_for_uri ("burn:///");
+ mount->is_burn_mount = TRUE;
+ }
+
+ /* need to set the volume only when the mount is fully constructed */
+ mount->volume = volume;
+ if (mount->volume != NULL)
+ {
+ gvfs_udisks2_volume_set_mount (volume, mount);
+ /* this is for piggy backing on the name and icon of the associated volume */
+ g_signal_connect (mount->volume, "changed", G_CALLBACK (on_volume_changed), mount);
+ }
+
+ update_mount (mount);
+
+ out:
+
+ return mount;
+}
+
+void
+gvfs_udisks2_mount_unmounted (GVfsUDisks2Mount *mount)
+{
+ if (mount->volume != NULL)
+ {
+ gvfs_udisks2_volume_unset_mount (mount->volume, mount);
+ g_signal_handlers_disconnect_by_func (mount->volume, on_volume_changed, mount);
+ mount->volume = NULL;
+ emit_changed (mount);
+ }
+}
+
+void
+gvfs_udisks2_mount_unset_volume (GVfsUDisks2Mount *mount,
+ GVfsUDisks2Volume *volume)
+{
+ if (mount->volume == volume)
+ {
+ g_signal_handlers_disconnect_by_func (mount->volume, on_volume_changed, mount);
+ mount->volume = NULL;
+ emit_changed (mount);
+ }
+}
+
+static GFile *
+gvfs_udisks2_mount_get_root (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return mount->root != NULL ? g_object_ref (mount->root) : NULL;
+}
+
+static GIcon *
+gvfs_udisks2_mount_get_icon (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return mount->icon != NULL ? g_object_ref (mount->icon) : NULL;
+}
+
+static gchar *
+gvfs_udisks2_mount_get_uuid (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return g_strdup (mount->uuid);
+}
+
+static gchar *
+gvfs_udisks2_mount_get_name (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return g_strdup (mount->name);
+}
+
+gboolean
+gvfs_udisks2_mount_has_uuid (GVfsUDisks2Mount *_mount,
+ const gchar *uuid)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return g_strcmp0 (mount->uuid, uuid) == 0;
+}
+
+gboolean
+gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount *_mount,
+ const gchar *mount_path)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return g_strcmp0 (mount->mount_path, mount_path) == 0;
+}
+
+static GDrive *
+gvfs_udisks2_mount_get_drive (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ GDrive *drive = NULL;
+
+ if (mount->volume != NULL)
+ drive = g_volume_get_drive (G_VOLUME (mount->volume));
+ return drive;
+}
+
+static GVolume *
+gvfs_udisks2_mount_get_volume (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ GVolume *volume = NULL;
+
+ if (mount->volume)
+ volume = G_VOLUME (g_object_ref (mount->volume));
+ return volume;
+}
+
+static gboolean
+gvfs_udisks2_mount_can_unmount (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ return mount->can_unmount;
+}
+
+static gboolean
+gvfs_udisks2_mount_can_eject (GMount *_mount)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ GDrive *drive;
+ gboolean can_eject;
+
+ can_eject = FALSE;
+ if (mount->volume != NULL)
+ {
+ drive = g_volume_get_drive (G_VOLUME (mount->volume));
+ if (drive != NULL)
+ can_eject = g_drive_can_eject (drive);
+ }
+
+ return can_eject;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gvfs_udisks2_mount_mount_iface_init (GMountIface *iface)
+{
+ iface->get_root = gvfs_udisks2_mount_get_root;
+ iface->get_name = gvfs_udisks2_mount_get_name;
+ iface->get_icon = gvfs_udisks2_mount_get_icon;
+ iface->get_uuid = gvfs_udisks2_mount_get_uuid;
+ iface->get_drive = gvfs_udisks2_mount_get_drive;
+ iface->get_volume = gvfs_udisks2_mount_get_volume;
+ iface->can_unmount = gvfs_udisks2_mount_can_unmount;
+ iface->can_eject = gvfs_udisks2_mount_can_eject;
+#if 0
+ iface->unmount = gvfs_udisks2_mount_unmount;
+ iface->unmount_finish = gvfs_udisks2_mount_unmount_finish;
+ iface->unmount_with_operation = gvfs_udisks2_mount_unmount_with_operation;
+ iface->unmount_with_operation_finish = gvfs_udisks2_mount_unmount_with_operation_finish;
+ iface->eject = gvfs_udisks2_mount_eject;
+ iface->eject_finish = gvfs_udisks2_mount_eject_finish;
+ iface->eject_with_operation = gvfs_udisks2_mount_eject_with_operation;
+ iface->eject_with_operation_finish = gvfs_udisks2_mount_eject_with_operation_finish;
+ iface->guess_content_type = gvfs_udisks2_mount_guess_content_type;
+ iface->guess_content_type_finish = gvfs_udisks2_mount_guess_content_type_finish;
+ iface->guess_content_type_sync = gvfs_udisks2_mount_guess_content_type_sync;
+#endif
+}
+
+gboolean
+gvfs_udisks2_mount_has_volume (GVfsUDisks2Mount *mount,
+ GVfsUDisks2Volume *volume)
+{
+ return mount->volume == volume;
+}
diff --git a/monitor/udisks2/gvfsudisks2mount.h b/monitor/udisks2/gvfsudisks2mount.h
new file mode 100644
index 0000000..03b7769
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2mount.h
@@ -0,0 +1,57 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GVFS_UDISKS2_MOUNT_H__
+#define __GVFS_UDISKS2_MOUNT_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include "gvfsudisks2volumemonitor.h"
+
+G_BEGIN_DECLS
+
+#define GVFS_TYPE_UDISKS2_MOUNT (gvfs_udisks2_mount_get_type ())
+#define GVFS_UDISKS2_MOUNT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVFS_TYPE_UDISKS2_MOUNT, GVfsUDisks2Mount))
+#define GVFS_IS_UDISKS2_MOUNT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVFS_TYPE_UDISKS2_MOUNT))
+
+
+GType gvfs_udisks2_mount_get_type (void) G_GNUC_CONST;
+GVfsUDisks2Mount *gvfs_udisks2_mount_new (GVfsUDisks2VolumeMonitor *monitor,
+ GUnixMountEntry *mount_entry,
+ GVfsUDisks2Volume *volume);
+void gvfs_udisks2_mount_unmounted (GVfsUDisks2Mount *mount);
+
+gboolean gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount *mount,
+ const gchar *mount_path);
+gboolean gvfs_udisks2_mount_has_uuid (GVfsUDisks2Mount *mount,
+ const gchar *uuid);
+
+void gvfs_udisks2_mount_unset_volume (GVfsUDisks2Mount *mount,
+ GVfsUDisks2Volume *volume);
+gboolean gvfs_udisks2_mount_has_volume (GVfsUDisks2Mount *mount,
+ GVfsUDisks2Volume *volume);
+
+G_END_DECLS
+
+#endif /* __GVFS_UDISKS2_MOUNT_H__ */
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
new file mode 100644
index 0000000..8d2e0a8
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -0,0 +1,541 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+
+#include "gvfsudisks2drive.h"
+#include "gvfsudisks2volume.h"
+#include "gvfsudisks2mount.h"
+
+typedef struct _GVfsUDisks2VolumeClass GVfsUDisks2VolumeClass;
+
+struct _GVfsUDisks2VolumeClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GVfsUDisks2Volume
+{
+ GObject parent;
+
+ GVfsUDisks2VolumeMonitor *monitor; /* owned by volume monitor */
+ GVfsUDisks2Mount *mount; /* owned by volume monitor */
+ GVfsUDisks2Drive *drive; /* owned by volume monitor */
+
+ UDisksBlock *block;
+
+ /* set in update_volume() */
+ GIcon *icon;
+ GFile *activation_root;
+ gchar *name;
+ gchar *device_file;
+ dev_t dev;
+ gchar *uuid;
+ gboolean can_mount;
+ gboolean should_automount;
+};
+
+static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);
+
+static void on_block_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
+
+G_DEFINE_TYPE_EXTENDED (GVfsUDisks2Volume, gvfs_udisks2_volume, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME, gvfs_udisks2_volume_volume_iface_init))
+
+static void
+gvfs_udisks2_volume_finalize (GObject *object)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (object);
+
+ if (volume->mount != NULL)
+ {
+ gvfs_udisks2_mount_unset_volume (volume->mount, volume);
+ }
+
+ if (volume->drive != NULL)
+ {
+ gvfs_udisks2_drive_unset_volume (volume->drive, volume);
+ }
+
+ g_signal_handlers_disconnect_by_func (volume->block, G_CALLBACK (on_block_changed), volume);
+ g_object_unref (volume->block);
+
+ if (volume->icon != NULL)
+ g_object_unref (volume->icon);
+ if (volume->activation_root != NULL)
+ g_object_unref (volume->activation_root);
+
+ g_free (volume->name);
+ g_free (volume->device_file);
+ g_free (volume->uuid);
+
+ G_OBJECT_CLASS (gvfs_udisks2_volume_parent_class)->finalize (object);
+}
+
+static void
+gvfs_udisks2_volume_class_init (GVfsUDisks2VolumeClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gvfs_udisks2_volume_finalize;
+}
+
+static void
+gvfs_udisks2_volume_init (GVfsUDisks2Volume *volume)
+{
+}
+
+static void
+emit_changed (GVfsUDisks2Volume *volume)
+{
+ g_signal_emit_by_name (volume, "changed");
+ g_signal_emit_by_name (volume->monitor, "volume_changed", volume);
+}
+
+static UDisksDrive *
+get_udisks_drive (GVfsUDisks2Volume *volume)
+{
+ UDisksDrive *ret = NULL;
+ UDisksClient *client;
+ UDisksObject *object;
+
+ client = gvfs_udisks2_volume_monitor_get_udisks_client (volume->monitor);
+ object = (UDisksObject *) g_dbus_object_manager_get_object (udisks_client_get_object_manager (client),
+ udisks_block_get_drive (volume->block));
+ if (object != NULL)
+ {
+ ret = udisks_object_peek_drive (object);
+ g_object_unref (object);
+ }
+ return ret;
+}
+
+static gboolean
+update_volume (GVfsUDisks2Volume *volume)
+{
+ gboolean changed;
+ gboolean old_can_mount;
+ gboolean old_should_automount;
+ gchar *old_name;
+ gchar *old_device_file;
+ dev_t old_dev;
+ GIcon *old_icon;
+ UDisksDrive *udisks_drive;
+ gchar *s;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* save old values */
+
+ old_can_mount = volume->can_mount;
+ old_should_automount = volume->should_automount;
+ old_name = g_strdup (volume->name);
+ old_device_file = g_strdup (volume->device_file);
+ old_dev = volume->dev;
+ old_icon = volume->icon != NULL ? g_object_ref (volume->icon) : NULL;
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* reset */
+
+ volume->can_mount = volume->should_automount = FALSE;
+ g_free (volume->name); volume->name = NULL;
+ g_free (volume->device_file); volume->device_file = NULL;
+ volume->dev = 0;
+ g_clear_object (&volume->icon);
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* in with the new */
+
+ volume->dev = makedev (udisks_block_get_major (volume->block), udisks_block_get_minor (volume->block));
+ volume->device_file = udisks_block_dup_device (volume->block);
+
+ if (strlen (udisks_block_get_id_label (volume->block)) > 0)
+ {
+ volume->name = g_strdup (udisks_block_get_id_label (volume->block));
+ }
+ else
+ {
+ s = g_format_size (udisks_block_get_size (volume->block));
+ /* Translators: This is used for volume with no filesystem label.
+ * The first %s is the formatted size (e.g. "42.0 MB").
+ */
+ volume->name = g_strdup_printf (_("%s Volume"), s);
+ g_free (s);
+ }
+
+ udisks_drive = get_udisks_drive (volume);
+ if (udisks_drive != NULL)
+ {
+ gchar *drive_desc;
+ GIcon *drive_icon;
+ gchar *media_desc;
+ GIcon *media_icon;
+ udisks_util_get_drive_info (udisks_drive,
+ NULL, /* drive_name */
+ &drive_desc,
+ &drive_icon,
+ &media_desc,
+ &media_icon);
+ if (media_desc == NULL)
+ {
+ media_desc = drive_desc;
+ drive_desc = NULL;
+ }
+ if (media_icon == NULL)
+ {
+ media_icon = drive_icon;
+ drive_icon = NULL;
+ }
+
+ //volume->name = g_strdup (media_desc);
+ volume->icon = media_icon != NULL ? g_object_ref (media_icon) : NULL;
+
+ g_free (media_desc);
+ if (media_icon != NULL)
+ g_object_unref (media_icon);
+ }
+ else
+ {
+ }
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* fallbacks */
+
+ if (volume->name == NULL)
+ {
+ /* Translators: Name used for volume */
+ volume->name = g_strdup (_("Volume"));
+ }
+ if (volume->icon == NULL)
+ volume->icon = g_themed_icon_new ("drive-removable-media");
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* compute whether something changed */
+
+ changed = !((old_can_mount == volume->can_mount) &&
+ (old_should_automount == volume->should_automount) &&
+ (g_strcmp0 (old_name, volume->name) == 0) &&
+ (g_strcmp0 (old_device_file, volume->device_file) == 0) &&
+ (old_dev == volume->dev) &&
+ g_icon_equal (old_icon, volume->icon)
+ );
+
+ /* ---------------------------------------------------------------------------------------------------- */
+ /* free old values */
+
+ g_free (old_name);
+ g_free (old_device_file);
+ if (old_icon != NULL)
+ g_object_unref (old_icon);
+
+ return changed;
+}
+
+static void
+on_block_changed (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (user_data);
+ if (update_volume (volume))
+ emit_changed (volume);
+}
+
+GVfsUDisks2Volume *
+gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksBlock *block,
+ GVfsUDisks2Drive *drive,
+ GFile *activation_root)
+{
+ GVfsUDisks2Volume *volume;
+
+ volume = g_object_new (GVFS_TYPE_UDISKS2_VOLUME, NULL);
+ volume->monitor = monitor;
+
+ volume->block = g_object_ref (block);
+ g_signal_connect (volume->block, "notify", G_CALLBACK (on_block_changed), volume);
+
+ volume->activation_root = activation_root != NULL ? g_object_ref (activation_root) : NULL;
+
+ volume->drive = drive;
+ if (drive != NULL)
+ gvfs_udisks2_drive_set_volume (drive, volume);
+
+ update_volume (volume);
+
+ return volume;
+}
+
+void
+gvfs_udisks2_volume_removed (GVfsUDisks2Volume *volume)
+{
+#if 0
+TODO
+ if (volume->pending_mount_op != NULL)
+ cancel_pending_mount_op (volume->pending_mount_op);
+#endif
+
+ if (volume->mount != NULL)
+ {
+ gvfs_udisks2_mount_unset_volume (volume->mount, volume);
+ volume->mount = NULL;
+ }
+
+ if (volume->drive != NULL)
+ {
+ gvfs_udisks2_drive_unset_volume (volume->drive, volume);
+ volume->drive = NULL;
+ }
+}
+
+void
+gvfs_udisks2_volume_set_mount (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Mount *mount)
+{
+ if (volume->mount != mount)
+ {
+ if (volume->mount != NULL)
+ gvfs_udisks2_mount_unset_volume (volume->mount, volume);
+
+ volume->mount = mount;
+
+ emit_changed (volume);
+ }
+}
+
+void
+gvfs_udisks2_volume_unset_mount (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Mount *mount)
+{
+ if (volume->mount == mount)
+ {
+ volume->mount = NULL;
+ emit_changed (volume);
+ }
+}
+
+void
+gvfs_udisks2_volume_set_drive (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Drive *drive)
+{
+ if (volume->drive != drive)
+ {
+ if (volume->drive != NULL)
+ gvfs_udisks2_drive_unset_volume (volume->drive, volume);
+ volume->drive = drive;
+ emit_changed (volume);
+ }
+}
+
+void
+gvfs_udisks2_volume_unset_drive (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Drive *drive)
+{
+ if (volume->drive == drive)
+ {
+ volume->drive = NULL;
+ emit_changed (volume);
+ }
+}
+
+static GIcon *
+gvfs_udisks2_volume_get_icon (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return volume->icon != NULL ? g_object_ref (volume->icon) : NULL;
+}
+
+static char *
+gvfs_udisks2_volume_get_name (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return g_strdup (volume->name);
+}
+
+static char *
+gvfs_udisks2_volume_get_uuid (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return g_strdup (volume->uuid);
+}
+
+static gboolean
+gvfs_udisks2_volume_can_mount (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return volume->can_mount;
+}
+
+static gboolean
+gvfs_udisks2_volume_can_eject (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ gboolean can_eject = FALSE;
+
+ if (volume->drive != NULL)
+ can_eject = g_drive_can_eject (G_DRIVE (volume->drive));
+ return can_eject;
+}
+
+static gboolean
+gvfs_udisks2_volume_should_automount (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return volume->should_automount;
+}
+
+static GDrive *
+gvfs_udisks2_volume_get_drive (GVolume *volume)
+{
+ GVfsUDisks2Volume *gdu_volume = GVFS_UDISKS2_VOLUME (volume);
+ GDrive *drive = NULL;
+
+ if (gdu_volume->drive != NULL)
+ drive = g_object_ref (gdu_volume->drive);
+ return drive;
+}
+
+static GMount *
+gvfs_udisks2_volume_get_mount (GVolume *volume)
+{
+ GVfsUDisks2Volume *gdu_volume = GVFS_UDISKS2_VOLUME (volume);
+ GMount *mount = NULL;
+
+ if (gdu_volume->mount != NULL)
+ mount = g_object_ref (gdu_volume->mount);
+ return mount;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *
+gvfs_udisks2_volume_get_identifier (GVolume *_volume,
+ const gchar *kind)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ const gchar *label;
+ const gchar *uuid;
+ gchar *ret = NULL;
+
+ label = udisks_block_get_id_label (volume->block);
+ uuid = udisks_block_get_id_uuid (volume->block);
+
+ if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
+ ret = g_strdup (volume->device_file);
+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
+ ret = strlen (label) > 0 ? g_strdup (label) : NULL;
+ else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
+ ret = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
+
+ return ret;
+}
+
+static gchar **
+gvfs_udisks2_volume_enumerate_identifiers (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ const gchar *label;
+ const gchar *uuid;
+ GPtrArray *p;
+
+ label = udisks_block_get_id_label (volume->block);
+ uuid = udisks_block_get_id_uuid (volume->block);
+
+ p = g_ptr_array_new ();
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
+ if (strlen (label) > 0)
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
+ if (strlen (uuid) > 0)
+ g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
+
+ g_ptr_array_add (p, NULL);
+ return (gchar **) g_ptr_array_free (p, FALSE);
+}
+
+static GFile *
+gvfs_udisks2_volume_get_activation_root (GVolume *_volume)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ return volume->activation_root != NULL ? g_object_ref (volume->activation_root) : NULL;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface)
+{
+ iface->get_name = gvfs_udisks2_volume_get_name;
+ iface->get_icon = gvfs_udisks2_volume_get_icon;
+ iface->get_uuid = gvfs_udisks2_volume_get_uuid;
+ iface->get_drive = gvfs_udisks2_volume_get_drive;
+ iface->get_mount = gvfs_udisks2_volume_get_mount;
+ iface->can_mount = gvfs_udisks2_volume_can_mount;
+ iface->can_eject = gvfs_udisks2_volume_can_eject;
+ iface->should_automount = gvfs_udisks2_volume_should_automount;
+ iface->get_activation_root = gvfs_udisks2_volume_get_activation_root;
+ iface->enumerate_identifiers = gvfs_udisks2_volume_enumerate_identifiers;
+ iface->get_identifier = gvfs_udisks2_volume_get_identifier;
+
+#if 0
+ iface->mount_fn = gvfs_udisks2_volume_mount;
+ iface->mount_finish = gvfs_udisks2_volume_mount_finish;
+ iface->eject = gvfs_udisks2_volume_eject;
+ iface->eject_finish = gvfs_udisks2_volume_eject_finish;
+ iface->eject_with_operation = gvfs_udisks2_volume_eject_with_operation;
+ iface->eject_with_operation_finish = gvfs_udisks2_volume_eject_with_operation_finish;
+#endif
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+UDisksBlock *
+gvfs_udisks2_volume_get_block (GVfsUDisks2Volume *volume)
+{
+ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME (volume), NULL);
+ return volume->block;
+}
+
+dev_t
+gvfs_udisks2_volume_get_dev (GVfsUDisks2Volume *volume)
+{
+ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME (volume), 0);
+ return volume->dev;
+}
+
+gboolean
+gvfs_udisks2_volume_has_uuid (GVfsUDisks2Volume *volume,
+ const gchar *uuid)
+{
+ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME (volume), FALSE);
+ return g_strcmp0 (volume->uuid, uuid) == 0;
+}
diff --git a/monitor/udisks2/gvfsudisks2volume.h b/monitor/udisks2/gvfsudisks2volume.h
new file mode 100644
index 0000000..cda2b9c
--- /dev/null
+++ b/monitor/udisks2/gvfsudisks2volume.h
@@ -0,0 +1,64 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* gvfs - extensions for gio
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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.
+ *
+ * Author: David Zeuthen <davidz redhat com>
+ */
+
+#ifndef __GVFS_UDISKS2_VOLUME_H__
+#define __GVFS_UDISKS2_VOLUME_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include "gvfsudisks2volumemonitor.h"
+
+G_BEGIN_DECLS
+
+#define GVFS_TYPE_UDISKS2_VOLUME (gvfs_udisks2_volume_get_type ())
+#define GVFS_UDISKS2_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVFS_TYPE_UDISKS2_VOLUME, GVfsUDisks2Volume))
+#define GVFS_IS_UDISKS2_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVFS_TYPE_UDISKS2_VOLUME))
+
+GType gvfs_udisks2_volume_get_type (void) G_GNUC_CONST;
+
+GVfsUDisks2Volume *gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksBlock *block,
+ GVfsUDisks2Drive *drive,
+ GFile *activation_root);
+void gvfs_udisks2_volume_removed (GVfsUDisks2Volume *volume);
+
+UDisksBlock *gvfs_udisks2_volume_get_block (GVfsUDisks2Volume *volume);
+dev_t gvfs_udisks2_volume_get_dev (GVfsUDisks2Volume *volume);
+
+void gvfs_udisks2_volume_set_mount (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Mount *mount);
+void gvfs_udisks2_volume_unset_mount (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Mount *mount);
+
+void gvfs_udisks2_volume_set_drive (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Drive *drive);
+void gvfs_udisks2_volume_unset_drive (GVfsUDisks2Volume *volume,
+ GVfsUDisks2Drive *drive);
+
+gboolean gvfs_udisks2_volume_has_uuid (GVfsUDisks2Volume *volume,
+ const gchar *uuid);
+
+G_END_DECLS
+
+#endif /* __GVFS_UDISKS2_VOLUME_H__ */
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c
index a3fabc6..0b14f2e 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.c
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.c
@@ -27,11 +27,18 @@
#include <string.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include "gvfsudisks2volumemonitor.h"
+#include "gvfsudisks2drive.h"
+#include "gvfsudisks2volume.h"
+#include "gvfsudisks2mount.h"
static GVfsUDisks2VolumeMonitor *the_volume_monitor = NULL;
@@ -47,10 +54,63 @@ struct _GVfsUDisks2VolumeMonitor
GNativeVolumeMonitor parent;
UDisksClient *client;
+
+ GList *last_mounts;
+
+ GList *drives;
+ GList *volumes;
+ GList *mounts;
+ /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */
+ GList *disc_volumes;
+ GList *disc_mounts;
};
+static void object_list_free (GList *objects);
static UDisksClient *get_udisks_client_sync (GError **error);
+static void update_all (GVfsUDisks2VolumeMonitor *monitor,
+ gboolean emit_changes);
+static void update_drives (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_drives,
+ GList **removed_drives);
+static void update_volumes (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_volumes,
+ GList **removed_volumes);
+static void update_mounts (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_mounts,
+ GList **removed_mounts);
+static void update_discs (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_volumes,
+ GList **removed_volumes,
+ GList **added_mounts,
+ GList **removed_mounts);
+
+
+static void on_object_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data);
+
+static void on_object_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data);
+
+static void on_interface_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data);
+
+static void on_interface_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data);
+
+static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
+ GDBusObjectProxy *object_proxy,
+ GDBusProxy *interface_proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties,
+ gpointer user_data);
+
G_DEFINE_TYPE (GVfsUDisks2VolumeMonitor, gvfs_udisks2_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR)
static void
@@ -66,55 +126,167 @@ static void
gvfs_udisks2_volume_monitor_finalize (GObject *object)
{
GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (object);
+ GDBusObjectManager *object_manager;
+
+ object_manager = udisks_client_get_object_manager (monitor->client);
+ g_signal_handlers_disconnect_by_func (object_manager,
+ G_CALLBACK (on_object_added),
+ monitor);
+ g_signal_handlers_disconnect_by_func (object_manager,
+ G_CALLBACK (on_object_removed),
+ monitor);
+ g_signal_handlers_disconnect_by_func (object_manager,
+ G_CALLBACK (on_interface_added),
+ monitor);
+ g_signal_handlers_disconnect_by_func (object_manager,
+ G_CALLBACK (on_interface_removed),
+ monitor);
+ g_signal_handlers_disconnect_by_func (object_manager,
+ G_CALLBACK (on_interface_proxy_properties_changed),
+ monitor);
g_clear_object (&monitor->client);
+ g_list_foreach (monitor->last_mounts, (GFunc) g_unix_mount_free, NULL);
+ g_list_free (monitor->last_mounts);
+
+ object_list_free (monitor->drives);
+ object_list_free (monitor->volumes);
+ object_list_free (monitor->mounts);
+
+ object_list_free (monitor->disc_volumes);
+ object_list_free (monitor->disc_mounts);
+
G_OBJECT_CLASS (gvfs_udisks2_volume_monitor_parent_class)->finalize (object);
}
static GList *
-get_mounts (GVolumeMonitor *monitor)
+get_mounts (GVolumeMonitor *_monitor)
{
- /* TODO */
- return NULL;
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (_monitor);
+ GList *ret;
+
+ ret = g_list_copy (monitor->mounts);
+ ret = g_list_concat (ret, g_list_copy (monitor->disc_mounts));
+ g_list_foreach (ret, (GFunc) g_object_ref, NULL);
+ return ret;
}
static GList *
-get_volumes (GVolumeMonitor *monitor)
+get_volumes (GVolumeMonitor *_monitor)
{
- /* TODO */
- return NULL;
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (_monitor);
+ GList *ret;
+
+ ret = g_list_copy (monitor->volumes);
+ ret = g_list_concat (ret, g_list_copy (monitor->disc_volumes));
+ g_list_foreach (ret, (GFunc) g_object_ref, NULL);
+ return ret;
}
static GList *
-get_connected_drives (GVolumeMonitor *monitor)
+get_connected_drives (GVolumeMonitor *_monitor)
{
- /* TODO */
- return NULL;
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (_monitor);
+ GList *ret;
+
+ ret = g_list_copy (monitor->drives);
+ g_list_foreach (ret, (GFunc) g_object_ref, NULL);
+ return ret;
}
static GVolume *
-get_volume_for_uuid (GVolumeMonitor *monitor,
+get_volume_for_uuid (GVolumeMonitor *_monitor,
const gchar *uuid)
{
- /* TODO */
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (_monitor);
+ GVfsUDisks2Volume *volume;
+ GList *l;
+
+ for (l = monitor->volumes; l != NULL; l = l->next)
+ {
+ volume = l->data;
+ if (gvfs_udisks2_volume_has_uuid (l->data, uuid))
+ goto found;
+ }
+ for (l = monitor->disc_volumes; l != NULL; l = l->next)
+ {
+ volume = l->data;
+ if (gvfs_udisks2_volume_has_uuid (volume, uuid))
+ goto found;
+ }
+
return NULL;
+
+ found:
+ return G_VOLUME (g_object_ref (volume));
}
static GMount *
-get_mount_for_uuid (GVolumeMonitor *monitor,
+get_mount_for_uuid (GVolumeMonitor *_monitor,
const gchar *uuid)
{
- /* TODO */
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (_monitor);
+ GVfsUDisks2Mount *mount;
+ GList *l;
+
+ for (l = monitor->mounts; l != NULL; l = l->next)
+ {
+ mount = l->data;
+ if (gvfs_udisks2_mount_has_uuid (l->data, uuid))
+ goto found;
+ }
+ for (l = monitor->disc_mounts; l != NULL; l = l->next)
+ {
+ mount = l->data;
+ if (gvfs_udisks2_mount_has_uuid (mount, uuid))
+ goto found;
+ }
+
return NULL;
+
+ found:
+ return G_MOUNT (g_object_ref (mount));
}
static GMount *
get_mount_for_mount_path (const gchar *mount_path,
GCancellable *cancellable)
{
- /* TODO */
- return NULL;
+ GVfsUDisks2VolumeMonitor *monitor = NULL;
+ GMount *ret = NULL;
+
+ if (the_volume_monitor == NULL)
+ {
+ /* Bah, no monitor is set up.. so we have to create one, find
+ * what the user asks for and throw it away again.
+ */
+ monitor = GVFS_UDISKS2_VOLUME_MONITOR (gvfs_udisks2_volume_monitor_new ());
+ }
+ else
+ {
+ monitor = g_object_ref (the_volume_monitor);
+ }
+
+ /* creation of the volume monitor could fail */
+ if (monitor != NULL)
+ {
+ GList *l;
+ for (l = monitor->mounts; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
+ if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+ {
+ ret = g_object_ref (mount);
+ goto out;
+ }
+ }
+ }
+
+ out:
+ if (monitor != NULL)
+ g_object_unref (monitor);
+ return ret;
}
static GObject *
@@ -145,7 +317,33 @@ gvfs_udisks2_volume_monitor_constructor (GType type,
static void
gvfs_udisks2_volume_monitor_init (GVfsUDisks2VolumeMonitor *monitor)
{
+ GDBusObjectManager *object_manager;
+
monitor->client = get_udisks_client_sync (NULL);
+
+ object_manager = udisks_client_get_object_manager (monitor->client);
+ g_signal_connect (object_manager,
+ "object-added",
+ G_CALLBACK (on_object_added),
+ monitor);
+ g_signal_connect (object_manager,
+ "object-removed",
+ G_CALLBACK (on_object_removed),
+ monitor);
+ g_signal_connect (object_manager,
+ "interface-added",
+ G_CALLBACK (on_interface_added),
+ monitor);
+ g_signal_connect (object_manager,
+ "interface-removed",
+ G_CALLBACK (on_interface_removed),
+ monitor);
+ g_signal_connect (object_manager,
+ "interface-proxy-properties-changed",
+ G_CALLBACK (on_interface_proxy_properties_changed),
+ monitor);
+
+ update_all (monitor, FALSE);
}
static gboolean
@@ -190,6 +388,15 @@ gvfs_udisks2_volume_monitor_new (void)
/* ---------------------------------------------------------------------------------------------------- */
+UDisksClient *
+gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor)
+{
+ g_return_val_if_fail (GVFS_IS_UDISKS2_VOLUME_MONITOR (monitor), NULL);
+ return monitor->client;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static UDisksClient *
get_udisks_client_sync (GError **error)
{
@@ -210,3 +417,658 @@ get_udisks_client_sync (GError **error)
}
/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+diff_sorted_lists (GList *list1,
+ GList *list2,
+ GCompareFunc compare,
+ GList **added,
+ GList **removed)
+{
+ int order;
+
+ *added = *removed = NULL;
+
+ while (list1 != NULL &&
+ list2 != NULL)
+ {
+ order = (*compare) (list1->data, list2->data);
+ if (order < 0)
+ {
+ *removed = g_list_prepend (*removed, list1->data);
+ list1 = list1->next;
+ }
+ else if (order > 0)
+ {
+ *added = g_list_prepend (*added, list2->data);
+ list2 = list2->next;
+ }
+ else
+ { /* same item */
+ list1 = list1->next;
+ list2 = list2->next;
+ }
+ }
+
+ while (list1 != NULL)
+ {
+ *removed = g_list_prepend (*removed, list1->data);
+ list1 = list1->next;
+ }
+ while (list2 != NULL)
+ {
+ *added = g_list_prepend (*added, list2->data);
+ list2 = list2->next;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+object_list_free (GList *objects)
+{
+ g_list_foreach (objects, (GFunc)g_object_unref, NULL);
+ g_list_free (objects);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+object_list_emit (GVfsUDisks2VolumeMonitor *monitor,
+ const gchar *monitor_signal,
+ const gchar *object_signal,
+ GList *objects)
+{
+ GList *l;
+ for (l = objects; l != NULL; l = l->next)
+ {
+ g_signal_emit_by_name (monitor, monitor_signal, l->data);
+ if (object_signal)
+ g_signal_emit_by_name (l->data, object_signal);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+on_object_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
+ // g_debug ("on_object_added %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ update_all (monitor, TRUE);
+}
+
+static void
+on_object_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
+ // g_debug ("on_object_removed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ update_all (monitor, TRUE);
+}
+
+static void
+on_interface_added (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data)
+{
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
+ // g_debug ("on_interface_added %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ update_all (monitor, TRUE);
+}
+
+static void
+on_interface_removed (GDBusObjectManager *manager,
+ GDBusObject *object,
+ GDBusInterface *interface,
+ gpointer user_data)
+{
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
+ // g_debug ("on_interface_removed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
+ update_all (monitor, TRUE);
+}
+
+static void
+on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager,
+ GDBusObjectProxy *object_proxy,
+ GDBusProxy *interface_proxy,
+ GVariant *changed_properties,
+ const gchar *const *invalidated_properties,
+ gpointer user_data)
+{
+ GVfsUDisks2VolumeMonitor *monitor = GVFS_UDISKS2_VOLUME_MONITOR (user_data);
+ // g_debug ("on_interface_proxy_properties_changed %s", g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy)));
+ update_all (monitor, TRUE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_all (GVfsUDisks2VolumeMonitor *monitor,
+ gboolean emit_changes)
+{
+ GList *added_drives, *removed_drives;
+ GList *added_volumes, *removed_volumes;
+ GList *added_mounts, *removed_mounts;
+
+ added_drives = NULL;
+ removed_drives = NULL;
+ added_volumes = NULL;
+ removed_volumes = NULL;
+ added_mounts = NULL;
+ removed_mounts = NULL;
+
+ update_drives (monitor, &added_drives, &removed_drives);
+ update_volumes (monitor, &added_volumes, &removed_volumes);
+ update_mounts (monitor, &added_mounts, &removed_mounts);
+ update_discs (monitor,
+ &added_volumes, &removed_volumes,
+ &added_mounts, &removed_mounts);
+
+ if (emit_changes)
+ {
+ object_list_emit (monitor,
+ "drive-disconnected", NULL,
+ removed_drives);
+ object_list_emit (monitor,
+ "drive-connected", NULL,
+ added_drives);
+
+ object_list_emit (monitor,
+ "volume-removed", "removed",
+ removed_volumes);
+ object_list_emit (monitor,
+ "volume-added", NULL,
+ added_volumes);
+
+ object_list_emit (monitor,
+ "mount-removed", "unmounted",
+ removed_mounts);
+ object_list_emit (monitor,
+ "mount-added", NULL,
+ added_mounts);
+ }
+
+ object_list_free (removed_drives);
+ object_list_free (added_drives);
+ object_list_free (removed_volumes);
+ object_list_free (added_volumes);
+ object_list_free (removed_mounts);
+ object_list_free (added_mounts);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+should_include_mount (GVfsUDisks2VolumeMonitor *monitor,
+ GUnixMountEntry *mount_entry)
+{
+ gboolean ret = FALSE;
+ ret = g_unix_mount_guess_should_display (mount_entry);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+should_include_volume_check_mount_points (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksBlock *block)
+{
+ gboolean ret = TRUE;
+ GDBusObject *obj;
+ UDisksFilesystem *fs;
+ const gchar* const *mount_points;
+ guint n;
+
+ obj = g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
+ if (obj == NULL)
+ goto out;
+
+ fs = udisks_object_peek_filesystem (UDISKS_OBJECT (obj));
+ if (fs == NULL)
+ goto out;
+
+ mount_points = udisks_filesystem_get_mount_points (fs);
+ for (n = 0; mount_points != NULL && mount_points[n] != NULL; n++)
+ {
+ const gchar *mount_point = mount_points[n];
+ GUnixMountEntry *mount_entry;
+
+ mount_entry = g_unix_mount_at (mount_point, NULL);
+ if (mount_entry != NULL)
+ {
+ if (!should_include_mount (monitor, mount_entry))
+ {
+ g_unix_mount_free (mount_entry);
+ ret = FALSE;
+ goto out;
+ }
+ g_unix_mount_free (mount_entry);
+ }
+ }
+
+ out:
+ return ret;
+}
+
+static gboolean
+should_include_volume (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksBlock *block)
+{
+ gboolean ret = FALSE;
+
+ /* Check should_include_mount() for all mount points, if any - e.g. if a volume
+ * is mounted in a place where the mount is to be ignored, we ignore the volume
+ * as well
+ */
+ if (!should_include_volume_check_mount_points (monitor, block))
+ goto out;
+
+ /* TODO: handle crypto, fstab and a bunch of other stuff */
+ if (g_strcmp0 (udisks_block_get_id_usage (block), "filesystem") != 0)
+ goto out;
+
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+should_include_drive (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksDrive *drive)
+{
+ gboolean ret = TRUE;
+ /* TODO */
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gint
+udisks_drive_compare (UDisksDrive *a, UDisksDrive *b)
+{
+ return g_strcmp0 (g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (a))),
+ g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (b))));
+}
+
+static gint
+block_compare (UDisksBlock *a, UDisksBlock *b)
+{
+ return g_strcmp0 (udisks_block_get_device (a), udisks_block_get_device (b));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GVfsUDisks2Drive *
+find_drive_for_udisks_drive (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksDrive *udisks_drive)
+{
+ GVfsUDisks2Drive *ret = NULL;
+ GList *l;
+
+ for (l = monitor->drives; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Drive *drive = GVFS_UDISKS2_DRIVE (l->data);
+ if (gvfs_udisks2_drive_get_udisks_drive (drive) == udisks_drive)
+ {
+ ret = drive;
+ goto out;
+ }
+ }
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GVfsUDisks2Volume *
+find_volume_for_block (GVfsUDisks2VolumeMonitor *monitor,
+ UDisksBlock *block)
+{
+ GVfsUDisks2Volume *ret = NULL;
+ GList *l;
+
+ for (l = monitor->volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (l->data);
+ if (gvfs_udisks2_volume_get_block (volume) == block)
+ {
+ ret = volume;
+ goto out;
+ }
+ }
+
+ for (l = monitor->disc_volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (l->data);
+ if (gvfs_udisks2_volume_get_block (volume) == block)
+ {
+ ret = volume;
+ goto out;
+ }
+ }
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GVfsUDisks2Volume *
+find_volume_for_device (GVfsUDisks2VolumeMonitor *monitor,
+ const gchar *device)
+{
+ GVfsUDisks2Volume *ret = NULL;
+ GList *l;
+ struct stat statbuf;
+
+ if (stat (device, &statbuf) != 0)
+ goto out;
+
+ for (l = monitor->volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (l->data);
+ if (gvfs_udisks2_volume_get_dev (volume) == statbuf.st_rdev)
+ {
+ ret = volume;
+ goto out;
+ }
+ }
+
+ for (l = monitor->disc_volumes; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (l->data);
+ if (gvfs_udisks2_volume_get_dev (volume) == statbuf.st_rdev)
+ {
+ ret = volume;
+ goto out;
+ }
+ }
+
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GVfsUDisks2Mount *
+find_mount_by_mount_path (GVfsUDisks2VolumeMonitor *monitor,
+ const gchar *mount_path)
+{
+ GVfsUDisks2Mount *ret = NULL;
+ GList *l;
+
+ for (l = monitor->mounts; l != NULL; l = l->next)
+ {
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
+ if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+ {
+ ret = mount;
+ goto out;
+ }
+ }
+ out:
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_drives (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_drives,
+ GList **removed_drives)
+{
+ GList *cur_udisks_drives;
+ GList *new_udisks_drives;
+ GList *removed, *added;
+ GList *l;
+ GVfsUDisks2Drive *drive;
+ GList *objects;
+
+ objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (monitor->client));
+
+ cur_udisks_drives = NULL;
+ for (l = monitor->drives; l != NULL; l = l->next)
+ {
+ cur_udisks_drives = g_list_prepend (cur_udisks_drives,
+ gvfs_udisks2_drive_get_udisks_drive (GVFS_UDISKS2_DRIVE (l->data)));
+ }
+
+ /* remove devices we want to ignore - we do it here so we get to reevaluate
+ * on the next update whether they should still be ignored
+ */
+ new_udisks_drives = NULL;
+ for (l = objects; l != NULL; l = l->next)
+ {
+ UDisksDrive *udisks_drive = udisks_object_peek_drive (UDISKS_OBJECT (l->data));
+ if (udisks_drive == NULL)
+ continue;
+ if (should_include_drive (monitor, udisks_drive))
+ new_udisks_drives = g_list_prepend (new_udisks_drives, udisks_drive);
+ }
+
+ cur_udisks_drives = g_list_sort (cur_udisks_drives, (GCompareFunc) udisks_drive_compare);
+ new_udisks_drives = g_list_sort (new_udisks_drives, (GCompareFunc) udisks_drive_compare);
+ diff_sorted_lists (cur_udisks_drives,
+ new_udisks_drives, (GCompareFunc) udisks_drive_compare,
+ &added, &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ UDisksDrive *udisks_drive = UDISKS_DRIVE (l->data);
+
+ drive = find_drive_for_udisks_drive (monitor, udisks_drive);
+ if (drive != NULL)
+ {
+ /*g_debug ("removing drive %s", gdu_presentable_get_id (p));*/
+ gvfs_udisks2_drive_disconnected (drive);
+ monitor->drives = g_list_remove (monitor->drives, drive);
+ *removed_drives = g_list_prepend (*removed_drives, g_object_ref (drive));
+ g_object_unref (drive);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ UDisksDrive *udisks_drive = UDISKS_DRIVE (l->data);
+
+ drive = find_drive_for_udisks_drive (monitor, udisks_drive);
+ if (drive == NULL)
+ {
+ /*g_debug ("adding drive %s", gdu_presentable_get_id (p));*/
+ drive = gvfs_udisks2_drive_new (monitor, udisks_drive);
+ if (udisks_drive != NULL)
+ {
+ monitor->drives = g_list_prepend (monitor->drives, drive);
+ *added_drives = g_list_prepend (*added_drives, g_object_ref (drive));
+ }
+ }
+ }
+
+ g_list_free (added);
+ g_list_free (removed);
+
+ g_list_free (cur_udisks_drives);
+ g_list_free (new_udisks_drives);
+
+ g_list_foreach (objects, (GFunc) g_object_unref, NULL);
+ g_list_free (objects);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_volumes (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_volumes,
+ GList **removed_volumes)
+{
+ GList *cur_block_volumes;
+ GList *new_block_volumes;
+ GList *removed, *added;
+ GList *l;
+ GVfsUDisks2Volume *volume;
+ GList *objects;
+
+ objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (monitor->client));
+
+ cur_block_volumes = NULL;
+ for (l = monitor->volumes; l != NULL; l = l->next)
+ {
+ cur_block_volumes = g_list_prepend (cur_block_volumes,
+ gvfs_udisks2_volume_get_block (GVFS_UDISKS2_VOLUME (l->data)));
+ }
+
+ new_block_volumes = NULL;
+ for (l = objects; l != NULL; l = l->next)
+ {
+ UDisksBlock *block = udisks_object_peek_block (UDISKS_OBJECT (l->data));
+ if (block == NULL)
+ continue;
+ if (should_include_volume (monitor, block))
+ new_block_volumes = g_list_prepend (new_block_volumes, block);
+ }
+
+ cur_block_volumes = g_list_sort (cur_block_volumes, (GCompareFunc) block_compare);
+ new_block_volumes = g_list_sort (new_block_volumes, (GCompareFunc) block_compare);
+ diff_sorted_lists (cur_block_volumes,
+ new_block_volumes, (GCompareFunc) block_compare,
+ &added, &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ UDisksBlock *block = UDISKS_BLOCK (l->data);
+ volume = find_volume_for_block (monitor, block);
+ if (volume != NULL)
+ {
+ gvfs_udisks2_volume_removed (volume);
+ monitor->volumes = g_list_remove (monitor->volumes, volume);
+ *removed_volumes = g_list_prepend (*removed_volumes, g_object_ref (volume));
+ g_object_unref (volume);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ UDisksBlock *block = UDISKS_BLOCK (l->data);
+ volume = find_volume_for_block (monitor, block);
+ if (volume == NULL)
+ {
+ GVfsUDisks2Drive *drive = NULL;
+ UDisksDrive *udisks_drive;
+
+ udisks_drive = udisks_client_get_drive_for_block (monitor->client, block);
+ if (udisks_drive != NULL)
+ {
+ drive = find_drive_for_udisks_drive (monitor, udisks_drive);
+ g_object_unref (udisks_drive);
+ }
+ volume = gvfs_udisks2_volume_new (monitor,
+ block,
+ drive,
+ NULL); /* activation_root */
+ if (volume != NULL)
+ {
+ monitor->volumes = g_list_prepend (monitor->volumes, volume);
+ *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
+ }
+ }
+ }
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_free (new_block_volumes);
+ g_list_free (cur_block_volumes);
+
+ g_list_foreach (objects, (GFunc) g_object_unref, NULL);
+ g_list_free (objects);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_mounts (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_mounts,
+ GList **removed_mounts)
+{
+ GList *new_mounts;
+ GList *removed, *added;
+ GList *l, *ll;
+ GVfsUDisks2Mount *mount;
+ GVfsUDisks2Volume *volume;
+
+ new_mounts = g_unix_mounts_get (NULL);
+
+ /* remove mounts we want to ignore - we do it here so we get to reevaluate
+ * on the next update whether they should still be ignored
+ */
+ for (l = new_mounts; l != NULL; l = ll)
+ {
+ GUnixMountEntry *mount_entry = l->data;
+ ll = l->next;
+ if (!should_include_mount (monitor, mount_entry))
+ {
+ g_unix_mount_free (mount_entry);
+ new_mounts = g_list_delete_link (new_mounts, l);
+ }
+ }
+ new_mounts = g_list_sort (new_mounts, (GCompareFunc) g_unix_mount_compare);
+
+ diff_sorted_lists (monitor->last_mounts,
+ new_mounts, (GCompareFunc) g_unix_mount_compare,
+ &added, &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ GUnixMountEntry *mount_entry = l->data;
+ mount = find_mount_by_mount_path (monitor, g_unix_mount_get_mount_path (mount_entry));
+ if (mount != NULL)
+ {
+ gvfs_udisks2_mount_unmounted (mount);
+ monitor->mounts = g_list_remove (monitor->mounts, mount);
+ *removed_mounts = g_list_prepend (*removed_mounts, g_object_ref (mount));
+ g_object_unref (mount);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ GUnixMountEntry *mount_entry = l->data;
+ const gchar *device_file;
+
+ device_file = g_unix_mount_get_device_path (mount_entry);
+ volume = find_volume_for_device (monitor, device_file);
+ mount = gvfs_udisks2_mount_new (monitor, mount_entry, volume); /* adopts mount_entry */
+ if (mount != NULL)
+ {
+ monitor->mounts = g_list_prepend (monitor->mounts, mount);
+ *added_mounts = g_list_prepend (*added_mounts, g_object_ref (mount));
+ }
+ }
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_foreach (monitor->last_mounts, (GFunc) g_unix_mount_free, NULL);
+ g_list_free (monitor->last_mounts);
+ monitor->last_mounts = new_mounts;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+update_discs (GVfsUDisks2VolumeMonitor *monitor,
+ GList **added_volumes,
+ GList **removed_volumes,
+ GList **added_mounts,
+ GList **removed_mounts)
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.h b/monitor/udisks2/gvfsudisks2volumemonitor.h
index 57a67ac..a152743 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.h
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.h
@@ -32,9 +32,9 @@
G_BEGIN_DECLS
-#define GVFS_TYPE_UDISKS2_VOLUME_MONITOR (gvfs_udisks2_volume_monitor_get_type ())
-#define GVFS_UDISKS2_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVFS_TYPE_UDISKS2_VOLUME_MONITOR, GVfsUDisks2VolumeMonitor))
-#define G_IS_GDU_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVFS_TYPE_UDISKS2_VOLUME_MONITOR))
+#define GVFS_TYPE_UDISKS2_VOLUME_MONITOR (gvfs_udisks2_volume_monitor_get_type ())
+#define GVFS_UDISKS2_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVFS_TYPE_UDISKS2_VOLUME_MONITOR, GVfsUDisks2VolumeMonitor))
+#define GVFS_IS_UDISKS2_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVFS_TYPE_UDISKS2_VOLUME_MONITOR))
typedef struct _GVfsUDisks2VolumeMonitor GVfsUDisks2VolumeMonitor;
@@ -43,8 +43,9 @@ typedef struct _GVfsUDisks2Drive GVfsUDisks2Drive;
typedef struct _GVfsUDisks2Volume GVfsUDisks2Volume;
typedef struct _GVfsUDisks2Mount GVfsUDisks2Mount;
-GType gvfs_udisks2_volume_monitor_get_type (void) G_GNUC_CONST;
-GVolumeMonitor *gvfs_udisks2_volume_monitor_new (void);
+GType gvfs_udisks2_volume_monitor_get_type (void) G_GNUC_CONST;
+GVolumeMonitor *gvfs_udisks2_volume_monitor_new (void);
+UDisksClient *gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]