7890760
Index: uriloader/exthandler/Makefile.in
7890760
===================================================================
7890760
RCS file: /cvsroot/mozilla/uriloader/exthandler/Makefile.in,v
7890760
retrieving revision 1.60
7890760
diff -d -u -p -r1.60 Makefile.in
7890760
--- uriloader/exthandler/Makefile.in	2 May 2005 16:30:03 -0000	1.60
7890760
+++ uriloader/exthandler/Makefile.in	21 Jul 2005 03:07:39 -0000
7890760
@@ -102,7 +102,7 @@ endif
7890760
 LOCAL_INCLUDES = -I$(srcdir)
7890760
 
7890760
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
7890760
-OSHELPER	+= nsGNOMERegistry.cpp
7890760
+OSHELPER	+= nsMIMEInfoUnix.cpp nsGNOMERegistry.cpp
7890760
 endif
7890760
 
7890760
 ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
7890760
Index: uriloader/exthandler/unix/nsGNOMERegistry.cpp
7890760
===================================================================
7890760
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp,v
7890760
retrieving revision 1.10
7890760
diff -d -u -p -r1.10 nsGNOMERegistry.cpp
7890760
--- uriloader/exthandler/unix/nsGNOMERegistry.cpp	16 Oct 2004 13:46:17 -0000	1.10
7890760
+++ uriloader/exthandler/unix/nsGNOMERegistry.cpp	21 Jul 2005 03:07:40 -0000
7890760
@@ -42,7 +42,7 @@
7890760
 #include "nsString.h"
7890760
 #include "nsIComponentManager.h"
7890760
 #include "nsILocalFile.h"
7890760
-#include "nsMIMEInfoImpl.h"
7890760
+#include "nsMIMEInfoUnix.h"
7890760
 #include "nsAutoPtr.h"
7890760
 
7890760
 #include <glib.h>
7890760
@@ -56,12 +56,12 @@ typedef struct _GConfClient GConfClient;
7890760
 typedef struct _GnomeProgram GnomeProgram;
7890760
 typedef struct _GnomeModuleInfo GnomeModuleInfo;
7890760
 
7890760
-typedef struct {
7890760
+struct GnomeVFSMimeApplication {
7890760
   char *id;
7890760
   char *name;
7890760
   char *command;
7890760
   /* there is more here, but we don't need it */
7890760
-} GnomeVFSMimeApplication;
7890760
+};
7890760
 
7890760
 typedef GConfClient * (*_gconf_client_get_default_fn)();
