예제 #1
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_eject_with_operation:
 * @volume: a #GVolume
 * @flags: flags affecting the unmount if required for eject
 * @mount_operation: (allow-none): a #GMountOperation or %NULL to
 *     avoid user interaction
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
 * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL
 * @user_data: user data passed to @callback
 *
 * Ejects a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_eject_with_operation_finish() with the @volume
 * and #GAsyncResult data returned in the @callback.
 *
 * Since: 2.22
 **/
void
g_volume_eject_with_operation (GVolume              *volume,
                               GMountUnmountFlags   flags,
                               GMountOperation     *mount_operation,
                               GCancellable        *cancellable,
                               GAsyncReadyCallback  callback,
                               gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->eject == NULL && iface->eject_with_operation == NULL)
    {
      g_task_report_new_error (volume, callback, user_data,
                               g_volume_eject_with_operation,
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                               /* Translators: This is an error
                                * message for volume objects that
                                * don't implement any of eject or eject_with_operation. */
                               _("volume doesn't implement eject or eject_with_operation"));
      return;
    }

  if (iface->eject_with_operation != NULL)
    (* iface->eject_with_operation) (volume, flags, mount_operation, cancellable, callback, user_data);
  else
    (* iface->eject) (volume, flags, cancellable, callback, user_data);
}
예제 #2
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_mount:
 * @volume: a #GVolume
 * @flags: flags affecting the operation
 * @mount_operation: (allow-none): a #GMountOperation or %NULL to avoid user interaction
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
 * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL
 * @user_data: user data that gets passed to @callback
 * 
 * Mounts a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_mount_finish() with the @volume
 * and #GAsyncResult returned in the @callback.
 *
 * Virtual: mount_fn
 */
void
g_volume_mount (GVolume             *volume,
		GMountMountFlags     flags,
                GMountOperation     *mount_operation,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->mount_fn == NULL)
    {
      g_task_report_new_error (volume, callback, user_data,
                               g_volume_mount,
                               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                               _("volume doesn't implement mount"));
      return;
    }
  
  (* iface->mount_fn) (volume, flags, mount_operation, cancellable, callback, user_data);
}
static void
xfdesktop_volume_icon_changed(GVolume *volume,
                              XfdesktopVolumeIcon *volume_icon)
{
    g_return_if_fail(G_IS_VOLUME(volume));
    g_return_if_fail(XFDESKTOP_IS_VOLUME_ICON(volume_icon));

    DBG("VOLUME CHANGED");

    /**
     * NOTE: We use a timeout here to check if the volume is 
     * now mounted (or has been unmounted). This timeout seems
     * to be needed because when the "changed" signal is emitted,
     * the GMount is always NULL. In a 500ms timeout we check
     * at most 5 times for a valid mount until we give up. This
     * hopefully is a suitable workaround for most machines and
     * drives. 
     */

    /* abort an existing timeout, we may have to run it a few times
     * once again for the new event */
    if(volume_icon->priv->changed_timeout_id > 0) {
        g_source_remove(volume_icon->priv->changed_timeout_id);
        volume_icon->priv->changed_timeout_id = 0;
    }

    /* reset timeout information and start a timeout */
    volume_icon->priv->changed_timeout_count = 0;
    volume_icon->priv->changed_timeout_id =
        g_timeout_add_full(G_PRIORITY_LOW, 500, 
                           (GSourceFunc) volume_icon_changed_timeout, 
                           g_object_ref(volume_icon),
                           g_object_unref);
}
예제 #4
0
static void
eject_cb (GObject *object, GAsyncResult *result, gpointer nothing)
{
	GError *error = NULL;

	if (G_IS_VOLUME (object)) {
		GVolume *volume = G_VOLUME (object);

		rb_debug ("finishing ejection of volume");
		g_volume_eject_with_operation_finish (volume, result, &error);
	} else if (G_IS_MOUNT (object)) {
		GMount *mount = G_MOUNT (object);

		rb_debug ("finishing ejection of mount");
		g_mount_eject_with_operation_finish (mount, result, &error);
	}

	if (error != NULL) {
		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
			rb_error_dialog (NULL, _("Unable to eject"), "%s", error->message);
		} else {
			rb_debug ("eject failure has already been handled");
		}
		g_error_free (error);
	}
}
예제 #5
0
char *
rb_gvolume_get_udi (GVolume *volume, gpointer ctx)
{
	char *udi, *dev, **udis;
	int num_udis;

	g_return_val_if_fail (volume != NULL, NULL);
	g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
	g_return_val_if_fail (ctx != NULL, NULL);

	udi = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
	if (udi != NULL)
		return udi;

	dev = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
	udis = libhal_manager_find_device_string_match ((LibHalContext *) ctx,
							"block.device", dev,
							&num_udis, NULL);

	if (udis == NULL || num_udis < 1) {
		libhal_free_string_array (udis);
		return NULL;
	}

	udi = g_strdup (udis[0]);
	libhal_free_string_array (udis);

	return udi;
}
예제 #6
0
static void
rb_removable_media_manager_eject_cb (GObject *object,
				     GAsyncResult *result,
				     RBRemovableMediaManager *mgr)
{
	GError *error = NULL;

	if (G_IS_VOLUME (object)) {
		GVolume *volume = G_VOLUME (object);

		rb_debug ("finishing ejection of volume");
		g_volume_eject_finish (volume, result, &error);
		if (error == NULL) {
			rb_removable_media_manager_remove_volume (mgr, volume);
		}
	} else if (G_IS_MOUNT (object)) {
		GMount *mount = G_MOUNT (object);

		rb_debug ("finishing ejection of mount");
		g_mount_eject_finish (mount, result, &error);
		if (error == NULL) {
			rb_removable_media_manager_remove_mount (mgr, mount);
		}
	}

	if (error != NULL) {
		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) {
			rb_error_dialog (NULL, _("Unable to eject"), "%s", error->message);
		} else {
			rb_debug ("eject failure has already been handled");
		}
		g_error_free (error);
	}
	g_object_unref (mgr);
}
예제 #7
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_drive:
 * @volume: a #GVolume
 * 
 * Gets the drive for the @volume.
 * 
 * Returns: (transfer full): a #GDrive or %NULL if @volume is not
 *     associated with a drive. The returned object should be unreffed
 *     with g_object_unref() when no longer needed.
 */
