diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2009-04-01 11:54:14 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2009-04-01 11:54:14 +0000 |
commit | cc01b14ca1e76bcfd3abd6141d4250bc3d7cc7d5 (patch) | |
tree | 60df7856cad6c4b98e38560eff822f8668757597 /extensions/source/plugin/aqua/macmgr.cxx | |
parent | a90774683ad9f7e053f427619fcd2d6ee97ea5fa (diff) |
CWS-TOOLING: integrate CWS vcl100
2009-03-26 21:27:56 +0100 pl r270106 : #i10000# fix an include path missing when using configure
2009-03-16 12:18:24 +0100 pl r269518 : #i98963# revert change
2009-03-13 14:56:47 +0100 pl r269483 : #i98980# work around a mysterious crash
2009-03-12 20:02:48 +0100 pl r269440 : resolve some warnings
2009-03-12 19:30:32 +0100 pl r269439 : resolve some warnings
2009-03-12 18:07:47 +0100 pl r269432 : solve some warnings
2009-03-12 09:07:33 +0100 hdu r269358 : #i100134# remove obsolete RCS/CVS keywords from source
2009-03-11 21:18:28 +0100 pl r269355 : #i100134# change sft.h and ttcr.h to c++ headers
2009-03-11 20:19:15 +0100 pl r269353 : #i100134# remove some ugly C style lists
2009-03-11 18:19:35 +0100 hdu r269347 : #i100134# make psprint.fontsubset source C++ and make it compile
2009-03-11 14:44:35 +0100 hdu r269334 : #i99862# fix justification of vocalized hebrew (thanks hennerdrewes)
2009-03-11 13:40:35 +0100 pl r269327 : CWS-TOOLING: rebase CWS vcl100 to trunk@269297 (milestone: DEV300:m43)
2009-03-10 16:49:34 +0100 hdu r269284 : #i1000020# add style-matching heuristics for single-char stylenames
2009-03-10 15:42:53 +0100 hdu r269278 : use fast ASCII-matching for extracting attributes from PSName
2009-03-09 16:29:08 +0100 pl r269200 : #i98980# skip bundles that are not NP plugins
2009-03-09 13:26:14 +0100 hdu r269083 : #i99868# fix text breaking for large nCharExtra
2009-03-09 12:20:01 +0100 hdu r269078 : #i99868# fix text breaking for large nCharExtra
2009-03-06 17:35:27 +0100 pl r269032 : #i98980# mouse events
2009-03-06 17:10:14 +0100 pl r269024 : #i98980# flash animations, initial paint problem
2009-03-05 20:00:21 +0100 pl r268939 : #i98980# more plugin support
2009-03-05 15:35:06 +0100 pl r268914 : #i98980# first twitches of a live plugin
2009-03-05 15:34:10 +0100 pl r268913 : #i98980# access to carbon headers
2009-03-04 15:46:29 +0100 pl r268839 : #i98980# generalize vcl SystemChildWindow from QTMovieView to NSView
2009-03-04 15:40:20 +0100 pl r268838 : #i98980# generalize vcl SystemChildWindow from QTMovieView to NSView
2009-03-04 11:30:49 +0100 hdu r268801 : #i99722# for OSX any anisotropy reported for the display resolution is best ignored
2009-03-02 15:52:21 +0100 pl r268655 : #i99770# fix ambiguous looking if statements (thanks cmc)
2009-03-02 13:28:17 +0100 pl r268649 : #i99770# fix ambiguous looking if statements (thanks cmc)
2009-02-27 15:39:30 +0100 pl r268603 : #i97512# omit degenrate current matrix
2009-02-27 12:37:29 +0100 pl r268579 : #i99716# remove unused code (thanks cmc)
2009-02-27 11:21:18 +0100 pl r268569 : #i99705 remove unused code (thanks cmc)
2009-02-23 10:42:00 +0100 pl r268345 : #i99492# remove a typo (thanks tono)
2009-02-19 12:46:21 +0100 pl r268274 : #i99411# add new mimetype
2009-02-10 12:57:59 +0100 pl r267548 : #i98980# more aqua plugin changes
2009-02-06 16:50:34 +0100 pl r267475 : #i98980# plugin detection
2009-02-06 16:46:48 +0100 pl r267474 : #i98980# make debug compilation work
2009-02-06 12:16:37 +0100 pl r267449 : #98963# add missing wrapper
2009-02-04 20:06:59 +0100 pl r267402 : #i97135# work around a gcc x64 optimizer bug
2009-02-04 13:45:36 +0100 pl r267380 : #159153# do not emit empty glyph vector
2009-02-03 17:47:16 +0100 pl r267338 : #i98533# recent gtk versions do not support GTK_MODULES for accessibility anymore
2009-02-03 10:39:46 +0100 pl r267305 : #i97146# check if the idle formatted view is still valid
2009-01-28 11:23:23 +0100 pl r267045 : #i42227# #i48965# refinement of check markings images
2009-01-27 19:40:01 +0100 pl r267016 : #i42227# #i48965# change menus wrt checkmarks and images
Diffstat (limited to 'extensions/source/plugin/aqua/macmgr.cxx')
-rw-r--r-- | extensions/source/plugin/aqua/macmgr.cxx | 658 |
1 files changed, 497 insertions, 161 deletions
diff --git a/extensions/source/plugin/aqua/macmgr.cxx b/extensions/source/plugin/aqua/macmgr.cxx index a80bac015b27..26df705a1d97 100644 --- a/extensions/source/plugin/aqua/macmgr.cxx +++ b/extensions/source/plugin/aqua/macmgr.cxx @@ -28,236 +28,572 @@ * ************************************************************************/ -#include <cstdarg> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <osl/thread.h> -#include <rtl/strbuf.hxx> +#include "rtl/ustrbuf.hxx" +#include "rtl/strbuf.hxx" -#include <vcl/svapp.hxx> -#include <plugin/impl.hxx> +#include "plugin/impl.hxx" +#include "osl/file.h" +#include "osl/module.hxx" using namespace rtl; using namespace std; using namespace com::sun::star::uno; using namespace com::sun::star::plugin; -// Unix specific implementation -static bool CheckPlugin( const ByteString& rPath, list< PluginDescription* >& rDescriptions ) +namespace plugstringhelper { -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "Trying plugin %s ... ", rPath.GetBuffer() ); -#endif - xub_StrLen nPos = rPath.SearchBackward( '/' ); - if( nPos == STRING_NOTFOUND ) +rtl::OUString getString( CFStringRef i_xString ) +{ + rtl::OUStringBuffer aBuf; + if( i_xString ) { -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "no absolute path to plugin\n" ); -#endif - return false; + CFIndex nChars = CFStringGetLength( i_xString ); + CFRange aRange = { 0, nChars }; + aBuf.setLength( nChars ); + CFStringGetCharacters( i_xString, aRange, static_cast< UniChar* >(const_cast<sal_Unicode*>(aBuf.getStr())) ); } + return aBuf.makeStringAndClear(); +} + +rtl::OUString getString( CFURLRef i_xURL ) +{ + CFStringRef xString = CFURLGetString( i_xURL ); + return getString( xString ); +} + +CFMutableStringRef createString( const rtl::OUString& i_rString ) +{ + CFMutableStringRef xString = CFStringCreateMutable( NULL, 0 ); + if( xString ) + CFStringAppendCharacters( xString, i_rString.getStr(), i_rString.getLength() ); + return xString; +} + +CFURLRef createURL( const rtl::OUString& i_rString ) +{ + + CFMutableStringRef xMutableString = createString( i_rString ); + CFURLRef xURL = CFURLCreateWithString( NULL, xMutableString, NULL ); + CFRelease( xMutableString ); + return xURL; +} - ByteString aBaseName = rPath.Copy( nPos+1 ); - if( aBaseName.Equals( "libnullplugin.so" ) ) +rtl::OUString getURLFromPath( const rtl::OUString& i_rPath ) +{ + CFMutableStringRef xMutableString = createString( i_rPath ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + CFRelease( xMutableString ); + CFStringRef xString = CFURLGetString( xURL ); + rtl::OUString aRet = getString( xString ); + CFRelease( xURL ); + return aRet; +} + +CFURLRef createURLFromPath( const rtl::OUString& i_rPath ) +{ + CFMutableStringRef xMutableString = createString( i_rPath ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + return xURL; +} + +rtl::OUString CFURLtoOSLURL( CFURLRef i_xURL ) +{ + // make URL absolute + CFURLRef xAbsURL = CFURLCopyAbsoluteURL( i_xURL ); + // copy system path + CFStringRef xSysPath = CFURLCopyFileSystemPath( xAbsURL ? xAbsURL : i_xURL, kCFURLPOSIXPathStyle ); + if( xAbsURL ) + CFRelease( xAbsURL ); + rtl::OUString aSysPath( getString( xSysPath ) ); + CFRelease( xSysPath ); + rtl::OUString aFileURL; + osl_getFileURLFromSystemPath( aSysPath.pData, &aFileURL.pData ); + return aFileURL; +} + +} + +using namespace plugstringhelper; + +static int parsePlist( CFBundleRef i_xBundle, const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions ) +{ + CFTypeRef xMimeDict = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginMIMETypes")); + int nMimetypes = 0; + if( xMimeDict == 0 || + CFGetTypeID(xMimeDict) != CFDictionaryGetTypeID() || + (nMimetypes = CFDictionaryGetCount( static_cast<CFDictionaryRef>(xMimeDict))) <= 0 ) { -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "don't like %s\n", aBaseName.GetBuffer() ); -#endif - return false; + return 0; } - struct stat aStat; - if( stat( rPath.GetBuffer(), &aStat ) || ! S_ISREG( aStat.st_mode ) ) + // prepare an array of key and value refs + std::vector< CFTypeRef > aKeys( nMimetypes, CFTypeRef(NULL) ); + std::vector< CFTypeRef > aValues( nMimetypes, CFTypeRef(NULL) ); + CFDictionaryGetKeysAndValues(static_cast<CFDictionaryRef>(xMimeDict), &aKeys[0], &aValues[0] ); + + int nAdded = 0; + for( int i = 0; i < nMimetypes; i++ ) { + // get the mimetype + CFTypeRef xKey = aKeys[i]; + if( ! xKey || CFGetTypeID(xKey) != CFStringGetTypeID() ) + continue; + rtl::OUString aMimetype = getString( (CFStringRef)xKey ); + + // the correspoding value should be a dictionary + CFTypeRef xDict = aValues[i]; + if( ! xDict || CFGetTypeID( xDict ) != CFDictionaryGetTypeID() ) + continue; + + // get the extension list + CFTypeRef xExtArray = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginExtensions" ) ); + if( !xExtArray || CFGetTypeID( xExtArray ) != CFArrayGetTypeID() ) + continue; + + OUStringBuffer aExtBuf; + int nExtensions = CFArrayGetCount( (CFArrayRef)xExtArray ); + for( int n = 0; n < nExtensions; n++ ) + { + CFTypeRef xExt = CFArrayGetValueAtIndex( (CFArrayRef)xExtArray, n ); + if( xExt && CFGetTypeID( xExt ) == CFStringGetTypeID() ) + { + if( aExtBuf.getLength() > 0 ) + aExtBuf.append( sal_Unicode(';') ); + OUString aExt( getString( (CFStringRef)xExt ) ); + if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) + aExtBuf.appendAscii( "*." ); + aExtBuf.append( aExt ); + } + } + + // get the description string + CFTypeRef xDescString = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginTypeDescription" ) ); + if( !xDescString || CFGetTypeID( xDescString ) != CFStringGetTypeID() ) + continue; + rtl::OUString aDescription = getString( (CFStringRef)xDescString ); + + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = aMimetype; + // set extension line + pNew->Extension = aExtBuf.makeStringAndClear(); + // set description + pNew->Description= aDescription; + + io_rDescriptions.push_back( pNew ); + nAdded++; + #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "%s is not a regular file\n", rPath.GetBuffer() ); + fprintf( stderr, + "Inserting from PList:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() + ); #endif - return false; + } + return nAdded; +} + +static int parseMimeString( const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions, const char* i_pMime ) +{ + if( ! i_pMime ) + return 0; rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); - ByteString aCommand( "pluginapp.bin \"" ); - aCommand.Append( rPath ); - aCommand.Append( '"' ); + OStringBuffer aMIME; + aMIME.append( i_pMime ); - FILE* pResult = popen( aCommand.GetBuffer(), "r" ); - int nDescriptions = 0; - if( pResult ) + if( aMIME.getLength() < 1 ) + return 0; + + OString aLine = aMIME.makeStringAndClear(); + + int nAdded = 0; + sal_Int32 nIndex = 0; + while( nIndex != -1 ) { - OStringBuffer aMIME; - char buf[256]; - while( fgets( buf, sizeof( buf ), pResult ) ) + OString aType = aLine.getToken( 0, ';', nIndex ); + + sal_Int32 nTypeIndex = 0; + OString aMimetype = aType.getToken( 0, ':', nTypeIndex ); + OString aExtLine = aType.getToken( 0, ':', nTypeIndex ); + if( nTypeIndex < 0 ) // ensure at least three tokens + continue; + OString aDesc = aType.getToken( 0, ':', nTypeIndex ); + + // create extension list string + sal_Int32 nExtIndex = 0; + OStringBuffer aExtension; + while( nExtIndex != -1 ) { - for( size_t i = 0; i < sizeof(buf) && buf[i]; ++i ) + OString aExt = aExtLine.getToken( 0, ',', nExtIndex); + if( aExt.indexOf( "*." ) != 0 ) + aExtension.append( "*." ); + aExtension.append( aExt ); + if( nExtIndex != -1 ) + aExtension.append( ';' ); + } + + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = OStringToOUString( aMimetype, aEncoding ); + // set extension line + pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding ); + // set description + pNew->Description= OStringToOUString( aDesc, aEncoding ); + io_rDescriptions.push_back( pNew ); + nAdded++; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "Inserting from mime string:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, aEncoding ).getStr(), + OUStringToOString( pNew->Extension, aEncoding ).getStr(), + OUStringToOString( pNew->Description, aEncoding ).getStr() + ); +#endif + } + return nAdded; +} + +// this is so ugly it you want to tear your eyes out +static rtl::OUString GetNextPluginStringFromHandle(Handle h, short *index) +{ + char* pPascalBytes = (*h + *index); + sal_uInt32 nLen = (unsigned char)pPascalBytes[0]; + rtl::OStringBuffer aBuf( nLen ); + aBuf.append( pPascalBytes+1, nLen ); + *index += nLen + 1; + return rtl::OStringToOUString( aBuf.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +} + +static int parseMimeResource( CFBundleRef i_xBundle, + oslModule& i_rMod, + const rtl::OUString& i_rBundleURL, + list< PluginDescription* >& io_rDescriptions ) +{ + int nAdded = 0; + // just to hurt our eyes more there is an alternative mimetype function plus the possibility + // of a resource fork. Must be a case of think different. + #if __LP64__ + int + #else + SInt16 + #endif + xRes = 0; + BPSupportedMIMETypes aMIMETypesStrangeStruct = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; + + BP_GetSupportedMIMETypesUPP pBPGetSupp = (BP_GetSupportedMIMETypesUPP)osl_getAsciiFunctionSymbol( i_rMod, "BP_GetSupportedMIMETypes" ); + if( pBPGetSupp && + noErr == pBPGetSupp( &aMIMETypesStrangeStruct, 0 ) && + aMIMETypesStrangeStruct.typeStrings ) + { + HLock( aMIMETypesStrangeStruct.typeStrings ); + if( aMIMETypesStrangeStruct.infoStrings ) // it's possible some plugins have infoStrings missing + HLock( aMIMETypesStrangeStruct.infoStrings ); + } + else // Try to get data from the resource fork + { + xRes = CFBundleOpenBundleResourceMap( i_xBundle ); + if( xRes > 0 ) + { + aMIMETypesStrangeStruct.typeStrings = Get1Resource('STR#', 128); + if( aMIMETypesStrangeStruct.typeStrings ) { - if( buf[i] == '\n' ) - buf[i] = ';'; + DetachResource( aMIMETypesStrangeStruct.typeStrings ); + HLock( aMIMETypesStrangeStruct.typeStrings ); + aMIMETypesStrangeStruct.infoStrings = Get1Resource('STR#', 127); + if( aMIMETypesStrangeStruct.infoStrings ) + { + DetachResource( aMIMETypesStrangeStruct.infoStrings ); + HLock( aMIMETypesStrangeStruct.infoStrings ); + } } - aMIME.append( buf ); } - pclose( pResult ); + } - if( aMIME.getLength() > 0 ) + if( aMIMETypesStrangeStruct.typeStrings && aMIMETypesStrangeStruct.infoStrings ) + { + short nVariantCount = (**(short**)aMIMETypesStrangeStruct.typeStrings) / 2; + // Fill in the info struct based on the data in the BPSupportedMIMETypes struct + // this is an array of pascal string of unknown (!) encoding + // whoever thought of this deserves a fair beating + short mimeIndex = 2; + short descriptionIndex = 2; + for( int i = 0; i < nVariantCount; i++ ) { - OString aLine = aMIME.makeStringAndClear(); + rtl::OUString aMimetype = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); + rtl::OUString aExtLine = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); + rtl::OUString aDescription; + if( aMIMETypesStrangeStruct.infoStrings ) + aDescription = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.infoStrings, &descriptionIndex ); - sal_Int32 nIndex = 0; - while( nIndex != -1 ) + // create extension list string + sal_Int32 nExtIndex = 0; + OUStringBuffer aExtension; + while( nExtIndex != -1 ) { - OString aType = aLine.getToken( 0, ';', nIndex ); - - sal_Int32 nTypeIndex = 0; - OString aMimetype = aType.getToken( 0, ':', nTypeIndex ); - OString aExtLine = aType.getToken( 0, ':', nTypeIndex ); - if( nTypeIndex < 0 ) // ensure at least three tokens - continue; - OString aDesc = aType.getToken( 0, ':', nTypeIndex ); - - // create extension list string - sal_Int32 nExtIndex = 0; - OStringBuffer aExtension; - while( nExtIndex != -1 ) - { - OString aExt = aExtLine.getToken( 0, ',', nExtIndex); - if( aExt.indexOf( "*." ) != 0 ) - aExtension.append( "*." ); - aExtension.append( aExt ); - if( nExtIndex != -1 ) - aExtension.append( ';' ); - } + OUString aExt = aExtLine.getToken( 0, ',', nExtIndex); + if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) + aExtension.appendAscii( "*." ); + aExtension.append( aExt ); + if( nExtIndex != -1 ) + aExtension.append( sal_Unicode(';') ); + } - PluginDescription* pNew = new PluginDescription; - // set plugin name (path to library) - pNew->PluginName = OStringToOUString( rPath, aEncoding ); - // set mimetype - pNew->Mimetype = OStringToOUString( aMimetype, aEncoding ); - // set extension line - pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding ); - // set description - pNew->Description= OStringToOUString( aDesc, aEncoding ); - rDescriptions.push_back( pNew ); -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "Mimetype: %s\nExtension: %s\n" - "Description: %s\n", - OUStringToOString( pNew->Mimetype, aEncoding ).getStr(), - OUStringToOString( pNew->Extension, aEncoding ).getStr(), - OUStringToOString( pNew->Description, aEncoding ).getStr() - ); -#endif + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = aMimetype; + // set extension line + pNew->Extension = aExtension.makeStringAndClear(); + // set description + pNew->Description= aDescription; + io_rDescriptions.push_back( pNew ); + nAdded++; + + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "Inserting from resource:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() + ); + #endif + } + } + + + // clean up + if( aMIMETypesStrangeStruct.typeStrings ) + { + HUnlock( aMIMETypesStrangeStruct.typeStrings ); + DisposeHandle( aMIMETypesStrangeStruct.typeStrings ); + } + if( aMIMETypesStrangeStruct.infoStrings ) + { + HUnlock( aMIMETypesStrangeStruct.infoStrings ); + DisposeHandle( aMIMETypesStrangeStruct.infoStrings ); + } + if( xRes ) + CFBundleCloseBundleResourceMap( i_xBundle, xRes ); + + return nAdded; +} + +static int getPluginDescriptions( CFBundleRef i_xBundle , list< PluginDescription* >& io_rDescriptions ) +{ + int nDescriptions = 0; + if( ! i_xBundle ) + return nDescriptions; + + rtl::OUString aPlugURL; + CFURLRef xURL = CFBundleCopyBundleURL( i_xBundle ); + aPlugURL = getString( xURL ); + CFRelease( xURL ); + + #if OSL_DEBUG_LEVEL > 1 + rtl::OUString aPlugName, aPlugDescription; + CFTypeRef name = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginName")); + if( name && CFGetTypeID(name) == CFStringGetTypeID() ) + aPlugName = getString( static_cast<CFStringRef>(name) ); + + CFTypeRef description = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginDescription")); + if( description && CFGetTypeID(description) == CFStringGetTypeID() ) + aPlugDescription = getString( static_cast<CFStringRef>(description) ); + + fprintf( stderr, "URL: %s\nname: %s\ndescription: %s\n", + rtl::OUStringToOString( aPlugURL, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aPlugName, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aPlugDescription, RTL_TEXTENCODING_UTF8 ).getStr() ); + #endif + + + // get location of plugin library + CFURLRef xLibURL = CFBundleCopyExecutableURL( i_xBundle ); + if( ! xLibURL ) + return 0; + // get the file system path + rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) ); + CFRelease( xLibURL ); + + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "exec URL = %s\n", rtl::OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + #endif + + /* TODO: originally the C++ wrapper for oslModule was used here, but that led to + mysterious crashes in the event loop (pointing to heap corruption). Why using + the C style oslModule should fix this is completely unknown. It may be that + we have just hidden the heap corruption a little more. + */ + oslModule aMod = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT ); + if( ! aMod ) + return 0; + + // check for at least the init function of a plugin + if( ! osl_getAsciiFunctionSymbol( aMod, "NP_Initialize") && + ! osl_getAsciiFunctionSymbol( aMod, "NP_GetEntryPoints" ) ) + { + return 0; + } + + // ask the plist of the bundle for mimetypes + nDescriptions = parsePlist( i_xBundle, aPlugURL, io_rDescriptions ); + if( nDescriptions ) + { + osl_unloadModule( aMod ); + return nDescriptions; + } + + // resolve the symbol that might get us the mimetypes + const char* (*pGetMimeDescription)() = (const char*(*)())osl_getAsciiFunctionSymbol( aMod, "_NP_GetMIMEDescription" ); + if( pGetMimeDescription ) + { + const char* pMime = pGetMimeDescription(); + if( pMime ) + { + nDescriptions = parseMimeString( aPlugURL, io_rDescriptions, pMime ); + if( nDescriptions ) + { + osl_unloadModule( aMod ); + return nDescriptions; } } + } + + // and as last resort check the resource of the bundle + nDescriptions = parseMimeResource( i_xBundle, aMod, aPlugURL, io_rDescriptions ); + osl_unloadModule( aMod ); + + return nDescriptions; +} + +// Unix specific implementation +static bool CheckPlugin( const rtl::OUString& rPath, list< PluginDescription* >& rDescriptions ) +{ #if OSL_DEBUG_LEVEL > 1 - else - fprintf( stderr, "result of \"%s\" contains no mimtype\n", - aCommand.GetBuffer() ); + fprintf( stderr, "Trying path %s ... ", rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif - } + CFURLRef xURL = createURL( rPath ); + + CFArrayRef xBundles = CFBundleCreateBundlesFromDirectory( NULL, xURL, CFSTR("plugin") ); + if( ! xBundles ) + return false; + + CFIndex nBundles = CFArrayGetCount( xBundles ); + #if OSL_DEBUG_LEVEL > 1 - else - fprintf( stderr, "command \"%s\" failed\n", aCommand.GetBuffer() ); + fprintf( stderr, "got %d bundles\n", (int)nBundles ); #endif + + int nDescriptions = 0; + for( CFIndex i = 0; i < nBundles; i++ ) + { + CFBundleRef xBundle = (CFBundleRef)CFArrayGetValueAtIndex( xBundles, i ); + nDescriptions += getPluginDescriptions( xBundle, rDescriptions ); + + CFRelease( xBundle ); + } + CFRelease( xBundles ); + + return nDescriptions > 0; } +static rtl::OUString FindFolderURL( FSVolumeRefNum vRefNum, OSType folderType ) +{ + rtl::OUString aRet; + + FSRef aFSRef; + OSErr err = FSFindFolder( vRefNum, folderType, kDontCreateFolder, &aFSRef ); + if( err == noErr ) + { + CFURLRef xURL = CFURLCreateFromFSRef( NULL, &aFSRef ); + aRet = getString( xURL ); + CFRelease( xURL ); + } + + return aRet; +} + Sequence<PluginDescription> XPluginManager_Impl::getPluginDescriptions() throw() { static Sequence<PluginDescription> aDescriptions; static BOOL bHavePlugins = FALSE; if( ! bHavePlugins ) { - rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); - list<PluginDescription*> aPlugins; - int i; - - // unix: search for plugins in /usr/lib/netscape/plugins, - // ~/.netscape/plugins und NPX_PLUGIN_PATH - // additionally: search in PluginsPath - static const char* pHome = getenv( "HOME" ); - static const char* pNPXPluginPath = getenv( "NPX_PLUGIN_PATH" ); - - ByteString aSearchPath( "/usr/lib/netscape/plugins" ); - if( pHome ) - { - aSearchPath.Append( ':' ); - aSearchPath.Append( pHome ); - aSearchPath += "/.netscape/plugins"; - } + std::list<PluginDescription*> aPlugins; + + static const char* pNPXPluginPath = getenv( "MOZ_PLUGIN_PATH" ); + + // get directories + std::list< rtl::OUString > aPaths; if( pNPXPluginPath ) { - aSearchPath.Append( ':' ); - aSearchPath += pNPXPluginPath; + CFMutableStringRef xMutableString = CFStringCreateMutable( NULL, 0 ); + CFStringAppendCString( xMutableString, pNPXPluginPath, kCFStringEncodingUTF8 ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + CFRelease( xMutableString ); + aPaths.push_back( getString( xURL ) ); + CFRelease( xURL ); } - const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() ); - for( i = 0; i < rPaths.getLength(); i++ ) - { - aSearchPath += ":"; - aSearchPath += ByteString( String( rPaths.getConstArray()[i] ), aEncoding ); - } + rtl::OUString aPath = FindFolderURL( kUserDomain, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); + aPath = FindFolderURL( kLocalDomain, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); + aPath = FindFolderURL( kOnAppropriateDisk, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); - long aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ]; - int nPaths = aSearchPath.GetTokenCount( ':' ); - for( i = 0; i < nPaths; i++ ) + const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() ); + for( sal_Int32 i = 0; i < rPaths.getLength(); i++ ) { - ByteString aPath( aSearchPath.GetToken( i, ':' ) ); - if( aPath.Len() ) - { - DIR* pDIR = opendir( aPath.GetBuffer() ); - struct dirent* pDirEnt = NULL; - while( pDIR && ! readdir_r( pDIR, (struct dirent*)aBuffer, &pDirEnt ) && pDirEnt ) - { - char* pBaseName = ((struct dirent*)aBuffer)->d_name; - if( pBaseName[0] != '.' || - pBaseName[1] != '.' || - pBaseName[2] != 0 ) - { - ByteString aFileName( aPath ); - aFileName += "/"; - aFileName += pBaseName; - CheckPlugin( aFileName, aPlugins ); - } - } - if( pDIR ) - closedir( pDIR ); - } + aPaths.push_back( getURLFromPath( rPaths.getConstArray()[i] ) ); } - // try ~/.mozilla/pluginreg.dat - ByteString aMozPluginreg( pHome ); - aMozPluginreg.Append( "/.mozilla/pluginreg.dat" ); - FILE* fp = fopen( aMozPluginreg.GetBuffer(), "r" ); - if( fp ) + for( std::list< rtl::OUString >::const_iterator it = aPaths.begin(); it != aPaths.end(); ++it ) { + rtl::OUString aPath( *it ); #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "parsing %s\n", aMozPluginreg.GetBuffer() ); + fprintf( stderr, "check path %s\n", rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif - char aLine[1024]; - while( fgets( aLine, sizeof( aLine ), fp ) ) - { - int nLineLen = strlen( aLine ); - int nDotPos; - for( nDotPos = nLineLen-1; nDotPos > 0 && aLine[nDotPos] != ':'; nDotPos-- ) - ; - if( aLine[0] == '/' && aLine[nDotPos] == ':' && aLine[nDotPos+1] == '$' ) - CheckPlugin( ByteString( aLine, nDotPos ), aPlugins ); - } - fclose( fp ); + CheckPlugin( aPath, aPlugins ); } + // create return value aDescriptions = Sequence<PluginDescription>( aPlugins.size() ); #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "found %d plugins\n", aPlugins.size() ); + fprintf( stderr, "found %d plugins\n", (int)aPlugins.size() ); #endif list<PluginDescription*>::iterator iter; - for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ ) + sal_Int32 nPlug = 0; + for( iter = aPlugins.begin(); iter != aPlugins.end(); ++iter ) { - aDescriptions.getArray()[ i ] = **iter; + aDescriptions.getArray()[ nPlug++ ] = **iter; delete *iter; } aPlugins.clear(); |