1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 #include <vcl/svapp.hxx> 35 #include <osl/module.hxx> 36 #include <osl/file.hxx> 37 #include <unotools/transliterationwrapper.hxx> 38 39 #include "callform.hxx" 40 #include "global.hxx" 41 #include "adiasync.hxx" 42 43 //------------------------------------------------------------------------ 44 45 extern "C" { 46 47 typedef void (CALLTYPE* ExFuncPtr1)(void*); 48 typedef void (CALLTYPE* ExFuncPtr2)(void*, void*); 49 typedef void (CALLTYPE* ExFuncPtr3)(void*, void*, void*); 50 typedef void (CALLTYPE* ExFuncPtr4)(void*, void*, void*, void*); 51 typedef void (CALLTYPE* ExFuncPtr5)(void*, void*, void*, void*, void*); 52 typedef void (CALLTYPE* ExFuncPtr6)(void*, void*, void*, void*, void*, void*); 53 typedef void (CALLTYPE* ExFuncPtr7)(void*, void*, void*, void*, void*, void*, void*); 54 typedef void (CALLTYPE* ExFuncPtr8)(void*, void*, void*, void*, void*, void*, void*, void*); 55 typedef void (CALLTYPE* ExFuncPtr9)(void*, void*, void*, void*, void*, void*, void*, void*, void*); 56 typedef void (CALLTYPE* ExFuncPtr10)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 57 typedef void (CALLTYPE* ExFuncPtr11)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 58 typedef void (CALLTYPE* ExFuncPtr12)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 59 typedef void (CALLTYPE* ExFuncPtr13)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 60 typedef void (CALLTYPE* ExFuncPtr14)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 61 typedef void (CALLTYPE* ExFuncPtr15)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 62 typedef void (CALLTYPE* ExFuncPtr16)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*); 63 64 typedef void (CALLTYPE* GetFuncCountPtr)(sal_uInt16& nCount); 65 typedef void (CALLTYPE* GetFuncDataPtr) 66 (sal_uInt16& nNo, sal_Char* pFuncName, sal_uInt16& nParamCount, ParamType* peType, sal_Char* pInternalName); 67 68 typedef void (CALLTYPE* SetLanguagePtr)( sal_uInt16& nLanguage ); 69 typedef void (CALLTYPE* GetParamDesc) 70 (sal_uInt16& nNo, sal_uInt16& nParam, sal_Char* pName, sal_Char* pDesc ); 71 72 typedef void (CALLTYPE* IsAsync) ( sal_uInt16& nNo, 73 ParamType* peType ); 74 typedef void (CALLTYPE* Advice) ( sal_uInt16& nNo, 75 AdvData& pfCallback ); 76 typedef void (CALLTYPE* Unadvice)( double& nHandle ); 77 78 typedef void (CALLTYPE* FARPROC) ( void ); 79 80 } 81 82 #if defined(OS2) && defined(BLC) 83 #define GETFUNCTIONCOUNT "_GetFunctionCount" 84 #define GETFUNCTIONDATA "_GetFunctionData" 85 #define SETLANGUAGE "_SetLanguage" 86 #define GETPARAMDESC "_GetParameterDescription" 87 #define ISASYNC "_IsAsync" 88 #define ADVICE "_Advice" 89 #define UNADVICE "_Unadvice" 90 #else // Pascal oder extern "C" 91 #define GETFUNCTIONCOUNT "GetFunctionCount" 92 #define GETFUNCTIONDATA "GetFunctionData" 93 #define SETLANGUAGE "SetLanguage" 94 #define GETPARAMDESC "GetParameterDescription" 95 #define ISASYNC "IsAsync" 96 #define ADVICE "Advice" 97 #define UNADVICE "Unadvice" 98 #endif 99 100 #define LIBFUNCNAME( name ) \ 101 (String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( name ) )) 102 103 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 104 105 FuncData::FuncData(const String& rIName) : 106 pModuleData (NULL), 107 aInternalName (rIName), 108 // aFuncName (""), 109 nNumber (0), 110 nParamCount (0), 111 eAsyncType (NONE) 112 { 113 for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++) 114 eParamType[i] = PTR_DOUBLE; 115 } 116 117 //------------------------------------------------------------------------ 118 119 FuncData::FuncData(const ModuleData*pModule, 120 const String& rIName, 121 const String& rFName, 122 sal_uInt16 nNo, 123 sal_uInt16 nCount, 124 const ParamType* peType, 125 ParamType eType) : 126 pModuleData (pModule), 127 aInternalName (rIName), 128 aFuncName (rFName), 129 nNumber (nNo), 130 nParamCount (nCount), 131 eAsyncType (eType) 132 { 133 for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++) 134 eParamType[i] = peType[i]; 135 } 136 137 //------------------------------------------------------------------------ 138 139 FuncData::FuncData(const FuncData& rData) : 140 ScDataObject(), 141 pModuleData (rData.pModuleData), 142 aInternalName (rData.aInternalName), 143 aFuncName (rData.aFuncName), 144 nNumber (rData.nNumber), 145 nParamCount (rData.nParamCount), 146 eAsyncType (rData.eAsyncType) 147 { 148 for (sal_uInt16 i = 0; i < MAXFUNCPARAM; i++) 149 eParamType[i] = rData.eParamType[i]; 150 } 151 152 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 153 154 short FuncCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const 155 { 156 return (short) ScGlobal::GetpTransliteration()->compareString( 157 ((FuncData*)pKey1)->aInternalName, ((FuncData*)pKey2)->aInternalName ); 158 } 159 160 //------------------------------------------------------------------------ 161 162 sal_Bool FuncCollection::SearchFunc( const String& rName, sal_uInt16& rIndex ) const 163 { 164 FuncData aDataObj(rName); 165 return Search( &aDataObj, rIndex ); 166 } 167 168 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 169 class ModuleData : public ScDataObject 170 { 171 friend class ModuleCollection; 172 String aName; 173 osl::Module* pInstance; 174 public: 175 ModuleData(const String& rStr, osl::Module* pInst) : aName (rStr), pInstance (pInst) {} 176 ModuleData(const ModuleData& rData) : ScDataObject(), aName (rData.aName) {pInstance = new osl::Module(aName);} 177 ~ModuleData() { delete pInstance; } 178 virtual ScDataObject* Clone() const { return new ModuleData(*this); } 179 180 const String& GetName() const { return aName; } 181 osl::Module* GetInstance() const { return pInstance; } 182 void FreeInstance() { delete pInstance; pInstance = 0; } 183 }; 184 185 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 186 class ModuleCollection : public ScSortedCollection 187 { 188 public: 189 ModuleCollection(sal_uInt16 nLim = 4, sal_uInt16 nDel = 4, sal_Bool bDup = sal_False) : ScSortedCollection ( nLim, nDel, bDup ) {} 190 ModuleCollection(const ModuleCollection& rModuleCollection) : ScSortedCollection ( rModuleCollection ) {} 191 192 virtual ScDataObject* Clone() const { return new ModuleCollection(*this); } 193 ModuleData* operator[]( const sal_uInt16 nIndex) const {return (ModuleData*)At(nIndex);} 194 virtual short Compare(ScDataObject* pKey1, ScDataObject* pKey2) const; 195 sal_Bool SearchModule( const String& rName, 196 const ModuleData*& rpModule ) const; 197 }; 198 199 static ModuleCollection aModuleCollection; 200 201 //------------------------------------------------------------------------ 202 203 short ModuleCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const 204 { 205 return (short) ScGlobal::GetpTransliteration()->compareString( 206 ((ModuleData*)pKey1)->aName, ((ModuleData*)pKey2)->aName ); 207 } 208 209 //------------------------------------------------------------------------ 210 211 sal_Bool ModuleCollection::SearchModule( const String& rName, 212 const ModuleData*& rpModule ) const 213 { 214 sal_uInt16 nIndex; 215 ModuleData aSearchModule(rName, 0); 216 sal_Bool bFound = Search( &aSearchModule, nIndex ); 217 if (bFound) 218 rpModule = (ModuleData*)At(nIndex); 219 else 220 rpModule = 0; 221 return bFound; 222 } 223 224 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 225 226 sal_Bool InitExternalFunc(const rtl::OUString& rModuleName) 227 { 228 String aModuleName( rModuleName ); 229 230 // Module schon geladen? 231 const ModuleData* pTemp; 232 if (aModuleCollection.SearchModule(aModuleName, pTemp)) 233 return sal_False; 234 235 rtl::OUString aNP; 236 aNP = rModuleName; 237 238 sal_Bool bRet = sal_False; 239 osl::Module* pLib = new osl::Module( aNP ); 240 if (pLib->is()) 241 { 242 FARPROC fpGetCount = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONCOUNT)); 243 FARPROC fpGetData = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(GETFUNCTIONDATA)); 244 if ((fpGetCount != NULL) && (fpGetData != NULL)) 245 { 246 FARPROC fpIsAsync = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ISASYNC)); 247 FARPROC fpAdvice = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(ADVICE)); 248 FARPROC fpSetLanguage = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(SETLANGUAGE)); 249 if ( fpSetLanguage ) 250 { 251 LanguageType eLanguage = Application::GetSettings().GetUILanguage(); 252 sal_uInt16 nLanguage = (sal_uInt16) eLanguage; 253 (*((SetLanguagePtr)fpSetLanguage))( nLanguage ); 254 } 255 256 // Module in die Collection aufnehmen 257 ModuleData* pModuleData = new ModuleData(aModuleName, pLib); 258 aModuleCollection.Insert(pModuleData); 259 260 // Schnittstelle initialisieren 261 AdvData pfCallBack = &ScAddInAsyncCallBack; 262 FuncData* pFuncData; 263 FuncCollection* pFuncCol = ScGlobal::GetFuncCollection(); 264 sal_uInt16 nCount; 265 (*((GetFuncCountPtr)fpGetCount))(nCount); 266 for (sal_uInt16 i=0; i < nCount; i++) 267 { 268 sal_Char cFuncName[256]; 269 sal_Char cInternalName[256]; 270 sal_uInt16 nParamCount; 271 ParamType eParamType[MAXFUNCPARAM]; 272 ParamType eAsyncType = NONE; 273 // #62113# alles initialisieren, falls das AddIn sich schlecht verhaelt 274 cFuncName[0] = 0; 275 cInternalName[0] = 0; 276 nParamCount = 0; 277 for ( sal_uInt16 j=0; j<MAXFUNCPARAM; j++ ) 278 { 279 eParamType[j] = NONE; 280 } 281 (*((GetFuncDataPtr)fpGetData))(i, cFuncName, nParamCount, 282 eParamType, cInternalName); 283 if( fpIsAsync ) 284 { 285 (*((IsAsync)fpIsAsync))(i, &eAsyncType); 286 if ( fpAdvice && eAsyncType != NONE ) 287 (*((Advice)fpAdvice))( i, pfCallBack ); 288 } 289 String aInternalName( cInternalName, osl_getThreadTextEncoding() ); 290 String aFuncName( cFuncName, osl_getThreadTextEncoding() ); 291 pFuncData = new FuncData( pModuleData, 292 aInternalName, 293 aFuncName, 294 i, 295 nParamCount, 296 eParamType, 297 eAsyncType ); 298 pFuncCol->Insert(pFuncData); 299 } 300 bRet = sal_True; 301 } 302 else 303 delete pLib; 304 } 305 else 306 delete pLib; 307 return bRet; 308 } 309 310 //------------------------------------------------------------------------ 311 312 void ExitExternalFunc() 313 { 314 sal_uInt16 nCount = aModuleCollection.GetCount(); 315 for (sal_uInt16 i=0; i<nCount; i++) 316 { 317 ModuleData* pData = aModuleCollection[i]; 318 pData->FreeInstance(); 319 } 320 } 321 322 //------------------------------------------------------------------------ 323 324 sal_Bool FuncData::Call(void** ppParam) 325 { 326 sal_Bool bRet = sal_False; 327 osl::Module* pLib = pModuleData->GetInstance(); 328 FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(aFuncName); 329 if (fProc != NULL) 330 { 331 switch (nParamCount) 332 { 333 case 1 : 334 (*((ExFuncPtr1)fProc))(ppParam[0]); 335 bRet = sal_True; 336 break; 337 case 2 : 338 (*((ExFuncPtr2)fProc))(ppParam[0], ppParam[1]); 339 bRet = sal_True; 340 break; 341 case 3 : 342 (*((ExFuncPtr3)fProc))(ppParam[0], ppParam[1], ppParam[2]); 343 bRet = sal_True; 344 break; 345 case 4 : 346 (*((ExFuncPtr4)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3]); 347 bRet = sal_True; 348 break; 349 case 5 : 350 (*((ExFuncPtr5)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4]); 351 bRet = sal_True; 352 break; 353 case 6 : 354 (*((ExFuncPtr6)fProc))(ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5]); 355 bRet = sal_True; 356 break; 357 case 7 : 358 (*((ExFuncPtr7)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 359 ppParam[6]); 360 bRet = sal_True; 361 break; 362 case 8 : 363 (*((ExFuncPtr8)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 364 ppParam[6], ppParam[7]); 365 bRet = sal_True; 366 break; 367 case 9 : 368 (*((ExFuncPtr9)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 369 ppParam[6], ppParam[7], ppParam[8]); 370 bRet = sal_True; 371 break; 372 case 10 : 373 (*((ExFuncPtr10)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 374 ppParam[6], ppParam[7], ppParam[8], ppParam[9]); 375 bRet = sal_True; 376 break; 377 case 11 : 378 (*((ExFuncPtr11)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 379 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10]); 380 bRet = sal_True; 381 break; 382 case 12: 383 (*((ExFuncPtr12)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 384 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11]); 385 bRet = sal_True; 386 break; 387 case 13: 388 (*((ExFuncPtr13)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 389 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], 390 ppParam[12]); 391 bRet = sal_True; 392 break; 393 case 14 : 394 (*((ExFuncPtr14)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 395 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], 396 ppParam[12], ppParam[13]); 397 bRet = sal_True; 398 break; 399 case 15 : 400 (*((ExFuncPtr15)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 401 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], 402 ppParam[12], ppParam[13], ppParam[14]); 403 bRet = sal_True; 404 break; 405 case 16 : 406 (*((ExFuncPtr16)fProc))( ppParam[0], ppParam[1], ppParam[2], ppParam[3], ppParam[4], ppParam[5], 407 ppParam[6], ppParam[7], ppParam[8], ppParam[9], ppParam[10], ppParam[11], 408 ppParam[12], ppParam[13], ppParam[14], ppParam[15]); 409 bRet = sal_True; 410 break; 411 default : break; 412 } 413 } 414 return bRet; 415 } 416 417 //------------------------------------------------------------------------ 418 419 sal_Bool FuncData::Unadvice( double nHandle ) 420 { 421 sal_Bool bRet = sal_False; 422 osl::Module* pLib = pModuleData->GetInstance(); 423 FARPROC fProc = (FARPROC)pLib->getFunctionSymbol(LIBFUNCNAME(UNADVICE)); 424 if (fProc != NULL) 425 { 426 ((::Unadvice)fProc)(nHandle); 427 bRet = sal_True; 428 } 429 return bRet; 430 } 431 432 //------------------------------------------------------------------------ 433 434 const String& FuncData::GetModuleName() const 435 { 436 // DBG_ASSERT( pModuleData, "Keine Arme, keine Kekse" ): 437 return pModuleData->GetName(); 438 } 439 440 //------------------------------------------------------------------------ 441 442 sal_Bool FuncData::GetParamDesc( String& aName, String& aDesc, sal_uInt16 nParam ) 443 { 444 sal_Bool bRet = sal_False; 445 if ( nParam <= nParamCount ) 446 { 447 osl::Module* pLib = pModuleData->GetInstance(); 448 FARPROC fProc = (FARPROC) pLib->getFunctionSymbol( LIBFUNCNAME(GETPARAMDESC) ); 449 if ( fProc != NULL ) 450 { 451 sal_Char pcName[256]; 452 sal_Char pcDesc[256]; 453 *pcName = *pcDesc = 0; 454 sal_uInt16 nFuncNo = nNumber; // nicht per Reference versauen lassen.. 455 ((::GetParamDesc)fProc)( nFuncNo, nParam, pcName, pcDesc ); 456 aName = String( pcName, osl_getThreadTextEncoding() ); 457 aDesc = String( pcDesc, osl_getThreadTextEncoding() ); 458 bRet = sal_True; 459 } 460 } 461 if ( !bRet ) 462 { 463 aName.Erase(); 464 aDesc.Erase(); 465 } 466 return bRet; 467 } 468 469 470