gvfs r1148 - in trunk: . hal



Author: davidz
Date: Fri Jan 18 08:06:39 2008
New Revision: 1148
URL: http://svn.gnome.org/viewvc/gvfs?rev=1148&view=rev

Log:
2008-01-18  David Zeuthen  <davidz redhat com>

	The volume monitor bits of gphoto2 support. The actual backend
	will follow later. Right now the code is only enabled on Linux,
	need trivial changes to work on other operating systems.

	* hal/ghalvolume.c: (do_update_from_hal_for_camera),
	(update_from_hal), (g_hal_volume_new):
	* hal/ghalvolumemonitor.c: (get_hal_pool),
	(g_hal_volume_monitor_finalize), (get_volumes),
	(mountpoints_changed), (mounts_changed),
	(g_hal_volume_monitor_force_update), (hal_changed),
	(g_hal_volume_monitor_constructor), (find_camera_volume_by_udi),
	(update_cameras):
	* hal/ghalvolumemonitor.h:
	* hal/hal-pool.c: (hal_pool_finalize), (has_cap_only),
	(hal_pool_add_device_by_udi),
	(hal_pool_add_device_by_udi_and_properties), (hal_pool_new):
	* hal/hal-pool.h:



Modified:
   trunk/ChangeLog
   trunk/hal/ghalvolume.c
   trunk/hal/ghalvolumemonitor.c
   trunk/hal/ghalvolumemonitor.h
   trunk/hal/hal-pool.c
   trunk/hal/hal-pool.h

Modified: trunk/hal/ghalvolume.c
==============================================================================
--- trunk/hal/ghalvolume.c	(original)
+++ trunk/hal/ghalvolume.c	Fri Jan 18 08:06:39 2008
@@ -289,6 +289,36 @@
                           (GDestroyNotify) g_free);
 }
 
