Index: uriloader/exthandler/Makefile.in ================================================================================ --- uriloader/exthandler/Makefile.in +++ uriloader/exthandler/Makefile.in @@ -103,7 +103,7 @@ LOCAL_INCLUDES = -I$(srcdir) ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) -OSHELPER += nsGNOMERegistry.cpp +OSHELPER += nsMIMEInfoUnix.cpp nsGNOMERegistry.cpp endif ifeq ($(MOZ_WIDGET_TOOLKIT),beos) --- uriloader/exthandler/unix/nsGNOMERegistry.cpp +++ uriloader/exthandler/unix/nsGNOMERegistry.cpp @@ -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 _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 @@ } -/* static */ already_AddRefed +/* static */ already_AddRefed nsGNOMERegistry::GetFromExtension(const char *aFileExt) { if (!gconfLib) @@ -286,7 +286,7 @@ return GetFromType(mimeType); } -/* static */ already_AddRefed +/* static */ already_AddRefed nsGNOMERegistry::GetFromType(const char *aMIMEType) { if (!gconfLib) @@ -296,9 +296,11 @@ if (!handlerApp) return nsnull; - nsRefPtr mimeInfo = new nsMIMEInfoImpl(aMIMEType); + nsRefPtr mimeInfo = new nsMIMEInfoUnix(aMIMEType); NS_ENSURE_TRUE(mimeInfo, nsnull); + mimeInfo->SetDefaultGnomeVFSMimeApplication(handlerApp); + // Get the list of extensions and append then to the mimeInfo. GList *extensions = _gnome_vfs_mime_get_extensions_list(aMIMEType); for (GList *extension = extensions; extension; extension = extension->next) @@ -320,11 +322,21 @@ 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 +354,7 @@ _gnome_vfs_mime_application_free(handlerApp); - nsMIMEInfoBase* retval; + nsMIMEInfoUnix* retval; NS_ADDREF((retval = mimeInfo)); return retval; } --- uriloader/exthandler/unix/nsGNOMERegistry.h +++ uriloader/exthandler/unix/nsGNOMERegistry.h @@ -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 @@ 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__ --- uriloader/exthandler/unix/nsMIMEInfoUnix.cpp +++ uriloader/exthandler/unix/nsMIMEInfoUnix.cpp @@ -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); +} --- uriloader/exthandler/unix/nsMIMEInfoUnix.h +++ uriloader/exthandler/unix/nsMIMEInfoUnix.h @@ -0,0 +1,50 @@ +/* ***** 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) {}; + + virtual ~nsMIMEInfoUnix(); + + void SetDefaultGnomeVFSMimeApplication(GnomeVFSMimeApplication *app); + +protected: + virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile); + + GnomeVFSMimeApplication *mDefaultVFSApplication; +}; + +#endif // nsMimeInfoUnix_h__ --- uriloader/exthandler/unix/nsOSHelperAppService.cpp +++ uriloader/exthandler/unix/nsOSHelperAppService.cpp @@ -44,6 +44,7 @@ #include "nsOSHelperAppService.h" #ifdef MOZ_WIDGET_GTK2 #include "nsGNOMERegistry.h" +#include "nsMIMEInfoUnix.h" #endif #include "nsISupports.h" #include "nsString.h"