From d776d125a586c520add4f63bcc1c8cbcd757a37f Mon Sep 17 00:00:00 2001 From: "reed@reedloden.com" Date: Tue, 29 Jan 2008 20:36:11 -0800 Subject: [PATCH] Bug 373397 - "nsGNOMERegistry could use the mozgnome component" [p=mh+mozilla@glandium.org (Mike Hommey) r=chpe sr=biesi a1.9=beltzner] --- uriloader/exthandler/unix/nsGNOMERegistry.cpp | 286 +++--------------- uriloader/exthandler/unix/nsGNOMERegistry.h | 6 +- .../exthandler/unix/nsOSHelperAppService.cpp | 8 +- 3 files changed, 53 insertions(+), 247 deletions(-) diff --git a/uriloader/exthandler/unix/nsGNOMERegistry.cpp b/uriloader/exthandler/unix/nsGNOMERegistry.cpp index 081148019ed..d9efbebc1be 100644 --- a/uriloader/exthandler/unix/nsGNOMERegistry.cpp +++ b/uriloader/exthandler/unix/nsGNOMERegistry.cpp @@ -44,202 +44,25 @@ #include "nsILocalFile.h" #include "nsMIMEInfoUnix.h" #include "nsAutoPtr.h" +#include "nsIGConfService.h" +#include "nsIGnomeVFSService.h" #include #include -static PRLibrary *gconfLib; -static PRLibrary *gnomeLib; -static PRLibrary *vfsLib; - -typedef struct _GConfClient GConfClient; -typedef struct _GnomeProgram GnomeProgram; -typedef struct _GnomeModuleInfo GnomeModuleInfo; - -typedef struct { - 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 *, - const char *, GError **); -typedef gboolean (*_gconf_client_get_bool_fn)(GConfClient *, - const char *, GError **); -typedef gboolean (*_gnome_url_show_fn)(const char *, GError **); -typedef const char * (*_gnome_vfs_mime_type_from_name_fn)(const char *); -typedef GList * (*_gnome_vfs_mime_get_extensions_list_fn)(const char *); -typedef void (*_gnome_vfs_mime_extensions_list_free_fn)(GList *); -typedef const char * (*_gnome_vfs_mime_get_description_fn)(const char *); -typedef GnomeVFSMimeApplication * (*_gnome_vfs_mime_get_default_application_fn) - (const char *); -typedef void (*_gnome_vfs_mime_application_free_fn)(GnomeVFSMimeApplication *); -typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *, - const GnomeModuleInfo *, int, - char **, const char *, ...); -typedef const GnomeModuleInfo * (*_libgnome_module_info_get_fn)(); -typedef GnomeProgram * (*_gnome_program_get_fn)(); - -#define DECL_FUNC_PTR(func) static _##func##_fn _##func - -DECL_FUNC_PTR(gconf_client_get_default); -DECL_FUNC_PTR(gconf_client_get_string); -DECL_FUNC_PTR(gconf_client_get_bool); -DECL_FUNC_PTR(gnome_url_show); -DECL_FUNC_PTR(gnome_vfs_mime_type_from_name); -DECL_FUNC_PTR(gnome_vfs_mime_get_extensions_list); -DECL_FUNC_PTR(gnome_vfs_mime_extensions_list_free); -DECL_FUNC_PTR(gnome_vfs_mime_get_description); -DECL_FUNC_PTR(gnome_vfs_mime_get_default_application); -DECL_FUNC_PTR(gnome_vfs_mime_application_free); -DECL_FUNC_PTR(gnome_program_init); -DECL_FUNC_PTR(libgnome_module_info_get); -DECL_FUNC_PTR(gnome_program_get); - -static void -CleanUp() -{ - // Unload all libraries - if (gnomeLib) { - PR_UnloadLibrary(gnomeLib); - gnomeLib = nsnull; - } - if (gconfLib) { - PR_UnloadLibrary(gconfLib); - gconfLib = nsnull; - } - if (vfsLib) { - PR_UnloadLibrary(vfsLib); - vfsLib = nsnull; - } -} - -static PRLibrary * -LoadVersionedLibrary(const char* libName, const char* libVersion) -{ - char *platformLibName = PR_GetLibraryName(nsnull, libName); - nsCAutoString versionLibName(platformLibName); - versionLibName.Append(libVersion); - PR_FreeLibraryName(platformLibName); - return PR_LoadLibrary(versionLibName.get()); -} - -/* static */ void -nsGNOMERegistry::Startup() -{ - #define ENSURE_LIB(lib) \ - PR_BEGIN_MACRO \ - if (!lib) { \ - CleanUp(); \ - return; \ - } \ - PR_END_MACRO - - #define GET_LIB_FUNCTION(lib, func) \ - PR_BEGIN_MACRO \ - _##func = (_##func##_fn) PR_FindFunctionSymbol(lib##Lib, #func); \ - if (!_##func) { \ - CleanUp(); \ - return; \ - } \ - PR_END_MACRO - - // Attempt to open libgconf - gconfLib = LoadVersionedLibrary("gconf-2", ".4"); - ENSURE_LIB(gconfLib); - - GET_LIB_FUNCTION(gconf, gconf_client_get_default); - GET_LIB_FUNCTION(gconf, gconf_client_get_string); - GET_LIB_FUNCTION(gconf, gconf_client_get_bool); - - // Attempt to open libgnome - gnomeLib = LoadVersionedLibrary("gnome-2", ".0"); - ENSURE_LIB(gnomeLib); - - GET_LIB_FUNCTION(gnome, gnome_url_show); - GET_LIB_FUNCTION(gnome, gnome_program_init); - GET_LIB_FUNCTION(gnome, libgnome_module_info_get); - GET_LIB_FUNCTION(gnome, gnome_program_get); - - // Attempt to open libgnomevfs - vfsLib = LoadVersionedLibrary("gnomevfs-2", ".0"); - ENSURE_LIB(vfsLib); - - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_type_from_name); - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_extensions_list); - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_extensions_list_free); - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_description); - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_get_default_application); - GET_LIB_FUNCTION(vfs, gnome_vfs_mime_application_free); - - // 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. -} - -/** - * Finds the application for a given protocol. - * - * @param aProtocolScheme - * Protocol to look up. For example, "ghelp" or "mailto". - * - * @return UTF-8 string identifying the application. Must be freed with - * g_free. - * NULL on error. - */ -static gchar* getAppForScheme(const nsACString& aProtocolScheme) -{ - if (!gconfLib) - return nsnull; - - GError *error = nsnull; - GConfClient *client = _gconf_client_get_default(); - NS_ASSERTION(client, "no gconf client"); - - nsCAutoString gconfPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") + - aProtocolScheme + - NS_LITERAL_CSTRING("/command")); - - gchar *app = _gconf_client_get_string(client, gconfPath.get(), &error); - g_object_unref(G_OBJECT(client)); - - if (error) - g_error_free(error); - - return app; -} - /* static */ PRBool nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) { - gchar *app = getAppForScheme(nsDependentCString(aProtocolScheme)); + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + if (!gconf) + return PR_FALSE; - if (app) { - g_free(app); - GConfClient *client = _gconf_client_get_default(); + PRBool isEnabled; + nsCAutoString handler; + if (NS_FAILED(gconf->GetAppForProtocol(nsDependentCString(aProtocolScheme), &isEnabled, handler))) + return PR_FALSE; - nsCAutoString enabledPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") + - nsDependentCString(aProtocolScheme) + - NS_LITERAL_CSTRING("/enabled")); - gboolean isEnabled = _gconf_client_get_bool(client, enabledPath.get(), NULL); - - g_object_unref(G_OBJECT(client)); - - return isEnabled ? PR_TRUE : PR_FALSE; - } - - return PR_FALSE; + return isEnabled; } // XXX Check HandlerExists() before calling LoadURL. @@ -253,98 +76,88 @@ nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) /* static */ nsresult nsGNOMERegistry::LoadURL(nsIURI *aURL) { - if (!gconfLib) + nsCOMPtr vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (!vfs) return NS_ERROR_FAILURE; - nsCAutoString spec; - aURL->GetAsciiSpec(spec); - - // XXX what if gnome_url_show() uses the default handler and that's us? - - if (_gnome_url_show(spec.get(), NULL)) - return NS_OK; - - return NS_ERROR_FAILURE; + return vfs->ShowURI(aURL); } /* static */ void nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc) { - char *app = getAppForScheme(aScheme); + nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); + if (!gconf) + return; - if (app) { + PRBool isEnabled; + nsCAutoString app; + if (NS_FAILED(gconf->GetAppForProtocol(aScheme, &isEnabled, app))) + return; + + if (!app.IsEmpty()) { // Try to only provide the executable name, as it is much simpler than with the path and arguments - char *firstSpace = strchr(app, ' '); - if (firstSpace) { - *firstSpace = '\0'; - char *lastSlash = strrchr(app, '/'); - if (lastSlash) { - CopyUTF8toUTF16(lastSlash + 1, aDesc); - g_free(app); - return; + PRInt32 firstSpace = app.FindChar(' '); + if (firstSpace != kNotFound) { + app.Truncate(firstSpace); + PRInt32 lastSlash = app.RFindChar('/'); + if (lastSlash != kNotFound) { + app.Cut(0, lastSlash + 1); } } CopyUTF8toUTF16(app, aDesc); - g_free(app); } } /* static */ already_AddRefed -nsGNOMERegistry::GetFromExtension(const char *aFileExt) +nsGNOMERegistry::GetFromExtension(const nsACString& aFileExt) { - if (!gconfLib) + NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot"); + nsCOMPtr vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (!vfs) return nsnull; // Get the MIME type from the extension, then call GetFromType to // fill in the MIMEInfo. - - nsCAutoString fileExtToUse; - if (aFileExt && aFileExt[0] != '.') - fileExtToUse = '.'; - - fileExtToUse.Append(aFileExt); - - const char *mimeType = _gnome_vfs_mime_type_from_name(fileExtToUse.get()); - if (!strcmp(mimeType, "application/octet-stream")) + nsCAutoString mimeType; + if (NS_FAILED(vfs->GetMimeTypeFromExtension(aFileExt, mimeType)) || + mimeType.EqualsLiteral("application/octet-stream")) return nsnull; return GetFromType(mimeType); } /* static */ already_AddRefed -nsGNOMERegistry::GetFromType(const char *aMIMEType) +nsGNOMERegistry::GetFromType(const nsACString& aMIMEType) { - if (!gconfLib) + nsCOMPtr vfs = do_GetService(NS_GNOMEVFSSERVICE_CONTRACTID); + if (!vfs) return nsnull; - GnomeVFSMimeApplication *handlerApp = _gnome_vfs_mime_get_default_application(aMIMEType); - if (!handlerApp) + nsCOMPtr handlerApp; + if (NS_FAILED(vfs->GetAppForMimeType(aMIMEType, getter_AddRefs(handlerApp))) || + !handlerApp) return nsnull; nsRefPtr mimeInfo = new nsMIMEInfoUnix(aMIMEType); NS_ENSURE_TRUE(mimeInfo, nsnull); - // 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) - mimeInfo->AppendExtension(nsDependentCString((const char *) extension->data)); - - _gnome_vfs_mime_extensions_list_free(extensions); - - const char *description = _gnome_vfs_mime_get_description(aMIMEType); + nsCAutoString description; + vfs->GetDescriptionForMimeType(aMIMEType, description); mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description)); // Convert UTF-8 registry value to filesystem encoding, which // g_find_program_in_path() uses. - gchar *nativeCommand = g_filename_from_utf8(handlerApp->command, + nsCAutoString command; + handlerApp->GetCommand(command); + gchar *nativeCommand = g_filename_from_utf8(command.get(), -1, NULL, NULL, NULL); if (!nativeCommand) { NS_ERROR("Could not convert helper app command to filesystem encoding"); - _gnome_vfs_mime_application_free(handlerApp); return nsnull; } @@ -353,7 +166,6 @@ nsGNOMERegistry::GetFromType(const char *aMIMEType) g_free(nativeCommand); if (!commandPath) { - _gnome_vfs_mime_application_free(handlerApp); return nsnull; } @@ -362,14 +174,14 @@ nsGNOMERegistry::GetFromType(const char *aMIMEType) getter_AddRefs(appFile)); if (appFile) { mimeInfo->SetDefaultApplication(appFile); - mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerApp->name)); + nsCAutoString name; + handlerApp->GetName(name); + mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(name)); mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault); } g_free(commandPath); - _gnome_vfs_mime_application_free(handlerApp); - nsMIMEInfoBase* retval; NS_ADDREF((retval = mimeInfo)); return retval; diff --git a/uriloader/exthandler/unix/nsGNOMERegistry.h b/uriloader/exthandler/unix/nsGNOMERegistry.h index cf2bdc11064..2e8e184f0fe 100644 --- a/uriloader/exthandler/unix/nsGNOMERegistry.h +++ b/uriloader/exthandler/unix/nsGNOMERegistry.h @@ -43,8 +43,6 @@ class nsMIMEInfoBase; class nsGNOMERegistry { public: - static void Startup(); - static PRBool HandlerExists(const char *aProtocolScheme); static nsresult LoadURL(nsIURI *aURL); @@ -52,7 +50,7 @@ class nsGNOMERegistry static void GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc); - static already_AddRefed GetFromExtension(const char *aFileExt); + static already_AddRefed GetFromExtension(const nsACString& aFileExt); - static already_AddRefed GetFromType(const char *aMIMEType); + static already_AddRefed GetFromType(const nsACString& aMIMEType); }; diff --git a/uriloader/exthandler/unix/nsOSHelperAppService.cpp b/uriloader/exthandler/unix/nsOSHelperAppService.cpp index e0a9d3bf3cf..694bbba85a6 100644 --- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp +++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp @@ -88,10 +88,6 @@ IsNetscapeFormat(const nsACString& aBuffer); nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService() { -#ifdef MOZ_WIDGET_GTK2 - nsGNOMERegistry::Startup(); -#endif - mode_t mask = umask(0777); umask(mask); mPermissions = 0666 & ~mask; @@ -1364,7 +1360,7 @@ nsOSHelperAppService::GetFromExtension(const nsCString& aFileExt) { #ifdef MOZ_WIDGET_GTK2 LOG(("Looking in GNOME registry\n")); - nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt.get()).get(); + nsMIMEInfoBase *gnomeInfo = nsGNOMERegistry::GetFromExtension(aFileExt).get(); if (gnomeInfo) { LOG(("Got MIMEInfo from GNOME registry\n")); return gnomeInfo; @@ -1490,7 +1486,7 @@ nsOSHelperAppService::GetFromType(const nsCString& aMIMEType) { // get back a MIMEInfo without any extensions set. In that case we'll have // to look in our mime.types files for the extensions. LOG(("Looking in GNOME registry\n")); - gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType.get()).get(); + gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType).get(); if (gnomeInfo && gnomeInfo->HasExtensions()) { LOG(("Got MIMEInfo from GNOME registry, and it has extensions set\n")); return gnomeInfo;