GDrive *
g_volume_get_drive (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_drive) (volume);
}
예제 #8
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_mount:
 * @volume: a #GVolume
 * 
 * Gets the mount for the @volume.
 * 
 * Returns: (transfer full): a #GMount or %NULL if @volume isn't mounted.
 *     The returned object should be unreffed with g_object_unref()
 *     when no longer needed.
 */
GMount *
g_volume_get_mount (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  return (* iface->get_mount) (volume);
}
예제 #9
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_activation_root:
 * @volume: a #GVolume
 *
 * Gets the activation root for a #GVolume if it is known ahead of
 * mount time. Returns %NULL otherwise. If not %NULL and if @volume
 * is mounted, then the result of g_mount_get_root() on the
 * #GMount object obtained from g_volume_get_mount() will always
 * either be equal or a prefix of what this function returns. In
 * other words, in code
 *
 * |[<!-- language="C" -->
 *   GMount *mount;
 *   GFile *mount_root
 *   GFile *volume_activation_root;
 *
 *   mount = g_volume_get_mount (volume); /&ast; mounted, so never NULL &ast;/
 *   mount_root = g_mount_get_root (mount);
 *   volume_activation_root = g_volume_get_activation_root (volume); /&ast; assume not NULL &ast;/
 * ]|
 * then the expression
 * |[<!-- language="C" -->
 *   (g_file_has_prefix (volume_activation_root, mount_root) ||
      g_file_equal (volume_activation_root, mount_root))
 * ]|
 * will always be %TRUE.
 *
 * Activation roots are typically used in #GVolumeMonitor
 * implementations to find the underlying mount to shadow, see
 * g_mount_is_shadowed() for more details.
 *
 * Returns: (transfer full): the activation root of @volume or %NULL. Use
 *     g_object_unref() to free.
 *
 * Since: 2.18
 */
