[Nautilus-list] start-here: etc. vfs method



Hi,

This is a bit overdue, my apologies. Anyhow, the patch is appended,
against stable branch, though clearly it needs merging to HEAD as
well.

Havoc

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.1057.2.17
diff -u -p -u -r1.1057.2.17 ChangeLog
--- ChangeLog	2001/09/19 19:13:34	1.1057.2.17
+++ ChangeLog	2001/09/20 19:29:00
@@ -1,3 +1,12 @@
+2001-09-20  Havoc Pennington  <hp redhat com>
+
+	* modules/file-method.c (find_trash_in_hierarchy): remove the
+	trash search stuff
+	(create_trash_near): ditto
+
+	* modules/Makefile.am, desktop-method.c, desktop-module.conf: Add
+	desktop method for desktop URIs such as start-here
+
 2001-09-18  Havoc Pennington  <hp redhat com>
 
 	* modules/Makefile.am (INCLUDES): add gnome cflags
Index: data/mime/ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/data/mime/ChangeLog,v
retrieving revision 1.39.2.3
diff -u -p -u -r1.39.2.3 ChangeLog
--- data/mime/ChangeLog	2001/08/22 17:24:12	1.39.2.3
+++ data/mime/ChangeLog	2001/09/20 19:29:00
@@ -1,3 +1,7 @@
+2001-09-20  Havoc Pennington  <hp redhat com>
+
+	* gnome-vfs-mime-magic: add magic for .desktop files
+
 2001-08-22  Dan Winship  <danw ximian com>
 
 	* gnome-vfs.mime: Map .ics to text/calendar
Index: data/mime/gnome-vfs-mime-magic
===================================================================
RCS file: /cvs/gnome/gnome-vfs/data/mime/gnome-vfs-mime-magic,v
retrieving revision 1.32.2.2
diff -u -p -u -r1.32.2.2 gnome-vfs-mime-magic
--- data/mime/gnome-vfs-mime-magic	2001/08/22 17:24:12	1.32.2.2
+++ data/mime/gnome-vfs-mime-magic	2001/09/20 19:29:00
@@ -72,6 +72,11 @@
 0	string		\x89PNG					image/png
 0	string		8BPS\ \ \000\000\000\000 &0xffffffff0000ffffffff image/x-psd
 
+# Desktop file support - slightly wrong, since comments can be before 
+# the [Desktop Entry] line in the current spec - probably should fix 
+# desktop entry spec to allow this 
+0:32   string          [Desktop\ Entry]                        application/x-gnome-app-info
+
 # special Nautilus link type
 0:32	string		\<nautilus_object\ nautilus_link	application/x-nautilus-link
 
Index: doc/tmpl/gnome-vfs-unused.sgml
===================================================================
RCS file: /cvs/gnome/gnome-vfs/doc/tmpl/gnome-vfs-unused.sgml,v
retrieving revision 1.5.2.3
diff -u -p -u -r1.5.2.3 gnome-vfs-unused.sgml
--- doc/tmpl/gnome-vfs-unused.sgml	2001/09/15 15:51:36	1.5.2.3
+++ doc/tmpl/gnome-vfs-unused.sgml	2001/09/20 19:29:00
@@ -1,132 +1,106 @@
-<!-- ##### FUNCTION gnome_vfs_app_context_new ##### -->
+<!-- ##### SECTION ./tmpl/app-context.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
- Returns: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_set_attribute ##### -->
+<!-- ##### SECTION ./tmpl/app-context.sgml:See_Also ##### -->
 <para>
 
 </para>
 
- app_context: 
- attribute_name: 
- value: 
 
-<!-- ##### MACRO GNOME_VFS_HOOKNAME_HTTP_PROXY_AUTH ##### -->
-<para>
+<!-- ##### SECTION ./tmpl/app-context.sgml:Short_Description ##### -->
 
-</para>
 
 
-<!-- ##### MACRO GNOME_VFS_HOOKNAME_BASIC_AUTH ##### -->
+<!-- ##### SECTION ./tmpl/app-context.sgml:Title ##### -->
+app-context
+
+
+<!-- ##### SECTION ./tmpl/constants.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_set_callback_full ##### -->
+<!-- ##### SECTION ./tmpl/constants.sgml:See_Also ##### -->
 <para>
 
 </para>
 
- app_context: 
- hook_name: 
- callback: 
- user_data: 
- dispatch_on_job_thread: 
- notify: 
 
+<!-- ##### SECTION ./tmpl/constants.sgml:Short_Description ##### -->
+
+
+
 <!-- ##### SECTION ./tmpl/constants.sgml:Title ##### -->
 Constants
 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_push_override_takesref ##### -->
