Author: benny
Date: 2007-01-16 14:40:46 +0000 (Tue, 16 Jan 2007)
New Revision: 24507

Modified:
   thunar/trunk/ChangeLog
   thunar/trunk/thunar-vfs/thunar-vfs-volume-hal.c
   thunar/trunk/thunar-vfs/thunar-vfs-volume-private.h
   thunar/trunk/thunar-vfs/thunar-vfs-volume.c
   thunar/trunk/thunar/thunar-application.c
Log:
2007-01-16      Benedikt Meurer <[EMAIL PROTECTED]>

        * thunar-vfs/thunar-vfs-volume-hal.c, thunar-vfs/thunar-vfs-volume.c,
          thunar-vfs/thunar-vfs-volume-private.h, thunar/thunar-application.c:
          Allow to use "Eject" button on CD-ROM drives to unmount and eject
          the media. Bug #2759.




Modified: thunar/trunk/ChangeLog
===================================================================
--- thunar/trunk/ChangeLog      2007-01-16 14:36:20 UTC (rev 24506)
+++ thunar/trunk/ChangeLog      2007-01-16 14:40:46 UTC (rev 24507)
@@ -1,3 +1,10 @@
+2007-01-16     Benedikt Meurer <[EMAIL PROTECTED]>
+
+       * thunar-vfs/thunar-vfs-volume-hal.c, thunar-vfs/thunar-vfs-volume.c,
+         thunar-vfs/thunar-vfs-volume-private.h, thunar/thunar-application.c:
+         Allow to use "Eject" button on CD-ROM drives to unmount and eject
+         the media. Bug #2759.
+
 2007-01-15     Benedikt Meurer <[EMAIL PROTECTED]>
 
        * docs/manual/: Fix thunar-volman website URL.

Modified: thunar/trunk/thunar/thunar-application.c
===================================================================
--- thunar/trunk/thunar/thunar-application.c    2007-01-16 14:36:20 UTC (rev 
24506)
+++ thunar/trunk/thunar/thunar-application.c    2007-01-16 14:40:46 UTC (rev 
24507)
@@ -102,6 +102,9 @@
 static void       thunar_application_volman_device_removed  
(ThunarVfsVolumeManager *volume_manager,
                                                              const gchar       
     *udi,
                                                              ThunarApplication 
     *application);
+static void       thunar_application_volman_device_eject    
(ThunarVfsVolumeManager *volume_manager,
+                                                             const gchar       
     *udi,
+                                                             ThunarApplication 
     *application);
 static gboolean   thunar_application_volman_idle            (gpointer          
      user_data);
 static void       thunar_application_volman_idle_destroy    (gpointer          
      user_data);
 static void       thunar_application_volman_watch           (GPid              
      pid,
@@ -229,6 +232,7 @@
       /* connect the volume manager support callbacks (used to spawn 
thunar-volman appropriately) */
       g_signal_connect (G_OBJECT (application->volman), "device-added", 
G_CALLBACK (thunar_application_volman_device_added), application);
       g_signal_connect (G_OBJECT (application->volman), "device-removed", 
G_CALLBACK (thunar_application_volman_device_removed), application);
+      g_signal_connect (G_OBJECT (application->volman), "device-eject", 
G_CALLBACK (thunar_application_volman_device_eject), application);
     }
 }
 
@@ -590,6 +594,44 @@
 
 
 
+static void
+thunar_application_volman_device_eject (ThunarVfsVolumeManager *volume_manager,
+                                        const gchar            *udi,
+                                        ThunarApplication      *application)
+{
+  GdkScreen *screen;
+  GError    *err = NULL;
+  gchar     *argv[4];
+
+  _thunar_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER (volume_manager));
+  _thunar_return_if_fail (application->volman == volume_manager);
+  _thunar_return_if_fail (THUNAR_IS_APPLICATION (application));
+
+  /* generate the argument list for exo-eject */
+  argv[0] = (gchar *) "exo-eject";
+  argv[1] = (gchar *) "-h";
+  argv[2] = (gchar *) udi;
+  argv[3] = NULL;
+
+  /* locate the currently active screen (the one with the pointer) */
+  screen = thunar_gdk_screen_get_active ();
+
+  /* try to spawn the volman on the active screen */
+  if (!gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, 
NULL, NULL, NULL, &err))
+    {
+      /* failed to launch exo-eject, inform the user about this */
+      thunar_dialogs_show_error (screen, err, _("Failed to execute \"%s\""), 
"exo-eject");
+      g_error_free (err);
+    }
+  else
+    {
+      /* we most probably removed the device */
+      thunar_application_volman_device_removed (volume_manager, udi, 
application);
+    }
+}
+
+
+
 static gboolean
 thunar_application_volman_idle (gpointer user_data)
 {

Modified: thunar/trunk/thunar-vfs/thunar-vfs-volume-hal.c
===================================================================
--- thunar/trunk/thunar-vfs/thunar-vfs-volume-hal.c     2007-01-16 14:36:20 UTC 
(rev 24506)
+++ thunar/trunk/thunar-vfs/thunar-vfs-volume-hal.c     2007-01-16 14:40:46 UTC 
(rev 24507)
@@ -22,9 +22,15 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
 
 #include <dbus/dbus-glib-lowlevel.h>
 
@@ -33,6 +39,7 @@
 #include <exo-hal/exo-hal.h>
 
 #include <thunar-vfs/thunar-vfs-exec.h>
+#include <thunar-vfs/thunar-vfs-marshal.h>
 #include <thunar-vfs/thunar-vfs-private.h>
 #include <thunar-vfs/thunar-vfs-volume-hal.h>
 #include <thunar-vfs/thunar-vfs-volume-private.h>
@@ -609,6 +616,10 @@
                                                                                
    const gchar                    *key,
                                                                                
    dbus_bool_t                     is_removed,
                                                                                
    dbus_bool_t                     is_added);
