blob: 2aa1f18fafc4ab94b5216d40f4ef007e6aef064c [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
// INCLUDE ---------------------------------------------------------------
#include <vcl/svapp.hxx>
#include <osl/module.hxx>
#include <osl/file.hxx>
#include <unotools/transliterationwrapper.hxx>
#include "callform.hxx"
#include "global.hxx"
#include "adiasync.hxx"
//------------------------------------------------------------------------
extern "C" {
typedef void (CALLTYPE* ExFuncPtr1)(void*);
typedef void (CALLTYPE* ExFuncPtr2)(void*, void*);
typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (CALLTYPE* GetFuncCountPtr)(sal_uInt16& nCount);
typedef void (CALLTYPE* GetFuncDataPtr)
(sal_uInt16& nNo, sal_Char* pFuncName, sal_uInt16& nParamCount, ParamType* peType, sal_Char* pInternalName);
typedef void (CALLTYPE* SetLanguagePtr)( sal_uInt16& nLanguage );
typedef void (CALLTYPE* GetParamDesc)
(sal_uInt16& nNo, sal_uInt16& nParam, sal_Char* pName, sal_Char* pDesc );
typedef void (CALLTYPE* IsAsync) ( sal_uInt16& nNo,
ParamType* peType );
typedef void (CALLTYPE* Advice) ( sal_uInt16& nNo,
AdvData& pfCallback );
typedef void (CALLTYPE* Unadvice)( double& nHandle );
typedef void (CALLTYPE* FARPROC) ( void );
}
#if defined(OS2) && defined(BLC)
#define GETFUNCTIONCOUNT "_GetFunctionCount"
#define GETFUNCTIONDATA "_GetFunctionData"
#define SETLANGUAGE "_SetLanguage"
#define GETPARAMDESC "_GetParameterDescription"
#define ISASYNC "_IsAsync"
#define ADVICE "_Advice"
#define UNADVICE "_Unadvice"
#else // Pascal oder extern "C"
#define GETFUNCTIONCOUNT "GetFunctionCount"
#define GETFUNCTIONDATA "GetFunctionData"
#define SETLANGUAGE "SetLanguage"
#define GETPARAMDESC "GetParameterDescription"
#define ISASYNC "IsAsync"
#define ADVICE "Advice"
#define UNADVICE "Unadvice"
#endif
#define LIBFUNCNAME( name ) \
(String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) ))
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FuncData::FuncData(const String& rIName) :
pModuleData (NULL),
aInternalName (rIName),
// aFuncName (""),
nNumber (0),
nParamCount (0),
eAsyncType (NONE)
{
for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
eParamType[i] = PTR_DOUBLE;
}
//------------------------------------------------------------------------
FuncData::FuncData(const ModuleData*pModule,
const String& rIName,
const String& rFName,
sal_uInt16 nNo,
sal_uInt16 nCount,
const ParamType* peType,
ParamType eType) :
pModuleData (pModule),
aInternalName (rIName),
aFuncName (rFName),
nNumber (nNo),
nParamCount (nCount),
eAsyncType (eType)
{
for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
eParamType[i] = peType[i];
}
//------------------------------------------------------------------------
FuncData::FuncData(const FuncData& rData) :
ScDataObject(),
pModuleData (rData.pModuleData),
aInternalName (rData.aInternalName),
aFuncName (rData.aFuncName),
nNumber (rData.nNumber),
nParamCount (rData.nParamCount),
eAsyncType (rData.eAsyncType)
{
for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++)
eParamType[i] = rData.eParamType[i];
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
short FuncCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
{
return (short) ScGlobal::GetpTransliteration()->compareString(
((FuncData*)pKey1)->aInternalName, ((FuncData*)pKey2)->aInternalName );
}
//------------------------------------------------------------------------
sal_Bool FuncCollection::SearchFunc( const String& rName, sal_uInt16& rIndex ) const
{
FuncData aDataObj(rName);
return Search( &aDataObj, rIndex );
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class ModuleData : public ScDataObject
{
friend class ModuleCollection;
String aName;
osl::Module* pInstance;
public:
ModuleData(const String& rStr, osl::Module* pInst) : aName (rStr), pInstance (pInst) {}
ModuleData(const ModuleData& rData) : ScDataObject(), aName (rData.aName) {pInstance = new osl::Module(aName);}
~ModuleData() { delete pInstance; }
virtual ScDataObject* Clone() const { return new ModuleData(*this); }
const String& GetName() const { return aName; }
osl::Module* GetInstance() const { return pInstance; }
void FreeInstance() { delete pInstance; pInstance = 0; }
};
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class ModuleCollection : public ScSortedCollection
{
public:
ModuleCollection(sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = sal_False) : ScSortedCollection ( nLim, nDel, bDup ) {}
ModuleCollection(const ModuleCollection& rModuleCollection) : ScSortedCollection ( rModuleCollection ) {}
virtual ScDataObject* Clone() const { return new ModuleCollection(*this); }
ModuleData* operator[]( const sal_uInt16 nIndex) const {return (ModuleData*)At(nIndex);}
virtual short Compare(ScDataObject* pKey1, ScDataObject* pKey2) const;
sal_Bool SearchModule( const String& rName,
const ModuleData*& rpModule ) const;
};
static ModuleCollection aModuleCollection;
//------------------------------------------------------------------------
short ModuleCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
{
return (short) ScGlobal::GetpTransliteration()->compareString(
((ModuleData*)pKey1)->aName, ((ModuleData*)pKey2)->aName );
}
//------------------------------------------------------------------------
sal_Bool ModuleCollection::SearchModule( const String& rName,
const ModuleData*& rpModule ) const
{
sal_uInt16 nIndex;
ModuleData aSearchModule(rName, 0);
sal_Bool bFound = Search( &aSearchModule, nIndex );
if (bFound)
rpModule = (ModuleData*)At(nIndex);
else
rpModule = 0;
return bFound;
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
sal_Bool InitExternalFunc(const rtl::OUString& rModuleName)
{
String aModuleName( rModuleName );
// Module schon geladen?
const ModuleData* pTemp;
if (aModuleCollection.SearchModule(aModuleName, pTemp))
return sal_False;
rtl::OUString aNP;
aNP = rModuleName;
sal_Bool bRet = sal_False;
osl::Module* pLib = new osl::Module( aNP );
if (pLib->is())
{
FARPROC fpGetCount = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONCOUNT));
FARPROC fpGetData = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONDATA));
if ((fpGetCount != NULL) && (fpGetData != NULL))
{
FARPROC fpIsAsync = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ISASYNC));
FARPROC fpAdvice = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ADVICE));
FARPROC fpSetLanguage = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(SETLANGUAGE));
if ( fpSetLanguage )
{
LanguageType eLanguage = Application::GetSettings().GetUILanguage();
sal_uInt16 nLanguage = (sal_uInt16) eLanguage;
(*((SetLanguagePtr)fpSetLanguage))( nLanguage );
}
// Module in die Collection aufnehmen
ModuleData* pModuleData = new ModuleData(aModuleName, pLib);
aModuleCollection.Insert(pModuleData);
// Schnittstelle initialisieren
AdvData pfCallBack = &ScAddInAsyncCallBack;
FuncData* pFuncData;
FuncCollection* pFuncCol = ScGlobal::GetFuncCollection();
sal_uInt16 nCount;
(*((GetFuncCountPtr)fpGetCount))(nCount);
for (sal_uInt16 i=0; i < nCount; i++)
{
sal_Char cFuncName[256];
sal_Char cInternalName[256];
sal_uInt16 nParamCount;
ParamType eParamType[MAXFUNCPARAM];
ParamType eAsyncType = NONE;
// #62113# alles initialisieren, falls das AddIn sich schlecht verhaelt
cFuncName[0] = 0;
cInternalName[0] = 0;
nParamCount = 0;
for ( sal_uInt16 j=0; j<MAXFUNCPARAM; j++ )
{
eParamType[j] = NONE;
}
(*((GetFuncDataPtr)fpGetData))(i, cFuncName, nParamCount,
eParamType, cInternalName);
if( fpIsAsync )
{
(*((IsAsync)fpIsAsync))(i, &eAsyncType);
if ( fpAdvice && eAsyncType != NONE )
(*((Advice)fpAdvice))( i, pfCallBack );
}
String aInternalName( cInternalName, osl_getThreadTextEncoding() );
String aFuncName( cFuncName, osl_getThreadTextEncoding() );
pFuncData = new FuncData( pModuleData,
aInternalName,
aFuncName,
i,
nParamCount,
eParamType,
eAsyncType );
pFuncCol->Insert(pFuncData);
}
bRet = sal_True;
}
else
delete pLib;
}
else
delete pLib;
return bRet;
}
//------------------------------------------------------------------------
void ExitExternalFunc()
{
sal_uInt16 nCount = aModuleCollection.GetCount();
for (sal_uInt16 i=0; i<nCount; i++)
{
ModuleData* pData = aModuleCollection[i];
pData->FreeInstance();
}
}
//------------------------------------------------------------------------
sal_Bool FuncData::Call(void** ppParam)
{
sal_Bool bRet = sal_False;
osl::Module* pLib = pModuleData->GetInstance();
FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(aFuncName);
if (fProc != NULL)
{
switch (nParamCount)
{
case 1 :
(*((ExFuncPtr1)fProc))(ppParam[0]);
bRet = sal_True;
break;
case 2 :
(*((ExFuncPtr2)fProc))(ppParam[0], ppParam[1]);
bRet = sal_True;
break;
case 3 :
(*((ExFuncPtr3)fProc))(ppParam[0], ppParam[1], ppParam[2]);
bRet = sal_True;
break;
case 4 :
(*((ExFuncPtr4)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]);
bRet = sal_True;
break;
case 5 :
(*((ExFuncPtr5)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]);
bRet = sal_True;
break;
case 6 :
(*((ExFuncPtr6)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]);
bRet = sal_True;
break;
case 7 :
(*((ExFuncPtr7)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6]);
bRet = sal_True;
break;
case 8 :
(*((ExFuncPtr8)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7]);
bRet = sal_True;
break;
case 9 :
(*((ExFuncPtr9)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8]);
bRet = sal_True;
break;
case 10 :
(*((ExFuncPtr10)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9]);
bRet = sal_True;
break;
case 11 :
(*((ExFuncPtr11)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]);
bRet = sal_True;
break;
case 12:
(*((ExFuncPtr12)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]);
bRet = sal_True;
break;
case 13:
(*((ExFuncPtr13)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
ppParam[12]);
bRet = sal_True;
break;
case 14 :
(*((ExFuncPtr14)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
ppParam[12], ppParam[13]);
bRet = sal_True;
break;
case 15 :
(*((ExFuncPtr15)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
ppParam[12], ppParam[13], ppParam[14]);
bRet = sal_True;
break;
case 16 :
(*((ExFuncPtr16)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5],
ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11],
ppParam[12], ppParam[13], ppParam[14], ppParam[15]);
bRet = sal_True;
break;
default : break;
}
}
return bRet;
}
//------------------------------------------------------------------------
sal_Bool FuncData::Unadvice( double nHandle )
{
sal_Bool bRet = sal_False;
osl::Module* pLib = pModuleData->GetInstance();
FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(UNADVICE));
if (fProc != NULL)
{
((::Unadvice)fProc)(nHandle);
bRet = sal_True;
}
return bRet;
}
//------------------------------------------------------------------------
const String& FuncData::GetModuleName() const
{
// DBG_ASSERT( pModuleData, "Keine Arme, keine Kekse" ):
return pModuleData->GetName();
}
//------------------------------------------------------------------------
sal_Bool FuncData::GetParamDesc( String& aName, String& aDesc, sal_uInt16 nParam )
{
sal_Bool bRet = sal_False;
if ( nParam <= nParamCount )
{
osl::Module* pLib = pModuleData->GetInstance();
FARPROC fProc = (FARPROC) pLib->getFunctionSymbol( LIBFUNCNAME(GETPARAMDESC) );
if ( fProc != NULL )
{
sal_Char pcName[256];
sal_Char pcDesc[256];
*pcName = *pcDesc = 0;
sal_uInt16 nFuncNo = nNumber; // nicht per Reference versauen lassen..
((::GetParamDesc)fProc)( nFuncNo, nParam, pcName, pcDesc );
aName = String( pcName, osl_getThreadTextEncoding() );
aDesc = String( pcDesc, osl_getThreadTextEncoding() );
bRet = sal_True;
}
}
if ( !bRet )
{
aName.Erase();
aDesc.Erase();
}
return bRet;
}