summaryrefslogtreecommitdiff
path: root/monitor/gphoto2/ggphoto2volumemonitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'monitor/gphoto2/ggphoto2volumemonitor.c')
-rw-r--r--monitor/gphoto2/ggphoto2volumemonitor.c564
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;
-}