+static void                thunar_vfs_volume_manager_hal_device_condition      
   (LibHalContext                  *context,
+                                                                               
    const gchar                    *udi,
+                                                                               
    const gchar                    *name,
+                                                                               
    const gchar                    *details);
 
 
 
@@ -701,6 +712,27 @@
                 g_cclosure_marshal_VOID__STRING,
                 G_TYPE_NONE, 1, G_TYPE_STRING);
 
+  /**
+   * ThunarVfsVolumeManagerHal::device-eject:
+   * @manager_hal : a #ThunarVfsVolumeManagerlHal instance.
+   * @udi         : the UDI of the device.
+   *
+   * Emitted by @manager_hal to let Thunar know that the "Eject"
+   * button was pressed on the device with the @udi.
+   *
+   * This signal is used by Thunar to support volume management.
+   * Since it's special to the HAL backend, no other application
+   * must use this signal, especially no application must assume
+   * that the signal is available on any given #ThunarVfsVolumeManager.
+   **/
+  g_signal_new (I_("device-eject"),
+                G_TYPE_FROM_CLASS (klass),
+                G_SIGNAL_RUN_LAST,
+                0, NULL, NULL,
+                g_cclosure_marshal_VOID__STRING,
+                G_TYPE_NONE, 1,
+                G_TYPE_STRING);
+
   /* initialize exo-hal support */
   if (!exo_hal_init ())
     {
@@ -747,6 +779,7 @@
   libhal_ctx_set_device_new_capability (manager_hal->context, 
thunar_vfs_volume_manager_hal_device_new_capability);
   libhal_ctx_set_device_lost_capability (manager_hal->context, 
thunar_vfs_volume_manager_hal_device_lost_capability);
   libhal_ctx_set_device_property_modified (manager_hal->context, 
thunar_vfs_volume_manager_hal_device_property_modified);
+  libhal_ctx_set_device_condition (manager_hal->context, 
thunar_vfs_volume_manager_hal_device_condition);
 
   /* try to initialize the HAL context */
   if (!libhal_ctx_init (manager_hal->context, &error))
@@ -1105,5 +1138,75 @@
 
 
 
+static void
+thunar_vfs_volume_manager_hal_device_condition (LibHalContext *context,
+                                                const gchar   *udi,
+                                                const gchar   *name,
+                                                const gchar   *details)
+{
+  ThunarVfsVolumeManagerHal *manager_hal = libhal_ctx_get_user_data (context);
+  ThunarVfsVolumeHal        *volume_hal;
+  DBusError                  derror;
+  GList                     *volumes = NULL;
+  GList                     *lp;
+  gchar                    **volume_udis;
+  gint                       n_volume_udis;
+  gint                       n;
+
+  _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME_MANAGER_HAL (manager_hal));
+  _thunar_vfs_return_if_fail (manager_hal->context == context);
+
+  /* check if the device should be ejected */
+  if (G_LIKELY (strcmp (name, "EjectPressed") == 0))
+    {
+      /* check if we have a volume for the device */
+      volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi 
(manager_hal, udi);
+      if (G_LIKELY (volume_hal == NULL))
+        {
+          /* initialize D-Bus error */
+          dbus_error_init (&derror);
+
+          /* the UDI most probably identifies the drive of the volume */
+          volume_udis = libhal_manager_find_device_string_match (context, 
"info.parent", udi, &n_volume_udis, &derror);
+          if (G_LIKELY (volume_udis != NULL))
+            {
+              /* determine the volumes for the UDIs */
+              for (n = 0; n < n_volume_udis; ++n)
+                {
+                  /* check if we have a mounted volume for this UDI */
+                  volume_hal = thunar_vfs_volume_manager_hal_get_volume_by_udi 
(manager_hal, volume_udis[n]);
+                  if (thunar_vfs_volume_is_mounted (THUNAR_VFS_VOLUME 
(volume_hal)))
+                    volumes = g_list_prepend (volumes, g_object_ref (G_OBJECT 
(volume_hal)));
+                }
+              libhal_free_string_array (volume_udis);
+            }
+
+          /* free D-Bus error */
+          dbus_error_free (&derror);
+        }
+      else if (thunar_vfs_volume_is_mounted (THUNAR_VFS_VOLUME (volume_hal)))
+        {
+          volumes = g_list_prepend (volumes, g_object_ref (G_OBJECT 
(volume_hal)));
+        }
+
+      /* check there are any mounted volumes on the device */
+      if (G_LIKELY (volumes != NULL))
+        {
+          /* tell everybody, that we're about to unmount those volumes */
+          for (lp = volumes; lp != NULL; lp = lp->next)
+            {
+              thunar_vfs_volume_pre_unmount (lp->data);
+              g_object_unref (G_OBJECT (lp->data));
+            }
+          g_list_free (volumes);
+
+          /* emit the "device-eject" signal and let Thunar eject the device */
+          g_signal_emit_by_name (G_OBJECT (manager_hal), "device-eject", udi);
+        }
+    }
+}
+
+
+
 #define __THUNAR_VFS_VOLUME_HAL_C__
 #include <thunar-vfs/thunar-vfs-aliasdef.c>

