static gboolean
xfdesktop_volume_icon_do_drop_dest(XfdesktopIcon *icon,
                                 XfdesktopIcon *src_icon,
                                 GdkDragAction action)
{
    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file, *parent, *dest_file = NULL;
    gboolean result = FALSE;
    gchar *name;
    
    DBG("entering");
    
    g_return_val_if_fail(volume_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_volume_icon_get_allowed_drop_actions(icon, NULL),
                         FALSE);
    
    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;

    if(!volume_icon->priv->file_info)
        return FALSE;
   
    parent = g_file_get_parent(src_file);
    if(!parent)
        return FALSE;
    g_object_unref(parent);
        
    name = g_file_get_basename(src_file);
    if(!name)
        return FALSE;
    
    switch(action) {
        case GDK_ACTION_MOVE:
            DBG("doing move");
            dest_file = g_object_ref(volume_icon->priv->file);
            break;
        
        case GDK_ACTION_COPY:
            DBG("doing copy");
            dest_file = g_file_get_child(volume_icon->priv->file, name);
            break;
        
        case GDK_ACTION_LINK:
            DBG("doing link");
            dest_file = g_object_ref(volume_icon->priv->file);
            break;
        
        default:
            g_warning("Unsupported drag action: %d", action);
    }

    if(dest_file) {
        xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                           volume_icon->priv->gscreen);
    
        g_object_unref(dest_file);

        result = TRUE;
    }

    g_free(name);
        
    return result;
}
gboolean
xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                         XfdesktopIcon *src_icon,
                                         GdkDragAction action)
{
    XfdesktopRegularFileIcon *regular_file_icon = XFDESKTOP_REGULAR_FILE_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file;
    gboolean result = FALSE;
    
    TRACE("entering");
    
    g_return_val_if_fail(regular_file_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_regular_file_icon_get_allowed_drop_actions(icon, NULL) != 0,
                         FALSE);
    
    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;
    
    if(g_file_info_get_file_type(regular_file_icon->priv->file_info) != G_FILE_TYPE_DIRECTORY
       && xfdesktop_file_utils_file_is_executable(regular_file_icon->priv->file_info))
    {
        GList files;

        files.data = src_file;
        files.prev = files.next = NULL;

        xfdesktop_file_utils_execute(NULL, regular_file_icon->priv->file, &files,
                                     regular_file_icon->priv->gscreen, NULL);

        result = TRUE;
    } else {
        GFile *parent, *dest_file = NULL;
        gchar *name;
        
        parent = g_file_get_parent(src_file);
        if(!parent)
            return FALSE;
        g_object_unref(parent);
        
        name = g_file_get_basename(src_file);
        if(!name)
            return FALSE;
        
        switch(action) {
            case GDK_ACTION_MOVE:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            case GDK_ACTION_COPY:
                dest_file = g_file_get_child(regular_file_icon->priv->file, name);
                break;
            case GDK_ACTION_LINK:
                dest_file = g_object_ref(regular_file_icon->priv->file);
                break;
            default:
                g_warning("Unsupported drag action: %d", action);
        }

        if(dest_file) {
            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                               regular_file_icon->priv->gscreen);

            g_object_unref(dest_file);

            result = TRUE;
        }

        g_free(name);
    }
    
    return result;
}
static gboolean
xfdesktop_special_file_icon_do_drop_dest(XfdesktopIcon *icon,
                                         XfdesktopIcon *src_icon,
                                         GdkDragAction action)
{
    XfdesktopSpecialFileIcon *special_file_icon = XFDESKTOP_SPECIAL_FILE_ICON(icon);
    XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
    GFileInfo *src_info;
    GFile *src_file;
    GFile *dest_file = NULL;
    gboolean result = FALSE;

    TRACE("entering");

    g_return_val_if_fail(special_file_icon && src_file_icon, FALSE);
    g_return_val_if_fail(xfdesktop_special_file_icon_get_allowed_drop_actions(icon, NULL),
                         FALSE);

    src_file = xfdesktop_file_icon_peek_file(src_file_icon);

    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
    if(!src_info)
        return FALSE;

    if(special_file_icon->priv->type == XFDESKTOP_SPECIAL_FILE_ICON_TRASH) {
        GList files;

        XF_DEBUG("doing trash");

        /* fake a file list */
        files.data = src_file;
        files.prev = files.next = NULL;

        /* let the trash service handle the trash operation */
        xfdesktop_file_utils_trash_files(&files, special_file_icon->priv->gscreen, NULL);
    } else {
        gchar *name = g_file_get_basename(src_file);
        if(!name)
            return FALSE;

        switch(action) {
            case GDK_ACTION_MOVE:
                XF_DEBUG("doing move");
                dest_file = g_object_ref(special_file_icon->priv->file);
                break;
            case GDK_ACTION_COPY:
                XF_DEBUG("doing copy");
                dest_file = g_file_get_child(special_file_icon->priv->file, name);
                break;
            case GDK_ACTION_LINK:
                XF_DEBUG("doing link");
                dest_file = g_object_ref(special_file_icon->priv->file);
                break;
            default:
                g_warning("Unsupported drag action: %d", action);
        }

        /* let the file manager service move/copy/link the file */
        if(dest_file) {
            xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                               special_file_icon->priv->gscreen);

            result = TRUE;
        }

        g_object_unref(dest_file);
        g_free(name);
    }

    return result;
}