diff options
Diffstat (limited to 'monitor/gphoto2/ggphoto2volumemonitor.c')
-rw-r--r-- | monitor/gphoto2/ggphoto2volumemonitor.c | 564 |
1 files changed, 0 insertions, 564 deletions
diff --git a/monitor/gphoto2/ggphoto2volumemonitor.c b/monitor/gphoto2/ggphoto2volumemonitor.c deleted file mode 100644 index 5b8e8341..00000000 --- a/monitor/gphoto2/ggphoto2volumemonitor.c +++ /dev/null @@ -1,564 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* GIO - GLib Input, Output and Streaming Library - * - * Copyright (C) 2006-2007 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include <config.h> - -#include <limits.h> -#include <string.h> -#include <stdlib.h> - -#include <glib.h> -#include <glib/gi18n-lib.h> -#include <gio/gio.h> - -#include "ggphoto2volumemonitor.h" -#include "ggphoto2volume.h" - -#include "hal-pool.h" - -G_LOCK_DEFINE_STATIC(hal_vm); - -static GGPhoto2VolumeMonitor *the_volume_monitor = NULL; -static HalPool *pool = NULL; - -struct _GGPhoto2VolumeMonitor { - GNativeVolumeMonitor parent; - - GUnixMountMonitor *mount_monitor; - - HalPool *pool; - - GList *last_camera_devices; - - GList *camera_volumes; -}; - -static void hal_changed (HalPool *pool, - HalDevice *device, - gpointer user_data); - -static void update_all (GGPhoto2VolumeMonitor *monitor, - gboolean emit_changes); - -static void update_cameras (GGPhoto2VolumeMonitor *monitor, - GList **added_volumes, - GList **removed_volumes); - - -G_DEFINE_TYPE (GGPhoto2VolumeMonitor, g_gphoto2_volume_monitor, G_TYPE_VOLUME_MONITOR) - -static void -list_free (GList *objects) -{ - g_list_foreach (objects, (GFunc)g_object_unref, NULL); - g_list_free (objects); -} - -static HalPool * -get_hal_pool (void) -{ - char *cap_only[] = {"camera", "portable_audio_player", "usb_device", NULL}; - - if (pool == NULL) - pool = hal_pool_new (cap_only); - - return pool; -} - -static void -g_gphoto2_volume_monitor_dispose (GObject *object) -{ - GGPhoto2VolumeMonitor *monitor; - - monitor = G_GPHOTO2_VOLUME_MONITOR (object); - - G_LOCK (hal_vm); - the_volume_monitor = NULL; - G_UNLOCK (hal_vm); - - if (G_OBJECT_CLASS (g_gphoto2_volume_monitor_parent_class)->dispose) - (*G_OBJECT_CLASS (g_gphoto2_volume_monitor_parent_class)->dispose) (object); -} - -static void -g_gphoto2_volume_monitor_finalize (GObject *object) -{ - GGPhoto2VolumeMonitor *monitor; - - monitor = G_GPHOTO2_VOLUME_MONITOR (object); - - g_signal_handlers_disconnect_by_func (monitor->pool, hal_changed, monitor); - - g_object_unref (monitor->pool); - - list_free (monitor->last_camera_devices); - list_free (monitor->camera_volumes); - - if (G_OBJECT_CLASS (g_gphoto2_volume_monitor_parent_class)->finalize) - (*G_OBJECT_CLASS (g_gphoto2_volume_monitor_parent_class)->finalize) (object); -} - -static GList * -get_mounts (GVolumeMonitor *volume_monitor) -{ - return NULL; -} - -static GList * -get_volumes (GVolumeMonitor *volume_monitor) -{ - GGPhoto2VolumeMonitor *monitor; - GList *l; - - monitor = G_GPHOTO2_VOLUME_MONITOR (volume_monitor); - - G_LOCK (hal_vm); - - l = g_list_copy (monitor->camera_volumes); - g_list_foreach (l, (GFunc)g_object_ref, NULL); - - G_UNLOCK (hal_vm); - - return l; -} - -static GList * -get_connected_drives (GVolumeMonitor *volume_monitor) -{ - return NULL; -} - -static GVolume * -get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) -{ - return NULL; -} - -static GMount * -get_mount_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid) -{ - return NULL; -} - -static void -hal_changed (HalPool *pool, - HalDevice *device, - gpointer user_data) -{ - GGPhoto2VolumeMonitor *monitor = G_GPHOTO2_VOLUME_MONITOR (user_data); - - /*g_warning ("hal changed");*/ - - update_all (monitor, TRUE); -} - -static GObject * -g_gphoto2_volume_monitor_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GObject *object; - GGPhoto2VolumeMonitor *monitor; - GGPhoto2VolumeMonitorClass *klass; - GObjectClass *parent_class; - - G_LOCK (hal_vm); - if (the_volume_monitor != NULL) - { - object = g_object_ref (the_volume_monitor); - G_UNLOCK (hal_vm); - return object; - } - G_UNLOCK (hal_vm); - - /*g_warning ("creating hal vm");*/ - - object = NULL; - - /* Invoke parent constructor. */ - klass = G_GPHOTO2_VOLUME_MONITOR_CLASS (g_type_class_peek (G_TYPE_GPHOTO2_VOLUME_MONITOR)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - object = parent_class->constructor (type, - n_construct_properties, - construct_properties); - - monitor = G_GPHOTO2_VOLUME_MONITOR (object); - monitor->pool = g_object_ref (get_hal_pool ()); - - g_signal_connect (monitor->pool, - "device_added", G_CALLBACK (hal_changed), - monitor); - - g_signal_connect (monitor->pool, - "device_removed", G_CALLBACK (hal_changed), - monitor); - - update_all (monitor, FALSE); - - G_LOCK (hal_vm); - the_volume_monitor = monitor; - G_UNLOCK (hal_vm); - - return object; -} - -static void -g_gphoto2_volume_monitor_init (GGPhoto2VolumeMonitor *monitor) -{ -} - -static gboolean -is_supported (void) -{ - return get_hal_pool() != NULL; -} - -static GVolume * -adopt_orphan_mount (GMount *mount, GVolumeMonitor *monitor) -{ - GList *l; - GFile *mount_root; - GVolume *ret; - - /* This is called by the union volume monitor which does - have a ref to this. So its guaranteed to live, unfortunately - the pointer is not passed as an argument :/ - */ - ret = NULL; - - G_LOCK (hal_vm); - if (the_volume_monitor == NULL) - { - G_UNLOCK (hal_vm); - return NULL; - } - - mount_root = g_mount_get_root (mount); - - /* gphoto2:// are foreign mounts */ - for (l = the_volume_monitor->camera_volumes; l != NULL; l = l->next) - { - GGPhoto2Volume *volume = l->data; - - if (g_gphoto2_volume_has_foreign_mount_root (volume, mount_root)) - { - g_gphoto2_volume_adopt_foreign_mount (volume, mount); - ret = g_object_ref (volume); - goto found; - } - } - - found: - g_object_unref (mount_root); - - G_UNLOCK (hal_vm); - return ret; -} - -static void -g_gphoto2_volume_monitor_class_init (GGPhoto2VolumeMonitorClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GVolumeMonitorClass *monitor_class = G_VOLUME_MONITOR_CLASS (klass); - - gobject_class->constructor = g_gphoto2_volume_monitor_constructor; - gobject_class->finalize = g_gphoto2_volume_monitor_finalize; - gobject_class->dispose = g_gphoto2_volume_monitor_dispose; - - monitor_class->get_mounts = get_mounts; - monitor_class->get_volumes = get_volumes; - monitor_class->get_connected_drives = get_connected_drives; - monitor_class->get_volume_for_uuid = get_volume_for_uuid; - monitor_class->get_mount_for_uuid = get_mount_for_uuid; - monitor_class->adopt_orphan_mount = adopt_orphan_mount; - monitor_class->is_supported = is_supported; -} - -/** - * g_gphoto2_volume_monitor_new: - * - * Returns: a new #GVolumeMonitor. - **/ -GVolumeMonitor * -g_gphoto2_volume_monitor_new (void) -{ - GGPhoto2VolumeMonitor *monitor; - - monitor = g_object_new (G_TYPE_GPHOTO2_VOLUME_MONITOR, NULL); - - return G_VOLUME_MONITOR (monitor); -} - -static void -diff_sorted_lists (GList *list1, - GList *list2, - GCompareFunc compare, - GList **added, - GList **removed) -{ - int order; - - *added = *removed = NULL; - - while (list1 != NULL && - list2 != NULL) - { - order = (*compare) (list1->data, list2->data); - if (order < 0) - { - *removed = g_list_prepend (*removed, list1->data); - list1 = list1->next; - } - else if (order > 0) - { - *added = g_list_prepend (*added, list2->data); - list2 = list2->next; - } - else - { /* same item */ - list1 = list1->next; - list2 = list2->next; - } - } - - while (list1 != NULL) - { - *removed = g_list_prepend (*removed, list1->data); - list1 = list1->next; - } - while (list2 != NULL) - { - *added = g_list_prepend (*added, list2->data); - list2 = list2->next; - } -} - -static GGPhoto2Volume * -find_camera_volume_by_udi (GGPhoto2VolumeMonitor *monitor, const char *udi) -{ - GList *l; - - for (l = monitor->camera_volumes; l != NULL; l = l->next) - { - GGPhoto2Volume *volume = l->data; - - if (g_gphoto2_volume_has_udi (volume, udi)) - return volume; - } - - return NULL; -} - -static gint -hal_device_compare (HalDevice *a, HalDevice *b) -{ - return strcmp (hal_device_get_udi (a), hal_device_get_udi (b)); -} - -static void -list_emit (GGPhoto2VolumeMonitor *monitor, - const char *monitor_signal, - const char *object_signal, - GList *objects) -{ - GList *l; - - for (l = objects; l != NULL; l = l->next) - { - g_signal_emit_by_name (monitor, monitor_signal, l->data); - if (object_signal) - g_signal_emit_by_name (l->data, object_signal); - } -} - -typedef struct { - GGPhoto2VolumeMonitor *monitor; - GList *added_volumes, *removed_volumes; -} ChangedLists; - - -static gboolean -emit_lists_in_idle (gpointer data) -{ - ChangedLists *lists = data; - - list_emit (lists->monitor, - "volume_removed", "removed", - lists->removed_volumes); - list_emit (lists->monitor, - "volume_added", NULL, - lists->added_volumes); - - list_free (lists->removed_volumes); - list_free (lists->added_volumes); - g_object_unref (lists->monitor); - g_free (lists); - - return FALSE; -} - -/* Must be called from idle if emit_changes, with no locks held */ -static void -update_all (GGPhoto2VolumeMonitor *monitor, - gboolean emit_changes) -{ - ChangedLists *lists; - GList *added_volumes, *removed_volumes; - - added_volumes = NULL; - removed_volumes = NULL; - - G_LOCK (hal_vm); - update_cameras (monitor, &added_volumes, &removed_volumes); - G_UNLOCK (hal_vm); - - if (emit_changes) - { - lists = g_new0 (ChangedLists, 1); - lists->monitor = g_object_ref (monitor); - lists->added_volumes = added_volumes; - lists->removed_volumes = removed_volumes; - - g_idle_add (emit_lists_in_idle, lists); - } - else - { - list_free (removed_volumes); - list_free (added_volumes); - } -} - -static void -update_cameras (GGPhoto2VolumeMonitor *monitor, - GList **added_volumes, - GList **removed_volumes) -{ - GList *new_camera_devices; - GList *new_mtp_devices; - GList *removed, *added; - GList *l, *ll; - GGPhoto2Volume *volume; - const char *udi; - - new_mtp_devices = hal_pool_find_by_capability (monitor->pool, "portable_audio_player"); - for (l = new_mtp_devices; l != NULL; l = ll) - { - HalDevice *d = l->data; - ll = l->next; - 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_mtp_devices = g_list_delete_link (new_mtp_devices, l); - } - } - - new_camera_devices = hal_pool_find_by_capability (monitor->pool, "camera"); - new_camera_devices = g_list_concat (new_camera_devices, new_mtp_devices); - for (l = new_camera_devices; l != NULL; l = ll) - { - HalDevice *d = l->data; - ll = l->next; - /*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_gphoto2_volume_removed (volume); - monitor->camera_volumes = g_list_remove (monitor->camera_volumes, volume); - *removed_volumes = g_list_prepend (*removed_volumes, 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; - gboolean found; - - /* Look for the device in the added volumes, so as - * not to add devices that are both audio players, and cameras */ - found = FALSE; - for (ll = *added_volumes; ll; ll = ll->next) - { - if (g_gphoto2_volume_has_udi (ll->data, hal_device_get_udi (d)) != FALSE) - { - found = TRUE; - break; - } - } - - if (found) - continue; - - 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_gphoto2_volume_new (G_VOLUME_MONITOR (monitor), - d, - monitor->pool, - foreign_mount_root); - g_object_unref (foreign_mount_root); - if (volume != NULL) - { - monitor->camera_volumes = g_list_prepend (monitor->camera_volumes, volume); - *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume)); - } - } - - g_list_free (added); - g_list_free (removed); - list_free (monitor->last_camera_devices); - monitor->last_camera_devices = new_camera_devices; -} |