GFile *
g_volume_get_activation_root (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_activation_root == NULL)
    return NULL;

  return (* iface->get_activation_root) (volume);
}
예제 #10
0
void
thunar_notify_eject_finish (GVolume *volume)
{
  NotifyNotification *notification;

  g_return_if_fail (G_IS_VOLUME (volume));

  notification = g_object_get_data (G_OBJECT (volume), "thunar-notification");
  if (notification != NULL)
    {
      notify_notification_close (notification, NULL);
      g_object_set_data (G_OBJECT (volume), "thunar-notification", NULL);
    }
}
예제 #11
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_sort_key:
 * @volume: a #GVolume
 *
 * Gets the sort key for @volume, if any.
 *
 * Returns: Sorting key for @volume or %NULL if no such key is available
 *
 * Since: 2.32
 */
const gchar *
g_volume_get_sort_key (GVolume *volume)
{
  const gchar *ret = NULL;
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);
  if (iface->get_sort_key != NULL)
    ret = iface->get_sort_key (volume);

  return ret;
}
예제 #12
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_should_automount:
 * @volume: a #GVolume
 *
 * Returns whether the volume should be automatically mounted.
 * 
 * Returns: %TRUE if the volume should be automatically mounted
 */
gboolean
g_volume_should_automount (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->should_automount == NULL)
    return FALSE;

  return (* iface->should_automount) (volume);
}
예제 #13
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_can_eject:
 * @volume: a #GVolume
 * 
 * Checks if a volume can be ejected.
 * 
 * Returns: %TRUE if the @volume can be ejected. %FALSE otherwise
 */
gboolean
g_volume_can_eject (GVolume *volume)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->can_eject == NULL)
    return FALSE;

  return (* iface->can_eject) (volume);
}
예제 #14
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_identifier:
 * @volume: a #GVolume
 * @kind: the kind of identifier to return
 *
 * Gets the identifier of the given kind for @volume. 
 * See the <link linkend="volume-identifier">introduction</link>
 * for more information about volume identifiers.
 *
 * Returns: a newly allocated string containing the
 *     requested identfier, or %NULL if the #GVolume
 *     doesn't have this kind of identifier
 */
char *
g_volume_get_identifier (GVolume    *volume,
			 const char *kind)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);
  g_return_val_if_fail (kind != NULL, NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_identifier == NULL)
    return NULL;
  
  return (* iface->get_identifier) (volume, kind);
}
예제 #15
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_get_symbolic_icon:
 * @volume: a #GVolume
 * 
 * Gets the symbolic icon for @volume.
 * 
 * Returns: (transfer full): a #GIcon.
 *     The returned object should be unreffed with g_object_unref()
 *     when no longer needed.
 *
 * Since: 2.34
 */
GIcon *
g_volume_get_symbolic_icon (GVolume *volume)
{
  GVolumeIface *iface;
  GIcon *ret;

  g_return_val_if_fail (G_IS_VOLUME (volume), NULL);

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->get_symbolic_icon != NULL)
    ret = iface->get_symbolic_icon (volume);
  else
    ret = g_themed_icon_new_with_default_fallbacks ("folder-remote-symbolic");

  return ret;

}
예제 #16
0
파일: gvolume.c 프로젝트: patito/glib
/**
 * g_volume_eject_finish:
 * @volume: pointer to a #GVolume
 * @result: a #GAsyncResult
 * @error: a #GError location to store an error, or %NULL to ignore
 * 
 * Finishes ejecting a volume. If any errors occurred during the operation,
 * @error will be set to contain the errors and %FALSE will be returned.
 * 
 * Returns: %TRUE, %FALSE if operation failed
 *
 * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead.
 **/