+<!-- ##### SECTION ./tmpl/module-api.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
- app_context: 
 
-<!-- ##### USER_FUNCTION GnomeVFSCallback ##### -->
+<!-- ##### SECTION ./tmpl/module-api.sgml:See_Also ##### -->
 <para>
 
 </para>
 
- user_data: 
- in: 
- in_size: 
- out: 
- out_size: 
-
-<!-- ##### TYPEDEF GnomeVFSCallbackSimpleAuthOut ##### -->
-<para>
 
-</para>
+<!-- ##### SECTION ./tmpl/module-api.sgml:Short_Description ##### -->
 
 
-<!-- ##### FUNCTION gnome_vfs_context_peek_app_context_current ##### -->
-<para>
 
-</para>
+<!-- ##### SECTION ./tmpl/module-api.sgml:Title ##### -->
+module-api
 
- Returns: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_peek_current ##### -->
+<!-- ##### MACRO GNOME_VFS_HOOKNAME_BASIC_AUTH ##### -->
 <para>
 
 </para>
 
- Returns: 
 
-<!-- ##### SECTION ./tmpl/app-context.sgml:See_Also ##### -->
+<!-- ##### MACRO GNOME_VFS_HOOKNAME_HTTP_PROXY_AUTH ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gnome_vfs_callback_call_hook ##### -->
+<!-- ##### USER_FUNCTION GnomeVFSCallback ##### -->
 <para>
 
 </para>
 
- hookname: 
+ user_data: 
 @in: 
 @in_size: 
 @out: 
 @out_size: 
- Returns: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_set_callback ##### -->
+<!-- ##### TYPEDEF GnomeVFSCallbackSimpleAuthIn ##### -->
 <para>
 
 </para>
 
- app_context: 
- hook_name: 
- callback: 
- user_data: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_get_current ##### -->
+<!-- ##### TYPEDEF GnomeVFSCallbackSimpleAuthOut ##### -->
 <para>
 
 </para>
 
- Returns: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_ref ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_get_attribute ##### -->
 <para>
 
 </para>
 
 @app_context: 
-
-<!-- ##### SECTION ./tmpl/module-api.sgml:See_Also ##### -->
-<para>
-
-</para>
-
+ attribute_name: 
+ Returns: 
 
 <!-- ##### FUNCTION gnome_vfs_app_context_get_callback ##### -->
 <para>
@@ -139,21 +113,26 @@ Constants
 @p_dispatch_on_job_thread: 
 @Returns: 
 
-<!-- ##### SECTION ./tmpl/module-api.sgml:Short_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_get_current ##### -->
+<para>
 
+</para>
 
+ Returns: 
 
-<!-- ##### SECTION ./tmpl/constants.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_new ##### -->
 <para>
 
 </para>
 
+ Returns: 
 
-<!-- ##### SECTION ./tmpl/app-context.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_peek_current ##### -->
 <para>
 
 </para>
 
+ Returns: 
 
 <!-- ##### FUNCTION gnome_vfs_app_context_pop ##### -->
 <para>
@@ -161,43 +140,58 @@ Constants
 </para>
 
 
-<!-- ##### SECTION ./tmpl/module-api.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_push_override_takesref ##### -->
 <para>
 
 </para>
 
+ app_context: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_get_attribute ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_push_takesref ##### -->
 <para>
 
 </para>
 
 @app_context: 
- attribute_name: 
- Returns: 
 
-<!-- ##### TYPEDEF GnomeVFSCallbackSimpleAuthIn ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_ref ##### -->
 <para>
 
 </para>
 
+ app_context: 
 
-<!-- ##### FUNCTION gnome_vfs_context_peek_app_context ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_set_attribute ##### -->
 <para>
 
 </para>
 
- ctx: 
- Returns: 
+ app_context: 
+ attribute_name: 
+ value: 
 
-<!-- ##### SECTION ./tmpl/constants.sgml:Short_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_app_context_set_callback ##### -->
+<para>
 
+</para>
 
+ app_context: 
+ hook_name: 
+ callback: 
+ user_data: 
 
-<!-- ##### SECTION ./tmpl/module-api.sgml:Title ##### -->
-module-api
+<!-- ##### FUNCTION gnome_vfs_app_context_set_callback_full ##### -->
+<para>
 
+</para>
 
+ app_context: 
+ hook_name: 
+ callback: 
+ user_data: 
+ dispatch_on_job_thread: 
+ notify: 
+
 <!-- ##### FUNCTION gnome_vfs_app_context_unref ##### -->
 <para>
 
