gvfs r1845 - in trunk: . client common daemon monitor/hal monitor/proxy programs



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]