gvfs r1845 - in trunk: . client common daemon monitor/hal monitor/proxy programs
- From: davidz svn gnome org
- To: svn-commits-list gnome org
- Subject: gvfs r1845 - in trunk: . client common daemon monitor/hal monitor/proxy programs
- Date: Tue, 29 Jul 2008 18:27:21 +0000 (UTC)
Author: davidz
Date: Tue Jul 29 18:27:21 2008
New Revision: 1845
URL: http://svn.gnome.org/viewvc/gvfs?rev=1845&view=rev
Log:
2008-07-29 David Zeuthen <davidz redhat com>
* client/gdaemonmount.c:
* common/gmounttracker.c:
* common/gmounttracker.h:
* daemon/gvfsbackend.c:
* daemon/gvfsbackend.h:
* daemon/gvfsbackendcdda.c:
* daemon/gvfsbackendgphoto2.c:
* daemon/mount.c:
Add x-content/* support to daemon mounts. Right now a backend
can only set the x-content/* type ahead of time. We might want
to add support dynamically obtaining it too (e.g. support
force_rescan).
* monitor/hal/ghalmount.c:
* monitor/hal/ghalvolume.c:
* monitor/hal/ghalvolumemonitor.c:
* monitor/hal/hal-utils.c:
* monitor/hal/hal-utils.h:
Add x-content/* support to the HAL volume monitor.
* monitor/proxy/gproxymount.c:
* monitor/proxy/gproxymount.h:
* monitor/proxy/gproxyvolumemonitor.c:
* monitor/proxy/gproxyvolumemonitor.h:
* monitor/proxy/gvfsproxyvolumemonitordaemon.c:
Add x-content/* support to proxy volume monitor. Also fix
a number of bugs the initial implementation had.
* programs/gvfs-mount.c:
Print out x-content-types.
Modified:
trunk/ChangeLog
trunk/client/gdaemonmount.c
trunk/common/gmounttracker.c
trunk/common/gmounttracker.h
trunk/daemon/gvfsbackend.c
trunk/daemon/gvfsbackend.h
trunk/daemon/gvfsbackendcdda.c
trunk/daemon/gvfsbackendgphoto2.c
trunk/daemon/mount.c
trunk/monitor/hal/ghalmount.c
trunk/monitor/hal/ghalvolume.c
trunk/monitor/hal/ghalvolumemonitor.c
trunk/monitor/hal/hal-utils.c
trunk/monitor/hal/hal-utils.h
trunk/monitor/proxy/gproxymount.c
trunk/monitor/proxy/gproxymount.h
trunk/monitor/proxy/gproxyvolumemonitor.c
trunk/monitor/proxy/gproxyvolumemonitor.h
trunk/monitor/proxy/gvfsproxyvolumemonitordaemon.c
trunk/programs/gvfs-mount.c
Modified: trunk/client/gdaemonmount.c
==============================================================================
--- trunk/client/gdaemonmount.c (original)
+++ trunk/client/gdaemonmount.c Tue Jul 29 18:27:21 2008
@@ -357,6 +357,49 @@
return res;
}
+static char **
+g_daemon_mount_guess_content_type_sync (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GDaemonMount *daemon_mount = G_DAEMON_MOUNT (mount);
+ char **result;
+
+ result = NULL;
+ G_LOCK (daemon_mount);
+ if (daemon_mount->mount_info->x_content_types != NULL &&
+ strlen (daemon_mount->mount_info->x_content_types) > 0)
+ result = g_strsplit (daemon_mount->mount_info->x_content_types, " ", 0);
+ G_UNLOCK (daemon_mount);
+
+ return result;
+}
+
+static void
+g_daemon_mount_guess_content_type (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ simple = g_simple_async_result_new (G_OBJECT (mount),
+ callback,
+ user_data,
+ NULL);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static char **
+g_daemon_mount_guess_content_type_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_daemon_mount_guess_content_type_sync (mount, FALSE, NULL, error);
+}
+
static void
g_daemon_mount_mount_iface_init (GMountIface *iface)
{
@@ -372,4 +415,7 @@
iface->unmount_finish = g_daemon_mount_unmount_finish;
iface->eject = g_daemon_mount_eject;
iface->eject_finish = g_daemon_mount_eject_finish;
+ iface->guess_content_type = g_daemon_mount_guess_content_type;
+ iface->guess_content_type_finish = g_daemon_mount_guess_content_type_finish;
+ iface->guess_content_type_sync = g_daemon_mount_guess_content_type_sync;
}
Modified: trunk/common/gmounttracker.c
==============================================================================
--- trunk/common/gmounttracker.c (original)
+++ trunk/common/gmounttracker.c Tue Jul 29 18:27:21 2008
@@ -115,6 +115,7 @@
copy->ref_count = 1;
copy->display_name = g_strdup (info->display_name);
copy->stable_name = g_strdup (info->stable_name);
+ copy->x_content_types = g_strdup (info->x_content_types);
copy->icon = g_strdup (info->icon);
copy->dbus_id = g_strdup (info->dbus_id);
copy->object_path = g_strdup (info->object_path);
@@ -140,6 +141,7 @@
{
g_free (info->display_name);
g_free (info->stable_name);
+ g_free (info->x_content_types);
g_free (info->icon);
g_free (info->dbus_id);
g_free (info->object_path);
@@ -184,6 +186,7 @@
dbus_bool_t user_visible;
char *display_name;
char *stable_name;
+ char *x_content_types;
char *icon;
char *prefered_filename_encoding;
char *dbus_id;
@@ -200,6 +203,7 @@
DBUS_TYPE_OBJECT_PATH, &obj_path,
DBUS_TYPE_STRING, &display_name,
DBUS_TYPE_STRING, &stable_name,
+ DBUS_TYPE_STRING, &x_content_types,
DBUS_TYPE_STRING, &icon,
DBUS_TYPE_STRING, &prefered_filename_encoding,
DBUS_TYPE_BOOLEAN, &user_visible,
@@ -217,6 +221,7 @@
info->ref_count = 1;
info->display_name = g_strdup (display_name);
info->stable_name = g_strdup (stable_name);
+ info->x_content_types = g_strdup (x_content_types);
info->icon = g_strdup (icon);
info->dbus_id = g_strdup (dbus_id);
info->object_path = g_strdup (obj_path);
Modified: trunk/common/gmounttracker.h
==============================================================================
--- trunk/common/gmounttracker.h (original)
+++ trunk/common/gmounttracker.h Tue Jul 29 18:27:21 2008
@@ -42,6 +42,7 @@
volatile int ref_count;
char *display_name;
char *stable_name;
+ char *x_content_types;
char *icon;
char *dbus_id;
char *object_path;
Modified: trunk/daemon/gvfsbackend.c
==============================================================================
--- trunk/daemon/gvfsbackend.c (original)
+++ trunk/daemon/gvfsbackend.c Tue Jul 29 18:27:21 2008
@@ -68,6 +68,7 @@
char *display_name;
char *stable_name;
+ char **x_content_types;
char *icon;
char *prefered_filename_encoding;
gboolean user_visible;
@@ -142,6 +143,7 @@
g_free (backend->priv->display_name);
g_free (backend->priv->stable_name);
+ g_strfreev (backend->priv->x_content_types);
g_free (backend->priv->icon);
g_free (backend->priv->prefered_filename_encoding);
if (backend->priv->mount_spec)
@@ -299,6 +301,27 @@
backend->priv->stable_name = g_strdup (stable_name);
}
+/**
+ * g_vfs_backend_set_x_content_types:
+ * @backend: backend
+ * @x_content_types: the x-content types
+ *
+ * For backends where the x-content type is known ahead of time and
+ * won't change (such as a CDDA audio disc backend), this function
+ * should be called when the backend is constructed with the given
+ * types.
+ *
+ * See the <ulink url="http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec">shared-mime-info</ulink>
+ * specification for more on x-content types.
+ **/
+void
+g_vfs_backend_set_x_content_types (GVfsBackend *backend,
+ char **x_content_types)
+{
+ g_strfreev (backend->priv->x_content_types);
+ backend->priv->x_content_types = g_strdupv (x_content_types);
+}
+
void
g_vfs_backend_set_icon_name (GVfsBackend *backend,
const char *icon)
@@ -351,6 +374,12 @@
return backend->priv->stable_name;
}
+char **
+g_vfs_backend_get_x_content_types (GVfsBackend *backend)
+{
+ return backend->priv->x_content_types;
+}
+
const char *
g_vfs_backend_get_icon_name (GVfsBackend *backend)
{
@@ -551,7 +580,13 @@
DBusMessage *message;
DBusMessageIter iter;
dbus_bool_t user_visible;
-
+ char *x_content_types_string;
+
+ if (backend->priv->x_content_types != NULL && g_strv_length (backend->priv->x_content_types) > 0)
+ x_content_types_string = g_strjoinv (" ", backend->priv->x_content_types);
+ else
+ x_content_types_string = g_strdup ("");
+
message = dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
G_VFS_DBUS_MOUNTTRACKER_PATH,
G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
@@ -570,6 +605,7 @@
DBUS_TYPE_OBJECT_PATH, &backend->priv->object_path,
DBUS_TYPE_STRING, &backend->priv->display_name,
DBUS_TYPE_STRING, &stable_name,
+ DBUS_TYPE_STRING, &x_content_types_string,
DBUS_TYPE_STRING, &backend->priv->icon,
DBUS_TYPE_STRING, &backend->priv->prefered_filename_encoding,
DBUS_TYPE_BOOLEAN, &user_visible,
@@ -584,6 +620,8 @@
_g_dbus_connection_call_async (NULL, message, -1,
callback, user_data);
dbus_message_unref (message);
+
+ g_free (x_content_types_string);
}
void
Modified: trunk/daemon/gvfsbackend.h
==============================================================================
--- trunk/daemon/gvfsbackend.h (original)
+++ trunk/daemon/gvfsbackend.h Tue Jul 29 18:27:21 2008
@@ -379,6 +379,8 @@
const char *display_name);
void g_vfs_backend_set_stable_name (GVfsBackend *backend,
const char *stable_name);
+void g_vfs_backend_set_x_content_types (GVfsBackend *backend,
+ char **x_content_types);
void g_vfs_backend_set_icon_name (GVfsBackend *backend,
const char *icon);
void g_vfs_backend_set_prefered_filename_encoding (GVfsBackend *backend,
@@ -396,6 +398,7 @@
const char *g_vfs_backend_get_backend_type (GVfsBackend *backend);
const char *g_vfs_backend_get_display_name (GVfsBackend *backend);
const char *g_vfs_backend_get_stable_name (GVfsBackend *backend);
+char **g_vfs_backend_get_x_content_types (GVfsBackend *backend);
const char *g_vfs_backend_get_icon_name (GVfsBackend *backend);
GMountSpec *g_vfs_backend_get_mount_spec (GVfsBackend *backend);
GVfsDaemon *g_vfs_backend_get_daemon (GVfsBackend *backend);
Modified: trunk/daemon/gvfsbackendcdda.c
==============================================================================
--- trunk/daemon/gvfsbackendcdda.c (original)
+++ trunk/daemon/gvfsbackendcdda.c Tue Jul 29 18:27:21 2008
@@ -182,10 +182,12 @@
{
GVfsBackend *backend = G_VFS_BACKEND (cdda_backend);
GMountSpec *mount_spec;
+ char *x_content_types[] = {"x-content/audio-cdda", NULL};
//g_warning ("initing %p", cdda_backend);
g_vfs_backend_set_display_name (backend, "cdda");
+ g_vfs_backend_set_x_content_types (backend, x_content_types);
// TODO: HMM: g_vfs_backend_set_user_visible (backend, FALSE);
mount_spec = g_mount_spec_new ("cdda");
Modified: trunk/daemon/gvfsbackendgphoto2.c
==============================================================================
--- trunk/daemon/gvfsbackendgphoto2.c (original)
+++ trunk/daemon/gvfsbackendgphoto2.c Tue Jul 29 18:27:21 2008
@@ -716,6 +716,8 @@
int usb_device_num;
char **tokens;
char *endp;
+ char *camera_x_content_types[] = {"x-content/image-dcf", NULL};
+ char *music_player_x_content_types[] = {"x-content/audio-player", NULL};
gphoto2_backend->hal_udi = NULL;
@@ -870,6 +872,19 @@
gphoto2_backend->hal_icon_name = g_strdup ("camera-photo");
}
}
+
+ /* TODO: should we sniff the files instead? */
+ if (m == 0)
+ {
+ g_vfs_backend_set_x_content_types (G_VFS_BACKEND (gphoto2_backend),
+ camera_x_content_types);
+ }
+ else
+ {
+ g_vfs_backend_set_x_content_types (G_VFS_BACKEND (gphoto2_backend),
+ music_player_x_content_types);
+ }
+
}
}
Modified: trunk/daemon/mount.c
==============================================================================
--- trunk/daemon/mount.c (original)
+++ trunk/daemon/mount.c Tue Jul 29 18:27:21 2008
@@ -39,6 +39,7 @@
typedef struct {
char *display_name;
char *stable_name;
+ char *x_content_types;
char *icon;
char *prefered_filename_encoding;
gboolean user_visible;
@@ -157,6 +158,7 @@
{
g_free (mount->display_name);
g_free (mount->stable_name);
+ g_free (mount->x_content_types);
g_free (mount->icon);
g_free (mount->prefered_filename_encoding);
g_free (mount->dbus_id);
@@ -199,6 +201,11 @@
DBUS_TYPE_STRING,
&mount->stable_name))
_g_dbus_oom ();
+
+ if (!dbus_message_iter_append_basic (&struct_iter,
+ DBUS_TYPE_STRING,
+ &mount->x_content_types))
+ _g_dbus_oom ();
if (!dbus_message_iter_append_basic (&struct_iter,
DBUS_TYPE_STRING,
@@ -647,7 +654,7 @@
VfsMount *mount;
DBusMessage *reply;
DBusError error;
- const char *display_name, *stable_name, *icon, *obj_path, *id, *prefered_filename_encoding;
+ const char *display_name, *stable_name, *x_content_types, *icon, *obj_path, *id, *prefered_filename_encoding;
dbus_bool_t user_visible;
DBusMessageIter iter;
GMountSpec *mount_spec;
@@ -662,6 +669,7 @@
DBUS_TYPE_OBJECT_PATH, &obj_path,
DBUS_TYPE_STRING, &display_name,
DBUS_TYPE_STRING, &stable_name,
+ DBUS_TYPE_STRING, &x_content_types,
DBUS_TYPE_STRING, &icon,
DBUS_TYPE_STRING, &prefered_filename_encoding,
DBUS_TYPE_BOOLEAN, &user_visible,
@@ -684,6 +692,7 @@
mount = g_new0 (VfsMount, 1);
mount->display_name = g_strdup (display_name);
mount->stable_name = g_strdup (stable_name);
+ mount->x_content_types = g_strdup (x_content_types);
mount->icon = g_strdup (icon);
mount->prefered_filename_encoding = g_strdup (prefered_filename_encoding);
mount->user_visible = user_visible;
@@ -850,6 +859,7 @@
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_BOOLEAN_AS_STRING
DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING
G_MOUNT_SPEC_TYPE_AS_STRING
Modified: trunk/monitor/hal/ghalmount.c
==============================================================================
--- trunk/monitor/hal/ghalmount.c (original)
+++ trunk/monitor/hal/ghalmount.c Tue Jul 29 18:27:21 2008
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
@@ -1134,6 +1135,121 @@
return res;
}
+/* TODO: handle force_rescan */
+static char **
+g_hal_mount_guess_content_type_sync (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GHalMount *hal_mount = G_HAL_MOUNT (mount);
+ const char *disc_type;
+ char **x_content_types;
+ GFile *root;
+ GPtrArray *p;
+ char **result;
+ int n;
+ char **caps;
+ char *uri;
+
+ p = g_ptr_array_new ();
+
+ G_LOCK (hal_mount);
+
+ root = get_root (hal_mount);
+ uri = g_file_get_uri (root);
+ if (g_str_has_prefix (uri, "burn://"))
+ {
+ /* doesn't make sense to probe burn:/// - look at the disc type instead */
+ if (hal_mount->device != NULL)
+ {
+ disc_type = hal_device_get_property_string (hal_mount->device, "volume.disc.type");
+ if (disc_type != NULL)
+ {
+ if (g_str_has_prefix (disc_type, "dvd"))
+ g_ptr_array_add (p, g_strdup ("x-content/blank-dvd"));
+ else if (g_str_has_prefix (disc_type, "hddvd"))
+ g_ptr_array_add (p, g_strdup ("x-content/blank-hddvd"));
+ else if (g_str_has_prefix (disc_type, "bd"))
+ g_ptr_array_add (p, g_strdup ("x-content/blank-bd"));
+ else
+ g_ptr_array_add (p, g_strdup ("x-content/blank-cd")); /* assume CD */
+ }
+ }
+ }
+ else
+ {
+ /* sniff content type */
+ x_content_types = g_content_type_guess_for_tree (root);
+ if (x_content_types != NULL)
+ {
+ for (n = 0; x_content_types[n] != NULL; n++)
+ g_ptr_array_add (p, g_strdup (x_content_types[n]));
+ g_strfreev (x_content_types);
+ }
+ }
+ g_object_unref (root);
+ g_free (uri);
+
+ /* also add content types from hal capabilities */
+ if (hal_mount->drive_device != NULL)
+ {
+ caps = dupv_and_uniqify (hal_device_get_property_strlist (hal_mount->drive_device, "info.capabilities"));
+ if (caps != NULL)
+ {
+ for (n = 0; caps[n] != NULL; n++)
+ {
+ if (strcmp (caps[n], "portable_audio_player") == 0)
+ g_ptr_array_add (p, g_strdup ("x-content/audio-player"));
+ }
+ g_strfreev (caps);
+ }
+ }
+
+ if (p->len == 0)
+ {
+ result = NULL;
+ g_ptr_array_free (p, TRUE);
+ }
+ else
+ {
+ g_ptr_array_add (p, NULL);
+ result = (char **) g_ptr_array_free (p, FALSE);
+ }
+
+ G_UNLOCK (hal_mount);
+
+ return result;
+}
+
+/* since we're an out-of-process volume monitor we'll just do this sync */
+static void
+g_hal_mount_guess_content_type (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ /* TODO: handle force_rescan */
+ simple = g_simple_async_result_new (G_OBJECT (mount),
+ callback,
+ user_data,
+ NULL);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static char **
+g_hal_mount_guess_content_type_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ /* TODO: handle force_rescan */
+ return g_hal_mount_guess_content_type_sync (mount, FALSE, NULL, error);
+}
+
static void
g_hal_mount_mount_iface_init (GMountIface *iface)
{
@@ -1149,6 +1265,9 @@
iface->unmount_finish = g_hal_mount_unmount_finish;
iface->eject = g_hal_mount_eject;
iface->eject_finish = g_hal_mount_eject_finish;
+ iface->guess_content_type = g_hal_mount_guess_content_type;
+ iface->guess_content_type_finish = g_hal_mount_guess_content_type_finish;
+ iface->guess_content_type_sync = g_hal_mount_guess_content_type_sync;
}
#define INSENSITIVE_SEARCH_ITEMS_PER_CALLBACK 100
Modified: trunk/monitor/hal/ghalvolume.c
==============================================================================
--- trunk/monitor/hal/ghalvolume.c (original)
+++ trunk/monitor/hal/ghalvolume.c Tue Jul 29 18:27:21 2008
@@ -165,36 +165,6 @@
return str;
}
-static char **
-dupv_and_uniqify (char **str_array)
-{
- int n, m, o;
- int len;
- char **result;
-
- result = g_strdupv (str_array);
- len = g_strv_length (result);
-
- for (n = 0; n < len; n++)
- {
- char *s = result[n];
- for (m = n + 1; m < len; m++)
- {
- char *p = result[m];
- if (strcmp (s, p) == 0)
- {
- for (o = m + 1; o < len; o++)
- result[o - 1] = result[o];
- len--;
- result[len] = NULL;
- m--;
- }
- }
- }
-
- return result;
-}
-
static void
do_update_from_hal (GHalVolume *mv)
{
Modified: trunk/monitor/hal/ghalvolumemonitor.c
==============================================================================
--- trunk/monitor/hal/ghalvolumemonitor.c (original)
+++ trunk/monitor/hal/ghalvolumemonitor.c Tue Jul 29 18:27:21 2008
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
Modified: trunk/monitor/hal/hal-utils.c
==============================================================================
--- trunk/monitor/hal/hal-utils.c (original)
+++ trunk/monitor/hal/hal-utils.c Tue Jul 29 18:27:21 2008
@@ -140,3 +140,32 @@
return icon;
}
+char **
+dupv_and_uniqify (char **str_array)
+{
+ int n, m, o;
+ int len;
+ char **result;
+
+ result = g_strdupv (str_array);
+ len = g_strv_length (result);
+
+ for (n = 0; n < len; n++)
+ {
+ char *s = result[n];
+ for (m = n + 1; m < len; m++)
+ {
+ char *p = result[m];
+ if (strcmp (s, p) == 0)
+ {
+ for (o = m + 1; o < len; o++)
+ result[o - 1] = result[o];
+ len--;
+ result[len] = NULL;
+ m--;
+ }
+ }
+ }
+
+ return result;
+}
Modified: trunk/monitor/hal/hal-utils.h
==============================================================================
--- trunk/monitor/hal/hal-utils.h (original)
+++ trunk/monitor/hal/hal-utils.h Tue Jul 29 18:27:21 2008
@@ -35,6 +35,8 @@
GIcon * get_themed_icon_with_fallbacks (const char *icon_name,
const char *fallbacks);
+char **dupv_and_uniqify (char **str_array);
+
G_END_DECLS
#endif /* __HAL_UTILS_H__ */
Modified: trunk/monitor/proxy/gproxymount.c
==============================================================================
--- trunk/monitor/proxy/gproxymount.c (original)
+++ trunk/monitor/proxy/gproxymount.c Tue Jul 29 18:27:21 2008
@@ -118,6 +118,22 @@
return mount;
}
+gboolean
+g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path)
+{
+ char *path;
+ gboolean result;
+ result = FALSE;
+ path = g_file_get_path (mount->root);
+ if (path != NULL)
+ {
+ if (strcmp (path, mount_path) == 0)
+ result = TRUE;
+ g_free (path);
+ }
+ return result;
+}
+
/* string id
* string name
* string gicon_data
@@ -479,6 +495,44 @@
}
static void
+g_proxy_mount_guess_content_type (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+
+ /* TODO: handle force_rescan */
+ simple = g_simple_async_result_new (G_OBJECT (mount),
+ callback,
+ user_data,
+ NULL);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static char **
+g_proxy_mount_guess_content_type_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ GProxyMount *proxy_mount = G_PROXY_MOUNT (mount);
+ return g_strdupv (proxy_mount->x_content_types);
+}
+
+static char **
+g_proxy_mount_guess_content_type_sync (GMount *mount,
+ gboolean force_rescan,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GProxyMount *proxy_mount = G_PROXY_MOUNT (mount);
+ /* TODO: handle force_rescan */
+ return g_strdupv (proxy_mount->x_content_types);
+}
+
+static void
g_proxy_mount_mount_iface_init (GMountIface *iface)
{
iface->get_root = g_proxy_mount_get_root;
@@ -493,6 +547,9 @@
iface->unmount_finish = g_proxy_mount_unmount_finish;
iface->eject = g_proxy_mount_eject;
iface->eject_finish = g_proxy_mount_eject_finish;
+ iface->guess_content_type = g_proxy_mount_guess_content_type;
+ iface->guess_content_type_finish = g_proxy_mount_guess_content_type_finish;
+ iface->guess_content_type_sync = g_proxy_mount_guess_content_type_sync;
}
void
Modified: trunk/monitor/proxy/gproxymount.h
==============================================================================
--- trunk/monitor/proxy/gproxymount.h (original)
+++ trunk/monitor/proxy/gproxymount.h Tue Jul 29 18:27:21 2008
@@ -49,7 +49,7 @@
void g_proxy_mount_update (GProxyMount *mount,
DBusMessageIter *iter);
const char *g_proxy_mount_get_id (GProxyMount *mount);
-
+gboolean g_proxy_mount_has_mount_path (GProxyMount *mount, const char *mount_path);
G_END_DECLS
Modified: trunk/monitor/proxy/gproxyvolumemonitor.c
==============================================================================
--- trunk/monitor/proxy/gproxyvolumemonitor.c (original)
+++ trunk/monitor/proxy/gproxyvolumemonitor.c Tue Jul 29 18:27:21 2008
@@ -31,7 +31,7 @@
* - neglible memory + cpu overhead
* - will need to construct them at some point
* - we can actually implement get_mount_for_mount_path()
- * correctly
+ * correctly even when no volume monitor is constructed
*
* - implement support for GMountOperation
* - not implemented in the HAL volume monitor and that's all
@@ -264,42 +264,45 @@
get_mount_for_mount_path (const char *mount_path,
GCancellable *cancellable)
{
- GType type;
GMount *mount;
- GNativeVolumeMonitorClass *klass;
+ GProxyVolumeMonitor *volume_monitor;
+ GProxyVolumeMonitorClass *klass;
+ GHashTableIter vm_hash_iter;
+ GHashTableIter vol_hash_iter;
+ GProxyMount *candidate_mount;
/* This static method on GNativeVolumeMonitor is a *complete* pain
* in the ass to deal with; we need to rework gio so it's deprecated
* and thus never will get called.
*
- * For now we just implement as badly as the GUnixVolumeMonitor
- * shipped with gio; e.g. we just return *some* object that
- * implements GMount and we don't worry about setting the
- * corresponding volume or ensuring it's the same reference as what
- * one would normally get.
+ * TODO: we don't handle the case when there's no volume monitor ever
+ * constructed. See TODO at the top of this file on how to handle that.
*/
mount = NULL;
- klass = NULL;
-
- /* You can't hide types from me
- *
- * (read: _g_unix_volume_monitor_get_type() isn't exported)
- */
- type = g_type_from_name ("GUnixVolumeMonitor");
- if (type == 0)
- goto out;
-
- klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_type_class_ref (type));
- if (klass == NULL)
- goto out;
+ G_LOCK (proxy_vm);
- if (klass->get_mount_for_mount_path != NULL)
- mount = klass->get_mount_for_mount_path (mount_path, cancellable);
+ /* First find the native volume monitor if one exists */
+ g_hash_table_iter_init (&vm_hash_iter, the_volume_monitors);
+ while (g_hash_table_iter_next (&vm_hash_iter, NULL, (gpointer) &volume_monitor)) {
+ klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (volume_monitor));
+
+ if (klass->is_native) {
+ /* The see if we've got a mount */
+ g_hash_table_iter_init (&vol_hash_iter, volume_monitor->mounts);
+ while (g_hash_table_iter_next (&vol_hash_iter, NULL, (gpointer) &candidate_mount)) {
+ if (g_proxy_mount_has_mount_path (candidate_mount, mount_path))
+ {
+ mount = g_object_ref (candidate_mount);
+ goto out;
+ }
+ }
+ goto out;
+ }
+ }
out:
- if (klass != NULL)
- g_type_class_unref (klass);
+ G_UNLOCK (proxy_vm);
return mount;
}
@@ -418,13 +421,17 @@
GProxyVolumeMonitor *monitor = G_PROXY_VOLUME_MONITOR (user_data);
DBusMessageIter iter;
const char *id;
+ const char *the_dbus_name;
const char *member;
GProxyDrive *drive;
GProxyVolume *volume;
GProxyMount *mount;
+ GProxyVolumeMonitorClass *klass;
G_LOCK (proxy_vm);
+ klass = G_PROXY_VOLUME_MONITOR_CLASS (G_OBJECT_GET_CLASS (monitor));
+
member = dbus_message_get_member (message);
if (dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveChanged") ||
@@ -433,9 +440,14 @@
dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "DriveEjectButton")) {
dbus_message_iter_init (message, &iter);
+ dbus_message_iter_get_basic (&iter, &the_dbus_name);
+ dbus_message_iter_next (&iter);
dbus_message_iter_get_basic (&iter, &id);
dbus_message_iter_next (&iter);
+ if (strcmp (the_dbus_name, klass->dbus_name) != 0)
+ goto not_for_us;
+
if (strcmp (member, "DriveChanged") == 0)
{
drive = g_hash_table_lookup (monitor->drives, id);
@@ -484,9 +496,14 @@
dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "VolumeRemoved")) {
dbus_message_iter_init (message, &iter);
+ dbus_message_iter_get_basic (&iter, &the_dbus_name);
+ dbus_message_iter_next (&iter);
dbus_message_iter_get_basic (&iter, &id);
dbus_message_iter_next (&iter);
+ if (strcmp (the_dbus_name, klass->dbus_name) != 0)
+ goto not_for_us;
+
if (strcmp (member, "VolumeChanged") == 0)
{
volume = g_hash_table_lookup (monitor->volumes, id);
@@ -527,9 +544,14 @@
dbus_message_is_signal (message, "org.gtk.Private.RemoteVolumeMonitor", "MountRemoved")) {
dbus_message_iter_init (message, &iter);
+ dbus_message_iter_get_basic (&iter, &the_dbus_name);
+ dbus_message_iter_next (&iter);
dbus_message_iter_get_basic (&iter, &id);
dbus_message_iter_next (&iter);
+ if (strcmp (the_dbus_name, klass->dbus_name) != 0)
+ goto not_for_us;
+
if (strcmp (member, "MountChanged") == 0)
{
mount = g_hash_table_lookup (monitor->mounts, id);
@@ -575,6 +597,7 @@
}
+ not_for_us:
G_UNLOCK (proxy_vm);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -591,10 +614,27 @@
g_free (klass->dbus_name);
}
+typedef struct {
+ char *dbus_name;
+ gboolean is_native;
+} ProxyClassData;
+
+static ProxyClassData *
+proxy_class_data_new (const char *dbus_name, gboolean is_native)
+{
+ ProxyClassData *data;
+ data = g_new0 (ProxyClassData, 1);
+ data->dbus_name = g_strdup (dbus_name);
+ data->is_native = is_native;
+ return data;
+}
+
static void
g_proxy_volume_monitor_class_intern_init_pre (GProxyVolumeMonitorClass *klass, gconstpointer class_data)
{
- klass->dbus_name = g_strdup ((char *) class_data);
+ ProxyClassData *data = (ProxyClassData *) class_data;
+ klass->dbus_name = g_strdup (data->dbus_name);
+ klass->is_native = data->is_native;
g_proxy_volume_monitor_class_intern_init (klass);
}
@@ -961,7 +1001,7 @@
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) g_proxy_volume_monitor_class_intern_init_pre,
(GClassFinalizeFunc) g_proxy_volume_monitor_class_finalize,
- (gconstpointer) g_strdup (dbus_name), /* class_data (leaked!) */
+ (gconstpointer) proxy_class_data_new (dbus_name, is_native), /* class_data (leaked!) */
sizeof (GProxyVolumeMonitor),
0, /* n_preallocs */
(GInstanceInitFunc) g_proxy_volume_monitor_init,
Modified: trunk/monitor/proxy/gproxyvolumemonitor.h
==============================================================================
--- trunk/monitor/proxy/gproxyvolumemonitor.h (original)
+++ trunk/monitor/proxy/gproxyvolumemonitor.h Tue Jul 29 18:27:21 2008
@@ -48,6 +48,7 @@
struct _GProxyVolumeMonitorClass {
GNativeVolumeMonitorClass parent_class;
char *dbus_name;
+ gboolean is_native;
};
GType g_proxy_volume_monitor_get_type (void) G_GNUC_CONST;
Modified: trunk/monitor/proxy/gvfsproxyvolumemonitordaemon.c
==============================================================================
--- trunk/monitor/proxy/gvfsproxyvolumemonitordaemon.c (original)
+++ trunk/monitor/proxy/gvfsproxyvolumemonitordaemon.c Tue Jul 29 18:27:21 2008
@@ -34,6 +34,7 @@
static GVolumeMonitor *monitor = NULL;
static DBusConnection *connection = NULL;
static GType the_volume_monitor_type;
+static const char *the_dbus_name = NULL;
static void monitor_try_create (void);
@@ -344,6 +345,8 @@
gboolean can_unmount;
GVolume *volume;
char *volume_id;
+ char **x_content_types;
+ int n;
dbus_message_iter_open_container (iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
@@ -375,7 +378,12 @@
dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &volume_id);
dbus_message_iter_open_container (&iter_struct, DBUS_TYPE_ARRAY, "s", &iter_x_content_types_array);
- /* TODO: append x-content types */
+ x_content_types = (char **) g_object_get_data (G_OBJECT (mount), "x-content-types");
+ if (x_content_types != NULL)
+ {
+ for (n = 0; x_content_types[n] != NULL; n++)
+ dbus_message_iter_append_basic (&iter_x_content_types_array, DBUS_TYPE_STRING, &(x_content_types[n]));
+ }
dbus_message_iter_close_container (&iter_struct, &iter_x_content_types_array);
g_free (volume_id);
@@ -893,6 +901,7 @@
message = dbus_message_new_signal ("/", "org.gtk.Private.RemoteVolumeMonitor", signal_name);
dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &the_dbus_name);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &id);
func (object, &iter);
@@ -954,8 +963,17 @@
}
static void
+mount_sniff_x_content_type (GMount *mount)
+{
+ char **x_content_types;
+ x_content_types = g_mount_guess_content_type_sync (mount, TRUE, NULL, NULL);
+ g_object_set_data_full (G_OBJECT (mount), "x-content-types", x_content_types, (GDestroyNotify) g_strfreev);
+}
+
+static void
mount_added (GVolumeMonitor *monitor, GMount *mount, DBusConnection *connection)
{
+ mount_sniff_x_content_type (mount);
emit_signal (connection, "MountAdded", mount, (AppendFunc) append_mount);
}
@@ -996,6 +1014,8 @@
monitor_try_create (void)
{
GVolumeMonitorClass *klass;
+ GList *mounts;
+ GList *l;
monitor = NULL;
klass = G_VOLUME_MONITOR_CLASS (g_type_class_ref (the_volume_monitor_type));
@@ -1021,6 +1041,12 @@
goto fail;
}
+ mounts = g_volume_monitor_get_mounts (monitor);
+ for (l = mounts; l != NULL; l = l->next)
+ mount_sniff_x_content_type (G_MOUNT (l->data));
+ g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
+ g_list_free (mounts);
+
fail:
if (klass != NULL)
g_type_class_unref (klass);
@@ -1047,6 +1073,7 @@
*/
the_volume_monitor_type = volume_monitor_type;
+ the_dbus_name = dbus_name;
/* try and create the monitor */
monitor_try_create ();
Modified: trunk/programs/gvfs-mount.c
==============================================================================
--- trunk/programs/gvfs-mount.c (original)
+++ trunk/programs/gvfs-mount.c Tue Jul 29 18:27:21 2008
@@ -1,3 +1,4 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2006-2007 Red Hat, Inc.
@@ -303,6 +304,7 @@
char *name, *uuid, *uri;
GFile *root;
GIcon *icon;
+ char **x_content_types;
for (c = 0, l = mounts; l != NULL; l = l->next, c++)
{
@@ -330,14 +332,25 @@
if (uuid)
g_print ("%*suuid=%s\n", indent + 2, "", uuid);
- icon = g_mount_get_icon (mount);
- if (icon)
- {
- if (G_IS_THEMED_ICON (icon))
- show_themed_icon_names (G_THEMED_ICON (icon), indent + 2);
+ icon = g_mount_get_icon (mount);
+ if (icon)
+ {
+ if (G_IS_THEMED_ICON (icon))
+ show_themed_icon_names (G_THEMED_ICON (icon), indent + 2);
+
+ g_object_unref (icon);
+ }
- g_object_unref (icon);
- }
+ x_content_types = g_mount_guess_content_type_sync (mount, FALSE, NULL, NULL);
+ if (x_content_types != NULL && g_strv_length (x_content_types) > 0)
+ {
+ int n;
+ g_print ("%*sx_content_types:", indent + 2, "");
+ for (n = 0; x_content_types[n] != NULL; n++)
+ g_print (" %s", x_content_types[n]);
+ g_print ("\n");
+ }
+ g_strfreev (x_content_types);
g_print ("%*scan_unmount=%d\n", indent + 2, "", g_mount_can_unmount (mount));
g_print ("%*scan_eject=%d\n", indent + 2, "", g_mount_can_eject (mount));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]