@@ -205,24 +199,30 @@ module-api
 
 @app_context: 
 
-<!-- ##### SECTION ./tmpl/app-context.sgml:Short_Description ##### -->
+<!-- ##### FUNCTION gnome_vfs_callback_call_hook ##### -->
+<para>
 
+</para>
 
+ hookname: 
+ in: 
+ in_size: 
+ out: 
+ out_size: 
+ Returns: 
 
-<!-- ##### FUNCTION gnome_vfs_app_context_push_takesref ##### -->
+<!-- ##### FUNCTION gnome_vfs_context_peek_app_context ##### -->
 <para>
 
 </para>
-
- app_context: 
 
-<!-- ##### SECTION ./tmpl/app-context.sgml:Title ##### -->
-app-context
-
+ ctx: 
+ Returns: 
 
-<!-- ##### SECTION ./tmpl/constants.sgml:See_Also ##### -->
+<!-- ##### FUNCTION gnome_vfs_context_peek_app_context_current ##### -->
 <para>
 
 </para>
 
+ Returns: 
 
Index: modules/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/Makefile.am,v
retrieving revision 1.67.2.3
diff -u -p -u -r1.67.2.3 Makefile.am
--- modules/Makefile.am	2001/09/19 19:13:35	1.67.2.3
+++ modules/Makefile.am	2001/09/20 19:29:00
@@ -20,6 +20,7 @@ INCLUDES =					\
 
 EXTRA_DIST =					\
 	default-modules.conf			\
+	desktop-module.conf			\
 	cdda-module.conf			\
 	ssl-modules.conf			\
 	$(libnfs_la_SOURCES)			\
@@ -47,6 +48,7 @@ modules_LTLIBRARIES =				\
 	libftp.la				\
 	libvfs-pipe.la				\
 	libvfs-translate.la			\
+	libdesktop.la				\
 	$(NULL)
 
 # Disabled for now
@@ -60,7 +62,7 @@ endif
 if HAVE_SSL
 SSL_CONF = ssl-modules.conf
 endif
-modulesconf_DATA = default-modules.conf $(CDDA_CONF) $(SSL_CONF)
+modulesconf_DATA = default-modules.conf desktop-module.conf $(CDDA_CONF) $(SSL_CONF)
 
 ###  `cdda' method
 
@@ -87,6 +89,12 @@ libfile_la_SOURCES = 				\
 	file-method.c 				\
 	file-method.h
 libfile_la_LDFLAGS = $(module_flags)
+
+###  `desktop' method
+
+libdesktop_la_SOURCES = 				\
+	desktop-method.c
+libdesktop_la_LDFLAGS = $(module_flags)
 
 ###  `ssh' method
 
