summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@src.gnome.org>2007-09-13 13:36:17 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-09-13 13:36:17 +0000
commit8924b724ebc40e630f14577234fc37daa06854be (patch)
tree8726bd79a8b3ae313c3319c65b1e2b2bb4f76188 /client
parentabedaec2e901f48a767e10be38274b91f7bfdc49 (diff)
downloadgvfs-8924b724ebc40e630f14577234fc37daa06854be.tar.gz
Add initial GDaemonVolume and GDaemonVolumeMonitor sources.
Original git commit by Hans Petter Jansson <hpj@kzerza.amok> at 1178826338 -0500 svn path=/trunk/; revision=550
Diffstat (limited to 'client')
-rw-r--r--client/Makefile.am2
-rw-r--r--client/gdaemonvolume.c182
-rw-r--r--client/gdaemonvolume.h33
-rw-r--r--client/gdaemonvolumemonitor.c306
-rw-r--r--client/gdaemonvolumemonitor.h33
5 files changed, 556 insertions, 0 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 12a5cbae..1077b786 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -14,6 +14,8 @@ modules_LTLIBRARIES = libgvfsdbus.la
libgvfsdbus_la_LDFLAGS = $(module_flags)
libgvfsdbus_la_SOURCES = \
gdaemonvfs.c gdaemonvfs.h \
+ gdaemonvolume.c gdaemonvolume.h \
+ gdaemonvolumemonitor.c gdaemonvolumemonitor.h \
gdaemonfile.c gdaemonfile.h \
gvfsuriutils.c gvfsuriutils.h \
gdaemonfileinputstream.c gdaemonfileinputstream.h \
diff --git a/client/gdaemonvolume.c b/client/gdaemonvolume.c
new file mode 100644
index 00000000..d51da304
--- /dev/null
+++ b/client/gdaemonvolume.c
@@ -0,0 +1,182 @@
+#include <config.h>
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include "gdaemonvolumemonitor.h"
+#include "gdaemonvolume.h"
+#include "gdaemondrive.h"
+
+struct _GDaemonVolume {
+ GObject parent;
+
+ GMountInfo *mount_info;
+ char *name;
+ char *icon;
+};
+
+static void g_daemon_volume_volume_iface_init (GVolumeIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GDaemonVolume, g_daemon_volume, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_VOLUME,
+ g_daemon_volume_volume_iface_init))
+
+
+static void
+g_daemon_volume_finalize (GObject *object)
+{
+ GDaemonVolume *volume;
+
+ volume = G_DAEMON_VOLUME (object);
+
+ g_free (volume->name);
+ g_free (volume->icon);
+ _g_mount_info_unref (volume->mount_info);
+
+ if (G_OBJECT_CLASS (g_daemon_volume_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_daemon_volume_parent_class)->finalize) (object);
+}
+
+static void
+g_daemon_volume_class_init (GDaemonVolumeClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = g_daemon_volume_finalize;
+}
+
+static void
+g_daemon_volume_init (GDaemonVolume *daemon_volume)
+{
+}
+
+GDaemonVolume *
+g_daemon_volume_new (GVolumeMonitor *volume_monitor,
+ GMountInfo *mount_info)
+{
+ GDaemonVolume *volume;
+ char *volume_name;
+
+ volume = g_object_new (G_TYPE_DAEMON_VOLUME, NULL);
+ volume->mount_info = _g_mount_info_ref (mount_info);
+
+ volume_name = NULL;
+
+ if (volume_name == NULL)
+ {
+ /* TODO: Use volume size as name? */
+ volume_name = g_strdup (_("Unknown volume"));
+ }
+
+ volume->name = volume_name;
+
+ /* TODO: Figure out a better icon */
+ volume->icon = g_strdup ("network");
+
+ return volume;
+}
+
+static char *
+g_daemon_volume_get_platform_id (GVolume *volume)
+{
+ GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume);
+
+ return g_strdup (daemon_volume->mount_info->spec->mount_prefix);
+}
+
+static GFile *
+g_daemon_volume_get_root (GVolume *volume)
+{
+ GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume);
+
+ return g_file_get_for_path (daemon_volume->mount_info->spec->mount_prefix);
+}
+
+static char *
+g_daemon_volume_get_icon (GVolume *volume)
+{
+ GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume);
+
+ return g_strdup (daemon_volume->icon);
+}
+
+static char *
+g_daemon_volume_get_name (GVolume *volume)
+{
+ GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume);
+
+ return g_strdup (daemon_volume->name);
+}
+
+static GDrive *
+g_daemon_volume_get_drive (GVolume *volume)
+{
+ GDaemonVolume *daemon_volume = G_DAEMON_VOLUME (volume);
+
+ daemon_volume = NULL;
+
+ return NULL;
+}
+
+static gboolean
+g_daemon_volume_can_unmount (GVolume *volume)
+{
+ /* TODO */
+ return TRUE;
+}
+
+static gboolean
+g_daemon_volume_can_eject (GVolume *volume)
+{
+ /* TODO */
+ return FALSE;
+}
+
+static void
+g_daemon_volume_unmount (GVolume *volume,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ /* TODO */
+}
+
+static gboolean
+g_daemon_volume_unmount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+g_daemon_volume_eject (GVolume *volume,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ /* TODO */
+}
+
+static gboolean
+g_daemon_volume_eject_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+g_daemon_volume_volume_iface_init (GVolumeIface *iface)
+{
+ iface->get_root = g_daemon_volume_get_root;
+ iface->get_name = g_daemon_volume_get_name;
+ iface->get_icon = g_daemon_volume_get_icon;
+ iface->get_drive = g_daemon_volume_get_drive;
+ iface->can_unmount = g_daemon_volume_can_unmount;
+ iface->can_eject = g_daemon_volume_can_eject;
+ iface->unmount = g_daemon_volume_unmount;
+ iface->unmount_finish = g_daemon_volume_unmount_finish;
+ iface->eject = g_daemon_volume_eject;
+ iface->eject_finish = g_daemon_volume_eject_finish;
+ iface->get_platform_id = g_daemon_volume_get_platform_id;
+}
diff --git a/client/gdaemonvolume.h b/client/gdaemonvolume.h
new file mode 100644
index 00000000..59512545
--- /dev/null
+++ b/client/gdaemonvolume.h
@@ -0,0 +1,33 @@
+#ifndef __G_DAEMON_VOLUME_H__
+#define __G_DAEMON_VOLUME_H__
+
+#include <glib-object.h>
+#include <gio/gvolume.h>
+#if 0
+# include <gio/gdaemonmounts.h>
+#endif
+#include "gdaemonvfs.h"
+#include "gdaemonvolumemonitor.h"
+
+G_BEGIN_DECLS
+
+#define G_TYPE_DAEMON_VOLUME (g_daemon_volume_get_type ())
+#define G_DAEMON_VOLUME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_VOLUME, GDaemonVolume))
+#define G_DAEMON_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_VOLUME, GDaemonVolumeClass))
+#define G_IS_DAEMON_VOLUME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_VOLUME))
+#define G_IS_DAEMON_VOLUME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_VOLUME))
+
+typedef struct _GDaemonVolumeClass GDaemonVolumeClass;
+
+struct _GDaemonVolumeClass {
+ GObjectClass parent_class;
+};
+
+GType g_daemon_volume_get_type (void) G_GNUC_CONST;
+
+GDaemonVolume *g_daemon_volume_new (GVolumeMonitor *volume_monitor,
+ GMountInfo *mount_info);
+
+G_END_DECLS
+
+#endif /* __G_DAEMON_VOLUME_H__ */
diff --git a/client/gdaemonvolumemonitor.c b/client/gdaemonvolumemonitor.c
new file mode 100644
index 00000000..115271cf
--- /dev/null
+++ b/client/gdaemonvolumemonitor.c
@@ -0,0 +1,306 @@
+#include <config.h>
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include "gdaemonvolumemonitor.h"
+#include "gdaemonvolume.h"
+
+struct _GDaemonVolumeMonitor {
+ GVolumeMonitor parent;
+
+ gpointer mount_monitor;
+
+ GList *last_mountpoints;
+ GList *last_mounts;
+
+ GList *drives;
+ GList *volumes;
+};
+
+static void update_drives (GDaemonVolumeMonitor *monitor);
+static void update_volumes (GDaemonVolumeMonitor *monitor);
+
+G_DEFINE_TYPE (GDaemonVolumeMonitor, g_daemon_volume_monitor, G_TYPE_VOLUME_MONITOR);
+
+static void
+g_daemon_volume_monitor_finalize (GObject *object)
+{
+ GDaemonVolumeMonitor *monitor;
+
+ monitor = G_DAEMON_VOLUME_MONITOR (object);
+
+ if (monitor->mount_monitor)
+ _g_stop_monitoring_daemon_mounts (monitor->mount_monitor);
+
+ g_list_foreach (monitor->last_mounts, (GFunc)_g_daemon_mount_free, NULL);
+ g_list_free (monitor->last_mounts);
+
+ g_list_foreach (monitor->volumes, (GFunc)g_object_unref, NULL);
+ g_list_free (monitor->volumes);
+ g_list_foreach (monitor->drives, (GFunc)g_object_unref, NULL);
+ g_list_free (monitor->drives);
+
+ if (G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize) (object);
+}
+
+static GList *
+get_mounted_volumes (GVolumeMonitor *volume_monitor)
+{
+ GDaemonVolumeMonitor *monitor;
+ GList *l;
+
+ monitor = G_DAEMON_VOLUME_MONITOR (volume_monitor);
+
+ l = g_list_copy (monitor->volumes);
+ g_list_foreach (l, (GFunc)g_object_ref, NULL);
+
+ return l;
+}
+
+static GList *
+get_connected_drives (GVolumeMonitor *volume_monitor)
+{
+ GDaemonVolumeMonitor *monitor;
+ GList *l;
+
+ monitor = G_DAEMON_VOLUME_MONITOR (volume_monitor);
+
+ l = g_list_copy (monitor->drives);
+ g_list_foreach (l, (GFunc)g_object_ref, NULL);
+
+ return l;
+}
+
+static void
+g_daemon_volume_monitor_class_init (GDaemonVolumeMonitorClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass);
+
+ gobject_class->finalize = g_daemon_volume_monitor_finalize;
+
+ monitor_class->get_mounted_volumes = get_mounted_volumes;
+ monitor_class->get_connected_drives = get_connected_drives;
+}
+
+static void
+mountpoints_changed (gpointer user_data)
+{
+ GDaemonVolumeMonitor *daemon_monitor = user_data;
+
+ /* Update both to make sure drives are created before volumes */
+ update_drives (daemon_monitor);
+ update_volumes (daemon_monitor);
+}
+
+static void
+mounts_changed (gpointer user_data)
+{
+ GDaemonVolumeMonitor *daemon_monitor = user_data;
+
+ /* Update both to make sure drives are created before volumes */
+ update_drives (daemon_monitor);
+ update_volumes (daemon_monitor);
+}
+
+static void
+g_daemon_volume_monitor_init (GDaemonVolumeMonitor *daemon_monitor)
+{
+
+ daemon_monitor->mount_monitor = _g_monitor_daemon_mounts (mountpoints_changed,
+ mounts_changed,
+ daemon_monitor);
+ update_drives (daemon_monitor);
+ update_volumes (daemon_monitor);
+
+}
+
+GVolumeMonitor *
+g_daemon_volume_monitor_new (void)
+{
+ GDaemonVolumeMonitor *monitor;
+
+ monitor = g_object_new (G_TYPE_DAEMON_VOLUME_MONITOR, NULL);
+
+ return G_VOLUME_MONITOR (monitor);
+}
+
+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;
+ }
+}
+
+GDaemonDrive *
+g_daemon_volume_monitor_lookup_drive_for_mountpoint (GDaemonVolumeMonitor *monitor,
+ const char *mountpoint)
+{
+ GList *l;
+
+ for (l = monitor->drives; l != NULL; l = l->next)
+ {
+ GDaemonDrive *drive = l->data;
+
+ if (g_daemon_drive_has_mountpoint (drive, mountpoint))
+ return drive;
+ }
+
+ return NULL;
+}
+
+static GDaemonVolume *
+find_volume_by_mountpoint (GDaemonVolumeMonitor *monitor,
+ const char *mountpoint)
+{
+ GList *l;
+
+ for (l = monitor->volumes; l != NULL; l = l->next)
+ {
+ GDaemonVolume *volume = l->data;
+
+ if (g_daemon_volume_has_mountpoint (volume, mountpoint))
+ return volume;
+ }
+
+ return NULL;
+}
+
+static void
+update_drives (GDaemonVolumeMonitor *monitor)
+{
+ GList *new_mountpoints;
+ GList *removed, *added;
+ GList *l;
+ GDaemonDrive *drive;
+
+ if (_g_get_daemon_mount_points (&new_mountpoints))
+ {
+ new_mountpoints = g_list_sort (new_mountpoints, (GCompareFunc) _g_daemon_mount_point_compare);
+
+ diff_sorted_lists (monitor->last_mountpoints,
+ new_mountpoints, (GCompareFunc) _g_daemon_mount_point_compare,
+ &added, &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ GDaemonMountPoint *mountpoint = l->data;
+
+ drive = g_daemon_volume_monitor_lookup_drive_for_mountpoint (monitor, mountpoint->mount_path);
+ if (drive)
+ {
+ g_daemon_drive_disconnected (drive);
+ monitor->drives = g_list_remove (monitor->drives, drive);
+ g_signal_emit_by_name (monitor, "drive_disconnected", drive);
+ g_object_unref (drive);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ GDaemonMountPoint *mountpoint = l->data;
+
+ drive = g_daemon_drive_new (G_VOLUME_MONITOR (monitor), mountpoint);
+ if (drive)
+ {
+ monitor->drives = g_list_prepend (monitor->drives, drive);
+ g_signal_emit_by_name (monitor, "drive_connected", drive);
+ }
+ }
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_foreach (monitor->last_mountpoints,
+ (GFunc)_g_daemon_mount_point_free, NULL);
+ g_list_free (monitor->last_mountpoints);
+ monitor->last_mountpoints = new_mountpoints;
+ }
+}
+
+static void
+update_volumes (GDaemonVolumeMonitor *monitor)
+{
+ GList *new_mounts;
+ GList *removed, *added;
+ GList *l;
+ GDaemonVolume *volume;
+
+ if (_g_get_daemon_mounts (&new_mounts))
+ {
+ new_mounts = g_list_sort (new_mounts, (GCompareFunc) _g_daemon_mount_compare);
+
+ diff_sorted_lists (monitor->last_mounts,
+ new_mounts, (GCompareFunc) _g_daemon_mount_compare,
+ &added, &removed);
+
+ for (l = removed; l != NULL; l = l->next)
+ {
+ GDaemonMount *mount = l->data;
+
+ volume = find_volume_by_mountpoint (monitor, mount->mount_path);
+ if (volume)
+ {
+ g_daemon_volume_unmounted (volume);
+ monitor->volumes = g_list_remove (monitor->volumes, volume);
+ g_signal_emit_by_name (monitor, "volume_unmounted", volume);
+ g_object_unref (volume);
+ }
+ }
+
+ for (l = added; l != NULL; l = l->next)
+ {
+ GDaemonMount *mount = l->data;
+
+ volume = g_daemon_volume_new (G_VOLUME_MONITOR (monitor), mount);
+ if (volume)
+ {
+ monitor->volumes = g_list_prepend (monitor->volumes, volume);
+ g_signal_emit_by_name (monitor, "volume_mounted", volume);
+ }
+ }
+
+ g_list_free (added);
+ g_list_free (removed);
+ g_list_foreach (monitor->last_mounts,
+ (GFunc)_g_daemon_mount_free, NULL);
+ g_list_free (monitor->last_mounts);
+ monitor->last_mounts = new_mounts;
+ }
+}
diff --git a/client/gdaemonvolumemonitor.h b/client/gdaemonvolumemonitor.h
new file mode 100644
index 00000000..3f867984
--- /dev/null
+++ b/client/gdaemonvolumemonitor.h
@@ -0,0 +1,33 @@
+#ifndef __G_DAEMON_VOLUME_MONITOR_H__
+#define __G_DAEMON_VOLUME_MONITOR_H__
+
+#include <glib-object.h>
+#include <gio/gvolumemonitor.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_DAEMON_VOLUME_MONITOR (g_daemon_volume_monitor_get_type ())
+#define G_DAEMON_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DAEMON_VOLUME_MONITOR, GDaemonVolumeMonitor))
+#define G_DAEMON_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DAEMON_VOLUME_MONITOR, GDaemonVolumeMonitorClass))
+#define G_IS_DAEMON_VOLUME_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DAEMON_VOLUME_MONITOR))
+#define G_IS_DAEMON_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DAEMON_VOLUME_MONITOR))
+
+typedef struct _GDaemonVolumeMonitor GDaemonVolumeMonitor;
+typedef struct _GDaemonVolumeMonitorClass GDaemonVolumeMonitorClass;
+
+/* Forward definitions */
+typedef struct _GDaemonVolume GDaemonVolume;
+typedef struct _GDaemonDrive GDaemonDrive;
+
+struct _GDaemonVolumeMonitorClass {
+ GVolumeMonitorClass parent_class;
+
+};
+
+GType g_daemon_volume_monitor_get_type (void) G_GNUC_CONST;
+
+GVolumeMonitor *g_daemon_volume_monitor_new (void);
+
+G_END_DECLS
+
+#endif /* __G_DAEMON_VOLUME_MONITOR_H__ */