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