7890760
 typedef gchar * (*_gconf_client_get_string_fn)(GConfClient *,
7890760
@@ -264,7 +264,7 @@ nsGNOMERegistry::GetAppDescForScheme(con
7890760
 }
7890760
 
7890760
 
7890760
-/* static */ already_AddRefed<nsMIMEInfoBase>
7890760
+/* static */ already_AddRefed<nsMIMEInfoUnix>
7890760
 nsGNOMERegistry::GetFromExtension(const char *aFileExt)
7890760
 {
7890760
   if (!gconfLib)
7890760
@@ -286,7 +286,7 @@ nsGNOMERegistry::GetFromExtension(const 
7890760
   return GetFromType(mimeType);
7890760
 }
7890760
 
7890760
-/* static */ already_AddRefed<nsMIMEInfoBase>
7890760
+/* static */ already_AddRefed<nsMIMEInfoUnix>
7890760
 nsGNOMERegistry::GetFromType(const char *aMIMEType)
7890760
 {
7890760
   if (!gconfLib)
7890760
@@ -296,9 +296,11 @@ nsGNOMERegistry::GetFromType(const char 
7890760
   if (!handlerApp)
7890760
     return nsnull;
7890760
 
7890760
-  nsRefPtr<nsMIMEInfoImpl> mimeInfo = new nsMIMEInfoImpl(aMIMEType);
7890760
+  nsRefPtr<nsMIMEInfoUnix> mimeInfo = new nsMIMEInfoUnix(aMIMEType);
7890760
   NS_ENSURE_TRUE(mimeInfo, nsnull);
7890760
 
7890760
+  mimeInfo->SetDefaultGnomeVFSMimeApplication(handlerApp);
7890760
+
7890760
   // Get the list of extensions and append then to the mimeInfo.
7890760
   GList *extensions = _gnome_vfs_mime_get_extensions_list(aMIMEType);
7890760
   for (GList *extension = extensions; extension; extension = extension->next)
7890760
@@ -320,11 +322,21 @@ nsGNOMERegistry::GetFromType(const char 
7890760
     return nsnull;
7890760
   }
7890760
 
7890760
-  gchar *commandPath = g_find_program_in_path(nativeCommand);
7890760
+  gchar **argv;
7890760
+  gboolean res = g_shell_parse_argv(nativeCommand, NULL, &argv, NULL);
7890760
+  if (!res) {
7890760
+    NS_ERROR("Could not convert helper app command to filesystem encoding");
7890760
+    _gnome_vfs_mime_application_free(handlerApp);
7890760
+    return nsnull;
7890760
+  }
7890760
+
7890760
+  gchar *commandPath = g_find_program_in_path(argv[0]);
7890760
 
7890760
   g_free(nativeCommand);
7890760
+  g_strfreev(argv);
7890760
 
7890760
   if (!commandPath) {
7890760
+    NS_WARNING("could not find command in path");
7890760
     _gnome_vfs_mime_application_free(handlerApp);
7890760
     return nsnull;
7890760
   }
7890760
@@ -342,7 +354,7 @@ nsGNOMERegistry::GetFromType(const char 
7890760
 
7890760
   _gnome_vfs_mime_application_free(handlerApp);
7890760
 
7890760
-  nsMIMEInfoBase* retval;
7890760
+  nsMIMEInfoUnix* retval;
7890760
   NS_ADDREF((retval = mimeInfo));
7890760
   return retval;
7890760
 }
7890760
Index: uriloader/exthandler/unix/nsGNOMERegistry.h
7890760
===================================================================
7890760
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h,v
7890760
retrieving revision 1.3
7890760
diff -d -u -p -r1.3 nsGNOMERegistry.h
7890760
--- uriloader/exthandler/unix/nsGNOMERegistry.h	16 Oct 2004 13:46:17 -0000	1.3
7890760
+++ uriloader/exthandler/unix/nsGNOMERegistry.h	21 Jul 2005 03:07:40 -0000
7890760
@@ -35,10 +35,13 @@
7890760
  *
7890760
  * ***** END LICENSE BLOCK ***** */
7890760
 
7890760
+#ifndef nsGNOMERegistry_h__
7890760
+#define nsGNOMERegistry_h__
7890760
+
7890760
 #include "nsIURI.h"
7890760
 #include "nsCOMPtr.h"
7890760
 
7890760
-class nsMIMEInfoBase;
7890760
+class nsMIMEInfoUnix;
7890760
 
7890760
 class nsGNOMERegistry
7890760
 {
7890760
@@ -52,7 +55,9 @@ class nsGNOMERegistry
7890760
   static void GetAppDescForScheme(const nsACString& aScheme,
7890760
                                   nsAString& aDesc);
7890760
 
7890760
-  static already_AddRefed<nsMIMEInfoBase> GetFromExtension(const char *aFileExt);
7890760
+  static already_AddRefed<nsMIMEInfoUnix> GetFromExtension(const char *aFileExt);
7890760
 
7890760
-  static already_AddRefed<nsMIMEInfoBase> GetFromType(const char *aMIMEType);
7890760
+  static already_AddRefed<nsMIMEInfoUnix> GetFromType(const char *aMIMEType);
7890760
 };
7890760
+
7890760
+#endif // nsGNOMERegistry_h__
7890760
Index: uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
7890760
===================================================================
7890760
RCS file: uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
7890760
diff -N uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
7890760
--- /dev/null	1 Jan 1970 00:00:00 -0000
7890760
+++ uriloader/exthandler/unix/nsMIMEInfoUnix.cpp	21 Jul 2005 03:07:40 -0000
7890760
@@ -0,0 +1,196 @@
7890760
+/* ***** BEGIN LICENSE BLOCK *****
7890760
+ * Version: MPL 1.1
7890760
+ *
7890760
+ * The contents of this file are subject to the Mozilla Public License Version
7890760
+ * 1.1 (the "License"); you may not use this file except in compliance with
7890760
+ * the License. You may obtain a copy of the License at
7890760
+ * http://www.mozilla.org/MPL/
7890760
+ *
7890760
+ * Software distributed under the License is distributed on an "AS IS" basis,
7890760
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7890760
+ * for the specific language governing rights and limitations under the
7890760
+ * License.
7890760
+ *
7890760
+ * The Original Code is mozilla.org Code.
7890760
+ *
7890760
+ * The Initial Developer of the Original Code is
7890760
+ * Red Hat, Inc.
7890760
+ * Portions created by the Initial Developer are Copyright (C) 2005
7890760
+ * the Initial Developer. All Rights Reserved.
7890760
+ *
7890760
+ * Contributor(s):
7890760
+ *   Christopher Aillon <caillon@redhat.com> (Original author)
7890760
+ *
7890760
+ *
7890760
+ * ***** END LICENSE BLOCK ***** */
7890760
+
7890760
+#include "nsMIMEInfoUnix.h"
7890760
+#include "prlink.h"
7890760
+#include "prmem.h"
7890760
+#include <glib.h>
7890760
+#include <glib-object.h>
7890760
+
7890760
+static PRLibrary *gnomeLib;
7890760
+static PRLibrary *vfsLib;
7890760
+
7890760
+typedef struct _GnomeProgram GnomeProgram;
7890760
+typedef struct _GnomeModuleInfo GnomeModuleInfo;
7890760
+
7890760
+typedef enum {
7890760
+  GNOME_VFS_OK // there's more but we don't care about them.
7890760
+} GnomeVFSResult;
7890760
+
7890760
+typedef GnomeVFSResult (*_gnome_vfs_mime_application_launch_fn)
7890760
+                              (GnomeVFSMimeApplication *app,
7890760
+                               GList *uris);
7890760
+typedef void (*_gnome_vfs_mime_application_free_fn)(GnomeVFSMimeApplication *);
7890760
+typedef GnomeVFSMimeApplication * (*_gnome_vfs_mime_application_copy_fn)(GnomeVFSMimeApplication *);
7890760
+typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *,
7890760
+						 const GnomeModuleInfo *, int,
7890760
+						 char **, const char *, ...);
7890760
+typedef const char * (*_gnome_vfs_mime_application_get_name_fn)(GnomeVFSMimeApplication *);
7890760
+typedef const GnomeModuleInfo * (*_libgnome_module_info_get_fn)();
7890760
+typedef GnomeProgram * (*_gnome_program_get_fn)();
7890760
+typedef char * (*_gnome_vfs_make_uri_from_input_fn)(const char *);
7890760
+
7890760
+#define DECL_FUNC_PTR(func) static _##func##_fn _##func
7890760
+
7890760
+DECL_FUNC_PTR(gnome_vfs_mime_application_launch);
7890760
+DECL_FUNC_PTR(gnome_vfs_mime_application_free);
7890760
+DECL_FUNC_PTR(gnome_vfs_mime_application_copy);
7890760
+DECL_FUNC_PTR(gnome_vfs_mime_application_get_name);
7890760
+DECL_FUNC_PTR(gnome_program_init);
7890760
+DECL_FUNC_PTR(gnome_program_get);
7890760
+DECL_FUNC_PTR(libgnome_module_info_get);
7890760
+DECL_FUNC_PTR(gnome_vfs_make_uri_from_input);
7890760
+
7890760
+static PRLibrary *
7890760
+LoadVersionedLibrary(const char* libName, const char* libVersion)
7890760
+{
7890760
+  char *platformLibName = PR_GetLibraryName(nsnull, libName);
7890760
+  nsCAutoString versionLibName(platformLibName);
7890760
+  versionLibName.Append(libVersion);
7890760
+  PR_Free(platformLibName);
7890760
+  return PR_LoadLibrary(versionLibName.get());
7890760
+}
7890760
+
7890760
+static void
7890760
+Cleanup()
7890760
+{
7890760
+  // Unload all libraries
7890760
+  if (gnomeLib)
7890760
+    PR_UnloadLibrary(gnomeLib);
7890760
+  if (vfsLib)
7890760
+    PR_UnloadLibrary(vfsLib);
7890760
+
7890760
+  gnomeLib = vfsLib = nsnull;
7890760
+}
7890760
+
7890760
+static void
7890760
+InitGnomeVFS()
7890760
+{
7890760
+  static PRBool initialized = PR_FALSE;
7890760
+
7890760
+  if (initialized)
7890760
+    return;
7890760
+
7890760
+  #define ENSURE_LIB(lib) \
7890760
+    PR_BEGIN_MACRO \
7890760
+    if (!lib) { \
7890760
+      Cleanup(); \
7890760
+      return; \
7890760
+    } \
7890760
+    PR_END_MACRO
7890760
+
7890760
+  #define GET_LIB_FUNCTION(lib, func, failure) \
7890760
+    PR_BEGIN_MACRO \
7890760
+    _##func = (_##func##_fn) PR_FindFunctionSymbol(lib##Lib, #func); \
7890760
+    if (!_##func) { \
7890760
+      failure; \
7890760
+    } \
7890760
+    PR_END_MACRO
7890760
+
7890760
+  // Attempt to open libgnome
7890760
+  gnomeLib = LoadVersionedLibrary("gnome-2", ".0");
7890760
+  ENSURE_LIB(gnomeLib);
7890760
+
7890760
+  GET_LIB_FUNCTION(gnome, gnome_program_init, return Cleanup());
7890760
+  GET_LIB_FUNCTION(gnome, libgnome_module_info_get, return Cleanup());
7890760
+  GET_LIB_FUNCTION(gnome, gnome_program_get, return Cleanup());
7890760
+
7890760
+  // Attempt to open libgnomevfs
7890760
+  vfsLib = LoadVersionedLibrary("gnomevfs-2", ".0");
7890760
+  ENSURE_LIB(vfsLib);
7890760
+
7890760
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_launch, /* do nothing */);
7890760
+  GET_LIB_FUNCTION(vfs, gnome_vfs_make_uri_from_input, return Cleanup());
7890760
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_get_name, return Cleanup());
7890760
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_free, return Cleanup());
7890760
+  GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_copy, return Cleanup());
7890760
+
7890760
+  // Initialize GNOME, if it's not already initialized.  It's not
7890760
+  // necessary to tell GNOME about our actual command line arguments.
7890760
+
7890760
+  if (!_gnome_program_get()) {
7890760
+    char *argv[1] = { "gecko" };
7890760
+    _gnome_program_init("Gecko", "1.0", _libgnome_module_info_get(),
7890760
+                        1, argv, NULL);
7890760
+  }
7890760
+
7890760
+  // Note: after GNOME has been initialized, do not ever unload these
7890760
+  // libraries.  They register atexit handlers, so if they are unloaded, we'll
7890760
+  // crash on exit.  
7890760
+}
7890760
+
7890760
+void
7890760
+nsMIMEInfoUnix::SetDefaultGnomeVFSMimeApplication(GnomeVFSMimeApplication* app)
7890760
+{
7890760
+  if (_gnome_vfs_mime_application_copy && _gnome_vfs_mime_application_free) {
7890760
+    mDefaultVFSApplication = _gnome_vfs_mime_application_copy(app);
7890760
+
7890760
+    mPreferredAction = nsIMIMEInfo::useSystemDefault;
7890760
+
7890760
+    const gchar * name = _gnome_vfs_mime_application_get_name(mDefaultVFSApplication);
7890760
+    if (name) 
7890760
+      mDefaultAppDescription = NS_ConvertUTF8toUCS2(name);
7890760
+  }
7890760
+}
7890760
+
7890760
+nsMIMEInfoUnix::~nsMIMEInfoUnix()
7890760
+{
7890760
+  if (mDefaultVFSApplication)
7890760
+    _gnome_vfs_mime_application_free(mDefaultVFSApplication);
7890760
+}
7890760
+
7890760
+nsresult
7890760
+nsMIMEInfoUnix::LaunchDefaultWithFile(nsIFile* aFile)
7890760
+{
7890760
+  NS_ENSURE_ARG_POINTER(aFile);
7890760
+
7890760
+  InitGnomeVFS();
7890760
+
7890760
+  if (_gnome_vfs_mime_application_launch && mDefaultVFSApplication) {
7890760
+    nsCAutoString nativePath;
7890760
+    aFile->GetNativePath(nativePath);
7890760
+
7890760
+    gchar *uri = _gnome_vfs_make_uri_from_input(nativePath.get());
7890760
+
7890760
+    GList *uris = NULL;
7890760
+    uris = g_list_append(uris, uri);
7890760
+
7890760
+    GnomeVFSResult result = _gnome_vfs_mime_application_launch(mDefaultVFSApplication, uris);
7890760
+
7890760
+    g_free(uri);
7890760
+    g_list_free(uris);
7890760
+
7890760
+    if (result != GNOME_VFS_OK)
7890760
+      return NS_ERROR_FAILURE;
7890760
+
7890760
+    return NS_OK;
7890760
+  }
7890760
+
7890760
+  if (!mDefaultApplication)
7890760
+    return NS_ERROR_FILE_NOT_FOUND;
7890760
+
7890760
+  return LaunchWithIProcess(mDefaultApplication, aFile);
7890760
+}
7890760
Index: uriloader/exthandler/unix/nsMIMEInfoUnix.h
7890760
===================================================================
7890760
RCS file: uriloader/exthandler/unix/nsMIMEInfoUnix.h
7890760
diff -N uriloader/exthandler/unix/nsMIMEInfoUnix.h
7890760
--- /dev/null	1 Jan 1970 00:00:00 -0000
7890760
+++ uriloader/exthandler/unix/nsMIMEInfoUnix.h	21 Jul 2005 03:07:40 -0000
7890760
@@ -0,0 +1,50 @@
7890760
+/* ***** BEGIN LICENSE BLOCK *****
7890760
+ * Version: MPL 1.1
7890760
+ *
7890760
+ * The contents of this file are subject to the Mozilla Public License Version
7890760
+ * 1.1 (the "License"); you may not use this file except in compliance with
7890760
+ * the License. You may obtain a copy of the License at
7890760
+ * http://www.mozilla.org/MPL/
7890760
+ *
7890760
+ * Software distributed under the License is distributed on an "AS IS" basis,
7890760
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7890760
+ * for the specific language governing rights and limitations under the
7890760
+ * License.
7890760
+ *
7890760
+ * The Original Code is mozilla.org Code.
7890760
+ *
7890760
+ * The Initial Developer of the Original Code is
7890760
+ * Red Hat, Inc.
7890760
+ * Portions created by the Initial Developer are Copyright (C) 2005
7890760
+ * the Initial Developer. All Rights Reserved.
7890760
+ *
7890760
+ * Contributor(s):
7890760
+ *   Christopher Aillon <caillon@redhat.com> (Original author)
7890760
+ *
7890760
+ *
7890760
+ * ***** END LICENSE BLOCK ***** */
7890760
+
7890760
+#ifndef nsMimeInfoUnix_h__
7890760
+#define nsMimeInfoUnix_h__
7890760
+
7890760
+#include "nsMIMEInfoImpl.h"
7890760
+
7890760
+struct GnomeVFSMimeApplication;
7890760
+
7890760
+class nsMIMEInfoUnix : public nsMIMEInfoImpl
7890760
+{
7890760
+public:
7890760
+  nsMIMEInfoUnix(const char* aType = "") : nsMIMEInfoImpl(aType), mDefaultVFSApplication(nsnull) {}
7890760
+  nsMIMEInfoUnix(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {};
7890760
+
7890760
+  virtual ~nsMIMEInfoUnix();
7890760
+
7890760
+  void SetDefaultGnomeVFSMimeApplication(GnomeVFSMimeApplication *app);
7890760
+
7890760
+protected:
7890760
+  virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile);
7890760
+
7890760
+  GnomeVFSMimeApplication *mDefaultVFSApplication;
7890760
+};
7890760
+ 
7890760
+#endif // nsMimeInfoUnix_h__
7890760
Index: uriloader/exthandler/unix/nsOSHelperAppService.cpp
7890760
===================================================================
7890760
RCS file: /cvsroot/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp,v
7890760
retrieving revision 1.58
7890760
diff -d -u -p -r1.58 nsOSHelperAppService.cpp
7890760
--- uriloader/exthandler/unix/nsOSHelperAppService.cpp	25 Oct 2004 07:46:01 -0000	1.58
7890760
+++ uriloader/exthandler/unix/nsOSHelperAppService.cpp	21 Jul 2005 03:07:40 -0000
7890760
@@ -44,6 +44,7 @@
7890760
 #include "nsOSHelperAppService.h"
