diff options
author | David Zeuthen <davidz@redhat.com> | 2008-01-18 08:06:39 +0000 |
---|---|---|
committer | David Zeuthen <davidz@src.gnome.org> | 2008-01-18 08:06:39 +0000 |
commit | 71500d8d36e2157397d275110c34bbe0d658f1e1 (patch) | |
tree | 1ce473cc30ae59237e4b802f39d7cedc5a6e52e6 | |
parent | 45aaa4ee822956140f3acabc548792f389e584b3 (diff) | |
download | gvfs-71500d8d36e2157397d275110c34bbe0d658f1e1.tar.gz |
The volume monitor bits of gphoto2 support. The actual backend will follow
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:
svn path=/trunk/; revision=1148
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | hal/ghalvolume.c | 88 | ||||
-rw-r--r-- | hal/ghalvolumemonitor.c | 122 | ||||
-rw-r--r-- | hal/ghalvolumemonitor.h | 5 | ||||
-rw-r--r-- | hal/hal-pool.c | 31 | ||||
-rw-r--r-- | hal/hal-pool.h | 2 |
6 files changed, 251 insertions, 17 deletions
@@ -1,3 +1,23 @@ +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: + 2008-01-17 Christian Kellner <gicmo@gnome.org> * daemon/gvfsbackenddav.c: diff --git a/hal/ghalvolume.c b/hal/ghalvolume.c index 6705b376..48a886d2 100644 --- a/hal/ghalvolume.c +++ b/hal/ghalvolume.c @@ -289,6 +289,36 @@ do_update_from_hal (GHalVolume *mv) (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 @@ update_from_hal (GHalVolume *mv, gboolean emit_changed) 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 @@ g_hal_volume_new (GVolumeMonitor *volume_monitor, 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; diff --git a/hal/ghalvolumemonitor.c b/hal/ghalvolumemonitor.c index ad831779..86abb284 100644 --- a/hal/ghalvolumemonitor.c +++ b/hal/ghalvolumemonitor.c @@ -54,6 +54,7 @@ struct _GHalVolumeMonitor { HalPool *pool; + GList *last_camera_devices;; GList *last_optical_disc_devices; GList *last_drive_devices; GList *last_volume_devices; @@ -67,6 +68,9 @@ struct _GHalVolumeMonitor { /* 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_drives (GHalVolumeMonitor *monitor); 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 @@ G_DEFINE_DYNAMIC_TYPE (GHalVolumeMonitor, g_hal_volume_monitor, G_TYPE_NATIVE_VO 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_hal_volume_monitor_finalize (GObject *object) 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_hal_volume_monitor_finalize (GObject *object) 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 @@ get_volumes (GVolumeMonitor *volume_monitor) 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 @@ mountpoints_changed (GUnixMountMonitor *mount_monitor, update_volumes (monitor); update_mounts (monitor); update_discs (monitor); + update_cameras (monitor); } static void @@ -318,6 +332,7 @@ mounts_changed (GUnixMountMonitor *mount_monitor, update_volumes (monitor); update_mounts (monitor); update_discs (monitor); + update_cameras (monitor); } void @@ -327,6 +342,7 @@ g_hal_volume_monitor_force_update (GHalVolumeMonitor *monitor) update_volumes (monitor); update_mounts (monitor); update_discs (monitor); + update_cameras (monitor); } static void @@ -342,6 +358,7 @@ hal_changed (HalPool *pool, update_volumes (monitor); update_mounts (monitor); update_discs (monitor); + update_cameras (monitor); } static GObject * @@ -396,6 +413,7 @@ g_hal_volume_monitor_constructor (GType type, update_volumes (monitor); update_mounts (monitor); update_discs (monitor); + update_cameras (monitor); the_volume_monitor = monitor; @@ -651,6 +669,24 @@ find_disc_volume_by_udi (GHalVolumeMonitor *monitor, const char *udi) 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 @@ update_discs (GHalVolumeMonitor *monitor) 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) { diff --git a/hal/ghalvolumemonitor.h b/hal/ghalvolumemonitor.h index 0ec355df..31c39ab8 100644 --- a/hal/ghalvolumemonitor.h +++ b/hal/ghalvolumemonitor.h @@ -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 ()) diff --git a/hal/hal-pool.c b/hal/hal-pool.c index 91e91291..3a19daa0 100644 --- a/hal/hal-pool.c +++ b/hal/hal-pool.c @@ -42,7 +42,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; struct _HalPoolPrivate { - char *cap_only; + char **cap_only; DBusConnection *dbus_connection; LibHalContext *hal_ctx; @@ -54,7 +54,7 @@ G_DEFINE_DYNAMIC_TYPE (HalPool, hal_pool, G_TYPE_OBJECT); 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 @@ hal_pool_init (HalPool *pool) 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 @@ hal_pool_add_device_by_udi (HalPool *pool, 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 @@ hal_pool_add_device_by_udi_and_properties (HalPool *pool, 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 @@ hal_pool_get_dbus_connection (HalPool *pool) } HalPool * -hal_pool_new (const char *cap_only) +hal_pool_new (char **cap_only) { int i; char **devices; @@ -311,7 +330,7 @@ hal_pool_new (const char *cap_only) 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... diff --git a/hal/hal-pool.h b/hal/hal-pool.h index 0b441f36..1a84793d 100644 --- a/hal/hal-pool.h +++ b/hal/hal-pool.h @@ -62,7 +62,7 @@ struct _HalPoolClass 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, |