From fae7dc0a72a5171def5eff59feb5ab5625f9ed74 Mon Sep 17 00:00:00 2001 From: Steven Michaud Date: Mon, 11 May 2009 15:39:37 -0500 Subject: [PATCH] Backed out changeset add33a95e3ef to fix talos crashes. b=489864 --- docshell/build/nsDocShellModule.cpp | 9 + .../decoders/icon/mac/nsIconChannelCocoa.mm | 20 +- netwerk/mime/public/nsIMIMEInfo.idl | 8 +- uriloader/exthandler/Makefile.in | 6 + uriloader/exthandler/mac/nsInternetConfig.h | 59 ++ uriloader/exthandler/mac/nsInternetConfig.mm | 135 ++++ .../exthandler/mac/nsInternetConfigService.h | 66 ++ .../exthandler/mac/nsInternetConfigService.mm | 629 ++++++++++++++++++ uriloader/exthandler/mac/nsMIMEInfoMac.mm | 26 +- .../exthandler/mac/nsOSHelperAppService.h | 4 + .../exthandler/mac/nsOSHelperAppService.mm | 312 ++++----- .../exthandler/nsExternalHelperAppService.cpp | 101 ++- .../exthandler/nsIInternetConfigService.idl | 126 ++++ uriloader/exthandler/nsMIMEInfoImpl.cpp | 45 ++ uriloader/exthandler/nsMIMEInfoImpl.h | 5 + widget/src/cocoa/nsLookAndFeel.mm | 24 +- 16 files changed, 1352 insertions(+), 223 deletions(-) create mode 100644 uriloader/exthandler/mac/nsInternetConfig.h create mode 100644 uriloader/exthandler/mac/nsInternetConfig.mm create mode 100644 uriloader/exthandler/mac/nsInternetConfigService.h create mode 100644 uriloader/exthandler/mac/nsInternetConfigService.mm create mode 100644 uriloader/exthandler/nsIInternetConfigService.idl diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index cd48b5b7c14..5e9275a0706 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -119,6 +119,11 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PlatformLocalHandlerApp_t) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDBusHandlerApp) #endif +#if defined(XP_MAC) || defined(XP_MACOSX) +#include "nsInternetConfigService.h" +NS_GENERIC_FACTORY_CONSTRUCTOR(nsInternetConfigService) +#endif + // session history NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHEntry) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSHTransaction) @@ -229,6 +234,10 @@ static const nsModuleComponentInfo gDocShellModuleInfo[] = { { "DBus Handler App", NS_DBUSHANDLERAPP_CID, NS_DBUSHANDLERAPP_CONTRACTID, nsDBusHandlerAppConstructor}, #endif +#if defined(XP_MAC) || defined(XP_MACOSX) + { "Internet Config Service", NS_INTERNETCONFIGSERVICE_CID, NS_INTERNETCONFIGSERVICE_CONTRACTID, + nsInternetConfigServiceConstructor, }, +#endif // session history { "nsSHEntry", NS_SHENTRY_CID, diff --git a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm index b7677fc448f..e0d47f9a7e0 100644 --- a/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm +++ b/modules/libpr0n/decoders/icon/mac/nsIconChannelCocoa.mm @@ -269,7 +269,25 @@ nsresult nsIconChannel::MakeInputStream(nsIInputStream** _retval, PRBool nonBloc } } - // if we don't have an icon yet try to get one by extension + // try by HFS type if we don't have an icon yet + if (!iconImage) { + nsCOMPtr mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + // if we were given an explicit content type, use it.... + nsCOMPtr mimeInfo; + if (mimeService && (!contentType.IsEmpty() || !fileExt.IsEmpty())) + mimeService->GetFromTypeAndExtension(contentType, fileExt, getter_AddRefs(mimeInfo)); + + if (mimeInfo) { + // get the icon by HFS type + PRUint32 macType; + if (NS_SUCCEEDED(mimeInfo->GetMacType(&macType))) + iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(macType)]; + } + } + + // if we still don't have an icon, try to get one by extension if (!iconImage && !fileExt.IsEmpty()) { NSString* fileExtension = [NSString stringWithUTF8String:PromiseFlatCString(fileExt).get()]; iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:fileExtension]; diff --git a/netwerk/mime/public/nsIMIMEInfo.idl b/netwerk/mime/public/nsIMIMEInfo.idl index 0f642ed5d51..a9e0a4be51f 100644 --- a/netwerk/mime/public/nsIMIMEInfo.idl +++ b/netwerk/mime/public/nsIMIMEInfo.idl @@ -53,7 +53,7 @@ typedef long nsHandlerInfoAction; * nsIHandlerInfo gives access to the information about how a given protocol * scheme or MIME-type is handled. */ -[scriptable, uuid(8E726396-3E02-467C-855E-5900E562BA42)] +[scriptable, uuid(325e56a7-3762-4312-aec7-f1fcf84b4145)] interface nsIHandlerInfo : nsISupports { /** * The type of this handler info. For MIME handlers, this is the MIME type. @@ -202,6 +202,12 @@ interface nsIMIMEInfo : nsIHandlerInfo { */ readonly attribute ACString MIMEType; + /** + * Mac Type and creator types + */ + attribute PRUint32 macType; + attribute PRUint32 macCreator; + /** * Returns whether or not these two nsIMIMEInfos are logically * equivalent. diff --git a/uriloader/exthandler/Makefile.in b/uriloader/exthandler/Makefile.in index 14ab5e4d857..7c0f4b140b8 100644 --- a/uriloader/exthandler/Makefile.in +++ b/uriloader/exthandler/Makefile.in @@ -97,6 +97,8 @@ REQUIRES += windowwatcher \ $(NULL) CMMSRCS = nsOSHelperAppService.mm \ + nsInternetConfig.mm \ + nsInternetConfigService.mm \ nsMIMEInfoMac.mm \ nsLocalHandlerAppMac.mm \ $(NULL) @@ -143,6 +145,10 @@ XPIDLSRCS = \ nsIHandlerService.idl \ $(NULL) +ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) +XPIDLSRCS += nsIInternetConfigService.idl +endif + CPPSRCS = \ nsExternalHelperAppService.cpp \ nsExternalProtocolHandler.cpp \ diff --git a/uriloader/exthandler/mac/nsInternetConfig.h b/uriloader/exthandler/mac/nsInternetConfig.h new file mode 100644 index 00000000000..8a02bfdebab --- /dev/null +++ b/uriloader/exthandler/mac/nsInternetConfig.h @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.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 Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __NS_INTERNETCONFIG_H__ +#define __NS_INTERNETCONFIG_H__ + +#include +#include "prtypes.h" +#include "nsError.h" + +class nsInternetConfig +{ +public: + nsInternetConfig(); + ~nsInternetConfig(); + + static ICInstance GetInstance(); + static PRBool HasSeedChanged(); +private: + static ICInstance sInstance; + static long sSeed; + static PRInt32 sRefCount; +}; + +#endif /* __NS_INTERNETCONFIG_H__ */ diff --git a/uriloader/exthandler/mac/nsInternetConfig.mm b/uriloader/exthandler/mac/nsInternetConfig.mm new file mode 100644 index 00000000000..59ed37fb490 --- /dev/null +++ b/uriloader/exthandler/mac/nsInternetConfig.mm @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.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 Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsInternetConfig.h" +#include "nsObjCExceptions.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsDebug.h" + +#include + +ICInstance nsInternetConfig::sInstance = NULL; +long nsInternetConfig::sSeed = 0; +PRInt32 nsInternetConfig::sRefCount = 0; + + + +static OSType GetAppCreatorCode() +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; + + ProcessSerialNumber psn = { 0, kCurrentProcess } ; + ProcessInfoRec procInfo; + + procInfo.processInfoLength = sizeof(ProcessInfoRec); + procInfo.processName = NULL; +#ifndef __LP64__ + procInfo.processAppSpec = NULL; +#else + procInfo.processAppRef = NULL; +#endif + + GetProcessInformation(&psn, &procInfo); + return procInfo.processSignature; + + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0x0); +} + + + +ICInstance nsInternetConfig::GetInstance() +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; + + if ( !sInstance ) + { + OSType creator = GetAppCreatorCode(); + OSStatus err = ::ICStart( &sInstance, creator ); + if ( err != noErr ) + { + ::ICStop( sInstance ); + } + else + { + ::ICGetSeed( sInstance, &sSeed ); + } + } + return sInstance; + + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL); +} + +PRBool nsInternetConfig::HasSeedChanged() +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; + + ICInstance instance = nsInternetConfig::GetInstance(); + if ( instance ) + { + long newSeed = 0; + ::ICGetSeed( sInstance, &newSeed ); + if ( newSeed != sSeed ) + { + sSeed = newSeed; + return PR_TRUE; + } + } + return PR_FALSE; + + NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE); +} + +nsInternetConfig::nsInternetConfig() +{ + sRefCount++; +} + +nsInternetConfig::~nsInternetConfig() +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + + sRefCount--; + if ( sRefCount == 0 && sInstance) + { + ::ICStop( sInstance ); + sInstance = NULL; + } + + NS_OBJC_END_TRY_ABORT_BLOCK; +} + diff --git a/uriloader/exthandler/mac/nsInternetConfigService.h b/uriloader/exthandler/mac/nsInternetConfigService.h new file mode 100644 index 00000000000..38b4b7cdf95 --- /dev/null +++ b/uriloader/exthandler/mac/nsInternetConfigService.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.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 Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef __nsInternetConfigService_h +#define __nsInternetConfigService_h + +#include "nsIInternetConfigService.h" +#include "nsInternetConfig.h" + +#define NS_INTERNETCONFIGSERVICE_CID \ + {0x9b8b9d81, 0x5f4f, 0x11d4, \ + { 0x96, 0x96, 0x00, 0x60, 0x08, 0x3a, 0x0b, 0xcf }} + +class nsInternetConfigService : public nsIInternetConfigService +{ +public: + + NS_DECL_ISUPPORTS + NS_DECL_NSIINTERNETCONFIGSERVICE + + nsresult GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry); + + nsInternetConfigService(); + virtual ~nsInternetConfigService(); +protected: + // some private helper methods... + nsresult FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo); + + nsresult GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey); + nsresult GetICPreference(PRUint32 inKey, void *outData, long *ioSize); +}; + +#endif diff --git a/uriloader/exthandler/mac/nsInternetConfigService.mm b/uriloader/exthandler/mac/nsInternetConfigService.mm new file mode 100644 index 00000000000..b67d32662fe --- /dev/null +++ b/uriloader/exthandler/mac/nsInternetConfigService.mm @@ -0,0 +1,629 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.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 Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Steve Dagley + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsInternetConfigService.h" +#include "nsObjCExceptions.h" +#include "nsCOMPtr.h" +#include "nsIMIMEInfo.h" +#include "nsMIMEInfoMac.h" +#include "nsAutoPtr.h" +#include "nsIFactory.h" +#include "nsIComponentManager.h" +#include "nsIURL.h" +#include "nsXPIDLString.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsCRT.h" +#include "nsILocalFileMac.h" +#include "nsMimeTypes.h" + +#import +#import +#import + +/* This is an undocumented interface that seems to exist at least in 10.4 and 10.5 */ +@class NSURLFileTypeMappingsInternal; + +@interface NSURLFileTypeMappings : NSObject +{ + NSURLFileTypeMappingsInternal *_internal; +} + ++ (NSURLFileTypeMappings*)sharedMappings; +- (NSString*)MIMETypeForExtension:(NSString*)fp8; +- (NSString*)preferredExtensionForMIMEType:(NSString*)fp8; +- (NSArray*)extensionsForMIMEType:(NSString*)fp8; +@end + +// helper converter function..... +static void ConvertCharStringToStr255(const char* inString, Str255& outString) +{ + if (inString == NULL) + return; + + PRInt32 len = strlen(inString); + NS_ASSERTION(len <= 255 , " String is too big"); + if (len> 255) + { + len = 255; + } + memcpy(&outString[1], inString, len); + outString[0] = len; +} + +/* Define Class IDs */ + +nsInternetConfigService::nsInternetConfigService() +{ +} + +nsInternetConfigService::~nsInternetConfigService() +{ +} + + +/* + * Implement the nsISupports methods... + */ +NS_IMPL_ISUPPORTS1(nsInternetConfigService, nsIInternetConfigService) + +// void LaunchURL (in string url); +// Given a url string, call ICLaunchURL using url +// Under OS X use LaunchServices instead of IC +NS_IMETHODIMP nsInternetConfigService::LaunchURL(const char *url) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + nsresult rv = NS_ERROR_FAILURE; + + CFURLRef myURLRef = ::CFURLCreateWithBytes( + kCFAllocatorDefault, + (const UInt8*)url, + strlen(url), + kCFStringEncodingUTF8, NULL); + if (myURLRef) + { + rv = ::LSOpenCFURLRef(myURLRef, NULL); + ::CFRelease(myURLRef); + } + + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +// boolean HasMappingForMIMEType (in string mimetype); +// given a mime type, search Internet Config database for a mapping for that mime type +NS_IMETHODIMP nsInternetConfigService::HasMappingForMIMEType(const char *mimetype, PRBool *_retval) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + ICMapEntry entry; + nsresult rv = GetMappingForMIMEType(mimetype, nsnull, &entry); + if (rv == noErr) + *_retval = PR_TRUE; + else + *_retval = PR_FALSE; + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +/* boolean hasProtocolHandler (in string protocol); */ +// returns NS_ERROR_NOT_AVAILABLE if the current application is registered +// as the protocol handler for the given protocol +NS_IMETHODIMP nsInternetConfigService::HasProtocolHandler(const char *protocol, PRBool *_retval) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + *_retval = PR_FALSE; // presume the OS doesn't have a handler + nsresult rv = NS_OK; + + // Since protocol comes in with _just_ the protocol we have to add a ':' to + // the end of it or LaunchServices will be very unhappy with the CFURLRef + // created from it (crashes trying to look up a handler for it with + // LSGetApplicationForURL, at least under 10.2.1) + nsCAutoString scheme(protocol); + scheme += ":"; + CFURLRef myURLRef = ::CFURLCreateWithBytes( + kCFAllocatorDefault, + (const UInt8 *)scheme.get(), + scheme.Length(), + kCFStringEncodingUTF8, NULL); + if (myURLRef) + { + FSRef appFSRef; + + if (::LSGetApplicationForURL(myURLRef, kLSRolesAll, &appFSRef, NULL) == noErr) + { // Now see if the FSRef for the found app == the running app + ProcessSerialNumber psn; + if (::GetCurrentProcess(&psn) == noErr) + { + FSRef runningAppFSRef; + if (::GetProcessBundleLocation(&psn, &runningAppFSRef) == noErr) + { + if (::FSCompareFSRefs(&appFSRef, &runningAppFSRef) == noErr) + { // Oops, the current app is the handler which would cause infinite recursion + rv = NS_ERROR_NOT_AVAILABLE; + } + else + { + *_retval = PR_TRUE; + } + } + } + } + ::CFRelease(myURLRef); + } + + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +// This method does the dirty work of traipsing through IC mappings database +// looking for a mapping for mimetype +nsresult nsInternetConfigService::GetMappingForMIMEType(const char *mimetype, const char *fileextension, ICMapEntry *entry) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + ICInstance inst = nsInternetConfig::GetInstance(); + OSStatus err = noErr; + ICAttr attr; + Handle prefH; + PRBool domimecheck = PR_TRUE; + PRBool gotmatch = PR_FALSE; + ICMapEntry ent; + + // if mime type is "unknown" or "octet stream" *AND* we have a file extension, + // then disable match on mime type + if (((nsCRT::strcasecmp(mimetype, UNKNOWN_CONTENT_TYPE) == 0) || + (nsCRT::strcasecmp(mimetype, APPLICATION_OCTET_STREAM) == 0)) && + fileextension) + domimecheck = PR_FALSE; + + entry->totalLength = 0; + if (inst) + { + err = ::ICBegin(inst, icReadOnlyPerm); + if (err == noErr) + { + prefH = ::NewHandle(2048); // picked 2048 out of thin air + if (prefH) + { + err = ::ICFindPrefHandle(inst, kICMapping, &attr, prefH); + if (err == noErr) + { + long count; + err = ::ICCountMapEntries(inst, prefH, &count); + if (err == noErr) + { + long pos; + for (long i = 1; i <= count; ++i) + { + err = ::ICGetIndMapEntry(inst, prefH, i, &pos, &ent); + if (err == noErr) + { + // first, do mime type check + if (domimecheck) + { + nsCAutoString temp((char *)&ent.MIMEType[1], (int)ent.MIMEType[0]); + if (!temp.EqualsIgnoreCase(mimetype)) + { + // we need to do mime check, and check failed + // nothing here to see, move along + continue; + } + } + if (fileextension) + { + // if fileextension was passed in, compare that also + if (ent.extension[0]) // check for non-empty pascal string + { + nsCAutoString temp((char *)&ent.extension[1], (int)ent.extension[0]); + if (temp.EqualsIgnoreCase(fileextension)) + { + // mime type and file extension match, we're outta here + gotmatch = PR_TRUE; + // copy over ICMapEntry + *entry = ent; + break; + } + } + } + else if(domimecheck) + { + // at this point, we've got our match because + // domimecheck is true, the mime strings match, and fileextension isn't passed in + // bad thing is we'll stop on first match, but what can you do? + gotmatch = PR_TRUE; + // copy over ICMapEntry + *entry = ent; + break; + } + } + } + } + } + ::DisposeHandle(prefH); + } + else + { + err = memFullErr; + } + err = ::ICEnd(inst); + if (err == noErr && gotmatch == PR_FALSE) + { + err = fnfErr; // return SOME kind of error + } + } + } + + if (err != noErr) + return NS_ERROR_FAILURE; + else + return NS_OK; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +nsresult nsInternetConfigService::FillMIMEInfoForICEntry(ICMapEntry& entry, nsIMIMEInfo ** mimeinfo) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + // create a mime info object and we'll fill it in based on the values from IC mapping entry + nsresult rv = NS_OK; + nsRefPtr info (new nsMIMEInfoMac()); + if (info) + { + nsCAutoString mimetype ((char *)&entry.MIMEType[1], entry.MIMEType[0]); + // check if entry.MIMEType is empty, if so, set mime type to APPLICATION_OCTET_STREAM + if (entry.MIMEType[0]) + info->SetMIMEType(mimetype); + else + { // The IC mappings seem to not be very agressive about determining the mime type if + // all we have is a type or creator code. This is a bandaid approach for when we + // get a file of type 'TEXT' with no mime type mapping so that we'll display the + // file rather than trying to download it. + if (entry.fileType == 'TEXT') + info->SetMIMEType(NS_LITERAL_CSTRING(TEXT_PLAIN)); + else + info->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM)); + } + + nsCAutoString temp; + + /* The internet config service seems to return the first extension + * from the map's list; however, that first extension is sometimes + * not the best one to use. Specifically, for image/jpeg, the + * internet config service will return "jfif", whereas the + * preferred extension is really "jpg". So, don't believe IC's + * lies, and ask NSURLFileTypeMappings instead (see bug 414201). + */ + NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings]; + NSString *mimeStr = [NSString stringWithCString:mimetype.get() encoding:NSASCIIStringEncoding]; + NSString *realExtension = map ? [map preferredExtensionForMIMEType:mimeStr] : NULL; + + if (realExtension) { + temp.Assign([realExtension cStringUsingEncoding:NSASCIIStringEncoding]); + + info->AppendExtension(temp); + } else { + // convert entry.extension which is a Str255 + // don't forget to remove the '.' in front of the file extension.... + temp.Assign((char *)&entry.extension[2], entry.extension[0] > 0 ? (int)entry.extension[0]-1 : 0); + + info->AppendExtension(temp); + } + + info->SetMacType(entry.fileType); + info->SetMacCreator(entry.fileCreator); + temp.Assign((char *) &entry.entryName[1], entry.entryName[0]); + info->SetDescription(NS_ConvertASCIItoUTF16(temp)); + + temp.Assign((char *) &entry.postAppName[1], entry.postAppName[0]); + info->SetDefaultDescription(NS_ConvertASCIItoUTF16(temp)); + + if (entry.flags & kICMapPostMask) + { + // there is a post processor app + info->SetPreferredAction(nsIMIMEInfo::useSystemDefault); + nsCOMPtr file (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + if (file) + { + rv = file->InitToAppWithCreatorCode(entry.postCreator); + if (rv == NS_OK) + { + nsCOMPtr nsfile = do_QueryInterface(file, &rv); + if (rv == NS_OK) + info->SetDefaultApplication(nsfile); + } + } + } + else + { + // there isn't a post processor app so set the preferred action to be save to disk. + info->SetPreferredAction(nsIMIMEInfo::saveToDisk); + } + + *mimeinfo = info; + NS_IF_ADDREF(*mimeinfo); + } + else // we failed to allocate the info object... + rv = NS_ERROR_FAILURE; + + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +/* void FillInMIMEInfo (in string mimetype, in string fileExtension, out nsIMIMEInfo mimeinfo); */ +NS_IMETHODIMP nsInternetConfigService::FillInMIMEInfo(const char *mimetype, const char * aFileExtension, nsIMIMEInfo **mimeinfo) +{ + nsresult rv; + ICMapEntry entry; + + NS_ENSURE_ARG_POINTER(mimeinfo); + *mimeinfo = nsnull; + + if (aFileExtension && *aFileExtension) + { + nsCAutoString fileExtension; + fileExtension.Assign("."); + fileExtension.Append(aFileExtension); + rv = GetMappingForMIMEType(mimetype, fileExtension.get(), &entry); + } + else + { + rv = GetMappingForMIMEType(mimetype, nsnull, &entry); + } + + if (rv == NS_OK) + rv = FillMIMEInfoForICEntry(entry, mimeinfo); + else + rv = NS_ERROR_FAILURE; + + return rv; +} + +NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromExtension(const char *aFileExt, nsIMIMEInfo **_retval) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + nsresult rv = NS_ERROR_FAILURE; + ICInstance instance = nsInternetConfig::GetInstance(); + if (instance) + { + nsCAutoString filename("foobar."); + filename += aFileExt; + Str255 pFileName; + ConvertCharStringToStr255(filename.get(), pFileName); + ICMapEntry entry; + OSStatus err = ::ICMapFilename(instance, pFileName, &entry); + if (err == noErr) + { + rv = FillMIMEInfoForICEntry(entry, _retval); + } + } + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + + +NS_IMETHODIMP nsInternetConfigService::GetMIMEInfoFromTypeCreator(PRUint32 aType, PRUint32 aCreator, const char *aFileExt, nsIMIMEInfo **_retval) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + nsresult rv = NS_ERROR_FAILURE; + ICInstance instance = nsInternetConfig::GetInstance(); + if (instance) + { + nsCAutoString filename("foobar."); + filename += aFileExt; + Str255 pFileName; + ConvertCharStringToStr255(filename.get(), pFileName); + ICMapEntry entry; + OSStatus err = ::ICMapTypeCreator(instance, aType, aCreator, pFileName, &entry); + if (err == noErr) + rv = FillMIMEInfoForICEntry(entry,_retval); + } + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + +nsresult nsInternetConfigService::GetICKeyPascalString(PRUint32 inIndex, const unsigned char*& outICKey) +{ + nsresult rv = NS_OK; + + switch (inIndex) + { + case eICColor_WebBackgroundColour: outICKey = kICWebBackgroundColour; break; + case eICColor_WebReadColor: outICKey = kICWebReadColor; break; + case eICColor_WebTextColor: outICKey = kICWebTextColor; break; + case eICColor_WebUnreadColor: outICKey = kICWebUnreadColor; break; + + case eICBoolean_WebUnderlineLinks: outICKey = kICWebUnderlineLinks; break; + case eICBoolean_UseFTPProxy: outICKey = kICUseFTPProxy; break; + case eICBoolean_UsePassiveFTP: outICKey = kICUsePassiveFTP; break; + case eICBoolean_UseHTTPProxy: outICKey = kICUseHTTPProxy; break; + case eICBoolean_NewMailDialog: outICKey = kICNewMailDialog; break; + case eICBoolean_NewMailFlashIcon: outICKey = kICNewMailFlashIcon; break; + case eICBoolean_NewMailPlaySound: outICKey = kICNewMailPlaySound; break; + case eICBoolean_UseGopherProxy: outICKey = kICUseGopherProxy; break; + case eICBoolean_UseSocks: outICKey = kICUseSocks; break; + + case eICString_WWWHomePage: outICKey = kICWWWHomePage; break; + case eICString_WebSearchPagePrefs: outICKey = kICWebSearchPagePrefs; break; + case eICString_MacSearchHost: outICKey = kICMacSearchHost; break; + case eICString_FTPHost: outICKey = kICFTPHost; break; + case eICString_FTPProxyUser: outICKey = kICFTPProxyUser; break; + case eICString_FTPProxyAccount: outICKey = kICFTPProxyAccount; break; + case eICString_FTPProxyHost: outICKey = kICFTPProxyHost; break; + case eICString_FTPProxyPassword: outICKey = kICFTPProxyPassword; break; + case eICString_HTTPProxyHost: outICKey = kICHTTPProxyHost; break; + case eICString_LDAPSearchbase: outICKey = kICLDAPSearchbase; break; + case eICString_LDAPServer: outICKey = kICLDAPServer; break; + case eICString_SMTPHost: outICKey = kICSMTPHost; break; + case eICString_Email: outICKey = kICEmail; break; + case eICString_MailAccount: outICKey = kICMailAccount; break; + case eICString_MailPassword: outICKey = kICMailPassword; break; + case eICString_NewMailSoundName: outICKey = kICNewMailSoundName; break; + case eICString_NNTPHost: outICKey = kICNNTPHost; break; + case eICString_NewsAuthUsername: outICKey = kICNewsAuthUsername; break; + case eICString_NewsAuthPassword: outICKey = kICNewsAuthPassword; break; + case eICString_InfoMacPreferred: outICKey = kICInfoMacPreferred; break; + case eICString_Organization: outICKey = kICOrganization; break; + case eICString_QuotingString: outICKey = kICQuotingString; break; + case eICString_RealName: outICKey = kICRealName; break; + case eICString_FingerHost: outICKey = kICFingerHost; break; + case eICString_GopherHost: outICKey = kICGopherHost; break; + case eICString_GopherProxy: outICKey = kICGopherProxy; break; + case eICString_SocksHost: outICKey = kICSocksHost; break; + case eICString_TelnetHost: outICKey = kICTelnetHost; break; + case eICString_IRCHost: outICKey = kICIRCHost; break; + case eICString_UMichPreferred: outICKey = kICUMichPreferred; break; + case eICString_WAISGateway: outICKey = kICWAISGateway; break; + case eICString_WhoisHost: outICKey = kICWhoisHost; break; + case eICString_PhHost: outICKey = kICPhHost; break; + case eICString_NTPHost: outICKey = kICNTPHost; break; + case eICString_ArchiePreferred: outICKey = kICArchiePreferred; break; + + case eICText_MailHeaders: outICKey = kICMailHeaders; break; + case eICText_Signature: outICKey = kICSignature; break; + case eICText_NewsHeaders: outICKey = kICNewsHeaders; break; + case eICText_SnailMailAddress: outICKey = kICSnailMailAddress; break; + case eICText_Plan: outICKey = kICPlan; break; + + default: + rv = NS_ERROR_INVALID_ARG; + } + return rv; +} + + +nsresult nsInternetConfigService::GetICPreference(PRUint32 inKey, + void *outData, long *ioSize) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + const unsigned char *icKey; + nsresult rv = GetICKeyPascalString(inKey, icKey); + if (rv == NS_OK) + { + ICInstance instance = nsInternetConfig::GetInstance(); + if (instance) + { + OSStatus err; + ICAttr junk; + err = ::ICGetPref(instance, icKey, &junk, outData, ioSize); + if (err != noErr) + rv = NS_ERROR_UNEXPECTED; + } + else + rv = NS_ERROR_FAILURE; + } + return rv; + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + + +NS_IMETHODIMP nsInternetConfigService::GetString(PRUint32 inKey, nsACString& value) +{ + long size = 256; + char buffer[256]; + nsresult rv = GetICPreference(inKey, (void *)&buffer, &size); + if (rv == NS_OK) + { + if (size == 0) + { + value = ""; + rv = NS_ERROR_UNEXPECTED; + } + else + { // Buffer is a Pascal string so adjust for length byte when assigning + value.Assign(&buffer[1], (unsigned char)buffer[0]); + } + } + return rv; +} + + +NS_IMETHODIMP nsInternetConfigService::GetColor(PRUint32 inKey, PRUint32 *outColor) +{ +// We're 'borrowing' this macro from nscolor.h so that uriloader doesn't depend on gfx. +// Make a color out of r,g,b values. This assumes that the r,g,b values are +// properly constrained to 0-255. This also assumes that a is 255. + + #define MAKE_NS_RGB(_r,_g,_b) \ + ((PRUint32) ((255 << 24) | ((_b)<<16) | ((_g)<<8) | (_r))) + + RGBColor buffer; + long size = sizeof(RGBColor); + nsresult rv = GetICPreference(inKey, &buffer, &size); + if (rv == NS_OK) + { + if (size != sizeof(RGBColor)) + { // default to white if we didn't get the right size + *outColor = MAKE_NS_RGB(0xff, 0xff, 0xff); + } + else + { // convert to a web color + *outColor = MAKE_NS_RGB(buffer.red >> 8, buffer.green >> 8, buffer.blue >> 8); + } + } + return rv; +} + + +NS_IMETHODIMP nsInternetConfigService::GetBoolean(PRUint32 inKey, PRBool *outFlag) +{ + Boolean buffer; + long size = sizeof(Boolean); + nsresult rv = GetICPreference(inKey, (void *)&buffer, &size); + if (rv == NS_OK) + { + if ((size_t)size < sizeof(Boolean)) + *outFlag = PR_FALSE; // default to false if we didn't get the right amount of data + else + *outFlag = buffer; + } + return rv; +} diff --git a/uriloader/exthandler/mac/nsMIMEInfoMac.mm b/uriloader/exthandler/mac/nsMIMEInfoMac.mm index b71a6d934c0..6af9ee522db 100644 --- a/uriloader/exthandler/mac/nsMIMEInfoMac.mm +++ b/uriloader/exthandler/mac/nsMIMEInfoMac.mm @@ -46,6 +46,7 @@ #include "nsMIMEInfoMac.h" #include "nsILocalFileMac.h" #include "nsIFileURL.h" +#include "nsIInternetConfigService.h" // We override this to make sure app bundles display their pretty name (without .app suffix) NS_IMETHODIMP nsMIMEInfoMac::GetDefaultDescription(nsAString& aDefaultDescription) @@ -123,29 +124,16 @@ nsMIMEInfoMac::LaunchWithFile(nsIFile *aFile) nsresult nsMIMEInfoMac::LoadUriInternal(nsIURI *aURI) { - NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - NS_ENSURE_ARG_POINTER(aURI); - nsresult rv = NS_ERROR_FAILURE; - + nsCAutoString uri; - aURI->GetSpec(uri); + aURI->GetAsciiSpec(uri); if (!uri.IsEmpty()) { - CFURLRef myURLRef = ::CFURLCreateWithBytes(kCFAllocatorDefault, - (const UInt8*)uri.get(), - strlen(uri.get()), - kCFStringEncodingUTF8, - NULL); - if (myURLRef) { - OSStatus status = ::LSOpenCFURLRef(myURLRef, NULL); - if (status == noErr) - rv = NS_OK; - ::CFRelease(myURLRef); - } + nsCOMPtr icService = + do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID); + if (icService) + rv = icService->LaunchURL(uri.get()); } - return rv; - - NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } diff --git a/uriloader/exthandler/mac/nsOSHelperAppService.h b/uriloader/exthandler/mac/nsOSHelperAppService.h index 578a14604bb..a21a43621f6 100644 --- a/uriloader/exthandler/mac/nsOSHelperAppService.h +++ b/uriloader/exthandler/mac/nsOSHelperAppService.h @@ -74,6 +74,10 @@ public: nsresult OSProtocolHandlerExists(const char * aScheme, PRBool * aHandlerExists); + +protected: + // add any mac specific service state here + void UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo); }; #endif // nsOSHelperAppService_h__ diff --git a/uriloader/exthandler/mac/nsOSHelperAppService.mm b/uriloader/exthandler/mac/nsOSHelperAppService.mm index 4357dcd12b3..2be7c199e1a 100644 --- a/uriloader/exthandler/mac/nsOSHelperAppService.mm +++ b/uriloader/exthandler/mac/nsOSHelperAppService.mm @@ -54,6 +54,7 @@ #include "nsMemory.h" #include "nsCRT.h" #include "nsMIMEInfoMac.h" +#include "nsIInternetConfigService.h" #include "nsEmbedCID.h" #import @@ -69,27 +70,6 @@ extern "C" { CFURLRef *appURL); } -/* This is an undocumented interface (in the Foundation framework) that has - * been stable since at least 10.2.8 and is still present on SnowLeopard. - * Furthermore WebKit has three public methods (in WebKitSystemInterface.h) - * that are thin wrappers around this interface's last three methods. So - * it's unlikely to change anytime soon. Now that we're no longer using - * Internet Config Services, this is the only way to look up a MIME type - * from an extension, or vice versa. - */ -@class NSURLFileTypeMappingsInternal; - -@interface NSURLFileTypeMappings : NSObject -{ - NSURLFileTypeMappingsInternal *_internal; -} - -+ (NSURLFileTypeMappings*)sharedMappings; -- (NSString*)MIMETypeForExtension:(NSString*)aString; -- (NSString*)preferredExtensionForMIMEType:(NSString*)aString; -- (NSArray*)extensionsForMIMEType:(NSString*)aString; -@end - nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService() { } @@ -99,16 +79,29 @@ nsOSHelperAppService::~nsOSHelperAppService() nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists) { - CFStringRef schemeString = ::CFStringCreateWithBytes(kCFAllocatorDefault, - (const UInt8*)aProtocolScheme, - strlen(aProtocolScheme), - kCFStringEncodingUTF8, - false); - CFStringRef handlerString = ::LSCopyDefaultHandlerForURLScheme(schemeString); - *aHandlerExists = !!handlerString; - ::CFRelease(handlerString); - ::CFRelease(schemeString); - return NS_OK; + // look up the protocol scheme in Internet Config....if we find a match then we have a handler for it... + *aHandlerExists = PR_FALSE; + // ask the internet config service to look it up for us... + nsresult rv = NS_OK; + nsCOMPtr icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + if (icService) + { + rv = icService->HasProtocolHandler(aProtocolScheme, aHandlerExists); + if (rv == NS_ERROR_NOT_AVAILABLE) + { + // There is a protocol handler, but it's the current app! We can't let + // the current app handle the protocol, as that'll get us into an infinite + // loop, so we just pretend there's no protocol handler available. + *aHandlerExists = PR_FALSE; + rv = NS_OK; + + // FIXME: instead of pretending there's no protocol handler available, + // let the caller know about the loop so it can deal with the problem + // (i.e. either fix it automatically, if there's some way to do that, + // or just provide the user with options for fixing it manually). + } + } + return rv; } NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval) @@ -217,14 +210,21 @@ nsresult nsOSHelperAppService::GetFileTokenForPath(const PRUnichar * aPlatformAp NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } +/////////////////////////// +// method overrides --> use internet config information for mime type lookup. +/////////////////////////// NS_IMETHODIMP nsOSHelperAppService::GetFromTypeAndExtension(const nsACString& aType, const nsACString& aFileExt, nsIMIMEInfo ** aMIMEInfo) { - return nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo); + // first, ask our base class.... + nsresult rv = nsExternalHelperAppService::GetFromTypeAndExtension(aType, aFileExt, aMIMEInfo); + if (NS_SUCCEEDED(rv) && *aMIMEInfo) + { + UpdateCreatorInfo(*aMIMEInfo); + } + return rv; } -// aMIMEType and aFileExt might not match, This method's documentation (in -// nsExternalHelperAppService.h) says that the MIME type is given preference. already_AddRefed nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, @@ -232,155 +232,101 @@ nsOSHelperAppService::GetMIMEInfoFromOS(const nsACString& aMIMEType, { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSNULL; - *aFound = PR_FALSE; + nsIMIMEInfo* mimeInfo = nsnull; + *aFound = PR_TRUE; const nsCString& flatType = PromiseFlatCString(aMIMEType); const nsCString& flatExt = PromiseFlatCString(aFileExt); - PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s'\n", - flatType.get(), flatExt.get())); + // ask the internet config service to look it up for us... + nsCOMPtr icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + PR_LOG(mLog, PR_LOG_DEBUG, ("Mac: HelperAppService lookup for type '%s' ext '%s' (IC: 0x%p)\n", + flatType.get(), flatExt.get(), icService.get())); + if (icService) + { + nsCOMPtr miByType, miByExt; + if (!aMIMEType.IsEmpty()) + icService->FillInMIMEInfo(flatType.get(), flatExt.get(), getter_AddRefs(miByType)); - // Create a Mac-specific MIME info so we can use Mac-specific members. - nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType); - if (!mimeInfoMac) - return nsnull; - NS_ADDREF(mimeInfoMac); + PRBool hasDefault = PR_FALSE; + if (miByType) + miByType->GetHasDefaultHandler(&hasDefault); - OSStatus err; - PRBool haveAppForType = PR_FALSE; - PRBool haveAppForExt = PR_FALSE; - PRBool typeAppIsDefault = PR_FALSE; - PRBool extAppIsDefault = PR_FALSE; - FSRef typeAppFSRef; - FSRef extAppFSRef; - - if (!aMIMEType.IsEmpty()) { - CFURLRef appURL = NULL; - CFStringRef CFType = ::CFStringCreateWithCString(NULL, flatType.get(), kCFStringEncodingUTF8); - err = ::LSCopyApplicationForMIMEType(CFType, kLSRolesAll, &appURL); - if ((err == noErr) && appURL && ::CFURLGetFSRef(appURL, &typeAppFSRef)) { - haveAppForType = PR_TRUE; - PR_LOG(mLog, PR_LOG_DEBUG, ("LSCopyApplicationForMIMEType found a default application\n")); + if (!aFileExt.IsEmpty() && (!hasDefault || !miByType)) { + icService->GetMIMEInfoFromExtension(flatExt.get(), getter_AddRefs(miByExt)); + if (miByExt && !aMIMEType.IsEmpty()) { + // XXX see XXX comment below + nsIMIMEInfo* pByExt = miByExt.get(); + nsMIMEInfoBase* byExt = static_cast(pByExt); + byExt->SetMIMEType(aMIMEType); + } } - if (appURL) - ::CFRelease(appURL); - ::CFRelease(CFType); + PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: By Type: 0x%p By Ext: 0x%p type has default: %s\n", + miByType.get(), miByExt.get(), hasDefault ? "true" : "false")); + + // If we got two matches, and the type has no default app, copy default app + if (!hasDefault && miByType && miByExt) { + // IC currently always uses nsMIMEInfoBase-derived classes. + // When it stops doing that, this code will need changing. + // XXX This assumes that IC will give os an nsMIMEInfoBase. I'd use + // dynamic_cast but that crashes. + // XXX these pBy* variables are needed because .get() returns an + // nsDerivedSafe thingy that can't be cast to nsMIMEInfoBase* + nsIMIMEInfo* pByType = miByType.get(); + nsIMIMEInfo* pByExt = miByExt.get(); + nsMIMEInfoBase* byType = static_cast(pByType); + nsMIMEInfoBase* byExt = static_cast(pByExt); + if (!byType || !byExt) { + NS_ERROR("IC gave us an nsIMIMEInfo that's no nsMIMEInfoBase! Fix nsOSHelperAppService."); + return nsnull; + } + // Copy the attributes of miByType onto miByExt + byType->CopyBasicDataTo(byExt); + miByType = miByExt; + } + if (miByType) + miByType.swap(mimeInfo); + else if (miByExt) + miByExt.swap(mimeInfo); } - if (!aFileExt.IsEmpty()) { + + if (!mimeInfo) { + *aFound = PR_FALSE; + PR_LOG(mLog, PR_LOG_DEBUG, ("Creating new mimeinfo\n")); + // Create a Mac-specific MIME info so we can use Mac-specific members. + nsMIMEInfoMac* mimeInfoMac = new nsMIMEInfoMac(aMIMEType); + if (!mimeInfoMac) + return nsnull; + NS_ADDREF(mimeInfoMac); + + if (!aFileExt.IsEmpty()) + mimeInfoMac->AppendExtension(aFileExt); + + // Now see if Launch Services knows of an application that should be run for this type. + OSStatus err; + FSRef appFSRef; CFStringRef CFExt = ::CFStringCreateWithCString(NULL, flatExt.get(), kCFStringEncodingUTF8); err = ::LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFExt, - kLSRolesAll, &extAppFSRef, nsnull); + kLSRolesAll, &appFSRef, nsnull); if (err == noErr) { - haveAppForExt = PR_TRUE; - PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n")); - } - } - - if (haveAppForType && haveAppForExt) { - typeAppIsDefault = PR_TRUE; - // Only add the extension if aMIMEType and aFileExt match. - if (::FSCompareFSRefs((const FSRef *) &typeAppFSRef, (const FSRef *) &extAppFSRef) == noErr) - mimeInfoMac->AppendExtension(aFileExt); - *aFound = PR_TRUE; - } else if (haveAppForType) { - typeAppIsDefault = PR_TRUE; - *aFound = PR_TRUE; - } else if (haveAppForExt) { - extAppIsDefault = PR_TRUE; - mimeInfoMac->AppendExtension(aFileExt); - *aFound = PR_TRUE; - } - - if (aMIMEType.IsEmpty()) { - if (haveAppForExt) { - // If aMIMEType is empty and we've found a default app for aFileExt, try - // to get the MIME type from aFileExt. (It might also be worth doing - // this when aMIMEType isn't empty but haveAppForType is false -- but - // the doc for this method says that if we have a MIME type (in - // aMIMEType), we need to give it preference.) - NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings]; - NSString *extStr = [NSString stringWithCString:flatExt.get() encoding:NSASCIIStringEncoding]; - NSString *typeStr = map ? [map MIMETypeForExtension:extStr] : NULL; - if (typeStr) { - nsCAutoString mimeType; - mimeType.Assign((char *)[typeStr cStringUsingEncoding:NSASCIIStringEncoding]); - mimeInfoMac->SetMIMEType(mimeType); + nsCOMPtr app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + if (!app) { + ::CFRelease(CFExt); + NS_RELEASE(mimeInfoMac); + return nsnull; } + app->InitWithFSRef(&appFSRef); + mimeInfoMac->SetDefaultApplication(app); + PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo found a default application\n")); } else { - // Otherwise set the MIME type to a reasonable fallback. - mimeInfoMac->SetMIMEType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM)); + // Just leave the default application unset. + PR_LOG(mLog, PR_LOG_DEBUG, ("LSGetApplicationForInfo returned error code %d; default application was not set\n", err)); } + mimeInfo = mimeInfoMac; + ::CFRelease(CFExt); } - - if (typeAppIsDefault || extAppIsDefault) { - nsCOMPtr app(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); - if (!app) { - NS_RELEASE(mimeInfoMac); - return nsnull; - } - - CFStringRef CFAppName = NULL; - if (typeAppIsDefault) { - app->InitWithFSRef(&typeAppFSRef); - ::LSCopyItemAttribute((const FSRef *) &typeAppFSRef, kLSRolesAll, - kLSItemDisplayName, (CFTypeRef *) &CFAppName); - } else { - app->InitWithFSRef(&extAppFSRef); - ::LSCopyItemAttribute((const FSRef *) &extAppFSRef, kLSRolesAll, - kLSItemDisplayName, (CFTypeRef *) &CFAppName); - } - if (CFAppName) { - nsAutoTArray buffer; - CFIndex appNameLength = ::CFStringGetLength(CFAppName); - buffer.SetLength(appNameLength); - ::CFStringGetCharacters(CFAppName, CFRangeMake(0, appNameLength), - buffer.Elements()); - nsAutoString appName; - appName.Assign(buffer.Elements(), appNameLength); - mimeInfoMac->SetDefaultDescription(appName); - ::CFRelease(CFAppName); - } - - mimeInfoMac->SetDefaultApplication(app); - mimeInfoMac->SetPreferredAction(nsIMIMEInfo::useSystemDefault); - } else { - mimeInfoMac->SetPreferredAction(nsIMIMEInfo::saveToDisk); - } - - nsCAutoString mimeType; - mimeInfoMac->GetMIMEType(mimeType); - if (!mimeType.IsEmpty()) { - // If we have a MIME type, make sure its preferred extension is included - // in our list. - NSURLFileTypeMappings *map = [NSURLFileTypeMappings sharedMappings]; - NSString *typeStr = [NSString stringWithCString:mimeType.get() encoding:NSASCIIStringEncoding]; - NSString *extStr = map ? [map preferredExtensionForMIMEType:typeStr] : NULL; - if (extStr) { - nsCAutoString preferredExt; - preferredExt.Assign((char *)[extStr cStringUsingEncoding:NSASCIIStringEncoding]); - mimeInfoMac->AppendExtension(preferredExt); - } - - CFStringRef CFType = ::CFStringCreateWithCString(NULL, mimeType.get(), kCFStringEncodingUTF8); - CFStringRef CFTypeDesc = NULL; - if (::LSCopyKindStringForMIMEType(CFType, &CFTypeDesc) == noErr) { - nsAutoTArray buffer; - CFIndex typeDescLength = ::CFStringGetLength(CFTypeDesc); - buffer.SetLength(typeDescLength); - ::CFStringGetCharacters(CFTypeDesc, CFRangeMake(0, typeDescLength), - buffer.Elements()); - nsAutoString typeDesc; - typeDesc.Assign(buffer.Elements(), typeDescLength); - mimeInfoMac->SetDescription(typeDesc); - } - if (CFTypeDesc) - ::CFRelease(CFTypeDesc); - ::CFRelease(CFType); - } - - PR_LOG(mLog, PR_LOG_DEBUG, ("OS gave us: type '%s' found '%i'\n", mimeType.get(), *aFound)); - - return mimeInfoMac; + + return mimeInfo; NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL; } @@ -414,3 +360,33 @@ nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme, return NS_OK; } + +// we never want to use a hard coded value for the creator and file type for the mac. always look these values up +// from internet config. +void nsOSHelperAppService::UpdateCreatorInfo(nsIMIMEInfo * aMIMEInfo) +{ + PRUint32 macCreatorType; + PRUint32 macFileType; + aMIMEInfo->GetMacType(&macFileType); + aMIMEInfo->GetMacCreator(&macCreatorType); + + if (macFileType == 0 || macCreatorType == 0) + { + // okay these values haven't been initialized yet so fetch a mime object from internet config. + nsCAutoString mimeType; + aMIMEInfo->GetMIMEType(mimeType); + nsCOMPtr icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + if (icService) + { + nsCOMPtr osMimeObject; + icService->FillInMIMEInfo(mimeType.get(), nsnull, getter_AddRefs(osMimeObject)); + if (osMimeObject) + { + osMimeObject->GetMacType(&macFileType); + osMimeObject->GetMacCreator(&macCreatorType); + aMIMEInfo->SetMacCreator(macCreatorType); + aMIMEInfo->SetMacType(macFileType); + } // if we got an os object + } // if we got the ic service + } // if the creator or file type hasn't been initialized yet +} diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index 78bb6315036..259d15a78f6 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -92,6 +92,7 @@ #ifdef XP_MACOSX #include "nsILocalFileMac.h" +#include "nsIInternetConfigService.h" #ifndef __LP64__ #include "nsIAppleFileDecoder.h" #endif @@ -491,6 +492,8 @@ struct nsExtraMimeTypeEntry { const char* mMimeType; const char* mFileExtensions; const char* mDescription; + PRUint32 mMactype; + PRUint32 mMacCreator; }; #ifdef XP_MACOSX @@ -509,39 +512,39 @@ struct nsExtraMimeTypeEntry { static nsExtraMimeTypeEntry extraMimeEntries [] = { #if defined(VMS) - { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File" }, + { APPLICATION_OCTET_STREAM, "exe,com,bin,sav,bck,pcsi,dcx_axpexe,dcx_vaxexe,sfx_axpexe,sfx_vaxexe", "Binary File", 0, 0 }, #elif defined(XP_MACOSX) // don't define .bin on the mac...use internet config to look that up... - { APPLICATION_OCTET_STREAM, "exe,com", "Binary File" }, + { APPLICATION_OCTET_STREAM, "exe,com", "Binary File", 0, 0 }, #else - { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File" }, + { APPLICATION_OCTET_STREAM, "exe,com,bin", "Binary File", 0, 0 }, #endif - { APPLICATION_GZIP2, "gz", "gzip" }, - { "application/x-arj", "arj", "ARJ file" }, - { APPLICATION_XPINSTALL, "xpi", "XPInstall Install" }, - { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File" }, - { APPLICATION_JAVASCRIPT, "js", "Javascript Source File" }, - { IMAGE_ART, "art", "ART Image" }, - { IMAGE_BMP, "bmp", "BMP Image" }, - { IMAGE_GIF, "gif", "GIF Image" }, - { IMAGE_ICO, "ico,cur", "ICO Image" }, - { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image" }, - { IMAGE_PNG, "png", "PNG Image" }, - { IMAGE_TIFF, "tiff,tif", "TIFF Image" }, - { IMAGE_XBM, "xbm", "XBM Image" }, - { "image/svg+xml", "svg", "Scalable Vector Graphics" }, - { MESSAGE_RFC822, "eml", "RFC-822 data" }, - { TEXT_PLAIN, "txt,text", "Text File" }, - { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language" }, - { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language" }, - { APPLICATION_RDF, "rdf", "Resource Description Framework" }, - { TEXT_XUL, "xul", "XML-Based User Interface Language" }, - { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language" }, - { TEXT_CSS, "css", "Style Sheet" }, - { VIDEO_OGG, "ogv", "Ogg Video" }, - { VIDEO_OGG, "ogg", "Ogg Video" }, - { APPLICATION_OGG, "ogg", "Ogg Video"}, - { AUDIO_OGG, "oga", "Ogg Audio" }, - { AUDIO_WAV, "wav", "Waveform Audio" } + { APPLICATION_GZIP2, "gz", "gzip", 0, 0 }, + { "application/x-arj", "arj", "ARJ file", 0,0 }, + { APPLICATION_XPINSTALL, "xpi", "XPInstall Install", MAC_TYPE('xpi*'), MAC_TYPE('MOSS') }, + { APPLICATION_POSTSCRIPT, "ps,eps,ai", "Postscript File", 0, 0 }, + { APPLICATION_JAVASCRIPT, "js", "Javascript Source File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { IMAGE_ART, "art", "ART Image", 0, 0 }, + { IMAGE_BMP, "bmp", "BMP Image", 0, 0 }, + { IMAGE_GIF, "gif", "GIF Image", 0,0 }, + { IMAGE_ICO, "ico,cur", "ICO Image", 0, 0 }, + { IMAGE_JPG, "jpeg,jpg,jfif,pjpeg,pjp", "JPEG Image", 0, 0 }, + { IMAGE_PNG, "png", "PNG Image", 0, 0 }, + { IMAGE_TIFF, "tiff,tif", "TIFF Image", 0, 0 }, + { IMAGE_XBM, "xbm", "XBM Image", 0, 0 }, + { "image/svg+xml", "svg", "Scalable Vector Graphics", MAC_TYPE('svg '), MAC_TYPE('ttxt') }, + { MESSAGE_RFC822, "eml", "RFC-822 data", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') }, + { TEXT_PLAIN, "txt,text", "Text File", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { TEXT_HTML, "html,htm,shtml,ehtml", "HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('MOSS') }, + { "application/xhtml+xml", "xhtml,xht", "Extensible HyperText Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { APPLICATION_RDF, "rdf", "Resource Description Framework", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { TEXT_XUL, "xul", "XML-Based User Interface Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { TEXT_XML, "xml,xsl,xbl", "Extensible Markup Language", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { TEXT_CSS, "css", "Style Sheet", MAC_TYPE('TEXT'), MAC_TYPE('ttxt') }, + { VIDEO_OGG, "ogv", "Ogg Video", 0, 0 }, + { VIDEO_OGG, "ogg", "Ogg Video", 0, 0 }, + { APPLICATION_OGG, "ogg", "Ogg Video", 0, 0}, + { AUDIO_OGG, "oga", "Ogg Audio", 0, 0 }, + { AUDIO_WAV, "wav", "Waveform Audio", 0, 0 } }; #undef MAC_TYPE @@ -1359,6 +1362,19 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel * aChannel) mTempFile->IsExecutable(&mTempFileIsExecutable); #endif +#ifdef XP_MACOSX + // Now that the file exists set Mac type if the file has no extension + // and we can determine a type. + if (ext.IsEmpty() && mMimeInfo) { + nsCOMPtr macfile = do_QueryInterface(mTempFile); + if (macfile) { + PRUint32 type; + mMimeInfo->GetMacType(&type); + macfile->SetFileType(type); + } + } +#endif + nsCOMPtr outputStream; rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTempFile, PR_WRONLY | PR_CREATE_FILE, 0600); @@ -2679,10 +2695,28 @@ NS_IMETHODIMP nsExternalHelperAppService::GetTypeFromFile(nsIFile* aFile, nsACSt } } } + +#ifdef XP_MACOSX + nsCOMPtr macFile; + macFile = do_QueryInterface( aFile, &rv ); + if (NS_SUCCEEDED( rv ) && fileExt.IsEmpty()) + { + PRUint32 type, creator; + macFile->GetFileType( (OSType*)&type ); + macFile->GetFileCreator( (OSType*)&creator ); + nsCOMPtr icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + if (icService) + { + rv = icService->GetMIMEInfoFromTypeCreator(type, creator, fileExt.get(), getter_AddRefs(info)); + if (NS_SUCCEEDED(rv)) + return info->GetMIMEType(aContentType); + } + } +#endif + // Windows, unix and mac when no type match occured. if (fileExt.IsEmpty()) - return NS_ERROR_FAILURE; - + return NS_ERROR_FAILURE; return GetTypeFromExtension(fileExt, aContentType); } @@ -2704,6 +2738,9 @@ nsresult nsExternalHelperAppService::FillMIMEInfoForMimeTypeFromExtras( // This is the one. Set attributes appropriately. aMIMEInfo->SetFileExtensions(nsDependentCString(extraMimeEntries[index].mFileExtensions)); aMIMEInfo->SetDescription(NS_ConvertASCIItoUTF16(extraMimeEntries[index].mDescription)); + aMIMEInfo->SetMacType(extraMimeEntries[index].mMactype); + aMIMEInfo->SetMacCreator(extraMimeEntries[index].mMacCreator); + return NS_OK; } } diff --git a/uriloader/exthandler/nsIInternetConfigService.idl b/uriloader/exthandler/nsIInternetConfigService.idl new file mode 100644 index 00000000000..b582ecf3983 --- /dev/null +++ b/uriloader/exthandler/nsIInternetConfigService.idl @@ -0,0 +1,126 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.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 Communicator client code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface nsIMIMEInfo; +interface nsIURL; + +%{C++ + +#include + +#define NS_INTERNETCONFIGSERVICE_CONTRACTID \ +"@mozilla.org/mac/internet-config-service;1" + +%} + +native FSSpec(FSSpec); +[ptr] native FSSpecPtr(FSSpec); + +[scriptable, uuid(38C37AA2-9F74-4B24-A70C-AC3AE4308210)] +interface nsIInternetConfigService : nsISupports +{ + const unsigned long eICColor_WebBackgroundColour = 1; + const unsigned long eICColor_WebReadColor = 2; + const unsigned long eICColor_WebTextColor = 3; + const unsigned long eICColor_WebUnreadColor = 4; + const unsigned long eICBoolean_WebUnderlineLinks = 11; + const unsigned long eICString_WWWHomePage = 101; + const unsigned long eICString_WebSearchPagePrefs = 102; + const unsigned long eICString_MacSearchHost = 103; + const unsigned long eICString_FTPHost = 121; + const unsigned long eICBoolean_UsePassiveFTP = 122; + const unsigned long eICBoolean_UseFTPProxy = 123; const unsigned long eICString_FTPProxyUser = 124; + const unsigned long eICString_FTPProxyAccount = 125; const unsigned long eICString_FTPProxyHost = 126; + const unsigned long eICString_FTPProxyPassword = 127; + const unsigned long eICBoolean_UseHTTPProxy = 130; const unsigned long eICString_HTTPProxyHost = 131; + const unsigned long eICString_LDAPSearchbase = 201; const unsigned long eICString_LDAPServer = 202; + const unsigned long eICString_SMTPHost = 221; + const unsigned long eICString_Email = 222; + const unsigned long eICString_MailAccount = 223; const unsigned long eICString_MailPassword = 224; + const unsigned long eICText_MailHeaders = 225; const unsigned long eICText_Signature = 226; + const unsigned long eICBoolean_NewMailDialog = 231; + const unsigned long eICBoolean_NewMailFlashIcon = 232; + const unsigned long eICBoolean_NewMailPlaySound = 233; const unsigned long eICString_NewMailSoundName = 234; + const unsigned long eICString_NNTPHost = 241; + const unsigned long eICString_NewsAuthUsername = 242; const unsigned long eICString_NewsAuthPassword = 243; + const unsigned long eICText_NewsHeaders = 244; + const unsigned long eICString_InfoMacPreferred = 245; + const unsigned long eICString_Organization = 251; const unsigned long eICString_RealName = 252; + const unsigned long eICText_SnailMailAddress = 253; + const unsigned long eICString_QuotingString = 254; + const unsigned long eICString_GopherHost = 301; + const unsigned long eICBoolean_UseGopherProxy = 302; const unsigned long eICString_GopherProxy = 303; + const unsigned long eICBoolean_UseSocks = 321; const unsigned long eICString_SocksHost = 322; + const unsigned long eICString_TelnetHost = 331; + const unsigned long eICString_IRCHost = 341; + const unsigned long eICString_NTPHost = 351; + const unsigned long eICString_WAISGateway = 381; + const unsigned long eICString_FingerHost = 382; const unsigned long eICText_Plan = 383; + const unsigned long eICString_WhoisHost = 384; + const unsigned long eICString_PhHost = 385; + const unsigned long eICString_ArchiePreferred = 386; + const unsigned long eICString_UMichPreferred = 391; + + const unsigned long eIICMapFlag_BinaryMask = 1; /* file should be transfered in binary as opposed to text mode*/ + const unsigned long eIICMapFlag_ResourceForkMask = 2; /* the resource fork of the file is significant*/ + const unsigned long eIICMapFlag_DataForkMask = 4; /* the data fork of the file is significant*/ + const unsigned long eIICMapFlag_PostMask = 8; /* post process using post fields*/ + const unsigned long eIICMapFlag_NotIncomingMask = 16; /* ignore this mapping for incoming files*/ + const unsigned long eIICMapFlag_NotOutgoingMask = 32; /* ignore this mapping for outgoing files*/ + + + void launchURL(in string url); + + boolean hasMappingForMIMEType(in string mimetype); + + boolean hasProtocolHandler(in string protocol); + + // pass in a mime type or a file extension..... + void fillInMIMEInfo(in string mimetype, in string aFileExtension, out nsIMIMEInfo mimeinfo); + + void getMIMEInfoFromExtension(in string aFileExt, out nsIMIMEInfo mimeinfo); + + void getMIMEInfoFromTypeCreator(in PRUint32 aType, in PRUint32 aCreator, in string aFileExt, out nsIMIMEInfo mimeInfo); + + ACString getString(in unsigned long keyenum); + + unsigned long getColor(in unsigned long keyenum); + + boolean getBoolean(in unsigned long keyenum); +}; diff --git a/uriloader/exthandler/nsMIMEInfoImpl.cpp b/uriloader/exthandler/nsMIMEInfoImpl.cpp index c225b07da79..467c0c83b6b 100644 --- a/uriloader/exthandler/nsMIMEInfoImpl.cpp +++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp @@ -63,6 +63,8 @@ NS_INTERFACE_MAP_END_THREADSAFE // Constructors for a MIME handler. nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) : + mMacType(0), + mMacCreator(0), mType(aMIMEType), mClass(eMIMEInfo), mPreferredAction(nsIMIMEInfo::saveToDisk), @@ -71,6 +73,8 @@ nsMIMEInfoBase::nsMIMEInfoBase(const char *aMIMEType) : } nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aMIMEType) : + mMacType(0), + mMacCreator(0), mType(aMIMEType), mClass(eMIMEInfo), mPreferredAction(nsIMIMEInfo::saveToDisk), @@ -84,6 +88,8 @@ nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aMIMEType) : // for both and distinguish between the two kinds of handlers via the aClass // argument to this method, which can be either eMIMEInfo or eProtocolInfo. nsMIMEInfoBase::nsMIMEInfoBase(const nsACString& aType, HandlerClass aClass) : + mMacType(0), + mMacCreator(0), mType(aType), mClass(aClass), mPreferredAction(nsIMIMEInfo::saveToDisk), @@ -209,6 +215,42 @@ nsMIMEInfoBase::Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval) return NS_OK; } +NS_IMETHODIMP +nsMIMEInfoBase::GetMacType(PRUint32 *aMacType) +{ + *aMacType = mMacType; + + if (!mMacType) + return NS_ERROR_NOT_INITIALIZED; + + return NS_OK; +} + +NS_IMETHODIMP +nsMIMEInfoBase::SetMacType(PRUint32 aMacType) +{ + mMacType = aMacType; + return NS_OK; +} + +NS_IMETHODIMP +nsMIMEInfoBase::GetMacCreator(PRUint32 *aMacCreator) +{ + *aMacCreator = mMacCreator; + + if (!mMacCreator) + return NS_ERROR_NOT_INITIALIZED; + + return NS_OK; +} + +NS_IMETHODIMP +nsMIMEInfoBase::SetMacCreator(PRUint32 aMacCreator) +{ + mMacCreator = aMacCreator; + return NS_OK; +} + NS_IMETHODIMP nsMIMEInfoBase::SetFileExtensions(const nsACString& aExtensions) { @@ -371,6 +413,9 @@ nsMIMEInfoBase::CopyBasicDataTo(nsMIMEInfoBase* aOther) aOther->mType = mType; aOther->mDefaultAppDescription = mDefaultAppDescription; aOther->mExtensions = mExtensions; + + aOther->mMacType = mMacType; + aOther->mMacCreator = mMacCreator; } /* static */ diff --git a/uriloader/exthandler/nsMIMEInfoImpl.h b/uriloader/exthandler/nsMIMEInfoImpl.h index e762a32d009..eef8905e93d 100644 --- a/uriloader/exthandler/nsMIMEInfoImpl.h +++ b/uriloader/exthandler/nsMIMEInfoImpl.h @@ -79,6 +79,10 @@ class nsMIMEInfoBase : public nsIMIMEInfo { NS_IMETHOD GetMIMEType(nsACString & aMIMEType); NS_IMETHOD GetDescription(nsAString & aDescription); NS_IMETHOD SetDescription(const nsAString & aDescription); + NS_IMETHOD GetMacType(PRUint32 *aMacType); + NS_IMETHOD SetMacType(PRUint32 aMacType); + NS_IMETHOD GetMacCreator(PRUint32 *aMacCreator); + NS_IMETHOD SetMacCreator(PRUint32 aMacCreator); NS_IMETHOD Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval); NS_IMETHOD GetPreferredApplicationHandler(nsIHandlerApp * *aPreferredAppHandler); NS_IMETHOD SetPreferredApplicationHandler(nsIHandlerApp * aPreferredAppHandler); @@ -164,6 +168,7 @@ class nsMIMEInfoBase : public nsIMIMEInfo { // member variables nsTArray mExtensions; ///< array of file extensions associated w/ this MIME obj nsString mDescription; ///< human readable description + PRUint32 mMacType, mMacCreator; ///< Mac file type and creator nsCString mType; HandlerClass mClass; nsCOMPtr mPreferredApplication; diff --git a/widget/src/cocoa/nsLookAndFeel.mm b/widget/src/cocoa/nsLookAndFeel.mm index 8227b11b4d0..f0a8ef8dc71 100644 --- a/widget/src/cocoa/nsLookAndFeel.mm +++ b/widget/src/cocoa/nsLookAndFeel.mm @@ -38,6 +38,7 @@ #include "nsLookAndFeel.h" #include "nsObjCExceptions.h" +#include "nsIInternetConfigService.h" #include "nsIServiceManager.h" #include "nsNativeThemeColors.h" @@ -66,7 +67,17 @@ nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor) switch (aID) { case eColor_WindowBackground: - aColor = NS_RGB(0xff,0xff,0xff); + { + nsCOMPtr icService_wb (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + if (icService_wb) { + res = icService_wb->GetColor(nsIInternetConfigService::eICColor_WebBackgroundColour, &aColor); + if (NS_SUCCEEDED(res)) + return res; + } + + aColor = NS_RGB(0xff,0xff,0xff); // default to white if we didn't find it in internet config + res = NS_OK; + } break; case eColor_WindowForeground: aColor = NS_RGB(0x00,0x00,0x00); @@ -92,8 +103,17 @@ nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor) case eColor_TextBackground: aColor = NS_RGB(0xff,0xff,0xff); break; - case eColor_TextForeground: + case eColor_TextForeground: + { + nsCOMPtr icService_tf (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID)); + if (icService_tf) { + res = icService_tf->GetColor(nsIInternetConfigService::eICColor_WebTextColor, &aColor); + if (NS_SUCCEEDED(res)) + return res; + } aColor = NS_RGB(0x00,0x00,0x00); + res = NS_OK; + } break; case eColor_TextSelectBackground: res = GetMacBrushColor(kThemeBrushPrimaryHighlightColor, aColor, NS_RGB(0x00,0x00,0x00));