diff options
Diffstat (limited to 'trunk/client/gdaemonvolumemonitor.c')
-rw-r--r-- | trunk/client/gdaemonvolumemonitor.c | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/trunk/client/gdaemonvolumemonitor.c b/trunk/client/gdaemonvolumemonitor.c new file mode 100644 index 00000000..2ca21130 --- /dev/null +++ b/trunk/client/gdaemonvolumemonitor.c @@ -0,0 +1,321 @@ + +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 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: Alexander Larsson <alexl@redhat.com> + */ + +#include <config.h> + +#include <string.h> + +#include <glib.h> +#include <glib/gi18n-lib.h> +#include "gdaemonvolumemonitor.h" +#include "gdaemonmount.h" +#include "gdaemonvfs.h" +#include "gmounttracker.h" + +G_LOCK_DEFINE_STATIC(daemon_vm); + +static GDaemonVolumeMonitor *_the_daemon_volume_monitor; + +struct _GDaemonVolumeMonitor { + GVolumeMonitor parent; + + GMountTracker *mount_tracker; + GList *mounts; +}; + +G_DEFINE_DYNAMIC_TYPE (GDaemonVolumeMonitor, g_daemon_volume_monitor, G_TYPE_VOLUME_MONITOR) + +static GList * +get_mounts (GVolumeMonitor *volume_monitor) +{ + GDaemonVolumeMonitor *monitor; + GList *l; + + G_LOCK (daemon_vm); + + monitor = G_DAEMON_VOLUME_MONITOR (volume_monitor); + + l = g_list_copy (monitor->mounts); + g_list_foreach (l, (GFunc)g_object_ref, NULL); + + G_UNLOCK (daemon_vm); + + return l; +} + +static GList * +get_volumes (GVolumeMonitor *volume_monitor) +{ + /* TODO: Can daemon mounts have volumes? */ + return NULL; +} + +static GList * +get_connected_drives (GVolumeMonitor *volume_monitor) +{ + /* TODO: Can daemon mounts have drives? */ + return NULL; +} + +static GVolume * +get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static GMount * +get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) +{ + return NULL; +} + +static GDaemonMount * +find_mount_by_mount_info (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info) +{ + GDaemonMount *found_mount = NULL; + GList *l; + + for (l = daemon_monitor->mounts; l; l = g_list_next (l)) + { + GDaemonMount *existing_mount = l->data; + GMountInfo *existing_mount_info; + + existing_mount_info = g_daemon_mount_get_mount_info (existing_mount); + if (g_mount_info_equal (mount_info, existing_mount_info)) + { + found_mount = existing_mount; + break; + } + } + + return found_mount; +} + +GDaemonMount * +g_daemon_volume_monitor_find_mount_by_mount_info (GMountInfo *mount_info) +{ + GDaemonMount *daemon_mount; + + G_LOCK (daemon_vm); + + daemon_mount = NULL; + if (_the_daemon_volume_monitor != NULL) + { + daemon_mount = find_mount_by_mount_info (_the_daemon_volume_monitor, mount_info); + + if (daemon_mount != NULL) + g_object_ref (daemon_mount); + } + + G_UNLOCK (daemon_vm); + + return daemon_mount; +} + +static void +mount_added (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info) +{ + GDaemonMount *mount; + + G_LOCK (daemon_vm); + + mount = find_mount_by_mount_info (daemon_monitor, mount_info); + if (mount) + { + g_warning (G_STRLOC ": Mount was added twice!"); + + G_UNLOCK (daemon_vm); + return; + } + + if (mount_info->user_visible) + { + mount = g_daemon_mount_new (mount_info, G_VOLUME_MONITOR (daemon_monitor)); + daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount); + + /* Ref for the signal emission, other ref is owned by volume monitor */ + g_object_ref (mount); + } + + G_UNLOCK (daemon_vm); + + if (mount) + { + /* Emit signal outside lock */ + g_signal_emit_by_name (daemon_monitor, "mount_added", mount); + g_object_unref (mount); + } +} + +static void +mount_removed (GDaemonVolumeMonitor *daemon_monitor, GMountInfo *mount_info) +{ + GDaemonMount *mount; + + G_LOCK (daemon_vm); + + mount = find_mount_by_mount_info (daemon_monitor, mount_info); + if (!mount) + { + if (mount_info->user_visible) + g_warning (G_STRLOC ": An unknown mount was removed!"); + + G_UNLOCK (daemon_vm); + return; + } + + daemon_monitor->mounts = g_list_remove (daemon_monitor->mounts, mount); + + G_UNLOCK (daemon_vm); + + g_signal_emit_by_name (daemon_monitor, "mount_removed", mount); + g_signal_emit_by_name (mount, "unmounted"); + + g_object_unref (mount); +} + +static void +g_daemon_volume_monitor_init (GDaemonVolumeMonitor *daemon_monitor) +{ + GList *mounts, *l; + GDaemonMount *mount; + GMountInfo *info; + + _the_daemon_volume_monitor = daemon_monitor; + + daemon_monitor->mount_tracker = g_mount_tracker_new (_g_daemon_vfs_get_async_bus ()); + + g_signal_connect_swapped (daemon_monitor->mount_tracker, "mounted", + (GCallback) mount_added, daemon_monitor); + g_signal_connect_swapped (daemon_monitor->mount_tracker, "unmounted", + (GCallback) mount_removed, daemon_monitor); + + /* Initialize with current list */ + mounts = g_mount_tracker_list_mounts (daemon_monitor->mount_tracker); + + for (l = mounts; l != NULL; l = l->next) { + info = l->data; + if (info->user_visible) + { + mount = g_daemon_mount_new (info, G_VOLUME_MONITOR (daemon_monitor)); + daemon_monitor->mounts = g_list_prepend (daemon_monitor->mounts, mount); + } + + g_mount_info_unref (info); + } + + g_list_free (mounts); +} + +static void +g_daemon_volume_monitor_finalize (GObject *object) +{ + GDaemonVolumeMonitor *monitor; + + monitor = G_DAEMON_VOLUME_MONITOR (object); + + g_signal_handlers_disconnect_by_func (monitor->mount_tracker, mount_added, monitor); + g_signal_handlers_disconnect_by_func (monitor->mount_tracker, mount_removed, monitor); + + g_object_unref (monitor->mount_tracker); + + g_list_foreach (monitor->mounts, (GFunc)g_object_unref, NULL); + g_list_free (monitor->mounts); + + if (G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize) + (*G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->finalize) (object); +} + +static void +g_daemon_volume_monitor_dispose (GObject *object) +{ + GDaemonVolumeMonitor *monitor; + + monitor = G_DAEMON_VOLUME_MONITOR (object); + + G_LOCK (daemon_vm); + _the_daemon_volume_monitor = NULL; + G_UNLOCK (daemon_vm); + + if (G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->dispose) + (*G_OBJECT_CLASS (g_daemon_volume_monitor_parent_class)->dispose) (object); +} + +static void +g_daemon_volume_monitor_class_finalize (GDaemonVolumeMonitorClass *klass) +{ +} + +static gboolean +is_supported (void) +{ + GVfs *vfs; + gboolean res; + + res = FALSE; + + /* Don't do anything if the default vfs is not DAEMON_VFS */ + vfs = g_vfs_get_default (); + + if (vfs != NULL && G_IS_DAEMON_VFS (vfs)) + res = TRUE; + + return res; +} + +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; + gobject_class->dispose = g_daemon_volume_monitor_dispose; + + monitor_class->is_supported = is_supported; + monitor_class->get_mounts = get_mounts; + monitor_class->get_volumes = get_volumes; + monitor_class->get_connected_drives = get_connected_drives; + monitor_class->get_volume_for_uuid = get_volume_for_uuid; + monitor_class->get_mount_for_uuid = get_mount_for_uuid; +} + +GVolumeMonitor * +g_daemon_volume_monitor_new (void) +{ + GDaemonVolumeMonitor *monitor; + + monitor = g_object_new (G_TYPE_DAEMON_VOLUME_MONITOR, NULL); + + return G_VOLUME_MONITOR (monitor); +} + +void +g_daemon_volume_monitor_register_types (GTypeModule *module) +{ + g_daemon_volume_monitor_register_type (G_TYPE_MODULE (module)); + g_io_extension_point_implement (G_VOLUME_MONITOR_EXTENSION_POINT_NAME, + G_TYPE_DAEMON_VOLUME_MONITOR, + "gvfs", + 0); +} |