summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/ChangeLog6
-rw-r--r--docs/reference/gio/gio-sections.txt3
-rw-r--r--gio/ChangeLog9
-rw-r--r--gio/gio.symbols3
-rw-r--r--gio/gmount.c134
-rw-r--r--gio/gmount.h8
-rw-r--r--gio/gunionvolumemonitor.c3
-rw-r--r--gio/gvolume.c34
8 files changed, 166 insertions, 34 deletions
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index 9c47c0269..041d58625 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,9 @@
+2008-12-01 Alexander Larsson <alexl@redhat.com>
+
+ Reviewed by NOBODY (OOPS!).
+
+ * gio/gio-sections.txt:
+
2008-11-30 Matthias Clasen <mclasen@redhat.com>
* glib/running.sgml: Mention all and help special options in
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index c54272cf9..0e5dd4262 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -863,6 +863,9 @@ g_mount_eject_finish
g_mount_guess_content_type
g_mount_guess_content_type_finish
g_mount_guess_content_type_sync
+g_mount_is_shadowed
+g_mount_shadow
+g_mount_unshadow
<SUBSECTION Standard>
G_IS_MOUNT
G_MOUNT
diff --git a/gio/ChangeLog b/gio/ChangeLog
index c1f38b84f..d4de9470d 100644
--- a/gio/ChangeLog
+++ b/gio/ChangeLog
@@ -1,3 +1,12 @@
+2008-12-01 Alexander Larsson <alexl@redhat.com>
+
+ * gio.symbols:
+ * gmount.[ch]:
+ * gunionvolumemonitor.c:
+ * gvolume.c:
+ Add and document g_mount_is_shadowed plus calls
+ to set/unset a mount as shadowed
+
2008-11-28 Matthias Clasen <mclasen@redhat.com>
* gio/tests/g-icon.c: Comment out two failing tests
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 3be198820..625666681 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -727,6 +727,9 @@ g_mount_remount_finish
g_mount_guess_content_type
g_mount_guess_content_type_finish
g_mount_guess_content_type_sync
+g_mount_is_shadowed
+g_mount_shadow
+g_mount_unshadow
#endif
#endif
diff --git a/gio/gmount.c b/gio/gmount.c
index 3c8ae6182..dbdbeaf49 100644
--- a/gio/gmount.c
+++ b/gio/gmount.c
@@ -695,5 +695,139 @@ g_mount_guess_content_type_sync (GMount *mount,
return (* iface->guess_content_type_sync) (mount, force_rescan, cancellable, error);
}
+G_LOCK_DEFINE_STATIC (priv_lock);
+
+/* only access this structure when holding priv_lock */
+typedef struct
+{
+ gint shadow_ref_count;
+} GMountPrivate;
+
+static void
+free_private (GMountPrivate *private)
+{
+ G_LOCK (priv_lock);
+ g_free (private);
+ G_UNLOCK (priv_lock);
+}
+
+/* may only be called when holding priv_lock */
+static GMountPrivate *
+get_private (GMount *mount)
+{
+ GMountPrivate *private;
+
+ private = g_object_get_data (G_OBJECT (mount), "g-mount-private");
+ if (G_LIKELY (private != NULL))
+ goto out;
+
+ private = g_new0 (GMountPrivate, 1);
+ g_object_set_data_full (G_OBJECT (mount),
+ "g-mount-private",
+ private,
+ (GDestroyNotify) free_private);
+
+ out:
+ return private;
+}
+
+/**
+ * g_mount_is_shadowed:
+ * @mount: A #GMount.
+ *
+ * Determines if @mount is shadowed. Applications or libraries should
+ * avoid displaying @mount in the user interface if it is shadowed.
+ *
+ * A mount is said to be shadowed if there exists one or more user
+ * visible objects (currently #GMount objects) with a root that is
+ * inside the root of @mount.
+ *
+ * One application of shadow mounts is when exposing a single file
+ * system that is used to address several logical volumes. In this
+ * situation, a #GVolumeMonitor implementation would create two
+ * #GVolume objects (for example, one for the camera functionality of
+ * the device and one for a SD card reader on the device) with
+ * activation URIs <literal>gphoto2://[usb:001,002]/store1/</literal>
+ * and <literal>gphoto2://[usb:001,002]/store2/</literal>. When the
+ * underlying mount (with root
+ * <literal>gphoto2://[usb:001,002]/</literal>) is mounted, said
+ * #GVolumeMonitor implementation would create two #GMount objects
+ * (each with their root matching the corresponding volume activation
+ * root) that would shadow the original mount.
+ *
+ * The proxy monitor in GVfs 2.26 and later, automatically creates and
+ * manage shadow mounts (and shadows the underlying mount) if the
+ * activation root on a #GVolume is set.
+ *
+ * Returns: %TRUE if @mount is shadowed.
+ *
+ * Since: 2.20
+ **/
+gboolean
+g_mount_is_shadowed (GMount *mount)
+{
+ GMountPrivate *priv;
+ gboolean ret;
+
+ g_return_val_if_fail (G_IS_MOUNT (mount), FALSE);
+
+ G_LOCK (priv_lock);
+ priv = get_private (mount);
+ ret = (priv->shadow_ref_count > 0);
+ G_UNLOCK (priv_lock);
+
+ return ret;
+}
+
+/**
+ * g_mount_shadow:
+ * @mount: A #GMount.
+ *
+ * Increments the shadow count on @mount. Usually used by
+ * #GVolumeMonitor implementations when creating a shadow mount for
+ * @mount, see g_mount_is_shadowed() for more information. The caller
+ * will need to emit the #GMount::changed signal on @mount manually.
+ *
+ * Since: 2.20
+ **/
+void
+g_mount_shadow (GMount *mount)
+{
+ GMountPrivate *priv;
+
+ g_return_if_fail (G_IS_MOUNT (mount));
+
+ G_LOCK (priv_lock);
+ priv = get_private (mount);
+ priv->shadow_ref_count += 1;
+ G_UNLOCK (priv_lock);
+}
+
+/**
+ * g_mount_unshadow:
+ * @mount: A #GMount.
+ *
+ * Decrements the shadow count on @mount. Usually used by
+ * #GVolumeMonitor implementations when destroying a shadow mount for
+ * @mount, see g_mount_is_shadowed() for more information. The caller
+ * will need to emit the #GMount::changed signal on @mount manually.
+ *
+ * Since: 2.20
+ **/
+void
+g_mount_unshadow (GMount *mount)
+{
+ GMountPrivate *priv;
+
+ g_return_if_fail (G_IS_MOUNT (mount));
+
+ G_LOCK (priv_lock);
+ priv = get_private (mount);
+ priv->shadow_ref_count -= 1;
+ if (priv->shadow_ref_count < 0)
+ g_warning ("Shadow ref count on GMount is negative");
+ G_UNLOCK (priv_lock);
+}
+
#define __G_MOUNT_C__
#include "gioaliasdef.c"
diff --git a/gio/gmount.h b/gio/gmount.h
index 66304bf7b..027960d5a 100644
--- a/gio/gmount.h
+++ b/gio/gmount.h
@@ -61,8 +61,8 @@ typedef struct _GMountIface GMountIface;
* @guess_content_type: Starts guessing the type of the content of a #GMount.
* See g_mount_guess_content_type() for more information on content
* type guessing. This operation was added in 2.18.
- * @guess_content_type_finish: Finishes a contenet type guessing operation.
- * @guess_content_type_sync: Synchronous variant of @guess_content_type.
+ * @guess_content_type_finish: Finishes a contenet type guessing operation. Added in 2.18.
+ * @guess_content_type_sync: Synchronous variant of @guess_content_type. Added in 2.18
*
* Interface for implementing operations for mounts.
**/
@@ -180,6 +180,10 @@ gchar ** g_mount_guess_content_type_sync (GMount *mount,
GCancellable *cancellable,
GError **error);
+gboolean g_mount_is_shadowed (GMount *mount);
+void g_mount_shadow (GMount *mount);
+void g_mount_unshadow (GMount *mount);
+
G_END_DECLS
#endif /* __G_MOUNT_H__ */
diff --git a/gio/gunionvolumemonitor.c b/gio/gunionvolumemonitor.c
index f12ecd905..1b5bafd6f 100644
--- a/gio/gunionvolumemonitor.c
+++ b/gio/gunionvolumemonitor.c
@@ -638,7 +638,8 @@ _g_mount_get_for_mount_path (const char *mount_path,
* Deprecated: 2.20: Instead of using this function, #GVolumeMonitor
* implementations should instead create shadow mounts with the URI of
* the mount they intend to adopt. See the proxy volume monitor in
- * gvfs for an example of this.
+ * gvfs for an example of this. Also see g_mount_is_shadowed(),
+ * g_mount_shadow() and g_mount_unshadow() functions.
*/
GVolume *
g_volume_monitor_adopt_orphan_mount (GMount *mount)
diff --git a/gio/gvolume.c b/gio/gvolume.c
index 7607b4290..ef550d822 100644
--- a/gio/gvolume.c
+++ b/gio/gvolume.c
@@ -566,37 +566,9 @@ g_volume_enumerate_identifiers (GVolume *volume)
*
* will always be %TRUE.
*
- * There is a number of possible uses of this function.
- *
- * First, implementations of #GVolumeMonitor can use this method to
- * determine if a #GMount should be adopted in the implementation of
- * g_volume_monitor_adopt_orphan_mount() by testing if the result of
- * this function equals (or has as prefix) the root of the given
- * #GMount. In particular this is useful in the in-process proxy part
- * of an out-of-process volume monitor implementation.
- *
- * Second, applications such as a file manager can use this to
- * navigate to the correct root in response to the user navigating to
- * a server. Now suppose there is a volume monitor for networked
- * servers that creates #GVolume objects corresponding to the
- * "favorite servers" (e.g. set up by the user via some "Connect to
- * Server" dialog). Suppose also that one of the favorite servers is
- * named "public_html @ fd.o" and the URI is
- * <literal>sftp://people.freedesktop.org/home/david/public_html</literal>.
- *
- * Now, due to the way GIO works, when the corresponding #GVolume is
- * mounted then a #GMount (typically adopted by the volume monitor)
- * will appear with the mount root (e.g. the result of
- * g_mount_get_root())
- * <literal>sftp://people.freedesktop.org</literal>. However, this
- * function (g_volume_get_activation_root()) can return a #GFile for
- * the URI
- * <literal>sftp://people.freedesktop.org/home/david/public_html</literal>.
- *
- * All this means that a file manager can use the latter URI for
- * navigating when the user clicks an icon representing the #GVolume
- * (e.g. clicking an icon with the name "public_html @ fd.o" or
- * similar).
+ * Activation roots are typically used in #GVolumeMonitor
+ * implementations to find the underlying mount to shadow, see
+ * g_mount_is_shadowed() for more details.
*
* Returns: the activation root of @volume or %NULL. Use
* g_object_unref() to free.