gboolean
g_volume_eject_finish (GVolume       *volume,
                       GAsyncResult  *result,
                       GError       **error)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (g_async_result_legacy_propagate_error (result, error))
    return FALSE;
  if (g_async_result_is_tagged (result, g_volume_eject_with_operation))
    return g_task_propagate_boolean (G_TASK (result), error);
  
  iface = G_VOLUME_GET_IFACE (volume);
  return (* iface->eject_finish) (volume, result, error);
}
static void
xfdesktop_volume_icon_eject_finish(GObject *object,
                                   GAsyncResult *result,
                                   gpointer user_data)
{
    XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(user_data);
    GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(icon));
    GtkWidget *toplevel = icon_view ? gtk_widget_get_toplevel(icon_view) : NULL;
    GVolume *volume = G_VOLUME(object);
    GError *error = NULL;
    gboolean eject_successful;
      
    g_return_if_fail(G_IS_VOLUME(object));
    g_return_if_fail(G_IS_ASYNC_RESULT(result));
    g_return_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon));

    eject_successful = g_volume_eject_with_operation_finish(volume, result, &error);

    if(!eject_successful) {
        /* ignore GIO errors handled internally */
        if(error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
            gchar *volume_name = g_volume_get_name(volume);
            gchar *primary = g_markup_printf_escaped(_("Failed to eject \"%s\""), 
                                                     volume_name);

            /* display an error dialog to inform the user */
            xfce_message_dialog(toplevel ? GTK_WINDOW(toplevel) : NULL,
                                _("Eject Failed"), GTK_STOCK_DIALOG_ERROR, 
                                primary, error->message,
                                GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);

            g_free(primary);
            g_free(volume_name);
        }

        g_error_free(error);
    }

#ifdef HAVE_LIBNOTIFY
    xfdesktop_notify_eject_finish(volume, eject_successful);
#endif

    g_object_unref(icon);
}
예제 #18
0
/**
 * g_volume_eject_finish:
 * @volume: pointer to a #GVolume.
 * @result: a #GAsyncResult.
 * @error: a #GError location to store an error, or %NULL to ignore
 * 
 * Finishes ejecting a volume. If any errors occurred during the operation,
 * @error will be set to contain the errors and %FALSE will be returned.
 * 
 * Returns: %TRUE, %FALSE if operation failed.
 *
 * Deprecated: 2.22: Use g_volume_eject_with_operation_finish() instead.
 **/
gboolean
g_volume_eject_finish (GVolume       *volume,
                       GAsyncResult  *result,
                       GError       **error)
{
  GVolumeIface *iface;

  g_return_val_if_fail (G_IS_VOLUME (volume), FALSE);
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);

  if (G_IS_SIMPLE_ASYNC_RESULT (result))
    {
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
      if (g_simple_async_result_propagate_error (simple, error))
	return FALSE;
    }
  
  iface = G_VOLUME_GET_IFACE (volume);
  return (* iface->eject_finish) (volume, result, error);
}
static void
cmd_duplicate_cd (GtkAction         	*action,
		  RBDiscRecorderPlugin	*pi)
{
	gchar *device;
	GVolume *volume;

	if (!pi->selected_source)
		return;

	g_object_get (pi->selected_source, "volume", &volume, NULL);
	if (G_IS_VOLUME (volume))
		device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
	else
		device = NULL;

	g_object_unref (volume);

	rb_disc_recorder_plugin_start_burning (pi, device, TRUE);
	g_free (device);
}
XfdesktopVolumeIcon *
xfdesktop_volume_icon_new(GVolume *volume,
                          GdkScreen *screen)
{
    XfdesktopVolumeIcon *volume_icon;
    GMount *mount;
    
    g_return_val_if_fail(G_IS_VOLUME(volume), NULL);
    
    volume_icon = g_object_new(XFDESKTOP_TYPE_VOLUME_ICON, NULL);
    volume_icon->priv->volume = g_object_ref(G_OBJECT(volume));
    volume_icon->priv->gscreen = screen;

    mount = g_volume_get_mount(volume);
    if(mount) {
        volume_icon->priv->file = g_mount_get_root(mount);
        volume_icon->priv->file_info = g_file_query_info(volume_icon->priv->file,
                                                         XFDESKTOP_FILE_INFO_NAMESPACE,
                                                         G_FILE_QUERY_INFO_NONE,
                                                         NULL, NULL);
        volume_icon->priv->filesystem_info = g_file_query_filesystem_info(volume_icon->priv->file,
                                                                          XFDESKTOP_FILESYSTEM_INFO_NAMESPACE,
                                                                          NULL, NULL);
        g_object_unref(mount);
    }

    g_signal_connect_swapped(G_OBJECT(gtk_icon_theme_get_for_screen(screen)),
                             "changed",
                             G_CALLBACK(xfdesktop_icon_invalidate_pixbuf),
                             volume_icon);

    g_signal_connect(volume, "changed", 
                     G_CALLBACK(xfdesktop_volume_icon_changed), 
                     volume_icon);
    
    return volume_icon;
}
예제 #21
0
/**
 * g_volume_eject:
 * @volume: a #GVolume.
 * @flags: flags affecting the unmount if required for eject
 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
 * @callback: (allow-none): a #GAsyncReadyCallback, or %NULL.
 * @user_data: user data that gets passed to @callback
 * 
 * Ejects a volume. This is an asynchronous operation, and is
 * finished by calling g_volume_eject_finish() with the @volume
 * and #GAsyncResult returned in the @callback.
 *
 * Deprecated: 2.22: Use g_volume_eject_with_operation() instead.
 **/
