summaryrefslogtreecommitdiff
path: root/extensions/source/plugin/aqua/macmgr.cxx
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2009-04-01 11:54:14 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2009-04-01 11:54:14 +0000
commitcc01b14ca1e76bcfd3abd6141d4250bc3d7cc7d5 (patch)
tree60df7856cad6c4b98e38560eff822f8668757597 /extensions/source/plugin/aqua/macmgr.cxx
parenta90774683ad9f7e053f427619fcd2d6ee97ea5fa (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.cxx658
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();