summaryrefslogtreecommitdiff
path: root/extensions/source/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/plugin')
-rw-r--r--extensions/source/plugin/aqua/macmgr.cxx646
-rw-r--r--extensions/source/plugin/aqua/makefile.mk75
-rw-r--r--extensions/source/plugin/aqua/sysplug.cxx808
-rw-r--r--extensions/source/plugin/base/context.cxx343
-rw-r--r--extensions/source/plugin/base/evtlstnr.cxx64
-rw-r--r--extensions/source/plugin/base/makefile.mk70
-rw-r--r--extensions/source/plugin/base/manager.cxx225
-rw-r--r--extensions/source/plugin/base/multiplx.cxx332
-rw-r--r--extensions/source/plugin/base/nfuncs.cxx677
-rw-r--r--extensions/source/plugin/base/plcom.cxx71
-rw-r--r--extensions/source/plugin/base/plctrl.cxx323
-rw-r--r--extensions/source/plugin/base/plmodel.cxx203
-rw-r--r--extensions/source/plugin/base/service.cxx93
-rw-r--r--extensions/source/plugin/base/xplugin.cxx1155
-rw-r--r--extensions/source/plugin/inc/plugin/aqua/sysplug.hxx167
-rw-r--r--extensions/source/plugin/inc/plugin/impl.hxx430
-rw-r--r--extensions/source/plugin/inc/plugin/model.hxx136
-rw-r--r--extensions/source/plugin/inc/plugin/multiplx.hxx167
-rw-r--r--extensions/source/plugin/inc/plugin/plcom.hxx85
-rw-r--r--extensions/source/plugin/inc/plugin/plctrl.hxx181
-rw-r--r--extensions/source/plugin/inc/plugin/unx/mediator.hxx183
-rw-r--r--extensions/source/plugin/inc/plugin/unx/plugcon.hxx251
-rw-r--r--extensions/source/plugin/inc/plugin/unx/sysplug.hxx83
-rw-r--r--extensions/source/plugin/inc/plugin/win/sysplug.hxx125
-rw-r--r--extensions/source/plugin/unx/makefile.mk110
-rw-r--r--extensions/source/plugin/unx/mediator.cxx309
-rw-r--r--extensions/source/plugin/unx/npnapi.cxx917
-rw-r--r--extensions/source/plugin/unx/nppapi.cxx621
-rw-r--r--extensions/source/plugin/unx/npwrap.cxx515
-rw-r--r--extensions/source/plugin/unx/plugcon.cxx282
-rw-r--r--extensions/source/plugin/unx/sysplug.cxx131
-rw-r--r--extensions/source/plugin/unx/unxmgr.cxx315
-rw-r--r--extensions/source/plugin/util/makefile.mk117
-rw-r--r--extensions/source/plugin/util/makefile.pmk48
-rw-r--r--extensions/source/plugin/util/pl.component37
-rw-r--r--extensions/source/plugin/win/makefile.mk65
-rw-r--r--extensions/source/plugin/win/sysplug.cxx443
-rw-r--r--extensions/source/plugin/win/winmgr.cxx470
38 files changed, 11273 insertions, 0 deletions
diff --git a/extensions/source/plugin/aqua/macmgr.cxx b/extensions/source/plugin/aqua/macmgr.cxx
new file mode 100644
index 000000000000..e0bfe3ad5c01
--- /dev/null
+++ b/extensions/source/plugin/aqua/macmgr.cxx
@@ -0,0 +1,646 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtl/ustrbuf.hxx"
+#include "rtl/strbuf.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;
+
+namespace plugstringhelper
+{
+
+rtl::OUString getString( CFStringRef i_xString )
+{
+ rtl::OUStringBuffer aBuf;
+ if( i_xString )
+ {
+ 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;
+}
+
+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 )
+ {
+ return 0;
+ }
+
+ // 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,
+ "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 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();
+
+ OStringBuffer aMIME;
+ aMIME.append( i_pMime );
+
+ if( aMIME.getLength() < 1 )
+ return 0;
+
+ OString aLine = aMIME.makeStringAndClear();
+
+ int nAdded = 0;
+ sal_Int32 nIndex = 0;
+ while( nIndex != -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( ';' );
+ }
+
+ 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 )
+ {
+ DetachResource( aMIMETypesStrangeStruct.typeStrings );
+ HLock( aMIMETypesStrangeStruct.typeStrings );
+ aMIMETypesStrangeStruct.infoStrings = Get1Resource('STR#', 127);
+ if( aMIMETypesStrangeStruct.infoStrings )
+ {
+ DetachResource( aMIMETypesStrangeStruct.infoStrings );
+ HLock( aMIMETypesStrangeStruct.infoStrings );
+ }
+ }
+ }
+ }
+
+ 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++ )
+ {
+ 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 );
+
+ // create extension list string
+ sal_Int32 nExtIndex = 0;
+ OUStringBuffer aExtension;
+ while( nExtIndex != -1 )
+ {
+ 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 = 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;
+}
+
+// check some known bad plugins to avoid crashes
+static bool checkBlackList( CFBundleRef i_xBundle )
+{
+ rtl::OUString aBundleName;
+ CFTypeRef bundlename = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleName"));
+ if( bundlename && CFGetTypeID(bundlename) == CFStringGetTypeID() )
+ aBundleName = getString( static_cast<CFStringRef>(bundlename) );
+
+ rtl::OUString aBundleVersion;
+ CFTypeRef bundleversion = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleVersion"));
+ if( bundleversion && CFGetTypeID(bundleversion) == CFStringGetTypeID() )
+ aBundleVersion = getString( static_cast<CFStringRef>(bundleversion) );
+
+ bool bReject = false;
+ // #i102735# VLC plugin prior to 1.0 tends to crash
+ if( aBundleName.equalsAscii( "VLC Plug-in" ) )
+ {
+ sal_Int32 nIndex = 0;
+ rtl::OUString aMajor( aBundleVersion.getToken( 0, '.', nIndex ) );
+ if( aMajor.toInt32() < 1 )
+ {
+ bReject = true;
+ }
+ }
+ // #i103674# Garmin Communicator Plugin crashes
+ else if( aBundleName.equalsAscii( "Garmin Communicator Plugin" ) )
+ {
+ bReject = true;
+ }
+
+ #if OSL_DEBUG_LEVEL > 1
+ if( bReject )
+ fprintf( stderr, "rejecting plugin \"%s\" version %s\n",
+ rtl::OUStringToOString( aBundleName, RTL_TEXTENCODING_UTF8 ).getStr(),
+ rtl::OUStringToOString( aBundleVersion, RTL_TEXTENCODING_UTF8 ).getStr()
+ );
+ #endif
+
+ return bReject;
+}
+
+static int getPluginDescriptions( CFBundleRef i_xBundle , list< PluginDescription* >& io_rDescriptions )
+{
+ int nDescriptions = 0;
+ if( ! i_xBundle )
+ return nDescriptions;
+
+ if( checkBlackList( i_xBundle ) )
+ return 0;
+
+ 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
+ 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
+ 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::impl_getPluginDescriptions() throw()
+{
+ static Sequence<PluginDescription> aDescriptions;
+ static sal_Bool bHavePlugins = sal_False;
+ if( ! bHavePlugins )
+ {
+ std::list<PluginDescription*> aPlugins;
+
+ static const char* pNPXPluginPath = getenv( "MOZ_PLUGIN_PATH" );
+
+ // get directories
+ std::list< rtl::OUString > aPaths;
+ if( 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 );
+ }
+
+ 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 );
+
+
+ const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
+ for( sal_Int32 i = 0; i < rPaths.getLength(); i++ )
+ {
+ aPaths.push_back( getURLFromPath( rPaths.getConstArray()[i] ) );
+ }
+
+ 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, "check path %s\n", rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+ CheckPlugin( aPath, aPlugins );
+ }
+
+
+ // create return value
+ aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "found %d plugins\n", (int)aPlugins.size() );
+#endif
+ list<PluginDescription*>::iterator iter;
+ sal_Int32 nPlug = 0;
+ for( iter = aPlugins.begin(); iter != aPlugins.end(); ++iter )
+ {
+ aDescriptions.getArray()[ nPlug++ ] = **iter;
+ delete *iter;
+ }
+ aPlugins.clear();
+ bHavePlugins = sal_True;
+ }
+ return aDescriptions;
+}
+
diff --git a/extensions/source/plugin/aqua/makefile.mk b/extensions/source/plugin/aqua/makefile.mk
new file mode 100644
index 000000000000..e29418a526f2
--- /dev/null
+++ b/extensions/source/plugin/aqua/makefile.mk
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=extensions
+TARGET=plaqua
+#ENABLE_EXCEPTIONS=TRUE
+#TARGETTYPE=CUI
+
+.INCLUDE : ..$/util$/makefile.pmk
+
+.IF "$(GUIBASE)"!="aqua" || "$(WITH_MOZILLA)"=="NO"
+
+dummy:
+ @echo "Nothing to build for GUIBASE $(GUIBASE)."
+
+.ELSE
+
+# --- Files --------------------------------------------------------
+
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/plugin
+.IF "$(SOLAR_JAVA)" != ""
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/java
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/nspr
+INCPRE+=-I$(SOLARINCDIR)$/npsdk
+CDEFS+=-DOJI
+.ENDIF
+
+.IF "$(GUIBASE)"=="aqua"
+CFLAGSCXX+=$(OBJCXXFLAGS)
+.ENDIF # "$(GUIBASE)"=="aqua"
+
+SLOFILES=\
+ $(SLO)$/macmgr.obj \
+ $(SLO)$/sysplug.obj
+
+#APP1TARGET=pluginapp.bin
+#APP1OBJS=$(OBJFILES)
+#APP1STDLIBS=\
+# $(TOOLSLIB) \
+# $(VOSLIB) \
+# $(SALLIB)
+
+#APP1DEF= $(MISC)$/$(TARGET).def
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.ENDIF # $(GUIBASE)==aqua
diff --git a/extensions/source/plugin/aqua/sysplug.cxx b/extensions/source/plugin/aqua/sysplug.cxx
new file mode 100644
index 000000000000..206204fa10a7
--- /dev/null
+++ b/extensions/source/plugin/aqua/sysplug.cxx
@@ -0,0 +1,808 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <cstdarg>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <osl/thread.h>
+
+#include <plugin/impl.hxx>
+
+extern NPNetscapeFuncs aNPNFuncs;
+
+#include <tools/debug.hxx>
+
+using namespace rtl;
+using namespace plugstringhelper;
+
+#if OSL_DEBUG_LEVEL > 1
+void TRACE( char const * s );
+void TRACEN( char const * s, long n );
+#else
+#define TRACE(x)
+#define TRACEN(x,n)
+#endif
+
+struct FakeEventRecord : public EventRecord
+{
+ FakeEventRecord()
+ {
+ memset( this, 0, sizeof(EventRecord) );
+ ::GetGlobalMouse( &where );
+ when = ::TickCount();
+ modifiers = ::GetCurrentEventKeyModifiers();
+ }
+};
+
+
+@interface OOoPluginView : NSView
+{
+ XPlugin_Impl* m_pImpl;
+ MacPluginComm* m_pCom;
+}
+-(id)initWithInstance: (XPlugin_Impl*)i_pImpl pluginComm: (MacPluginComm*)i_pCom frame: (NSRect)i_aRect;
+-(void)drawRect: (NSRect)i_aRect;
+-(BOOL)isOpaque;
+-(BOOL)isFlipped;
+
+// NSResponder
+-(void)mouseMoved: (NSEvent*)i_pEvent;
+-(void)mouseDown: (NSEvent*)i_pEvent;
+-(void)mouseDragged: (NSEvent*)i_pEvent;
+-(void)mouseUp: (NSEvent*)i_pEvent;
+-(void)rightMouseDown: (NSEvent*)i_pEvent;
+-(void)rightMouseDragged: (NSEvent*)i_pEvent;
+-(void)rightMouseUp: (NSEvent*)i_pEvent;
+-(void)otherMouseDown: (NSEvent*)i_pEvent;
+-(void)otherMouseDragged: (NSEvent*)i_pEvent;
+-(void)otherMouseUp: (NSEvent*)i_pEvent;
+-(void)mouseEntered: (NSEvent*)i_pEvent;
+-(void)mouseExited: (NSEvent*)i_pEvent;
+@end
+
+@implementation OOoPluginView
+-(id)initWithInstance: (XPlugin_Impl*)i_pImpl pluginComm: (MacPluginComm*)i_pCom frame: (NSRect) i_aRect
+{
+ if( (self = [super initWithFrame: i_aRect]) )
+ {
+ m_pImpl = i_pImpl;
+ m_pCom = i_pCom;
+ }
+ return self;
+}
+
+-(void)drawRect: (NSRect) i_aRect
+{
+ m_pCom->drawView( m_pImpl );
+}
+
+-(BOOL)isOpaque
+{
+ return NO;
+}
+
+-(BOOL)isFlipped
+{
+ return YES;
+}
+
+// NSResponder
+-(void)mouseMoved: (NSEvent*)i_pEvent
+{
+ FakeEventRecord aRec;
+ aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)mouseDown: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseDown;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)mouseDragged: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)mouseUp: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseUp;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)rightMouseDown: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseDown;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)rightMouseDragged: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)rightMouseUp: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseUp;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)otherMouseDown: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseDown;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)otherMouseDragged: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)otherMouseUp: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = mouseUp;
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)mouseEntered: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+-(void)mouseExited: (NSEvent*)i_pEvent;
+{
+ FakeEventRecord aRec;
+ aRec.what = aRec.what = osEvt + 18; // NPEventType_AdjustCursorEvent
+ m_pCom->NPP_HandleEvent( m_pImpl->getNPPInstance(), &aRec );
+}
+
+@end
+
+//--------------------------------------------------------------------------------------------------
+MacPluginComm::MacPluginComm( const rtl::OUString& i_rMimetype, const rtl::OUString& i_rBundle, NSView* i_pParent )
+ : PluginComm( OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ) ),
+ m_xBundle( NULL ),
+ m_hPlugLib( NULL ),
+ m_pNullTimer( NULL )
+{
+ // initialize plugin function table
+ memset( &m_aNPPfuncs, 0, sizeof( m_aNPPfuncs ) );
+
+ // load the bundle
+ CFURLRef xURL = createURL( i_rBundle );
+ m_xBundle = CFBundleCreate( NULL, xURL );
+ CFRelease( xURL );
+ if( m_xBundle )
+ {
+ // ask the plugin library
+ // first get its location
+ CFURLRef xLibURL = CFBundleCopyExecutableURL( m_xBundle );
+ if( xLibURL )
+ {
+ // get the file system path
+ rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) );
+ CFRelease( xLibURL );
+ m_hPlugLib = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT );
+ #if OSL_DEBUG_LEVEL > 1
+ if( ! m_hPlugLib )
+ fprintf( stderr, "module %s could not be loaded\n", OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+ #endif
+ }
+ #if OSL_DEBUG_LEVEL > 1
+ else
+ fprintf( stderr, "bundle %s has no exectutable URL\n", OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ).getStr() );
+ #endif
+ }
+ else
+ {
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "bundle %s could not be loaded\n", OUStringToOString( i_rBundle, RTL_TEXTENCODING_UTF8 ).getStr() );
+ #endif
+ }
+
+ DBG_ASSERT( m_xBundle && m_hPlugLib, "loading plugin bundle failed!" );
+
+
+ m_aNPPfuncs.size = sizeof( m_aNPPfuncs );
+ m_aNPPfuncs.version = 0;
+
+
+ m_eCall = eNP_Initialize;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+MacPluginComm::~MacPluginComm()
+{
+ if( m_hPlugLib )
+ {
+ // NPP_Shutdown();
+ NPError (*pShutdown)();
+ if( retrieveFunction( "NP_Shutdown", (void**)&pShutdown ) )
+ {
+ NPError nErr = (*pShutdown)(); (void)nErr;
+ DBG_ASSERT( nErr == NPERR_NO_ERROR, "NP_Shutdown() failed!" );
+ }
+ osl_unloadModule( m_hPlugLib );
+ }
+ if( m_xBundle )
+ CFRelease( m_xBundle );
+}
+
+//--------------------------------------------------------------------------------------------------
+sal_Bool MacPluginComm::retrieveFunction( const char* i_pName, void** o_ppFunc ) const
+{
+ if( ! m_hPlugLib || ! o_ppFunc )
+ return sal_False;
+
+ *o_ppFunc = (void*)osl_getAsciiFunctionSymbol( m_hPlugLib, i_pName );
+
+ if( ! *o_ppFunc && m_xBundle )
+ {
+ rtl::OUString aName( OUString::createFromAscii( *i_pName == '_' ? i_pName+1 : i_pName ) );
+ CFStringRef xName = createString( aName );
+ if( xName )
+ {
+ *o_ppFunc = CFBundleGetFunctionPointerForName( m_xBundle, xName );
+ CFRelease( xName );
+ }
+ }
+
+ return (*o_ppFunc != NULL);
+}
+
+IMPL_LINK( MacPluginComm, NullTimerHdl, void*, EMPTYARG )
+{
+ // note: this is a Timer handler, we are already protected by the SolarMutex
+
+ FakeEventRecord aRec;
+ aRec.what = nullEvent;
+ aRec.where.h = aRec.where.v = 20000;
+
+ for( std::list< XPlugin_Impl* >::iterator it = m_aNullEventClients.begin();
+ it != m_aNullEventClients.end(); ++it )
+ {
+ SysPlugData& rPlugData( (*it)->getSysPlugData() );
+ if( rPlugData.m_pPlugView ) // for safety do not dispatch null events before first NPP_SetWindow
+ (*m_aNPPfuncs.event)( (*it)->getNPPInstance(), &aRec );
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+long MacPluginComm::doIt()
+{
+ long nRet = 0;
+ switch( m_eCall )
+ {
+ case eNP_Initialize:
+ {
+ TRACE( "eNP_Initialize" );
+ NPError (*pInit)( NPNetscapeFuncs* );
+ if( retrieveFunction( "NP_Initialize", (void**)&pInit ) )
+ {
+ nRet = (*pInit)( &aNPNFuncs );
+
+ NPError nErr = NPERR_NO_ERROR;
+ NPError (*pEntry)( NPPluginFuncs* );
+ retrieveFunction( "NP_GetEntryPoints", (void**)&pEntry );
+ nErr = (*pEntry)( &m_aNPPfuncs );
+
+ DBG_ASSERT( nErr == NPERR_NO_ERROR, "NP_GetEntryPoints() failed!" );
+ }
+ else
+ {
+ nRet = NPERR_GENERIC_ERROR;
+ }
+ DBG_ASSERT( nRet == NPERR_NO_ERROR, "### NP_Initialize() failed!" );
+ }
+ break;
+ case eNPP_Destroy:
+ if( m_aNullEventClients.empty() )
+ delete m_pNullTimer, m_pNullTimer = NULL;
+
+ TRACE( "eNPP_Destroy" );
+ nRet = (m_aNPPfuncs.destroy
+ ? (*m_aNPPfuncs.destroy)(
+ (NPP)m_aArgs[0],
+ (NPSavedData**)m_aArgs[1] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_DestroyStream:
+ TRACE( "eNPP_DestroyStream" );
+ nRet = (m_aNPPfuncs.destroystream
+ ? (*m_aNPPfuncs.destroystream)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (NPError)(sal_IntPtr)m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_New:
+ TRACE( "eNPP_New" );
+ nRet = (m_aNPPfuncs.newp
+ ? (*m_aNPPfuncs.newp)(
+ (NPMIMEType)m_aArgs[0],
+ (NPP)m_aArgs[1],
+ (uint16)(sal_IntPtr)m_aArgs[2],
+ (int16)(sal_IntPtr)m_aArgs[3],
+ (char**)m_aArgs[4],
+ (char**)m_aArgs[5],
+ (NPSavedData*)m_aArgs[6] )
+ : NPERR_GENERIC_ERROR);
+
+ if( ! m_pNullTimer && m_aNPPfuncs.event )
+ {
+ m_pNullTimer = new AutoTimer();
+ m_pNullTimer->SetTimeout( 50 );
+ m_pNullTimer->SetTimeoutHdl( LINK( this, MacPluginComm, NullTimerHdl ) );
+ m_pNullTimer->Start();
+ }
+
+ break;
+ case eNPP_NewStream:
+ TRACE( "eNPP_NewStream" );
+ nRet = (m_aNPPfuncs.newstream
+ ? (*m_aNPPfuncs.newstream)(
+ (NPP)m_aArgs[0],
+ (NPMIMEType)m_aArgs[1],
+ (NPStream*)m_aArgs[2],
+ (NPBool)(sal_IntPtr)m_aArgs[3],
+ (uint16*)m_aArgs[4] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_Print:
+ TRACE( "eNPP_Print" );
+ if (m_aNPPfuncs.print)
+ (*m_aNPPfuncs.print)(
+ (NPP)m_aArgs[0],
+ (NPPrint*)m_aArgs[1] );
+ break;
+ case eNPP_SetWindow:
+ {
+ TRACE( "eNPP_SetWindow" );
+ nRet = (m_aNPPfuncs.setwindow
+ ? (*m_aNPPfuncs.setwindow)(
+ (NPP)m_aArgs[0],
+ (NPWindow*)m_aArgs[1] )
+ : NPERR_GENERIC_ERROR);
+
+ break;
+ }
+ case eNPP_HandleEvent:
+ {
+ TRACE( "eNPP_HandleEvent" );
+ nRet = (m_aNPPfuncs.event
+ ? (*m_aNPPfuncs.event)(
+ (NPP)m_aArgs[0],
+ m_aArgs[1] )
+ : NPERR_GENERIC_ERROR);
+
+ break;
+ }
+ case eNPP_StreamAsFile:
+ TRACE( "eNPP_StreamAsFile" );
+ if (m_aNPPfuncs.asfile)
+ (*m_aNPPfuncs.asfile)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (char*)m_aArgs[2] );
+ break;
+ case eNPP_URLNotify:
+ TRACE( "eNPP_URLNotify" );
+ if (m_aNPPfuncs.urlnotify)
+ (*m_aNPPfuncs.urlnotify)(
+ (NPP)m_aArgs[0],
+ (char*)m_aArgs[1],
+ (NPReason)(sal_IntPtr)m_aArgs[2],
+ m_aArgs[3] );
+ break;
+ case eNPP_Write:
+ TRACEN( "eNPP_Write n=", (int32)m_aArgs[3] );
+ nRet = (m_aNPPfuncs.write
+ ? (*m_aNPPfuncs.write)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (int32)m_aArgs[2],
+ (int32)m_aArgs[3],
+ m_aArgs[4] )
+ : 0);
+ break;
+ case eNPP_WriteReady:
+ TRACE( "eNPP_WriteReady" );
+ nRet = (m_aNPPfuncs.writeready
+ ? (*m_aNPPfuncs.writeready)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1] )
+ : 0);
+ break;
+ case eNPP_GetValue:
+ TRACE( "eNPP_GetValue" );
+ nRet = (m_aNPPfuncs.getvalue
+ ? (*m_aNPPfuncs.getvalue)(
+ (NPP)m_aArgs[0],
+ (NPPVariable)(int)m_aArgs[1],
+ m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_SetValue:
+ TRACE( "eNPP_SetValue" );
+ nRet = (m_aNPPfuncs.setvalue
+ ? (*m_aNPPfuncs.setvalue)(
+ (NPP)m_aArgs[0],
+ (NPNVariable)(int)m_aArgs[1],
+ m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_Shutdown:
+ {
+ TRACE( "eNPP_Shutdown" );
+ NPP_ShutdownUPP pFunc;
+ if (retrieveFunction( "NPP_Shutdown", (void**)&pFunc ))
+ (*pFunc)();
+ }
+ break;
+ case eNPP_Initialize:
+ TRACE( "eNPP_Initialize" );
+ OSL_ENSURE( false, "NPP_Initialize: not implemented!" );
+ break;
+ case eNPP_GetJavaClass:
+ TRACE( "eNPP_GetJavaClass" );
+ OSL_ENSURE( false, "NPP_GetJavaClass: not implemented!" );
+ break;
+ }
+ return nRet;
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_Destroy( XPlugin_Impl* i_pImpl, NPSavedData** save )
+{
+ // remove from NullEvent timer
+ m_aNullEventClients.remove( i_pImpl );
+
+ NPError nErr = NPP_Destroy( i_pImpl->getNPPInstance(), save );
+
+ // release plugin view
+ SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
+ if( rPlugData.m_pPlugView )
+ {
+ [rPlugData.m_pPlugView removeFromSuperview];
+ [rPlugData.m_pPlugView release];
+ rPlugData.m_pPlugView = nil;
+ }
+
+ return nErr;
+}
+
+
+NPError MacPluginComm::NPP_Destroy( NPP instance, NPSavedData** save )
+{
+ DBG_ASSERT( m_aNPPfuncs.destroy, "### NPP_Destroy(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Destroy;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)save;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason )
+{
+ DBG_ASSERT( m_aNPPfuncs.destroystream, "### NPP_DestroyStream(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_DestroyStream;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)reason;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved )
+{
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ DBG_ASSERT( pImpl, "no instance found" );
+
+ if( pImpl ) // sanity check
+ m_aNullEventClients.push_back( pImpl );
+
+ DBG_ASSERT( m_aNPPfuncs.newp, "### NPP_New(): null pointer in NPP functions table!" );
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "NPP_New( %s. %p, %d, %d",
+ pluginType, instance, (int)mode, (int)argc );
+ for( int16 i = 0; i < argc; i++ )
+ fprintf( stderr, "\n%s = %s", argn[i], argv[i] );
+ fprintf( stderr, ", %p )\n", saved );
+ #endif
+ m_eCall = eNPP_New;
+ m_aArgs[0] = (void*)pluginType;
+ m_aArgs[1] = (void*)instance;
+ m_aArgs[2] = (void*)mode;
+ m_aArgs[3] = (void*)argc;
+ m_aArgs[4] = (void*)argn;
+ m_aArgs[5] = (void*)argv;
+ m_aArgs[6] = (void*)saved;
+
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype )
+{
+ DBG_ASSERT( m_aNPPfuncs.newstream, "### NPP_NewStream(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_NewStream;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)type;
+ m_aArgs[2] = (void*)stream;
+ m_aArgs[3] = (void*)seekable;
+ m_aArgs[4] = (void*)stype;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void MacPluginComm::NPP_Print( NPP instance, NPPrint* platformPrint )
+{
+ DBG_ASSERT( m_aNPPfuncs.print, "### NPP_Print(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Print;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)platformPrint;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_SetWindow( NPP instance, NPWindow* window )
+{
+ DBG_ASSERT( m_aNPPfuncs.setwindow, "### NPP_SetWindow(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_SetWindow;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)window;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_HandleEvent( NPP instance, void* event )
+{
+ DBG_ASSERT( m_aNPPfuncs.event, "### NPP_HandleEvent(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_HandleEvent;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = event;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void MacPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
+{
+ DBG_ASSERT( m_aNPPfuncs.asfile, "### NPP_StreamAsFile(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_StreamAsFile;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)fname;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void MacPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
+{
+ DBG_ASSERT( m_aNPPfuncs.urlnotify, "### NPP_URLNotify(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_URLNotify;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)url;
+ m_aArgs[2] = (void*)reason;
+ m_aArgs[3] = notifyData;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+int32 MacPluginComm::NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer )
+{
+ DBG_ASSERT( m_aNPPfuncs.write, "### NPP_Write(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Write;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)offset;
+ m_aArgs[3] = (void*)len;
+ m_aArgs[4] = buffer;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+int32 MacPluginComm::NPP_WriteReady( NPP instance, NPStream* stream )
+{
+ DBG_ASSERT( m_aNPPfuncs.writeready, "### NPP_WriteReady(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_WriteReady;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ return execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void *ret_value )
+{
+ DBG_ASSERT( m_aNPPfuncs.getvalue, "### NPP_GetValue(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_GetValue;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)variable;
+ m_aArgs[2] = ret_value;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_SetValue( NPP instance, NPNVariable variable, void *set_value )
+{
+ DBG_ASSERT( m_aNPPfuncs.setvalue, "### NPP_SetValue(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_SetValue;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)variable;
+ m_aArgs[2] = set_value;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void * MacPluginComm::NPP_GetJavaClass()
+{
+ DBG_ERROR( "no java class available!" );
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_Initialize()
+{
+ return NPERR_NO_ERROR;
+}
+
+//--------------------------------------------------------------------------------------------------
+void MacPluginComm::NPP_Shutdown()
+{
+ m_eCall = eNPP_Shutdown;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError MacPluginComm::NPP_SetWindow( XPlugin_Impl* i_pImpl )
+{
+ // update window NPWindow from view
+ SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
+
+ // update plug view
+ NSRect aPlugRect = [rPlugData.m_pParentView frame];
+ aPlugRect.origin.x = aPlugRect.origin.y = 0;
+ if( ! rPlugData.m_pPlugView )
+ {
+ rPlugData.m_pPlugView = [[OOoPluginView alloc] initWithInstance: i_pImpl pluginComm: this frame: aPlugRect];
+ [rPlugData.m_pParentView addSubview: rPlugData.m_pPlugView];
+ }
+ else
+ [rPlugData.m_pPlugView setFrame: aPlugRect];
+
+ NPWindow* pNPWin = i_pImpl->getNPWindow();
+ NSWindow* pWin = [rPlugData.m_pPlugView window];
+ NSRect aWinRect = [pWin frame];
+ NSRect aBounds = [rPlugData.m_pPlugView frame];
+ NSRect aVisibleBounds = [rPlugData.m_pPlugView visibleRect];
+
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "visible bounds = %d+%d+%dx%d\n",
+ (int)aVisibleBounds.origin.x, (int)aVisibleBounds.origin.y,
+ (int)aVisibleBounds.size.width, (int)aVisibleBounds.size.height );
+ #endif
+
+ NSPoint aViewOrigin = [rPlugData.m_pPlugView convertPoint: NSZeroPoint toView: nil];
+ // save view origin so we can notice movement of the view in drawView
+ // in case of a moved view we need to reset the port/context
+ rPlugData.m_aLastPlugViewOrigin = aViewOrigin;
+
+ // convert view origin to topdown coordinates
+ aViewOrigin.y = aWinRect.size.height - aViewOrigin.y;
+
+ // same for clipping
+ NSPoint aClipOrigin = [rPlugData.m_pPlugView convertPoint: aVisibleBounds.origin toView: nil];
+ aClipOrigin.y = aWinRect.size.height - aClipOrigin.y;
+
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "view origin: %d+%d, clip origin = %d+%d\n",
+ (int)aViewOrigin.x, (int)aViewOrigin.y,
+ (int)aClipOrigin.x, (int)aClipOrigin.y );
+ #endif
+
+ pNPWin->x = aViewOrigin.x;
+ pNPWin->y = aViewOrigin.y;
+ pNPWin->width = aBounds.size.width;
+ pNPWin->height = aBounds.size.height;
+ pNPWin->clipRect.left = aClipOrigin.x;
+ pNPWin->clipRect.top = aClipOrigin.y;
+ pNPWin->clipRect.right = aClipOrigin.x + aVisibleBounds.size.width;
+ pNPWin->clipRect.bottom = aClipOrigin.y + aVisibleBounds.size.height;
+
+ if( rPlugData.m_nDrawingModel == 1 )
+ {
+ rPlugData.m_aCGContext.window = reinterpret_cast<WindowRef>([pWin windowRef]);
+ pNPWin->window = &rPlugData.m_aCGContext;
+ rPlugData.m_aCGContext.context = reinterpret_cast<CGContextRef>([[pWin graphicsContext] graphicsPort]);
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "window is %p, context is %p\n",
+ rPlugData.m_aCGContext.window, rPlugData.m_aCGContext.context );
+ #endif
+ }
+ else
+ {
+ rPlugData.m_aNPPort.port = GetWindowPort( reinterpret_cast<WindowRef>([pWin windowRef]) );
+ rPlugData.m_aNPPort.portx = aClipOrigin.x;
+ rPlugData.m_aNPPort.porty = aClipOrigin.y;
+ pNPWin->window = &rPlugData.m_aNPPort;
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "port is %p at (%d,%d)\n",
+ rPlugData.m_aNPPort.port, (int)rPlugData.m_aNPPort.portx, (int)rPlugData.m_aNPPort.porty );
+ #endif
+ }
+
+ if( pNPWin->width == 0 || pNPWin->height == 0 || [rPlugData.m_pPlugView isHiddenOrHasHiddenAncestor] )
+ rPlugData.m_bSetWindowOnDraw = true;
+
+ NPError nErr = NPP_SetWindow( i_pImpl->getNPPInstance(), i_pImpl->getNPWindow() );
+
+ return nErr;
+}
+
+void MacPluginComm::drawView( XPlugin_Impl* i_pImpl )
+{
+ SysPlugData& rPlugData( i_pImpl->getSysPlugData() );
+
+ // check if the view was moved since the last SetWindow
+ NSPoint aViewOrigin = [rPlugData.m_pPlugView convertPoint: NSZeroPoint toView: nil];
+ if( rPlugData.m_bSetWindowOnDraw ||
+ aViewOrigin.x != rPlugData.m_aLastPlugViewOrigin.x ||
+ aViewOrigin.y != rPlugData.m_aLastPlugViewOrigin.y )
+ {
+ NPP_SetWindow( i_pImpl );
+ rPlugData.m_bSetWindowOnDraw = false;
+ }
+
+ // send a paint event
+ NSWindow* pWin = [rPlugData.m_pPlugView window];
+ FakeEventRecord aRec;
+ aRec.what = updateEvt;
+ aRec.message = (UInt32)[pWin windowRef];
+ this->NPP_HandleEvent( i_pImpl->getNPPInstance(), &aRec );
+}
+
diff --git a/extensions/source/plugin/base/context.cxx b/extensions/source/plugin/base/context.cxx
new file mode 100644
index 000000000000..27266579148e
--- /dev/null
+++ b/extensions/source/plugin/base/context.cxx
@@ -0,0 +1,343 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#include <cstdio>
+#endif
+
+#include <plugin/impl.hxx>
+
+#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAGS_HPP_
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#endif
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <tools/fsys.hxx>
+#include <tools/urlobj.hxx>
+
+#include <cppuhelper/implbase1.hxx>
+
+using namespace com::sun::star::io;
+
+namespace ext_plug {
+
+class FileSink : public ::cppu::WeakAggImplHelper1< ::com::sun::star::io::XOutputStream >
+{
+private:
+ Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ FILE* fp;
+ Reference< ::com::sun::star::plugin::XPlugin > m_xPlugin;
+ ::rtl::OUString m_aMIMEType;
+ ::rtl::OUString m_aTarget;
+ ::rtl::OUString m_aFileName;
+
+public:
+ FileSink( const Reference< ::com::sun::star::lang::XMultiServiceFactory > &,
+ const Reference< ::com::sun::star::plugin::XPlugin > & plugin,
+ const ::rtl::OUString& mimetype,
+ const ::rtl::OUString& target,
+ const Reference< ::com::sun::star::io::XActiveDataSource > & source );
+ virtual ~FileSink();
+
+ // ::com::sun::star::io::XOutputStream
+ virtual void SAL_CALL writeBytes( const Sequence<sal_Int8>& ) throw();
+ virtual void SAL_CALL flush() throw();
+ virtual void SAL_CALL closeOutput() throw();
+};
+
+}
+using namespace ext_plug;
+
+class XPluginContext_Impl : public ::cppu::WeakAggImplHelper1< ::com::sun::star::plugin::XPluginContext >
+{
+ Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ rtl_TextEncoding m_aEncoding;
+public:
+
+ XPluginContext_Impl( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & );
+ virtual ~XPluginContext_Impl();
+
+
+ virtual ::rtl::OUString SAL_CALL getValue(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, ::com::sun::star::plugin::PluginVariable variable) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL getURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Reference< ::com::sun::star::lang::XEventListener > & listener) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL getURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL postURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file, const Reference< ::com::sun::star::lang::XEventListener > & listener) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL postURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL newStream(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& mimetype, const ::rtl::OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual void SAL_CALL displayStatusText(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& message) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+ virtual ::rtl::OUString SAL_CALL getUserAgent(const Reference< ::com::sun::star::plugin::XPlugin > & plugin) throw( ::com::sun::star::plugin::PluginException, RuntimeException );
+};
+
+Reference< ::com::sun::star::plugin::XPluginContext > XPluginManager_Impl::createPluginContext() throw()
+{
+ return new XPluginContext_Impl( m_xSMgr );
+}
+
+XPluginContext_Impl::XPluginContext_Impl( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr )
+ : m_xSMgr( rSMgr ),
+ m_aEncoding( gsl_getSystemTextEncoding() )
+{
+}
+
+XPluginContext_Impl::~XPluginContext_Impl()
+{
+}
+
+::rtl::OUString XPluginContext_Impl::getValue( const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/, ::com::sun::star::plugin::PluginVariable /*variable*/ )
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ return ::rtl::OUString();
+}
+
+
+void XPluginContext_Impl::getURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target) throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ Reference< XInterface > xInst = m_xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) );
+ if( ! xInst.is() )
+ return;
+
+ if( ! target.getLength() )
+ {
+ INetURLObject aURL;
+ aURL.SetSmartProtocol( INET_PROT_FILE );
+ aURL.SetSmartURL( ::rtl::OUStringToOString( url, m_aEncoding ) );
+
+ rtl::OUString aUrl = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
+ // the mimetype cannot be specified
+ plugin->provideNewStream( ::rtl::OUString(),
+ Reference< XActiveDataSource >(),
+ aUrl,
+ 0, 0, (sal_Bool)(aUrl.compareToAscii( "file:", 5 ) == 0) );
+ return;
+ }
+
+ Reference< ::com::sun::star::frame::XComponentLoader > xLoader( xInst, UNO_QUERY );
+ XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( plugin );
+
+ if( xLoader.is() && pPlugin )
+ {
+ try
+ {
+ ::com::sun::star::beans::PropertyValue aValue;
+ aValue.Name = ::rtl::OUString::createFromAscii( "Referer" );
+ aValue.Value <<= pPlugin->getRefererURL();
+
+ Sequence< ::com::sun::star::beans::PropertyValue > aArgs( &aValue, 1 );
+ Reference< ::com::sun::star::lang::XComponent > xComp =
+ xLoader->loadComponentFromURL(
+ url,
+ target,
+ ::com::sun::star::frame::FrameSearchFlag::PARENT |
+ ::com::sun::star::frame::FrameSearchFlag::SELF |
+ ::com::sun::star::frame::FrameSearchFlag::CHILDREN |
+ ::com::sun::star::frame::FrameSearchFlag::SIBLINGS |
+ ::com::sun::star::frame::FrameSearchFlag::TASKS |
+ ::com::sun::star::frame::FrameSearchFlag::CREATE,
+ aArgs
+ );
+ }
+ catch(...)
+ {
+ throw ::com::sun::star::plugin::PluginException();
+ }
+ }
+}
+
+void XPluginContext_Impl::getURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Reference< ::com::sun::star::lang::XEventListener > & listener )
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ getURL( plugin, url, target );
+ if( listener.is() )
+ listener->disposing( ::com::sun::star::lang::EventObject() );
+}
+
+::rtl::OUString XPluginContext_Impl::getUserAgent(const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/)
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ return ::rtl::OUString::createFromAscii( "Mozilla 3.0" );
+}
+
+void XPluginContext_Impl::displayStatusText(const Reference< ::com::sun::star::plugin::XPlugin > & /*plugin*/, const ::rtl::OUString& /*message*/)
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+}
+
+void XPluginContext_Impl::postURL(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file)
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ Sequence< sal_Int8 > aBuf;
+
+ if( file )
+ {
+ String aFileName( (char*)buf.getConstArray(), m_aEncoding );
+ INetURLObject aFilePath( aFileName );
+ aFileName = aFilePath.PathToFileName();
+ SvFileStream aStream( aFileName, STREAM_READ );
+ if( aStream.IsOpen() )
+ {
+ int nBytes = 0;
+ aStream.Seek( STREAM_SEEK_TO_END );
+ aBuf = Sequence<sal_Int8>( nBytes = aStream.Tell() );
+ aStream.Seek( STREAM_SEEK_TO_BEGIN );
+ aStream.Read( aBuf.getArray(), nBytes );
+ aStream.Close();
+ DirEntry( aFileName ).Kill();
+ }
+ }
+
+ Reference< XInterface > xInst = m_xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) );
+ if( ! xInst.is() )
+ return ;
+
+ Reference< ::com::sun::star::frame::XComponentLoader > xLoader( xInst, UNO_QUERY );
+ XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( plugin );
+ if( xLoader.is() && pPlugin )
+ {
+ try
+ {
+ ::com::sun::star::beans::PropertyValue aValues[2];
+ aValues[0].Name = ::rtl::OUString::createFromAscii( "Referer" );
+ aValues[0].Value <<= pPlugin->getRefererURL();
+
+ aValues[1].Name = ::rtl::OUString::createFromAscii( "PostString" );
+ aValues[1].Value <<= ::rtl::OStringToOUString( (char*)( file ? aBuf : buf ).getConstArray(), m_aEncoding );
+ Sequence< ::com::sun::star::beans::PropertyValue > aArgs( aValues, 2 );
+ Reference< ::com::sun::star::lang::XComponent > xComp =
+ xLoader->loadComponentFromURL(
+ url,
+ target,
+ ::com::sun::star::frame::FrameSearchFlag::PARENT |
+ ::com::sun::star::frame::FrameSearchFlag::SELF |
+ ::com::sun::star::frame::FrameSearchFlag::CHILDREN |
+ ::com::sun::star::frame::FrameSearchFlag::SIBLINGS |
+ ::com::sun::star::frame::FrameSearchFlag::TASKS |
+ ::com::sun::star::frame::FrameSearchFlag::CREATE,
+ aArgs
+ );
+ }
+ catch( ... )
+ {
+ throw ::com::sun::star::plugin::PluginException();
+ }
+ }
+}
+
+void XPluginContext_Impl::postURLNotify(const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& url, const ::rtl::OUString& target, const Sequence< sal_Int8 >& buf, sal_Bool file, const Reference< ::com::sun::star::lang::XEventListener > & listener )
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ postURL( plugin, url, target, buf, file );
+ if( listener.is() )
+ listener->disposing( ::com::sun::star::lang::EventObject() );
+}
+
+void XPluginContext_Impl::newStream( const Reference< ::com::sun::star::plugin::XPlugin > & plugin, const ::rtl::OUString& mimetype, const ::rtl::OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source )
+ throw( ::com::sun::star::plugin::PluginException, RuntimeException )
+{
+ FileSink* pNewSink = new FileSink( m_xSMgr, plugin, mimetype, target, source );
+ pNewSink->acquire();
+}
+
+
+
+FileSink::FileSink( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr, const Reference< ::com::sun::star::plugin::XPlugin > & plugin,
+ const ::rtl::OUString& mimetype,
+ const ::rtl::OUString& target, const Reference< ::com::sun::star::io::XActiveDataSource > & source ) :
+ m_xSMgr( rSMgr ),
+ m_xPlugin( plugin ),
+ m_aMIMEType( mimetype ),
+ m_aTarget( target )
+{
+ DirEntry aEntry;
+ m_aFileName = aEntry.TempName().GetFull();
+ ::rtl::OString aFile = ::rtl::OUStringToOString( m_aFileName, gsl_getSystemTextEncoding() );
+ fp = fopen( aFile.getStr() , "wb" );
+
+ Reference< ::com::sun::star::io::XActiveDataControl > xControl( source, UNO_QUERY );
+
+ source->setOutputStream( Reference< ::com::sun::star::io::XOutputStream > ( this ) );
+ if( xControl.is() )
+ xControl->start();
+}
+
+FileSink::~FileSink()
+{
+ DirEntry aEntry( m_aFileName );
+ aEntry.Kill();
+}
+
+void FileSink::closeOutput() throw()
+{
+ if( fp )
+ fclose( fp );
+
+ Reference< XInterface > xInst = m_xSMgr->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) );
+ Reference< ::com::sun::star::frame::XComponentLoader > xLoader( xInst, UNO_QUERY );
+ XPlugin_Impl* pPlugin = XPluginManager_Impl::getPluginImplementation( m_xPlugin );
+
+ if( xLoader.is() && pPlugin )
+ {
+ try
+ {
+ ::com::sun::star::beans::PropertyValue aValue;
+ aValue.Name = ::rtl::OUString::createFromAscii( "Referer" );
+ aValue.Value <<= pPlugin->getRefererURL();
+
+ Sequence< ::com::sun::star::beans::PropertyValue > aArgs( &aValue, 1 );
+ Reference< ::com::sun::star::lang::XComponent > xComp =
+ xLoader->loadComponentFromURL(
+ m_aFileName,
+ m_aTarget,
+ ::com::sun::star::frame::FrameSearchFlag::PARENT |
+ ::com::sun::star::frame::FrameSearchFlag::SELF |
+ ::com::sun::star::frame::FrameSearchFlag::CHILDREN |
+ ::com::sun::star::frame::FrameSearchFlag::SIBLINGS |
+ ::com::sun::star::frame::FrameSearchFlag::TASKS |
+ ::com::sun::star::frame::FrameSearchFlag::CREATE,
+ aArgs
+ );
+ }
+ catch( ... )
+ {
+ }
+ }
+ release();
+}
+
+void FileSink::writeBytes( const Sequence<sal_Int8>& Buffer ) throw()
+{
+ if( fp )
+ fwrite( Buffer.getConstArray(), 1, Buffer.getLength(), fp );
+}
+
+void FileSink::flush() throw()
+{
+ if( fp )
+ fflush( fp );
+}
diff --git a/extensions/source/plugin/base/evtlstnr.cxx b/extensions/source/plugin/base/evtlstnr.cxx
new file mode 100644
index 000000000000..fda829f99b72
--- /dev/null
+++ b/extensions/source/plugin/base/evtlstnr.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include <plugin/impl.hxx>
+
+PluginEventListener::PluginEventListener( XPlugin_Impl* pPlugin,
+ const char* url,
+ const char* normurl,
+ void* notifyData ) :
+ m_pPlugin( pPlugin ),
+ m_xPlugin( pPlugin ),
+ m_pUrl( strdup( url ) ),
+ m_pNormalizedUrl( strdup( normurl ) ),
+ m_pNotifyData( notifyData )
+{
+}
+
+PluginEventListener::~PluginEventListener()
+{
+ if( m_pUrl )
+ free( m_pUrl );
+ if( m_pNormalizedUrl )
+ free( m_pNormalizedUrl );
+}
+
+void PluginEventListener::disposing( const ::com::sun::star::lang::EventObject& /*rEvt*/ ) throw()
+{
+ m_pPlugin->getPluginComm()->
+ NPP_URLNotify( m_pPlugin->getNPPInstance(),
+ m_pUrl,
+ NPRES_DONE,
+ m_pNotifyData );
+}
diff --git a/extensions/source/plugin/base/makefile.mk b/extensions/source/plugin/base/makefile.mk
new file mode 100644
index 000000000000..35390c6e6322
--- /dev/null
+++ b/extensions/source/plugin/base/makefile.mk
@@ -0,0 +1,70 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=extensions
+TARGET=plbase
+TARGETTYPE=GUI
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : ..$/util$/makefile.pmk
+
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/plugin
+.IF "$(SOLAR_JAVA)" != ""
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/java
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/nspr
+CDEFS+=-DOJI
+.ENDIF
+
+.IF "$(DISABLE_XAW)" != ""
+CDEFS+=-DDISABLE_XAW
+.ENDIF
+
+.IF "$(WITH_MOZILLA)" != "NO"
+
+.IF "$(GUIBASE)"=="aqua"
+CFLAGSCXX+=$(OBJCXXFLAGS)
+.ENDIF # "$(GUIBASE)"=="aqua"
+
+SLOFILES= \
+ $(SLO)$/plctrl.obj \
+ $(SLO)$/service.obj \
+ $(SLO)$/xplugin.obj \
+ $(SLO)$/nfuncs.obj \
+ $(SLO)$/manager.obj \
+ $(SLO)$/context.obj \
+ $(SLO)$/evtlstnr.obj \
+ $(SLO)$/plcom.obj \
+ $(SLO)$/multiplx.obj \
+ $(SLO)$/plmodel.obj
+
+.ENDIF # $(WITH_MOZILLA) != "NO"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/extensions/source/plugin/base/manager.cxx b/extensions/source/plugin/base/manager.cxx
new file mode 100644
index 000000000000..c40f599aad23
--- /dev/null
+++ b/extensions/source/plugin/base/manager.cxx
@@ -0,0 +1,225 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include "plugin/impl.hxx"
+
+#include "osl/mutex.hxx"
+#include "unotools/pathoptions.hxx"
+#include "vcl/configsettings.hxx"
+
+#include "com/sun/star/container/XEnumerationAccess.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/container/XEnumeration.hpp"
+#include "com/sun/star/container/XElementAccess.hpp"
+#include "com/sun/star/container/XIndexAccess.hpp"
+#include "com/sun/star/loader/XImplementationLoader.hpp"
+#include "com/sun/star/loader/CannotActivateFactoryException.hpp"
+
+PluginManager* PluginManager::pManager = NULL;
+
+PluginManager& PluginManager::get()
+{
+ if( ! pManager )
+ pManager = new PluginManager();
+ return *pManager;
+}
+
+void PluginManager::setServiceFactory( const Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
+{
+ PluginManager& rManager = get();
+ if( ! rManager.m_xSMgr.is() )
+ rManager.m_xSMgr = xFactory;
+}
+
+PluginManager::PluginManager()
+{
+}
+
+const Sequence< ::rtl::OUString >& PluginManager::getAdditionalSearchPaths()
+{
+ static Sequence< ::rtl::OUString > aPaths;
+
+ if( ! aPaths.getLength() )
+ {
+ SvtPathOptions aOptions;
+ String aPluginPath( aOptions.GetPluginPath() );
+ if( aPluginPath.Len() )
+ {
+ sal_uInt16 nPaths = aPluginPath.GetTokenCount( ';' );
+ aPaths.realloc( nPaths );
+ for( sal_uInt16 i = 0; i < nPaths; i++ )
+ aPaths.getArray()[i] = aPluginPath.GetToken( i, ';' );
+ }
+ }
+
+ return aPaths;
+}
+
+//==================================================================================================
+Reference< XInterface > SAL_CALL PluginManager_CreateInstance( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr ) throw( Exception )
+{
+ Reference< XInterface > xService = *new XPluginManager_Impl( rSMgr );
+ return xService;
+}
+
+// ::com::sun::star::lang::XServiceInfo
+::rtl::OUString XPluginManager_Impl::getImplementationName() throw( )
+
+{
+ return getImplementationName_Static();
+
+}
+
+// ::com::sun::star::lang::XServiceInfo
+sal_Bool XPluginManager_Impl::supportsService(const ::rtl::OUString& ServiceName) throw( )
+{
+ Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
+ const ::rtl::OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// ::com::sun::star::lang::XServiceInfo
+Sequence< ::rtl::OUString > XPluginManager_Impl::getSupportedServiceNames(void) throw( )
+{
+ return getSupportedServiceNames_Static();
+}
+
+// XPluginManager_Impl
+Sequence< ::rtl::OUString > XPluginManager_Impl::getSupportedServiceNames_Static(void) throw( )
+{
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[0] = ::rtl::OUString::createFromAscii( "com.sun.star.plugin.PluginManager" );
+ return aSNS;
+}
+
+XPluginManager_Impl::XPluginManager_Impl( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr )
+: m_xSMgr( rSMgr )
+{
+ PluginManager::setServiceFactory( rSMgr );
+}
+
+XPluginManager_Impl::~XPluginManager_Impl()
+{
+}
+
+XPlugin_Impl* XPluginManager_Impl::getXPluginFromNPP( NPP instance )
+{
+ ::std::list<XPlugin_Impl*>::iterator iter;
+ for( iter = PluginManager::get().getPlugins().begin();
+ iter != PluginManager::get().getPlugins().end(); ++iter )
+ {
+ if( (*iter)->getNPPInstance() == instance )
+ return *iter;
+ }
+
+ return NULL;
+}
+
+XPlugin_Impl* XPluginManager_Impl::getPluginImplementation( const Reference< ::com::sun::star::plugin::XPlugin >& plugin )
+{
+ ::std::list<XPlugin_Impl*>::iterator iter;
+ for( iter = PluginManager::get().getPlugins().begin();
+ iter != PluginManager::get().getPlugins().end(); ++iter )
+ {
+ if( plugin == Reference< ::com::sun::star::plugin::XPlugin >((*iter)) )
+ return *iter;
+ }
+
+ return NULL;
+}
+
+Sequence<com::sun::star::plugin::PluginDescription> XPluginManager_Impl::getPluginDescriptions() throw()
+{
+ Sequence<com::sun::star::plugin::PluginDescription> aRet;
+
+ vcl::SettingsConfigItem* pCfg = vcl::SettingsConfigItem::get();
+ rtl::OUString aVal( pCfg->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BrowserPlugins" ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Disabled" ) ) ) );
+ if( ! aVal.toBoolean() )
+ {
+ aRet = impl_getPluginDescriptions();
+ }
+ return aRet;
+}
+
+Reference< ::com::sun::star::plugin::XPlugin > XPluginManager_Impl::createPlugin( const Reference< ::com::sun::star::plugin::XPluginContext >& acontext, sal_Int16 mode, const Sequence< ::rtl::OUString >& argn, const Sequence< ::rtl::OUString >& argv, const ::com::sun::star::plugin::PluginDescription& plugintype)
+ throw( RuntimeException,::com::sun::star::plugin::PluginException )
+{
+ XPlugin_Impl* pImpl = new XPlugin_Impl( m_xSMgr );
+ pImpl->setPluginContext( acontext );
+
+ PluginManager::get().getPlugins().push_back( pImpl );
+
+ pImpl->initInstance( plugintype,
+ argn,
+ argv,
+ mode );
+
+ return pImpl;
+}
+
+Reference< ::com::sun::star::plugin::XPlugin > XPluginManager_Impl::createPluginFromURL( const Reference< ::com::sun::star::plugin::XPluginContext > & acontext, sal_Int16 mode, const Sequence< ::rtl::OUString >& argn, const Sequence< ::rtl::OUString >& argv, const Reference< ::com::sun::star::awt::XToolkit > & toolkit, const Reference< ::com::sun::star::awt::XWindowPeer > & parent, const ::rtl::OUString& url ) throw()
+{
+ XPlugin_Impl* pImpl = new XPlugin_Impl( m_xSMgr );
+ Reference< ::com::sun::star::plugin::XPlugin > xRef = pImpl;
+
+ pImpl->setPluginContext( acontext );
+
+ PluginManager::get().getPlugins().push_back( pImpl );
+
+
+ pImpl->initInstance( url,
+ argn,
+ argv,
+ mode );
+
+ pImpl->createPeer( toolkit, parent );
+
+ pImpl->provideNewStream( pImpl->getDescription().Mimetype,
+ Reference< com::sun::star::io::XActiveDataSource >(),
+ url,
+ 0, 0, (sal_Bool)(url.compareToAscii( "file:", 5 ) == 0) );
+
+ if( ! pImpl->getPluginComm() )
+ {
+ pImpl->dispose();
+ xRef = NULL;
+ }
+
+ return xRef;
+}
+
diff --git a/extensions/source/plugin/base/multiplx.cxx b/extensions/source/plugin/base/multiplx.cxx
new file mode 100644
index 000000000000..1957a9c19115
--- /dev/null
+++ b/extensions/source/plugin/base/multiplx.cxx
@@ -0,0 +1,332 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <vos/diagnose.hxx>
+#include <plugin/multiplx.hxx>
+
+// ---------------------------------------------------------------------
+// class MRCListenerMultiplexerHelper
+// ---------------------------------------------------------------------
+MRCListenerMultiplexerHelper::MRCListenerMultiplexerHelper
+(
+ const Reference< ::com::sun::star::awt::XWindow > & rControl
+ , const Reference< ::com::sun::star::awt::XWindow > & rPeer
+)
+ : xPeer( rPeer )
+ , xControl( Reference< ::com::sun::star::awt::XControl >( rControl, UNO_QUERY ) )
+ , aListenerHolder( aMutex )
+{
+}
+
+
+void MRCListenerMultiplexerHelper::setPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer )
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
+ if( xPeer != rPeer )
+ {
+ if( xPeer.is() )
+ {
+ // get all uiks from the listener added to the peer
+ Sequence<Type> aContainedTypes = aListenerHolder.getContainedTypes();
+ const Type* pArray = aContainedTypes.getConstArray();
+ sal_Int32 nCount = aContainedTypes.getLength();
+ // loop over all listener types and remove the listeners from the peer
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ unadviseFromPeer( xPeer, pArray[i] );
+ }
+ xPeer = rPeer;
+ if( xPeer.is() )
+ {
+ // get all uiks from the listener added to the peer
+ Sequence<Type> aContainedTypes = aListenerHolder.getContainedTypes();
+ const Type * pArray = aContainedTypes.getConstArray();
+ sal_Int32 nCount = aContainedTypes.getLength();
+ // loop over all listener types and add the listeners to the peer
+ for( sal_Int32 i = 0; i < nCount; i++ )
+ adviseToPeer( xPeer, pArray[i] );
+ }
+ }
+}
+
+// MRCListenerMultiplexerHelper
+void MRCListenerMultiplexerHelper::disposeAndClear()
+{
+ ::com::sun::star::lang::EventObject aEvt;
+ aEvt.Source = xControl;
+ aListenerHolder.disposeAndClear( aEvt );
+}
+
+// MRCListenerMultiplexerHelper
+void MRCListenerMultiplexerHelper::adviseToPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer, const Type & type )
+{
+ // add a listener to the source (peer)
+ if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XWindowListener >*)0) )
+ rPeer->addWindowListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XKeyListener >*)0) )
+ rPeer->addKeyListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XFocusListener >*)0) )
+ rPeer->addFocusListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XMouseListener >*)0) )
+ rPeer->addMouseListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XMouseMotionListener >*)0) )
+ rPeer->addMouseMotionListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XPaintListener >*)0) )
+ rPeer->addPaintListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XTopWindowListener >*)0) )
+ {
+ Reference< ::com::sun::star::awt::XTopWindow > xTop( rPeer, UNO_QUERY );
+ if( xTop.is() )
+ xTop->addTopWindowListener( this );
+ }
+ else
+ {
+ VOS_ENSHURE( sal_False, "unknown listener" );
+ }
+}
+
+// MRCListenerMultiplexerHelper
+void MRCListenerMultiplexerHelper::unadviseFromPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer, const Type & type )
+{
+ // the last listener is removed, remove the listener from the source (peer)
+ if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XWindowListener >*)0) )
+ rPeer->removeWindowListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XKeyListener >*)0) )
+ rPeer->removeKeyListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XFocusListener >*)0) )
+ rPeer->removeFocusListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XMouseListener >*)0) )
+ rPeer->removeMouseListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XMouseMotionListener >*)0) )
+ rPeer->removeMouseMotionListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XPaintListener >*)0) )
+ rPeer->removePaintListener( this );
+ else if( type == ::getCppuType((const Reference< ::com::sun::star::awt::XTopWindowListener >*)0) )
+ {
+ Reference< ::com::sun::star::awt::XTopWindow > xTop( rPeer, UNO_QUERY );
+ if( xTop.is() )
+ xTop->removeTopWindowListener( this );
+ }
+ else
+ {
+ VOS_ENSHURE( sal_False, "unknown listener" );
+ }
+}
+
+// MRCListenerMultiplexerHelper
+void MRCListenerMultiplexerHelper::advise( const Type & type, const Reference< XInterface > & listener)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
+ if( 1 == aListenerHolder.addInterface( type, listener ) )
+ {
+ // the first listener is added
+ if( xPeer.is() )
+ adviseToPeer( xPeer, type );
+ }
+}
+
+// MRCListenerMultiplexerHelper
+void MRCListenerMultiplexerHelper::unadvise(const Type & type, const Reference< XInterface > & listener)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
+ ::cppu::OInterfaceContainerHelper * pCont = aListenerHolder.getContainer( type );
+ if( pCont )
+ {
+ if( 0 == pCont->removeInterface( listener ) && xPeer.is() )
+ // the last listener is removed
+ unadviseFromPeer( xPeer, type );
+ }
+}
+
+// ::com::sun::star::lang::XEventListener
+void MRCListenerMultiplexerHelper::disposing(const ::com::sun::star::lang::EventObject& ) throw()
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
+ // peer is disposed, clear the reference
+ xPeer = Reference< ::com::sun::star::awt::XWindow > ();
+}
+
+#define MULTIPLEX( InterfaceName, MethodName, EventName ) \
+::cppu::OInterfaceContainerHelper * pCont; \
+pCont = aListenerHolder.getContainer( ::getCppuType((const Reference< InterfaceName >*)0) ); \
+if( pCont ) \
+{ \
+ ::cppu::OInterfaceIteratorHelper aIt( *pCont ); \
+ EventName aEvt = e; \
+ /* Remark: The control is the event source not the peer. We must change */ \
+ /* the source of the event */ \
+ aEvt.Source = xControl;\
+ /*.is the control not destroyed */ \
+ if( aEvt.Source.is() ) \
+ { \
+ if( aIt.hasMoreElements() ) \
+ { \
+ InterfaceName * pListener = (InterfaceName *)aIt.next(); \
+ try \
+ { \
+ pListener->MethodName( aEvt ); \
+ } \
+ catch( RuntimeException& ) \
+ { \
+ /* ignore all usr system exceptions from the listener */ \
+ } \
+ } \
+ } \
+}
+
+// ::com::sun::star::awt::XFocusListener
+void MRCListenerMultiplexerHelper::focusGained(const ::com::sun::star::awt::FocusEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XFocusListener, focusGained, ::com::sun::star::awt::FocusEvent )
+}
+
+// ::com::sun::star::awt::XFocusListener
+void MRCListenerMultiplexerHelper::focusLost(const ::com::sun::star::awt::FocusEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XFocusListener, focusLost, ::com::sun::star::awt::FocusEvent )
+}
+
+// ::com::sun::star::awt::XWindowListener
+void MRCListenerMultiplexerHelper::windowResized(const ::com::sun::star::awt::WindowEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XWindowListener, windowResized, ::com::sun::star::awt::WindowEvent )
+}
+
+// ::com::sun::star::awt::XWindowListener
+void MRCListenerMultiplexerHelper::windowMoved(const ::com::sun::star::awt::WindowEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XWindowListener, windowMoved, ::com::sun::star::awt::WindowEvent )
+}
+
+// ::com::sun::star::awt::XWindowListener
+void MRCListenerMultiplexerHelper::windowShown(const ::com::sun::star::lang::EventObject& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XWindowListener, windowShown, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XWindowListener
+void MRCListenerMultiplexerHelper::windowHidden(const ::com::sun::star::lang::EventObject& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XWindowListener, windowHidden, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XKeyListener
+void MRCListenerMultiplexerHelper::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XKeyListener, keyPressed, ::com::sun::star::awt::KeyEvent )
+}
+
+// ::com::sun::star::awt::XKeyListener
+void MRCListenerMultiplexerHelper::keyReleased(const ::com::sun::star::awt::KeyEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XKeyListener, keyReleased, ::com::sun::star::awt::KeyEvent )
+}
+
+// ::com::sun::star::awt::XMouseListener
+void MRCListenerMultiplexerHelper::mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseListener, mousePressed, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XMouseListener
+void MRCListenerMultiplexerHelper::mouseReleased(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseListener, mouseReleased, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XMouseListener
+void MRCListenerMultiplexerHelper::mouseEntered(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseListener, mouseEntered, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XMouseListener
+void MRCListenerMultiplexerHelper::mouseExited(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseListener, mouseExited, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XMouseMotionListener
+void MRCListenerMultiplexerHelper::mouseDragged(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseMotionListener, mouseDragged, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XMouseMotionListener
+void MRCListenerMultiplexerHelper::mouseMoved(const ::com::sun::star::awt::MouseEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XMouseMotionListener, mouseMoved, ::com::sun::star::awt::MouseEvent )
+}
+
+// ::com::sun::star::awt::XPaintListener
+void MRCListenerMultiplexerHelper::windowPaint(const ::com::sun::star::awt::PaintEvent& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XPaintListener, windowPaint, ::com::sun::star::awt::PaintEvent )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowOpened(const ::com::sun::star::lang::EventObject& e) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowOpened, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowClosing( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowClosing, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowClosed( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowClosed, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowMinimized( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowMinimized, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowNormalized( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowNormalized, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowActivated( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowActivated, ::com::sun::star::lang::EventObject )
+}
+
+// ::com::sun::star::awt::XTopWindowListener
+void MRCListenerMultiplexerHelper::windowDeactivated( const ::com::sun::star::lang::EventObject& e ) throw()
+{
+ MULTIPLEX( ::com::sun::star::awt::XTopWindowListener, windowDeactivated, ::com::sun::star::lang::EventObject )
+}
diff --git a/extensions/source/plugin/base/nfuncs.cxx b/extensions/source/plugin/base/nfuncs.cxx
new file mode 100644
index 000000000000..f4164fd71a46
--- /dev/null
+++ b/extensions/source/plugin/base/nfuncs.cxx
@@ -0,0 +1,677 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include <list>
+
+#include <plugin/impl.hxx>
+#include <vcl/svapp.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+#include <osl/thread.h>
+#include <stdio.h>
+static FILE * s_file = 0;
+void TRACE( char const * s )
+{
+ if (! s_file)
+ s_file = stderr;
+ if (s_file)
+ {
+ oslThreadIdentifier t = osl_getThreadIdentifier(0);
+ fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s\n", t, s );
+ fflush( s_file );
+ }
+}
+void TRACEN( char const * s, long n )
+{
+ if (! s_file)
+ s_file = stderr;
+ if (s_file)
+ {
+ oslThreadIdentifier t = osl_getThreadIdentifier(0);
+ fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s%ld\n", t, s, n );
+ fflush( s_file );
+ }
+}
+void TRACES( char const* s, char const* s2 )
+{
+ if (! s_file)
+ s_file = stderr;
+ if (s_file)
+ {
+ oslThreadIdentifier t = osl_getThreadIdentifier(0);
+ fprintf( s_file, "log [t_id=%"SAL_PRIuUINT32"]: %s %s\n", t, s, s2 );
+ fflush( s_file );
+ }
+}
+#else
+#define TRACE(x)
+#define TRACEN(x,n)
+#define TRACES(x,s)
+#endif
+
+using namespace rtl;
+using namespace com::sun::star::lang;
+
+NPNetscapeFuncs aNPNFuncs =
+{
+ sizeof( NPNetscapeFuncs ),
+ (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
+ NPN_GetURL,
+ NPN_PostURL,
+ NPN_RequestRead,
+ NPN_NewStream,
+ NPN_Write,
+ NPN_DestroyStream,
+ NPN_Status,
+ NPN_UserAgent,
+ NPN_MemAlloc,
+ NPN_MemFree,
+ NPN_MemFlush,
+ NPN_ReloadPlugins,
+#ifdef OJI
+ NPN_GetJavaEnv,
+ NPN_GetJavaPeer,
+#else
+ 0,
+ 0,
+#endif
+ NPN_GetURLNotify,
+ NPN_PostURLNotify,
+ NPN_GetValue,
+ NPN_SetValue,
+ NPN_InvalidateRect,
+ NPN_InvalidateRegion,
+ NPN_ForceRedraw
+};
+
+static ::rtl::OString normalizeURL( XPlugin_Impl* plugin, const ::rtl::OString& url )
+{
+ ::rtl::OString aLoadURL;
+ if( url.indexOf( ":" ) == -1 )
+ {
+ aLoadURL = ::rtl::OUStringToOString( plugin->getCreationURL(), plugin->getTextEncoding() );
+ int nPos;
+ if( ( nPos = aLoadURL.indexOf( "://" ) ) != -1 )
+ {
+ if( url.getLength() && (url.getStr()[ 0 ] == '/' || url.indexOf( '/' ) != -1) )
+ {
+ // this means same server but new path
+ nPos = aLoadURL.indexOf( '/', nPos+3 );
+
+ if( nPos != -1 )
+ aLoadURL = aLoadURL.copy( 0, url.getStr()[0] == '/' ? nPos : nPos+1 );
+ }
+ else
+ {
+ // same server but new file
+ nPos = aLoadURL.lastIndexOf( '/' );
+ aLoadURL = aLoadURL.copy( 0, nPos+1 );
+ }
+ aLoadURL += url;
+ }
+ else
+ aLoadURL = url;
+ }
+ else if( url.indexOf( ":/" ) != -1 )
+ aLoadURL = url;
+
+ return aLoadURL;
+}
+
+struct AsynchronousGetURL
+{
+ OUString aUrl;
+ OUString aTarget;
+ Reference< XEventListener > xListener;
+
+ DECL_LINK( getURL, XPlugin_Impl* );
+};
+
+IMPL_LINK( AsynchronousGetURL, getURL, XPlugin_Impl*, pImpl )
+{
+ try
+ {
+ pImpl->enterPluginCallback();
+ if( xListener.is() )
+ pImpl->getPluginContext()->
+ getURLNotify( pImpl,
+ aUrl,
+ aTarget,
+ xListener );
+ else
+ pImpl->getPluginContext()->
+ getURL( pImpl,
+ aUrl,
+ aTarget );
+ }
+ catch( ::com::sun::star::plugin::PluginException& e )
+ {
+ (void)e;
+ }
+ pImpl->leavePluginCallback();
+ delete this;
+ return 0;
+}
+
+
+extern "C" {
+
+ void* SAL_CALL NP_LOADDS NPN_MemAlloc( uint32 nBytes )
+ {
+ TRACE( "NPN_MemAlloc" );
+ void* pMem = malloc( nBytes );
+ return pMem;
+ }
+
+ void SAL_CALL NP_LOADDS NPN_MemFree( void* pMem )
+ {
+ TRACE( "NPN_MemFree" );
+ free( pMem );
+ }
+
+ uint32 SAL_CALL NP_LOADDS NPN_MemFlush( uint32 /*nSize*/ )
+ {
+ TRACE( "NPN_MemFlush" );
+ return 0;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_DestroyStream( NPP instance, NPStream* stream, NPError /*reason*/ )
+ {
+ TRACE( "NPN_DestroyStream" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
+ if( pStream )
+ {
+ if( pStream->getStreamType() == InputStream )
+ static_cast<PluginInputStream*>(pStream)->releaseSelf();
+ else
+ delete pStream;
+ }
+
+ return NPERR_NO_ERROR;
+ }
+
+ #ifdef OJI
+ const JRIEnvInterface** SAL_CALL NP_LOADDS NPN_GetJavaEnv()
+ {
+ TRACE( "NPN_GetJavaEnv" );
+ // no java in this program
+ return NULL;
+ }
+
+ jref SAL_CALL NP_LOADDS NPN_GetJavaPeer( NPP /*instance*/ )
+ {
+ TRACE( "NPN_GetJavaPeer" );
+ return NULL;
+ }
+ #endif
+
+ NPError SAL_CALL NP_LOADDS NPN_GetURL( NPP instance, const char* url, const char* window )
+ {
+ TRACES( "NPN_GetURL", url );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ AsynchronousGetURL* pAsync = new AsynchronousGetURL();
+
+ OString aLoadURL = normalizeURL( pImpl, url );
+ TRACES( "NPN_GetURL", aLoadURL.getStr() );
+ pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
+ pAsync->aTarget = OStringToOUString( window, pImpl->getTextEncoding() );
+ pImpl->setLastGetUrl( aLoadURL );
+ Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
+ return NPERR_NO_ERROR;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_GetURLNotify( NPP instance, const char* url, const char* target,
+ void* notifyData )
+ {
+ TRACES( "NPN_GetURLNotify", url );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ OString aLoadURL = normalizeURL( pImpl, url );
+ if( !aLoadURL.getLength() )
+ return NPERR_INVALID_URL;
+
+ AsynchronousGetURL* pAsync = new AsynchronousGetURL();
+ PluginEventListener* pListener =
+ new PluginEventListener( pImpl, url, aLoadURL.getStr(), notifyData );
+ if( ! target || ! *target )
+ {
+ // stream will be fed back to plugin,
+ // notify immediately after destruction of stream
+ pImpl->addPluginEventListener( pListener );
+ pListener = NULL;
+ }
+ pAsync->aUrl = OStringToOUString( aLoadURL, pImpl->getTextEncoding() );
+ pAsync->aTarget = OStringToOUString( target, pImpl->getTextEncoding() );
+ pAsync->xListener = pListener;
+ pImpl->setLastGetUrl( aLoadURL );
+ Application::PostUserEvent( LINK( pAsync, AsynchronousGetURL, getURL ), pImpl );
+
+ return NPERR_NO_ERROR;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
+ NPStream** stream )
+ // stream is a return value
+ {
+ TRACE( "NPN_NewStream" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ PluginOutputStream* pStream = new PluginOutputStream( pImpl,
+ "", 0, 0 );
+ *stream = pStream->getStream();
+
+ try
+ {
+ pImpl->enterPluginCallback();
+ pImpl->getPluginContext()->
+ newStream(
+ pImpl,
+ ::rtl::OStringToOUString( type, pImpl->getTextEncoding () ),
+ ::rtl::OStringToOUString( target, pImpl->getTextEncoding() ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > ( pStream->getOutputStream(), UNO_QUERY )
+ );
+ pImpl->leavePluginCallback();
+ }
+ catch( ::com::sun::star::plugin::PluginException& e )
+ {
+ pImpl->leavePluginCallback();
+ return e.ErrorCode;
+ }
+
+ return NPERR_NO_ERROR;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData )
+ {
+ TRACE( "NPN_PostURLNotify" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
+
+ ::rtl::OString aPostURL = normalizeURL( pImpl, url );
+ PluginEventListener* pListener =
+ new PluginEventListener( pImpl, url, aPostURL.getStr(), notifyData );
+
+ if( ! target || ! *target )
+ {
+ // stream will be fed back to plugin,
+ // notify immediately after destruction of stream
+ pImpl->addPluginEventListener( pListener );
+ pListener = NULL;
+ }
+
+ try
+ {
+ pImpl->enterPluginCallback();
+ pImpl->getPluginContext()->
+ postURLNotify( pImpl,
+ ::rtl::OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
+ ::rtl::OStringToOUString( target, pImpl->getTextEncoding() ),
+ Bytes,
+ file,
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > ( pListener ) );
+ pImpl->leavePluginCallback();
+ }
+ catch( ::com::sun::star::plugin::PluginException& e )
+ {
+ pImpl->leavePluginCallback();
+ return e.ErrorCode;
+ }
+
+ return NPERR_NO_ERROR;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_PostURL( NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file )
+ {
+ TRACE( "NPN_PostURL" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buf, len );
+ ::rtl::OString aPostURL = normalizeURL( pImpl, url );
+ try
+ {
+ pImpl->enterPluginCallback();
+ pImpl->getPluginContext()->
+ postURL( pImpl,
+ ::rtl::OStringToOUString( aPostURL, pImpl->getTextEncoding() ),
+ ::rtl::OStringToOUString( window, pImpl->getTextEncoding () ),
+ Bytes,
+ file );
+ pImpl->leavePluginCallback();
+ }
+ catch( ::com::sun::star::plugin::PluginException& e )
+ {
+ pImpl->leavePluginCallback();
+ return e.ErrorCode;
+ }
+
+ return NPERR_NO_ERROR;
+ }
+
+ NPError SAL_CALL NP_LOADDS NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
+ {
+ TRACE( "NPN_RequestRead" );
+ if( ! rangeList )
+ return NPERR_NO_ERROR;
+
+ ::std::list<XPlugin_Impl*>& rList = PluginManager::get().getPlugins();
+ ::std::list<XPlugin_Impl*>::iterator iter;
+ XPlugin_Impl* pPlugin = NULL;
+ PluginStream* pStream = NULL;
+ for( iter = rList.begin(); iter!= rList.end(); ++iter )
+ {
+ pStream = (*iter)->getStreamFromNPStream( stream );
+ if( pStream )
+ {
+ pPlugin = *iter;
+ break;
+ }
+ }
+ if( ! pPlugin )
+ return NPERR_INVALID_INSTANCE_ERROR;
+ if( ! pStream || pStream->getStreamType() != InputStream )
+ return NPERR_FILE_NOT_FOUND;
+
+ PluginInputStream* pInputStream = (PluginInputStream*)pStream;
+ sal_Int8* pBytes = NULL;
+ int nBytes = 0;
+ pPlugin->enterPluginCallback();
+ while( rangeList )
+ {
+ if( pBytes && nBytes < (int)rangeList->length )
+ {
+ delete [] pBytes;
+ pBytes = NULL;
+ }
+ if( ! pBytes )
+ pBytes = new sal_Int8[ nBytes = rangeList->length ];
+ int nRead =
+ pInputStream->read( rangeList->offset, pBytes, rangeList->length );
+ int nPos = 0;
+ int nNow;
+ do
+ {
+ nNow = pPlugin->getPluginComm()->
+ NPP_WriteReady( pPlugin->getNPPInstance(),
+ stream );
+ nNow = pPlugin->getPluginComm()->
+ NPP_Write( pPlugin->getNPPInstance(),
+ stream,
+ rangeList->offset + nPos,
+ nNow,
+ pBytes+nPos );
+ nPos += nNow;
+ nRead -= nNow;
+ } while( nRead > 0 && nNow );
+ rangeList = rangeList->next;
+ }
+ pPlugin->leavePluginCallback();
+
+ return NPERR_NO_ERROR;
+ }
+
+ void SAL_CALL NP_LOADDS NPN_Status( NPP instance, const char* message )
+ {
+ TRACE( "NPN_Status" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return;
+
+ try
+ {
+ pImpl->enterPluginCallback();
+ pImpl->getPluginContext()->
+ displayStatusText( pImpl, ::rtl::OStringToOUString( message, pImpl->getTextEncoding() ) );
+ pImpl->leavePluginCallback();
+ }
+ catch( ::com::sun::star::plugin::PluginException& )
+ {
+ pImpl->leavePluginCallback();
+ return;
+ }
+ }
+
+ const char* SAL_CALL NP_LOADDS NPN_UserAgent( NPP instance )
+ {
+ static char* pAgent = strdup( "Mozilla 3.0" );
+
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( pImpl )
+ {
+ rtl::OUString UserAgent;
+ try
+ {
+ pImpl->enterPluginCallback();
+ UserAgent = pImpl->getPluginContext()->
+ getUserAgent( pImpl );
+ pImpl->leavePluginCallback();
+ if( pAgent )
+ free( pAgent );
+ pAgent = strdup( ::rtl::OUStringToOString( UserAgent, pImpl->getTextEncoding() ).getStr() );
+ }
+ catch( ::com::sun::star::plugin::PluginException& )
+ {
+ pImpl->leavePluginCallback();
+ }
+ }
+
+ TRACES( "NPN_UserAgent: returning", pAgent );
+
+ return pAgent;
+ }
+
+void SAL_CALL NP_LOADDS NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
+{
+ TRACE( "NPN_Version" );
+ *major = 4;
+ *minor = 0;
+ *net_major = 4;
+ *net_minor = 5;
+}
+
+int32 SAL_CALL NP_LOADDS NPN_Write( NPP instance, NPStream* stream, int32 len,
+ void* buffer )
+{
+ TRACE( "NPN_Write" );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( ! pImpl )
+ return 0;
+
+ PluginStream* pStream = pImpl->getStreamFromNPStream( stream );
+ if( ! pStream || pStream->getStreamType() != OutputStream )
+ return 0;
+
+ pImpl->enterPluginCallback();
+ ::com::sun::star::uno::Sequence<sal_Int8> Bytes( (sal_Int8*)buffer, len );
+ ((PluginOutputStream*)pStream)->getOutputStream()->writeBytes( Bytes );
+ pImpl->leavePluginCallback();
+
+ return len;
+}
+
+
+NPError SAL_CALL NP_LOADDS NPN_GetValue( NPP instance, NPNVariable variable, void* value )
+{
+ TRACEN( "NPN_GetValue: ", variable );
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+
+ if( ! pImpl )
+ return 0;
+
+ NPError aResult( NPERR_NO_ERROR );
+
+ switch( variable )
+ {
+ case NPNVxDisplay:
+ // Unix only, handled in sysdep part
+ case NPNVxtAppContext:
+ // Unix only, handled in sysdep part
+ default:
+ aResult = NPERR_INVALID_PARAM;
+ break;
+ #ifdef QUARTZ
+ case 2000: // NPNVsupportsQuickDrawBool
+ *(NPBool*)value = false;
+ break;
+ case 2001: // NPNVsupportsCoreGraphicsBool
+ *(NPBool*)value = true;
+ break;
+ #endif
+ case NPNVjavascriptEnabledBool:
+ // no javascript
+ *(NPBool*)value = false;
+ break;
+ case NPNVasdEnabledBool:
+ // no SmartUpdate
+ *(NPBool*)value = false;
+ break;
+ case NPNVisOfflineBool:
+ // no offline browsing
+ *(NPBool*)value = false;
+ break;
+ }
+ /*
+ provisional code should there ever be NPNVariables that we actually
+ want to query from the PluginContext
+ ::rtl::OUString aValue;
+ try
+ {
+ pImpl->enterPluginCallback();
+ aValue = pImpl->getPluginContext()->
+ getValue( pImpl, (::com::sun::star::plugin::PluginVariable)variable );
+ pImpl->leavePluginCallback();
+ }
+ catch( ::com::sun::star::plugin::PluginException& e )
+ {
+ pImpl->leavePluginCallback();
+ return e.ErrorCode;
+ }
+ */
+
+ return aResult;
+}
+
+void SAL_CALL NP_LOADDS NPN_ReloadPlugins(NPBool /*reloadPages*/)
+{
+ TRACE( "NPN_ReloadPlugins" );
+}
+
+
+NPError SAL_CALL NP_LOADDS NPN_SetValue( NPP instance,
+ NPPVariable variable,
+ void* value )
+{
+ NPError nError = NPERR_NO_ERROR;
+ TRACEN( "NPN_SetValue ", variable );
+ switch( variable )
+ {
+ #ifdef QUARTZ
+ case (NPPVariable)1000: // NPNVpluginDrawingModel
+ {
+ int nDrawingModel = (int)value; // ugly, but that's the way we need to do it
+
+ TRACEN( "drawing model: ", nDrawingModel );
+
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( pImpl )
+ pImpl->getSysPlugData().m_nDrawingModel = nDrawingModel;
+ }
+ break;
+ #endif
+ case NPPVpluginNameString: // make the windows compiler happy, it needs at least one case statement
+ break;
+ default:
+ break;
+ }
+ #ifndef QUARTZ
+ (void)instance;
+ (void)value;
+ #endif
+ return nError;
+}
+
+void SAL_CALL NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect* /*invalidRect*/)
+{
+ TRACE( "NPN_InvalidateRect" );
+
+ #ifdef QUARTZ
+ NPN_ForceRedraw( instance );
+ #else
+ (void)instance;
+ #endif
+}
+
+void SAL_CALL NP_LOADDS NPN_InvalidateRegion(NPP instance, NPRegion /*invalidRegion*/)
+{
+ TRACE( "NPN_InvalidateRegion" );
+
+ #ifdef QUARTZ
+ NPN_ForceRedraw( instance );
+ #else
+ (void)instance;
+ #endif
+}
+
+void SAL_CALL NP_LOADDS NPN_ForceRedraw(NPP instance)
+{
+ TRACE( "NPN_ForceRedraw" );
+ #ifdef QUARTZ
+ XPlugin_Impl* pImpl = XPluginManager_Impl::getXPluginFromNPP( instance );
+ if( pImpl )
+ {
+ SysPlugData& rPlugData( pImpl->getSysPlugData() );
+ if( rPlugData.m_pPlugView )
+ [rPlugData.m_pPlugView setNeedsDisplay: YES];
+ }
+ #else
+ (void)instance;
+ #endif
+}
+
+}
diff --git a/extensions/source/plugin/base/plcom.cxx b/extensions/source/plugin/base/plcom.cxx
new file mode 100644
index 000000000000..09b4f1913d13
--- /dev/null
+++ b/extensions/source/plugin/base/plcom.cxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#ifdef SOLARIS
+#include <limits>
+#endif
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include <tools/fsys.hxx>
+#include <plugin/impl.hxx>
+
+PluginComm::PluginComm( const ::rtl::OString& rLibName, bool bReusable ) :
+ m_nRefCount( 0 ),
+ m_aLibName( rLibName )
+{
+ if( bReusable )
+ PluginManager::get().getPluginComms().push_back( this );
+}
+
+PluginComm::~PluginComm()
+{
+ PluginManager::get().getPluginComms().remove( this );
+ while( m_aFilesToDelete.size() )
+ {
+ String aFile = m_aFilesToDelete.front();
+ m_aFilesToDelete.pop_front();
+ DirEntry aEntry( aFile );
+ aEntry.Kill();
+ }
+}
+
+NPError PluginComm::NPP_SetWindow( XPlugin_Impl* i_pImpl )
+{
+ return NPP_SetWindow( i_pImpl->getNPPInstance(), i_pImpl->getNPWindow() );
+}
+
+NPError PluginComm::NPP_Destroy( XPlugin_Impl* i_pImpl, NPSavedData** save )
+{
+ return NPP_Destroy( i_pImpl->getNPPInstance(), save );
+}
+
diff --git a/extensions/source/plugin/base/plctrl.cxx b/extensions/source/plugin/base/plctrl.cxx
new file mode 100644
index 000000000000..cad58711b394
--- /dev/null
+++ b/extensions/source/plugin/base/plctrl.cxx
@@ -0,0 +1,323 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <com/sun/star/awt/XAdjustmentListener.hpp>
+#include <com/sun/star/awt/XActionListener.hpp>
+#include <com/sun/star/awt/XTextListener.hpp>
+#include <com/sun/star/awt/XSpinListener.hpp>
+#include <com/sun/star/awt/XItemListener.hpp>
+#include <com/sun/star/awt/XVclContainerListener.hpp>
+
+#include <plugin/plctrl.hxx>
+#include <vcl/syschild.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+
+
+//--------------------------------------------------------------------------------------------------
+PluginControl_Impl::PluginControl_Impl() :
+ _pMultiplexer( NULL )
+ , _nX( 0 )
+ , _nY( 0 )
+ , _nWidth( 100 )
+ , _nHeight( 100 )
+ , _nFlags( WINDOW_POSSIZE_ALL )
+ , _bVisible( sal_False )
+ , _bInDesignMode( sal_False )
+ , _bEnable( sal_True )
+{
+}
+
+//--------------------------------------------------------------------------------------------------
+PluginControl_Impl::~PluginControl_Impl()
+{
+}
+
+MRCListenerMultiplexerHelper* PluginControl_Impl::getMultiplexer()
+{
+ if( ! _pMultiplexer )
+ _pMultiplexer = new MRCListenerMultiplexerHelper( this, _xPeerWindow );
+ return _pMultiplexer;
+}
+//==================================================================================================
+
+void PluginControl_Impl::addEventListener( const Reference< ::com::sun::star::lang::XEventListener > & l )
+ throw( RuntimeException )
+{
+ _aDisposeListeners.push_back( l );
+}
+
+//---- ::com::sun::star::lang::XComponent ----------------------------------------------------------------------------------
+void PluginControl_Impl::removeEventListener( const Reference< ::com::sun::star::lang::XEventListener > & l )
+ throw( RuntimeException )
+{
+ _aDisposeListeners.remove( l );
+}
+
+//---- ::com::sun::star::lang::XComponent ----------------------------------------------------------------------------------
+void PluginControl_Impl::dispose(void)
+ throw( RuntimeException )
+{
+ // send disposing events
+ ::com::sun::star::lang::EventObject aEvt;
+ if( getMultiplexer() )
+ getMultiplexer()->disposeAndClear();
+
+ // release context
+ _xContext = Reference< XInterface > ();
+ releasePeer();
+}
+
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::setPosSize( sal_Int32 nX_, sal_Int32 nY_, sal_Int32 nWidth_, sal_Int32 nHeight_, sal_Int16 nFlags )
+ throw( RuntimeException )
+{
+ _nX = nX_ >=0 ? nX_ : 0;
+ _nY = nY_ >=0 ? nY_ : 0;
+ _nWidth = nWidth_ >=0 ? nWidth_ : 0;
+ _nHeight = nHeight_ >=0 ? nHeight_ : 0;
+ _nFlags = nFlags;
+
+ if (_xPeerWindow.is())
+ _xPeerWindow->setPosSize( _nX, _nY, _nWidth, _nHeight, nFlags );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+::com::sun::star::awt::Rectangle PluginControl_Impl::getPosSize(void)
+ throw( RuntimeException )
+{
+ return _xPeerWindow->getPosSize();
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::setVisible( sal_Bool bVisible )
+ throw( RuntimeException )
+{
+ _bVisible = bVisible;
+ if (_xPeerWindow.is())
+ _xPeerWindow->setVisible( _bVisible && !_bInDesignMode );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::setEnable( sal_Bool bEnable )
+ throw( RuntimeException )
+{
+ _bEnable = bEnable;
+ if (_xPeerWindow.is())
+ _xPeerWindow->setEnable( _bEnable );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::setFocus(void) throw( RuntimeException )
+{
+ if (_xPeerWindow.is())
+ _xPeerWindow->setFocus();
+}
+
+
+//--------------------------------------------------------------------------------------------------
+void PluginControl_Impl::releasePeer()
+{
+ if (_xPeer.is())
+ {
+ _xParentWindow->removeFocusListener( this );
+ _xPeerWindow->dispose();
+ _pSysChild = NULL;
+ _xPeerWindow = Reference< ::com::sun::star::awt::XWindow > ();
+ _xPeer = Reference< ::com::sun::star::awt::XWindowPeer > ();
+ getMultiplexer()->setPeer( Reference< ::com::sun::star::awt::XWindow > () );
+ }
+}
+
+//---- ::com::sun::star::awt::XControl ------------------------------------------------------------------------------------
+void PluginControl_Impl::createPeer( const Reference< ::com::sun::star::awt::XToolkit > & /*xToolkit*/, const Reference< ::com::sun::star::awt::XWindowPeer > & xParentPeer )
+ throw( RuntimeException )
+{
+ if (_xPeer.is())
+ {
+ DBG_ERROR( "### Peer is already set!" );
+ return;
+ }
+
+ _xParentPeer = xParentPeer;
+ _xParentWindow = Reference< ::com::sun::star::awt::XWindow > ( xParentPeer, UNO_QUERY );
+ DBG_ASSERT( _xParentWindow.is(), "### no parent peer window!" );
+
+ Window* pImpl = VCLUnoHelper::GetWindow( xParentPeer );
+ if (pImpl)
+ {
+ _pSysChild = new SystemChildWindow( pImpl, WB_CLIPCHILDREN );
+ if (pImpl->HasFocus())
+ _pSysChild->GrabFocus();
+
+ // get peer
+ _xPeer = Reference< ::com::sun::star::awt::XWindowPeer > ( _pSysChild->GetComponentInterface() );
+ _xPeerWindow = Reference< ::com::sun::star::awt::XWindow > ( _xPeer, UNO_QUERY );
+ // !_BOTH_ MUST BE VALID!
+ DBG_ASSERT( (_xPeer.is() && _xPeerWindow.is()), "### no peer!" );
+
+ _xParentWindow->addFocusListener( this );
+ _xPeerWindow->setPosSize( _nX, _nY, _nWidth, _nHeight, _nFlags );
+ _xPeerWindow->setEnable( _bEnable );
+ _xPeerWindow->setVisible( _bVisible && !_bInDesignMode );
+ }
+ else
+ {
+ DBG_ERROR( "### cannot get implementation of parent peer!" );
+ }
+
+ getMultiplexer()->setPeer( _xPeerWindow );
+}
+
+//---- ::com::sun::star::awt::XControl ------------------------------------------------------------------------------------
+void PluginControl_Impl::setDesignMode( sal_Bool bOn )
+ throw( RuntimeException )
+{
+ _bInDesignMode = bOn;
+ if (_xPeerWindow.is())
+ _xPeerWindow->setVisible( _bVisible && !_bInDesignMode );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addPaintListener( const Reference< ::com::sun::star::awt::XPaintListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XPaintListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removePaintListener( const Reference< ::com::sun::star::awt::XPaintListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XPaintListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addWindowListener( const Reference< ::com::sun::star::awt::XWindowListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XWindowListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removeWindowListener( const Reference< ::com::sun::star::awt::XWindowListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XWindowListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addFocusListener( const Reference< ::com::sun::star::awt::XFocusListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XFocusListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removeFocusListener( const Reference< ::com::sun::star::awt::XFocusListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XFocusListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addKeyListener( const Reference< ::com::sun::star::awt::XKeyListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XKeyListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removeKeyListener( const Reference< ::com::sun::star::awt::XKeyListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XKeyListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addMouseListener( const Reference< ::com::sun::star::awt::XMouseListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XMouseListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removeMouseListener( const Reference< ::com::sun::star::awt::XMouseListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XMouseListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::addMouseMotionListener( const Reference< ::com::sun::star::awt::XMouseMotionListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->advise( ::getCppuType((const Reference< ::com::sun::star::awt::XMouseMotionListener >*)0), l );
+}
+
+//---- ::com::sun::star::awt::XWindow -------------------------------------------------------------------------------------
+void PluginControl_Impl::removeMouseMotionListener( const Reference< ::com::sun::star::awt::XMouseMotionListener > & l )
+ throw( RuntimeException )
+{
+ getMultiplexer()->unadvise( ::getCppuType((const Reference< ::com::sun::star::awt::XMouseMotionListener >*)0), l );
+}
+
+
+//---- ::com::sun::star::awt::XView ---------------------------------------------------------------------------------------
+void PluginControl_Impl::draw( sal_Int32 /*x*/, sal_Int32 /*y*/ )
+ throw( RuntimeException )
+{
+ // has to be done by further implementation of control
+}
+
+//---- ::com::sun::star::awt::XView ---------------------------------------------------------------------------------------
+void PluginControl_Impl::setZoom( float /*ZoomX*/, float /*ZoomY*/ )
+ throw( RuntimeException )
+{
+ // has to be done by further implementation of control
+}
+
+//---- ::com::sun::star::lang::XEventListener ------------------------------------------------------------------------------
+void PluginControl_Impl::disposing( const ::com::sun::star::lang::EventObject & /*rSource*/ )
+ throw( RuntimeException )
+{
+}
+//---- ::com::sun::star::awt::XFocusListener ------------------------------------------------------------------------------
+void PluginControl_Impl::focusGained( const ::com::sun::star::awt::FocusEvent & /*rEvt*/ )
+ throw( RuntimeException )
+{
+ if (_xPeerWindow.is())
+ _xPeerWindow->setFocus();
+}
+//---- ::com::sun::star::awt::XFocusListener ------------------------------------------------------------------------------
+void PluginControl_Impl::focusLost( const ::com::sun::star::awt::FocusEvent & /*rEvt*/ )
+ throw( RuntimeException )
+{
+}
+
diff --git a/extensions/source/plugin/base/plmodel.cxx b/extensions/source/plugin/base/plmodel.cxx
new file mode 100644
index 000000000000..7e14ecd45d70
--- /dev/null
+++ b/extensions/source/plugin/base/plmodel.cxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <plugin/model.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+using namespace com::sun::star::uno;
+
+//==================================================================================================
+Reference< XInterface > SAL_CALL PluginModel_CreateInstance( const Reference< ::com::sun::star::lang::XMultiServiceFactory > & ) throw( Exception )
+{
+ Reference< XInterface > xService = *new PluginModel();
+ return xService;
+}
+
+Any PluginModel::queryAggregation( const Type& type ) throw( RuntimeException )
+{
+ Any aRet( ::cppu::queryInterface( type,
+ static_cast< ::com::sun::star::lang::XComponent* >(this),
+ static_cast< ::com::sun::star::io::XPersistObject* >(this ),
+ static_cast< ::com::sun::star::awt::XControlModel* >(this),
+ static_cast< ::com::sun::star::beans::XPropertySet* >(this),
+ static_cast< ::com::sun::star::beans::XMultiPropertySet* >(this),
+ static_cast< ::com::sun::star::beans::XFastPropertySet* >(this)
+ ) );
+ return aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( type );
+}
+
+
+// XPluginManager_Impl
+Sequence< ::rtl::OUString > PluginModel::getSupportedServiceNames_Static(void) throw()
+{
+ Sequence< ::rtl::OUString > aSNS( 1 );
+ aSNS.getArray()[0] = ::rtl::OUString::createFromAscii( "com.sun.star.plugin.PluginModel" );
+ return aSNS;
+}
+
+
+static const char* aCreationURL = "URL";
+static const char* aMime = "TYPE";
+
+static ::osl::Mutex aPropertyMutex;
+
+static ::com::sun::star::beans::Property aProps[] =
+{
+ ::com::sun::star::beans::Property(
+ ::rtl::OUString::createFromAscii( aMime ),
+ 1,
+ ::getCppuType((const ::rtl::OUString*)0),
+ ::com::sun::star::beans::PropertyAttribute::BOUND ),
+ ::com::sun::star::beans::Property(
+ ::rtl::OUString::createFromAscii( aCreationURL ),
+ 2,
+ ::getCppuType((const ::rtl::OUString*)0),
+ ::com::sun::star::beans::PropertyAttribute::BOUND )
+};
+
+PluginModel::PluginModel() :
+ BroadcasterHelperHolder( aPropertyMutex ),
+ OPropertySetHelper( m_aHelper ),
+ OPropertyArrayHelper( aProps, 2 )
+{
+}
+
+PluginModel::PluginModel(const ::rtl::OUString& rURL, const rtl::OUString& rMimeType ) :
+ BroadcasterHelperHolder( aPropertyMutex ),
+ OPropertySetHelper( m_aHelper ),
+ OPropertyArrayHelper( aProps, 2 ),
+ m_aCreationURL( rURL ),
+ m_aMimeType( rMimeType )
+{
+}
+
+PluginModel::~PluginModel()
+{
+}
+
+Reference< ::com::sun::star::beans::XPropertySetInfo > PluginModel::getPropertySetInfo() throw()
+{
+ static Reference< ::com::sun::star::beans::XPropertySetInfo > aInfo =
+ createPropertySetInfo( *this );
+ return aInfo;
+}
+
+::cppu::IPropertyArrayHelper& PluginModel::getInfoHelper()
+{
+ return *this;
+}
+
+sal_Bool PluginModel::convertFastPropertyValue( Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue ) throw()
+{
+ if( nHandle == 1 || nHandle == 2 )
+ {
+ if( rValue.getValueTypeClass() == TypeClass_STRING )
+ {
+ rConvertedValue = rValue;
+ if( nHandle == 2 )
+ rOldValue <<= m_aCreationURL;
+ else if( nHandle == 1 )
+ rOldValue <<= m_aMimeType;
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+void PluginModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
+ const Any& rValue )
+ throw(::com::sun::star::uno::Exception)
+{
+ if( rValue.getValueTypeClass() == TypeClass_STRING ) // FIXME wrong type!
+
+ {
+ if( nHandle == 2 )
+ rValue >>= m_aCreationURL;
+ else if( nHandle == 1 )
+ rValue >>= m_aMimeType;
+ }
+ else
+ throw ::com::sun::star::lang::IllegalArgumentException();
+}
+
+void PluginModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const throw()
+{
+ if( nHandle == 2 )
+ rValue <<= m_aCreationURL;
+ else if( nHandle == 1 )
+ rValue <<= m_aMimeType;
+}
+
+//---- ::com::sun::star::lang::XComponent ----------------------------------------------------------------------------------
+void PluginModel::addEventListener( const Reference< ::com::sun::star::lang::XEventListener > & l ) throw()
+{
+ m_aDisposeListeners.push_back( l );
+}
+
+//---- ::com::sun::star::lang::XComponent ----------------------------------------------------------------------------------
+void PluginModel::removeEventListener( const Reference< ::com::sun::star::lang::XEventListener > & l ) throw()
+{
+ m_aDisposeListeners.remove( l );
+}
+
+//---- ::com::sun::star::lang::XComponent ----------------------------------------------------------------------------------
+void PluginModel::dispose(void) throw()
+{
+ // send disposing events
+ ::com::sun::star::lang::EventObject aEvt;
+ aEvt.Source = (::cppu::OWeakObject*)this;
+ ::std::list< Reference< ::com::sun::star::lang::XEventListener > > aLocalListeners = m_aDisposeListeners;
+ for( ::std::list< Reference< ::com::sun::star::lang::XEventListener > >::iterator it = aLocalListeners.begin();
+ it != aLocalListeners.end(); ++it )
+ (*it)->disposing( aEvt );
+
+ m_aDisposeListeners.clear();
+
+ disposing();
+}
+
+
+// ::com::sun::star::io::XPersistObject
+::rtl::OUString PluginModel::getServiceName() throw()
+{
+ return ::rtl::OUString::createFromAscii( "com.sun.star.plugin.PluginModel" );
+}
+
+void PluginModel::write(const Reference< ::com::sun::star::io::XObjectOutputStream > & OutStream) throw()
+{
+ OutStream->writeUTF( m_aCreationURL );
+}
+
+void PluginModel::read(const Reference< ::com::sun::star::io::XObjectInputStream > & InStream) throw()
+{
+ m_aCreationURL = InStream->readUTF();
+}
diff --git a/extensions/source/plugin/base/service.cxx b/extensions/source/plugin/base/service.cxx
new file mode 100644
index 000000000000..21389caa2bbd
--- /dev/null
+++ b/extensions/source/plugin/base/service.cxx
@@ -0,0 +1,93 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include <plugin/impl.hxx>
+#include <tools/debug.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#include <uno/dispatcher.h> // declaration of generic uno interface
+#include <uno/mapping.hxx> // mapping stuff
+
+#include <cppuhelper/factory.hxx>
+
+using namespace cppu;
+
+extern "C" {
+ void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char** ppEnvTypeName,
+ uno_Environment** /*ppEnv*/ )
+ {
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+
+ void* SAL_CALL component_getFactory(
+ const sal_Char* pImplementationName,
+ void* pXUnoSMgr,
+ void* /*pXUnoKey*/
+ )
+ {
+ void* pRet = 0;
+
+ ::rtl::OUString aImplName( ::rtl::OUString::createFromAscii( pImplementationName ) );
+
+ if( pXUnoSMgr )
+ {
+ Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr(
+ reinterpret_cast< ::com::sun::star::lang::XMultiServiceFactory* >( pXUnoSMgr )
+ );
+ Reference< ::com::sun::star::lang::XSingleServiceFactory > xFactory;
+ if( aImplName.equals( XPluginManager_Impl::getImplementationName_Static() ) )
+ {
+ xFactory = ::cppu::createSingleFactory(
+ xMgr, aImplName, PluginManager_CreateInstance,
+ XPluginManager_Impl::getSupportedServiceNames_Static() );
+ }
+ else if( aImplName.equals( PluginModel::getImplementationName_Static() ) )
+ {
+ xFactory = ::cppu::createSingleFactory(
+ xMgr, aImplName, PluginModel_CreateInstance,
+ PluginModel::getSupportedServiceNames_Static() );
+ }
+ if( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+ return pRet;
+ }
+} /* extern "C" */
diff --git a/extensions/source/plugin/base/xplugin.cxx b/extensions/source/plugin/base/xplugin.cxx
new file mode 100644
index 000000000000..b031df45e2af
--- /dev/null
+++ b/extensions/source/plugin/base/xplugin.cxx
@@ -0,0 +1,1155 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/loader/XImplementationLoader.hpp>
+#include <com/sun/star/loader/CannotActivateFactoryException.hpp>
+
+#include <plugin/impl.hxx>
+#include <tools/fsys.hxx>
+#include <ucbhelper/content.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/string.hxx>
+#include <vcl/svapp.hxx>
+#include <vos/timer.hxx>
+#include <osl/file.hxx>
+
+#ifdef UNX
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+using namespace com::sun::star;
+using namespace com::sun::star::io;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::plugin;
+using namespace rtl;
+using namespace osl;
+
+class PluginDisposer : public vos::OTimer
+{
+private:
+ XPlugin_Impl* m_pPlugin;
+
+ virtual void SAL_CALL onShot();
+public:
+ PluginDisposer( XPlugin_Impl* pPlugin ) :
+ OTimer( vos::TTimeValue( 2, 0 ),
+ vos::TTimeValue( 2, 0 ) ),
+ m_pPlugin( pPlugin )
+ { start(); }
+ ~PluginDisposer() {}
+};
+
+void PluginDisposer::onShot()
+{
+ if( m_pPlugin )
+ {
+ if( m_pPlugin->isDisposable() )
+ {
+ sal_uLong nEvent;
+ Application::PostUserEvent( nEvent, LINK( m_pPlugin, XPlugin_Impl, secondLevelDispose ), (void*)m_pPlugin );
+ }
+ }
+ else
+ release();
+}
+
+//==================================================================================================
+
+Any XPlugin_Impl::queryInterface( const Type& type ) throw( RuntimeException )
+{
+ return OWeakAggObject::queryInterface( type );
+}
+
+Any XPlugin_Impl::queryAggregation( const Type& type ) throw( RuntimeException )
+{
+ Any aRet( cppu::queryInterface( type, static_cast< XPlugin* >(this) ) );
+ if( ! aRet.hasValue() )
+ aRet = PluginControl_Impl::queryAggregation( type );
+ return aRet;
+}
+
+
+XPlugin_Impl::XPlugin_Impl( const uno::Reference< com::sun::star::lang::XMultiServiceFactory > & rSMgr) :
+ PluginControl_Impl(),
+ m_xSMgr( rSMgr ),
+ m_pPluginComm( NULL ),
+ m_aEncoding( gsl_getSystemTextEncoding() ),
+ m_pArgv( NULL ),
+ m_pArgn( NULL ),
+ m_nArgs( 0 ),
+ m_aPluginMode( NP_FULL ),
+ m_nProvidingState( PROVIDING_NONE ),
+ m_nCalledFromPlugin( 0 ),
+ m_pDisposer( NULL ),
+ m_bIsDisposed( sal_False )
+{
+ memset( &m_aInstance, 0, sizeof( m_aInstance ) );
+ memset( &m_aNPWindow, 0, sizeof( m_aNPWindow ) );
+ memset( &m_aSysPlugData, 0, sizeof( m_aSysPlugData ) );
+
+ m_xModel = new PluginModel();
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY );
+ xPS->addPropertyChangeListener( OUString(), this );
+
+ Guard< Mutex > aGuard( PluginManager::get().getPluginMutex() );
+ PluginManager::get().getPlugins().push_back( this );
+}
+
+void XPlugin_Impl::destroyInstance()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ NPSavedData* pSavedData = NULL;
+
+ destroyStreams();
+ if( getPluginComm() )
+ {
+ getPluginComm()->NPP_Destroy( this, &pSavedData );
+ getPluginComm()->decRef();
+ m_pPluginComm = NULL;
+ }
+
+ freeArgs();
+
+ while( m_aPEventListeners.size() )
+ {
+ delete *m_aPEventListeners.begin();
+ m_aPEventListeners.pop_front();
+ }
+}
+
+XPlugin_Impl::~XPlugin_Impl()
+{
+ destroyInstance();
+}
+
+void XPlugin_Impl::checkListeners( const char* normalizedURL )
+{
+ if( ! normalizedURL )
+ return;
+
+ Guard< Mutex > aGuard( m_aMutex );
+
+ std::list<PluginEventListener*>::iterator iter;
+ for( iter = m_aPEventListeners.begin();
+ iter != m_aPEventListeners.end();
+ ++iter )
+ {
+ if( ! strcmp( normalizedURL, (*iter)->getURL() ) ||
+ ! strcmp( normalizedURL, (*iter)->getNormalizedURL() ) )
+ {
+ (*iter)->disposing( com::sun::star::lang::EventObject() );
+ delete *iter;
+ m_aPEventListeners.remove( *iter );
+ return;
+ }
+ }
+}
+
+IMPL_LINK( XPlugin_Impl, secondLevelDispose, XPlugin_Impl*, /*pThis*/ )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ // may have become undisposable between PostUserEvent and here
+ // or may have disposed and receive a second UserEvent
+ std::list<XPlugin_Impl*>& rList = PluginManager::get().getPlugins();
+ std::list<XPlugin_Impl*>::iterator iter;
+
+ {
+ Guard< Mutex > aPluginGuard( PluginManager::get().getPluginMutex() );
+ for( iter = rList.begin(); iter != rList.end(); ++iter )
+ {
+ if( *iter == this )
+ break;
+ }
+ if( iter == rList.end() || ! isDisposable() )
+ return 0;
+ }
+
+ if (m_pDisposer)
+ {
+ m_pDisposer->release();
+ m_pDisposer = NULL;
+ }
+
+ uno::Reference< XPlugin > xProtection( this );
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY );
+ xPS->removePropertyChangeListener( OUString(), this );
+ {
+ Guard< Mutex > aPluginGuard( PluginManager::get().getPluginMutex() );
+ rList.remove( this );
+ }
+ m_aNPWindow.window = NULL;
+#ifndef UNX
+ // acrobat does an unconditional XtParent on the windows widget
+ getPluginComm()->NPP_SetWindow( this );
+#endif
+ destroyInstance();
+ PluginControl_Impl::dispose();
+ return 0;
+}
+
+void XPlugin_Impl::dispose() throw()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ if (m_bIsDisposed || !getPluginComm())
+ return;
+ m_bIsDisposed = sal_True;
+
+ if( isDisposable() )
+ secondLevelDispose( this );
+ else
+ {
+ m_pDisposer = new PluginDisposer( this );
+ m_pDisposer->acquire();
+ }
+}
+
+void XPlugin_Impl::initArgs( const Sequence< OUString >& argn,
+ const Sequence< OUString >& argv,
+ sal_Int16 mode )
+{
+ m_aPluginMode = mode;
+
+ m_nArgs = argn.getLength();
+ m_pArgn = new const char*[m_nArgs];
+ m_pArgv = new const char*[m_nArgs];
+ const OUString* pUArgn = argn.getConstArray();
+ const OUString* pUArgv = argv.getConstArray();
+ for( int i = 0; i < m_nArgs; i++ )
+ {
+ m_pArgn[i] = strdup(
+ OUStringToOString( pUArgn[i], m_aEncoding ).getStr()
+ );
+ m_pArgv[i] = strdup(
+ OUStringToOString( pUArgv[i], m_aEncoding ).getStr()
+ );
+ }
+}
+
+void XPlugin_Impl::freeArgs()
+{
+ if( m_nArgs > 0 )
+ {
+ for( ; m_nArgs--; )
+ {
+ free( (void*)m_pArgn[m_nArgs] );
+ free( (void*)m_pArgv[m_nArgs] );
+ }
+ delete [] m_pArgn;
+ delete [] m_pArgv;
+ }
+}
+
+void XPlugin_Impl::prependArg( const char* pName, const char* pValue )
+{
+ const char** pNewNames = new const char*[m_nArgs+1];
+ const char** pNewValues = new const char*[m_nArgs+1];
+
+ pNewNames[0] = strdup( pName );
+ pNewValues[0] = strdup( pValue );
+ for( int nIndex = 0; nIndex < m_nArgs; ++nIndex )
+ {
+ pNewNames[nIndex+1] = m_pArgn[nIndex];
+ pNewValues[nIndex+1]= m_pArgv[nIndex];
+ }
+ // free old arrays
+ delete [] m_pArgn;
+ delete [] m_pArgv;
+ // set new arrays
+ m_pArgn = pNewNames;
+ m_pArgv = pNewValues;
+ // set new number of arguments
+ m_nArgs++;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "inserted %s=%s\n", pNewNames[0], pNewValues[0] );
+#endif
+}
+
+void XPlugin_Impl::handleSpecialArgs()
+{
+ // special handling for real audio which needs a lot of parameters
+ // or won't function at all
+ if( ! m_aDescription.Mimetype.compareToAscii( "audio/x-pn-realaudio-plugin" ) && m_nArgs < 1 )
+ {
+ OUString aURL;
+ if( m_xModel.is() )
+ {
+ try
+ {
+ uno::Reference< XPropertySet > xProp( m_xModel, UNO_QUERY );
+ Any aProp = xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) );
+ aProp >>= aURL;
+ }
+ catch( UnknownPropertyException )
+ {
+ }
+ }
+
+ if( aURL.getLength() )
+ {
+ // set new args, old args need not be freed as there were none set
+ m_nArgs = 6;
+ m_pArgn = new const char*[m_nArgs];
+ m_pArgv = new const char*[m_nArgs];
+
+ // SRC
+ m_pArgn[0] = strdup( "SRC" );
+ m_pArgv[0] = strdup( OUStringToOString( aURL, m_aEncoding ).getStr() );
+ // WIDTH
+ m_pArgn[1] = strdup( "WIDTH" );
+ m_pArgv[1] = strdup( "200" );
+ // HEIGHT
+ m_pArgn[2] = strdup( "HEIGHT" );
+ m_pArgv[2] = strdup( "200" );
+ // CONTROLS
+ m_pArgn[3] = strdup( "CONTROLS" );
+ m_pArgv[3] = strdup( "PlayButton,StopButton,ImageWindow" );
+ // AUTOSTART
+ m_pArgn[4] = strdup( "AUTOSTART" );
+ m_pArgv[4] = strdup( "TRUE" );
+ // NOJAVA
+ m_pArgn[5] = strdup( "NOJAVA" );
+ m_pArgv[5] = strdup( "TRUE" );
+ }
+ }
+ // #69333# special for pdf
+ else if( ! m_aDescription.Mimetype.compareToAscii( "application/pdf" ) )
+ m_aPluginMode = PluginMode::FULL;
+
+ // see if we have a TYPE tag
+ int nIndex;
+ for( nIndex = 0; nIndex < m_nArgs; ++nIndex )
+ if( m_pArgn[nIndex][0] == 'T' &&
+ m_pArgn[nIndex][1] == 'Y' &&
+ m_pArgn[nIndex][2] == 'P' &&
+ m_pArgn[nIndex][3] == 'E' &&
+ m_pArgn[nIndex][4] == 0 )
+ break;
+ if( nIndex >= m_nArgs )
+ {
+ // TYPE
+ prependArg( "TYPE", OUStringToOString( m_aDescription.Mimetype, m_aEncoding ).getStr() );
+ }
+
+ // see if we have a SRC tag
+ for( nIndex = 0; nIndex < m_nArgs; ++nIndex )
+ if( m_pArgn[nIndex][0] == 'S' &&
+ m_pArgn[nIndex][1] == 'R' &&
+ m_pArgn[nIndex][2] == 'C' &&
+ m_pArgn[nIndex][3] == 0 )
+ break;
+ if( nIndex >= m_nArgs )
+ {
+ // need a SRC parameter (as all browser set one on the plugin
+ OUString aURL;
+ if( m_xModel.is() )
+ {
+ try
+ {
+ uno::Reference< XPropertySet > xProp( m_xModel, UNO_QUERY );
+ Any aProp = xProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) );
+ aProp >>= aURL;
+ }
+ catch( UnknownPropertyException )
+ {
+ }
+ }
+
+ if( aURL.getLength() )
+ {
+ // SRC
+ prependArg( "SRC", OUStringToOString( aURL, m_aEncoding ).getStr() );
+ }
+ }
+}
+
+void XPlugin_Impl::initInstance( const PluginDescription& rDescription,
+ const Sequence< OUString >& argn,
+ const Sequence< OUString >& argv,
+ sal_Int16 mode )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ m_aDescription = rDescription;
+ initArgs( argn, argv, mode );
+ handleSpecialArgs();
+}
+
+void XPlugin_Impl::initInstance( const OUString& rURL,
+ const Sequence< OUString >& argn,
+ const Sequence< OUString >& argv,
+ sal_Int16 mode )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ initArgs( argn, argv, mode );
+ m_aDescription = fitDescription( rURL );
+
+ m_xModel = new PluginModel( rURL, m_aDescription.Mimetype );
+ handleSpecialArgs();
+}
+
+void XPlugin_Impl::modelChanged()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ m_nProvidingState = PROVIDING_MODEL_UPDATE;
+
+ destroyInstance();
+
+ m_aDescription = fitDescription( getCreationURL() );
+ if( !m_aDescription.Mimetype.getLength() )
+ {
+ m_nProvidingState = PROVIDING_NONE;
+ return;
+ }
+
+ OUString aURL = getCreationURL();
+ provideNewStream( m_aDescription.Mimetype,
+ uno::Reference< XActiveDataSource >(),
+ aURL,
+ 0, 0, (sal_Bool)(aURL.compareToAscii( "file:", 5 ) == 0) );
+ m_nProvidingState = PROVIDING_NONE;
+}
+
+OUString XPlugin_Impl::getCreationURL()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ OUString aRet;
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY );
+ if( xPS.is() )
+ {
+ Any aValue = xPS->getPropertyValue( OUString::createFromAscii( "URL" ) );
+ aValue >>= aRet;
+ }
+ return aRet;
+}
+
+
+sal_Bool XPlugin_Impl::setModel( const uno::Reference< com::sun::star::awt::XControlModel > & Model )
+ throw( RuntimeException )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( Model, UNO_QUERY );
+ if( ! xPS.is() )
+ return sal_False;
+
+ if( getCreationURL().getLength() )
+ {
+ m_xModel = Model;
+ modelChanged();
+ xPS->addPropertyChangeListener( OUString(), this );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+void XPlugin_Impl::createPeer( const uno::Reference< com::sun::star::awt::XToolkit > & xToolkit, const uno::Reference< com::sun::star::awt::XWindowPeer > & Parent )
+ throw( RuntimeException )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ if( ! _xPeer.is() )
+ {
+ if( ! Parent.is() )
+ throw RuntimeException();
+ PluginControl_Impl::createPeer( xToolkit, Parent );
+ }
+}
+
+void XPlugin_Impl::loadPlugin()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ std::list<PluginComm*>::iterator iter;
+ for( iter = PluginManager::get().getPluginComms().begin();
+ iter != PluginManager::get().getPluginComms().end(); ++iter )
+ {
+ if( OStringToOUString( (*iter)->getLibName(), m_aEncoding ) == m_aDescription.PluginName )
+ {
+ setPluginComm( *iter );
+ break;
+ }
+ }
+ const SystemEnvData* pEnvData = getSysChildSysData();
+#if defined( UNX ) && !(defined(QUARTZ))
+ XSync( (Display*)pEnvData->pDisplay, False );
+#endif
+ if( ! getPluginComm() )
+ {
+ if( m_aDescription.PluginName.getLength() )
+ {
+#if defined QUARTZ
+ PluginComm* pComm = new MacPluginComm( m_aDescription.Mimetype,
+ m_aDescription.PluginName,
+ pEnvData->pView );
+#elif defined UNX
+ // need a new PluginComm
+ PluginComm* pComm = NULL;
+ int sv[2];
+ if( !socketpair( AF_UNIX, SOCK_STREAM, 0, sv ) )
+ pComm = new UnxPluginComm( m_aDescription.Mimetype,
+ m_aDescription.PluginName,
+ (XLIB_Window)pEnvData->aWindow,
+ sv[0],
+ sv[1]
+ );
+#elif (defined WNT || defined OS2)
+ PluginComm* pComm = new PluginComm_Impl( m_aDescription.Mimetype,
+ m_aDescription.PluginName,
+ (HWND)pEnvData->hWnd );
+#endif
+ setPluginComm( pComm );
+ }
+ else
+ return;
+ }
+
+ NPError aError = getPluginComm()->
+ NPP_New( (char*)OUStringToOString( m_aDescription.Mimetype,
+ m_aEncoding).getStr(),
+ getNPPInstance(),
+ m_aPluginMode == PluginMode::FULL ? NP_FULL : NP_EMBED,
+ ::sal::static_int_cast< int16, int >( m_nArgs ),
+ (char**)(m_nArgs ? m_pArgn : NULL),
+ (char**)(m_nArgs ? m_pArgv : NULL),
+ NULL );
+#ifdef QUARTZ
+ // m_aNPWindow is set up in the MacPluginComm from the view
+ m_aSysPlugData.m_pParentView = pEnvData->pView;
+#elif defined( UNX )
+ XSync( (Display*)pEnvData->pDisplay, False );
+ m_aNPWindow.window = (void*)pEnvData->aWindow;
+ m_aNPWindow.ws_info = NULL;
+#else
+ m_aNPWindow.window = (void*)pEnvData->hWnd;
+#endif
+ com::sun::star::awt::Rectangle aPosSize = getPosSize();
+
+ for( int i = 0; i < m_nArgs; i++ )
+ {
+ OString aName( m_pArgn[i] );
+ if( aName.equalsIgnoreAsciiCase( "width" ) )
+ {
+ OString aValue( m_pArgv[i] );
+ aPosSize.Width = aValue.toInt32();
+ }
+ else if( aName.equalsIgnoreAsciiCase( "height" ) )
+ {
+ OString aValue( m_pArgv[i] );
+ aPosSize.Height = aValue.toInt32();
+ }
+ }
+
+ m_aNPWindow.clipRect.top = 0;
+ m_aNPWindow.clipRect.left = 0;
+ m_aNPWindow.clipRect.bottom = ::sal::static_int_cast< uint16, sal_Int32 >( aPosSize.Height );
+ m_aNPWindow.clipRect.right = ::sal::static_int_cast< uint16, sal_Int32 >( aPosSize.Width );
+ m_aNPWindow.type = NPWindowTypeWindow;
+
+ m_aNPWindow.x = 0;
+ m_aNPWindow.y = 0;
+ m_aNPWindow.width = aPosSize.Width ? aPosSize.Width : 600;
+ m_aNPWindow.height = aPosSize.Height ? aPosSize.Height : 600;
+
+ aError = getPluginComm()->NPP_SetWindow( this );
+}
+
+void XPlugin_Impl::destroyStreams()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ // streams remove themselves from this list when deleted
+ while( m_aOutputStreams.size() )
+ delete *m_aOutputStreams.begin();
+
+ // input streams are XOutputStreams, they cannot be simply deleted
+ std::list<PluginInputStream*> aLocalList( m_aInputStreams );
+ for( std::list<PluginInputStream*>::iterator it = aLocalList.begin();
+ it != aLocalList.end(); ++it )
+ (*it)->setMode( -1 );
+}
+
+PluginStream* XPlugin_Impl::getStreamFromNPStream( NPStream* stream )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ std::list<PluginInputStream*>::iterator iter;
+ for( iter = m_aInputStreams.begin(); iter != m_aInputStreams.end(); ++iter )
+ if( (*iter)->getStream() == stream )
+ return *iter;
+
+ std::list<PluginOutputStream*>::iterator iter2;
+ for( iter2 = m_aOutputStreams.begin(); iter2 != m_aOutputStreams.end(); ++iter2 )
+ if( (*iter2)->getStream() == stream )
+ return *iter2;
+
+ return NULL;
+}
+
+sal_Bool XPlugin_Impl::provideNewStream(const OUString& mimetype,
+ const uno::Reference< com::sun::star::io::XActiveDataSource > & stream,
+ const OUString& url, sal_Int32 length,
+ sal_Int32 lastmodified, sal_Bool isfile) throw()
+
+{
+ Guard< Mutex > aGuard( m_aMutex );
+ sal_Bool bRet = sal_False;
+
+ if( m_nProvidingState != PROVIDING_NONE )
+ {
+ m_nProvidingState = PROVIDING_NOW;
+ Any aAny;
+ aAny <<= url;
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY );
+ if( xPS.is() )
+ {
+ try
+ {
+ xPS->setPropertyValue( OUString::createFromAscii( "URL" ), aAny );
+ aAny <<= mimetype;
+ xPS->setPropertyValue( OUString::createFromAscii( "TYPE" ), aAny );
+ }
+ catch(...)
+ {
+ }
+ }
+ }
+ m_nProvidingState = PROVIDING_NOW;
+
+ OString aMIME;
+ if( mimetype.getLength() )
+ aMIME = OUStringToOString( mimetype, m_aEncoding );
+ else
+ aMIME = OUStringToOString( m_aDescription.Mimetype, m_aEncoding );
+
+ OString aURL = OUStringToOString( url, m_aEncoding );
+
+ // check wether there is a notifylistener for this stream
+ // this means that the strema is created from the plugin
+ // via NPN_GetURLNotify or NPN_PostURLNotify
+ std::list<PluginEventListener*>::iterator iter;
+ for( iter = m_aPEventListeners.begin();
+ iter != m_aPEventListeners.end();
+ ++iter )
+ {
+ if( (*iter)->getNormalizedURL() == aURL )
+ {
+ aURL = (*iter)->getURL();
+ break;
+ }
+ }
+
+ if( ! m_pPluginComm )
+ {
+ loadPlugin();
+ if( m_aLastGetUrl.getLength() && m_aLastGetUrl == aURL )
+ {
+ // plugin is pulling data, don't push the same stream;
+ // this complicated method could have been avoided if
+ // all plugins respected the SRC parameter; but e.g.
+ // acrobat reader plugin does not
+ m_nProvidingState = PROVIDING_NONE;
+ return sal_True;
+ }
+ }
+ if( ! m_pPluginComm )
+ return sal_False;
+
+ if( ! url.getLength() )
+ // this is valid if the plugin is supposed to
+ // pull data (via e.g. NPN_GetURL)
+ return sal_True;
+
+ // set mimetype on model
+ {
+ uno::Reference< com::sun::star::beans::XPropertySet > xPS( m_xModel, UNO_QUERY );
+ if( xPS.is() )
+ {
+ try
+ {
+ Any aAny;
+ aAny <<= m_aDescription.Mimetype;
+ xPS->setPropertyValue( OUString::createFromAscii( "TYPE" ), aAny );
+ }
+ catch(...)
+ {
+ }
+ }
+ }
+
+ // there may be plugins that can use the file length information,
+ // but currently none are known. Since this file opening/seeking/closing
+ // is rather costly, it is #if'ed out. If there are plugins known to
+ // make use of the file length, simply put it in
+#if 0
+ if( isfile && ! length )
+ {
+ osl::File aFile( url );
+ if( aFile.open( OpenFlag_Read ) == FileBase::E_None )
+ {
+ aFile.setPos( Pos_End, 0 );
+ sal_uInt64 nPos = 0;
+ if( aFile.getPos( nPos ) == FileBase::E_None )
+ length = nPos;
+ aFile.close();
+ }
+ }
+#endif
+
+ PluginInputStream* pStream = new PluginInputStream( this, aURL.getStr(),
+ length, lastmodified );
+ uno::Reference< com::sun::star::io::XOutputStream > xNewStream( pStream );
+
+ if( iter != m_aPEventListeners.end() )
+ pStream->getStream()->notifyData = (*iter)->getNotifyData();
+
+ uint16 stype = 0;
+
+ // special handling acrobat reader
+ // presenting a seekable stream to it does not seem to work correctly
+ if( aMIME.equals( "application/pdf" ) )
+ isfile = sal_False;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "new stream \"%s\" of MIMEType \"%s\"\n"
+ "for plugin \"%s\"\n"
+ "seekable = %s, length = %"SAL_PRIdINT32"\n",
+ aURL.getStr(), aMIME.getStr(), getPluginComm()->getLibName().getStr(),
+ isfile ? "true" : "false", length );
+
+#endif
+ if( ! m_pPluginComm->NPP_NewStream( &m_aInstance,
+ (char*)aMIME.getStr(),
+ pStream->getStream(), isfile,
+ &stype ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ const char* pType;
+ switch( stype )
+ {
+ case NP_NORMAL: pType = "NP_NORMAL";break;
+ case NP_SEEK: pType = "NP_SEEK";break;
+ case NP_ASFILE: pType = "NP_ASFILE";break;
+ case NP_ASFILEONLY: pType = "NP_ASFILEONLY";break;
+ default: pType = "unknown!!!";
+ }
+ fprintf( stderr, "Plugin wants it in Mode %s\n", pType );
+#endif
+ if( isfile && stype == NP_ASFILEONLY )
+ {
+ OString aFileName;
+ if( url.compareToAscii( "file:", 5 ) == 0 )
+ {
+ OUString aSysName;
+ osl_getSystemPathFromFileURL( url.pData, &aSysName.pData );
+ aFileName = OUStringToOString( aSysName, m_aEncoding );
+ }
+ else
+ aFileName = OUStringToOString( url, m_aEncoding );
+ m_pPluginComm->
+ NPP_StreamAsFile( &m_aInstance,
+ pStream->getStream(),
+ aFileName.getStr() );
+ }
+ else
+ {
+ pStream->setMode( stype );
+
+ if( ! stream.is() )
+ {
+ // stream has to be loaded by PluginStream itself via UCB
+ pStream->load();
+ }
+ else
+ {
+ uno::Reference< com::sun::star::io::XConnectable > xConnectable( stream, UNO_QUERY );
+ pStream->setPredecessor( xConnectable );
+ if( xConnectable.is() )
+ {
+ xConnectable->setSuccessor( static_cast< com::sun::star::io::XConnectable* >(pStream) );
+ while( xConnectable->getPredecessor().is() )
+ xConnectable = xConnectable->getPredecessor();
+ }
+ stream->setOutputStream( xNewStream );
+ pStream->setSource( stream );
+ uno::Reference< com::sun::star::io::XActiveDataControl > xController;
+ if( xConnectable.is() )
+ xController = uno::Reference< com::sun::star::io::XActiveDataControl >( xConnectable, UNO_QUERY );
+ else
+ xController = uno::Reference< com::sun::star::io::XActiveDataControl >( stream, UNO_QUERY );
+
+ if( xController.is() )
+ xController->start();
+ }
+ }
+ bRet = sal_True;
+ }
+
+ m_nProvidingState = PROVIDING_NONE;
+
+ return bRet;
+}
+
+void XPlugin_Impl::disposing( const com::sun::star::lang::EventObject& /*rSource*/ ) throw()
+{
+}
+
+void XPlugin_Impl::propertyChange( const com::sun::star::beans::PropertyChangeEvent& rEvent ) throw()
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+ if( ! rEvent.PropertyName.compareToAscii( "URL" ) )
+ {
+ OUString aStr;
+ rEvent.NewValue >>= aStr;
+ if( m_nProvidingState == PROVIDING_NONE )
+ {
+ if( aStr != m_aURL )
+ {
+ m_aURL = aStr;
+ modelChanged();
+ }
+ }
+ }
+}
+
+void XPlugin_Impl::setPluginContext( const uno::Reference< XPluginContext > & rContext )
+{
+ m_rBrowserContext = rContext;
+}
+
+void XPlugin_Impl::setPosSize( sal_Int32 nX_, sal_Int32 nY_, sal_Int32 nWidth_, sal_Int32 nHeight_, sal_Int16 nFlags )
+ throw( RuntimeException )
+{
+ Guard< Mutex > aGuard( m_aMutex );
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "XPlugin_Impl::setPosSize( %"SAL_PRIdINT32", %"SAL_PRIdINT32", %"SAL_PRIdINT32", %"SAL_PRIdINT32", %d )\n",
+ nX_, nY_, nWidth_, nHeight_, nFlags );
+#endif
+
+ PluginControl_Impl::setPosSize(nX_, nY_, nWidth_, nHeight_, nFlags);
+
+ m_aNPWindow.x = 0;
+ m_aNPWindow.y = 0;
+ m_aNPWindow.width = nWidth_;
+ m_aNPWindow.height = nHeight_;
+ m_aNPWindow.clipRect.top = 0;
+ m_aNPWindow.clipRect.left = 0;
+ m_aNPWindow.clipRect.right = ::sal::static_int_cast< uint16, sal_Int32 >( nWidth_ );
+ m_aNPWindow.clipRect.bottom = ::sal::static_int_cast< uint16, sal_Int32 >( nHeight_ );
+
+ if( getPluginComm() )
+ getPluginComm()->NPP_SetWindow( this );
+}
+
+PluginDescription XPlugin_Impl::fitDescription( const OUString& rURL )
+{
+ uno::Reference< XPluginManager > xPMgr( m_xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.plugin.PluginManager" ) ), UNO_QUERY );
+ if( !xPMgr.is() )
+ {
+ m_nProvidingState = PROVIDING_NONE;
+ return PluginDescription();
+ }
+
+ Sequence< PluginDescription > aDescrs = xPMgr->getPluginDescriptions();
+ const PluginDescription* pDescrs = aDescrs.getConstArray();
+
+ for( int nArg = 0; nArg < m_nArgs; nArg++ )
+ {
+ if( strncmp( m_pArgn[nArg], "TYPE", 4 ) == 0 &&
+ m_pArgn[nArg][4] == 0 )
+ {
+ for( int i = 0; i < aDescrs.getLength(); i++ )
+ {
+ if( pDescrs[i].Mimetype.compareToAscii( m_pArgv[nArg] ) == 0 )
+ return pDescrs[i];
+ }
+ }
+ }
+
+ int nPos = rURL.lastIndexOf( (sal_Unicode)'.' );
+ OUString aExt = rURL.copy( nPos ).toAsciiLowerCase();
+ if( nPos != -1 )
+ {
+ for( int i = 0; i < aDescrs.getLength(); i++ )
+ {
+ OUString aThisExt = pDescrs[ i ].Extension.toAsciiLowerCase();
+ if( aThisExt.indexOf( aExt ) != -1 )
+ {
+ return pDescrs[i];
+ }
+ }
+ }
+ return PluginDescription();
+}
+
+
+PluginStream::PluginStream( XPlugin_Impl* pPlugin,
+ const char* url, sal_uInt32 len, sal_uInt32 lastmod ) :
+ m_pPlugin( pPlugin )
+{
+ memset( &m_aNPStream, 0, sizeof( m_aNPStream ) );
+ m_aNPStream.url = strdup( url );
+ m_aNPStream.end = len;
+ m_aNPStream.lastmodified = lastmod;
+}
+
+PluginStream::~PluginStream()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ if( m_pPlugin && m_pPlugin->getPluginComm() )
+ {
+ m_pPlugin->getPluginComm()->NPP_DestroyStream( m_pPlugin->getNPPInstance(),
+ &m_aNPStream, NPRES_DONE );
+ m_pPlugin->checkListeners( m_aNPStream.url );
+ m_pPlugin->getPluginComm()->NPP_SetWindow( m_pPlugin );
+ }
+ ::free( (void*)m_aNPStream.url );
+}
+
+PluginInputStream::PluginInputStream( XPlugin_Impl* pPlugin,
+ const char* url,
+ sal_uInt32 len,
+ sal_uInt32 lastmod ) :
+ PluginStream( pPlugin, url, len, lastmod ),
+ m_pContent( NULL ),
+ m_nMode( NP_NORMAL ),
+ m_nWritePos( 0 )
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_pPlugin->getInputStreams().push_back( this );
+ DirEntry aEntry;
+ aEntry = aEntry.TempName();
+
+ // set correct extension, some plugins need that
+ DirEntry aName( String( m_aNPStream.url, m_pPlugin->getTextEncoding() ) );
+ String aExtension = aName.GetExtension();
+ if( aExtension.Len() )
+ aEntry.SetExtension( aExtension );
+ m_aFileStream.Open( aEntry.GetFull(), STREAM_READ | STREAM_WRITE );
+ if( ! m_aFileStream.IsOpen() )
+ {
+ // #74808# might be that the extension scrambled the whole filename
+ aEntry = aEntry.TempName();
+ m_aFileStream.Open( aEntry.GetFull(), STREAM_READ | STREAM_WRITE );
+ }
+}
+
+PluginInputStream::~PluginInputStream()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_pPlugin->getInputStreams().remove( this );
+
+ String aFile( m_aFileStream.GetFileName() );
+
+ m_aFileStream.Close();
+ if( m_pPlugin )
+ {
+ ByteString aFileName( aFile, m_pPlugin->getTextEncoding() );
+ if( m_pPlugin->getPluginComm() && m_nMode != -1 )
+ // mode -1 means either an error occured,
+ // or the plugin is already disposing
+ {
+ m_pPlugin->getPluginComm()->addFileToDelete( aFile );
+ if( m_nMode == NP_ASFILE )
+ {
+ m_pPlugin->getPluginComm()->
+ NPP_StreamAsFile( m_pPlugin->getNPPInstance(),
+ &m_aNPStream,
+ aFileName.GetBuffer() );
+ }
+ m_pPlugin->getPluginComm()->NPP_SetWindow( m_pPlugin );
+ m_pPlugin->getInputStreams().remove( this );
+ }
+ else
+ DirEntry( m_aFileStream.GetFileName() ).Kill();
+ }
+ else
+ DirEntry( m_aFileStream.GetFileName() ).Kill();
+ if( m_pContent )
+ delete m_pContent;
+}
+
+PluginStreamType PluginInputStream::getStreamType()
+{
+ return InputStream;
+}
+
+void PluginInputStream::load()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ INetURLObject aUrl;
+ aUrl.SetSmartProtocol( INET_PROT_FILE );
+ aUrl.SetSmartURL(
+ String( getStream()->url,
+ ::sal::static_int_cast< sal_uInt16, size_t >( strlen( getStream()->url ) ),
+ RTL_TEXTENCODING_MS_1252
+ ) );
+ try
+ {
+ m_pContent =
+ new ::ucbhelper::Content(
+ aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI),
+ uno::Reference< com::sun::star::ucb::XCommandEnvironment >()
+ );
+ m_pContent->openStream( static_cast< XOutputStream* >( this ) );
+ }
+ catch( com::sun::star::uno::Exception )
+ {
+ }
+}
+
+void PluginInputStream::setMode( sal_Int32 nMode )
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_nMode = nMode;
+
+ // invalidation by plugin
+ if( m_nMode == -1 && m_pPlugin )
+ {
+ m_pPlugin->getInputStreams().remove( this );
+ m_pPlugin = NULL;
+ }
+}
+
+void PluginInputStream::writeBytes( const Sequence<sal_Int8>& Buffer ) throw()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_aFileStream.Seek( STREAM_SEEK_TO_END );
+ m_aFileStream.Write( Buffer.getConstArray(), Buffer.getLength() );
+
+ if( m_nMode == NP_SEEK )
+ // hold reference, streem gets destroyed in NPN_DestroyStream
+ m_xSelf = this;
+
+ if( m_nMode == -1 || !m_pPlugin->getPluginComm() )
+ return;
+
+ sal_uInt32 nPos = m_aFileStream.Tell();
+ sal_uInt32 nBytes = 0;
+ while( m_nMode != NP_ASFILEONLY &&
+ m_nWritePos < nPos &&
+ (nBytes = m_pPlugin->getPluginComm()-> NPP_WriteReady(
+ m_pPlugin->getNPPInstance(), &m_aNPStream )) > 0 )
+ {
+ nBytes = (nBytes > nPos - m_nWritePos) ? nPos - m_nWritePos : nBytes;
+
+ char* pBuffer = new char[ nBytes ];
+ m_aFileStream.Seek( m_nWritePos );
+ nBytes = m_aFileStream.Read( pBuffer, nBytes );
+
+ int32 nBytesRead = 0;
+ try
+ {
+ nBytesRead = m_pPlugin->getPluginComm()->NPP_Write(
+ m_pPlugin->getNPPInstance(), &m_aNPStream, m_nWritePos, nBytes, pBuffer );
+ }
+ catch( ... )
+ {
+ nBytesRead = 0;
+ }
+ delete [] pBuffer;
+
+ if( nBytesRead < 0 )
+ {
+ m_nMode = -1;
+ return;
+ }
+
+ m_nWritePos += nBytesRead;
+ }
+}
+
+void PluginInputStream::closeOutput() throw()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ flush();
+ m_xSource = uno::Reference< com::sun::star::io::XActiveDataSource >();
+}
+
+sal_uInt32 PluginInputStream::read( sal_uInt32 offset, sal_Int8* buffer, sal_uInt32 size )
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ if( m_nMode != NP_SEEK )
+ return 0;
+
+ m_aFileStream.Seek( offset );
+ return m_aFileStream.Read( buffer, size );
+}
+
+void PluginInputStream::flush(void) throw()
+{
+}
+
+PluginOutputStream::PluginOutputStream( XPlugin_Impl* pPlugin,
+ const char* url,
+ sal_uInt32 len,
+ sal_uInt32 lastmod ) :
+ PluginStream( pPlugin, url, len, lastmod ),
+ m_xStream( pPlugin->getServiceManager()->createInstance( OUString::createFromAscii( "com.sun.star.io.DataOutputStream" ) ), UNO_QUERY )
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_pPlugin->getOutputStreams().push_back( this );
+}
+
+PluginOutputStream::~PluginOutputStream()
+{
+ Guard< Mutex > aGuard( m_pPlugin->getMutex() );
+
+ m_pPlugin->getOutputStreams().remove( this );
+}
+
+PluginStreamType PluginOutputStream::getStreamType()
+{
+ return OutputStream;
+}
+
diff --git a/extensions/source/plugin/inc/plugin/aqua/sysplug.hxx b/extensions/source/plugin/inc/plugin/aqua/sysplug.hxx
new file mode 100644
index 000000000000..bd4fc5405822
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/aqua/sysplug.hxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLUGIN_INC_MACPLUG_HXX
+#define __PLUGIN_INC_MACPLUG_HXX
+
+#include <unistd.h>
+
+#include <list>
+#include <map>
+#include <algorithm>
+#include "premac.h"
+#include <Carbon/Carbon.h>
+#include <Security/cssmconfig.h>
+#include "postmac.h"
+#undef uint32
+
+#define XP_MAC
+#include "npsdk/npapi.h"
+#include "npsdk/npupp.h"
+
+#include "plugin/plcom.hxx"
+#include "premac.h"
+#include <Cocoa/Cocoa.h>
+#include "postmac.h"
+
+#include "vcl/sysdata.hxx"
+#include "vcl/threadex.hxx"
+#include "vcl/timer.hxx"
+#include "osl/module.h"
+
+class XPlugin_Impl;
+
+namespace plugstringhelper
+{
+rtl::OUString getString( CFStringRef i_xString );
+rtl::OUString getString( CFURLRef i_xURL );
+CFMutableStringRef createString( const rtl::OUString& i_rString );
+CFURLRef createURL( const rtl::OUString& i_rString );
+rtl::OUString getURLFromPath( const rtl::OUString& i_rPath );
+CFURLRef createURLFromPath( const rtl::OUString& i_rPath );
+rtl::OUString CFURLtoOSLURL( CFURLRef i_xURL );
+}
+
+//==================================================================================================
+class MacPluginComm :
+ public PluginComm,
+ public ::vcl::SolarThreadExecutor
+
+{
+ enum CallType {
+ eNPP_Destroy,
+ eNPP_DestroyStream,
+ eNPP_GetJavaClass,
+ eNPP_Initialize,
+ eNPP_New,
+ eNPP_NewStream,
+ eNPP_Print,
+ eNPP_SetWindow,
+ eNPP_Shutdown,
+ eNPP_StreamAsFile,
+ eNPP_URLNotify,
+ eNPP_Write,
+ eNPP_WriteReady,
+ eNPP_GetValue,
+ eNPP_SetValue,
+ eNPP_HandleEvent,
+ eNP_Initialize
+ };
+
+ void* m_aArgs[ 8 ];
+ CallType m_eCall;
+
+ virtual long doIt();
+public:
+ MacPluginComm( const rtl::OUString& rMIME, const rtl::OUString& rName, NSView* pView );
+ virtual ~MacPluginComm();
+
+ // FIXME:
+ // this actually should be from the NP headers
+ // but currently we have too old a version
+ // changes this when we have updated our headers
+ typedef struct NP_CGContext
+ {
+ CGContextRef context;
+ WindowRef window;
+ } NP_CGContext;
+
+public:
+ virtual NPError NPP_Destroy( NPP instance, NPSavedData** save );
+ virtual NPError NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason );
+ virtual void * NPP_GetJavaClass();
+ virtual NPError NPP_Initialize();
+ virtual NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved );
+ virtual NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype );
+ virtual void NPP_Print( NPP instance, NPPrint* platformPrint );
+ virtual NPError NPP_SetWindow( NPP instance, NPWindow* window );
+ virtual void NPP_Shutdown();
+ virtual void NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname );
+ virtual void NPP_URLNotify( NPP instance, const char* url,
+ NPReason reason, void* notifyData );
+ virtual int32 NPP_Write( NPP instance, NPStream* stream, int32 offset,
+ int32 len, void* buffer );
+ virtual int32 NPP_WriteReady( NPP instance, NPStream* stream );
+ virtual NPError NPP_GetValue( NPP instance, NPPVariable variable, void *ret_value );
+ virtual NPError NPP_SetValue( NPP instance, NPNVariable variable, void *ret_value );
+ virtual int16 NPP_HandleEvent( NPP instance, void* event );
+
+ virtual NPError NPP_SetWindow( XPlugin_Impl* );
+ virtual NPError NPP_Destroy( XPlugin_Impl*, NPSavedData** save );
+
+ void drawView( XPlugin_Impl* );
+private:
+ sal_Bool retrieveFunction( const char* i_pName, void** i_ppFunc ) const;
+ DECL_LINK( NullTimerHdl, void* );
+
+private:
+ CFBundleRef m_xBundle;
+ oslModule m_hPlugLib;
+ NPPluginFuncs m_aNPPfuncs;
+
+ // timer for sending nullEvents
+ AutoTimer* m_pNullTimer;
+ std::list< XPlugin_Impl* > m_aNullEventClients;
+};
+
+struct SysPlugData
+{
+ MacPluginComm::NP_CGContext m_aCGContext;
+ NP_Port m_aNPPort;
+ NSView* m_pParentView;
+ NSView* m_pPlugView;
+ int m_nDrawingModel;
+ NSPoint m_aLastPlugViewOrigin;
+ bool m_bSetWindowOnDraw;
+};
+
+
+
+#endif
+
+
diff --git a/extensions/source/plugin/inc/plugin/impl.hxx b/extensions/source/plugin/inc/plugin/impl.hxx
new file mode 100644
index 000000000000..9b91c2fdeef1
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/impl.hxx
@@ -0,0 +1,430 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLUGIN_SOURCE_MGR_IMPL_HXX
+#define __PLUGIN_SOURCE_MGR_IMPL_HXX
+
+#ifdef SOLARIS
+#include <limits>
+#endif
+
+#include "cppuhelper/weak.hxx"
+
+#include "com/sun/star/awt/Key.hpp"
+#include "com/sun/star/awt/KeyFunction.hpp"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/plugin/PluginMode.hpp"
+#include "com/sun/star/plugin/PluginDescription.hpp"
+#include "com/sun/star/plugin/PluginException.hpp"
+#include "com/sun/star/plugin/PluginVariable.hpp"
+#include "com/sun/star/plugin/XPlugin.hpp"
+#include "com/sun/star/plugin/XPluginManager.hpp"
+#include "com/sun/star/plugin/XPluginContext.hpp"
+#include "com/sun/star/io/XConnectable.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XDataOutputStream.hpp"
+#include "com/sun/star/io/XActiveDataControl.hpp"
+#include "com/sun/star/io/XDataInputStream.hpp"
+#include "com/sun/star/io/XMarkableStream.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/io/XStreamListener.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/io/XActiveDataSource.hpp"
+#include "com/sun/star/lang/XServiceName.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/awt/GradientStyle.hpp"
+#include "com/sun/star/awt/RasterOperation.hpp"
+#include "com/sun/star/awt/Gradient.hpp"
+#include "com/sun/star/awt/XGraphics.hpp"
+
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+#include <list>
+
+#ifdef WNT
+#include "plugin/win/sysplug.hxx"
+#endif
+
+#ifdef WNT
+#include <plugin/win/sysplug.hxx>
+#elif defined(OS2)
+#include "plugin/os2/sysplug.hxx"
+#elif defined(QUARTZ)
+#include "plugin/aqua/sysplug.hxx"
+#elif defined(UNX)
+#include "plugin/unx/sysplug.hxx"
+#endif
+
+#if ! defined (QUARTZ)
+// the QUARTZ implementation needs special instance data
+typedef int SysPlugData;
+#endif
+
+#include "plugin/plctrl.hxx"
+#include "plugin/model.hxx"
+
+#include "vcl/sysdata.hxx"
+#include "vcl/syschild.hxx"
+
+#include "tools/link.hxx"
+#include "tools/stream.hxx"
+
+
+using namespace com::sun::star::uno;
+
+#define PROVIDING_NONE 0
+#define PROVIDING_NOW 1
+#define PROVIDING_MODEL_UPDATE 2
+
+// forwards
+namespace ucbhelper { class Content; }
+class PluginStream;
+class PluginInputStream;
+class PluginOutputStream;
+class XPlugin_Impl;
+class PluginDisposer;
+class PluginEventListener;
+
+class XPlugin_Impl : public com::sun::star::plugin::XPlugin,
+ public PluginControl_Impl,
+ public com::sun::star::beans::XPropertyChangeListener
+{
+private:
+ ::osl::Mutex m_aMutex;
+ Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ Reference< com::sun::star::plugin::XPluginContext > m_rBrowserContext;
+
+ PluginComm* m_pPluginComm;
+ NPP_t m_aInstance;
+ NPWindow m_aNPWindow;
+ SysPlugData m_aSysPlugData;
+ rtl_TextEncoding m_aEncoding;
+
+ const char** m_pArgv;
+ const char** m_pArgn;
+ int m_nArgs;
+ rtl::OString m_aLastGetUrl;
+
+ Reference< com::sun::star::awt::XControlModel > m_xModel;
+
+ ::com::sun::star::plugin::PluginDescription m_aDescription;
+ sal_Int16 m_aPluginMode;
+
+ int m_nProvidingState;
+ int m_nCalledFromPlugin;
+ PluginDisposer* m_pDisposer;
+
+ ::std::list<PluginInputStream*> m_aInputStreams;
+ ::std::list<PluginOutputStream*> m_aOutputStreams;
+ ::std::list<PluginEventListener*> m_aPEventListeners;
+ ::rtl::OUString m_aURL;
+
+ sal_Bool m_bIsDisposed;
+
+ void prependArg( const char* pName, const char* pValue ); // arguments will be strdup'ed
+ void initArgs( const Sequence< rtl::OUString >& argn,
+ const Sequence< rtl::OUString >& argv,
+ sal_Int16 mode );
+ void freeArgs();
+ void handleSpecialArgs();
+
+ void loadPlugin();
+ void destroyInstance();
+ void modelChanged();
+
+public:
+ XPlugin_Impl( const Reference< com::sun::star::lang::XMultiServiceFactory > & rSMgr );
+ virtual ~XPlugin_Impl();
+
+ ::osl::Mutex& getMutex() { return m_aMutex; }
+
+ void destroyStreams();
+
+ void setLastGetUrl( const rtl::OString& rUrl ) { m_aLastGetUrl = rUrl; }
+
+ com::sun::star::plugin::PluginDescription fitDescription( const rtl::OUString& rURL );
+
+ ::std::list<PluginInputStream*>& getInputStreams() { return m_aInputStreams; }
+ ::std::list<PluginOutputStream*>& getOutputStreams() { return m_aOutputStreams; }
+ PluginComm* getPluginComm() { return m_pPluginComm; }
+ void setPluginComm( PluginComm* comm )
+ {
+ if( ! m_pPluginComm )
+ {
+ m_pPluginComm = comm;
+ m_pPluginComm->addRef();
+ }
+ }
+ Reference< com::sun::star::lang::XMultiServiceFactory > getServiceManager() { return m_xSMgr; }
+ const com::sun::star::plugin::PluginDescription& getDescription() const { return m_aDescription; }
+ rtl_TextEncoding getTextEncoding() { return m_aEncoding; }
+ NPP getNPPInstance() { return &m_aInstance; }
+ NPWindow* getNPWindow() { return &m_aNPWindow; }
+ SysPlugData& getSysPlugData() { return m_aSysPlugData; }
+
+ void enterPluginCallback() { m_nCalledFromPlugin++; }
+ void leavePluginCallback() { m_nCalledFromPlugin--; }
+ sal_Bool isDisposable() { return m_nCalledFromPlugin < 1 ? sal_True : sal_False; }
+ DECL_LINK( secondLevelDispose, XPlugin_Impl* );
+
+ void addPluginEventListener( PluginEventListener* pListener )
+ { m_aPEventListeners.push_back( pListener ); }
+ void checkListeners( const char* normalizedURL );
+
+ void initInstance(
+ const com::sun::star::plugin::PluginDescription& rDescription,
+ const Sequence< rtl::OUString >& argn,
+ const Sequence< rtl::OUString >& argv,
+ sal_Int16 mode );
+ void initInstance(
+ const rtl::OUString& rURL,
+ const Sequence< rtl::OUString >& argn,
+ const Sequence< rtl::OUString >& argv,
+ sal_Int16 mode );
+
+ const rtl::OUString& getRefererURL() { return m_aURL; }
+ ::rtl::OUString getCreationURL();
+
+ PluginStream* getStreamFromNPStream( NPStream* );
+
+ const SystemEnvData* getSysChildSysData()
+ { return _pSysChild->GetSystemData(); }
+
+ const Reference< com::sun::star::plugin::XPluginContext > & getPluginContext() const
+ { return m_rBrowserContext; }
+ void setPluginContext( const Reference< com::sun::star::plugin::XPluginContext > & );
+
+ void secondLevelDispose();
+
+// static const Reference< com::sun::star::reflection::XIdlClass > & staticGetIdlClass();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type& ) throw( com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL acquire() throw()
+ { OWeakAggObject::acquire(); }
+ virtual void SAL_CALL release() throw()
+ { OWeakAggObject::release(); }
+
+ // OWeakAggObject
+ virtual Any SAL_CALL queryAggregation( const Type& )
+ throw( com::sun::star::uno::RuntimeException );
+
+ // PluginContol_Impl
+ virtual void SAL_CALL dispose() throw();
+ virtual void SAL_CALL createPeer( const Reference< com::sun::star::awt::XToolkit > & xToolkit, const Reference< com::sun::star::awt::XWindowPeer > & Parent) throw( RuntimeException );
+
+ virtual sal_Bool SAL_CALL setModel( const Reference< com::sun::star::awt::XControlModel > & Model ) throw( RuntimeException );
+ virtual Reference< com::sun::star::awt::XControlModel > SAL_CALL getModel()throw( RuntimeException )
+ { return m_xModel; }
+
+ virtual void SAL_CALL setPosSize( sal_Int32 nX_, sal_Int32 nY_, sal_Int32 nWidth_, sal_Int32 nHeight_, sal_Int16 nFlags ) throw( RuntimeException );
+
+ // com::sun::star::plugin::XPlugin
+ virtual sal_Bool SAL_CALL provideNewStream(const rtl::OUString& mimetype, const Reference< com::sun::star::io::XActiveDataSource > & stream, const rtl::OUString& url, sal_Int32 length, sal_Int32 lastmodified, sal_Bool isfile) throw();
+
+ // com::sun::star::beans::XPropertyChangeListener
+ virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& rSource ) throw();
+ virtual void SAL_CALL propertyChange( const com::sun::star::beans::PropertyChangeEvent& rEvent ) throw();
+};
+
+class PluginManager
+{
+private:
+ Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+ ::std::list<PluginComm*> m_aPluginComms;
+ ::std::list<XPlugin_Impl*> m_aAllPlugins;
+ ::osl::Mutex m_aPluginMutex;
+
+ static PluginManager* pManager;
+
+ PluginManager();
+public:
+
+ static PluginManager& get();
+ static void setServiceFactory( const Reference< com::sun::star::lang::XMultiServiceFactory >& xFactory );
+ static const Sequence< rtl::OUString >& getAdditionalSearchPaths();
+
+ ::std::list<PluginComm*>& getPluginComms() { return m_aPluginComms; }
+ ::std::list<XPlugin_Impl*>& getPlugins() { return m_aAllPlugins; }
+ ::osl::Mutex& getPluginMutex() { return m_aPluginMutex; }
+};
+
+class XPluginManager_Impl :
+ public cppu::WeakAggImplHelper1< com::sun::star::plugin::XPluginManager >
+{
+ Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+public:
+ XPluginManager_Impl( const Reference< com::sun::star::lang::XMultiServiceFactory > & );
+ virtual ~XPluginManager_Impl();
+
+ static XPlugin_Impl* getXPluginFromNPP( NPP );
+ static XPlugin_Impl* getPluginImplementation( const Reference< com::sun::star::plugin::XPlugin >& plugin );
+
+ virtual Reference< com::sun::star::plugin::XPluginContext > SAL_CALL createPluginContext() throw();
+
+ // has to be implemented per system
+ virtual Sequence< com::sun::star::plugin::PluginDescription > SAL_CALL impl_getPluginDescriptions(void) throw();
+ // calls system specific impl_getPluginDescriptions
+ // checks whether plugins are disabled
+ virtual Sequence< com::sun::star::plugin::PluginDescription > SAL_CALL getPluginDescriptions(void) throw();
+
+ virtual Reference< com::sun::star::plugin::XPlugin > SAL_CALL createPlugin( const Reference< com::sun::star::plugin::XPluginContext > & acontext, sal_Int16 mode, const Sequence< rtl::OUString >& argn, const Sequence< rtl::OUString >& argv, const com::sun::star::plugin::PluginDescription& plugintype) throw( RuntimeException,::com::sun::star::plugin::PluginException );
+
+ virtual Reference< com::sun::star::plugin::XPlugin > SAL_CALL createPluginFromURL( const Reference< com::sun::star::plugin::XPluginContext > & acontext, sal_Int16 mode, const Sequence< rtl::OUString >& argn, const Sequence< rtl::OUString >& argv, const Reference< com::sun::star::awt::XToolkit > & toolkit, const Reference< com::sun::star::awt::XWindowPeer > & parent, const rtl::OUString& url ) throw();
+
+ virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) throw();
+ virtual rtl::OUString SAL_CALL getImplementationName() throw();
+
+ Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( );
+ static Sequence< rtl::OUString > getSupportedServiceNames_Static(void) throw( );
+ static rtl::OUString getImplementationName_Static() throw( )
+ {
+ /** the soplayer uses this name in its source! maybe not after 5.2 */
+ return rtl::OUString::createFromAscii( "com.sun.star.extensions.PluginManager" );
+ }
+};
+Reference< XInterface > SAL_CALL PluginManager_CreateInstance( const Reference< com::sun::star::lang::XMultiServiceFactory > & ) throw( Exception );
+
+enum PluginStreamType { InputStream, OutputStream };
+
+class PluginStream
+{
+protected:
+ XPlugin_Impl* m_pPlugin;
+ NPStream m_aNPStream;
+public:
+ PluginStream( XPlugin_Impl* pPlugin,
+ const char* url, sal_uInt32 len, sal_uInt32 lastmod );
+ virtual ~PluginStream();
+
+ NPStream* getStream() { return &m_aNPStream; }
+ XPlugin_Impl* getPlugin() { return m_pPlugin; }
+
+ virtual PluginStreamType getStreamType() = 0;
+};
+
+class PluginInputStream :
+ public PluginStream,
+ public cppu::WeakAggImplHelper2<
+ ::com::sun::star::io::XOutputStream,
+ ::com::sun::star::io::XConnectable
+ >
+{
+private:
+ ::ucbhelper::Content* m_pContent;
+ sal_Int32 m_nMode;
+ sal_uInt32 m_nWritePos;
+
+ Reference< com::sun::star::io::XActiveDataSource > m_xSource;
+ // hold a reference on input until closeOutput is called
+
+ Reference< com::sun::star::io::XConnectable > m_xPredecessor;
+ Reference< com::sun::star::io::XConnectable > m_xSuccessor;
+
+ // needed to hold a reference to self in NP_SEEK mode
+ Reference< com::sun::star::io::XOutputStream > m_xSelf;
+
+ SvFileStream m_aFileStream;
+public:
+ PluginInputStream( XPlugin_Impl* pPlugin,
+ const char* url, sal_uInt32 len, sal_uInt32 lastmod );
+
+ PluginInputStream() : PluginStream( NULL, NULL, 0, 0 ) {}
+
+ virtual ~PluginInputStream();
+
+ virtual PluginStreamType getStreamType();
+
+ void setMode( sal_Int32 nMode );
+ sal_uInt32 read( sal_uInt32 offset, sal_Int8* buffer, sal_uInt32 size );
+ void setSource( const Reference< com::sun::star::io::XActiveDataSource >& xSource ) { m_xSource = xSource; }
+ // get contents ot url via ucbhelper::Content
+ void load();
+
+ // clear reference
+ bool releaseSelf()
+ { bool bRet = m_xSelf.is(); m_xSelf.clear(); return bRet; }
+
+ // XOutputStream
+ virtual void SAL_CALL writeBytes( const Sequence<sal_Int8>& ) throw();
+ virtual void SAL_CALL flush() throw();
+ virtual void SAL_CALL closeOutput() throw();
+
+ // XConnectable
+ virtual void SAL_CALL setPredecessor( const Reference< com::sun::star::io::XConnectable >& xPredecessor ) throw()
+ { m_xPredecessor = xPredecessor; }
+ virtual Reference< com::sun::star::io::XConnectable > SAL_CALL getPredecessor() throw()
+ { return m_xPredecessor; }
+
+ virtual void SAL_CALL setSuccessor( const Reference< com::sun::star::io::XConnectable >& xSuccessor ) throw()
+ { m_xSuccessor = xSuccessor; }
+ virtual Reference< com::sun::star::io::XConnectable > SAL_CALL getSuccessor() throw()
+ { return m_xSuccessor; }
+};
+
+class PluginOutputStream : public PluginStream
+{
+private:
+ Reference< com::sun::star::io::XOutputStream > m_xStream;
+public:
+ PluginOutputStream( XPlugin_Impl* pPlugin, const char* url,
+ sal_uInt32 len, sal_uInt32 lastmod );
+ virtual ~PluginOutputStream();
+
+ virtual PluginStreamType getStreamType();
+
+ Reference< com::sun::star::io::XOutputStream > & getOutputStream() { return m_xStream; }
+};
+
+class PluginEventListener :
+ public cppu::WeakAggImplHelper1< com::sun::star::lang::XEventListener >
+{
+private:
+ XPlugin_Impl* m_pPlugin;
+ Reference< com::sun::star::plugin::XPlugin > m_xPlugin; // just to hold the plugin
+ char* m_pUrl;
+ char* m_pNormalizedUrl;
+ void* m_pNotifyData;
+public:
+ PluginEventListener( XPlugin_Impl*,
+ const char* url,
+ const char* normurl,
+ void* notifyData );
+ virtual ~PluginEventListener();
+
+ const char* getURL() { return m_pUrl; }
+ const char* getNormalizedURL() { return m_pNormalizedUrl; }
+ void* getNotifyData() { return m_pNotifyData; }
+
+ // com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& Source ) throw();
+};
+
+#endif
diff --git a/extensions/source/plugin/inc/plugin/model.hxx b/extensions/source/plugin/inc/plugin/model.hxx
new file mode 100644
index 000000000000..9f9ac01f0ac3
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/model.hxx
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLUGIN_MODEL_HXX
+#define __PLUGIN_MODEL_HXX
+
+#include <com/sun/star/io/XObjectInputStream.hpp>
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/lang/XServiceName.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+
+#include <cppuhelper/propshlp.hxx>
+#include <cppuhelper/weakagg.hxx>
+#include <rtl/alloc.h>
+
+#include <list>
+
+using namespace com::sun::star::uno;
+
+class BroadcasterHelperHolder
+{
+protected:
+ ::cppu::OBroadcastHelper m_aHelper;
+public:
+ BroadcasterHelperHolder( osl::Mutex& rMutex ) :
+ m_aHelper( rMutex ) {}
+ ~BroadcasterHelperHolder() {}
+
+ ::cppu::OBroadcastHelper& getHelper() { return m_aHelper; }
+
+};
+
+class PluginModel : public BroadcasterHelperHolder,
+ public cppu::OPropertySetHelper,
+ public cppu::OPropertyArrayHelper,
+ public cppu::OWeakAggObject,
+ public com::sun::star::lang::XComponent,
+ public com::sun::star::io::XPersistObject,
+ public com::sun::star::awt::XControlModel
+{
+ private:
+ rtl::OUString m_aCreationURL;
+ rtl::OUString m_aMimeType;
+
+ std::list< Reference< com::sun::star::lang::XEventListener > >
+ m_aDisposeListeners;
+ public:
+ // these are here to force memory de/allocation to sal lib.
+ static void * SAL_CALL operator new( size_t nSize ) throw()
+ { return rtl_allocateMemory( nSize ); }
+ static void SAL_CALL operator delete( void * pMem ) throw()
+ { rtl_freeMemory( pMem ); }
+
+ PluginModel();
+ PluginModel( const rtl::OUString& rURL, const rtl::OUString& rMimeType );
+ virtual ~PluginModel();
+
+
+ const rtl::OUString& getCreationURL() { return m_aCreationURL; }
+ void setMimeType( const rtl::OUString& rMime ) { m_aMimeType = rMime; }
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type& rType ) throw( com::sun::star::uno::RuntimeException )
+ { return OWeakAggObject::queryInterface( rType ); }
+ virtual void SAL_CALL acquire() throw()
+ { OWeakAggObject::acquire(); }
+ virtual void SAL_CALL release() throw()
+ { OWeakAggObject::release(); }
+
+ virtual Any SAL_CALL queryAggregation( const Type& ) throw( com::sun::star::uno::RuntimeException );
+
+
+ // com::sun::star::lang::XTypeProvider
+
+ static Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames_Static(void) throw( );
+ static rtl::OUString SAL_CALL getImplementationName_Static() throw( )
+ {
+ /** the soplayer uses this name in its source! maybe not after 5.2 */
+ return rtl::OUString::createFromAscii( "com.sun.star.extensions.PluginModel" );
+ }
+
+ // OPropertySetHelper
+ virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+ virtual sal_Bool SAL_CALL convertFastPropertyValue( Any & rConvertedValue,
+ Any & rOldValue,
+ sal_Int32 nHandle,
+ const Any& rValue ) throw();
+ virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
+ const Any& rValue )
+ throw(::com::sun::star::uno::Exception);
+ virtual void SAL_CALL getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const throw();
+ virtual Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw();
+
+ // com::sun::star::io::XPersistObject
+ virtual rtl::OUString SAL_CALL getServiceName() throw();
+ virtual void SAL_CALL write(const Reference< com::sun::star::io::XObjectOutputStream > & OutStream) throw();
+ virtual void SAL_CALL read(const Reference< com::sun::star::io::XObjectInputStream > & InStream) throw();
+
+ // com::sun::star::lang::XComponent
+ virtual void SAL_CALL addEventListener( const Reference< com::sun::star::lang::XEventListener > & l ) throw();
+ virtual void SAL_CALL removeEventListener( const Reference< com::sun::star::lang::XEventListener > & l ) throw();
+ virtual void SAL_CALL dispose() throw();
+ private:
+ using cppu::OPropertySetHelper::getFastPropertyValue;
+};
+Reference< XInterface > SAL_CALL PluginModel_CreateInstance( const Reference< com::sun::star::lang::XMultiServiceFactory > & ) throw( Exception );
+
+#endif // __PLUGIN_MODEL_HXX
diff --git a/extensions/source/plugin/inc/plugin/multiplx.hxx b/extensions/source/plugin/inc/plugin/multiplx.hxx
new file mode 100644
index 000000000000..45b60c12313d
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/multiplx.hxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _MRC_MULTIPLX_HXX
+#define _MRC_MULTIPLX_HXX
+
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/awt/XPaintListener.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/awt/XMouseMotionListener.hpp>
+#include <com/sun/star/awt/FocusEvent.hpp>
+#include <com/sun/star/awt/XWindowListener.hpp>
+#include <com/sun/star/awt/XActivateListener.hpp>
+#include <com/sun/star/awt/MouseEvent.hpp>
+#include <com/sun/star/awt/XTopWindowListener.hpp>
+#include <com/sun/star/awt/PaintEvent.hpp>
+#include <com/sun/star/awt/InputEvent.hpp>
+#include <com/sun/star/awt/KeyGroup.hpp>
+#include <com/sun/star/awt/Key.hpp>
+#include <com/sun/star/awt/WindowEvent.hpp>
+#include <com/sun/star/awt/XMouseListener.hpp>
+#include <com/sun/star/awt/KeyFunction.hpp>
+#include <com/sun/star/awt/FocusChangeReason.hpp>
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/awt/XFocusListener.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+
+#include <cppuhelper/implbase7.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+
+using namespace com::sun::star::uno;
+
+struct MRCListenerMultiplexerHelper_Mutex
+{
+ ::osl::Mutex aMutex;
+};
+
+class MRCListenerMultiplexerHelper :
+ public MRCListenerMultiplexerHelper_Mutex,
+
+ public ::cppu::WeakAggImplHelper7<
+ ::com::sun::star::awt::XFocusListener,
+ ::com::sun::star::awt::XWindowListener,
+ ::com::sun::star::awt::XKeyListener,
+ ::com::sun::star::awt::XMouseListener,
+ ::com::sun::star::awt::XMouseMotionListener,
+ ::com::sun::star::awt::XPaintListener,
+ ::com::sun::star::awt::XTopWindowListener >
+{
+public:
+ /**
+ * Create a Multiplexer of XWindowEvents.
+ *
+ * @param rControl The control. All listeners think that this is the original
+ * broadcaster.
+ * @param rPeer The peer from which the original events are dispatched. Null is
+ * allowed.
+ */
+ MRCListenerMultiplexerHelper( const Reference< ::com::sun::star::awt::XWindow > & rControl, const Reference< ::com::sun::star::awt::XWindow > & rPeer );
+
+ /**
+ * Remove all listeners from the previous set peer and add the needed listeners to rPeer.
+ * @param rPeer The peer from which the original events are dispatched. Null is
+ * allowed.
+ */
+ void setPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer );
+
+ /**
+ * Remove all listeners and send a disposing message.
+ */
+ void disposeAndClear();
+
+ /**
+ * Add the specified listener to the source.
+ */
+ void advise( const Type& type, const Reference< XInterface > & listener);
+ /**
+ * Remove the specified listener from the source.
+ */
+ void unadvise(const Type& type, const Reference< XInterface > & listener);
+
+ // ::com::sun::star::lang::XEventListener
+ void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw();
+ // ::com::sun::star::awt::XFocusListener
+ void SAL_CALL focusGained(const ::com::sun::star::awt::FocusEvent& e) throw();
+ void SAL_CALL focusLost(const ::com::sun::star::awt::FocusEvent& e) throw();
+ // ::com::sun::star::awt::XWindowListener
+ void SAL_CALL windowResized(const ::com::sun::star::awt::WindowEvent& e) throw();
+ void SAL_CALL windowMoved(const ::com::sun::star::awt::WindowEvent& e) throw();
+ void SAL_CALL windowShown(const ::com::sun::star::lang::EventObject& e) throw();
+ void SAL_CALL windowHidden(const ::com::sun::star::lang::EventObject& e) throw();
+ // ::com::sun::star::awt::XKeyListener
+ void SAL_CALL keyPressed( const ::com::sun::star::awt::KeyEvent& e ) throw();
+ void SAL_CALL keyReleased( const ::com::sun::star::awt::KeyEvent& e ) throw();
+ // ::com::sun::star::awt::XMouseListener
+ void SAL_CALL mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw();
+ void SAL_CALL mouseReleased(const ::com::sun::star::awt::MouseEvent& e) throw();
+ void SAL_CALL mouseEntered(const ::com::sun::star::awt::MouseEvent& e) throw();
+ void SAL_CALL mouseExited(const ::com::sun::star::awt::MouseEvent& e) throw();
+ // ::com::sun::star::awt::XMouseMotionListener
+ void SAL_CALL mouseDragged(const ::com::sun::star::awt::MouseEvent& e) throw();
+ void SAL_CALL mouseMoved(const ::com::sun::star::awt::MouseEvent& e) throw();
+ // ::com::sun::star::awt::XPaintListener
+ void SAL_CALL windowPaint(const ::com::sun::star::awt::PaintEvent& e) throw();
+ // ::com::sun::star::awt::XTopWindowListener
+ void SAL_CALL windowOpened( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowClosing( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowClosed( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowMinimized( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowNormalized( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowActivated( const ::com::sun::star::lang::EventObject& e ) throw();
+ void SAL_CALL windowDeactivated( const ::com::sun::star::lang::EventObject& e ) throw();
+protected:
+ /**
+ * Remove the listener with the uik rUik from the peer rPeer.
+ * @param rPeer the peer from which the listener is removed.
+ * @param rUik the listener uik, which specify the type of the listener.
+ */
+ void adviseToPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer, const Type & type );
+ /**
+ * Add the listener with the uik rUik to the peer rPeer.
+ * @param rPeer the peer to which the listener is added.
+ * @param rUik the listener uik, which specify the type of the listener.
+ */
+ void unadviseFromPeer( const Reference< ::com::sun::star::awt::XWindow > & rPeer, const Type & type );
+private:
+ /** The source of the events. Normally this is the peer object.*/
+ Reference< ::com::sun::star::awt::XWindow > xPeer;
+ WeakReference< ::com::sun::star::awt::XControl > xControl;
+ ::cppu::OMultiTypeInterfaceContainerHelper aListenerHolder;
+
+
+ MRCListenerMultiplexerHelper( const MRCListenerMultiplexerHelper & );
+ MRCListenerMultiplexerHelper & operator = ( const MRCListenerMultiplexerHelper & );
+};
+
+#endif // _MRC_MULTIPLX_HXX
+
+
+
diff --git a/extensions/source/plugin/inc/plugin/plcom.hxx b/extensions/source/plugin/inc/plugin/plcom.hxx
new file mode 100644
index 000000000000..f0c4d54c02c3
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/plcom.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLUGIN_INC_PLCOM_HXX
+#define __PLUGIN_INC_PLCOM_HXX
+
+#include <tools/string.hxx>
+#include <list>
+
+class XPlugin_Impl;
+
+class PluginComm
+{
+protected:
+ int m_nRefCount;
+ ::rtl::OString m_aLibName;
+ std::list< String > m_aFilesToDelete;
+public:
+ PluginComm( const ::rtl::OString& rLibName, bool bReusable = true );
+ virtual ~PluginComm();
+
+ int getRefCount() { return m_nRefCount; }
+ void addRef() { m_nRefCount++; }
+ void decRef() { m_nRefCount--; if( ! m_nRefCount ) delete this; }
+
+ const ::rtl::OString& getLibName() { return m_aLibName; }
+ void setLibName( const ::rtl::OString& rName ) { m_aLibName = rName; }
+
+ void addFileToDelete( const String& filename )
+ { m_aFilesToDelete.push_back( filename ); }
+
+ virtual NPError NPP_Destroy( NPP instance, NPSavedData** save ) = 0;
+ virtual NPError NPP_DestroyStream( NPP instance, NPStream* stream,
+ NPError reason ) = 0;
+ virtual void* NPP_GetJavaClass() = 0;
+ virtual NPError NPP_Initialize() = 0;
+ virtual NPError NPP_New( NPMIMEType pluginType, NPP instance,
+ uint16 mode, int16 argc,
+ char* argn[], char* argv[],
+ NPSavedData *saved ) = 0;
+ virtual NPError NPP_NewStream( NPP instance, NPMIMEType type,
+ NPStream* stream,
+ NPBool seekable, uint16* stype ) = 0;
+ virtual void NPP_Print( NPP instance, NPPrint* platformPrint ) = 0;
+ virtual NPError NPP_SetWindow( NPP instance, NPWindow* window ) = 0;
+ virtual void NPP_Shutdown() = 0;
+ virtual void NPP_StreamAsFile( NPP instance, NPStream* stream,
+ const char* fname ) = 0;
+ virtual void NPP_URLNotify( NPP instance, const char* url,
+ NPReason reason, void* notifyData ) = 0;
+ virtual int32 NPP_Write( NPP instance, NPStream* stream, int32 offset,
+ int32 len, void* buffer ) = 0;
+ virtual int32 NPP_WriteReady( NPP instance, NPStream* stream ) = 0;
+ virtual NPError NPP_GetValue( NPP instance, NPPVariable variable, void* value ) = 0;
+ virtual NPError NPP_SetValue( NPP instance, NPNVariable variable,
+ void *value) = 0;
+
+ virtual NPError NPP_SetWindow( XPlugin_Impl* );
+ virtual NPError NPP_Destroy( XPlugin_Impl*, NPSavedData** save );
+};
+
+#endif
diff --git a/extensions/source/plugin/inc/plugin/plctrl.hxx b/extensions/source/plugin/inc/plugin/plctrl.hxx
new file mode 100644
index 000000000000..1980fa7b6725
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/plctrl.hxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLCTRL_HXX
+#define __PLCTRL_HXX
+
+#include <tools/debug.hxx>
+
+#include <cppuhelper/weak.hxx>
+#include <plugin/multiplx.hxx>
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyState.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/beans/XPropertyStateChangeListener.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/PropertyStateChangeEvent.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/awt/XVclContainerPeer.hpp>
+#include <com/sun/star/awt/XVclWindowPeer.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/awt/XUnoControlContainer.hpp>
+#include <com/sun/star/awt/XControlContainer.hpp>
+#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
+#include <com/sun/star/awt/XVclContainer.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+
+#include <cppuhelper/implbase4.hxx>
+
+#include <list>
+
+class SystemChildWindow;
+
+//==================================================================================================
+class PluginControl_Impl : public ::cppu::WeakAggImplHelper4<
+ ::com::sun::star::awt::XControl,
+ ::com::sun::star::awt::XWindow,
+ ::com::sun::star::awt::XFocusListener,
+ ::com::sun::star::awt::XView >
+{
+public:
+ // ::com::sun::star::awt::XControl
+ virtual void SAL_CALL setContext( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & xContext ) throw( ::com::sun::star::uno::RuntimeException )
+ { _xContext = xContext; }
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getContext() throw( ::com::sun::star::uno::RuntimeException )
+ { return _xContext; }
+
+ virtual sal_Bool SAL_CALL setModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > & Model ) throw( ::com::sun::star::uno::RuntimeException ) = 0;
+// { DBG_ERROR( "### setModel() illegal on plugincontrol!" ); return sal_False; }
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > SAL_CALL getModel() throw( ::com::sun::star::uno::RuntimeException ) = 0;
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XView > SAL_CALL getView() throw( ::com::sun::star::uno::RuntimeException )
+ { return (::com::sun::star::awt::XView*)this; }
+
+ virtual sal_Bool SAL_CALL isTransparent() throw( ::com::sun::star::uno::RuntimeException )
+ { return sal_False; }
+
+ virtual void SAL_CALL setDesignMode( sal_Bool bOn ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL isDesignMode() throw( ::com::sun::star::uno::RuntimeException )
+ { return _bInDesignMode; }
+
+ virtual void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > & xToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > & Parent) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > SAL_CALL getPeer() throw( ::com::sun::star::uno::RuntimeException )
+ { return _xPeer; }
+
+ // ::com::sun::star::awt::XWindow
+ virtual void SAL_CALL setVisible( sal_Bool bVisible ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setEnable( sal_Bool bEnable ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setFocus(void) throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setPosSize( sal_Int32 nX_, sal_Int32 nY_, sal_Int32 nWidth_, sal_Int32 nHeight_, sal_Int16 nFlags ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::awt::Rectangle SAL_CALL getPosSize(void) throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL addWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeFocusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFocusListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeKeyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XKeyListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeMouseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addMouseMotionListener( const Reference< ::com::sun::star::awt::XMouseMotionListener > & l ) throw( RuntimeException );
+ virtual void SAL_CALL removeMouseMotionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseMotionListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL addPaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removePaintListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XPaintListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::lang::XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject & rSource ) throw( ::com::sun::star::uno::RuntimeException );
+ // ::com::sun::star::awt::XFocusListener
+ virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent & rEvt ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent & rEvt ) throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::lang::XComponent
+ virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & l ) throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException );
+
+ // ::com::sun::star::awt::XView
+ virtual sal_Bool SAL_CALL setGraphics( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > & /*aDevice*/ ) throw( ::com::sun::star::uno::RuntimeException )
+ { return sal_False; }
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > SAL_CALL getGraphics(void) throw( ::com::sun::star::uno::RuntimeException )
+ { return ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > (); }
+
+ virtual ::com::sun::star::awt::Size SAL_CALL getSize(void) throw( ::com::sun::star::uno::RuntimeException )
+ { return ::com::sun::star::awt::Size(_nWidth, _nHeight); }
+
+ virtual void SAL_CALL draw( sal_Int32 x, sal_Int32 y ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL setZoom( float ZoomX, float ZoomY ) throw( ::com::sun::star::uno::RuntimeException );
+
+public:
+ PluginControl_Impl();
+ virtual ~PluginControl_Impl();
+
+ MRCListenerMultiplexerHelper* getMultiplexer();
+
+protected:
+ void releasePeer();
+
+protected:
+ ::std::list< Reference< ::com::sun::star::lang::XEventListener > > _aDisposeListeners;
+ MRCListenerMultiplexerHelper* _pMultiplexer;
+
+ Reference< XInterface > _xContext;
+
+ sal_Int32 _nX;
+ sal_Int32 _nY;
+ sal_Int32 _nWidth;
+ sal_Int32 _nHeight;
+ sal_Int16 _nFlags;
+
+ sal_Bool _bVisible;
+ sal_Bool _bInDesignMode;
+ sal_Bool _bEnable;
+
+ SystemChildWindow* _pSysChild;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > _xPeer;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > _xPeerWindow;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > _xParentWindow;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > _xParentPeer;
+};
+
+#endif
+
+
diff --git a/extensions/source/plugin/inc/plugin/unx/mediator.hxx b/extensions/source/plugin/inc/plugin/unx/mediator.hxx
new file mode 100644
index 000000000000..ea068410d13e
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/unx/mediator.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _MEDIATOR_HXX
+#define _MEDIATOR_HXX
+
+#include <string.h>
+#include <stdarg.h>
+#include <tools/string.hxx>
+#include <tools/link.hxx>
+#include <vos/pipe.hxx>
+#include <vos/mutex.hxx>
+#include <vos/conditn.hxx>
+#include <vos/thread.hxx>
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+#include <vector>
+
+struct MediatorMessage
+{
+ sal_uLong m_nID;
+ sal_uLong m_nBytes;
+ char* m_pBytes;
+ char* m_pRun;
+
+ MediatorMessage() : m_nID( 0 ), m_nBytes( 0 ),
+ m_pBytes( NULL ), m_pRun( NULL ) {}
+ MediatorMessage( sal_uLong nID, sal_uLong nBytes, char* pBytes ) :
+ m_nID( nID ),m_nBytes( nBytes ), m_pRun( NULL )
+ {
+ m_pBytes = new char[ m_nBytes ];
+ memcpy( m_pBytes, pBytes, (size_t)m_nBytes );
+ }
+
+ ~MediatorMessage()
+ {
+ if( m_pBytes )
+ delete [] m_pBytes;
+ }
+
+ void Set( sal_uLong nBytes, char* pBytes )
+ {
+ if( m_pBytes )
+ delete [] m_pBytes;
+ m_nBytes = nBytes;
+ m_pBytes = new char[ m_nBytes ];
+ memcpy( m_pBytes, pBytes, (size_t)m_nBytes );
+ }
+
+ sal_uLong ExtractULONG();
+ char* GetString();
+ sal_uInt32 GetUINT32();
+ void* GetBytes( sal_uLong& );
+ void* GetBytes() { sal_uLong nBytes; return GetBytes( nBytes ); }
+
+ void Rewind() { m_pRun = NULL; }
+};
+
+class MediatorListener;
+
+class Mediator
+{
+ friend class MediatorListener;
+protected:
+ int m_nSocket;
+
+ std::vector<MediatorMessage*> m_aMessageQueue;
+ vos::OMutex m_aQueueMutex;
+ vos::OMutex m_aSendMutex;
+ // only one thread can send a message at any given time
+ vos::OCondition m_aNewMessageCdtn;
+ MediatorListener* m_pListener;
+ // thread to fill the queue
+
+ sal_uLong m_nCurrentID;
+ // will be constantly increased with each message sent
+ bool m_bValid;
+
+ Link m_aConnectionLostHdl;
+ Link m_aNewMessageHdl;
+public:
+ Mediator( int nSocket );
+ ~Mediator();
+
+ // mark mediator as invalid. No more messages will be processed,
+ // SendMessage, WaitForMessage, TransactMessage will return immediatly
+ // with error
+ void invalidate() { m_bValid = false; }
+
+ sal_uLong SendMessage( sal_uLong nBytes, const char* pBytes, sal_uLong nMessageID = 0 );
+ sal_uLong SendMessage( const ByteString& rMessage, sal_uLong nMessageID = 0 )
+ {
+ return SendMessage( rMessage.Len(), rMessage.GetBuffer(), nMessageID );
+ }
+
+ sal_Bool WaitForMessage( sal_uLong nTimeOut = 5000 );
+ // timeout in ms
+ // TRUE: Message came in
+ // FALSE: timed out
+ // if timeout is set, WaitForMessage will wait even if there are messages
+ // in the queue
+
+ virtual MediatorMessage* WaitForAnswer( sal_uLong nMessageID );
+ // wait for an answer message ( ID >= 1 << 24 )
+ // the message will be removed from the queue and returned
+
+ MediatorMessage* TransactMessage( sal_uLong nBytes, char* pBytes );
+ // sends a message and waits for an answer
+
+ MediatorMessage* GetNextMessage( sal_Bool bWait = sal_False );
+
+
+ Link SetConnectionLostHdl( const Link& rLink )
+ {
+ Link aRet = m_aConnectionLostHdl;
+ m_aConnectionLostHdl = rLink;
+ return aRet;
+ }
+
+ Link SetNewMessageHdl( const Link& rLink )
+ {
+ Link aRet = m_aNewMessageHdl;
+ m_aNewMessageHdl = rLink;
+ return aRet;
+ }
+};
+
+class MediatorListener : public vos:: OThread
+{
+ friend class Mediator;
+ private:
+ Mediator* m_pMediator;
+ ::vos::OMutex m_aMutex;
+
+ MediatorListener( Mediator* );
+ ~MediatorListener();
+
+ virtual void run();
+ virtual void onTerminated();
+};
+
+inline void medDebug( int condition, const char* pFormat, ... )
+{
+#if OSL_DEBUG_LEVEL > 1
+ if( condition )
+ {
+ va_list ap;
+ va_start( ap, pFormat );
+ vfprintf( stderr, pFormat, ap );
+ va_end( ap );
+ }
+#else
+ (void)condition;
+ (void)pFormat;
+#endif
+}
+
+#endif // _MEDIATOR_HXX
diff --git a/extensions/source/plugin/inc/plugin/unx/plugcon.hxx b/extensions/source/plugin/inc/plugin/unx/plugcon.hxx
new file mode 100644
index 000000000000..d333d994e111
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/unx/plugcon.hxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _PLUGCON_HXX
+#define _PLUGCON_HXX
+
+#include <stdarg.h>
+#include <string.h>
+
+#include <list>
+#include <vector>
+#include <plugin/unx/mediator.hxx>
+
+#if defined SOLARIS
+#define USE_MOTIF
+#endif
+
+#define Window XLIB_Window
+#define Font XLIB_Font
+#define KeyCode XLIB_KeyCode
+#define Time XLIB_Time
+#define Cursor XLIB_Cursor
+#define Region XLIB_Region
+#define String XLIB_String
+#define Boolean XLIB_Boolean
+#define XPointer XLIB_XPointer
+#include <X11/Xlib.h>
+extern "C" {
+#include <X11/Intrinsic.h>
+}
+#include <X11/Shell.h>
+#include <X11/IntrinsicP.h> /* Intrinsics Definitions*/
+#include <X11/StringDefs.h> /* Standard Name-String definitions*/
+#if defined USE_MOTIF
+#include <Xm/DrawingA.h>
+#else
+# if defined DISABLE_XAW
+# include <X11/Composite.h>
+# else
+# include <X11/Xaw/Label.h>
+# endif
+#endif
+#include <X11/Xatom.h>
+#ifndef XP_UNIX
+# define XP_UNIX
+#endif
+#define MOZ_X11
+#include <stdio.h>
+#ifdef SYSTEM_MOZILLA
+#ifndef OJI
+# define OJI
+#endif
+#define MOZ_X11
+#endif
+
+//http://qa.openoffice.org/issues/show_bug.cgi?id=82545
+//https://bugzilla.mozilla.org/show_bug.cgi?id=241262
+#ifdef UNIX
+# ifndef _UINT32
+# if defined(__alpha) || defined(__LP64__)
+ typedef unsigned int uint32;
+# else /* __alpha */
+ typedef unsigned long uint32;
+# endif
+# define _UINT32
+# endif
+# ifndef _INT32
+# if defined(__alpha) || defined(__LP64__)
+ typedef int int32;
+# else /* __alpha */
+ typedef long int32;
+# endif
+# define _INT32
+# endif
+#endif
+
+#ifndef _NPAPI_H_
+extern "C" {
+#include <npsdk/npupp.h>
+}
+#include <npsdk/npapi.h>
+
+#if NP_VERSION_MINOR < 17
+// compatibility hack: compile with older NPN api header, but define
+// some later introduced constants
+// for gcc 3
+#define NP_ABI_MASK 0x10000000
+#define NPNVSupportsXEmbedBool ((NPNVariable)14)
+#define NPPVpluginNeedsXEmbed ((NPPVariable)14)
+#define NPNVToolkit ((int)(13 | NP_ABI_MASK))
+#define NPNVGtk12 1
+#define NPNVGtk2 2
+#endif
+#endif
+
+#ifdef ENABLE_GTK
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#else
+#define GtkWidget void
+#endif
+
+#undef Window
+#undef Font
+#undef KeyCode
+#undef Time
+#undef Cursor
+#undef String
+#undef Region
+#undef Boolean
+#undef XPointer
+
+class ConnectorInstance
+{
+public:
+ NPP instance;
+ NPWindow window;
+ NPSetWindowCallbackStruct ws_info;
+ char* pMimeType;
+ void* pShell;
+ void* pWidget;
+ void* pForm;
+
+ GtkWidget* pGtkWindow;
+ GtkWidget* pGtkWidget;
+
+ bool bShouldUseXEmbed;
+
+ int nArg;
+ char** argn;
+ char** argv;
+ char* pArgnBuf;
+ char* pArgvBuf;
+ NPSavedData aData;
+
+ ConnectorInstance( NPP inst, char* type,
+ int args, char* pargnbuf, sal_uLong nargnbytes,
+ char* pargvbuf, sal_uLong nargvbytes,
+ char* savedata, sal_uLong savebytes );
+ ~ConnectorInstance();
+};
+
+class PluginConnector : public Mediator
+{
+protected:
+ vos::OMutex m_aUserEventMutex;
+
+ static std::vector<PluginConnector*> allConnectors;
+
+ DECL_LINK( NewMessageHdl, Mediator* );
+ DECL_LINK( WorkOnNewMessageHdl, Mediator* );
+
+ std::vector<NPStream*> m_aNPWrapStreams;
+ std::vector<ConnectorInstance*> m_aInstances;
+
+ sal_uLong FillBuffer( char*&, const char*, sal_uLong, va_list );
+public:
+ PluginConnector( int nSocket );
+ ~PluginConnector();
+
+ virtual MediatorMessage* WaitForAnswer( sal_uLong nMessageID );
+ MediatorMessage* Transact( const char*, sal_uLong, ... );
+ MediatorMessage* Transact( sal_uInt32, ... );
+ void Respond( sal_uLong nID, char*, sal_uLong, ... );
+ sal_uLong Send( sal_uInt32, ... );
+
+ static const sal_uInt32 UnknownStreamID = 0xffffffff;
+ static const sal_uInt32 UnknownNPPID = 0xffffffff;
+
+ sal_uInt32 GetStreamID( NPStream* pStream );
+ sal_uInt32 GetNPPID( NPP );
+
+ std::vector<NPStream*>& getStreamList() { return m_aNPWrapStreams; }
+
+ NPError GetNPError( MediatorMessage* pMes )
+ {
+ NPError* pErr = (NPError*)pMes->GetBytes();
+ NPError aErr = *pErr;
+ delete [] pErr;
+ return aErr;
+ }
+
+ void CallWorkHandler()
+ {
+ LINK( this, PluginConnector, WorkOnNewMessageHdl ).
+ Call( (Mediator*)this );
+ }
+
+ ConnectorInstance* getInstance( NPP );
+ ConnectorInstance* getInstanceById( sal_uInt32 );
+};
+
+enum CommandAtoms
+{
+ eNPN_GetURL,
+ eNPN_GetURLNotify,
+ eNPN_DestroyStream,
+ eNPN_NewStream,
+ eNPN_PostURLNotify,
+ eNPN_PostURL,
+ eNPN_RequestRead,
+ eNPN_Status,
+ eNPN_Version,
+ eNPN_Write,
+ eNPN_UserAgent,
+
+ eNPP_DestroyStream,
+ eNPP_Destroy,
+ eNPP_DestroyPhase2,
+ eNPP_NewStream,
+ eNPP_New,
+ eNPP_SetWindow,
+ eNPP_StreamAsFile,
+ eNPP_URLNotify,
+ eNPP_WriteReady,
+ eNPP_Write,
+ eNPP_GetMIMEDescription,
+ eNPP_Initialize,
+ eNPP_Shutdown,
+
+ eMaxCommand
+};
+
+const char* GetCommandName( CommandAtoms );
+
+#define POST_STRING( x ) x ? x : const_cast<char*>(""), x ? strlen(x) : 1
+
+#endif // _PLUGCON_HXX
diff --git a/extensions/source/plugin/inc/plugin/unx/sysplug.hxx b/extensions/source/plugin/inc/plugin/unx/sysplug.hxx
new file mode 100644
index 000000000000..70b01d3fc69c
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/unx/sysplug.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef __PLUGIN_INC_UNXPLUG_HXX
+#define __PLUGIN_INC_UNXPLUG_HXX
+
+#include <unistd.h>
+
+#include <plugin/unx/plugcon.hxx>
+#include <plugin/plcom.hxx>
+#include <vcl/sysdata.hxx>
+
+class UnxPluginComm : public PluginComm, public PluginConnector
+{
+private:
+ static int nConnCounter;
+
+ pid_t m_nCommPID;
+public:
+ UnxPluginComm( const String& mimetype,
+ const String& library,
+ XLIB_Window aParent,
+ int nDescriptor1,
+ int nDescriptor2
+ );
+ virtual ~UnxPluginComm();
+
+ using PluginComm::NPP_Destroy;
+ virtual NPError NPP_Destroy( NPP instance, NPSavedData** save );
+ virtual NPError NPP_DestroyStream( NPP instance, NPStream* stream,
+ NPError reason );
+ virtual void* NPP_GetJavaClass();
+ virtual NPError NPP_Initialize();
+ virtual NPError NPP_New( NPMIMEType pluginType, NPP instance,
+ uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved );
+ virtual NPError NPP_NewStream( NPP instance, NPMIMEType type,
+ NPStream* stream,
+ NPBool seekable, uint16* stype );
+ virtual void NPP_Print( NPP instance, NPPrint* platformPrint );
+
+ using PluginComm::NPP_SetWindow;
+ virtual NPError NPP_SetWindow( NPP instance, NPWindow* window );
+ virtual void NPP_Shutdown();
+ virtual void NPP_StreamAsFile( NPP instance, NPStream* stream,
+ const char* fname );
+ virtual void NPP_URLNotify( NPP instance, const char* url, NPReason reason,
+ void* notifyData );
+ virtual int32 NPP_Write( NPP instance, NPStream* stream, int32 offset,
+ int32 len, void* buffer );
+ virtual int32 NPP_WriteReady( NPP instance, NPStream* stream );
+ virtual char* NPP_GetMIMEDescription();
+ virtual NPError NPP_GetValue( NPP instance, NPPVariable variable, void* value );
+ virtual NPError NPP_SetValue( NPP instance, NPNVariable variable,
+ void *value);
+
+ static bool getPluginappPath(rtl::OString * path);
+};
+
+#endif
diff --git a/extensions/source/plugin/inc/plugin/win/sysplug.hxx b/extensions/source/plugin/inc/plugin/win/sysplug.hxx
new file mode 100644
index 000000000000..9dd25d34dd06
--- /dev/null
+++ b/extensions/source/plugin/inc/plugin/win/sysplug.hxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef __PLUGIN_INC_WINPLUG_HXX
+#define __PLUGIN_INC_WINPLUG_HXX
+
+#pragma warning (push,1)
+#pragma warning (disable:4005)
+
+#include <tools/prewin.h>
+
+#include <windows.h>
+#include <tchar.h>
+#include <winbase.h>
+
+#include <tools/postwin.h>
+
+#pragma pack( push, 8 )
+#include <npsdk/npapi.h>
+#include <npsdk/npupp.h>
+#pragma pack( pop )
+
+#pragma warning (pop)
+
+#include <list>
+#include <map>
+#include <algorithm>
+
+#include <plugin/plcom.hxx>
+#include <vcl/threadex.hxx>
+
+//==================================================================================================
+class PluginComm_Impl :
+ public PluginComm,
+ public ::vcl::SolarThreadExecutor
+
+{
+ enum CallType {
+ eNPP_Destroy,
+ eNPP_DestroyStream,
+ eNPP_GetJavaClass,
+ eNPP_Initialize,
+ eNPP_New,
+ eNPP_NewStream,
+ eNPP_Print,
+ eNPP_SetWindow,
+ eNPP_Shutdown,
+ eNPP_StreamAsFile,
+ eNPP_URLNotify,
+ eNPP_Write,
+ eNPP_WriteReady,
+ eNPP_GetValue,
+ eNPP_SetValue,
+ eNP_Initialize
+ };
+
+ void* m_aArgs[ 8 ];
+ CallType m_eCall;
+
+ virtual long doIt();
+public:
+ PluginComm_Impl( const rtl::OUString& rMIME, const rtl::OUString& rName, HWND hWnd );
+ virtual ~PluginComm_Impl();
+
+public:
+ using PluginComm::NPP_Destroy;
+ virtual NPError NPP_Destroy( NPP instance, NPSavedData** save );
+ virtual NPError NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason );
+ virtual void * NPP_GetJavaClass();
+ virtual NPError NPP_Initialize();
+ virtual NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved );
+ virtual NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype );
+ virtual void NPP_Print( NPP instance, NPPrint* platformPrint );
+
+ using PluginComm::NPP_SetWindow;
+ virtual NPError NPP_SetWindow( NPP instance, NPWindow* window );
+ virtual void NPP_Shutdown();
+ virtual void NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname );
+ virtual void NPP_URLNotify( NPP instance, const char* url,
+ NPReason reason, void* notifyData );
+ virtual int32 NPP_Write( NPP instance, NPStream* stream, int32 offset,
+ int32 len, void* buffer );
+ virtual int32 NPP_WriteReady( NPP instance, NPStream* stream );
+ virtual NPError NPP_GetValue( NPP instance, NPPVariable variable, void *ret_alue );
+ virtual NPError NPP_SetValue( NPP instance, NPNVariable variable, void *ret_alue );
+
+private:
+ BOOL retrieveFunction( TCHAR* pName, void** ppFunc ) const;
+
+private:
+ HINSTANCE _plDLL;
+
+ NPPluginFuncs _NPPfuncs;
+};
+
+
+#endif
+
+
diff --git a/extensions/source/plugin/unx/makefile.mk b/extensions/source/plugin/unx/makefile.mk
new file mode 100644
index 000000000000..669aaa556e62
--- /dev/null
+++ b/extensions/source/plugin/unx/makefile.mk
@@ -0,0 +1,110 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=extensions
+TARGET=plunx
+TARGETTYPE=CUI
+ENABLE_EXCEPTIONS=TRUE
+
+.INCLUDE : ..$/util$/makefile.pmk
+
+.IF "$(GUIBASE)"=="aqua"
+dummy:
+ @echo "Nothing to build for GUIBASE aqua."
+
+.ELSE
+
+# --- Files --------------------------------------------------------
+
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/plugin
+.IF "$(SOLAR_JAVA)" != ""
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/java
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/nspr
+CDEFS+=-DOJI
+.ENDIF
+
+.IF "$(WITH_MOZILLA)" != "NO"
+
+.IF "$(DISABLE_XAW)" == "TRUE"
+CDEFS+=-DDISABLE_XAW
+.ENDIF
+
+SLOFILES=\
+ $(SLO)$/nppapi.obj \
+ $(SLO)$/sysplug.obj \
+ $(SLO)$/mediator.obj \
+ $(SLO)$/plugcon.obj \
+ $(SLO)$/unxmgr.obj
+
+OBJFILES=\
+ $(OBJ)$/npwrap.obj \
+ $(OBJ)$/npnapi.obj \
+ $(OBJ)$/mediator.obj \
+ $(OBJ)$/plugcon.obj
+
+APP1TARGET=pluginapp.bin
+APP1OBJS=$(OBJFILES)
+APP1STDLIBS=\
+ $(VOSLIB) \
+ $(SALLIB)
+.IF "$(OS)"=="SOLARIS" || "$(OS)"=="SCO" || "$(OS)"=="HPUX"
+APP1STDLIBS+=-lXm -lXt $(X11LINK_DYNAMIC) -ldl
+.ELSE
+.IF "$(DISABLE_XAW)" != "TRUE"
+APP1STDLIBS+=-lXaw
+.ENDIF
+.IF "$(OS)"=="FREEBSD" || "$(OS)"=="NETBSD"
+APP1STDLIBS+= -lXt -lXext -lX11
+.ELSE
+APP1STDLIBS+= -lXt $(X11LINK_DYNAMIC) -ldl
+.ENDIF
+.ENDIF
+
+.IF "$(ENABLE_GTK)" == "TRUE"
+# libs for gtk plugin
+APP1STDLIBS+=$(PKGCONFIG_LIBS:s/ -lpangoxft-1.0//)
+# hack for faked SO environment
+.IF "$(PKGCONFIG_ROOT)"!=""
+.IF "$(OS)" == "SOLARIS"
+# don't ask, it's ugly
+DIRECT :=-z nodefs $(DIRECT)
+.ENDIF
+.ENDIF # "$(PKGCONFIG_ROOT)"!=""
+.ENDIF
+
+
+APP1DEF= $(MISC)$/$(TARGET).def
+
+.ENDIF # $(WITH_MOZILLA) != "NO"
+
+.ENDIF # $(GUIBASE)==aqua
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/extensions/source/plugin/unx/mediator.cxx b/extensions/source/plugin/unx/mediator.cxx
new file mode 100644
index 000000000000..4d8fd64a8407
--- /dev/null
+++ b/extensions/source/plugin/unx/mediator.cxx
@@ -0,0 +1,309 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <errno.h>
+#include <unistd.h>
+
+#include <plugin/unx/mediator.hxx>
+#include <vcl/svapp.hxx>
+
+#define MEDIATOR_MAGIC 0xf7a8d2f4
+
+Mediator::Mediator( int nSocket ) :
+ m_nSocket( nSocket ),
+ m_pListener( NULL ),
+ m_nCurrentID( 1 ),
+ m_bValid( true )
+{
+ m_pListener = new MediatorListener( this );
+ m_pListener->create();
+}
+
+Mediator::~Mediator()
+{
+ if( m_pListener )
+ {
+ {
+ ::vos::OGuard aGuard( m_pListener->m_aMutex );
+ m_pListener->m_pMediator = NULL;
+ }
+ m_pListener = NULL;
+ if( m_bValid )
+ {
+ sal_uLong aHeader[3];
+ aHeader[0] = 0;
+ aHeader[1] = 0;
+ aHeader[2] = MEDIATOR_MAGIC;
+ write( m_nSocket, aHeader, sizeof( aHeader ) );
+ }
+ // kick the thread out of its run method; it deletes itself
+ close( m_nSocket );
+ }
+ else
+ close( m_nSocket );
+ for( std::vector< MediatorMessage* >::iterator it = m_aMessageQueue.begin();
+ it != m_aMessageQueue.end(); ++it )
+ {
+ delete *it;
+ }
+}
+
+
+sal_uLong Mediator::SendMessage( sal_uLong nBytes, const char* pBytes, sal_uLong nMessageID )
+{
+ if( ! m_pListener )
+ return 0;
+
+ vos::OGuard aGuard( m_aSendMutex );
+ if( ! nMessageID )
+ nMessageID = m_nCurrentID;
+
+ m_nCurrentID++;
+ if( m_nCurrentID >= 1 << 24 ) // protection against overflow
+ m_nCurrentID = 1;
+
+ if( ! m_bValid )
+ return nMessageID;
+
+ sal_uLong* pBuffer = new sal_uLong[ (nBytes/sizeof(sal_uLong)) + 4 ];
+ pBuffer[ 0 ] = nMessageID;
+ pBuffer[ 1 ] = nBytes;
+ pBuffer[ 2 ] = MEDIATOR_MAGIC;
+ memcpy( &pBuffer[3], pBytes, (size_t)nBytes );
+ write( m_nSocket, pBuffer, nBytes + 3*sizeof( sal_uLong ) );
+ delete [] pBuffer;
+
+ return nMessageID;
+}
+
+sal_Bool Mediator::WaitForMessage( sal_uLong nTimeOut )
+{
+ if( ! m_pListener )
+ return sal_False;
+
+ size_t nItems = m_aMessageQueue.size();
+
+ if( ! nTimeOut && nItems > 0 )
+ return sal_True;
+
+ TimeValue aValue;
+ aValue.Seconds = nTimeOut/1000;
+ aValue.Nanosec = ( nTimeOut % 1000 ) * 1000;
+
+ while( m_aMessageQueue.size() == nItems )
+ {
+ m_aNewMessageCdtn.wait( & aValue );
+ m_aNewMessageCdtn.reset();
+ if( nTimeOut && m_aMessageQueue.size() == nItems )
+ return sal_False;
+ }
+ return sal_True;
+}
+
+MediatorMessage* Mediator::WaitForAnswer( sal_uLong nMessageID )
+{
+ nMessageID &= 0x00ffffff;
+ while( m_pListener )
+ {
+ {
+ vos::OGuard aGuard( m_aQueueMutex );
+ for( size_t i = 0; i < m_aMessageQueue.size(); i++ )
+ {
+ MediatorMessage* pMessage = m_aMessageQueue[ i ];
+ sal_uLong nID = pMessage->m_nID;
+ if( ( nID & 0xff000000 ) &&
+ ( ( nID & 0x00ffffff ) == nMessageID ) )
+ {
+ m_aMessageQueue.erase( m_aMessageQueue.begin() + i );
+ return pMessage;
+ }
+ }
+ }
+ WaitForMessage( 10 );
+ }
+ return NULL;
+}
+
+MediatorMessage* Mediator::GetNextMessage( sal_Bool bWait )
+{
+ while( m_pListener )
+ {
+ {
+ // guard must be after WaitForMessage, else the listener
+ // cannot insert a new one -> deadlock
+ vos::OGuard aGuard( m_aQueueMutex );
+ for( size_t i = 0; i < m_aMessageQueue.size(); i++ )
+ {
+ MediatorMessage* pMessage = m_aMessageQueue[ i ];
+ if( ! ( pMessage->m_nID & 0xff000000 ) )
+ {
+ m_aMessageQueue.erase( m_aMessageQueue.begin() + i );
+ return pMessage;
+ }
+ }
+ if( ! bWait )
+ return NULL;
+ }
+ WaitForMessage();
+ }
+ return NULL;
+}
+
+MediatorMessage* Mediator::TransactMessage( sal_uLong nBytes, char* pBytes )
+{
+ sal_uLong nID = SendMessage( nBytes, pBytes );
+ return WaitForAnswer( nID );
+}
+
+MediatorListener::MediatorListener( Mediator* pMediator ) :
+ m_pMediator( pMediator )
+{
+}
+
+MediatorListener::~MediatorListener()
+{
+}
+
+void MediatorListener::run()
+{
+ bool bRun = true;
+ while( schedule() && m_pMediator && bRun )
+ {
+ sal_uLong nHeader[ 3 ];
+ int nBytes;
+
+ if( m_pMediator && ( nBytes = read( m_pMediator->m_nSocket, nHeader, sizeof( nHeader ) ) ) == sizeof( nHeader ) && nHeader[2] == MEDIATOR_MAGIC)
+ {
+ if( nHeader[ 0 ] == 0 && nHeader[ 1 ] == 0 )
+ return;
+ char* pBuffer = new char[ nHeader[ 1 ] ];
+ if( m_pMediator && (sal_uLong)read( m_pMediator->m_nSocket, pBuffer, nHeader[ 1 ] ) == nHeader[ 1 ] )
+ {
+ ::vos::OGuard aMyGuard( m_aMutex );
+ {
+ vos::OGuard
+ aGuard( m_pMediator->m_aQueueMutex );
+ MediatorMessage* pMessage =
+ new MediatorMessage( nHeader[ 0 ], nHeader[ 1 ], pBuffer );
+ m_pMediator->m_aMessageQueue.push_back( pMessage );
+ }
+ m_pMediator->m_aNewMessageCdtn.set();
+ m_pMediator->m_aNewMessageHdl.Call( m_pMediator );
+ }
+ else
+ {
+ medDebug( 1, "got incomplete MediatorMessage: { %d, %d, %*s }\n",
+ nHeader[0], nHeader[1], nHeader[1], pBuffer );
+ bRun = false;
+ }
+ delete [] pBuffer;
+ }
+ else
+ {
+ medDebug( 1, "got incomplete message header of %d bytes ( nHeader = [ %u, %u ] ), errno is %d\n",
+ nBytes, nHeader[ 0 ], nHeader[ 1 ], (int)errno );
+ bRun = false;
+ }
+ }
+}
+
+void MediatorListener::onTerminated()
+{
+ if( m_pMediator )
+ {
+ m_pMediator->m_aConnectionLostHdl.Call( m_pMediator );
+ m_pMediator->m_pListener = NULL;
+ }
+ delete this;
+}
+
+sal_uLong MediatorMessage::ExtractULONG()
+{
+ if( ! m_pRun )
+ m_pRun = m_pBytes;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::ExtractULONG\n" );
+ sal_uLong nCount;
+ memcpy( &nCount, m_pRun, sizeof( sal_uLong ) );
+ m_pRun += sizeof( sal_uLong );
+ return nCount;
+}
+
+void* MediatorMessage::GetBytes( sal_uLong& rBytes )
+{
+ if( ! m_pRun )
+ m_pRun = m_pBytes;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetBytes\n" );
+ sal_uLong nBytes = ExtractULONG();
+
+ if( nBytes == 0 )
+ return NULL;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetBytes\n" );
+ char* pBuffer = new char[ nBytes ];
+ memcpy( pBuffer, m_pRun, nBytes );
+ m_pRun += nBytes;
+ rBytes = nBytes;
+ return pBuffer;
+}
+
+char* MediatorMessage::GetString()
+{
+ if( ! m_pRun )
+ m_pRun = m_pBytes;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetString\n" );
+ sal_uLong nBytes = ExtractULONG();
+
+ if( nBytes == 0 )
+ return NULL;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetString\n" );
+ char* pBuffer = new char[ nBytes+1 ];
+ memcpy( pBuffer, m_pRun, nBytes );
+ pBuffer[ nBytes ] = 0;
+ m_pRun += nBytes;
+ return pBuffer;
+}
+
+sal_uInt32 MediatorMessage::GetUINT32()
+{
+ if( ! m_pRun )
+ m_pRun = m_pBytes;
+
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetUINT32\n" );
+ sal_uLong nBytes = ExtractULONG();
+ medDebug( nBytes != sizeof( sal_uInt32 ), "No sal_uInt32 in MediatorMessage::GetUINT32\n" );
+ medDebug( (sal_uLong)(m_pRun - m_pBytes) >= m_nBytes, "Overflow in MediatorMessage::GetUINT32\n" );
+ sal_uInt32 nRet;
+ memcpy( &nRet, m_pRun, sizeof( nRet ) );
+ m_pRun += sizeof( sal_uInt32 );
+ return nRet;
+}
diff --git a/extensions/source/plugin/unx/npnapi.cxx b/extensions/source/plugin/unx/npnapi.cxx
new file mode 100644
index 000000000000..364ff05606bc
--- /dev/null
+++ b/extensions/source/plugin/unx/npnapi.cxx
@@ -0,0 +1,917 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <plugin/unx/plugcon.hxx>
+
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include <osl/module.h>
+
+extern PluginConnector* pConnector;
+extern XtAppContext app_context;
+extern int wakeup_fd[];
+extern Widget topLevel, topBox;
+extern Display* pAppDisplay;
+extern Display* pXtAppDisplay;
+extern int nAppArguments;
+extern char** pAppArguments;
+
+void* CreateNewShell( void**, XLIB_Window );
+
+// begin Netscape plugin api calls
+extern "C" {
+
+static void* l_NPN_MemAlloc( uint32 nBytes )
+{
+ void* pMem = new char[nBytes];
+ return pMem;
+}
+
+static void l_NPN_MemFree( void* pMem )
+{
+ delete [] (char*)pMem;
+}
+
+static uint32 l_NPN_MemFlush( uint32 /*nSize*/ )
+{
+ return 0;
+}
+
+static NPError l_NPN_DestroyStream( NPP instance, NPStream* stream, NPError reason )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ sal_uInt32 nFileID = pConnector->GetStreamID( stream );
+ MediatorMessage* pMes=
+ pConnector->
+ Transact( eNPN_DestroyStream,
+ &nInstance, sizeof( nInstance ),
+ &nFileID, sizeof( nFileID ),
+ POST_STRING( stream->url ),
+ &reason, sizeof( reason ),
+ NULL );
+
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ for( std::vector< NPStream* >::iterator it = pConnector->getStreamList().begin();
+ it != pConnector->getStreamList().end(); ++it )
+ {
+ if( *it == stream )
+ {
+ pConnector->getStreamList().erase( it );
+ break;
+ }
+ }
+ delete [] stream->url;
+ delete stream;
+ // returns NPError
+ NPError aRet = pConnector->GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+#ifdef OJI
+static JRIEnv* l_NPN_GetJavaEnv()
+{
+ // no java in this program
+ medDebug( 1, "SNI: NPN_GetJavaEnv\n" );
+ return NULL;
+}
+
+static jref l_NPN_GetJavaPeer( NPP /*instance*/ )
+{
+ medDebug( 1, "SNI: NPN_GetJavaPeer\n" );
+ return NULL;
+}
+#endif
+
+static NPError l_NPN_GetURL( NPP instance, const char* url, const char* window )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes=
+ pConnector->
+ Transact( eNPN_GetURL,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING(url),
+ POST_STRING(window),
+ NULL );
+ medDebug( !pMes, "geturl: message unaswered\n" );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ // returns NPError
+ NPError aRet = pConnector->GetNPError( pMes );
+ medDebug( aRet, "geturl returns %d\n", (int)aRet );
+ delete pMes;
+ return aRet;
+}
+
+static NPError l_NPN_GetURLNotify( NPP instance, const char* url, const char* target,
+ void* notifyData )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes=
+ pConnector->
+ Transact( eNPN_GetURLNotify,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING(url),
+ POST_STRING(target),
+ &notifyData, sizeof( void* ), // transmit the actual pointer
+ // since it is a pointer to private data fed back
+ // by NPP_URLNotify; this can be thought of as an ID
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ // returns NPError
+ NPError aRet = pConnector->GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+static NPError l_NPN_NewStream( NPP instance, NPMIMEType type, const char* target,
+ NPStream** stream )
+ // stream is a return value
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes=
+ pConnector->
+ Transact( eNPN_NewStream,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING(type),
+ POST_STRING(target),
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ // returns a new NPStream and an error
+ NPError aRet = pConnector->GetNPError( pMes );
+ if( ! aRet )
+ {
+ NPStream* pStream = new NPStream;
+ pStream->url = pMes->GetString();
+ pStream->end = pMes->GetUINT32();
+ pStream->lastmodified = pMes->GetUINT32();
+ pStream->ndata = pStream->pdata = pStream->notifyData = NULL;
+
+ pConnector->getStreamList().push_back( pStream );
+ *stream = pStream;
+ }
+
+ delete pMes;
+ return aRet;
+}
+
+static NPError l_NPN_PostURLNotify( NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void* notifyData )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_PostURLNotify,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING( url ),
+ POST_STRING( target ),
+ &len, sizeof( len ),
+ buf, len,
+ &file, sizeof( NPBool ),
+ &notifyData, sizeof( void* ), // send the real pointer
+ NULL );
+
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ NPError aRet = pConnector->GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+static NPError l_NPN_PostURL( NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_PostURL,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING( url ),
+ POST_STRING( window ),
+ &len, sizeof( len ),
+ buf, len,
+ &file, sizeof( NPBool ),
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ NPError aRet = pConnector->GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+static NPError l_NPN_RequestRead( NPStream* stream, NPByteRange* rangeList )
+{
+ medDebug( 1, "pluginapp: NPN_RequestRead\n" );
+
+ NPByteRange* pRange = rangeList;
+ sal_uInt32 nRanges = 0;
+ while( pRange )
+ {
+ nRanges++;
+ pRange = pRange->next;
+ }
+
+ sal_uInt32* pArray = new sal_uInt32[ 2 * nRanges ];
+ pRange = rangeList;
+ sal_uInt32 n = 0;
+ while( pRange )
+ {
+ pArray[ 2*n ] = (sal_uInt32)pRange->offset;
+ pArray[ 2*n + 1] = (sal_uInt32)pRange->length;
+ n++;
+ pRange = pRange->next;
+ }
+ sal_uInt32 nFileID = pConnector->GetStreamID( stream );
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_RequestRead,
+ &nFileID, sizeof( nFileID ),
+ &nRanges, sizeof( nRanges ),
+ pArray, sizeof( sal_uInt32 ) * 2 * nRanges,
+ NULL );
+
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ NPError aRet = pConnector->GetNPError( pMes );
+ delete [] pArray;
+ delete pMes;
+ return aRet;
+}
+
+static void l_NPN_Status( NPP instance, const char* message )
+{
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return;
+
+ pConnector->Send( eNPN_Status,
+ &nInstance, sizeof( nInstance ),
+ POST_STRING( message ),
+ NULL );
+}
+
+static const char* l_NPN_UserAgent( NPP instance )
+{
+ static char* pAgent = NULL;
+
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ {
+ if( instance )
+ return "Mozilla 3.0";
+ else // e.g. flashplayer calls NPN_UserAgent with NULL
+ nInstance = 0;
+ }
+
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_UserAgent,
+ &nInstance, sizeof( nInstance ),
+ NULL );
+
+ if( ! pMes )
+ return pAgent;
+
+ if( pAgent )
+ delete [] pAgent;
+ pAgent = pMes->GetString();
+
+ delete pMes;
+
+ medDebug( 1, "NPN_UserAgent returns %s\n", pAgent );
+
+ return pAgent;
+}
+
+#if 0
+static void l_NPN_Version( int* major, int* minor, int* net_major, int* net_minor )
+{
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_Version,
+ NULL );
+
+ if( ! pMes )
+ return;
+
+ *major = pMes->GetUINT32();
+ *minor = pMes->GetUINT32();
+ *net_major = pMes->GetUINT32();
+ *net_minor = pMes->GetUINT32();
+
+ medDebug( 1, "pluginapp: NPN_Version: results %d %d, %d %d\n", *major, *minor, *net_major, *net_minor );
+
+ delete pMes;
+}
+#endif
+
+static int32 l_NPN_Write( NPP instance, NPStream* stream, int32 len, void* buffer )
+{
+ sal_uInt32 nFileID = pConnector->GetStreamID( stream );
+ if( nFileID == PluginConnector::UnknownStreamID )
+ return NPERR_GENERIC_ERROR;
+ sal_uInt32 nInstance = pConnector->GetNPPID( instance );
+ if( nInstance == PluginConnector::UnknownNPPID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes = pConnector->
+ Transact( eNPN_Write,
+ &nInstance, sizeof( nInstance ),
+ &nFileID, sizeof( nFileID ),
+ &len, sizeof( len ),
+ buffer, len,
+ NULL );
+
+ if( ! pMes )
+ return 0;
+
+ sal_Int32 nRet = pMes->GetUINT32();
+ return nRet;
+}
+
+static void l_NPN_ReloadPlugins( NPBool /*reloadPages*/ )
+{
+ medDebug( 1, "NPN_ReloadPlugins: SNI\n" );
+}
+
+static NPError l_NPN_GetValue( NPP, NPNVariable variable, void* value )
+{
+ /*
+ * We want to handle values injected into a NPNVariable which aren't in
+ * the old enum we build against, but that we know are in the new enum
+ * we want to support
+ */
+ switch( (int)variable )
+ {
+ case NPNVxDisplay:
+ *((Display**)value) = pXtAppDisplay;
+ medDebug( 1, "Display requested\n" );
+ break;
+ case NPNVxtAppContext:
+ *((XtAppContext*)value) = app_context;
+ medDebug( 1, "AppContext requested\n" );
+ break;
+ case NPNVjavascriptEnabledBool:
+ // no javascript
+ *(NPBool*)value = false;
+ medDebug( 1, "javascript enabled requested\n" );
+ break;
+ case NPNVasdEnabledBool:
+ // no SmartUpdate
+ *(NPBool*)value = false;
+ medDebug( 1, "smart update enabled requested\n" );
+ break;
+ case NPNVisOfflineBool:
+ // no offline browsing
+ *(NPBool*)value = false;
+ medDebug( 1, "offline browsing requested\n" );
+ break;
+ case NPNVSupportsXEmbedBool:
+ // asking xembed
+ *(int*)value = true;
+ medDebug( 1, "xembed requested\n" );
+ break;
+ case NPNVToolkit:
+# ifdef ENABLE_GTK
+ *(int*)value = NPNVGtk2;
+# else
+ *(int*)value = 0;
+# endif
+ medDebug( 1, "toolkit requested\n" );
+ break;
+ default:
+ medDebug( 1, "unknown NPNVariable %x requested\n", variable );
+ return NPERR_INVALID_PARAM;
+ }
+ return NPERR_NO_ERROR;
+}
+
+static NPError l_NPN_SetValue(NPP /*instance*/, NPPVariable variable, void *value)
+{
+ medDebug( 1, "NPN_SetValue %d=%p\n", variable, value );
+ return 0;
+}
+
+static void l_NPN_InvalidateRect(NPP /*instance*/, NPRect* /*invalidRect*/)
+{
+ medDebug( 1, "NPN_InvalidateRect\n" );
+}
+
+static void l_NPN_InvalidateRegion(NPP /*instance*/, NPRegion /*invalidRegion*/)
+{
+ medDebug( 1, "NPN_InvalidateRegion\n" );
+}
+
+static void l_NPN_ForceRedraw(NPP /*instance*/)
+{
+ medDebug( 1, "NPN_ForceRedraw\n" );
+}
+
+}
+
+static NPNetscapeFuncs aNetscapeFuncs =
+{
+ sizeof(aNetscapeFuncs),
+ (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
+ l_NPN_GetURL,
+ l_NPN_PostURL,
+ l_NPN_RequestRead,
+ l_NPN_NewStream,
+ l_NPN_Write,
+ l_NPN_DestroyStream,
+ l_NPN_Status,
+ l_NPN_UserAgent,
+ l_NPN_MemAlloc,
+ l_NPN_MemFree,
+ l_NPN_MemFlush,
+ l_NPN_ReloadPlugins,
+# ifdef OJI
+ l_NPN_GetJavaEnv,
+ l_NPN_GetJavaPeer,
+# else
+ NULL,
+ NULL,
+# endif
+ l_NPN_GetURLNotify,
+ l_NPN_PostURLNotify,
+ l_NPN_GetValue,
+ l_NPN_SetValue,
+ l_NPN_InvalidateRect,
+ l_NPN_InvalidateRegion,
+ l_NPN_ForceRedraw
+};
+
+static NPPluginFuncs aPluginFuncs =
+{
+ sizeof(aPluginFuncs),
+ (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+oslModule pPluginLib = NULL;
+char*(*pNPP_GetMIMEDescription)() = NULL;
+NPError (*pNP_Initialize)(NPNetscapeFuncs*,NPPluginFuncs*) = NULL;
+NPError (*pNP_Shutdown)() = NULL;
+
+std::vector< PluginConnector* > PluginConnector::allConnectors;
+
+PluginConnector::PluginConnector( int nSocket ) :
+ Mediator( nSocket )
+{
+ SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
+}
+
+PluginConnector::~PluginConnector()
+{
+}
+
+IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
+{
+ MediatorMessage* pMessage;
+ CommandAtoms nCommand;
+ while( (pMessage = GetNextMessage( sal_False )) )
+ {
+ nCommand = (CommandAtoms)pMessage->GetUINT32();
+ medDebug( 1, "pluginapp: %s\n", GetCommandName( nCommand ) );
+ switch( nCommand )
+ {
+ case eNPP_DestroyStream:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ NPError aReason = GetNPError( pMessage );
+ m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
+
+ aReason = aPluginFuncs.destroystream( instance, pStream, aReason );
+ Respond( pMessage->m_nID,
+ (char*)&aReason, sizeof( aReason ),
+ NULL );
+
+ delete [] pStream->url;
+ delete pStream;
+ }
+ break;
+ case eNPP_Destroy:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ ConnectorInstance* pInst= m_aInstances[ nInstance ];
+
+ // some plugin rely on old netscapes behaviour
+ // to first destroy the widget and then destroy
+ // the instance, so mimic that behaviour here
+ if( pInst->pShell )
+ XtDestroyWidget( (Widget)pInst->pShell );
+
+ pInst->pWidget = pInst->pShell = NULL;
+
+ // the other side will call eNPP_DestroyPhase2 after this
+ NPError aReason = NPERR_NO_ERROR;
+ Respond( pMessage->m_nID, (char*)&aReason, sizeof( aReason ), NULL );
+ }
+ break;
+ case eNPP_DestroyPhase2:
+ {
+ // now really destroy the instance
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ ConnectorInstance* pInst= m_aInstances[ nInstance ];
+ NPP instance = pInst->instance;
+ NPSavedData* pSave = NULL;
+
+ NPError aRet = aPluginFuncs.destroy( instance, &pSave );
+ if( pSave )
+ {
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ pSave->buf, pSave->len,
+ NULL );
+ delete [] (char*)pSave->buf;
+ }
+ else
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ "0000", 4,
+ NULL );
+
+ #ifdef ENABLE_GTK
+ if( pInst->pGtkWindow )
+ g_object_unref( G_OBJECT(pInst->pGtkWindow) );
+ if( pInst->pGtkWidget )
+ g_object_unref( G_OBJECT(pInst->pGtkWidget) );
+ #endif
+
+ m_aInstances.erase( m_aInstances.begin() + nInstance );
+ delete pInst;
+ delete instance;
+ medDebug( 1, "destroyed instance (returning %d)\n", aRet );
+ }
+ break;
+ case eNPP_NewStream:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pType = pMessage->GetString();
+ NPStream* pStream = new NPStream;
+ pStream->url = pMessage->GetString();
+ pStream->end = pMessage->GetUINT32();
+ pStream->lastmodified = pMessage->GetUINT32();
+ pStream->pdata = pStream->ndata = pStream->notifyData = NULL;
+ NPBool* pSeekable = (NPBool*)pMessage->GetBytes();
+ m_aNPWrapStreams.push_back( pStream );
+ uint16 nStype = NP_ASFILE;
+ NPError aRet = aPluginFuncs.newstream( instance, pType, pStream,
+ *pSeekable, &nStype );
+ medDebug( 1, "pluginapp: NPP_NewStream( %p, %s, %p, %s, %p ) returns %d\n"
+ "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
+ instance, pType, pStream, *pSeekable ? "seekable" : "not seekable", &nStype, (int)aRet,
+ pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ &nStype, sizeof( nStype ),
+ NULL );
+ delete [] pType;
+ delete [] pSeekable;
+ }
+ break;
+ case eNPP_New:
+ {
+ char* pType = pMessage->GetString();
+ uint16* pMode = (uint16*)pMessage->GetBytes();
+ int16* pArgc = (int16*)pMessage->GetBytes();
+ NPP instance = new NPP_t;
+ instance->pdata = instance->ndata = NULL;
+ sal_uLong nArgnBytes, nArgvBytes;
+ char* pArgn = (char*)pMessage->GetBytes( nArgnBytes );
+ char* pArgv = (char*)pMessage->GetBytes( nArgvBytes );
+ sal_uLong nSaveBytes;
+ char* pSavedData = (char*)pMessage->GetBytes( nSaveBytes );
+ ConnectorInstance* pInst =
+ new ConnectorInstance( instance, pType,
+ *pArgc,
+ pArgn, nArgnBytes,
+ pArgv, nArgvBytes,
+ pSavedData, nSaveBytes );
+ m_aInstances.push_back( pInst );
+ NPError aRet;
+ aRet = aPluginFuncs.newp( pInst->pMimeType, instance, *pMode, *pArgc,
+ pInst->nArg ? pInst->argn : NULL,
+ pInst->nArg ? pInst->argv : NULL,
+ ( nSaveBytes == 4 && *(sal_uInt32*)pSavedData == 0 ) ?
+ &(pInst->aData) : NULL );
+ medDebug( 1, "pluginapp: NPP_New( %s, %p, %d, %d, %p, %p, %p ) returns %d\n",
+ pInst->pMimeType,
+ instance, *pMode, pInst->nArg, pInst->argn, pInst->argv, &pInst->aData,
+ (int) aRet );
+#if OSL_DEBUG_LEVEL > 1
+ for( int i = 0; i < pInst->nArg; i++ )
+ medDebug( 1, " \"%s\"=\"%s\"\n", pInst->argn[i], pInst->argv[i] );
+#endif
+
+ #ifdef ENABLE_GTK
+ // check if XEMBED is to be used
+ // ask for Bool. there seems to be no clear definition whether the
+ // return value should be an int or unsigned char
+ // int can hold both and will be nonzero in case of "true"
+ if( aPluginFuncs.getvalue )
+ {
+ int bNeedsXEmbed = 0;
+ NPError error = aPluginFuncs.getvalue( instance, NPPVpluginNeedsXEmbed, (void *)&bNeedsXEmbed );
+ if( error == NPERR_NO_ERROR )
+ pInst->bShouldUseXEmbed = (bNeedsXEmbed != 0);
+ medDebug( 1, "should use xembed = %s\n", pInst->bShouldUseXEmbed ? "true" : "false" );
+ }
+ #endif
+
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ NULL );
+ delete [] pMode;
+ delete [] pArgc;
+ delete [] pType;
+ }
+ break;
+ case eNPP_SetWindow:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ ConnectorInstance* pInst= m_aInstances[ nInstance ];
+ NPWindow* pWindow = (NPWindow*)pMessage->GetBytes();
+
+ if( pWindow->width < 1 )
+ pWindow->width = 1;
+ if( pWindow->height < 1 )
+ pWindow->height = 1;
+
+ #ifdef ENABLE_GTK
+ if( pInst->bShouldUseXEmbed )
+ {
+ if( ! pInst->pGtkWidget )
+ {
+ medDebug( 1, "creating gtk plug and socket\n" );
+
+ pInst->pGtkWindow = gtk_plug_new((GdkNativeWindow)reinterpret_cast<sal_uIntPtr>(pWindow->window));
+ gtk_widget_show( pInst->pGtkWindow );
+ pInst->pGtkWidget = gtk_socket_new();
+ gtk_widget_show( pInst->pGtkWidget );
+ gtk_container_add( GTK_CONTAINER(pInst->pGtkWindow), pInst->pGtkWidget );
+ gtk_widget_show_all( pInst->pGtkWindow );
+ pInst->window.window = (void *)gtk_socket_get_id( GTK_SOCKET(pInst->pGtkWidget ) );
+
+ XSync( pAppDisplay, False );
+
+ XMapWindow( pAppDisplay, GDK_WINDOW_XWINDOW(pInst->pGtkWindow->window) );
+
+ XSync( pAppDisplay, False );
+ }
+
+ // update widget size; alas out parent is not yet really XEMBED conformant
+ gtk_widget_set_size_request( pInst->pGtkWidget, pWindow->width, pWindow->height );
+ gtk_window_resize( GTK_WINDOW(pInst->pGtkWindow), pWindow->width, pWindow->height );
+
+ GdkScreen* pGdkScreen = gtk_widget_get_screen( pInst->pGtkWidget );
+ Screen* pScreen = ScreenOfDisplay( pAppDisplay, gdk_screen_get_number( pGdkScreen ) );
+
+ pInst->window.x = 0;
+ pInst->window.y = 0;
+ pInst->window.width = pWindow->width;
+ pInst->window.height = pWindow->height;
+ pInst->window.clipRect.left = 0;
+ pInst->window.clipRect.top = 0;
+ pInst->window.clipRect.right = pWindow->width;
+ pInst->window.clipRect.bottom = pWindow->height;
+ pInst->window.ws_info = &pInst->ws_info;
+ pInst->window.type = NPWindowTypeWindow;
+ pInst->ws_info.type = NP_SETWINDOW;
+ pInst->ws_info.display = pAppDisplay;
+ pInst->ws_info.visual = DefaultVisualOfScreen( pScreen );
+ pInst->ws_info.colormap = DefaultColormapOfScreen( pScreen );
+ pInst->ws_info.depth = DefaultDepthOfScreen( pScreen );
+ }
+ else
+ #endif
+ {
+ if( ! pInst->pWidget )
+ {
+ pInst->pWidget = CreateNewShell( &(pInst->pShell), (XLIB_Window)pWindow->window );
+ }
+
+ // fill in NPWindow and NPCallbackStruct
+ pInst->window.window = (void*)XtWindow( (Widget)pInst->pWidget );
+ pInst->window.x = 0;
+ pInst->window.y = 0;
+ pInst->window.width = pWindow->width;
+ pInst->window.height = pWindow->height;
+ pInst->window.clipRect.left = 0;
+ pInst->window.clipRect.top = 0;
+ pInst->window.clipRect.right = pWindow->width;
+ pInst->window.clipRect.bottom = pWindow->height;
+ pInst->window.ws_info = &pInst->ws_info;
+ pInst->window.type = NPWindowTypeWindow;
+ pInst->ws_info.type = NP_SETWINDOW;
+ pInst->ws_info.display = XtDisplay( (Widget)pInst->pWidget );
+ pInst->ws_info.visual = DefaultVisualOfScreen( XtScreen( (Widget)pInst->pWidget ) );
+ pInst->ws_info.colormap = DefaultColormapOfScreen( XtScreen( (Widget)pInst->pWidget ) );
+ pInst->ws_info.depth = DefaultDepthOfScreen( XtScreen( (Widget)pInst->pWidget ) );
+
+ XtResizeWidget( (Widget)pInst->pShell,
+ pInst->window.width,
+ pInst->window.height,
+ 0 );
+ XtResizeWidget( (Widget)pInst->pWidget,
+ pInst->window.width,
+ pInst->window.height,
+ 0 );
+ }
+
+ NPError aRet = aPluginFuncs.setwindow( pInst->instance, &pInst->window );
+ medDebug( 1, "pluginapp: NPP_SetWindow returns %d\n", (int) aRet );
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ NULL );
+ delete [] (char*)pWindow;
+ }
+ break;
+ case eNPP_StreamAsFile:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ char* fname = pMessage->GetString();
+ medDebug( 1, "pluginapp: NPP_StreamAsFile %s\n", fname );
+ aPluginFuncs.asfile( instance, pStream, fname );
+ delete [] fname;
+ }
+ break;
+ case eNPP_URLNotify:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* url = pMessage->GetString();
+ NPReason* pReason = (NPReason*)pMessage->GetBytes();
+ void** notifyData = (void**)pMessage->GetBytes();
+ aPluginFuncs.urlnotify( instance, url, *pReason, *notifyData );
+ delete [] url;
+ delete [] pReason;
+ delete [] notifyData;
+ }
+ break;
+ case eNPP_WriteReady:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ int32 nRet = aPluginFuncs.writeready( instance, pStream );
+
+ medDebug( 1, "pluginapp: NPP_WriteReady( %p, %p ) (stream id = %d) returns %d\n",
+ instance, pStream, nFileID, nRet );
+
+ Respond( pMessage->m_nID,
+ (char*)&nRet, sizeof( nRet ),
+ NULL );
+ }
+ break;
+ case eNPP_Write:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ int32 offset = pMessage->GetUINT32();
+ sal_uLong len;
+ char* buffer = (char*)pMessage->GetBytes( len );
+ int32 nRet = aPluginFuncs.write( instance, pStream, offset, len, buffer );
+
+ medDebug( 1,"pluginapp: NPP_Write( %p, %p, %d, %d, %p ) returns %d\n"
+ "stream = { pdata = %p, ndata = %p, url = %s, end = %d, lastmodified = %d, notifyData = %p }\n",
+ instance, pStream, offset, len, buffer, nRet,
+ pStream->pdata, pStream->ndata, pStream->url, pStream->end, pStream->lastmodified, pStream->notifyData );
+
+ Respond( pMessage->m_nID,
+ (char*)&nRet, sizeof( nRet ),
+ NULL );
+ delete [] buffer;
+ }
+ break;
+ case eNPP_GetMIMEDescription:
+ {
+ if( ! pNPP_GetMIMEDescription )
+ pNPP_GetMIMEDescription = (char*(*)())
+ osl_getAsciiFunctionSymbol( pPluginLib, "NPP_GetMIMEDescription" );
+ char* pMIME = pNPP_GetMIMEDescription();
+ Respond( pMessage->m_nID,
+ POST_STRING( pMIME ),
+ NULL );
+ }
+ break;
+ case eNPP_Initialize:
+ {
+
+ pNP_Initialize =
+ (NPError(*)(NPNetscapeFuncs*, NPPluginFuncs*))
+ osl_getAsciiFunctionSymbol( pPluginLib, "NP_Initialize" );
+ medDebug( !pNP_Initialize, "no NP_Initialize, %s\n", dlerror() );
+ pNP_Shutdown = (NPError(*)())
+ osl_getAsciiFunctionSymbol( pPluginLib, "NP_Shutdown" );
+ medDebug( !pNP_Initialize, "no NP_Shutdown, %s\n", dlerror() );
+
+ medDebug( 1, "entering NP_Initialize\n" );
+ NPError aRet = pNP_Initialize( &aNetscapeFuncs, &aPluginFuncs );
+ medDebug( 1, "pluginapp: NP_Initialize returns %d\n", (int) aRet );
+ Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
+ }
+ break;
+ case eNPP_Shutdown:
+ {
+ write( wakeup_fd[1], "xxxx", 4 );
+ }
+ break;
+ default:
+ medDebug( 1, "caught unknown NPP request %d\n", nCommand );
+ break;
+ }
+ delete pMessage;
+ }
+ return 0;
+}
+
+void LoadAdditionalLibs( const char* _pPluginLib )
+{
+ medDebug( 1, "LoadAdditionalLibs %s\n", _pPluginLib );
+
+ if( ! strncmp( _pPluginLib, "libflashplayer.so", 17 ) )
+ {
+ /* #b4951312# flash 7 implicitly assumes a gtk application
+ * if the API version is greater or equal to 12 (probably
+ * because they think they run in mozilla then). In that
+ * case they try to find gtk within the process and crash
+ * when they don't find it.
+ */
+ aNetscapeFuncs.version = 11;
+ aPluginFuncs.version = 11;
+ }
+}
+
diff --git a/extensions/source/plugin/unx/nppapi.cxx b/extensions/source/plugin/unx/nppapi.cxx
new file mode 100644
index 000000000000..640daba417ce
--- /dev/null
+++ b/extensions/source/plugin/unx/nppapi.cxx
@@ -0,0 +1,621 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#if STLPORT_VERSION>=321
+#include <cstdarg>
+#endif
+
+#include <plugin/impl.hxx>
+#include <vcl/svapp.hxx>
+
+std::vector<PluginConnector*> PluginConnector::allConnectors;
+
+PluginConnector::PluginConnector( int nSocket ) :
+ Mediator( nSocket )
+{
+ allConnectors.push_back( this );
+ SetNewMessageHdl( LINK( this, PluginConnector, NewMessageHdl ) );
+}
+
+PluginConnector::~PluginConnector()
+{
+ vos::OGuard aGuard( m_aUserEventMutex );
+ for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
+ it != allConnectors.end(); ++it )
+ {
+ if( *it == this )
+ {
+ allConnectors.erase( it );
+ break;
+ }
+ }
+}
+
+IMPL_LINK( PluginConnector, NewMessageHdl, Mediator*, /*pMediator*/ )
+{
+ vos::OGuard aGuard( m_aUserEventMutex );
+ bool bFound = false;
+ for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
+ it != allConnectors.end() && bFound == false; ++it )
+ {
+ if( *it == this )
+ bFound = true;
+ }
+ if( ! bFound )
+ return 0;
+ Application::PostUserEvent( LINK( this, PluginConnector, WorkOnNewMessageHdl ) );
+ return 0;
+}
+
+IMPL_LINK( PluginConnector, WorkOnNewMessageHdl, Mediator*, /*pMediator*/ )
+{
+ bool bFound = false;
+ for( std::vector< PluginConnector* >::iterator it = allConnectors.begin();
+ it != allConnectors.end() && bFound == false; ++it )
+ {
+ if( *it == this )
+ bFound = true;
+ }
+ if( ! bFound )
+ return 0;
+/*
+ {
+ vos::OGuard aGuard( m_aUserEventMutex );
+ m_aUserEventIDs.pop_front();
+ }
+*/
+
+ MediatorMessage* pMessage;
+ CommandAtoms nCommand;
+ while( (pMessage = GetNextMessage( sal_False )) )
+ {
+ nCommand = (CommandAtoms)pMessage->GetUINT32();
+ medDebug( 1, "%s\n", GetCommandName( nCommand ) );
+ switch( nCommand )
+ {
+ case eNPN_GetURL:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pUrl = pMessage->GetString();
+ char* pWindow = pMessage->GetString();
+ NPError aRet = NPN_GetURL( instance, pUrl, pWindow );
+ Respond( pMessage->m_nID,
+ (char*)(&aRet), sizeof( NPError ), NULL );
+ delete [] pUrl;
+ delete [] pWindow;
+ }
+ break;
+ case eNPN_GetURLNotify:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pUrl = pMessage->GetString();
+ char* pWindow = pMessage->GetString();
+ void** pNotifyData = (void**)pMessage->GetBytes();
+ NPError aRet = NPN_GetURLNotify( instance, pUrl, pWindow,
+ *pNotifyData );
+ Respond( pMessage->m_nID,
+ (char*)(&aRet), sizeof( NPError ), NULL );
+ delete [] pUrl;
+ delete [] pWindow;
+ delete [] pNotifyData;
+ }
+ break;
+ case eNPN_DestroyStream:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ char* pUrl = pMessage->GetString();
+ NPError* pReason = (NPError*)pMessage->GetBytes();
+ NPError aRet = NPERR_FILE_NOT_FOUND;
+ if( nFileID < static_cast<sal_uInt32>(m_aNPWrapStreams.size()) )
+ {
+ if( ! strcmp( m_aNPWrapStreams[ nFileID ]->url, pUrl ) )
+ {
+ aRet =
+ NPN_DestroyStream( instance, m_aNPWrapStreams[ nFileID ],
+ *pReason );
+ m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
+ }
+ else
+ medDebug( 1, "StreamID %d has incoherent urls %s and %s\n",
+ nFileID, pUrl, m_aNPWrapStreams[ nFileID ]->url );
+ }
+ else
+ medDebug( 1, "Nonexistent StreamID %d\n", nFileID );
+
+ Respond( pMessage->m_nID,
+ (char*)(&aRet), sizeof( NPError ), NULL );
+
+ delete [] pUrl;
+ delete [] pReason;
+ }
+ break;
+ case eNPN_NewStream:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ NPMIMEType pType = pMessage->GetString();
+ char* pTarget = pMessage->GetString();
+
+ NPStream* pStream = NULL;
+
+ NPError aRet = NPN_NewStream( instance, pType, pTarget, &pStream );
+
+ if( aRet != NPERR_NO_ERROR )
+ {
+ sal_uInt32 nDummy = 0;
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ "", 0,
+ &nDummy, sizeof(sal_uInt32),
+ &nDummy, sizeof(sal_uInt32),
+ NULL );
+ }
+ else
+ {
+ m_aNPWrapStreams.push_back( pStream );
+
+ sal_uLong nLen = strlen( pStream->url );
+ Respond( pMessage->m_nID,
+ (char*)&aRet, sizeof( aRet ),
+ pStream->url, nLen,
+ &pStream->end, sizeof(sal_uInt32),
+ &pStream->lastmodified, sizeof(sal_uInt32),
+ NULL );
+ }
+
+ delete [] pTarget;
+ delete [] pType;
+ }
+ break;
+ case eNPN_PostURLNotify:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pUrl = pMessage->GetString();
+ char* pTarget = pMessage->GetString();
+ sal_uInt32 nLen = pMessage->GetUINT32();
+ char* pBuf = (char*)pMessage->GetBytes();
+ NPBool* pFile = (NPBool*)pMessage->GetBytes();
+ void** pNData = (void**)pMessage->GetBytes();
+ NPError aRet =
+ NPN_PostURLNotify( instance, pUrl, pTarget, nLen, pBuf, *pFile, *pNData );
+ Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
+ delete [] pUrl;
+ delete [] pTarget;
+ delete [] pBuf;
+ delete [] pFile;
+ delete [] pNData;
+ }
+ break;
+ case eNPN_PostURL:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pUrl = pMessage->GetString();
+ char* pWindow = pMessage->GetString();
+ sal_uInt32 nLen = pMessage->GetUINT32();
+ char* pBuf = (char*)pMessage->GetBytes();
+ NPBool* pFile = (NPBool*)pMessage->GetBytes();
+ NPError aRet =
+ NPN_PostURL( instance, pUrl, pWindow, nLen, pBuf, *pFile );
+ Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
+ delete [] pUrl;
+ delete [] pWindow;
+ delete [] pBuf;
+ delete [] pFile;
+ }
+ break;
+ case eNPN_RequestRead:
+ {
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ sal_uInt32 nRanges = pMessage->GetUINT32();
+ sal_uInt32* pArray = (sal_uInt32*)pMessage->GetBytes();
+ // build ranges table
+ NPByteRange* pFirst = new NPByteRange;
+ NPByteRange* pRun = pFirst;
+ for( sal_uInt32 n = 0; n < nRanges; n++ )
+ {
+ pRun->offset = pArray[ 2*n ];
+ pRun->length = pArray[ 2*n+1 ];
+ pRun->next = n < nRanges-1 ? new NPByteRange : NULL;
+ pRun = pRun->next;
+ }
+ NPError aRet = NPN_RequestRead( pStream, pFirst );
+ Respond( pMessage->m_nID, (char*)&aRet, sizeof( aRet ), NULL );
+ while( pFirst )
+ {
+ pRun = pFirst->next;
+ delete pFirst;
+ pFirst = pRun;
+ }
+ delete [] pArray;
+ }
+ break;
+ case eNPN_Status:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ char* pString = pMessage->GetString();
+ NPN_Status( instance, pString );
+ delete [] pString;
+ }
+ break;
+ case eNPN_Version:
+ {
+ int major, minor, net_major, net_minor;
+ NPN_Version( &major, &minor, &net_major, &net_minor );
+ Respond( pMessage->m_nID,
+ (char*)&major, sizeof( int ),
+ &minor, sizeof( int ),
+ &net_major, sizeof( int ),
+ &net_minor, sizeof( int ),
+ NULL );
+ }
+ break;
+ case eNPN_Write:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ sal_uInt32 nFileID = pMessage->GetUINT32();
+ NPStream* pStream = m_aNPWrapStreams[ nFileID ];
+ sal_Int32 nLen = pMessage->GetUINT32();
+ void* pBuffer = pMessage->GetBytes();
+ sal_Int32 nRet = NPN_Write( instance, pStream, nLen, pBuffer );
+ Respond( pMessage->m_nID,
+ (char*)&nRet, sizeof( nRet ),
+ NULL );
+ delete [] (char*)pBuffer;
+ delete instance;
+ }
+ break;
+ case eNPN_UserAgent:
+ {
+ sal_uInt32 nInstance = pMessage->GetUINT32();
+ NPP instance = m_aInstances[ nInstance ]->instance;
+ const char* pAnswer = NPN_UserAgent( instance );
+ Respond( pMessage->m_nID,
+ (char*)pAnswer, strlen( pAnswer ),
+ NULL );
+ }
+ break;
+ default:
+ medDebug( 1, "caught unknown NPN request %d\n", nCommand );
+ }
+
+ delete pMessage;
+ }
+ return 0;
+}
+
+#define GET_INSTANCE() \
+ sal_uInt32 nInstance; \
+ nInstance = GetNPPID( instance );
+
+#define GET_INSTANCE_RET( err ) \
+ GET_INSTANCE() \
+ if( nInstance == PluginConnector::UnknownNPPID ) \
+ return err
+
+
+#define POST_INSTANCE() (char*)&nInstance, sizeof( nInstance )
+
+NPError UnxPluginComm::NPP_Destroy( NPP instance, NPSavedData** save )
+{
+ NPError aRet = NPERR_GENERIC_ERROR;
+ GET_INSTANCE_RET( aRet );
+ MediatorMessage* pMes =
+ Transact( eNPP_Destroy,
+ POST_INSTANCE(),
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+ delete pMes;
+
+ pMes = Transact( eNPP_DestroyPhase2,
+ POST_INSTANCE(),
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ aRet = GetNPError( pMes );
+ sal_uLong nSaveBytes;
+ void* pSaveData = pMes->GetBytes( nSaveBytes );
+ if( nSaveBytes == 4 && *(sal_uInt32*)pSaveData == 0 )
+ *save = NULL;
+ else
+ {
+ *save = new NPSavedData;
+ (*save)->len = nSaveBytes;
+ (*save)->buf = pSaveData;
+ }
+ delete pMes;
+
+ return aRet;
+}
+
+NPError UnxPluginComm::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason )
+{
+ NPError aRet = NPERR_GENERIC_ERROR;
+ GET_INSTANCE_RET( aRet );
+ sal_uInt32 nFileID = GetStreamID( stream );
+ if( nFileID == PluginConnector::UnknownStreamID )
+ return NPERR_GENERIC_ERROR;
+
+ MediatorMessage* pMes =
+ Transact( eNPP_DestroyStream,
+ POST_INSTANCE(),
+ &nFileID, sizeof( nFileID ),
+ &reason, sizeof( reason ),
+ NULL );
+ m_aNPWrapStreams.erase( m_aNPWrapStreams.begin() + nFileID );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ aRet = GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+void* UnxPluginComm::NPP_GetJavaClass()
+{
+ return NULL;
+}
+
+NPError UnxPluginComm::NPP_Initialize()
+{
+ MediatorMessage* pMes =
+ Transact( eNPP_Initialize,
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ NPError aRet = GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+NPError UnxPluginComm::NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved )
+{
+ m_aInstances.push_back(
+ new ConnectorInstance( instance, pluginType, 0,
+ NULL, 0, NULL, 0,
+ saved ? (char*)saved->buf : NULL,
+ saved ? saved->len : 0 ) );
+
+ char *pArgnBuf, *pArgvBuf;
+ size_t nArgnLen = 0, nArgvLen = 0;
+ int i;
+ for( i = 0; i < argc; i++ )
+ {
+ nArgnLen += strlen( argn[i] ) +1;
+ nArgvLen += strlen( argv[i] ) +1;
+ }
+ pArgnBuf = new char[ nArgnLen ];
+ pArgvBuf = new char[ nArgvLen ];
+ char* pRunArgn = pArgnBuf;
+ char* pRunArgv = pArgvBuf;
+ for( i = 0; i < argc; i++ )
+ {
+ strcpy( pRunArgn, argn[i] );
+ strcpy( pRunArgv, argv[i] );
+ pRunArgn += strlen( argn[i] ) +1;
+ pRunArgv += strlen( argv[i] ) +1;
+ }
+
+ MediatorMessage* pMes;
+ if( saved )
+ pMes =
+ Transact( eNPP_New,
+ pluginType, strlen( pluginType ),
+ &mode, sizeof( mode ),
+ &argc, sizeof( argc ),
+ pArgnBuf, nArgnLen,
+ pArgvBuf, nArgvLen,
+ saved->buf, static_cast<size_t>(saved->len),
+ NULL );
+ else
+ pMes =
+ Transact( eNPP_New,
+ pluginType, strlen( pluginType ),
+ &mode, sizeof( mode ),
+ &argc, sizeof( argc ),
+ pArgnBuf, nArgnLen,
+ pArgvBuf, nArgvLen,
+ "0000", size_t(4),
+ NULL );
+ delete [] pArgnBuf;
+ delete [] pArgvBuf;
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ NPError aRet = GetNPError( pMes );
+ delete pMes;
+
+ return aRet;
+}
+
+NPError UnxPluginComm::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype )
+{
+ NPError aRet = NPERR_GENERIC_ERROR;
+ GET_INSTANCE_RET( aRet );
+
+ m_aNPWrapStreams.push_back( stream );
+ MediatorMessage* pMes =
+ Transact( eNPP_NewStream,
+ POST_INSTANCE(),
+ type, strlen( type ),
+ stream->url, strlen( stream->url ),
+ &stream->end, sizeof( stream->end ),
+ &stream->lastmodified, sizeof( stream->lastmodified ),
+ &seekable, sizeof( seekable ),
+ NULL );
+
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ aRet = GetNPError( pMes );
+ uint16* pSType = (uint16*)pMes->GetBytes();
+ *stype = *pSType;
+
+ delete [] pSType;
+ delete pMes;
+ return aRet;
+}
+
+void UnxPluginComm::NPP_Print( NPP /*instance*/, NPPrint* /*platformPrint*/ )
+{
+}
+
+NPError UnxPluginComm::NPP_SetWindow( NPP instance, NPWindow* window )
+{
+ NPError aRet = NPERR_GENERIC_ERROR;
+ GET_INSTANCE_RET( aRet );
+
+ MediatorMessage* pMes =
+ Transact( eNPP_SetWindow,
+ POST_INSTANCE(),
+ window, sizeof( NPWindow ),
+ NULL );
+ if( ! pMes )
+ return NPERR_GENERIC_ERROR;
+
+ aRet = GetNPError( pMes );
+ delete pMes;
+ return aRet;
+}
+
+void UnxPluginComm::NPP_Shutdown()
+{
+ Send( eNPP_Shutdown, NULL );
+}
+
+void UnxPluginComm::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
+{
+ GET_INSTANCE();
+ sal_uInt32 nFileID = GetStreamID( stream );
+ if( nFileID == PluginConnector::UnknownStreamID )
+ return;
+
+ Send( eNPP_StreamAsFile,
+ POST_INSTANCE(),
+ &nFileID, sizeof( nFileID ),
+ fname, strlen( fname ),
+ NULL );
+}
+
+void UnxPluginComm::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
+{
+ GET_INSTANCE();
+
+ Send( eNPP_URLNotify,
+ POST_INSTANCE(),
+ url, strlen( url ),
+ &reason, sizeof( reason ),
+ &notifyData, sizeof( void* ),
+ NULL );
+}
+
+int32 UnxPluginComm::NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer )
+{
+ GET_INSTANCE_RET( -1 );
+ sal_uInt32 nFileID = GetStreamID( stream );
+ if( nFileID == PluginConnector::UnknownStreamID )
+ return -1;
+
+ MediatorMessage* pMes =
+ Transact( eNPP_Write,
+ POST_INSTANCE(),
+ &nFileID, sizeof( nFileID ),
+ &offset, sizeof( offset ),
+ buffer, static_cast<size_t>(len),
+ NULL );
+ if( ! pMes )
+ return 0;
+
+ int32 aRet = pMes->GetUINT32();
+ delete pMes;
+
+ return aRet;
+}
+
+int32 UnxPluginComm::NPP_WriteReady( NPP instance, NPStream* stream )
+{
+ GET_INSTANCE_RET( -1 );
+ sal_uInt32 nFileID = GetStreamID( stream );
+ if( nFileID == PluginConnector::UnknownStreamID )
+ return -1;
+
+ MediatorMessage* pMes =
+ Transact( eNPP_WriteReady,
+ POST_INSTANCE(),
+ &nFileID, sizeof( nFileID ),
+ NULL );
+
+ if( ! pMes )
+ return 0;
+
+ int32 aRet = pMes->GetUINT32();
+ delete pMes;
+
+ return aRet;
+}
+
+char* UnxPluginComm::NPP_GetMIMEDescription()
+{
+ static char* pDesc = NULL;
+ MediatorMessage* pMes =
+ Transact( eNPP_GetMIMEDescription,
+ NULL );
+ if( ! pMes )
+ return (char*)"";
+
+ if( pDesc )
+ delete [] pDesc;
+ pDesc = pMes->GetString();
+ delete pMes;
+ return pDesc;
+}
+
+NPError UnxPluginComm::NPP_GetValue( NPP /*instance*/, NPPVariable /*variable*/, void* /*value*/ )
+{
+ return 0;
+}
+
+NPError UnxPluginComm::NPP_SetValue( NPP /*instance*/, NPNVariable /*variable*/, void* /*value*/ )
+{
+ return 0;
+}
diff --git a/extensions/source/plugin/unx/npwrap.cxx b/extensions/source/plugin/unx/npwrap.cxx
new file mode 100644
index 000000000000..98bb858ecc0f
--- /dev/null
+++ b/extensions/source/plugin/unx/npwrap.cxx
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <errno.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include <plugin/unx/plugcon.hxx>
+
+#include <osl/file.h>
+#include <osl/module.h>
+
+PluginConnector* pConnector = NULL;
+
+int nAppArguments = 0;
+char** pAppArguments = NULL;
+Display* pAppDisplay = NULL;
+Display* pXtAppDisplay = NULL;
+
+extern oslModule pPluginLib;
+extern NPError (*pNP_Shutdown)();
+
+void LoadAdditionalLibs(const char*);
+
+XtAppContext app_context;
+Widget topLevel = NULL, topBox = NULL;
+int wakeup_fd[2] = { 0, 0 };
+static bool bPluginAppQuit = false;
+
+static long GlobalConnectionLostHdl( void* /*pInst*/, void* /*pArg*/ )
+{
+ medDebug( 1, "pluginapp exiting due to connection lost\n" );
+
+ write( wakeup_fd[1], "xxxx", 4 );
+ return 0;
+}
+
+extern "C"
+{
+ static int plugin_x_error_handler( Display*, XErrorEvent* )
+ {
+ return 0;
+ }
+
+ #ifndef ENABLE_GTK
+ static void ThreadEventHandler( XtPointer /*client_data*/, int* /*source*/, XtInputId* id )
+ {
+ char buf[256];
+ // clear pipe
+ int len, nLast = -1;
+
+ while( (len = read( wakeup_fd[0], buf, sizeof( buf ) ) ) > 0 )
+ nLast = len-1;
+ if( ! bPluginAppQuit )
+ {
+ if( ( nLast == -1 || buf[nLast] != 'x' ) && pConnector )
+ pConnector->CallWorkHandler();
+ else
+ {
+ // it seems you can use XtRemoveInput only
+ // safely from within the callback
+ // why is that ?
+ medDebug( 1, "removing wakeup pipe\n" );
+ XtRemoveInput( *id );
+ XtAppSetExitFlag( app_context );
+ bPluginAppQuit = true;
+
+ delete pConnector;
+ pConnector = NULL;
+ }
+ }
+ }
+ #endif
+}
+
+
+IMPL_LINK( PluginConnector, NewMessageHdl, Mediator*, /*pMediator*/ )
+{
+ medDebug( 1, "new message handler\n" );
+ write( wakeup_fd[1], "cccc", 4 );
+ return 0;
+
+}
+
+Widget createSubWidget( char* /*pPluginText*/, Widget shell, XLIB_Window aParentWindow )
+{
+ Widget newWidget = XtVaCreateManagedWidget(
+#if defined USE_MOTIF
+ "drawingArea",
+ xmDrawingAreaWidgetClass,
+#else
+ "",
+# if defined DISABLE_XAW
+ compositeWidgetClass,
+# else
+ labelWidgetClass,
+# endif
+#endif
+ shell,
+ XtNwidth, 200,
+ XtNheight, 200,
+ (char *)NULL );
+ XtRealizeWidget( shell );
+ XtRealizeWidget( newWidget );
+
+ medDebug( 1, "Reparenting new widget %x to %x\n", XtWindow( newWidget ), aParentWindow );
+ XReparentWindow( pXtAppDisplay,
+ XtWindow( shell ),
+ aParentWindow,
+ 0, 0 );
+ XtMapWidget( shell );
+ XtMapWidget( newWidget );
+ XRaiseWindow( pXtAppDisplay, XtWindow( shell ) );
+ XSync( pXtAppDisplay, False );
+
+ return newWidget;
+}
+
+void* CreateNewShell( void** pShellReturn, XLIB_Window aParentWindow )
+{
+ XLIB_String n, c;
+ XtGetApplicationNameAndClass(pXtAppDisplay, &n, &c);
+
+ Widget newShell =
+ XtVaAppCreateShell( "pane", c,
+ topLevelShellWidgetClass,
+ pXtAppDisplay,
+ XtNwidth, 200,
+ XtNheight, 200,
+ XtNoverrideRedirect, True,
+ (char *)NULL );
+ *pShellReturn = newShell;
+
+ char pText[1024];
+ sprintf( pText, "starting plugin %s ...", pAppArguments[2] );
+
+ Widget newWidget = createSubWidget( pText, newShell, aParentWindow );
+
+ return newWidget;
+}
+
+static oslModule LoadModule( const char* pPath )
+{
+ ::rtl::OUString sSystemPath( ::rtl::OUString::createFromAscii( pPath ) );
+ ::rtl::OUString sFileURL;
+ osl_getFileURLFromSystemPath( sSystemPath.pData, &sFileURL.pData );
+
+ oslModule pLib = osl_loadModule( sFileURL.pData, SAL_LOADMODULE_LAZY );
+ if( ! pLib )
+ {
+ medDebug( 1, "could not open %s: %s\n", pPath, dlerror() );
+ }
+ return pLib;
+}
+
+// Unix specific implementation
+static void CheckPlugin( const char* pPath )
+{
+ oslModule pLib = LoadModule( pPath );
+
+ char*(*pNP_GetMIMEDescription)() = (char*(*)())
+ osl_getAsciiFunctionSymbol( pLib, "NP_GetMIMEDescription" );
+ if( pNP_GetMIMEDescription )
+ printf( "%s\n", pNP_GetMIMEDescription() );
+ else
+ medDebug( 1, "could not get symbol NP_GetMIMEDescription %s\n", dlerror() );
+
+ osl_unloadModule( pLib );
+}
+
+#if OSL_DEBUG_LEVEL > 1 && defined LINUX
+#include <execinfo.h>
+#endif
+
+extern "C" {
+
+static void signal_handler( int nSig )
+{
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "caught signal %d, exiting\n", nSig );
+#ifdef LINUX
+ void* pStack[64];
+ int nStackLevels = backtrace( pStack, sizeof(pStack)/sizeof(pStack[0]) );
+ backtrace_symbols_fd( pStack, nStackLevels, STDERR_FILENO );
+#endif
+#endif
+ if( pConnector )
+ {
+ // ensure that a read on the other side will wakeup
+ delete pConnector;
+ pConnector = NULL;
+ }
+
+ _exit(nSig);
+}
+
+#ifdef ENABLE_GTK
+
+static gboolean noClosure( gpointer )
+{
+ return sal_True;
+}
+
+// Xt events
+static gboolean prepareXtEvent( GSource*, gint* )
+{
+ int nMask = XtAppPending( app_context );
+ return (nMask & XtIMAll) != 0;
+}
+
+static gboolean checkXtEvent( GSource* )
+{
+ int nMask = XtAppPending( app_context );
+ return (nMask & XtIMAll) != 0;
+}
+
+static gboolean dispatchXtEvent( GSource*, GSourceFunc, gpointer )
+{
+ XtAppProcessEvent( app_context, XtIMAll );
+ return sal_True;
+}
+
+static GSourceFuncs aXtEventFuncs =
+{
+ prepareXtEvent,
+ checkXtEvent,
+ dispatchXtEvent,
+ NULL,
+ noClosure,
+ NULL
+};
+
+static gboolean pollXtTimerCallback(gpointer)
+{
+ for(int i = 0; i < 5; i++)
+ {
+ if( (XtAppPending(app_context) & (XtIMAll & ~XtIMXEvent)) == 0 )
+ break;
+ XtAppProcessEvent(app_context, XtIMAll & ~XtIMXEvent);
+ }
+ return sal_True;
+}
+
+static gboolean prepareWakeupEvent( GSource*, gint* )
+{
+ struct pollfd aPoll = { wakeup_fd[0], POLLIN, 0 };
+ poll( &aPoll, 1, 0 );
+ return (aPoll.revents & POLLIN ) != 0;
+}
+
+static gboolean checkWakeupEvent( GSource* pSource )
+{
+ gint nDum = 0;
+ return prepareWakeupEvent( pSource, &nDum );
+}
+
+static gboolean dispatchWakeupEvent( GSource*, GSourceFunc, gpointer )
+{
+ char buf[256];
+ // clear pipe
+ int len, nLast = -1;
+
+ while( (len = read( wakeup_fd[0], buf, sizeof( buf ) ) ) > 0 )
+ nLast = len-1;
+ if( ( nLast == -1 || buf[nLast] != 'x' ) && pConnector )
+ pConnector->CallWorkHandler();
+ else
+ {
+ XtAppSetExitFlag( app_context );
+ bPluginAppQuit = true;
+
+ delete pConnector;
+ pConnector = NULL;
+ }
+
+ return sal_True;
+}
+
+static GSourceFuncs aWakeupEventFuncs = {
+ prepareWakeupEvent,
+ checkWakeupEvent,
+ dispatchWakeupEvent,
+ NULL,
+ noClosure,
+ NULL
+};
+
+#endif // GTK
+
+}
+
+int main( int argc, char **argv)
+{
+ struct sigaction aSigAction;
+ aSigAction.sa_handler = signal_handler;
+ sigemptyset( &aSigAction.sa_mask );
+ aSigAction.sa_flags = SA_NOCLDSTOP;
+ sigaction( SIGSEGV, &aSigAction, NULL );
+ sigaction( SIGBUS, &aSigAction, NULL );
+ sigaction( SIGABRT, &aSigAction, NULL );
+ sigaction( SIGTERM, &aSigAction, NULL );
+ sigaction( SIGILL, &aSigAction, NULL );
+
+ int nArg = (argc < 3) ? 1 : 2;
+ char* pBaseName = argv[nArg] + strlen(argv[nArg]);
+ while( pBaseName > argv[nArg] && pBaseName[-1] != '/' )
+ pBaseName--;
+ LoadAdditionalLibs( pBaseName );
+
+ if( argc == 2 )
+ {
+ CheckPlugin(argv[1]);
+ exit(0);
+ }
+ nAppArguments = argc;
+ pAppArguments = argv;
+
+ XSetErrorHandler( plugin_x_error_handler );
+
+ if( pipe( wakeup_fd ) )
+ {
+ medDebug( 1, "could not pipe()\n" );
+ return 1;
+ }
+ // initialize 'wakeup' pipe.
+ int flags;
+
+ // set close-on-exec descriptor flag.
+ if ((flags = fcntl (wakeup_fd[0], F_GETFD)) != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl (wakeup_fd[0], F_SETFD, flags);
+ }
+ if ((flags = fcntl (wakeup_fd[1], F_GETFD)) != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl (wakeup_fd[1], F_SETFD, flags);
+ }
+
+ // set non-blocking I/O flag.
+ if ((flags = fcntl (wakeup_fd[0], F_GETFL)) != -1)
+ {
+ flags |= O_NONBLOCK;
+ fcntl (wakeup_fd[0], F_SETFL, flags);
+ }
+ if ((flags = fcntl (wakeup_fd[1], F_GETFL)) != -1)
+ {
+ flags |= O_NONBLOCK;
+ fcntl (wakeup_fd[1], F_SETFL, flags);
+ }
+
+ pPluginLib = LoadModule( argv[2] );
+ if( ! pPluginLib )
+ {
+ exit(255);
+ }
+ int nSocket = atol( argv[1] );
+
+ #ifdef ENABLE_GTK
+ g_thread_init(NULL);
+ gtk_init(&argc, &argv);
+ #endif
+
+ pConnector = new PluginConnector( nSocket );
+ pConnector->SetConnectionLostHdl( Link( NULL, GlobalConnectionLostHdl ) );
+
+ XtSetLanguageProc( NULL, NULL, NULL );
+
+ XtToolkitInitialize();
+ app_context = XtCreateApplicationContext();
+ pXtAppDisplay = XtOpenDisplay( app_context, NULL, "SOPlugin", "SOPlugin", NULL, 0, &argc, argv );
+
+
+ #ifdef ENABLE_GTK
+ // integrate Xt events into GTK event loop
+ GPollFD aXtPollDesc, aWakeupPollDesc;
+
+ GSource* pXTSource = g_source_new( &aXtEventFuncs, sizeof(GSource) );
+ if( !pXTSource )
+ {
+ medDebug( 1, "could not get Xt GSource" );
+ return 1;
+ }
+
+ g_source_set_priority( pXTSource, GDK_PRIORITY_EVENTS );
+ g_source_set_can_recurse( pXTSource, sal_True );
+ g_source_attach( pXTSource, NULL );
+ aXtPollDesc.fd = ConnectionNumber( pXtAppDisplay );
+ aXtPollDesc.events = G_IO_IN;
+ aXtPollDesc.revents = 0;
+ g_source_add_poll( pXTSource, &aXtPollDesc );
+
+ gint xt_polling_timer_id = g_timeout_add( 25, pollXtTimerCallback, NULL);
+ // Initialize wakeup events listener
+ GSource *pWakeupSource = g_source_new( &aWakeupEventFuncs, sizeof(GSource) );
+ if ( pWakeupSource == NULL )
+ {
+ medDebug( 1, "could not get wakeup source" );
+ return 1;
+ }
+ g_source_set_priority( pWakeupSource, GDK_PRIORITY_EVENTS);
+ g_source_attach( pWakeupSource, NULL );
+ aWakeupPollDesc.fd = wakeup_fd[0];
+ aWakeupPollDesc.events = G_IO_IN;
+ aWakeupPollDesc.revents = 0;
+ g_source_add_poll( pWakeupSource, &aWakeupPollDesc );
+
+ pAppDisplay = gdk_x11_display_get_xdisplay( gdk_display_get_default() );
+ #else
+ pAppDisplay = pXtAppDisplay;
+ XtAppAddInput( app_context,
+ wakeup_fd[0],
+ (XtPointer)XtInputReadMask,
+ ThreadEventHandler, NULL );
+ #endif
+
+ // send that we are ready to go
+ MediatorMessage* pMessage =
+ pConnector->Transact( "init req", 8,
+ NULL );
+ delete pMessage;
+
+#if OSL_DEBUG_LEVEL > 3
+ int nPID = getpid();
+ int nChild = fork();
+ if( nChild == 0 )
+ {
+ char pidbuf[16];
+ char* pArgs[] = { "xterm", "-sl", "2000", "-sb", "-e", "gdb", "pluginapp.bin", pidbuf, NULL };
+ sprintf( pidbuf, "%d", nPID );
+ execvp( pArgs[0], pArgs );
+ _exit(255);
+ }
+ else
+ sleep( 10 );
+#endif
+
+ /*
+ * Loop for events.
+ */
+ // for some reason XtAppSetExitFlag won't quit the application
+ // in ThreadEventHandler most of times; Xt will hang in select
+ // (hat is in XtAppNextEvent). Have our own mainloop instead
+ // of XtAppMainLoop
+ do
+ {
+ #ifdef ENABLE_GTK
+ g_main_context_iteration( NULL, sal_True );
+ #else
+ XtAppProcessEvent( app_context, XtIMAll );
+ #endif
+ } while( ! XtAppGetExitFlag( app_context ) && ! bPluginAppQuit );
+
+ medDebug( 1, "left plugin app main loop\n" );
+
+ #ifdef ENABLE_GTK
+ g_source_remove(xt_polling_timer_id);
+ #endif
+
+ pNP_Shutdown();
+ medDebug( 1, "NP_Shutdown done\n" );
+ osl_unloadModule( pPluginLib );
+ medDebug( 1, "plugin close\n" );
+
+ close( wakeup_fd[0] );
+ close( wakeup_fd[1] );
+
+ return 0;
+}
+
+#ifdef GCC
+extern "C" {
+ void __pure_virtual()
+ {}
+
+ void* __builtin_new( int nBytes )
+ { return malloc(nBytes); }
+ void* __builtin_vec_new( int nBytes )
+ { return malloc(nBytes); }
+ void __builtin_delete( char* pMem )
+ { free(pMem); }
+ void __builtin_vec_delete( char* pMem )
+ { free(pMem); }
+}
+#endif
+
diff --git a/extensions/source/plugin/unx/plugcon.cxx b/extensions/source/plugin/unx/plugcon.cxx
new file mode 100644
index 000000000000..c71738be3632
--- /dev/null
+++ b/extensions/source/plugin/unx/plugcon.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <plugin/unx/plugcon.hxx>
+
+#include <cstdarg>
+#include <vector>
+
+sal_uInt32 PluginConnector::GetStreamID( NPStream* pStream )
+{
+ size_t nLen = m_aNPWrapStreams.size();
+ for( size_t i = 0; i < nLen; i++ )
+ if( m_aNPWrapStreams[ i ] == pStream )
+ return static_cast<sal_uInt32>(i);
+ medDebug( 1, "Error: NPStream has no ID\n" );
+ return UnknownStreamID;
+}
+
+sal_uInt32 PluginConnector::GetNPPID( NPP instance )
+{
+ size_t nLen = m_aInstances.size();
+ for( size_t i=0; i <nLen; i++ )
+ if( m_aInstances[ i ]->instance == instance )
+ return static_cast<sal_uInt32>(i);
+ medDebug( 1, "Error: NPP has no ID\n" );
+
+ return UnknownNPPID;
+}
+
+ConnectorInstance* PluginConnector::getInstance( NPP instance )
+{
+ size_t nLen = m_aInstances.size();
+ for( size_t i=0; i <nLen; i++ )
+ {
+ ConnectorInstance* pInst = m_aInstances[i];
+ if( pInst->instance == instance )
+ return pInst;
+ }
+ return NULL;
+}
+
+ConnectorInstance* PluginConnector::getInstanceById( sal_uInt32 nInstanceID )
+{
+ return nInstanceID < static_cast<sal_uInt32>(m_aInstances.size()) ? m_aInstances[ nInstanceID ] : NULL;
+}
+
+struct PtrStruct
+{
+ char* pData;
+ sal_uLong nBytes;
+
+ PtrStruct( char* i_pData, sal_uLong i_nBytes )
+ : pData( i_pData ), nBytes( i_nBytes ) {}
+};
+
+sal_uLong PluginConnector::FillBuffer( char*& rpBuffer,
+ const char* pFunction,
+ sal_uLong nFunctionLen,
+ va_list ap )
+{
+ std::vector< PtrStruct > aList;
+ aList.reserve( 5 );
+
+ sal_uLong nDataSize = nFunctionLen + sizeof( sal_uLong );
+ char* pNext;
+
+ do {
+ pNext = va_arg( ap, char* );
+ if( pNext )
+ {
+ aList.push_back( PtrStruct( pNext, va_arg( ap, sal_uLong ) ) );
+ nDataSize += aList.back().nBytes + sizeof(sal_uLong);
+ }
+ } while( pNext );
+
+ rpBuffer = new char[ nDataSize ];
+ char* pRun = rpBuffer;
+ memcpy( pRun, &nFunctionLen, sizeof( nFunctionLen ) );
+ pRun += sizeof( nFunctionLen );
+ memcpy( pRun, pFunction, nFunctionLen );
+ pRun += nFunctionLen;
+
+ for( std::vector<PtrStruct>::const_iterator it = aList.begin(); it != aList.end(); ++it )
+ {
+ memcpy( pRun, &it->nBytes, sizeof( sal_uLong ) );
+ pRun += sizeof( sal_uLong );
+ memcpy( pRun, it->pData, it->nBytes );
+ pRun += it->nBytes;
+ }
+ return nDataSize;
+}
+
+MediatorMessage* PluginConnector::Transact( const char* pFunction,
+ sal_uLong nFunctionLen, ... )
+{
+ va_list ap;
+ char* pBuffer;
+
+ va_start( ap, nFunctionLen );
+ sal_uLong nSize = FillBuffer( pBuffer, pFunction, nFunctionLen, ap );
+ va_end( ap );
+ return TransactMessage( nSize, pBuffer );
+}
+
+MediatorMessage* PluginConnector::Transact( sal_uInt32 nFunction, ... )
+{
+ va_list ap;
+ char* pBuffer;
+
+ va_start( ap, nFunction );
+ sal_uLong nSize = FillBuffer( pBuffer, (char*)&nFunction, sizeof( nFunction ), ap );
+ va_end( ap );
+ return TransactMessage( nSize, pBuffer );
+}
+
+sal_uLong PluginConnector::Send( sal_uInt32 nFunction, ... )
+{
+ va_list ap;
+ char* pBuffer;
+
+ va_start( ap, nFunction );
+ sal_uLong nSize = FillBuffer( pBuffer, (char*)&nFunction, sizeof( nFunction ), ap );
+ va_end( ap );
+ return SendMessage( nSize, pBuffer );
+}
+
+void PluginConnector::Respond( sal_uLong nID,
+ char* pFunction,
+ sal_uLong nFunctionLen, ... )
+{
+ va_list ap;
+ char* pBuffer;
+
+ va_start( ap, nFunctionLen );
+ sal_uLong nSize = FillBuffer( pBuffer, pFunction, nFunctionLen, ap );
+ va_end( ap );
+ SendMessage( nSize, pBuffer, nID | ( 1 << 24 ) );
+}
+
+MediatorMessage* PluginConnector::WaitForAnswer( sal_uLong nMessageID )
+{
+ if( ! m_bValid )
+ return NULL;
+
+ nMessageID &= 0x00ffffff;
+ while( m_pListener )
+ {
+ {
+ vos::OGuard aGuard( m_aQueueMutex );
+ for( size_t i = 0; i < m_aMessageQueue.size(); i++ )
+ {
+ MediatorMessage* pMessage = m_aMessageQueue[ i ];
+ sal_uLong nID = pMessage->m_nID;
+ if( ( nID & 0xff000000 ) &&
+ ( ( nID & 0x00ffffff ) == nMessageID ) )
+ {
+ m_aMessageQueue.erase( m_aMessageQueue.begin() + i );
+ return pMessage;
+ }
+ }
+ }
+ if( ! m_aMessageQueue.empty() )
+ CallWorkHandler();
+ WaitForMessage( 2000 );
+ }
+ return NULL;
+}
+
+ConnectorInstance::ConnectorInstance( NPP inst, char* type,
+ int args, char* pargnbuf, sal_uLong nargnbytes,
+ char* pargvbuf, sal_uLong nargvbytes,
+ char* savedata, sal_uLong savebytes ) :
+ instance( inst ),
+ pShell( NULL ),
+ pWidget( NULL ),
+ pForm( NULL ),
+ pGtkWindow( NULL ),
+ pGtkWidget( NULL ),
+ bShouldUseXEmbed( false ),
+ nArg( args ),
+ pArgnBuf( pargnbuf ),
+ pArgvBuf( pargvbuf )
+{
+ memset( &window, 0, sizeof(window) );
+ pMimeType = new char[ strlen( type ) + 1 ];
+ strcpy( pMimeType, type );
+ aData.len = savebytes;
+ aData.buf = savedata;
+ argn = new char*[ nArg ];
+ argv = new char*[ nArg ];
+ int i;
+ char* pRun = pArgnBuf;
+ for( i = 0; i < nArg; i++ )
+ {
+ argn[i] = pRun;
+ while( *pRun != 0 && (sal_uLong)(pRun - pArgnBuf) < nargnbytes )
+ pRun++;
+ if( (sal_uLong)(pRun - pArgnBuf) < nargnbytes )
+ pRun++;
+ }
+ pRun = pArgvBuf;
+ for( i = 0; i < nArg; i++ )
+ {
+ argv[i] = pRun;
+ while( *pRun != 0 && (sal_uLong)(pRun - pArgvBuf) < nargvbytes )
+ pRun++;
+ if( (sal_uLong)(pRun - pArgvBuf) < nargvbytes )
+ pRun++;
+ }
+}
+
+ConnectorInstance::~ConnectorInstance()
+{
+ delete [] pMimeType;
+ delete [] argn;
+ delete [] argv;
+ delete [] pArgnBuf;
+ delete [] pArgvBuf;
+ delete [] (char*)aData.buf;
+}
+
+const char* GetCommandName( CommandAtoms eCommand )
+{
+ switch( eCommand )
+ {
+ case eNPN_GetURL: return "NPN_GetURL";
+ case eNPN_GetURLNotify: return "NPN_GetURLNotify";
+ case eNPN_DestroyStream: return "NPN_DestroyStream";
+ case eNPN_NewStream: return "NPN_NewStream";
+ case eNPN_PostURLNotify: return "NPN_PostURLNotify";
+ case eNPN_PostURL: return "NPN_PostURL";
+ case eNPN_RequestRead: return "NPN_RequestRead";
+ case eNPN_Status: return "NPN_Status";
+ case eNPN_Version: return "NPN_Version";
+ case eNPN_Write: return "NPN_Write";
+ case eNPN_UserAgent: return "NPN_UserAgent";
+
+ case eNPP_DestroyStream: return "NPP_DestroyStream";
+ case eNPP_Destroy: return "NPP_Destroy";
+ case eNPP_DestroyPhase2: return "NPP_DestroyPhase2";
+ case eNPP_NewStream: return "NPP_NewStream";
+ case eNPP_New: return "NPP_New";
+ case eNPP_SetWindow: return "NPP_SetWindow";
+ case eNPP_StreamAsFile: return "NPP_StreamAsFile";
+ case eNPP_URLNotify: return "NPP_URLNotify";
+ case eNPP_WriteReady: return "NPP_WriteReady";
+ case eNPP_Write: return "NPP_Write";
+ case eNPP_GetMIMEDescription: return "NPP_GetMIMEDescription";
+ case eNPP_Initialize: return "NPP_Initialize";
+ case eNPP_Shutdown: return "NPP_Shutdown";
+
+ case eMaxCommand: return "eMaxCommand";
+ default: return "unknown command";
+ }
+ return NULL;
+}
diff --git a/extensions/source/plugin/unx/sysplug.cxx b/extensions/source/plugin/unx/sysplug.cxx
new file mode 100644
index 000000000000..be5879bf238d
--- /dev/null
+++ b/extensions/source/plugin/unx/sysplug.cxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <cstdarg>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <rtl/bootstrap.hxx>
+
+#include <plugin/impl.hxx>
+
+int UnxPluginComm::nConnCounter = 0;
+
+UnxPluginComm::UnxPluginComm(
+ const String& /*mimetype*/,
+ const String& library,
+ XLIB_Window aParent,
+ int nDescriptor1,
+ int nDescriptor2
+ ) :
+ PluginComm( ::rtl::OUStringToOString( library, osl_getThreadTextEncoding() ), false ),
+ PluginConnector( nDescriptor2 )
+{
+ char pDesc[32];
+ char pWindow[32];
+ sprintf( pWindow, "%d", (int)aParent );
+ sprintf( pDesc, "%d", nDescriptor1 );
+ ByteString aLib( library, osl_getThreadTextEncoding() );
+ rtl::OString path;
+ if (!getPluginappPath(&path)) {
+ fprintf( stderr, "cannot construct path to pluginapp.bin\n" );
+ m_nCommPID = -1;
+ return;
+ }
+
+ char const* pArgs[5];
+ pArgs[0] = path.getStr();
+ pArgs[1] = pDesc;
+ pArgs[2] = aLib.GetBuffer();
+ pArgs[3] = pWindow;
+ pArgs[4] = NULL;
+
+#if OSL_DEBUG_LEVEL > 1
+ m_nCommPID = 10;
+ fprintf( stderr, "Try to launch: %s %s %s %s, descriptors are %d, %d\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3], nDescriptor1, nDescriptor2 );
+#endif
+
+ if( ! ( m_nCommPID = fork() ) )
+ {
+ execvp( pArgs[0], const_cast< char ** >(pArgs) );
+ fprintf( stderr, "Error: could not exec %s\n", pArgs[0] );
+ _exit(255);
+ }
+
+ if( m_nCommPID != -1 )
+ {
+ // wait for pluginapp.bin to start up
+ if( ! WaitForMessage( 5000 ) )
+ {
+ fprintf( stderr, "Timeout on command: %s %s %s %s\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3] );
+ invalidate();
+ }
+ else
+ {
+ MediatorMessage* pMessage = GetNextMessage( sal_True );
+ Respond( pMessage->m_nID,
+ const_cast<char*>("init ack"),8,
+ NULL );
+ delete pMessage;
+ NPP_Initialize();
+ }
+ }
+}
+
+UnxPluginComm::~UnxPluginComm()
+{
+ NPP_Shutdown();
+ if( m_nCommPID != -1 && m_nCommPID != 0 )
+ {
+ int status = 16777216;
+ pid_t nExit = waitpid( m_nCommPID, &status, WUNTRACED );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "child %d (plugin app child %d) exited with status %d\n", nExit, m_nCommPID, WEXITSTATUS(status) );
+#else
+ (void)nExit;
+#endif
+ }
+}
+
+bool UnxPluginComm::getPluginappPath(rtl::OString * path) {
+ OSL_ASSERT(path != NULL);
+ rtl::OUString p(
+ RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/pluginapp.bin"));
+ rtl::Bootstrap::expandMacros(p);
+ return
+ (osl::FileBase::getSystemPathFromFileURL(p, p) ==
+ osl::FileBase::E_None) &&
+ p.convertToString(
+ path, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR));
+}
diff --git a/extensions/source/plugin/unx/unxmgr.cxx b/extensions/source/plugin/unx/unxmgr.cxx
new file mode 100644
index 000000000000..5c02910ada33
--- /dev/null
+++ b/extensions/source/plugin/unx/unxmgr.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+#include <cstdarg>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <osl/thread.h>
+#include <rtl/strbuf.hxx>
+#include <tools/appendunixshellword.hxx>
+
+#include <vcl/svapp.hxx>
+#include <plugin/impl.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 )
+{
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "Trying plugin %s ... ", rPath.GetBuffer() );
+#endif
+
+ xub_StrLen nPos = rPath.SearchBackward( '/' );
+ if( nPos == STRING_NOTFOUND )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "no absolute path to plugin\n" );
+#endif
+ return false;
+ }
+
+ ByteString aBaseName = rPath.Copy( nPos+1 );
+ if( aBaseName.Equals( "libnullplugin.so" ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "don't like %s\n", aBaseName.GetBuffer() );
+#endif
+ return false;
+ }
+
+ struct stat aStat;
+ if( stat( rPath.GetBuffer(), &aStat ) || ! S_ISREG( aStat.st_mode ) )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "%s is not a regular file\n", rPath.GetBuffer() );
+#endif
+ return false;
+ }
+
+
+ rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
+
+ rtl::OString path;
+ if (!UnxPluginComm::getPluginappPath(&path)) {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "cannot construct path to pluginapp.bin\n" );
+#endif
+ return false;
+ }
+ rtl::OStringBuffer cmd;
+ tools::appendUnixShellWord(&cmd, path);
+ cmd.append(' ');
+ tools::appendUnixShellWord(&cmd, rPath);
+ rtl::OString aCommand(cmd.makeStringAndClear());
+
+ FILE* pResult = popen( aCommand.getStr(), "r" );
+ int nDescriptions = 0;
+ if( pResult )
+ {
+ OStringBuffer aMIME;
+ char buf[256];
+ while( fgets( buf, sizeof( buf ), pResult ) )
+ {
+ for( size_t i = 0; i < sizeof(buf) && buf[i]; ++i )
+ {
+ if( buf[i] == '\n' )
+ buf[i] = ';';
+ }
+ aMIME.append( buf );
+ }
+ pclose( pResult );
+
+ if( aMIME.getLength() > 0 )
+ {
+ OString aLine = aMIME.makeStringAndClear();
+
+ sal_Int32 nIndex = 0;
+ while( nIndex != -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( ';' );
+ }
+
+ 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
+ }
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ fprintf( stderr, "result of \"%s\" contains no mimtype\n",
+ aCommand.getStr() );
+#endif
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ fprintf( stderr, "command \"%s\" failed\n", aCommand.getStr() );
+#endif
+ return nDescriptions > 0;
+}
+
+union maxDirent
+{
+ char aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ];
+ struct dirent asDirent;
+};
+
+static void CheckPluginRegistryFiles( const rtl::OString& rPath, list< PluginDescription* >& rDescriptions )
+{
+ rtl::OStringBuffer aPath( 1024 );
+ aPath.append( rPath );
+ aPath.append( "/pluginreg.dat" );
+ FILE* fp = fopen( aPath.getStr(), "r" );
+ if( fp )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "parsing %s\n", aPath.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 ), rDescriptions );
+ }
+ fclose( fp );
+ }
+
+ // check subdirectories
+ DIR* pDIR = opendir( rPath.getStr() );
+ struct dirent* pDirEnt = NULL;
+ struct stat aStat;
+ maxDirent u;
+ while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
+ {
+ char* pBaseName = u.asDirent.d_name;
+ if( rtl_str_compare( ".", pBaseName ) && rtl_str_compare( "..", pBaseName ) )
+ {
+ rtl::OStringBuffer aBuf( 1024 );
+ aBuf.append( rPath );
+ aBuf.append( '/' );
+ aBuf.append( pBaseName );
+
+ if( ! stat( aBuf.getStr(), &aStat ) )
+ {
+ if( S_ISDIR( aStat.st_mode ) )
+ CheckPluginRegistryFiles( aBuf.makeStringAndClear(), rDescriptions );
+ }
+ }
+ }
+ if( pDIR )
+ closedir( pDIR );
+}
+
+Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw()
+{
+ static Sequence<PluginDescription> aDescriptions;
+ static sal_Bool bHavePlugins = sal_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";
+ }
+ if( pNPXPluginPath )
+ {
+ aSearchPath.Append( ':' );
+ aSearchPath += pNPXPluginPath;
+ }
+
+ const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
+ for( i = 0; i < rPaths.getLength(); i++ )
+ {
+ aSearchPath += ":";
+ aSearchPath += ByteString( String( rPaths.getConstArray()[i] ), aEncoding );
+ }
+
+ int nPaths = aSearchPath.GetTokenCount( ':' );
+ maxDirent u;
+ for( i = 0; i < nPaths; i++ )
+ {
+ ByteString aPath( aSearchPath.GetToken( i, ':' ) );
+ if( aPath.Len() )
+ {
+ DIR* pDIR = opendir( aPath.GetBuffer() );
+ struct dirent* pDirEnt = NULL;
+ while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
+ {
+ char* pBaseName = u.asDirent.d_name;
+ if( pBaseName[0] != '.' ||
+ pBaseName[1] != '.' ||
+ pBaseName[2] != 0 )
+ {
+ ByteString aFileName( aPath );
+ aFileName += "/";
+ aFileName += pBaseName;
+ CheckPlugin( aFileName, aPlugins );
+ }
+ }
+ if( pDIR )
+ closedir( pDIR );
+ }
+ }
+
+ // try ~/.mozilla/pluginreg.dat
+ rtl::OStringBuffer aBuf(256);
+ aBuf.append( pHome );
+ aBuf.append( "/.mozilla" );
+ CheckPluginRegistryFiles( aBuf.makeStringAndClear(), aPlugins );
+
+ // create return value
+ aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "found %d plugins\n", aPlugins.size() );
+#endif
+ list<PluginDescription*>::iterator iter;
+ for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ )
+ {
+ aDescriptions.getArray()[ i ] = **iter;
+ delete *iter;
+ }
+ aPlugins.clear();
+ bHavePlugins = sal_True;
+ }
+ return aDescriptions;
+}
diff --git a/extensions/source/plugin/util/makefile.mk b/extensions/source/plugin/util/makefile.mk
new file mode 100644
index 000000000000..765941689658
--- /dev/null
+++ b/extensions/source/plugin/util/makefile.mk
@@ -0,0 +1,117 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..$/..
+
+PRJNAME=extensions
+TARGET=pl
+TARGETTYPE=GUI
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(WITH_MOZILLA)" != "NO"
+
+LIB1TARGET = $(SLB)$/plall.lib
+LIB1FILES = \
+ $(SLB)$/plbase.lib \
+ $(SHL1LINKLIB)
+
+.IF "$(GUI)" == "UNX"
+.IF "$(GUIBASE)"=="aqua"
+.IF "$(WITH_MOZILLA)"=="YES"
+SHL1LINKLIB = $(SLB)$/plaqua.lib
+.ENDIF
+.ELSE
+SHL1LINKLIB = $(SLB)$/plunx.lib
+.ENDIF # $(GUIBASE)==aqua
+.IF "$(OS)" == "SOLARIS"
+SHL1OWNLIBS = -lsocket
+.ENDIF # SOLARIS
+.ENDIF # UNX
+
+.IF "$(GUI)" == "WNT"
+SHL1LINKLIB = $(SLB)$/plwin.lib
+SHL1OWNLIBS = \
+ $(VERSIONLIB) \
+ $(OLE32LIB) \
+ $(ADVAPI32LIB)
+.ENDIF # WNT
+
+SHL1TARGET= $(TARGET)$(DLLPOSTFIX)
+SHL1IMPLIB= i$(TARGET)
+
+SHL1VERSIONMAP=$(SOLARENV)/src/component.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+SHL1LIBS=$(LIB1TARGET)
+
+.IF "$(OS)"=="MACOSX"
+SHL1STDLIBS= \
+ $(LIBSTLPORT) \
+ $(TKLIB)
+.ELSE
+SHL1STDLIBS= \
+ $(TKLIB)
+.ENDIF
+
+SHL1STDLIBS+= \
+ $(VCLLIB) \
+ $(SVLLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(VOSLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.IF "$(GUIBASE)"=="unx"
+SHL1STDLIBS+=$(X11LINK_DYNAMIC)
+.ENDIF
+
+SHL1STDLIBS+=$(SHL1OWNLIBS)
+
+.ENDIF # $(WITH_MOZILLA) != "NO"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
+
+
+ALLTAR : $(MISC)/pl.component
+
+$(MISC)/pl.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ pl.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt pl.component
diff --git a/extensions/source/plugin/util/makefile.pmk b/extensions/source/plugin/util/makefile.pmk
new file mode 100644
index 000000000000..0f06ea2a50ce
--- /dev/null
+++ b/extensions/source/plugin/util/makefile.pmk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+NOUNODOC=true
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_MOZILLA)" == "YES"
+CFLAGS+=-DSYSTEM_MOZILLA
+PKGCONFIG_MODULES+=$(MOZ_FLAVOUR)-plugin
+.ENDIF
+
+.IF "$(GUIBASE)" == "unx" && "$(ENABLE_GTK)" == "TRUE"
+CDEFS+=-DENABLE_GTK
+PKGCONFIG_MODULES+=gtk+-2.0 gthread-2.0
+.ENDIF
+
+.IF "$(GUIBASE)" == "aqua"
+CFLAGS += -I$(FRAMEWORKSHOME)/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers\
+ -I$(FRAMEWORKSHOME)/Carbon.framework/Versions/Current/Frameworks/HIToolbox.framework/Versions/Current/Headers
+.ENDIF
+
+.IF "$(PKGCONFIG_MODULES)" != ""
+.INCLUDE : pkg_config.mk
+.ENDIF
diff --git a/extensions/source/plugin/util/pl.component b/extensions/source/plugin/util/pl.component
new file mode 100644
index 000000000000..4a9d98f7dc7b
--- /dev/null
+++ b/extensions/source/plugin/util/pl.component
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.extensions.PluginManager">
+ <service name="com.sun.star.plugin.PluginManager"/>
+ </implementation>
+ <implementation name="com.sun.star.extensions.PluginModel">
+ <service name="com.sun.star.plugin.PluginModel"/>
+ </implementation>
+</component>
diff --git a/extensions/source/plugin/win/makefile.mk b/extensions/source/plugin/win/makefile.mk
new file mode 100644
index 000000000000..3167c22d135d
--- /dev/null
+++ b/extensions/source/plugin/win/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=extensions
+TARGET=plwin
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+.IF "$(GUI)" == "WNT"
+
+.INCLUDE : ..$/util$/makefile.pmk
+
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/plugin
+.IF "$(SOLAR_JAVA)" != ""
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/java
+INCPRE+=-I$(SOLARINCDIR)$/mozilla$/nspr
+CDEFS+=-DOJI
+.ENDIF
+
+# --- Types -------------------------------------
+
+.IF "$(WITH_MOZILLA)" != "NO"
+
+#UNOUCROUT=$(OUT)$/inc$/$(PRJNAME)
+#INCPRE+=$(UNOUCROUT)
+
+# --- Types -------------------------------------
+
+SLOFILES = $(SLO)$/winmgr.obj \
+ $(SLO)$/sysplug.obj
+
+.ENDIF # $(WITH_MOZILLA) != "NO"
+.ENDIF
+
+# ------------------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
diff --git a/extensions/source/plugin/win/sysplug.cxx b/extensions/source/plugin/win/sysplug.cxx
new file mode 100644
index 000000000000..1d117f6927d5
--- /dev/null
+++ b/extensions/source/plugin/win/sysplug.cxx
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include <plugin/impl.hxx>
+
+#pragma warning (push,1)
+#pragma warning (disable:4005)
+
+ #include <tools/prewin.h>
+
+ #include <windows.h>
+ #include <string.h>
+ #include <tchar.h>
+ #include <winreg.h>
+ #include <winbase.h>
+ #include <objbase.h>
+
+ #include <tools/postwin.h>
+
+#pragma warning (pop)
+
+#include <list>
+#include <map>
+#include <algorithm>
+
+
+extern NPNetscapeFuncs aNPNFuncs;
+
+#include <tools/debug.hxx>
+
+using namespace rtl;
+
+#if OSL_DEBUG_LEVEL > 1
+void TRACE( char const * s );
+void TRACEN( char const * s, long n );
+#else
+#define TRACE(x)
+#define TRACEN(x,n)
+#endif
+
+
+//--------------------------------------------------------------------------------------------------
+PluginComm_Impl::PluginComm_Impl( const OUString& /*rMIME*/, const OUString& rName, HWND /*hWnd*/ )
+ : PluginComm( OUStringToOString( rName, RTL_TEXTENCODING_MS_1252 ) )
+{
+ // initialize plugin function table
+ memset( &_NPPfuncs, 0, sizeof( _NPPfuncs ) );
+#ifdef UNICODE
+ _plDLL = ::LoadLibrary( rName.getStr() );
+#else
+ OString aStr( OUStringToOString( rName, RTL_TEXTENCODING_MS_1252 ) );
+ _plDLL = ::LoadLibrary( aStr.getStr() );
+#endif
+ DBG_ASSERT( _plDLL, "### loading plugin dll failed!" );
+
+ NPError nErr = NPERR_NO_ERROR;
+ NPError (WINAPI * pEntry)( NPPluginFuncs* );
+ retrieveFunction( _T("NP_GetEntryPoints"), (void**)&pEntry );
+
+ _NPPfuncs.size = sizeof( _NPPfuncs );
+ _NPPfuncs.version = 0;
+ nErr = (*pEntry)( &_NPPfuncs );
+
+ DBG_ASSERT( nErr == NPERR_NO_ERROR, "### NP_GetEntryPoints() failed!" );
+ DBG_ASSERT( (_NPPfuncs.version >> 8) >= NP_VERSION_MAJOR,
+ "### version failure!" );
+
+ m_eCall = eNP_Initialize;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+PluginComm_Impl::~PluginComm_Impl()
+{
+ if (_plDLL)
+ {
+// NPP_Shutdown();
+
+ NPError (WINAPI * pShutdown)();
+ if (retrieveFunction( _T("NP_Shutdown"), (void**)&pShutdown ))
+ {
+ NPError nErr = (*pShutdown)(); (void)nErr;
+ DBG_ASSERT( nErr == NPERR_NO_ERROR, "### NP_Shutdown() failed!" );
+ }
+
+ BOOL bRet = (BOOL)::FreeLibrary( _plDLL ); (void)bRet;
+ DBG_ASSERT( bRet, "### unloading plugin dll failed!" );
+ _plDLL = NULL;
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+BOOL PluginComm_Impl::retrieveFunction( TCHAR* pName, void** ppFunc ) const
+{
+ if( ! _plDLL )
+ return FALSE;
+
+ *ppFunc = (void*)::GetProcAddress( _plDLL, pName );
+
+ return (*ppFunc != NULL);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+long PluginComm_Impl::doIt()
+{
+ long nRet = 0;
+ switch( m_eCall )
+ {
+ case eNP_Initialize:
+ {
+ TRACE( "eNP_Initialize" );
+ NPError (WINAPI * pInit)( NPNetscapeFuncs* );
+ if ((_NPPfuncs.version >> 8) >= NP_VERSION_MAJOR &&
+ (retrieveFunction( _T("NP_Initialize"), (void**)&pInit ) ||
+ retrieveFunction( _T("NP_PluginInit"), (void**)&pInit )))
+ {
+ nRet = (*pInit)( &aNPNFuncs );
+ }
+ else
+ {
+ nRet = NPERR_GENERIC_ERROR;
+ }
+ DBG_ASSERT( nRet == NPERR_NO_ERROR, "### NP_Initialize() failed!" );
+ }
+ break;
+ case eNPP_Destroy:
+ TRACE( "eNPP_Destroy" );
+ nRet = (_NPPfuncs.destroy
+ ? (*_NPPfuncs.destroy)(
+ (NPP)m_aArgs[0],
+ (NPSavedData**)m_aArgs[1] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_DestroyStream:
+ TRACE( "eNPP_DestroyStream" );
+ nRet = (_NPPfuncs.destroystream
+ ? (*_NPPfuncs.destroystream)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (NPError)(sal_IntPtr)m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_New:
+ TRACE( "eNPP_New" );
+ nRet = (_NPPfuncs.newp
+ ? (*_NPPfuncs.newp)(
+ (NPMIMEType)m_aArgs[0],
+ (NPP)m_aArgs[1],
+ (uint16)(sal_IntPtr)m_aArgs[2],
+ (int16)(sal_IntPtr)m_aArgs[3],
+ (char**)m_aArgs[4],
+ (char**)m_aArgs[5],
+ (NPSavedData*)m_aArgs[6] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_NewStream:
+ TRACE( "eNPP_NewStream" );
+ nRet = (_NPPfuncs.newstream
+ ? (*_NPPfuncs.newstream)(
+ (NPP)m_aArgs[0],
+ (NPMIMEType)m_aArgs[1],
+ (NPStream*)m_aArgs[2],
+ (NPBool)(sal_IntPtr)m_aArgs[3],
+ (uint16*)m_aArgs[4] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_Print:
+ TRACE( "eNPP_Print" );
+ if (_NPPfuncs.print)
+ (*_NPPfuncs.print)(
+ (NPP)m_aArgs[0],
+ (NPPrint*)m_aArgs[1] );
+ break;
+ case eNPP_SetWindow:
+ {
+ TRACE( "eNPP_SetWindow" );
+ nRet = (_NPPfuncs.setwindow
+ ? (*_NPPfuncs.setwindow)(
+ (NPP)m_aArgs[0],
+ (NPWindow*)m_aArgs[1] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ }
+ case eNPP_StreamAsFile:
+ TRACE( "eNPP_StreamAsFile" );
+ if (_NPPfuncs.asfile)
+ (*_NPPfuncs.asfile)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (char*)m_aArgs[2] );
+ break;
+ case eNPP_URLNotify:
+ TRACE( "eNPP_URLNotify" );
+ if (_NPPfuncs.urlnotify)
+ (*_NPPfuncs.urlnotify)(
+ (NPP)m_aArgs[0],
+ (char*)m_aArgs[1],
+ (NPReason)(sal_IntPtr)m_aArgs[2],
+ m_aArgs[3] );
+ break;
+ case eNPP_Write:
+ TRACEN( "eNPP_Write n=", (int32)m_aArgs[3] );
+ nRet = (_NPPfuncs.write
+ ? (*_NPPfuncs.write)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1],
+ (int32)m_aArgs[2],
+ (int32)m_aArgs[3],
+ m_aArgs[4] )
+ : 0);
+ break;
+ case eNPP_WriteReady:
+ TRACE( "eNPP_WriteReady" );
+ nRet = (_NPPfuncs.writeready
+ ? (*_NPPfuncs.writeready)(
+ (NPP)m_aArgs[0],
+ (NPStream*)m_aArgs[1] )
+ : 0);
+ break;
+ case eNPP_GetValue:
+ TRACE( "eNPP_GetValue" );
+ nRet = (_NPPfuncs.getvalue
+ ? (*_NPPfuncs.getvalue)(
+ (NPP)m_aArgs[0],
+ (NPPVariable)(int)m_aArgs[1],
+ m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_SetValue:
+ TRACE( "eNPP_SetValue" );
+ nRet = (_NPPfuncs.setvalue
+ ? (*_NPPfuncs.setvalue)(
+ (NPP)m_aArgs[0],
+ (NPNVariable)(int)m_aArgs[1],
+ m_aArgs[2] )
+ : NPERR_GENERIC_ERROR);
+ break;
+ case eNPP_Shutdown:
+ {
+ TRACE( "eNPP_Shutdown" );
+ NPP_ShutdownUPP pFunc;
+ if (retrieveFunction( _T("NPP_Shutdown"), (void**)&pFunc ))
+ (*pFunc)();
+ }
+ break;
+ case eNPP_Initialize:
+ TRACE( "eNPP_Initialize" );
+ OSL_ENSURE( false, "NPP_Initialize: not implemented!" );
+ break;
+ case eNPP_GetJavaClass:
+ TRACE( "eNPP_GetJavaClass" );
+ OSL_ENSURE( false, "NPP_GetJavaClass: not implemented!" );
+ break;
+ }
+ return nRet;
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_Destroy( NPP instance, NPSavedData** save )
+{
+ DBG_ASSERT( _NPPfuncs.destroy, "### NPP_Destroy(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Destroy;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)save;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_DestroyStream( NPP instance, NPStream* stream, NPError reason )
+{
+ DBG_ASSERT( _NPPfuncs.destroystream, "### NPP_DestroyStream(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_DestroyStream;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)reason;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_New( NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
+ char* argn[], char* argv[], NPSavedData *saved )
+{
+ DBG_ASSERT( _NPPfuncs.newp, "### NPP_New(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_New;
+ m_aArgs[0] = (void*)pluginType;
+ m_aArgs[1] = (void*)instance;
+ m_aArgs[2] = (void*)mode;
+ m_aArgs[3] = (void*)argc;
+ m_aArgs[4] = (void*)argn;
+ m_aArgs[5] = (void*)argv;
+ m_aArgs[6] = (void*)saved;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream,
+ NPBool seekable, uint16* stype )
+{
+ DBG_ASSERT( _NPPfuncs.newstream, "### NPP_NewStream(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_NewStream;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)type;
+ m_aArgs[2] = (void*)stream;
+ m_aArgs[3] = (void*)seekable;
+ m_aArgs[4] = (void*)stype;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void PluginComm_Impl::NPP_Print( NPP instance, NPPrint* platformPrint )
+{
+ DBG_ASSERT( _NPPfuncs.print, "### NPP_Print(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Print;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)platformPrint;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_SetWindow( NPP instance, NPWindow* window )
+{
+ DBG_ASSERT( _NPPfuncs.setwindow, "### NPP_SetWindow(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_SetWindow;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)window;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void PluginComm_Impl::NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
+{
+ DBG_ASSERT( _NPPfuncs.asfile, "### NPP_StreamAsFile(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_StreamAsFile;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)fname;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void PluginComm_Impl::NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
+{
+ DBG_ASSERT( _NPPfuncs.urlnotify, "### NPP_URLNotify(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_URLNotify;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)url;
+ m_aArgs[2] = (void*)reason;
+ m_aArgs[3] = notifyData;
+ execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+int32 PluginComm_Impl::NPP_Write( NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer )
+{
+ DBG_ASSERT( _NPPfuncs.write, "### NPP_Write(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_Write;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ m_aArgs[2] = (void*)offset;
+ m_aArgs[3] = (void*)len;
+ m_aArgs[4] = buffer;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+int32 PluginComm_Impl::NPP_WriteReady( NPP instance, NPStream* stream )
+{
+ DBG_ASSERT( _NPPfuncs.writeready, "### NPP_WriteReady(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_WriteReady;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)stream;
+ return execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_GetValue( NPP instance, NPPVariable variable, void *ret_value )
+{
+ DBG_ASSERT( _NPPfuncs.getvalue, "### NPP_GetValue(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_GetValue;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)variable;
+ m_aArgs[2] = ret_value;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_SetValue( NPP instance, NPNVariable variable, void *set_value )
+{
+ DBG_ASSERT( _NPPfuncs.setvalue, "### NPP_SetValue(): null pointer in NPP functions table!" );
+ m_eCall = eNPP_SetValue;
+ m_aArgs[0] = (void*)instance;
+ m_aArgs[1] = (void*)variable;
+ m_aArgs[2] = set_value;
+ return (NPError)execute();
+}
+
+//--------------------------------------------------------------------------------------------------
+void * PluginComm_Impl::NPP_GetJavaClass()
+{
+ DBG_ERROR( "no java class available!" );
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------------------
+NPError PluginComm_Impl::NPP_Initialize()
+{
+ return NPERR_NO_ERROR;
+}
+
+//--------------------------------------------------------------------------------------------------
+void PluginComm_Impl::NPP_Shutdown()
+{
+ m_eCall = eNPP_Shutdown;
+ execute();
+}
diff --git a/extensions/source/plugin/win/winmgr.cxx b/extensions/source/plugin/win/winmgr.cxx
new file mode 100644
index 000000000000..e4a9d9732c24
--- /dev/null
+++ b/extensions/source/plugin/win/winmgr.cxx
@@ -0,0 +1,470 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_extensions.hxx"
+
+#include "vcl/svapp.hxx"
+#include "tools/fsys.hxx"
+#include "tools/urlobj.hxx"
+#include "osl/mutex.hxx"
+
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "plugin/impl.hxx"
+
+#pragma warning (push,1)
+#pragma warning (disable:4005)
+
+ #include "tools/prewin.h"
+
+ #include <windows.h>
+ #include <string.h>
+ #include <tchar.h>
+ #include <winreg.h>
+ #include <winbase.h>
+ #include <objbase.h>
+
+ #include "tools/postwin.h"
+
+#pragma warning (pop)
+
+#include <list>
+#include <map>
+#include <algorithm>
+
+
+using namespace rtl;
+using namespace std;
+using namespace osl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::plugin;
+
+typedef map< OString, OUString, less< OString > > PluginLocationMap;
+
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+
+static void logPlugin( OUString const & path_ )
+{
+ static FILE * s_file = 0;
+ if (! s_file)
+ s_file = fopen( "d:\\plugins.log", "a+" );
+ OString path( OUStringToOString( path_, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( s_file, "%s\n", path.getStr() );
+}
+#endif
+
+//__________________________________________________________________________________________________
+static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
+{
+ // append dll name pattern we are looking for
+ TCHAR arPluginsPath[MAX_PATH];
+ arPluginsPath[0] = 0;
+
+ if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
+ {
+ const char * p = ::getenv( "ProgramFiles" );
+ if (p)
+ {
+ ::lstrcpy( arPluginsPath, p );
+ pPluginsPath += 14;
+ }
+ }
+ ::lstrcat( arPluginsPath, pPluginsPath );
+ ::lstrcat( arPluginsPath, _T("\\") );
+
+ TCHAR arPluginsPattern[MAX_PATH];
+ ::lstrcpy( arPluginsPattern, arPluginsPath );
+ ::lstrcat( arPluginsPattern, _T("NP*.DLL") );
+
+ WIN32_FIND_DATA aFindData;
+ HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );
+
+ while (hFind != INVALID_HANDLE_VALUE)
+ {
+ OString aName( aFindData.cFileName );
+ aName.toAsciiLowerCase();
+
+ // no netscape default plugin anymore...
+ // and no double plugin dlls
+ if ( !aName.equals( "npnul32.dll" ) &&
+ ! aName.equals( "npnrvp.dll" ) &&
+ rPlugins.find( aName ) == rPlugins.end())
+ {
+ TCHAR arComplete[MAX_PATH];
+ ::lstrcpy( arComplete, arPluginsPath );
+ ::lstrcat( arComplete, aFindData.cFileName );
+
+ OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
+ rPlugins[ aName ] = path;
+#if OSL_DEBUG_LEVEL > 1
+ logPlugin( path );
+#endif
+ }
+
+ if (! ::FindNextFile( hFind, &aFindData ))
+ break;
+ }
+
+ if (hFind != INVALID_HANDLE_VALUE)
+ ::FindClose( hFind );
+}
+//__________________________________________________________________________________________________
+static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
+{
+ TCHAR arPluginsPath[MAX_PATH];
+ DWORD dwPluginsPathSize = sizeof(arPluginsPath);
+ arPluginsPath[dwPluginsPathSize-1] = 0;
+
+ OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
+ ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );
+
+ addPluginsFromPath( arPluginsPath, rPlugins );
+}
+
+
+//__________________________________________________________________________________________________
+static void add_IE_Plugins( PluginLocationMap & rPlugins )
+{
+ HKEY hKey;
+ TCHAR arCurrent[MAX_PATH];
+ DWORD dwType, dwCurrentSize = sizeof(arCurrent);
+
+ if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
+ 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
+ {
+ if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
+ (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
+ (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
+ {
+ // add \\Plugins
+ ::lstrcat( arCurrent, _T("\\Plugins") );
+
+ addPluginsFromPath( arCurrent, rPlugins );
+ }
+ ::RegCloseKey( hKey );
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
+{
+ TCHAR value[MAX_PATH];
+ DWORD dwType, size = sizeof(value);
+
+ // 4.7
+ size = sizeof(value);
+ if (::RegQueryValueEx(
+ hKey, _T("Plugins Directory"), NULL, &dwType,
+ (LPBYTE)value, &size ) == ERROR_SUCCESS &&
+ (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
+ {
+ addPluginsFromPath( value, rPlugins );
+ }
+ // 6
+ size = sizeof(value);
+ if (::RegQueryValueEx(
+ hKey, _T("Install Directory"), NULL, &dwType,
+ (LPBYTE)value, &size ) == ERROR_SUCCESS &&
+ (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
+ {
+ int n = size / sizeof (TCHAR);
+ if ('\\' != value[ n -2 ])
+ {
+ value[ n -1 ] = '\\';
+ value[ n ] = 0;
+ }
+ addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
+ }
+ size = sizeof(value);
+ if (::RegQueryValueEx(
+ hKey, _T("Plugins"), NULL, &dwType,
+ (LPBYTE)value, &size ) == ERROR_SUCCESS &&
+ (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
+ {
+ addPluginsFromPath( value, rPlugins );
+ }
+}
+//--------------------------------------------------------------------------------------------------
+static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
+{
+ add_NS_keys( hKey, rPlugins );
+
+ TCHAR keyName[MAX_PATH];
+ DWORD dwIndex = 0, size = sizeof (keyName);
+
+ while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
+ {
+ size = sizeof (keyName);
+ HKEY hSubKey;
+ if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
+ {
+ add_NS_lookupRecursive( hSubKey, rPlugins );
+ ::RegCloseKey( hSubKey );
+ }
+ ++dwIndex;
+ }
+}
+//__________________________________________________________________________________________________
+static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
+{
+ TCHAR value[MAX_PATH];
+ DWORD dwType, size = sizeof(value);
+
+ size = sizeof(value);
+ if (::RegQueryValueEx(
+ hKey, _T("Path"), NULL, &dwType,
+ (LPBYTE)value, &size ) == ERROR_SUCCESS &&
+ (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
+ {
+ OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
+ INetURLObject aURL( aUPath );
+ OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );
+
+ // no netscape default plugin anymore...
+ // and no double plugin dlls
+ if ( !aName.equals( "npnul32.dll" ) &&
+ ! aName.equals( "npnrvp.dll" ) &&
+ rPlugins.find( aName ) == rPlugins.end())
+ {
+ rPlugins[ aName ] = aUPath;
+#if OSL_DEBUG_LEVEL > 1
+ logPlugin( aUPath );
+#endif
+ }
+ }
+}
+static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
+{
+ TCHAR keyName[MAX_PATH];
+ DWORD dwIndex = 0, size = sizeof (keyName);
+
+ while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
+ {
+ size = sizeof (keyName);
+ HKEY hSubKey;
+ if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
+ {
+ add_MozPlugin( hSubKey, rPlugins );
+ ::RegCloseKey( hSubKey );
+ }
+ ++dwIndex;
+ }
+}
+//__________________________________________________________________________________________________
+static void add_NS_Plugins( PluginLocationMap & rPlugins )
+{
+ HKEY hKey;
+ // Netscape
+ if (::RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
+ 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
+ {
+ add_NS_lookupRecursive( hKey, rPlugins );
+ ::RegCloseKey( hKey );
+ }
+ // Mozilla
+ if (::RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
+ 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
+ {
+ add_NS_lookupRecursive( hKey, rPlugins );
+ ::RegCloseKey( hKey );
+ }
+ // Mozilla - plugins
+ if (::RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
+ 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
+ {
+ add_MozillaPlugin( hKey, rPlugins );
+ ::RegCloseKey( hKey );
+ }
+}
+
+//__________________________________________________________________________________________________
+static void add_SO_Plugins( PluginLocationMap & rPlugins )
+{
+ const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();
+
+ const OUString * pPaths = rPaths.getConstArray();
+ for ( UINT32 nPos = rPaths.getLength(); nPos--; )
+ {
+ addPluginsFromPath( pPaths[nPos], rPlugins );
+ }
+}
+
+//__________________________________________________________________________________________________
+Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
+{
+ Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
+ static Sequence<PluginDescription > s_aDescriptions( 0 );
+ static bool s_bInit = FALSE;
+
+ if (! s_bInit)
+ {
+ // collect all distinct plugin dlls
+ PluginLocationMap aPlugins;
+ add_SO_Plugins( aPlugins );
+ add_NS_Plugins( aPlugins );
+ add_IE_Plugins( aPlugins );
+
+ // collect mime types of plugin dlls
+ for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
+ iPos != aPlugins.end();
+ ++iPos )
+ {
+ TCHAR arFileName[MAX_PATH];
+ DWORD dwDummy, dwSize;
+
+ // DLL name
+ OUString aName( (*iPos).second.getStr() );
+
+ OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
+ ::strcpy( arFileName, aStr.getStr() );
+ dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );
+
+ if ( !dwSize )
+ continue;
+
+ char * pVersionData = new char[dwSize];
+ if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
+ {
+ // optional comment
+ OUString aComment;
+
+ TCHAR * pInfo = NULL, * pInfo2 = NULL;
+ UINT nSize = 0;
+ if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
+ (void**)&pInfo, &nSize ) && pInfo)
+ {
+ aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
+ }
+
+ // mandatory mime type and file extensions
+ if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
+ (void**)&pInfo, &nSize ) && pInfo &&
+ ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
+ (void**)&pInfo2, &nSize ) && pInfo2)
+ {
+ OString aStr2( pInfo2 );
+ OString aExt( aStr2 );
+ OString aStr( pInfo );
+ OString aMIME( aStr );
+ aMIME.trim();
+
+ // count mime tokens
+ USHORT nToken = 0;
+ if (aMIME.getLength())
+ {
+ ++nToken;
+ for ( sal_Int32 n = aMIME.getLength(); n--; )
+ {
+ if (aMIME[ n ] == '|')
+ {
+ ++nToken;
+ }
+ }
+ }
+ sal_Int32 nIndex = 0, nIndex2 = 0;
+
+ UINT32 nStart = s_aDescriptions.getLength();
+ s_aDescriptions.realloc( nStart + nToken );
+ PluginDescription* pDescriptions = s_aDescriptions.getArray();
+ // for every MIME Type
+ sal_Int32 nTok = 0;
+ while (true)
+ {
+ if (nIndex < 0 || nIndex2 < 0)
+ break;
+
+ PluginDescription & rDescr = pDescriptions[nStart+nTok];
+ OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
+ OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
+ if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
+ continue;
+
+ rDescr.Mimetype = OUString(
+ aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
+ if (! rDescr.Mimetype.getLength())
+ break;
+
+ OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
+ rDescr.PluginName = aName;
+ rDescr.Description = aComment;
+
+ sal_Int32 nPos = 0, nLen = aExtToken.getLength();
+ OUString aExtensions( OUString::createFromAscii( nLen ? "*." : "*.*" ) );
+
+ for ( ; nPos < nLen; ++nPos )
+ {
+ sal_Unicode c = aExtToken[nPos];
+ switch (c)
+ {
+ case ',':
+ case ';':
+ aExtensions += OUString::createFromAscii( ";*." );
+ case ' ':
+ break;
+ case '*':
+ if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
+ {
+ ++nPos;
+ break;
+ }
+ default:
+ aExtensions += OUString( &c, 1 );
+ }
+ }
+ rDescr.Extension = aExtensions;
+
+ ++nTok;
+ }
+
+ if (nToken != nTok)
+ {
+ s_aDescriptions.realloc( nTok );
+ }
+ }
+#if OSL_DEBUG_LEVEL > 1
+ else
+ DBG_ERROR( "### cannot get MIME type or extensions!" );
+#endif
+ }
+ if (pVersionData)
+ delete[] pVersionData;
+ }
+
+ s_bInit = TRUE;
+ }
+ return s_aDescriptions;
+}
+
+