+#ifdef _WITH_GPHOTO2
+static void
+do_update_from_hal_for_camera (GHalVolume *v)
+{
+  const char *vendor;
+  const char *product;
+
+  vendor = hal_device_get_property_string (v->drive_device, "usb_device.vendor");
+  product = hal_device_get_property_string (v->drive_device, "usb_device.product");
+
+  if (vendor == NULL)
+    {
+      if (product != NULL)
+        v->name = g_strdup (product);
+      else
+        v->name = g_strdup (_("Camera"));
+    }
+  else
+    {
+      if (product != NULL)
+        v->name = g_strdup_printf ("%s %s", vendor, product);
+      else
+        v->name = g_strdup_printf (_("%s Camera"), vendor);
+    }
+
+  v->icon = g_strdup ("camera");
+  v->mount_path = NULL;
+}
+#endif
+
 static void
 update_from_hal (GHalVolume *mv, gboolean emit_changed)
 {
@@ -303,7 +333,14 @@
   g_free (mv->name);
   g_free (mv->icon);
   g_free (mv->mount_path);
-  do_update_from_hal (mv);
+#ifdef _WITH_GPHOTO2
+  if (hal_device_has_capability (mv->device, "camera"))
+    do_update_from_hal_for_camera (mv);
+  else
+    do_update_from_hal (mv);
+#else
+    do_update_from_hal (mv);
+#endif
 
   if (emit_changed)
     {
@@ -380,20 +417,53 @@
   GHalVolume *volume;
   HalDevice *drive_device;
   const char *storage_udi;
+  const char *device_path;
+      
+  if (hal_device_has_capability (device, "block"))
+    {
+      storage_udi = hal_device_get_property_string (device, "block.storage_device");
+      if (storage_udi == NULL)
+        return NULL;
       
-  storage_udi = hal_device_get_property_string (device, "block.storage_device");
-  if (storage_udi == NULL)
-    return NULL;
+      drive_device = hal_pool_get_device_by_udi (pool, storage_udi);
+      if (drive_device == NULL)
+        return NULL;
       
-  drive_device = hal_pool_get_device_by_udi (pool, storage_udi);
-  if (drive_device == NULL)
-    return NULL;
-  
+      device_path = hal_device_get_property_string (device, "block.device");
+    }
+#ifdef _WITH_GPHOTO2
+  else if (hal_device_has_capability (device, "camera"))
+    {
+      /* OK, so we abuse storage_udi and drive_device for the USB main
+       * device that holds this interface... 
+       */
+      storage_udi = hal_device_get_property_string (device, "info.parent");
+      if (storage_udi == NULL)
+        return NULL;
+      
+      drive_device = hal_pool_get_device_by_udi (pool, storage_udi);
+      if (drive_device == NULL)
+        return NULL;
+
+      /* TODO: other OS'es? Will address this with DK aka HAL 2.0 */
+      device_path = hal_device_get_property_string (drive_device, "linux.device_file");
+      if (strlen (device_path) == 0)
+        device_path = NULL;
+
+      if (foreign_mount_root == NULL)
+        return NULL;
+    }
+#endif
+  else
+    {
+      return NULL;
+    }
+
   volume = g_object_new (G_TYPE_HAL_VOLUME, NULL);
   volume->volume_monitor = volume_monitor;
   g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(volume->volume_monitor));
   volume->mount_path = NULL;
-  volume->device_path = g_strdup (hal_device_get_property_string (device, "block.device"));
+  volume->device_path = g_strdup (device_path);
   volume->device = g_object_ref (device);
   volume->drive_device = g_object_ref (drive_device);
   volume->foreign_mount_root = foreign_mount_root != NULL ? g_object_ref (foreign_mount_root) : NULL;

Modified: trunk/hal/ghalvolumemonitor.c
==============================================================================
--- trunk/hal/ghalvolumemonitor.c	(original)
+++ trunk/hal/ghalvolumemonitor.c	Fri Jan 18 08:06:39 2008
@@ -54,6 +54,7 @@
 
   HalPool *pool;
 
+  GList *last_camera_devices;;
   GList *last_optical_disc_devices;
   GList *last_drive_devices;
   GList *last_volume_devices;
@@ -67,6 +68,9 @@
   /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */
   GList *disc_volumes;
   GList *disc_mounts;
+
+  /* Digital cameras (e.g. gphoto2) are kept here */
+  GList *camera_volumes;
 };
 
 static void mountpoints_changed      (GUnixMountMonitor  *mount_monitor,
@@ -80,6 +84,7 @@
 static void update_volumes           (GHalVolumeMonitor *monitor);
 static void update_mounts            (GHalVolumeMonitor *monitor);
 static void update_discs             (GHalVolumeMonitor *monitor);
+static void update_cameras           (GHalVolumeMonitor *monitor);
 
 #define g_hal_volume_monitor_get_type g_hal_volume_monitor_get_type
 G_DEFINE_DYNAMIC_TYPE (GHalVolumeMonitor, g_hal_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR);
@@ -87,8 +92,10 @@
 static HalPool *
 get_hal_pool (void)
 {
+  char *cap_only[] = {"block", "camera", NULL};
+
   if (pool == NULL)
-    pool = hal_pool_new ("block");
+    pool = hal_pool_new (cap_only);
   
   return pool;
 }
@@ -109,6 +116,8 @@
   g_object_unref (monitor->mount_monitor);
   g_object_unref (monitor->pool);
 
+  g_list_foreach (monitor->last_camera_devices, (GFunc)g_object_unref, NULL);
+  g_list_free (monitor->last_optical_disc_devices);
   g_list_foreach (monitor->last_optical_disc_devices, (GFunc)g_object_unref, NULL);
   g_list_free (monitor->last_optical_disc_devices);
   g_list_foreach (monitor->last_drive_devices, (GFunc)g_object_unref, NULL);
@@ -131,6 +140,8 @@
   g_list_free (monitor->disc_volumes);
   g_list_foreach (monitor->disc_mounts, (GFunc)g_object_unref, NULL);
   g_list_free (monitor->disc_mounts);
+  g_list_foreach (monitor->camera_volumes, (GFunc)g_object_unref, NULL);
+  g_list_free (monitor->camera_volumes);
   
   if (G_OBJECT_CLASS (g_hal_volume_monitor_parent_class)->finalize)
     (*G_OBJECT_CLASS (g_hal_volume_monitor_parent_class)->finalize) (object);
@@ -164,6 +175,8 @@
   l = g_list_copy (monitor->volumes);
   ll = g_list_copy (monitor->disc_volumes);
   l = g_list_concat (l, ll);
+  ll = g_list_copy (monitor->camera_volumes);
+  l = g_list_concat (l, ll);
 
   g_list_foreach (l, (GFunc)g_object_ref, NULL);
 
@@ -306,6 +319,7 @@
   update_volumes (monitor);
   update_mounts (monitor);
   update_discs (monitor);
+  update_cameras (monitor);
 }
 
 static void
@@ -318,6 +332,7 @@
   update_volumes (monitor);
   update_mounts (monitor);
   update_discs (monitor);