Index: modules/desktop-method.c
===================================================================
RCS file: desktop-method.c
diff -N desktop-method.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ desktop-method.c	Thu Sep 20 15:29:00 2001
@@ -0,0 +1,861 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */
+
+/* desktop-file-method.c
+
+   Copyright (C) 2001 Red Hat, Inc.
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+/* URI scheme for remapping directories under magic URIs, used
+ * for the magic desktop file directories such as start-here.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <glib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libgnome/libgnome.h>
+
+#include <libgnomevfs/gnome-vfs-mime.h>
+
+#include <libgnomevfs/gnome-vfs-module.h>
+#include <libgnomevfs/gnome-vfs-method.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-module-shared.h>
+
+#define G_N_ELEMENTS(arr)		(sizeof (arr) / sizeof ((arr)[0]))
+
+static GnomeVFSURI* file_uri_to_desktop_uri (GnomeVFSURI *file_uri);
+static GnomeVFSURI* desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri);
+
+static GnomeVFSResult open_merged_directory (GnomeVFSMethod *method,
+					     GnomeVFSMethodHandle **method_handle,
+					     GnomeVFSURI *uri,
+					     GnomeVFSFileInfoOptions options,
+					     const GnomeVFSDirectoryFilter *filter,
+					     GnomeVFSContext *context);
+
+static GnomeVFSMethod *parent_method = NULL;
+
+static GnomeVFSResult
+do_open (GnomeVFSMethod *method,
+	 GnomeVFSMethodHandle **method_handle,
+	 GnomeVFSURI *uri,
+	 GnomeVFSOpenMode mode,
+	 GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->open) (parent_method,
+					  method_handle,
+					  file_uri,
+					  mode,
+					  context);
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_create (GnomeVFSMethod *method,
+	   GnomeVFSMethodHandle **method_handle,
+	   GnomeVFSURI *uri,
+	   GnomeVFSOpenMode mode,
+	   gboolean exclusive,
+	   guint perm,
+	   GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->create) (parent_method,
+					    method_handle,
+					    file_uri,
+					    mode,
+					    exclusive,
+					    perm,
+					    context);
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_close (GnomeVFSMethod *method,
+	  GnomeVFSMethodHandle *method_handle,
+	  GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->close) (parent_method,
+					   method_handle,
+					   context);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_read (GnomeVFSMethod *method,
+	 GnomeVFSMethodHandle *method_handle,
+	 gpointer buffer,
+	 GnomeVFSFileSize num_bytes,
+	 GnomeVFSFileSize *bytes_read,
+	 GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->read) (parent_method,
+					  method_handle,
+					  buffer, num_bytes,
+					  bytes_read,
+					  context);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_write (GnomeVFSMethod *method,
+	  GnomeVFSMethodHandle *method_handle,
+	  gconstpointer buffer,
+	  GnomeVFSFileSize num_bytes,
+	  GnomeVFSFileSize *bytes_written,
+	  GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->write) (parent_method,
+					   method_handle,
+					   buffer, num_bytes,
+					   bytes_written,
+					   context);
+
+	return result;
+}
+
+
+static GnomeVFSResult
+do_seek (GnomeVFSMethod *method,
+	 GnomeVFSMethodHandle *method_handle,
+	 GnomeVFSSeekPosition whence,
+	 GnomeVFSFileOffset offset,
+	 GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->seek) (parent_method,
+					  method_handle,
+					  whence, offset,
+					  context);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_tell (GnomeVFSMethod *method,
+	 GnomeVFSMethodHandle *method_handle,
+	 GnomeVFSFileOffset *offset_return)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->tell) (parent_method,
+					  method_handle,
+					  offset_return);
+
+	return result;
+}
+
+
+static GnomeVFSResult
+do_truncate_handle (GnomeVFSMethod *method,
+		    GnomeVFSMethodHandle *method_handle,
+		    GnomeVFSFileSize where,
+		    GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	
+	result = (* parent_method->truncate_handle) (parent_method,
+						     method_handle,
+						     where,
+						     context);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_truncate (GnomeVFSMethod *method,
+	     GnomeVFSURI *uri,
+	     GnomeVFSFileSize where,
+	     GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->truncate) (parent_method,
+					      file_uri,
+					      where,
+					      context);
+
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+typedef struct _DirHandle DirHandle;
+
+struct _DirHandle
+{
+	GSList *next;
+	GSList *handles;
+};
+
+static GnomeVFSResult
+do_open_directory (GnomeVFSMethod *method,
+		   GnomeVFSMethodHandle **method_handle,
+		   GnomeVFSURI *uri,
+		   GnomeVFSFileInfoOptions options,
+		   const GnomeVFSDirectoryFilter *filter,
+		   GnomeVFSContext *context)
+{
+	return open_merged_directory (method, method_handle,
+				      uri, options, filter, context);
+}
+
+static GnomeVFSResult
+do_close_directory (GnomeVFSMethod *method,
+		    GnomeVFSMethodHandle *method_handle,
+		    GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	GSList *tmp;
+	DirHandle *dh;
+
+	dh = (DirHandle*) method_handle;
+
+	result = GNOME_VFS_OK;
+	tmp = dh->handles;
+	while (tmp != NULL) {
+		GnomeVFSResult this_result;
+		
+		this_result = (* parent_method->close_directory) (parent_method,
+								  tmp->data,
+								  context);
+
+		if (this_result != GNOME_VFS_OK)
+			result = this_result;
+		
+		tmp = tmp->next;
+	}
+
+	g_slist_free (dh->handles);
+	g_free (dh);
+	
+	return result;
+}
+
+static GnomeVFSResult
+do_read_directory (GnomeVFSMethod *method,
+		   GnomeVFSMethodHandle *method_handle,
+		   GnomeVFSFileInfo *file_info,
+		   GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	GnomeVFSMethodHandle *parent_handle;
+	DirHandle *dh;
+
+	dh = (DirHandle*) method_handle;
+
+	if (dh->next == NULL) {
+		return GNOME_VFS_ERROR_EOF;
+	}
+
+ next:
+	parent_handle = dh->next->data;
+	
+	result = (* parent_method->read_directory) (parent_method,
+						    parent_handle,
+						    file_info,
+						    context);
+
+	if (result != GNOME_VFS_OK) {
+		dh->next = dh->next->next;
+		if (dh->next)
+			goto next;
+		else
+			return result;
+	} else {
+		return GNOME_VFS_OK;
+	}
+}
+
+
+static GnomeVFSResult
+do_get_file_info (GnomeVFSMethod *method,
+		  GnomeVFSURI *uri,
+		  GnomeVFSFileInfo *file_info,
+		  GnomeVFSFileInfoOptions options,
+		  GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->get_file_info) (parent_method,
+						   file_uri,
+						   file_info,
+						   options,
+						   context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_get_file_info_from_handle (GnomeVFSMethod *method,
+			      GnomeVFSMethodHandle *method_handle,
+			      GnomeVFSFileInfo *file_info,
+			      GnomeVFSFileInfoOptions options,
+			      GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+
+	result = (* parent_method->get_file_info_from_handle) (parent_method,
+							       method_handle,
+							       file_info,
+							       options,
+							       context);
+
+	return result;
+}
+
+
+static gboolean
+do_is_local (GnomeVFSMethod *method,
+	     const GnomeVFSURI *uri)
+{
+	return TRUE;
+}
+
+
+static GnomeVFSResult
+do_make_directory (GnomeVFSMethod *method,
+		   GnomeVFSURI *uri,
+		   guint perm,
+		   GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->make_directory) (parent_method,
+						    file_uri,
+						    perm,
+						    context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_remove_directory (GnomeVFSMethod *method,
+		     GnomeVFSURI *uri,
+		     GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->remove_directory) (parent_method,
+						      file_uri,
+						      context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_find_directory (GnomeVFSMethod *method,
+		   GnomeVFSURI *near_uri,
+		   GnomeVFSFindDirectoryKind kind,
+		   GnomeVFSURI **result_uri,
+		   gboolean create_if_needed,
+		   gboolean find_if_needed,
+		   guint permissions,
+		   GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSURI *file_result_uri;
+	GnomeVFSResult result;
+
+	file_result_uri = NULL;
+	file_uri = desktop_uri_to_file_uri (near_uri);
+	result = (* parent_method->find_directory) (parent_method,
+						    file_uri,
+						    kind,
+						    &file_result_uri,
+						    create_if_needed,
+						    find_if_needed,
+						    permissions,
+						    context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	if (file_result_uri) {
+		GnomeVFSURI *desktop_uri;
+
+		desktop_uri = file_uri_to_desktop_uri (file_result_uri);
+		
+		if (result_uri)
+			*result_uri = desktop_uri;
+
+		if (desktop_uri == NULL)
+			result = GNOME_VFS_ERROR_NOT_FOUND;
+		
+		gnome_vfs_uri_unref (file_result_uri);
+	}
+
+	return result;
+}
+
+static GnomeVFSResult
+do_move (GnomeVFSMethod *method,
+	 GnomeVFSURI *old_uri,
+	 GnomeVFSURI *new_uri,
+	 gboolean force_replace,
+	 GnomeVFSContext *context)
+{
+	GnomeVFSURI *old_file_uri;
+	GnomeVFSURI *new_file_uri;
+	GnomeVFSResult result;
+
+	old_file_uri = desktop_uri_to_file_uri (old_uri);
+	new_file_uri = desktop_uri_to_file_uri (new_uri);
+
+	result = (* parent_method->move) (parent_method,
+					  old_file_uri,
+					  new_file_uri,
+					  force_replace,
+					  context);
+	gnome_vfs_uri_unref (old_file_uri);
+	gnome_vfs_uri_unref (new_file_uri);
+
+	return result;
+}
+
+static GnomeVFSResult
+do_unlink (GnomeVFSMethod *method,
+	   GnomeVFSURI *uri,
+	   GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->unlink) (parent_method,
+					    file_uri,
+					    context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;	
+}
+
+static GnomeVFSResult
+do_create_symbolic_link (GnomeVFSMethod *method,
+			 GnomeVFSURI *uri,
+			 const char *target_reference,
+			 GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->create_symbolic_link) (parent_method,
+							  file_uri,
+							  target_reference,
+							  context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;	
+}
+
+static GnomeVFSResult
+do_check_same_fs (GnomeVFSMethod *method,
+		  GnomeVFSURI *source_uri,
+		  GnomeVFSURI *target_uri,
+		  gboolean *same_fs_return,
+		  GnomeVFSContext *context)
+{
+	GnomeVFSURI *source_file_uri;
+	GnomeVFSURI *target_file_uri;
+	GnomeVFSResult result;
+
+	source_file_uri = desktop_uri_to_file_uri (source_uri);
+	target_file_uri = desktop_uri_to_file_uri (target_uri);
+
+	result = (* parent_method->check_same_fs) (parent_method,
+						   source_file_uri,
+						   target_file_uri,
+						   same_fs_return,
+						   context);
+	gnome_vfs_uri_unref (source_file_uri);
+	gnome_vfs_uri_unref (target_file_uri);
+
+	return result;	
+}
+
+static GnomeVFSResult
+do_set_file_info (GnomeVFSMethod *method,
+		  GnomeVFSURI *uri,
+		  const GnomeVFSFileInfo *info,
+		  GnomeVFSSetFileInfoMask mask,
+		  GnomeVFSContext *context)
+{
+	GnomeVFSURI *file_uri;
+	GnomeVFSResult result;
+
+	file_uri = desktop_uri_to_file_uri (uri);
+	result = (* parent_method->set_file_info) (parent_method,
+						   file_uri,
+						   info,
+						   mask,
+						   context);
+	
+	gnome_vfs_uri_unref (file_uri);
+
+	return result;	
+}
+
+
+/* gnome-vfs bureaucracy */
+
+static GnomeVFSMethod method = {
+	sizeof (GnomeVFSMethod),
+	do_open,
+	do_create,
+	do_close,
+	do_read,
+	do_write,
+	do_seek,
+	do_tell,
+	do_truncate_handle,
+	do_open_directory,
+	do_close_directory,
+	do_read_directory,
+	do_get_file_info,
+	do_get_file_info_from_handle,
+	do_is_local,
+	do_make_directory,
+	do_remove_directory,
+	do_move,
+	do_unlink,
+	do_check_same_fs,
+	do_set_file_info,
+	do_truncate,
+	do_find_directory,
+	do_create_symbolic_link
+};
+
+
+typedef enum
+{
+	SCHEME_FAVORITES,
+	SCHEME_PREFERENCES,
+	SCHEME_STARTHERE,
+	SCHEME_SYSCONFIG,
+	SCHEME_SERVERCONFIG,
+	SCHEME_PROGRAMS
+} SchemeID;
+
+#define MAX_DIRECTORIES 3
+#define DIRECTORIES_INITIALIZER { NULL, NULL, NULL }
+
+typedef struct _SchemeDesc SchemeDesc;
+
+struct _SchemeDesc
+{
+	SchemeID id;
+	
+	const char *scheme;
+
+	char *directories[MAX_DIRECTORIES];
+};
+
+static SchemeDesc schemes[] = 
+{
+	{ SCHEME_FAVORITES, "favorites",
+	  DIRECTORIES_INITIALIZER },
+	{ SCHEME_PREFERENCES, "preferences",
+	  DIRECTORIES_INITIALIZER },
+	{ SCHEME_STARTHERE, "start-here",
+	  DIRECTORIES_INITIALIZER },
+	{ SCHEME_SYSCONFIG, "system-settings",
+	  DIRECTORIES_INITIALIZER },
+	{ SCHEME_SERVERCONFIG, "server-settings",
+	  DIRECTORIES_INITIALIZER },
+	{ SCHEME_PROGRAMS, "programs",
+	  DIRECTORIES_INITIALIZER }
+};
+
+GnomeVFSMethod *
+vfs_module_init (const char *method_name, 
+		 const char *args)
+{
+	int i;
+	
+	parent_method = gnome_vfs_method_get ("file");
+
+	if (parent_method == NULL) {
+		g_error ("Could not find 'file' method for gnome-vfs");
+		return NULL;
+	}
+
+	i = 0;
+	while (i < G_N_ELEMENTS (schemes)) {
+		switch (schemes[i].id) {
+		case SCHEME_FAVORITES:
+			schemes[i].directories[0] =
+				g_strconcat (g_get_home_dir (),
+					     "/.gnome/apps",
+					     NULL);
+			break;
+		case SCHEME_PREFERENCES:
+			schemes[i].directories[0] =
+				gnome_unconditional_datadir_file ("control-center");
+			break;
+		case SCHEME_STARTHERE:
+			schemes[i].directories[0] = g_strdup ("/etc/X11/starthere");
+			break;
+		case SCHEME_SYSCONFIG:
+			schemes[i].directories[0] =
+				g_strdup ("/etc/X11/sysconfig");
+			break;
+		case SCHEME_SERVERCONFIG:
+			schemes[i].directories[0] =
+				g_strdup ("/etc/X11/serverconfig");
+			break;
+		case SCHEME_PROGRAMS:
+			schemes[i].directories[0] = g_strdup ("/etc/X11/applnk");
+			schemes[i].directories[1] =
+				gnome_unconditional_datadir_file ("gnome/apps");
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+		}
+
+		++i;
+	}
+	
+	return &method;
+}
+
+void
+vfs_module_shutdown (GnomeVFSMethod *method)
+{
+	int i;
+	
+	i = 0;
+	while (i < G_N_ELEMENTS (schemes)) {
+		int j;
+
+		j = 0;
+		while (j < MAX_DIRECTORIES) {
+			g_free (schemes[i].directories[j]);
+			schemes[i].directories[j] = NULL;
+			++j;
+		}
+		
+		++i;
+	}
+}
+
+
+
+static const SchemeDesc*
+get_desc_for_uri (GnomeVFSURI *desktop_uri)
+{
+	const SchemeDesc *desc;
+	int i;
+	const char *scheme;
+	
+	scheme = gnome_vfs_uri_get_scheme (desktop_uri);
+
+	desc = NULL;
+	i = 0;
+	while (i < G_N_ELEMENTS (schemes)) {
+		if (strcmp (schemes[i].scheme, scheme) == 0) {
+			desc = &schemes[i];
+			break;
+		}
+		
+		++i;
+	}
+
+	return desc;
+}
+
+static GnomeVFSURI*
+file_uri_to_desktop_uri (GnomeVFSURI *file_uri)
+{
+	/* FIXME we would need to implement this if
+	 * we wanted find_directory to work.
+	 */
+	return NULL;
+}
+
+static GnomeVFSURI*
+desktop_uri_to_file_uri (GnomeVFSURI *desktop_uri)
+{
+	const SchemeDesc *desc;
+	GnomeVFSURI *new_uri;
+	const char *path;
+	int i;
+
+	desc = get_desc_for_uri (desktop_uri);
+
+	if (desc == NULL) {
+		gnome_vfs_uri_ref (desktop_uri);
+		return desktop_uri;
+	}
+
+	/* Prepend the base for the desktop URI.
+	 * If the SchemeDesc contains > 1 directory, we use the directory
+	 * after the first if the given file actually exists there.
+	 */
+	new_uri = NULL;
+	path = gnome_vfs_uri_get_path (desktop_uri);
+	i = 0;
+	while (desc->directories[i])
+		++i;
+	do {
+		char *s;
+
+		--i;
+		
+		s = g_strconcat ("file://", desc->directories[i], "/", path, NULL);
+
+		new_uri = gnome_vfs_uri_new (s);
+
+		g_free (s);
+		
+		if (i == 0 ||
+		    gnome_vfs_uri_exists (new_uri)) {
+			return new_uri;
+		} else {
+			gnome_vfs_uri_unref (new_uri);
+			new_uri = NULL;
+		}
+	} while (i > 0);
+
+
+	g_assert_not_reached ();
+
+	return NULL;
+}
+
+
+static GnomeVFSResult
+open_merged_directory (GnomeVFSMethod *method,
+		       GnomeVFSMethodHandle **method_handle,
+		       GnomeVFSURI *desktop_uri,
+		       GnomeVFSFileInfoOptions options,
+		       const GnomeVFSDirectoryFilter *filter,
+		       GnomeVFSContext *context)
+{
+	GnomeVFSResult result;
+	DirHandle *dh;
+	const SchemeDesc *desc;
+	int i;
+	gboolean found;
+	const char *path;
+	
+	desc = get_desc_for_uri (desktop_uri);
+	
+	if (desc == NULL) {
+		return GNOME_VFS_ERROR_NOT_FOUND;
+	}
+
+	dh = g_new0 (DirHandle, 1);
+	
+	/* Prepend the base for the desktop URI.
+	 * If the SchemeDesc contains > 1 directory, we use the directory
+	 * after the first if the given file actually exists there.
+	 */
+	found = FALSE;
+	path = gnome_vfs_uri_get_path (desktop_uri);
+	i = 0;
+	while (desc->directories[i]) {
+		char *s;
+		GnomeVFSURI *file_uri;
+		GnomeVFSMethodHandle *parent_handle = NULL;
+		
+		s = g_strconcat ("file://", desc->directories[i], "/", path, NULL);
+
+		file_uri = gnome_vfs_uri_new (s);
+
+		g_free (s);
+
+		result = (* parent_method->open_directory) (parent_method,
+							    &parent_handle,
+							    file_uri,
+							    options,
+							    filter,
+							    context);
+
+		if (result == GNOME_VFS_OK) {
+			found = TRUE;
+			dh->handles = g_slist_prepend (dh->handles, parent_handle);
+		}
+
+		gnome_vfs_uri_unref (file_uri);
+
+		++i;
+	}
+
+	dh->next = dh->handles;
+
+	*method_handle = (GnomeVFSMethodHandle*) dh;
+	
+	return found ? GNOME_VFS_OK : GNOME_VFS_ERROR_NOT_FOUND;
+}
+
+
+
+
+
+
+
Index: modules/desktop-module.conf
===================================================================
RCS file: desktop-module.conf
diff -N desktop-module.conf
--- /dev/null	Tue May  5 16:32:27 1998
+++ desktop-module.conf	Thu Sep 20 15:29:00 2001
@@ -0,0 +1,8 @@
+
+preferences: libdesktop.so
+system-settings: libdesktop.so
+server-settings: libdesktop.so
+favorites: libdesktop.so
+start-here: libdesktop.so
+programs: libdesktop.so
+
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.84
diff -u -p -u -r1.84 file-method.c
--- modules/file-method.c	2001/06/01 04:59:02	1.84
+++ modules/file-method.c	2001/09/20 19:29:00
@@ -1147,45 +1147,19 @@ find_trash_in_one_hierarchy_level (const
 static char *
 find_trash_in_hierarchy (const char *start_dir, dev_t near_device_id, GnomeVFSContext *context)
 {
-	GList *current_directory_list;
 	GList *next_directory_list;
-	GList *list_iterator;
 	char *result;
-	int level;
 
 #ifdef DEBUG_FIND_DIRECTORY
 	g_print ("searching for trash in %s\n", start_dir);
 #endif
 
 	next_directory_list = NULL;
-	current_directory_list = NULL;
 
 	/* Search the top level. */
 	result = find_trash_in_one_hierarchy_level (start_dir, near_device_id, 
 		&next_directory_list, context);
-
-	for (level = 1; result == NULL && level < MAX_TRASH_SEARCH_DEPTH; level++) {
-		gnome_vfs_list_deep_free (current_directory_list);
-
-		current_directory_list = next_directory_list;
-		next_directory_list = NULL;
-
-		if (current_directory_list == NULL) {
-			/* Shallow hierarchy, bail. */
-			break;
-		}
-		for (list_iterator = current_directory_list; list_iterator != NULL;
-			list_iterator = list_iterator->next) {
-			result = find_trash_in_one_hierarchy_level (list_iterator->data, 
-				near_device_id, &next_directory_list, context);
-
-			if (result != NULL) {
-				break;
-			}
-		}
-	}
-
-	gnome_vfs_list_deep_free (current_directory_list);
+	
 	gnome_vfs_list_deep_free (next_directory_list);
 
 	return result;
@@ -1481,56 +1455,7 @@ static char *
 create_trash_near (const char *full_name_near, dev_t near_device_id, const char *disk_top_directory,
 	guint permissions, GnomeVFSContext *context)
 {
-	char *result;
-	const char *scanner;
-	int depth;
-	char *current_directory;
-
-	result = NULL;
-
-	/* Point at the last directory in the top directory path */
-	scanner = strrchr (disk_top_directory, G_DIR_SEPARATOR);
-	g_assert (scanner != NULL);
-
-#ifdef DEBUG_FIND_DIRECTORY
-	g_print ("creating trash near %s, disk top %s\n", full_name_near, disk_top_directory);
-#endif
-	scanner = full_name_near + strlen (disk_top_directory);
-	if (*scanner != '\0') {
-		/* Try creating the Trash as high up in the volume hierarchy as possible
-		 * this makes it faster to find and less likely that the user will try
-		 * to delete it as a part of throwing something into the Trash.
-		 */
-		for (depth = 1; depth < MAX_TRASH_SEARCH_DEPTH; depth++) {
-			g_assert (*scanner == G_DIR_SEPARATOR);
-
-			/* Special-case to handle "/" (and similar?) */
-			if (scanner == full_name_near) {
-				current_directory = g_strdup (G_DIR_SEPARATOR_S);
-			} else {
-				current_directory = g_strdup (full_name_near);
-				current_directory[scanner - full_name_near] = '\0';
-			}
-
-			result = try_creating_trash_in (current_directory, permissions);
-			g_free (current_directory);
-			if (result != NULL) {
-				break;
-			}
-
-			scanner = strchr (scanner + 1, G_DIR_SEPARATOR);
-			if (scanner == NULL) {
-				break;
-			}
-		}
-	}
-	if (result == NULL) {
-		/* full_name_near must be the top of the disk hierarchy, we have to create a Trash in it
-		 */
-		 result = try_creating_trash_in (full_name_near, permissions);
-	}
-
-	return result;
+	return try_creating_trash_in (disk_top_directory, permissions);
 }
 




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]