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