7890760
 #ifdef MOZ_WIDGET_GTK2
7890760
 #include "nsGNOMERegistry.h"
7890760
+#include "nsMIMEInfoUnix.h"
7890760
 #endif
7890760
 #include "nsISupports.h"
7890760
 #include "nsString.h"
7890760
@@ -1486,6 +1487,17 @@ nsOSHelperAppService::GetFromType(const 
7890760
   
7890760
   LOG(("Here we do a mimetype lookup for '%s'\n", aMIMEType.get()));
7890760
 
7890760
+#ifdef MOZ_WIDGET_GTK2
7890760
+  // Look in GNOME registry first since it is the preferred method in GNOME,
7890760
+  // should trump the mailcap entry
7890760
+  LOG(("Looking in GNOME registry\n"));
7890760
+  nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
7890760
+  if (gnomeInfo) {
7890760
+    LOG(("Got MIMEInfo from GNOME registry\n"));
7890760
+    return gnomeInfo;
7890760
+  }
7890760
+#endif
7890760
+
7890760
   // extract the major and minor types
7890760
   NS_ConvertASCIItoUTF16 mimeType(aMIMEType);
7890760
   nsAString::const_iterator start_iter, end_iter,
7890760
@@ -1522,21 +1534,6 @@ nsOSHelperAppService::GetFromType(const 
7890760
                                 mozillaFlags,
7890760
                                 PR_TRUE);
7890760
 
7890760
-  
7890760
-  if (handler.IsEmpty() && extensions.IsEmpty() &&
7890760
-      mailcap_description.IsEmpty() && mime_types_description.IsEmpty()) {
7890760
-    // No useful data yet
7890760
-    
7890760
-#ifdef MOZ_WIDGET_GTK2
7890760
-    LOG(("Looking in GNOME registry\n"));
7890760
-    nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get();
7890760
-    if (gnomeInfo) {
7890760
-      LOG(("Got MIMEInfo from GNOME registry\n"));
7890760
-      return gnomeInfo;
7890760
-    }
7890760
-#endif
7890760
-  }
7890760
-
7890760
   if (handler.IsEmpty() && mailcap_description.IsEmpty()) {
7890760
     DoLookUpHandlerAndDescription(majorType,
7890760
                                   minorType,