+  update_cameras (monitor);
 }
 
 void 
@@ -327,6 +342,7 @@
   update_volumes (monitor);
   update_mounts (monitor);
   update_discs (monitor);
+  update_cameras (monitor);
 }
 
 static void
@@ -342,6 +358,7 @@
   update_volumes (monitor);
   update_mounts (monitor);
   update_discs (monitor);
+  update_cameras (monitor);
 }
 
 static GObject *
@@ -396,6 +413,7 @@
   update_volumes (monitor);
   update_mounts (monitor);
   update_discs (monitor);
+  update_cameras (monitor);
 
   the_volume_monitor = monitor;
 
@@ -651,6 +669,24 @@
   return NULL;
 }
 
+#ifdef _WITH_GPHOTO2
+static GHalVolume *
+find_camera_volume_by_udi (GHalVolumeMonitor *monitor, const char *udi)
+{
+  GList *l;
+
+  for (l = monitor->camera_volumes; l != NULL; l = l->next)
+    {
+      GHalVolume *volume = l->data;
+
+      if (g_hal_volume_has_udi (volume, udi))
+	return volume;
+    }
+  
+  return NULL;
+}
+#endif
+
 static gint
 hal_device_compare (HalDevice *a, HalDevice *b)
 {
@@ -1028,6 +1064,90 @@
   monitor->last_optical_disc_devices = new_optical_disc_devices;
 }
 
