diff --git a/ChangeLog b/ChangeLog index 2bcb3c77587b45fbf0c01b80f35d7be3be5f5b17..41d0f83a30ad5fecd1b37e16e62033085cca191d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-03-15 Benedikt Meurer <benny@xfce.org> + + * acinclude.m4(BM_THUNAR_VFS_VOLUME_IMPL): Handle "none" properly. + * thunar-vfs/thunar-vfs-volume-manager.c, thunar-vfs/Makefile.am, + thunar-vfs/thunar-vfs-volume-private.h, thunar-vfs/thunar-vfs.symbols, + thunar-vfs/thunar-vfs-volume.c, thunar-vfs/thunar-vfs-volume-none.c, + thunar-vfs/thunar-vfs-volume.h, thunar-vfs/thunar-vfs-volume-hal.c, + thunar-vfs/thunar-vfs-volume-freebsd.c: Improve the volume manager + implemenation. The ThunarVfsVolumeManager and ThunarVfsVolume inter- + faces are now abstract base classes, with the implementation API + completely separated from the public API. The HAL backend was fixed + to work around a strange HAL bug, where 'volume.is_mounted' is FALSE + for mounted volumes (instead of trusting HAL, we ask the kernel to + make sure we always display the proper state). Also, new signals + "mounted", "pre-unmount" and "unmounted" were added to both + ThunarVfsVolume and ThunarVfsVolumeManager, to allow applications to + perform certain actions for these events. + * docs/reference/thunar-vfs/: Update the API documentation. + * thunar/thunar-window.c: Whenever the user requests to unmount a + volume, check if the window displays a folder on this volume and if + so, go to the home folder, to make sure we don't display a probably + no longer existing mount point afterwards. + 2006-03-14 Benedikt Meurer <benny@xfce.org> * thunar-vfs/thunar-vfs-exec.{c,h}: Add thunar_vfs_exec_sync() helper diff --git a/acinclude.m4 b/acinclude.m4 index 8e3e4de75d1423a6beba9563bc23285962bce158..a0e1eba2d9483d18638d71e30b4bcb70a02c3700 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -79,6 +79,8 @@ AC_HELP_STRING([--with-volume-manager=@<:@auto/freebsd/hal/none@:>@], [The volum ac_bm_thunar_vfs_volume_impl=freebsd elif test x"$with_volume_manager" = x"hal"; then ac_bm_thunar_vfs_volume_impl=hal + elif test x"$with_volume_manager" = x"none"; then + ac_bm_thunar_vfs_volume_impl=none else dnl # Check target platform (auto-detection) case "$target_os" in diff --git a/docs/reference/thunar-vfs/thunar-vfs-sections.txt b/docs/reference/thunar-vfs/thunar-vfs-sections.txt index 8cad2a9f669c1a04c7a27e019466f51770a77fb2..da13c59b96ac8e9a140bee7c40c1522a20337c8e 100644 --- a/docs/reference/thunar-vfs/thunar-vfs-sections.txt +++ b/docs/reference/thunar-vfs/thunar-vfs-sections.txt @@ -386,7 +386,6 @@ thunar_vfs_humanize_size <TITLE>ThunarVfsVolume</TITLE> ThunarVfsVolumeKind ThunarVfsVolumeStatus -ThunarVfsVolumeIface ThunarVfsVolume thunar_vfs_volume_get_kind thunar_vfs_volume_get_name @@ -400,14 +399,16 @@ thunar_vfs_volume_lookup_icon_name thunar_vfs_volume_eject thunar_vfs_volume_mount thunar_vfs_volume_unmount -thunar_vfs_volume_changed <SUBSECTION Standard> +ThunarVfsVolumeClass THUNAR_VFS_TYPE_VFS_VOLUME_KIND THUNAR_VFS_TYPE_VFS_VOLUME_STATUS THUNAR_VFS_TYPE_VOLUME THUNAR_VFS_VOLUME +THUNAR_VFS_VOLUME_CLASS THUNAR_VFS_IS_VOLUME -THUNAR_VFS_VOLUME_GET_IFACE +THUNAR_VFS_IS_VOLUME_CLASS +THUNAR_VFS_VOLUME_GET_CLASS <SUBSECTION Private> thunar_vfs_volume_kind_get_type thunar_vfs_volume_status_get_type @@ -418,18 +419,18 @@ thunar_vfs_volume_get_type <SECTION> <FILE>thunar-vfs-volume-manager</FILE> <TITLE>ThunarVfsVolumeManager</TITLE> -ThunarVfsVolumeManagerIface ThunarVfsVolumeManager thunar_vfs_volume_manager_get_default thunar_vfs_volume_manager_get_volume_by_info thunar_vfs_volume_manager_get_volumes -thunar_vfs_volume_manager_volumes_added -thunar_vfs_volume_manager_volumes_removed <SUBSECTION Standard> +ThunarVfsVolumeManagerClass THUNAR_VFS_TYPE_VOLUME_MANAGER THUNAR_VFS_VOLUME_MANAGER +THUNAR_VFS_VOLUME_MANAGER_CLASS THUNAR_VFS_IS_VOLUME_MANAGER -THUNAR_VFS_VOLUME_MANAGER_GET_IFACE +THUNAR_VFS_IS_VOLUME_MANAGER_CLASS +THUNAR_VFS_VOLUME_MANAGER_GET_CLASS <SUBSECTION Private> thunar_vfs_volume_manager_get_type </SECTION> diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml index 7d8dcad9a2d40225d0b0acd1c047109ba37a59e3..a291a9ad13dc36ddc4bddc401f03464245913369 100644 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml +++ b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume-manager.sgml @@ -17,64 +17,77 @@ ThunarVfsVolumeManager <!-- ##### SECTION Stability_Level ##### --> -<!-- ##### STRUCT ThunarVfsVolumeManagerIface ##### --> +<!-- ##### STRUCT ThunarVfsVolumeManager ##### --> <para> </para> -@get_volume_by_info: -@get_volumes: -@volumes_added: -@volumes_removed: +@volumes: -<!-- ##### STRUCT ThunarVfsVolumeManager ##### --> +<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-mounted ##### --> <para> </para> +@thunarvfsvolumemanager: the object which received the signal. +@arg1: -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_default ##### --> +<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-pre-unmount ##### --> <para> </para> -@Returns: +@thunarvfsvolumemanager: the object which received the signal. +@arg1: +<!-- ##### SIGNAL ThunarVfsVolumeManager::volume-unmounted ##### --> +<para> -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volume_by_info ##### --> +</para> + +@thunarvfsvolumemanager: the object which received the signal. +@arg1: + +<!-- ##### SIGNAL ThunarVfsVolumeManager::volumes-added ##### --> <para> </para> -@manager: -@info: -@Returns: +@thunarvfsvolumemanager: the object which received the signal. +@arg1: +<!-- ##### SIGNAL ThunarVfsVolumeManager::volumes-removed ##### --> +<para> -<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volumes ##### --> +</para> + +@thunarvfsvolumemanager: the object which received the signal. +@arg1: + +<!-- ##### FUNCTION thunar_vfs_volume_manager_get_default ##### --> <para> </para> -@manager: @Returns: -<!-- ##### FUNCTION thunar_vfs_volume_manager_volumes_added ##### --> +<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volume_by_info ##### --> <para> </para> @manager: -@volumes: +@info: +@Returns: -<!-- ##### FUNCTION thunar_vfs_volume_manager_volumes_removed ##### --> +<!-- ##### FUNCTION thunar_vfs_volume_manager_get_volumes ##### --> <para> </para> @manager: -@volumes: +@Returns: diff --git a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml index ce5eed3c9063fa69e7b4e9e5f73d7373321ed9c0..efb2c2dda1f2c67de6f2d764ca66da02cec2ea8e 100644 --- a/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml +++ b/docs/reference/thunar-vfs/tmpl/thunar-vfs-volume.sgml @@ -45,26 +45,39 @@ ThunarVfsVolume @THUNAR_VFS_VOLUME_STATUS_MOUNTED: @THUNAR_VFS_VOLUME_STATUS_PRESENT: -<!-- ##### STRUCT ThunarVfsVolumeIface ##### --> +<!-- ##### STRUCT ThunarVfsVolume ##### --> <para> </para> -@get_kind: -@get_name: -@get_status: -@get_mount_point: -@lookup_icon_name: -@eject: -@mount: -@unmount: -@changed: -<!-- ##### STRUCT ThunarVfsVolume ##### --> +<!-- ##### SIGNAL ThunarVfsVolume::changed ##### --> +<para> + +</para> + +@thunarvfsvolume: the object which received the signal. + +<!-- ##### SIGNAL ThunarVfsVolume::mounted ##### --> +<para> + +</para> + +@thunarvfsvolume: the object which received the signal. + +<!-- ##### SIGNAL ThunarVfsVolume::pre-unmount ##### --> <para> </para> +@thunarvfsvolume: the object which received the signal. + +<!-- ##### SIGNAL ThunarVfsVolume::unmounted ##### --> +<para> + +</para> + +@thunarvfsvolume: the object which received the signal. <!-- ##### FUNCTION thunar_vfs_volume_get_kind ##### --> <para> @@ -181,11 +194,3 @@ ThunarVfsVolume @Returns: -<!-- ##### FUNCTION thunar_vfs_volume_changed ##### --> -<para> - -</para> - -@volume: - - diff --git a/thunar-vfs/Makefile.am b/thunar-vfs/Makefile.am index 3f87b95d6df049566fee9f7c3a78dba7b8c8bb7d..b290e1abfaa7d935b57d3472890a723cb0972768 100644 --- a/thunar-vfs/Makefile.am +++ b/thunar-vfs/Makefile.am @@ -103,6 +103,8 @@ libthunar_vfs_1_la_SOURCES = \ thunar-vfs-user.c \ thunar-vfs-util.c \ thunar-vfs-volume.c \ + thunar-vfs-volume-manager.c \ + thunar-vfs-volume-private.h \ thunar-vfs-xfer.c \ thunar-vfs-xfer.h \ thunar-vfs.c diff --git a/thunar-vfs/thunar-vfs-volume-freebsd.c b/thunar-vfs/thunar-vfs-volume-freebsd.c index 851c47ed25090878ccbd13f1e0a8254414dda103..c00f6868954490684f150c101d3110c9ce6b31c7 100644 --- a/thunar-vfs/thunar-vfs-volume-freebsd.c +++ b/thunar-vfs/thunar-vfs-volume-freebsd.c @@ -45,17 +45,14 @@ #include <unistd.h> #endif -#include <exo/exo.h> - #include <thunar-vfs/thunar-vfs-exec.h> #include <thunar-vfs/thunar-vfs-volume-freebsd.h> +#include <thunar-vfs/thunar-vfs-volume-private.h> #include <thunar-vfs/thunar-vfs-alias.h> static void thunar_vfs_volume_freebsd_class_init (ThunarVfsVolumeFreeBSDClass *klass); -static void thunar_vfs_volume_freebsd_volume_init (ThunarVfsVolumeIface *iface); -static void thunar_vfs_volume_freebsd_init (ThunarVfsVolumeFreeBSD *volume_freebsd); static void thunar_vfs_volume_freebsd_finalize (GObject *object); static ThunarVfsVolumeKind thunar_vfs_volume_freebsd_get_kind (ThunarVfsVolume *volume); static const gchar *thunar_vfs_volume_freebsd_get_name (ThunarVfsVolume *volume); @@ -78,12 +75,12 @@ static ThunarVfsVolumeFreeBSD *thunar_vfs_volume_freebsd_new (cons struct _ThunarVfsVolumeFreeBSDClass { - GObjectClass __parent__; + ThunarVfsVolumeClass __parent__; }; struct _ThunarVfsVolumeFreeBSD { - GObject __parent__; + ThunarVfsVolume __parent__; gchar *device_path; const gchar *device_name; @@ -102,42 +99,59 @@ struct _ThunarVfsVolumeFreeBSD -G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeFreeBSD, - thunar_vfs_volume_freebsd, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME, - thunar_vfs_volume_freebsd_volume_init)); +static GObjectClass *thunar_vfs_volume_freebsd_parent_class; -static void -thunar_vfs_volume_freebsd_class_init (ThunarVfsVolumeFreeBSDClass *klass) +GType +thunar_vfs_volume_freebsd_get_type (void) { - GObjectClass *gobject_class; + static GType type = G_TYPE_INVALID; - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_freebsd_finalize; + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeFreeBSDClass), + NULL, + NULL, + (GClassInitFunc) thunar_vfs_volume_freebsd_class_init, + NULL, + NULL, + sizeof (ThunarVfsVolumeFreeBSD), + 0, + NULL, + NULL, + }; + + type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME, I_("ThunarVfsVolumeFreeBSD"), &info, 0); + } + + return type; } static void -thunar_vfs_volume_freebsd_volume_init (ThunarVfsVolumeIface *iface) +thunar_vfs_volume_freebsd_class_init (ThunarVfsVolumeFreeBSDClass *klass) { - iface->get_kind = thunar_vfs_volume_freebsd_get_kind; - iface->get_name = thunar_vfs_volume_freebsd_get_name; - iface->get_status = thunar_vfs_volume_freebsd_get_status; - iface->get_mount_point = thunar_vfs_volume_freebsd_get_mount_point; - iface->eject = thunar_vfs_volume_freebsd_eject; - iface->mount = thunar_vfs_volume_freebsd_mount; - iface->unmount = thunar_vfs_volume_freebsd_unmount; -} + ThunarVfsVolumeClass *thunarvfs_volume_class; + GObjectClass *gobject_class; + /* determine the parent type class */ + thunar_vfs_volume_freebsd_parent_class = g_type_class_peek_parent (klass); + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_vfs_volume_freebsd_finalize; -static void -thunar_vfs_volume_freebsd_init (ThunarVfsVolumeFreeBSD *volume_freebsd) -{ + thunarvfs_volume_class = THUNAR_VFS_VOLUME_CLASS (klass); + thunarvfs_volume_class->get_kind = thunar_vfs_volume_freebsd_get_kind; + thunarvfs_volume_class->get_name = thunar_vfs_volume_freebsd_get_name; + thunarvfs_volume_class->get_status = thunar_vfs_volume_freebsd_get_status; + thunarvfs_volume_class->get_mount_point = thunar_vfs_volume_freebsd_get_mount_point; + thunarvfs_volume_class->eject = thunar_vfs_volume_freebsd_eject; + thunarvfs_volume_class->mount = thunar_vfs_volume_freebsd_mount; + thunarvfs_volume_class->unmount = thunar_vfs_volume_freebsd_unmount; } @@ -147,9 +161,7 @@ thunar_vfs_volume_freebsd_finalize (GObject *object) { ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (object); - g_return_if_fail (THUNAR_VFS_IS_VOLUME_FREEBSD (volume_freebsd)); - - if (G_LIKELY (volume_freebsd->update_timer_id >= 0)) + if (G_LIKELY (volume_freebsd->update_timer_id > 0)) g_source_remove (volume_freebsd->update_timer_id); if (G_LIKELY (volume_freebsd->mount_point != NULL)) @@ -158,7 +170,7 @@ thunar_vfs_volume_freebsd_finalize (GObject *object) g_free (volume_freebsd->device_path); g_free (volume_freebsd->label); - G_OBJECT_CLASS (thunar_vfs_volume_freebsd_parent_class)->finalize (object); + (*G_OBJECT_CLASS (thunar_vfs_volume_freebsd_parent_class)->finalize) (object); } @@ -175,7 +187,6 @@ static const gchar* thunar_vfs_volume_freebsd_get_name (ThunarVfsVolume *volume) { ThunarVfsVolumeFreeBSD *volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (volume); - return (volume_freebsd->label != NULL) ? volume_freebsd->label : volume_freebsd->device_name; } @@ -405,52 +416,60 @@ thunar_vfs_volume_freebsd_new (const gchar *device_path, static void thunar_vfs_volume_manager_freebsd_class_init (ThunarVfsVolumeManagerFreeBSDClass *klass); -static void thunar_vfs_volume_manager_freebsd_manager_init (ThunarVfsVolumeManagerIface *iface); static void thunar_vfs_volume_manager_freebsd_init (ThunarVfsVolumeManagerFreeBSD *manager_freebsd); -static void thunar_vfs_volume_manager_freebsd_finalize (GObject *object); static ThunarVfsVolume *thunar_vfs_volume_manager_freebsd_get_volume_by_info (ThunarVfsVolumeManager *manager, const ThunarVfsInfo *info); -static GList *thunar_vfs_volume_manager_freebsd_get_volumes (ThunarVfsVolumeManager *manager); struct _ThunarVfsVolumeManagerFreeBSDClass { - GObjectClass __parent__; + ThunarVfsVolumeManagerClass __parent__; }; struct _ThunarVfsVolumeManagerFreeBSD { - GObject __parent__; - GList *volumes; + ThunarVfsVolumeManager __parent__; }; -G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeManagerFreeBSD, - thunar_vfs_volume_manager_freebsd, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME_MANAGER, - thunar_vfs_volume_manager_freebsd_manager_init)); - - - -static void -thunar_vfs_volume_manager_freebsd_class_init (ThunarVfsVolumeManagerFreeBSDClass *klass) +GType +thunar_vfs_volume_manager_freebsd_get_type (void) { - GObjectClass *gobject_class; + static GType type = G_TYPE_INVALID; - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_manager_freebsd_finalize; + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeManagerFreeBSDClass), + NULL, + NULL, + (GClassInitFunc) thunar_vfs_volume_manager_freebsd_class_init, + NULL, + NULL, + sizeof (ThunarVfsVolumeManagerFreeBSD), + 0, + (GInstanceInitFunc) thunar_vfs_volume_manager_freebsd_init, + NULL, + }; + + type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME_MANAGER, I_("ThunarVfsVolumeManagerFreeBSD"), &info, 0); + } + + return type; } static void -thunar_vfs_volume_manager_freebsd_manager_init (ThunarVfsVolumeManagerIface *iface) +thunar_vfs_volume_manager_freebsd_class_init (ThunarVfsVolumeManagerFreeBSDClass *klass) { - iface->get_volume_by_info = thunar_vfs_volume_manager_freebsd_get_volume_by_info; - iface->get_volumes = thunar_vfs_volume_manager_freebsd_get_volumes; + ThunarVfsVolumeManagerClass *thunarvfs_volume_manager_class; + + thunarvfs_volume_manager_class = THUNAR_VFS_VOLUME_MANAGER_CLASS (klass); + thunarvfs_volume_manager_class->get_volume_by_info = thunar_vfs_volume_manager_freebsd_get_volume_by_info; } @@ -480,7 +499,10 @@ thunar_vfs_volume_manager_freebsd_init (ThunarVfsVolumeManagerFreeBSD *manager_f volume_freebsd = thunar_vfs_volume_freebsd_new (fs->fs_spec, fs->fs_file); if (G_LIKELY (volume_freebsd != NULL)) - manager_freebsd->volumes = g_list_append (manager_freebsd->volumes, volume_freebsd); + { + thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_freebsd), THUNAR_VFS_VOLUME (volume_freebsd)); + g_object_unref (G_OBJECT (volume_freebsd)); + } } /* unload the fstab database */ @@ -489,32 +511,14 @@ thunar_vfs_volume_manager_freebsd_init (ThunarVfsVolumeManagerFreeBSD *manager_f -static void -thunar_vfs_volume_manager_freebsd_finalize (GObject *object) -{ - ThunarVfsVolumeManagerFreeBSD *manager_freebsd = THUNAR_VFS_VOLUME_MANAGER_FREEBSD (object); - GList *lp; - - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager_freebsd)); - - for (lp = manager_freebsd->volumes; lp != NULL; lp = lp->next) - g_object_unref (G_OBJECT (lp->data)); - g_list_free (manager_freebsd->volumes); - - G_OBJECT_CLASS (thunar_vfs_volume_manager_freebsd_parent_class)->finalize (object); -} - - - static ThunarVfsVolume* thunar_vfs_volume_manager_freebsd_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) + const ThunarVfsInfo *info) { - ThunarVfsVolumeManagerFreeBSD *manager_freebsd = THUNAR_VFS_VOLUME_MANAGER_FREEBSD (manager); - ThunarVfsVolumeFreeBSD *volume_freebsd = NULL; - GList *lp; + ThunarVfsVolumeFreeBSD *volume_freebsd = NULL; + GList *lp; - for (lp = manager_freebsd->volumes; lp != NULL; lp = lp->next) + for (lp = manager->volumes; lp != NULL; lp = lp->next) { volume_freebsd = THUNAR_VFS_VOLUME_FREEBSD (lp->data); if ((volume_freebsd->status & THUNAR_VFS_VOLUME_STATUS_MOUNTED) != 0 && volume_freebsd->device_id == info->device) @@ -526,12 +530,5 @@ thunar_vfs_volume_manager_freebsd_get_volume_by_info (ThunarVfsVolumeManager *ma -static GList* -thunar_vfs_volume_manager_freebsd_get_volumes (ThunarVfsVolumeManager *manager) -{ - return THUNAR_VFS_VOLUME_MANAGER_FREEBSD (manager)->volumes; -} - - - - +#define __THUNAR_VFS_VOLUME_FREEBSD_C__ +#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-hal.c b/thunar-vfs/thunar-vfs-volume-hal.c index 2047c1d375ac8e298a5ffa3c59af5eb5450d3b60..fe6b6be5aa4658a2b5f02bb72f7faa871c4e540e 100644 --- a/thunar-vfs/thunar-vfs-volume-hal.c +++ b/thunar-vfs/thunar-vfs-volume-hal.c @@ -35,19 +35,16 @@ #include <dbus/dbus-glib-lowlevel.h> -#include <exo/exo.h> - #include <libhal.h> #include <libhal-storage.h> #include <thunar-vfs/thunar-vfs-volume-hal.h> +#include <thunar-vfs/thunar-vfs-volume-private.h> #include <thunar-vfs/thunar-vfs-alias.h> static void thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass); -static void thunar_vfs_volume_hal_volume_init (ThunarVfsVolumeIface *iface); -static void thunar_vfs_volume_hal_init (ThunarVfsVolumeHal *volume_hal); static void thunar_vfs_volume_hal_finalize (GObject *object); static ThunarVfsVolumeKind thunar_vfs_volume_hal_get_kind (ThunarVfsVolume *volume); static const gchar *thunar_vfs_volume_hal_get_name (ThunarVfsVolume *volume); @@ -62,6 +59,8 @@ static gboolean thunar_vfs_volume_hal_mount (ThunarVfsVo static gboolean thunar_vfs_volume_hal_unmount (ThunarVfsVolume *volume, GtkWidget *window, GError **error); +static ThunarVfsPath *thunar_vfs_volume_hal_find_mount_point (ThunarVfsVolumeHal *volume_hal, + const gchar *file); static void thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, LibHalContext *context, LibHalVolume *hv, @@ -71,12 +70,12 @@ static void thunar_vfs_volume_hal_update (ThunarVfsVo struct _ThunarVfsVolumeHalClass { - GObjectClass __parent__; + ThunarVfsVolumeClass __parent__; }; struct _ThunarVfsVolumeHal { - GObject __parent__; + ThunarVfsVolume __parent__; gchar *udi; gchar *drive_udi; @@ -90,42 +89,59 @@ struct _ThunarVfsVolumeHal -G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeHal, - thunar_vfs_volume_hal, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME, - thunar_vfs_volume_hal_volume_init)); +static GObjectClass *thunar_vfs_volume_hal_parent_class; -static void -thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass) +GType +thunar_vfs_volume_hal_get_type (void) { - GObjectClass *gobject_class; + static GType type = G_TYPE_INVALID; - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_hal_finalize; + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeHalClass), + NULL, + NULL, + (GClassInitFunc) thunar_vfs_volume_hal_class_init, + NULL, + NULL, + sizeof (ThunarVfsVolumeHal), + 0, + NULL, + NULL, + }; + + type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME, I_("ThunarVfsVolumeHal"), &info, 0); + } + + return type; } static void -thunar_vfs_volume_hal_volume_init (ThunarVfsVolumeIface *iface) +thunar_vfs_volume_hal_class_init (ThunarVfsVolumeHalClass *klass) { - iface->get_kind = thunar_vfs_volume_hal_get_kind; - iface->get_name = thunar_vfs_volume_hal_get_name; - iface->get_status = thunar_vfs_volume_hal_get_status; - iface->get_mount_point = thunar_vfs_volume_hal_get_mount_point; - iface->eject = thunar_vfs_volume_hal_eject; - iface->mount = thunar_vfs_volume_hal_mount; - iface->unmount = thunar_vfs_volume_hal_unmount; -} + ThunarVfsVolumeClass *thunarvfs_volume_class; + GObjectClass *gobject_class; + /* determine the parent type class */ + thunar_vfs_volume_hal_parent_class = g_type_class_peek_parent (klass); + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_vfs_volume_hal_finalize; -static void -thunar_vfs_volume_hal_init (ThunarVfsVolumeHal *volume_hal) -{ + thunarvfs_volume_class = THUNAR_VFS_VOLUME_CLASS (klass); + thunarvfs_volume_class->get_kind = thunar_vfs_volume_hal_get_kind; + thunarvfs_volume_class->get_name = thunar_vfs_volume_hal_get_name; + thunarvfs_volume_class->get_status = thunar_vfs_volume_hal_get_status; + thunarvfs_volume_class->get_mount_point = thunar_vfs_volume_hal_get_mount_point; + thunarvfs_volume_class->eject = thunar_vfs_volume_hal_eject; + thunarvfs_volume_class->mount = thunar_vfs_volume_hal_mount; + thunarvfs_volume_class->unmount = thunar_vfs_volume_hal_unmount; } @@ -254,13 +270,11 @@ thunar_vfs_volume_hal_mount (ThunarVfsVolume *volume, { ThunarVfsVolumeHal *volume_hal = THUNAR_VFS_VOLUME_HAL (volume); ThunarVfsPath *path; - struct mntent *mntent; gboolean result; gchar *standard_error; gchar *command_line; gchar *mount_point; gchar *quoted; - FILE *fp; gint exit_status; /* generate the mount command */ @@ -352,53 +366,23 @@ thunar_vfs_volume_hal_mount (ThunarVfsVolume *volume, if (G_LIKELY (result)) { /* try to figure out where the device was mounted */ - fp = setmntent ("/proc/mounts", "r"); - if (G_LIKELY (fp != NULL)) + path = thunar_vfs_volume_hal_find_mount_point (volume_hal, "/proc/mounts"); + if (G_LIKELY (path != NULL)) { - /* assume that we failed */ - result = FALSE; + /* we must have been mounted successfully */ + volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - /* lookup the mount entry for our device */ - for (;;) - { - /* read the next entry */ - mntent = getmntent (fp); - if (mntent == NULL) - break; - - /* check if this is the entry we are looking for */ - if (exo_str_is_equal (mntent->mnt_fsname, volume_hal->device_file)) - { - /* transform the mount point to a path */ - path = thunar_vfs_path_new (mntent->mnt_dir, NULL); - if (G_LIKELY (path != NULL)) - { - /* we must have been mounted successfully */ - volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; - result = TRUE; - - /* replace the existing mount point */ - thunar_vfs_path_unref (volume_hal->mount_point); - volume_hal->mount_point = path; - - /* tell everybody that we have a new state */ - thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); - } - break; - } - } + /* replace the existing mount point */ + thunar_vfs_path_unref (volume_hal->mount_point); + volume_hal->mount_point = path; - /* check if we were unable to figure out the mount point */ - if (G_UNLIKELY (!result)) - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Failed to determine the mount point for %s"), volume_hal->device_file); - - /* close the file handle */ - fclose (fp); + /* tell everybody that we have a new state */ + thunar_vfs_volume_changed (THUNAR_VFS_VOLUME (volume_hal)); } else { - /* if we cannot read /proc/mounts, we cannot where the volume was mounted */ - g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), _("Failed to open /proc/mounts: %s"), g_strerror (errno)); + /* something went wrong, for sure */ + g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Failed to determine the mount point for %s"), volume_hal->device_file); result = FALSE; } } @@ -519,6 +503,43 @@ thunar_vfs_volume_hal_unmount (ThunarVfsVolume *volume, +static ThunarVfsPath* +thunar_vfs_volume_hal_find_mount_point (ThunarVfsVolumeHal *volume_hal, + const gchar *file) +{ + ThunarVfsPath *mount_point = NULL; + struct mntent *mntent; + FILE *fp; + + /* try to open that file as mnt entry list */ + fp = setmntent (file, "r"); + if (G_LIKELY (fp != NULL)) + { + /* process all mnt entries */ + while (mount_point == NULL) + { + /* read the next entry */ + mntent = getmntent (fp); + if (mntent == NULL) + break; + + /* check if this is the entry we are looking for */ + if (exo_str_is_equal (mntent->mnt_fsname, volume_hal->device_file)) + { + /* and there's our mount point */ + mount_point = thunar_vfs_path_new (mntent->mnt_dir, NULL); + } + } + + /* close the file handle */ + endmntent (fp); + } + + return mount_point; +} + + + static void thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, LibHalContext *context, @@ -526,13 +547,11 @@ thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, LibHalDrive *hd) { LibHalStoragePolicy *policy; - struct mntent *mntent; const gchar *desired_mount_point; const gchar *volume_label; gchar *mount_root; gchar *basename; gchar *filename; - FILE *fp; g_return_if_fail (THUNAR_VFS_IS_VOLUME_HAL (volume_hal)); g_return_if_fail (hv != NULL); @@ -656,6 +675,15 @@ thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, if (G_LIKELY (volume_hal->mount_point != NULL)) volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; } + else + { + /* we don't trust HAL, so let's see what /proc/mounts says about the volume */ + volume_hal->mount_point = thunar_vfs_volume_hal_find_mount_point (volume_hal, "/proc/mounts"); + + /* we must have been mounted successfully if we have a mount point */ + if (G_LIKELY (volume_hal->mount_point != NULL)) + volume_hal->status |= THUNAR_VFS_VOLUME_STATUS_MOUNTED | THUNAR_VFS_VOLUME_STATUS_PRESENT; + } /* check if we have to figure out the mount point ourself */ if (G_UNLIKELY (volume_hal->mount_point == NULL)) @@ -670,29 +698,7 @@ thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, } /* lets see, maybe /etc/fstab knows where to mount */ - fp = setmntent ("/etc/fstab", "r"); - if (G_LIKELY (fp != NULL)) - { - /* check all entries */ - for (;;) - { - /* read the next entry */ - mntent = getmntent (fp); - if (mntent == NULL) - break; - - /* check if the entry is for our device */ - if (exo_str_is_equal (mntent->mnt_fsname, volume_hal->device_file)) - { - /* transform to a path object */ - volume_hal->mount_point = thunar_vfs_path_new (mntent->mnt_dir, NULL); - break; - } - } - - /* close the /etc/fstab file handle */ - endmntent (fp); - } + volume_hal->mount_point = thunar_vfs_volume_hal_find_mount_point (volume_hal, "/etc/fstab"); /* if we still don't have a mount point, ask HAL */ if (G_UNLIKELY (volume_hal->mount_point == NULL)) @@ -736,12 +742,8 @@ thunar_vfs_volume_hal_update (ThunarVfsVolumeHal *volume_hal, static void thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass); -static void thunar_vfs_volume_manager_hal_manager_init (ThunarVfsVolumeManagerIface *iface); static void thunar_vfs_volume_manager_hal_init (ThunarVfsVolumeManagerHal *manager_hal); static void thunar_vfs_volume_manager_hal_finalize (GObject *object); -static ThunarVfsVolume *thunar_vfs_volume_manager_hal_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); -static GList *thunar_vfs_volume_manager_hal_get_volumes (ThunarVfsVolumeManager *manager); static ThunarVfsVolumeHal *thunar_vfs_volume_manager_hal_get_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, const gchar *udi); static void thunar_vfs_volume_manager_hal_update_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, @@ -766,43 +768,62 @@ static void thunar_vfs_volume_manager_hal_device_property_modifie struct _ThunarVfsVolumeManagerHalClass { - GObjectClass __parent__; + ThunarVfsVolumeManagerClass __parent__; }; struct _ThunarVfsVolumeManagerHal { - GObject __parent__; - DBusConnection *dbus_connection; - LibHalContext *context; - GList *volumes; + ThunarVfsVolumeManager __parent__; + DBusConnection *dbus_connection; + LibHalContext *context; + GList *volumes; }; -G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeManagerHal, - thunar_vfs_volume_manager_hal, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME_MANAGER, - thunar_vfs_volume_manager_hal_manager_init)); +static GObjectClass *thunar_vfs_volume_manager_hal_parent_class; -static void -thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass) +GType +thunar_vfs_volume_manager_hal_get_type (void) { - GObjectClass *gobject_class; + static GType type = G_TYPE_INVALID; - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_volume_manager_hal_finalize; + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeManagerHalClass), + NULL, + NULL, + (GClassInitFunc) thunar_vfs_volume_manager_hal_class_init, + NULL, + NULL, + sizeof (ThunarVfsVolumeManagerHal), + 0, + (GInstanceInitFunc) thunar_vfs_volume_manager_hal_init, + NULL, + }; + + type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME_MANAGER, I_("ThunarVfsVolumeManagerHal"), &info, 0); + } + + return type; } static void -thunar_vfs_volume_manager_hal_manager_init (ThunarVfsVolumeManagerIface *iface) +thunar_vfs_volume_manager_hal_class_init (ThunarVfsVolumeManagerHalClass *klass) { - iface->get_volume_by_info = thunar_vfs_volume_manager_hal_get_volume_by_info; - iface->get_volumes = thunar_vfs_volume_manager_hal_get_volumes; + GObjectClass *gobject_class; + + /* determine the parent type class */ + thunar_vfs_volume_manager_hal_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_vfs_volume_manager_hal_finalize; } @@ -940,31 +961,13 @@ thunar_vfs_volume_manager_hal_finalize (GObject *object) -static ThunarVfsVolume* -thunar_vfs_volume_manager_hal_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) -{ - // FIXME: No idea how to implement this on Linux right now. - return NULL; -} - - - -static GList* -thunar_vfs_volume_manager_hal_get_volumes (ThunarVfsVolumeManager *manager) -{ - return THUNAR_VFS_VOLUME_MANAGER_HAL (manager)->volumes; -} - - - static ThunarVfsVolumeHal* thunar_vfs_volume_manager_hal_get_volume_by_udi (ThunarVfsVolumeManagerHal *manager_hal, const gchar *udi) { GList *lp; - for (lp = manager_hal->volumes; lp != NULL; lp = lp->next) + for (lp = THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes; lp != NULL; lp = lp->next) if (exo_str_is_equal (THUNAR_VFS_VOLUME_HAL (lp->data)->udi, udi)) return THUNAR_VFS_VOLUME_HAL (lp->data); @@ -1034,7 +1037,6 @@ thunar_vfs_volume_manager_hal_device_added (LibHalContext *context, LibHalVolume *hv; LibHalDrive *hd; const gchar *drive_udi; - GList volume_list; g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); g_return_if_fail (manager_hal->context == context); @@ -1073,16 +1075,13 @@ thunar_vfs_volume_manager_hal_device_added (LibHalContext *context, thunar_vfs_volume_hal_update (volume_hal, context, hv, hd); /* add the volume object to our list if we allocated a new one */ - if (g_list_find (manager_hal->volumes, volume_hal) == NULL) + if (g_list_find (THUNAR_VFS_VOLUME_MANAGER (manager_hal)->volumes, volume_hal) == NULL) { - /* just prepend the volume object... */ - manager_hal->volumes = g_list_prepend (manager_hal->volumes, volume_hal); - - /* ...and emit "volumes-added" */ - volume_list.data = volume_hal; - volume_list.next = NULL; - volume_list.prev = NULL; - thunar_vfs_volume_manager_volumes_added (THUNAR_VFS_VOLUME_MANAGER (manager_hal), &volume_list); + /* add the volume to the volume manager */ + thunar_vfs_volume_manager_add (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); + + /* release the reference on the volume */ + g_object_unref (G_OBJECT (volume_hal)); } /* release the HAL drive */ @@ -1102,7 +1101,6 @@ thunar_vfs_volume_manager_hal_device_removed (LibHalContext *context, { ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context); ThunarVfsVolumeHal *volume_hal; - GList volume_list; g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal)); g_return_if_fail (manager_hal->context == context); @@ -1111,17 +1109,8 @@ thunar_vfs_volume_manager_hal_device_removed (LibHalContext *context, volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi (manager_hal, udi); if (G_LIKELY (volume_hal != NULL)) { - /* remove that volume from our list */ - manager_hal->volumes = g_list_remove (manager_hal->volumes, volume_hal); - - /* tell listeners that we dropped the volume */ - volume_list.data = volume_hal; - volume_list.next = NULL; - volume_list.prev = NULL; - thunar_vfs_volume_manager_volumes_removed (THUNAR_VFS_VOLUME_MANAGER (manager_hal), &volume_list); - - /* drop our reference on the volume */ - g_object_unref (G_OBJECT (volume_hal)); + /* remove the volume from the volume manager */ + thunar_vfs_volume_manager_remove (THUNAR_VFS_VOLUME_MANAGER (manager_hal), THUNAR_VFS_VOLUME (volume_hal)); } } @@ -1177,4 +1166,5 @@ thunar_vfs_volume_manager_hal_device_property_modified (LibHalContext *context, - +#define __THUNAR_VFS_VOLUME_HAL_C__ +#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-manager.c b/thunar-vfs/thunar-vfs-volume-manager.c new file mode 100644 index 0000000000000000000000000000000000000000..1119bdfb8c4844876d0772b68e0f873e1c63d05f --- /dev/null +++ b/thunar-vfs/thunar-vfs-volume-manager.c @@ -0,0 +1,488 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <thunar-vfs/thunar-vfs-enum-types.h> +#include <thunar-vfs/thunar-vfs-volume-freebsd.h> +#include <thunar-vfs/thunar-vfs-volume-hal.h> +#include <thunar-vfs/thunar-vfs-volume-none.h> +#include <thunar-vfs/thunar-vfs-volume-private.h> +#include <thunar-vfs/thunar-vfs-alias.h> + + + +/* determine the default thunar vfs volume manager type */ +#if defined(THUNAR_VFS_VOLUME_IMPL_FREEBSD) +#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD +#elif defined(THUNAR_VFS_VOLUME_IMPL_HAL) +#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL +#elif defined(THUNAR_VFS_VOLUME_IMPL_NONE) +#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE +#else +#error "Add your volume manager implemenation here!" +#endif + + + +/* Signal identifiers */ +enum +{ + VOLUMES_ADDED, + VOLUMES_REMOVED, + VOLUME_MOUNTED, + VOLUME_PRE_UNMOUNT, + VOLUME_UNMOUNTED, + LAST_SIGNAL, +}; + + + +static void thunar_vfs_volume_manager_class_init (ThunarVfsVolumeManagerClass *klass); +static void thunar_vfs_volume_manager_finalize (GObject *object); +static ThunarVfsVolume *thunar_vfs_volume_manager_real_get_volume_by_info (ThunarVfsVolumeManager *manager, + const ThunarVfsInfo *info); +static void thunar_vfs_volume_manager_volume_mounted (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); +static void thunar_vfs_volume_manager_volume_pre_unmount (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); +static void thunar_vfs_volume_manager_volume_unmounted (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); + + + +static GObjectClass *thunar_vfs_volume_manager_parent_class; +static guint manager_signals[LAST_SIGNAL]; + + + +GType +thunar_vfs_volume_manager_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeManagerClass), + NULL, + NULL, + (GClassInitFunc) thunar_vfs_volume_manager_class_init, + NULL, + NULL, + sizeof (ThunarVfsVolumeManager), + 0, + NULL, + }; + + type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarVfsVolumeManager"), &info, G_TYPE_FLAG_ABSTRACT); + } + + return type; +} + + + +static void +thunar_vfs_volume_manager_class_init (ThunarVfsVolumeManagerClass *klass) +{ + GObjectClass *gobject_class; + + /* determine the parent type class */ + thunar_vfs_volume_manager_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_vfs_volume_manager_finalize; + + /* we provide a fallback implementation */ + klass->get_volume_by_info = thunar_vfs_volume_manager_real_get_volume_by_info; + + /** + * ThunarVfsVolumeManager::volumes-added: + * @manager : a #ThunarVfsVolumeManager instance. + * @volumes : a list of #ThunarVfsVolume<!---->s. + * + * Invoked by the @manager whenever new volumes have been + * attached to the system or the administrator changes the + * /etc/fstab file, or some other condition, depending + * on the manager implementation. + * + * Note that the implementation should not invoke this + * method when a volume is mounted, as that's a completely + * different condition! + **/ + manager_signals[VOLUMES_ADDED] = + g_signal_new (I_("volumes-added"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volumes_added), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + /** + * ThunarVfsVolumeManager::volumes-removed: + * @manager : a #ThunarVfsVolumeManager instance. + * @volumes : a list of #ThunarVfsVolume<!---->s. + * + * Invoked whenever the @manager notices that @volumes have + * been detached from the system. + **/ + manager_signals[VOLUMES_REMOVED] = + g_signal_new (I_("volumes-removed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volumes_removed), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + /** + * ThunarVfsVolumeManager::volume-mounted: + * @manager : a #ThunarVfsVolumeManager instance. + * @volume : a #ThunarVfsVolume instance. + * + * Emitted by @manager right after the @volume was + * successfully mounted. + **/ + manager_signals[VOLUME_MOUNTED] = + g_signal_new (I_("volume-mounted"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_mounted), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); + + /** + * ThunarVfsVolumeManager::volume-pre-unmount: + * @manager : a #ThunarVfsVolumeManager instance. + * @volume : a #ThunarVfsVolume instance. + * + * Emitted by @manager right before an attempt is + * made to unmount @volume. Applications can connect + * to this signal to perform cleanups, like changing + * to a different folder if a folder on the @volume + * is currently displayed. + **/ + manager_signals[VOLUME_PRE_UNMOUNT] = + g_signal_new (I_("volume-pre-unmount"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_pre_unmount), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); + + /** + * ThunarVfsVolumeManager::volume-unmounted: + * @manager : a #ThunarVfsVolumeManager instance. + * @volume : a #ThunarVfsVolume instance. + * + * Emitted by @manager right after the @volume was + * successfully unmounted. + **/ + manager_signals[VOLUME_UNMOUNTED] = + g_signal_new (I_("volume-unmounted"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeManagerClass, volume_unmounted), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, THUNAR_VFS_TYPE_VOLUME); +} + + + +static void +thunar_vfs_volume_manager_finalize (GObject *object) +{ + ThunarVfsVolumeManager *manager = THUNAR_VFS_VOLUME_MANAGER (object); + ThunarVfsVolume *volume; + + /* drop all managed volumes */ + while (manager->volumes != NULL) + { + /* grab the first volume */ + volume = THUNAR_VFS_VOLUME (manager->volumes->data); + + /* verify that we're the only one keeping a reference on it */ + if (G_UNLIKELY (G_OBJECT (volume)->ref_count > 1)) + { + g_warning ("Attempt detected to finalize the ThunarVfsVolumeManager, while " + "there are still ThunarVfsVolume instances with a reference count " + "of 2 or more. This usually presents a bug in the application."); + } + + /* disconnect from the volume */ + thunar_vfs_volume_manager_remove (manager, volume); + } + + (*G_OBJECT_CLASS (thunar_vfs_volume_manager_parent_class)->finalize) (object); +} + + + +static ThunarVfsVolume* +thunar_vfs_volume_manager_real_get_volume_by_info (ThunarVfsVolumeManager *manager, + const ThunarVfsInfo *info) +{ + ThunarVfsVolume *best_volume = NULL; + ThunarVfsPath *best_path = NULL; + ThunarVfsPath *path; + GList *lp; + + /* otherwise try to find it the hard way */ + for (lp = manager->volumes; lp != NULL; lp = lp->next) + { + /* check if the volume is mounted */ + if (!thunar_vfs_volume_is_mounted (lp->data)) + continue; + + /* check if the mount point is an ancestor of the info path */ + path = thunar_vfs_volume_get_mount_point (lp->data); + if (path == NULL || (!thunar_vfs_path_equal (info->path, path) && !thunar_vfs_path_is_ancestor (info->path, path))) + continue; + + /* possible match, check if better than previous match */ + if (best_volume == NULL || thunar_vfs_path_equal (path, best_path) || thunar_vfs_path_is_ancestor (path, best_path)) + { + best_volume = lp->data; + best_path = path; + } + } + + return best_volume; +} + + + +static void +thunar_vfs_volume_manager_volume_mounted (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) +{ + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); + g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); + g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_MOUNTED], 0, volume); +} + + + +static void +thunar_vfs_volume_manager_volume_pre_unmount (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) +{ + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); + g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); + g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_PRE_UNMOUNT], 0, volume); +} + + + +static void +thunar_vfs_volume_manager_volume_unmounted (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) +{ + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); + g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); + g_signal_emit (G_OBJECT (manager), manager_signals[VOLUME_UNMOUNTED], 0, volume); +} + + + +/** + * thunar_vfs_volume_manager_get_default: + * + * Returns the default, shared #ThunarVfsVolumeManager instance + * for this system. This function automatically determines, which + * implementation of #ThunarVfsVolumeManager should be used for + * the target system and returns an instance of that class, which + * is shared among all modules using the volume manager facility. + * + * Call g_object_unref() on the returned object when you are + * done with it. + * + * Return value: the shared #ThunarVfsVolumeManager instance. + **/ +ThunarVfsVolumeManager* +thunar_vfs_volume_manager_get_default (void) +{ + static ThunarVfsVolumeManager *manager = NULL; + + if (G_UNLIKELY (manager == NULL)) + { + manager = g_object_new (THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL, NULL); + g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager); + } + else + { + g_object_ref (G_OBJECT (manager)); + } + + return manager; +} + + + +/** + * thunar_vfs_volume_manager_get_volume_by_info: + * @manager : a #ThunarVfsVolumeManager instance. + * @info : a #ThunarVfsInfo. + * + * Tries to lookup the #ThunarVfsVolume on which @info is + * located. If @manager doesn't know a #ThunarVfsVolume + * for @info, %NULL will be returned. + * + * The returned #ThunarVfsVolume (if any) is owned by + * @manager and must not be freed by the caller. + * + * Return value: the #ThunarVfsVolume, on which @info is + * located or %NULL. + **/ +ThunarVfsVolume* +thunar_vfs_volume_manager_get_volume_by_info (ThunarVfsVolumeManager *manager, + const ThunarVfsInfo *info) +{ + g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); + g_return_val_if_fail (info != NULL, NULL); + return (*THUNAR_VFS_VOLUME_MANAGER_GET_CLASS (manager)->get_volume_by_info) (manager, info); +} + + + +/** + * thunar_vfs_volume_manager_get_volumes: + * @manager : a #ThunarVfsVolumeManager instance. + * + * Returns all #ThunarVfsVolume<!---->s currently known for + * @manager. The returned list is owned by @manager and should + * therefore considered constant in the caller. + * + * Return value: the list of volumes known for @manager. + **/ +GList* +thunar_vfs_volume_manager_get_volumes (ThunarVfsVolumeManager *manager) +{ + g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); + return manager->volumes; +} + + + +/** + * thunar_vfs_volume_manager_add: + * @manager : a #ThunarVfsVolumeManager instance. + * @volume : a #ThunarVfsVolume. + * + * Adds @volume to the list of #ThunarVfsVolume<!---->s managed + * by the @manager, and emits the "volumes-added" signal on + * @manager using the given @volume. + * + * It is an error to call this method with a @volume that is + * already managed by @manager. + * + * This method should only be used by #ThunarVfsVolumeManager + * implementations. + **/ +void +thunar_vfs_volume_manager_add (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) +{ + GList list; + + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); + g_return_if_fail (g_list_find (manager->volumes, volume) == NULL); + + /* add the volume to the list of managed volumes */ + manager->volumes = g_list_prepend (manager->volumes, volume); + g_object_ref (G_OBJECT (volume)); + + /* connect the required signals */ + g_signal_connect_swapped (G_OBJECT (volume), "mounted", G_CALLBACK (thunar_vfs_volume_manager_volume_mounted), manager); + g_signal_connect_swapped (G_OBJECT (volume), "pre-unmount", G_CALLBACK (thunar_vfs_volume_manager_volume_pre_unmount), manager); + g_signal_connect_swapped (G_OBJECT (volume), "unmounted", G_CALLBACK (thunar_vfs_volume_manager_volume_unmounted), manager); + + /* fake a volume list */ + list.data = volume; + list.next = NULL; + list.prev = NULL; + + /* emit "volumes-added" with the faked list */ + g_signal_emit (G_OBJECT (manager), manager_signals[VOLUMES_ADDED], 0, &list); +} + + + +/** + * thunar_vfs_volume_manager_remove: + * @manager : a #ThunarVfsVolumeManager instance. + * @volume : a #ThunarVfsVolume. + * + * Removes @volume from the list of #ThunarVfsVolume<!---->s managed + * by the @manager, and emits the "volumes-removed" signal on + * @manager using the given @volume. + * + * It is an error to call this method with @volume that is not + * currently managed by @manager. + * + * This method should only be used by #ThunarVfsVolumeManager + * implementations. + **/ +void +thunar_vfs_volume_manager_remove (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) +{ + GList list; + + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); + g_return_if_fail (g_list_find (manager->volumes, volume) != NULL); + + /* remove the volume from our list */ + manager->volumes = g_list_remove (manager->volumes, volume); + + /* disconnect our signal handlers */ + g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_mounted, manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_pre_unmount, manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (volume), thunar_vfs_volume_manager_volume_unmounted, manager); + + /* fake a volume list */ + list.data = volume; + list.next = NULL; + list.prev = NULL; + + /* emit "volumes-removed" with the faked list */ + g_signal_emit (G_OBJECT (manager), manager_signals[VOLUMES_REMOVED], 0, &list); + + /* drop our reference on the volume */ + g_object_unref (G_OBJECT (volume)); +} + + + +#define __THUNAR_VFS_VOLUME_MANAGER_C__ +#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-none.c b/thunar-vfs/thunar-vfs-volume-none.c index be9d0cc785789b20beba5857747c547f3dd2f83d..fdc314d2477bf1a9a07399843df3c08df662cdef 100644 --- a/thunar-vfs/thunar-vfs-volume-none.c +++ b/thunar-vfs/thunar-vfs-volume-none.c @@ -23,76 +23,51 @@ #endif #include <thunar-vfs/thunar-vfs-volume-none.h> +#include <thunar-vfs/thunar-vfs-volume-private.h> #include <thunar-vfs/thunar-vfs-alias.h> -static void thunar_vfs_volume_manager_none_class_init (ThunarVfsVolumeManagerNoneClass *klass); -static void thunar_vfs_volume_manager_none_manager_init (ThunarVfsVolumeManagerIface *iface); -static void thunar_vfs_volume_manager_none_init (ThunarVfsVolumeManagerNone *manager_none); -static ThunarVfsVolume *thunar_vfs_volume_manager_none_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); -static GList *thunar_vfs_volume_manager_none_get_volumes (ThunarVfsVolumeManager *manager); - - - struct _ThunarVfsVolumeManagerNoneClass { - GObjectClass __parent__; + ThunarVfsVolumeManagerClass __parent__; }; struct _ThunarVfsVolumeManagerNone { - GObject __parent__; + ThunarVfsVolumeClass __parent__; }; -G_DEFINE_TYPE_WITH_CODE (ThunarVfsVolumeManagerNone, - thunar_vfs_volume_manager_none, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (THUNAR_VFS_TYPE_VOLUME_MANAGER, - thunar_vfs_volume_manager_none_manager_init)); - - -static void -thunar_vfs_volume_manager_none_class_init (ThunarVfsVolumeManagerNoneClass *klass) -{ -} - - - -static void -thunar_vfs_volume_manager_none_manager_init (ThunarVfsVolumeManagerIface *iface) -{ - iface->get_volume_by_info = thunar_vfs_volume_manager_none_get_volume_by_info; - iface->get_volumes = thunar_vfs_volume_manager_none_get_volumes; -} - - - -static void -thunar_vfs_volume_manager_none_init (ThunarVfsVolumeManagerNone *manager_none) -{ -} - - - -static ThunarVfsVolume* -thunar_vfs_volume_manager_none_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) +GType +thunar_vfs_volume_manager_none_get_type (void) { - return NULL; + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarVfsVolumeManagerNoneClass), + NULL, + NULL, + NULL, + NULL, + NULL, + sizeof (ThunarVfsVolumeManagerNone), + 0, + NULL, + NULL, + }; + + type = g_type_register_static (THUNAR_VFS_TYPE_VOLUME_MANAGER, I_("ThunarVfsVolumeManagerNone"), &info, 0); + } + + return type; } -static GList* -thunar_vfs_volume_manager_none_get_volumes (ThunarVfsVolumeManager *manager) -{ - return NULL; -} - - - - +#define __THUNAR_VFS_VOLUME_NONE_C__ +#include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume-private.h b/thunar-vfs/thunar-vfs-volume-private.h new file mode 100644 index 0000000000000000000000000000000000000000..bf7933c6ad733ac4413fbd96d0b40d75f62ff687 --- /dev/null +++ b/thunar-vfs/thunar-vfs-volume-private.h @@ -0,0 +1,111 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + +#ifndef __THUNAR_VFS_VOLUME_PRIVATE_H__ +#define __THUNAR_VFS_VOLUME_PRIVATE_H__ + +#include <thunar-vfs/thunar-vfs-volume.h> + +G_BEGIN_DECLS; + +struct _ThunarVfsVolumeClass +{ + /*< private >*/ + GObjectClass __parent__; + + /*< public >*/ + + /* methods */ + ThunarVfsVolumeKind (*get_kind) (ThunarVfsVolume *volume); + const gchar *(*get_name) (ThunarVfsVolume *volume); + ThunarVfsVolumeStatus (*get_status) (ThunarVfsVolume *volume); + ThunarVfsPath *(*get_mount_point) (ThunarVfsVolume *volume); + const gchar *(*lookup_icon_name) (ThunarVfsVolume *volume, + GtkIconTheme *icon_theme); + + gboolean (*eject) (ThunarVfsVolume *volume, + GtkWidget *window, + GError **error); + gboolean (*mount) (ThunarVfsVolume *volume, + GtkWidget *window, + GError **error); + gboolean (*unmount) (ThunarVfsVolume *volume, + GtkWidget *window, + GError **error); + + /* signals */ + void (*changed) (ThunarVfsVolume *volume); + void (*mounted) (ThunarVfsVolume *volume); + void (*pre_unmount) (ThunarVfsVolume *volume); + void (*unmounted) (ThunarVfsVolume *volume); +}; + +struct _ThunarVfsVolume +{ + /*< private >*/ + GObject __parent__; +}; + +void thunar_vfs_volume_changed (ThunarVfsVolume *volume) G_GNUC_INTERNAL; + + +struct _ThunarVfsVolumeManagerClass +{ + /*< private >*/ + GObjectClass __parent__; + + /*< public >*/ + + /* methods */ + ThunarVfsVolume *(*get_volume_by_info) (ThunarVfsVolumeManager *manager, + const ThunarVfsInfo *info); + + /* signals */ + void (*volumes_added) (ThunarVfsVolumeManager *manager, + GList *volumes); + void (*volumes_removed) (ThunarVfsVolumeManager *manager, + GList *volumes); + void (*volume_mounted) (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); + void (*volume_pre_unmount) (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); + void (*volume_unmounted) (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume); +}; + +struct _ThunarVfsVolumeManager +{ + /*< private >*/ + GObject __parent__; + + /*< public >*/ + + /* the list of available volumes */ + GList *volumes; +}; + +void thunar_vfs_volume_manager_add (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) G_GNUC_INTERNAL; +void thunar_vfs_volume_manager_remove (ThunarVfsVolumeManager *manager, + ThunarVfsVolume *volume) G_GNUC_INTERNAL; + +G_END_DECLS; + +#endif /* !__THUNAR_VFS_VOLUME_PRIVATE_H__ */ diff --git a/thunar-vfs/thunar-vfs-volume.c b/thunar-vfs/thunar-vfs-volume.c index 9a4bfb5ca0eff67db32fcf0e26a93c116fe4eb29..51a54e02d52dac677fc009d7ae3bde43f46cfa59 100644 --- a/thunar-vfs/thunar-vfs-volume.c +++ b/thunar-vfs/thunar-vfs-volume.c @@ -22,44 +22,29 @@ #include <config.h> #endif -#include <exo/exo.h> - #include <thunar-vfs/thunar-vfs-enum-types.h> -#include <thunar-vfs/thunar-vfs-volume-freebsd.h> -#include <thunar-vfs/thunar-vfs-volume-hal.h> -#include <thunar-vfs/thunar-vfs-volume-none.h> -#include <thunar-vfs/thunar-vfs-volume.h> +#include <thunar-vfs/thunar-vfs-volume-private.h> #include <thunar-vfs/thunar-vfs-alias.h> -/* determine the default thunar vfs volume manager type */ -#if defined(THUNAR_VFS_VOLUME_IMPL_FREEBSD) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_FREEBSD -#elif defined(THUNAR_VFS_VOLUME_IMPL_HAL) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_HAL -#elif defined(THUNAR_VFS_VOLUME_IMPL_NONE) -#define THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL THUNAR_VFS_TYPE_VOLUME_MANAGER_NONE -#else -#error "Add your volume manager implemenation here!" -#endif - - - /* Signal identifiers */ enum { - THUNAR_VFS_VOLUME_CHANGED, - THUNAR_VFS_VOLUME_LAST_SIGNAL, + CHANGED, + MOUNTED, + PRE_UNMOUNT, + UNMOUNTED, + LAST_SIGNAL, }; -static void thunar_vfs_volume_base_init (gpointer klass); +static void thunar_vfs_volume_class_init (ThunarVfsVolumeClass *klass); -static guint volume_signals[THUNAR_VFS_VOLUME_LAST_SIGNAL]; +static guint volume_signals[LAST_SIGNAL]; @@ -72,20 +57,19 @@ thunar_vfs_volume_get_type (void) { static const GTypeInfo info = { - sizeof (ThunarVfsVolumeIface), - (GBaseInitFunc) thunar_vfs_volume_base_init, + sizeof (ThunarVfsVolumeClass), NULL, NULL, + (GClassInitFunc) thunar_vfs_volume_class_init, NULL, NULL, - 0, + sizeof (ThunarVfsVolume), 0, NULL, NULL, }; - type = g_type_register_static (G_TYPE_INTERFACE, I_("ThunarVfsVolume"), &info, 0); - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarVfsVolume"), &info, G_TYPE_FLAG_ABSTRACT); } return type; @@ -94,29 +78,70 @@ thunar_vfs_volume_get_type (void) static void -thunar_vfs_volume_base_init (gpointer klass) +thunar_vfs_volume_class_init (ThunarVfsVolumeClass *klass) { - static gboolean initialized = FALSE; - - if (G_UNLIKELY (!initialized)) - { - /** - * ThunarVfsVolume::changed: - * @volume : the #ThunarVfsVolume instance. - * - * Emitted whenever the state of @volume changed. - **/ - volume_signals[THUNAR_VFS_VOLUME_CHANGED] = - g_signal_new (I_("changed"), - G_TYPE_FROM_INTERFACE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeIface, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - initialized = TRUE; - } + /** + * ThunarVfsVolume::changed: + * @volume : the #ThunarVfsVolume instance. + * + * Emitted whenever the state of @volume changed. + **/ + volume_signals[CHANGED] = + g_signal_new (I_("changed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * ThunarVfsVolume::mounted: + * @volume : the #ThunarVfsVolume instance. + * + * Emitted by @volume after a successfull mount + * operation. + **/ + volume_signals[MOUNTED] = + g_signal_new (I_("mounted"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeClass, mounted), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * ThunarVfsVolume::pre-unmount: + * @volume : the #ThunarVfsVolume instance. + * + * Emitted by @volume right before an attempt + * is made to unmount the @volume. + **/ + volume_signals[PRE_UNMOUNT] = + g_signal_new (I_("pre-unmount"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeClass, pre_unmount), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * ThunarVfsVolume::unmounted: + * @volume : the #ThunarVfsVolume instance. + * + * Emitted by @volume right after the @volume + * was successfully unmounted. + **/ + volume_signals[UNMOUNTED] = + g_signal_new (I_("unmounted"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ThunarVfsVolumeClass, unmounted), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } @@ -133,7 +158,7 @@ ThunarVfsVolumeKind thunar_vfs_volume_get_kind (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), THUNAR_VFS_VOLUME_KIND_UNKNOWN); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_kind) (volume); + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_kind) (volume); } @@ -152,7 +177,7 @@ const gchar* thunar_vfs_volume_get_name (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), NULL); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_name) (volume); + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_name) (volume); } @@ -171,7 +196,7 @@ ThunarVfsVolumeStatus thunar_vfs_volume_get_status (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), 0); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_status) (volume); + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume); } @@ -195,7 +220,7 @@ ThunarVfsPath* thunar_vfs_volume_get_mount_point (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), NULL); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_mount_point) (volume); + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_mount_point) (volume); } @@ -237,7 +262,7 @@ gboolean thunar_vfs_volume_is_mounted (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_MOUNTED; + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_MOUNTED; } @@ -256,7 +281,7 @@ gboolean thunar_vfs_volume_is_present (ThunarVfsVolume *volume) { g_return_val_if_fail (THUNAR_VFS_IS_VOLUME (volume), FALSE); - return (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_PRESENT; + return (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->get_status) (volume) & THUNAR_VFS_VOLUME_STATUS_PRESENT; } @@ -340,7 +365,7 @@ const gchar* thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume, GtkIconTheme *icon_theme) { - ThunarVfsVolumeIface *iface; + ThunarVfsVolumeClass *klass; ThunarVfsVolumeKind kind; const gchar *icon_name; @@ -348,10 +373,10 @@ thunar_vfs_volume_lookup_icon_name (ThunarVfsVolume *volume, g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), NULL); /* allow the implementing class to provide a custom icon */ - iface = THUNAR_VFS_VOLUME_GET_IFACE (volume); - if (iface->lookup_icon_name != NULL) + klass = THUNAR_VFS_VOLUME_GET_CLASS (volume); + if (klass->lookup_icon_name != NULL) { - icon_name = (*iface->lookup_icon_name) (volume, icon_theme); + icon_name = (*klass->lookup_icon_name) (volume, icon_theme); if (G_LIKELY (icon_name != NULL)) return icon_name; } @@ -469,6 +494,9 @@ thunar_vfs_volume_eject (ThunarVfsVolume *volume, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE); + /* we're about to unmount (and eject) the volume */ + g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0); + /* setup a watch cursor on the window */ if (window != NULL && GTK_WIDGET_REALIZED (window)) { @@ -482,12 +510,16 @@ thunar_vfs_volume_eject (ThunarVfsVolume *volume, } /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->eject) (volume, window, error); + result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->eject) (volume, window, error); /* reset the cursor */ if (window != NULL && GTK_WIDGET_REALIZED (window)) gdk_window_set_cursor (window->window, NULL); + /* check if we unmounted successfully */ + if (G_LIKELY (result)) + g_signal_emit (G_OBJECT (volume), volume_signals[UNMOUNTED], 0); + return result; } @@ -540,12 +572,16 @@ thunar_vfs_volume_mount (ThunarVfsVolume *volume, } /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->mount) (volume, window, error); + result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->mount) (volume, window, error); /* reset the cursor */ if (window != NULL && GTK_WIDGET_REALIZED (window)) gdk_window_set_cursor (window->window, NULL); + /* check if we successfully mounted the volume */ + if (G_LIKELY (result)) + g_signal_emit (G_OBJECT (volume), volume_signals[MOUNTED], 0); + return result; } @@ -585,6 +621,9 @@ thunar_vfs_volume_unmount (ThunarVfsVolume *volume, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE); + /* we're about to unmount the volume */ + g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0); + /* setup a watch cursor on the window */ if (window != NULL && GTK_WIDGET_REALIZED (window)) { @@ -598,12 +637,16 @@ thunar_vfs_volume_unmount (ThunarVfsVolume *volume, } /* try to mount the volume */ - result = (*THUNAR_VFS_VOLUME_GET_IFACE (volume)->unmount) (volume, window, error); + result = (*THUNAR_VFS_VOLUME_GET_CLASS (volume)->unmount) (volume, window, error); /* reset the cursor */ if (window != NULL && GTK_WIDGET_REALIZED (window)) gdk_window_set_cursor (window->window, NULL); + /* check if we unmounted successfully */ + if (G_LIKELY (result)) + g_signal_emit (G_OBJECT (volume), volume_signals[UNMOUNTED], 0); + return result; } @@ -621,237 +664,11 @@ void thunar_vfs_volume_changed (ThunarVfsVolume *volume) { g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); - g_signal_emit (G_OBJECT (volume), volume_signals[THUNAR_VFS_VOLUME_CHANGED], 0); -} - - - - -enum -{ - THUNAR_VFS_VOLUME_MANAGER_VOLUMES_ADDED, - THUNAR_VFS_VOLUME_MANAGER_VOLUMES_REMOVED, - THUNAR_VFS_VOLUME_MANAGER_LAST_SIGNAL, -}; - - - -static void thunar_vfs_volume_manager_base_init (gpointer klass); - - - -static guint manager_signals[THUNAR_VFS_VOLUME_MANAGER_LAST_SIGNAL]; - - - -GType -thunar_vfs_volume_manager_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarVfsVolumeManagerIface), - (GBaseInitFunc) thunar_vfs_volume_manager_base_init, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - }; - - type = g_type_register_static (G_TYPE_INTERFACE, - "ThunarVfsVolumeManager", - &info, 0); - - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); - } - - return type; -} - - - -static void -thunar_vfs_volume_manager_base_init (gpointer klass) -{ - static gboolean initialized = FALSE; - - if (G_UNLIKELY (!initialized)) - { - /** - * ThunarVfsVolumeManager::volumes-added: - * @manager : a #ThunarVfsVolumeManager instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Invoked by the @manager whenever new volumes have been - * attached to the system or the administrator changes the - * /etc/fstab file, or some other condition, depending - * on the manager implementation. - * - * Note that the implementation should not invoke this - * method when a volume is mounted, as that's a completely - * different condition! - **/ - manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_ADDED] = - g_signal_new (I_("volumes-added"), - G_TYPE_FROM_INTERFACE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerIface, volumes_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - /** - * ThunarVfsVolumeManager::volumes-removed: - * @manager : a #ThunarVfsVolume instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Invoked whenever the @manager notices that @volumes have - * been detached from the system. - **/ - manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_REMOVED] = - g_signal_new (I_("volumes-removed"), - G_TYPE_FROM_INTERFACE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ThunarVfsVolumeManagerIface, volumes_removed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - initialized = TRUE; - } -} - - - -/** - * thunar_vfs_volume_manager_get_default: - * - * Returns the default, shared #ThunarVfsVolumeManager instance - * for this system. This function automatically determines, which - * implementation of #ThunarVfsVolumeManager should be used for - * the target system and returns an instance of that class, which - * is shared among all modules using the volume manager facility. - * - * Call g_object_unref() on the returned object when you are - * done with it. - * - * Return value: the shared #ThunarVfsVolumeManager instance. - **/ -ThunarVfsVolumeManager* -thunar_vfs_volume_manager_get_default (void) -{ - extern GType _thunar_vfs_volume_manager_impl_get_type (void); - static ThunarVfsVolumeManager *manager = NULL; - - if (G_UNLIKELY (manager == NULL)) - { - manager = g_object_new (THUNAR_VFS_TYPE_VOLUME_MANAGER_IMPL, NULL); - g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager); - } - else - { - g_object_ref (G_OBJECT (manager)); - } - - return manager; -} - - - -/** - * thunar_vfs_volume_manager_get_volume_by_info: - * @manager : a #ThunarVfsVolumeManager instance. - * @info : a #ThunarVfsInfo. - * - * Tries to lookup the #ThunarVfsVolume on which @info is - * located. If @manager doesn't know a #ThunarVfsVolume - * for @info, %NULL will be returned. - * - * The returned #ThunarVfsVolume (if any) is owned by - * @manager and must not be freed by the caller. - * - * Return value: the #ThunarVfsVolume, on which @info is - * located or %NULL. - **/ -ThunarVfsVolume* -thunar_vfs_volume_manager_get_volume_by_info (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); - g_return_val_if_fail (info != NULL, NULL); - return (*THUNAR_VFS_VOLUME_MANAGER_GET_IFACE (manager)->get_volume_by_info) (manager, info); + g_signal_emit (G_OBJECT (volume), volume_signals[CHANGED], 0); } -/** - * thunar_vfs_volume_manager_get_volumes: - * @manager : a #ThunarVfsVolumeManager instance. - * - * Returns all #ThunarVfsVolume<!---->s currently known for - * @manager. The returned list is owned by @manager and should - * therefore considered constant in the caller. - * - * Return value: the list of volumes known for @manager. - **/ -GList* -thunar_vfs_volume_manager_get_volumes (ThunarVfsVolumeManager *manager) -{ - g_return_val_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager), NULL); - return (*THUNAR_VFS_VOLUME_MANAGER_GET_IFACE (manager)->get_volumes) (manager); -} - - - -/** - * thunar_vfs_volume_manager_volumes_added: - * @manager : a #ThunarVfsVolumeManager instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Emits the "volumes-added" signal on @manager using the - * given @volumes. - * - * This method should only be used by classes implementing - * the #ThunarVfsVolumeManager interface. - **/ -void -thunar_vfs_volume_manager_volumes_added (ThunarVfsVolumeManager *manager, - GList *volumes) -{ - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_length (volumes) > 0); - g_signal_emit (G_OBJECT (manager), manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_ADDED], 0, volumes); -} - - - -/** - * thunar_vfs_volume_manager_volumes_removed: - * @manager : a #ThunarVfsVolumeManager instance. - * @volumes : a list of #ThunarVfsVolume<!---->s. - * - * Emits the "volumes-removed" signal on @manager using - * the given @volumes. - * - * This method should only be used by classes implementing - * the #ThunarVfsVolumeManager interface. - **/ -void -thunar_vfs_volume_manager_volumes_removed (ThunarVfsVolumeManager *manager, - GList *volumes) -{ - g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (manager)); - g_return_if_fail (g_list_length (volumes) > 0); - g_signal_emit (G_OBJECT (manager), manager_signals[THUNAR_VFS_VOLUME_MANAGER_VOLUMES_REMOVED], 0, volumes); -} - - #define __THUNAR_VFS_VOLUME_C__ #include <thunar-vfs/thunar-vfs-aliasdef.c> diff --git a/thunar-vfs/thunar-vfs-volume.h b/thunar-vfs/thunar-vfs-volume.h index 8d7b02563a53e03f1222acdf881b0f714dc789a3..5f6879165403fef010a87a7daff633ae2cffc565 100644 --- a/thunar-vfs/thunar-vfs-volume.h +++ b/thunar-vfs/thunar-vfs-volume.h @@ -27,13 +27,15 @@ G_BEGIN_DECLS; -typedef struct _ThunarVfsVolumeIface ThunarVfsVolumeIface; +typedef struct _ThunarVfsVolumeClass ThunarVfsVolumeClass; typedef struct _ThunarVfsVolume ThunarVfsVolume; #define THUNAR_VFS_TYPE_VOLUME (thunar_vfs_volume_get_type ()) #define THUNAR_VFS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolume)) +#define THUNAR_VFS_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolumeClass)) #define THUNAR_VFS_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME)) -#define THUNAR_VFS_VOLUME_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolumeIface)) +#define THUNAR_VFS_IS_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME)) +#define THUNAR_VFS_VOLUME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME, ThunarVfsVolumeClass)) /** * ThunarVfsVolumeKind: @@ -85,51 +87,6 @@ typedef enum /*< flags >*/ THUNAR_VFS_VOLUME_STATUS_PRESENT = 1 << 1, } ThunarVfsVolumeStatus; -struct _ThunarVfsVolumeIface -{ - /*< private >*/ - GTypeInterface __parent__; - - /*< public >*/ - - /* methods */ - ThunarVfsVolumeKind (*get_kind) (ThunarVfsVolume *volume); - const gchar *(*get_name) (ThunarVfsVolume *volume); - ThunarVfsVolumeStatus (*get_status) (ThunarVfsVolume *volume); - ThunarVfsPath *(*get_mount_point) (ThunarVfsVolume *volume); - const gchar *(*lookup_icon_name) (ThunarVfsVolume *volume, - GtkIconTheme *icon_theme); - - gboolean (*eject) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - gboolean (*mount) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - gboolean (*unmount) (ThunarVfsVolume *volume, - GtkWidget *window, - GError **error); - - /*< private >*/ - void (*reserved0) (void); - void (*reserved1) (void); - void (*reserved2) (void); - void (*reserved3) (void); - void (*reserved4) (void); - void (*reserved5) (void); - - /*< public >*/ - - /* signals */ - void (*changed) (ThunarVfsVolume *volume); - - /*< private >*/ - void (*reserved6) (void); - void (*reserved7) (void); - void (*reserved8) (void); - void (*reserved9) (void); -}; - GType thunar_vfs_volume_get_type (void) G_GNUC_CONST; ThunarVfsVolumeKind thunar_vfs_volume_get_kind (ThunarVfsVolume *volume); @@ -156,51 +113,16 @@ gboolean thunar_vfs_volume_unmount (ThunarVfsVolume *vo GtkWidget *window, GError **error); -void thunar_vfs_volume_changed (ThunarVfsVolume *volume) G_GNUC_INTERNAL; - -typedef struct _ThunarVfsVolumeManagerIface ThunarVfsVolumeManagerIface; +typedef struct _ThunarVfsVolumeManagerClass ThunarVfsVolumeManagerClass; typedef struct _ThunarVfsVolumeManager ThunarVfsVolumeManager; #define THUNAR_VFS_TYPE_VOLUME_MANAGER (thunar_vfs_volume_manager_get_type ()) #define THUNAR_VFS_VOLUME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManager)) +#define THUNAR_VFS_VOLUME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManagerClass)) #define THUNAR_VFS_IS_VOLUME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER)) -#define THUNAR_VFS_VOLUME_MANAGER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManagerIface)) - -struct _ThunarVfsVolumeManagerIface -{ - /*< private >*/ - GTypeInterface __parent__; - - /*< public >*/ - - /* methods */ - ThunarVfsVolume *(*get_volume_by_info) (ThunarVfsVolumeManager *manager, - const ThunarVfsInfo *info); - GList *(*get_volumes) (ThunarVfsVolumeManager *manager); - - /*< private >*/ - void (*reserved0) (void); - void (*reserved1) (void); - void (*reserved2) (void); - void (*reserved3) (void); - void (*reserved4) (void); - void (*reserved5) (void); - - /*< public >*/ - - /* signals */ - void (*volumes_added) (ThunarVfsVolumeManager *manager, - GList *volumes); - void (*volumes_removed) (ThunarVfsVolumeManager *manager, - GList *volumes); - - /*< private >*/ - void (*reserved6) (void); - void (*reserved7) (void); - void (*reserved8) (void); - void (*reserved9) (void); -}; +#define THUNAR_VFS_IS_VOLUME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_VOLUME_MANAGER)) +#define THUNAR_VFS_VOLUME_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_VOLUME_MANAGER, ThunarVfsVolumeManagerClass)) GType thunar_vfs_volume_manager_get_type (void) G_GNUC_CONST; @@ -210,11 +132,6 @@ ThunarVfsVolume *thunar_vfs_volume_manager_get_volume_by_info (ThunarVfs const ThunarVfsInfo *info); GList *thunar_vfs_volume_manager_get_volumes (ThunarVfsVolumeManager *manager); -void thunar_vfs_volume_manager_volumes_added (ThunarVfsVolumeManager *manager, - GList *volumes) G_GNUC_INTERNAL; -void thunar_vfs_volume_manager_volumes_removed (ThunarVfsVolumeManager *manager, - GList *volumes) G_GNUC_INTERNAL; - G_END_DECLS; #endif /* !__THUNAR_VFS_VOLUME_H__ */ diff --git a/thunar-vfs/thunar-vfs.symbols b/thunar-vfs/thunar-vfs.symbols index fd6af31befa42c4c8f9b198e8ed840aa0bb653d6..bda4a1d3be9963be8bbbbd2bd576e85a7115bf5b 100644 --- a/thunar-vfs/thunar-vfs.symbols +++ b/thunar-vfs/thunar-vfs.symbols @@ -318,6 +318,8 @@ thunar_vfs_volume_lookup_icon_name thunar_vfs_volume_eject thunar_vfs_volume_mount thunar_vfs_volume_unmount +#endif +#if IN_SOURCE(__THUNAR_VFS_VOLUME_MANAGER_C__) thunar_vfs_volume_manager_get_type G_GNUC_CONST thunar_vfs_volume_manager_get_default thunar_vfs_volume_manager_get_volume_by_info @@ -325,3 +327,4 @@ thunar_vfs_volume_manager_get_volumes #endif #endif + diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 41eefa279450b9aa906ae14c31d70ff91dcac377..a70218c39362eeabb2ddffc61cfad284891d531b 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -70,93 +70,96 @@ enum -static void thunar_window_class_init (ThunarWindowClass *klass); -static void thunar_window_init (ThunarWindow *window); -static void thunar_window_dispose (GObject *object); -static void thunar_window_finalize (GObject *object); -static void thunar_window_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_window_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static gboolean thunar_window_reload (ThunarWindow *window); -static gboolean thunar_window_zoom_in (ThunarWindow *window); -static gboolean thunar_window_zoom_out (ThunarWindow *window); -static void thunar_window_realize (GtkWidget *widget); -static void thunar_window_unrealize (GtkWidget *widget); -static gboolean thunar_window_configure_event (GtkWidget *widget, - GdkEventConfigure *event); -static void thunar_window_merge_custom_preferences (ThunarWindow *window); -static void thunar_window_install_sidepane (ThunarWindow *window, - GType type); -static void thunar_window_start_open_location (ThunarWindow *window, - const gchar *initial_text); -static void thunar_window_action_open_new_window (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_close_all_windows (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_close (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_preferences (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_reload (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_location_bar_changed (GtkRadioAction *action, - GtkRadioAction *current, - ThunarWindow *window); -static void thunar_window_action_shortcuts_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_tree_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_statusbar_changed (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_in (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_out (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_zoom_reset (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_view_changed (GtkRadioAction *action, - GtkRadioAction *current, - ThunarWindow *window); -static void thunar_window_action_go_up (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_home (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_templates (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_open_location (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_contents (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_about (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_show_hidden (GtkToggleAction *action, - ThunarWindow *window); -static void thunar_window_current_directory_changed (ThunarFile *current_directory, - ThunarWindow *window); -static void thunar_window_connect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window); -static void thunar_window_disconnect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy, - ThunarWindow *window); -static void thunar_window_menu_item_selected (GtkWidget *menu_item, - ThunarWindow *window); -static void thunar_window_menu_item_deselected (GtkWidget *menu_item, - ThunarWindow *window); -static void thunar_window_notify_loading (ThunarView *view, - GParamSpec *pspec, - ThunarWindow *window); -static gboolean thunar_window_merge_idle (gpointer user_data); -static void thunar_window_merge_idle_destroy (gpointer user_data); -static gboolean thunar_window_save_geometry_timer (gpointer user_data); -static void thunar_window_save_geometry_timer_destroy (gpointer user_data); +static void thunar_window_class_init (ThunarWindowClass *klass); +static void thunar_window_init (ThunarWindow *window); +static void thunar_window_dispose (GObject *object); +static void thunar_window_finalize (GObject *object); +static void thunar_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static gboolean thunar_window_reload (ThunarWindow *window); +static gboolean thunar_window_zoom_in (ThunarWindow *window); +static gboolean thunar_window_zoom_out (ThunarWindow *window); +static void thunar_window_realize (GtkWidget *widget); +static void thunar_window_unrealize (GtkWidget *widget); +static gboolean thunar_window_configure_event (GtkWidget *widget, + GdkEventConfigure *event); +static void thunar_window_merge_custom_preferences (ThunarWindow *window); +static void thunar_window_install_sidepane (ThunarWindow *window, + GType type); +static void thunar_window_start_open_location (ThunarWindow *window, + const gchar *initial_text); +static void thunar_window_action_open_new_window (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_close_all_windows (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_close (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_preferences (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_reload (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_location_bar_changed (GtkRadioAction *action, + GtkRadioAction *current, + ThunarWindow *window); +static void thunar_window_action_shortcuts_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_tree_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_statusbar_changed (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_in (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_out (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_zoom_reset (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_view_changed (GtkRadioAction *action, + GtkRadioAction *current, + ThunarWindow *window); +static void thunar_window_action_go_up (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_home (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_templates (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_open_location (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_contents (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_about (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_show_hidden (GtkToggleAction *action, + ThunarWindow *window); +static void thunar_window_current_directory_changed (ThunarFile *current_directory, + ThunarWindow *window); +static void thunar_window_connect_proxy (GtkUIManager *manager, + GtkAction *action, + GtkWidget *proxy, + ThunarWindow *window); +static void thunar_window_disconnect_proxy (GtkUIManager *manager, + GtkAction *action, + GtkWidget *proxy, + ThunarWindow *window); +static void thunar_window_menu_item_selected (GtkWidget *menu_item, + ThunarWindow *window); +static void thunar_window_menu_item_deselected (GtkWidget *menu_item, + ThunarWindow *window); +static void thunar_window_notify_loading (ThunarView *view, + GParamSpec *pspec, + ThunarWindow *window); +static void thunar_window_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, + ThunarVfsVolume *volume, + ThunarWindow *window); +static gboolean thunar_window_merge_idle (gpointer user_data); +static void thunar_window_merge_idle_destroy (gpointer user_data); +static gboolean thunar_window_save_geometry_timer (gpointer user_data); +static void thunar_window_save_geometry_timer_destroy (gpointer user_data); @@ -187,6 +190,9 @@ struct _ThunarWindow GtkActionGroup *action_group; GtkUIManager *ui_manager; + /* to be able to change folder on "volume-pre-unmount" if required */ + ThunarVfsVolumeManager *volume_manager; + /* closures for the menu_item_selected()/menu_item_deselected() callbacks */ GClosure *menu_item_selected_closure; GClosure *menu_item_deselected_closure; @@ -460,6 +466,10 @@ thunar_window_init (ThunarWindow *window) /* allocate the scroll_to_files mapping */ window->scroll_to_files = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, g_object_unref); + /* connect to the volume manager */ + window->volume_manager = thunar_vfs_volume_manager_get_default (); + g_signal_connect (G_OBJECT (window->volume_manager), "volume-pre-unmount", G_CALLBACK (thunar_window_volume_pre_unmount), window); + /* allocate a closure for the menu_item_selected() callback */ window->menu_item_selected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_selected), G_OBJECT (window)); g_closure_ref (window->menu_item_selected_closure); @@ -692,6 +702,10 @@ thunar_window_finalize (GObject *object) g_closure_unref (window->menu_item_deselected_closure); g_closure_unref (window->menu_item_selected_closure); + /* disconnect from the volume manager */ + g_signal_handlers_disconnect_matched (G_OBJECT (window->volume_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); + g_object_unref (G_OBJECT (window->volume_manager)); + /* disconnect from the ui manager */ g_signal_handlers_disconnect_matched (G_OBJECT (window->ui_manager), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); g_object_unref (G_OBJECT (window->ui_manager)); @@ -1834,6 +1848,45 @@ thunar_window_notify_loading (ThunarView *view, +static void +thunar_window_volume_pre_unmount (ThunarVfsVolumeManager *volume_manager, + ThunarVfsVolume *volume, + ThunarWindow *window) +{ + ThunarVfsPath *path; + ThunarFile *file; + GtkAction *action; + + g_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager)); + g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume)); + g_return_if_fail (THUNAR_IS_WINDOW (window)); + + /* nothing to do if we don't have a current directory */ + if (G_UNLIKELY (window->current_directory == NULL)) + return; + + /* determine the mount point for the volume */ + path = thunar_vfs_volume_get_mount_point (volume); + if (G_UNLIKELY (path == NULL)) + return; + + /* check if a ThunarFile is known for the mount point */ + file = thunar_file_cache_lookup (path); + if (G_UNLIKELY (file == NULL)) + return; + + /* check if the file is the current directory or an ancestor of the current directory */ + if (window->current_directory == file || thunar_file_is_ancestor (window->current_directory, file)) + { + /* change to the home folder */ + action = gtk_action_group_get_action (window->action_group, "open-home"); + if (G_LIKELY (action != NULL)) + gtk_action_activate (action); + } +} + + + static gboolean thunar_window_merge_idle (gpointer user_data) {