void
g_volume_eject (GVolume             *volume,
		GMountUnmountFlags   flags,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
{
  GVolumeIface *iface;

  g_return_if_fail (G_IS_VOLUME (volume));

  iface = G_VOLUME_GET_IFACE (volume);

  if (iface->eject == NULL)
    {
      g_simple_async_report_error_in_idle (G_OBJECT (volume), callback, user_data,
					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
					   _("volume doesn't implement eject"));
      
      return;
    }
  
  (* iface->eject) (volume, flags, cancellable, callback, user_data);
}
예제 #22
0
void
thunar_notify_eject (GVolume *volume)
{
  const gchar * const *icon_names;
  NotifyNotification  *notification = NULL;
  const gchar         *summary;
  GFileInfo           *info;
  gboolean             read_only = FALSE;
  GMount              *mount;
  GFile               *icon_file;
  GFile               *mount_point;
  GIcon               *icon;
  gchar               *icon_name = NULL;
  gchar               *message;
  gchar               *name;

  g_return_if_fail (G_IS_VOLUME (volume));

  if (!thunar_notify_init ())
    return;

  mount = g_volume_get_mount (volume);
  if (mount != NULL)
    {
      mount_point = g_mount_get_root (mount);
      
      info = g_file_query_info (mount_point, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, 
                                G_FILE_QUERY_INFO_NONE, NULL, NULL);

      if (info != NULL)
        {
          read_only =
            !g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);

          g_object_unref (info);
        }

      g_object_unref (mount_point);
    }

  name = g_volume_get_name (volume);

  icon = g_volume_get_icon (volume);
  if (G_IS_THEMED_ICON (icon))
    {
      icon_names = g_themed_icon_get_names (G_THEMED_ICON (icon));
      if (icon_names != NULL)
        icon_name = g_strdup (icon_names[0]);
    }
  else if (G_IS_FILE_ICON (icon))
    {
      icon_file = g_file_icon_get_file (G_FILE_ICON (icon));
      if (icon_file != NULL)
        {
          icon_name = g_file_get_path (icon_file);
          g_object_unref (icon_file);
        }
    }
  g_object_unref (icon);

  if (icon_name == NULL)
    icon_name = g_strdup ("drive-removable-media");

  if (read_only)
    {
      summary = _("Ejecting device");
      message = g_strdup_printf (_("The device \"%s\" is being ejected. "
                                   "This may take some time"), name);
    }
  else
    {
      summary = _("Writing data to device");
      message = g_strdup_printf (_("There is data that needs to be written to the "
                                   "device \"%s\" before it can be removed. Please "
                                   "do not remove the media or disconnect the drive"),
                                   name);
    }

#ifdef NOTIFY_CHECK_VERSION
#if NOTIFY_CHECK_VERSION (0, 7, 0)
  notification = notify_notification_new (summary, message, icon_name);
#else
  notification = notify_notification_new (summary, message, icon_name, NULL);
#endif
#else
  notification = notify_notification_new (summary, message, icon_name, NULL);
#endif
  notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
  notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
  notify_notification_show (notification, NULL);

  g_object_set_data_full (G_OBJECT (volume), "thunar-notification", notification, 
                          g_object_unref);

  g_free (message);
  g_free (icon_name);
  g_free (name);
}