+static void
+update_cameras (GHalVolumeMonitor *monitor)
+{
+#ifdef _WITH_GPHOTO2
+  GList *new_camera_devices;
+  GList *removed, *added;
+  GList *l, *ll;
+  GHalVolume *volume;
+  const char *udi;
+
+  new_camera_devices = hal_pool_find_by_capability (monitor->pool, "camera");
+  for (l = new_camera_devices; l != NULL; l = ll)
+    {
+      ll = l->next;
+      HalDevice *d = l->data;
+      /*g_warning ("got %s", hal_device_get_udi (d));*/
+      if (! hal_device_get_property_bool (d, "camera.libgphoto2.support"))
+        {
+          /*g_warning ("ignoring %s", hal_device_get_udi (d));*/
+          /* filter out everything that isn't supported by libgphoto2 */
+          new_camera_devices = g_list_delete_link (new_camera_devices, l);
+        }
+    }
+  g_list_foreach (new_camera_devices, (GFunc) g_object_ref, NULL);
+
+  new_camera_devices = g_list_sort (new_camera_devices, (GCompareFunc) hal_device_compare);
+  diff_sorted_lists (monitor->last_camera_devices,
+                     new_camera_devices, (GCompareFunc) hal_device_compare,
+                     &added, &removed);
+
+  for (l = removed; l != NULL; l = l->next)
+    {
+      HalDevice *d = l->data;
+
+      udi = hal_device_get_udi (d);
+      /*g_warning ("camera removing %s", udi);*/
+
+      volume = find_camera_volume_by_udi (monitor, udi);
+      if (volume != NULL)
+        {
+	  g_hal_volume_removed (volume);
+	  monitor->camera_volumes = g_list_remove (monitor->camera_volumes, volume);
+	  g_signal_emit_by_name (monitor, "volume_removed", volume);
+	  g_signal_emit_by_name (volume, "removed");
+	  g_object_unref (volume);
+        }
+    }
+  
+  for (l = added; l != NULL; l = l->next)
+    {
+      HalDevice *d = l->data;
+      char *uri;
+      GFile *foreign_mount_root;
+      int usb_bus_num;
+      int usb_device_num;
+
+      usb_bus_num = hal_device_get_property_int (d, "usb.bus_number");
+      usb_device_num = hal_device_get_property_int (d, "usb.linux.device_number");
+
+      uri = g_strdup_printf ("gphoto2://usb:%03d,%03d", usb_bus_num, usb_device_num);
+      /*g_warning ("uri is '%s'", uri);*/
+      foreign_mount_root = g_file_new_for_uri (uri);
+      g_free (uri);
+
+      udi = hal_device_get_udi (d);
+      /*g_warning ("camera adding %s", udi);*/
+
+      volume = g_hal_volume_new (G_VOLUME_MONITOR (monitor), d, monitor->pool, foreign_mount_root, TRUE, NULL);
+      g_object_unref (foreign_mount_root);
+      if (volume != NULL)
+        {
+          monitor->camera_volumes = g_list_prepend (monitor->camera_volumes, volume);
+          g_signal_emit_by_name (monitor, "volume_added", volume);
+        }
+    }
+
+  g_list_free (added);
+  g_list_free (removed);
+  g_list_foreach (monitor->last_camera_devices, (GFunc)g_object_unref, NULL);
+  g_list_free (monitor->last_camera_devices);
+  monitor->last_camera_devices = new_camera_devices;
+#endif
+}
+
 void 
 g_hal_volume_monitor_register (GIOModule *module)
 {

Modified: trunk/hal/ghalvolumemonitor.h
==============================================================================
--- trunk/hal/ghalvolumemonitor.h	(original)
+++ trunk/hal/ghalvolumemonitor.h	Fri Jan 18 08:06:39 2008
@@ -29,6 +29,11 @@
 #include <gio/gio.h>
 #include <gio/gunixmounts.h>
 
+/* TODO: need to use different properties on HAL for other OS's (!) */
+#ifdef __linux__
+#define _WITH_GPHOTO2
+#endif
+
 G_BEGIN_DECLS
 
 #define G_TYPE_HAL_VOLUME_MONITOR        (g_hal_volume_monitor_get_type ())

Modified: trunk/hal/hal-pool.c
==============================================================================
--- trunk/hal/hal-pool.c	(original)
+++ trunk/hal/hal-pool.c	Fri Jan 18 08:06:39 2008
@@ -42,7 +42,7 @@
 
 struct _HalPoolPrivate
 {
-  char *cap_only;
+  char **cap_only;
   
   DBusConnection *dbus_connection;
   LibHalContext *hal_ctx;
@@ -54,7 +54,7 @@
 static void
 hal_pool_finalize (HalPool *pool)
 {
-  g_free (pool->priv->cap_only);
+  g_strfreev (pool->priv->cap_only);
 
   dbus_bus_remove_match (pool->priv->dbus_connection,
                          "type='signal',"
@@ -134,6 +134,25 @@
   pool->priv->hal_ctx = NULL;
 }
 
+static gboolean
+has_cap_only (HalPool *pool, HalDevice *device)
+{
+  unsigned int n;
+
+  if (pool->priv->cap_only)
+    return TRUE;
+
+  for (n = 0; pool->priv->cap_only[n] != NULL; n++)
+    {
+      if (hal_device_has_capability (device, pool->priv->cap_only[n]))
+        {
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
 static void
 hal_pool_add_device_by_udi (HalPool *pool, 
                             const char *udi, 
@@ -144,7 +163,7 @@
   
   if (device != NULL)
     {
-      if (pool->priv->cap_only != NULL && !hal_device_has_capability (device, pool->priv->cap_only))
+      if (!has_cap_only (pool, device))
         {
           g_object_unref (device);
         } 
@@ -169,7 +188,7 @@
   
   if (device != NULL)
     {
-      if (pool->priv->cap_only != NULL && !hal_device_has_capability (device, pool->priv->cap_only))
+      if (!has_cap_only (pool, device))
         {
           g_object_unref (device);
         } 
@@ -266,7 +285,7 @@
 }
 
 HalPool *
-hal_pool_new (const char *cap_only)
+hal_pool_new (char **cap_only)
 {
   int i;
   char **devices;
@@ -311,7 +330,7 @@
   pool->priv->dbus_connection = dbus_connection;
   pool->priv->hal_ctx = hal_ctx;
   pool->priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-  pool->priv->cap_only = g_strdup (cap_only);
+  pool->priv->cap_only = g_strdupv (cap_only);
   
   /* Gah, unfortunately we have to watch all devices as HAL's PropertyModified signal
    * doesn't include the capabilities...

Modified: trunk/hal/hal-pool.h
==============================================================================
--- trunk/hal/hal-pool.h	(original)
+++ trunk/hal/hal-pool.h	Fri Jan 18 08:06:39 2008
@@ -62,7 +62,7 @@
 
 GType            hal_pool_get_type                            (void);
 void             hal_pool_register                            (GIOModule    *module);
-HalPool *        hal_pool_new                                 (const char   *cap_only);
+HalPool *        hal_pool_new                                 (char        **cap_only);
 LibHalContext *  hal_pool_get_hal_ctx                         (HalPool      *pool);
 DBusConnection * hal_pool_get_dbus_connection                 (HalPool      *pool);
 HalDevice *      hal_pool_get_device_by_udi                   (HalPool      *pool, 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]