Modified: thunar/trunk/thunar-vfs/thunar-vfs-volume-private.h
===================================================================
--- thunar/trunk/thunar-vfs/thunar-vfs-volume-private.h 2007-01-16 14:36:20 UTC 
(rev 24506)
+++ thunar/trunk/thunar-vfs/thunar-vfs-volume-private.h 2007-01-16 14:40:46 UTC 
(rev 24507)
@@ -63,7 +63,8 @@
   GObject __parent__;
 };
 
-void thunar_vfs_volume_changed (ThunarVfsVolume *volume) G_GNUC_INTERNAL;
+void thunar_vfs_volume_changed     (ThunarVfsVolume *volume) G_GNUC_INTERNAL;
+void thunar_vfs_volume_pre_unmount (ThunarVfsVolume *volume) G_GNUC_INTERNAL;
 
 
 struct _ThunarVfsVolumeManagerClass

Modified: thunar/trunk/thunar-vfs/thunar-vfs-volume.c
===================================================================
--- thunar/trunk/thunar-vfs/thunar-vfs-volume.c 2007-01-16 14:36:20 UTC (rev 
24506)
+++ thunar/trunk/thunar-vfs/thunar-vfs-volume.c 2007-01-16 14:40:46 UTC (rev 
24507)
@@ -504,7 +504,7 @@
   g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE);
 
   /* we're about to unmount (and eject) the volume */
-  g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0);
+  thunar_vfs_volume_pre_unmount (volume);
 
   /* setup a watch cursor on the window */
   if (window != NULL && GTK_WIDGET_REALIZED (window))
@@ -631,7 +631,7 @@
   g_return_val_if_fail (window == NULL || GTK_IS_WINDOW (window), FALSE);
 
   /* we're about to unmount the volume */
-  g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0);
+  thunar_vfs_volume_pre_unmount (volume);
 
   /* setup a watch cursor on the window */
   if (window != NULL && GTK_WIDGET_REALIZED (window))
@@ -672,7 +672,9 @@
 void
 thunar_vfs_volume_changed (ThunarVfsVolume *volume)
 {
-  g_return_if_fail (THUNAR_VFS_IS_VOLUME (volume));
+  _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME (volume));
+
+  /* emit the "changed" signal */
   g_signal_emit (G_OBJECT (volume), volume_signals[CHANGED], 0);
 
   /* rescan the mount points for the trash subsystem,
@@ -683,6 +685,22 @@
 
 
 
+/**
+ * thunar_vfs_volume_pre_unmount:
+ * @volume :a #ThunarVfsVolume instance.
+ *
+ * Emits the "pre-unmount" signal on the @volume. This function
+ * should only be used by implementations of the #ThunarVfsVolume
+ * interface.
+ **/
+void
+thunar_vfs_volume_pre_unmount (ThunarVfsVolume *volume)
+{
+  _thunar_vfs_return_if_fail (THUNAR_VFS_IS_VOLUME (volume));
+  g_signal_emit (G_OBJECT (volume), volume_signals[PRE_UNMOUNT], 0);
+}
 
+
+
 #define __THUNAR_VFS_VOLUME_C__
 #include <thunar-vfs/thunar-vfs-aliasdef.c>

_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to