1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
23 #include <vcl/svapp.hxx>
24 #include <vcl/settings.hxx>
25 #include <osl/module.hxx>
26 #include <i18nlangtag/languagetag.hxx>
29 #include <callform.hxx>
31 #include <adiasync.hxx>
35 typedef void (CALLTYPE
* ExFuncPtr1
)(void*);
36 typedef void (CALLTYPE
* ExFuncPtr2
)(void*, void*);
37 typedef void (CALLTYPE
* ExFuncPtr3
)(void*, void*, void*);
38 typedef void (CALLTYPE
* ExFuncPtr4
)(void*, void*, void*, void*);
39 typedef void (CALLTYPE
* ExFuncPtr5
)(void*, void*, void*, void*, void*);
40 typedef void (CALLTYPE
* ExFuncPtr6
)(void*, void*, void*, void*, void*, void*);
41 typedef void (CALLTYPE
* ExFuncPtr7
)(void*, void*, void*, void*, void*, void*, void*);
42 typedef void (CALLTYPE
* ExFuncPtr8
)(void*, void*, void*, void*, void*, void*, void*, void*);
43 typedef void (CALLTYPE
* ExFuncPtr9
)(void*, void*, void*, void*, void*, void*, void*, void*, void*);
44 typedef void (CALLTYPE
* ExFuncPtr10
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
45 typedef void (CALLTYPE
* ExFuncPtr11
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
46 typedef void (CALLTYPE
* ExFuncPtr12
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
47 typedef void (CALLTYPE
* ExFuncPtr13
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
48 typedef void (CALLTYPE
* ExFuncPtr14
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
49 typedef void (CALLTYPE
* ExFuncPtr15
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
50 typedef void (CALLTYPE
* ExFuncPtr16
)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
52 typedef void (CALLTYPE
* GetFuncCountPtr
)(sal_uInt16
& nCount
);
53 typedef void (CALLTYPE
* GetFuncDataPtr
)
54 (sal_uInt16
& nNo
, char* pFuncName
, sal_uInt16
& nParamCount
, ParamType
* peType
, char* pInternalName
);
56 typedef void (CALLTYPE
* SetLanguagePtr
)( sal_uInt16
& nLanguage
);
57 typedef void (CALLTYPE
* GetParamDesc
)
58 (sal_uInt16
& nNo
, sal_uInt16
& nParam
, char* pName
, char* pDesc
);
60 typedef void (CALLTYPE
* IsAsync
) ( sal_uInt16
& nNo
,
62 typedef void (CALLTYPE
* Advice
) ( sal_uInt16
& nNo
,
63 AdvData
& pfCallback
);
64 typedef void (CALLTYPE
* Unadvice
)( double& nHandle
);
68 #ifndef DISABLE_DYNLOADING
69 constexpr OUStringLiteral GETFUNCTIONCOUNT
= u
"GetFunctionCount";
70 constexpr OUStringLiteral GETFUNCTIONDATA
= u
"GetFunctionData";
71 constexpr OUStringLiteral SETLANGUAGE
= u
"SetLanguage";
72 constexpr OUStringLiteral GETPARAMDESC
= u
"GetParameterDescription";
73 constexpr OUStringLiteral ISASYNC
= u
"IsAsync";
74 constexpr OUStringLiteral ADVICE
= u
"Advice";
75 constexpr OUStringLiteral UNADVICE
= u
"Unadvice";
80 friend class ModuleCollection
;
82 std::unique_ptr
<osl::Module
> pInstance
;
84 ModuleData(const ModuleData
&) = delete;
85 const ModuleData
& operator=(const ModuleData
&) = delete;
87 ModuleData(OUString aStr
, std::unique_ptr
<osl::Module
> pInst
) : aName(std::move(aStr
)), pInstance(std::move(pInst
)) {}
89 const OUString
& GetName() const { return aName
; }
90 osl::Module
* GetInstance() const { return pInstance
.get(); }
93 LegacyFuncData::LegacyFuncData(const ModuleData
*pModule
,
98 const ParamType
* peType
,
100 pModuleData (pModule
),
101 aInternalName (std::move(aIName
)),
102 aFuncName (std::move(aFName
)),
104 nParamCount (nCount
),
107 for (sal_uInt16 i
= 0; i
< MAXFUNCPARAM
; i
++)
108 eParamType
[i
] = peType
[i
];
111 LegacyFuncData::LegacyFuncData(const LegacyFuncData
& rData
) :
112 pModuleData (rData
.pModuleData
),
113 aInternalName (rData
.aInternalName
),
114 aFuncName (rData
.aFuncName
),
115 nNumber (rData
.nNumber
),
116 nParamCount (rData
.nParamCount
),
117 eAsyncType (rData
.eAsyncType
)
119 for (sal_uInt16 i
= 0; i
< MAXFUNCPARAM
; i
++)
120 eParamType
[i
] = rData
.eParamType
[i
];
125 class ModuleCollection
127 typedef std::map
<OUString
, std::unique_ptr
<ModuleData
>> MapType
;
130 ModuleCollection() {}
132 const ModuleData
* findByName(const OUString
& rName
) const;
133 void insert(ModuleData
* pNew
);
137 const ModuleData
* ModuleCollection::findByName(const OUString
& rName
) const
139 MapType::const_iterator it
= m_Data
.find(rName
);
140 return it
== m_Data
.end() ? nullptr : it
->second
.get();
143 void ModuleCollection::insert(ModuleData
* pNew
)
148 OUString aName
= pNew
->GetName();
149 m_Data
.insert(std::make_pair(aName
, std::unique_ptr
<ModuleData
>(pNew
)));
152 void ModuleCollection::clear()
157 ModuleCollection aModuleCollection
;
161 bool InitExternalFunc(const OUString
& rModuleName
)
163 #ifdef DISABLE_DYNLOADING
167 // Module already loaded?
168 const ModuleData
* pTemp
= aModuleCollection
.findByName(rModuleName
);
172 OUString aNP
= rModuleName
;
174 std::unique_ptr
<osl::Module
> pLib(new osl::Module( aNP
));
178 oslGenericFunction fpGetCount
= pLib
->getFunctionSymbol(GETFUNCTIONCOUNT
);
179 oslGenericFunction fpGetData
= pLib
->getFunctionSymbol(GETFUNCTIONDATA
);
180 if ((fpGetCount
== nullptr) || (fpGetData
== nullptr))
183 oslGenericFunction fpIsAsync
= pLib
->getFunctionSymbol(ISASYNC
);
184 oslGenericFunction fpAdvice
= pLib
->getFunctionSymbol(ADVICE
);
185 oslGenericFunction fpSetLanguage
= pLib
->getFunctionSymbol(SETLANGUAGE
);
188 LanguageType eLanguage
= Application::GetSettings().GetUILanguageTag().getLanguageType();
189 sal_uInt16 nLanguage
= static_cast<sal_uInt16
>(eLanguage
);
190 (*reinterpret_cast<SetLanguagePtr
>(fpSetLanguage
))( nLanguage
);
193 // include module into the collection
194 ModuleData
* pModuleData
= new ModuleData(rModuleName
, std::move(pLib
));
195 aModuleCollection
.insert(pModuleData
);
197 // initialize interface
198 AdvData pfCallBack
= &ScAddInAsyncCallBack
;
199 LegacyFuncCollection
* pLegacyFuncCol
= ScGlobal::GetLegacyFuncCollection();
201 (*reinterpret_cast<GetFuncCountPtr
>(fpGetCount
))(nCount
);
202 for (sal_uInt16 i
=0; i
< nCount
; i
++)
205 char cInternalName
[256];
206 sal_uInt16 nParamCount
;
207 ParamType eParamType
[MAXFUNCPARAM
];
208 ParamType eAsyncType
= ParamType::NONE
;
209 // initialize all, in case the AddIn behaves bad
211 cInternalName
[0] = 0;
213 for (ParamType
& rParamType
: eParamType
)
215 rParamType
= ParamType::NONE
;
217 (*reinterpret_cast<GetFuncDataPtr
>(fpGetData
))(i
, cFuncName
, nParamCount
,
218 eParamType
, cInternalName
);
221 (*reinterpret_cast<IsAsync
>(fpIsAsync
))(i
, &eAsyncType
);
222 if ( fpAdvice
&& eAsyncType
!= ParamType::NONE
)
223 (*reinterpret_cast<Advice
>(fpAdvice
))( i
, pfCallBack
);
225 OUString
aInternalName( cInternalName
, strlen(cInternalName
), osl_getThreadTextEncoding() );
226 OUString
aFuncName( cFuncName
, strlen(cFuncName
), osl_getThreadTextEncoding() );
227 LegacyFuncData
* pLegacyFuncData
= new LegacyFuncData( pModuleData
,
234 pLegacyFuncCol
->insert(pLegacyFuncData
);
240 void ExitExternalFunc()
242 aModuleCollection
.clear();
245 void LegacyFuncData::Call(void** ppParam
) const
247 #ifdef DISABLE_DYNLOADING
250 osl::Module
* pLib
= pModuleData
->GetInstance();
251 oslGenericFunction fProc
= pLib
->getFunctionSymbol(aFuncName
);
252 if (fProc
== nullptr)
258 (*reinterpret_cast<ExFuncPtr1
>(fProc
))(ppParam
[0]);
261 (*reinterpret_cast<ExFuncPtr2
>(fProc
))(ppParam
[0], ppParam
[1]);
264 (*reinterpret_cast<ExFuncPtr3
>(fProc
))(ppParam
[0], ppParam
[1], ppParam
[2]);
267 (*reinterpret_cast<ExFuncPtr4
>(fProc
))(ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3]);
270 (*reinterpret_cast<ExFuncPtr5
>(fProc
))(ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4]);
273 (*reinterpret_cast<ExFuncPtr6
>(fProc
))(ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5]);
276 (*reinterpret_cast<ExFuncPtr7
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
280 (*reinterpret_cast<ExFuncPtr8
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
281 ppParam
[6], ppParam
[7]);
284 (*reinterpret_cast<ExFuncPtr9
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
285 ppParam
[6], ppParam
[7], ppParam
[8]);
288 (*reinterpret_cast<ExFuncPtr10
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
289 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9]);
292 (*reinterpret_cast<ExFuncPtr11
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
293 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10]);
296 (*reinterpret_cast<ExFuncPtr12
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
297 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10], ppParam
[11]);
300 (*reinterpret_cast<ExFuncPtr13
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
301 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10], ppParam
[11],
305 (*reinterpret_cast<ExFuncPtr14
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
306 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10], ppParam
[11],
307 ppParam
[12], ppParam
[13]);
310 (*reinterpret_cast<ExFuncPtr15
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
311 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10], ppParam
[11],
312 ppParam
[12], ppParam
[13], ppParam
[14]);
315 (*reinterpret_cast<ExFuncPtr16
>(fProc
))( ppParam
[0], ppParam
[1], ppParam
[2], ppParam
[3], ppParam
[4], ppParam
[5],
316 ppParam
[6], ppParam
[7], ppParam
[8], ppParam
[9], ppParam
[10], ppParam
[11],
317 ppParam
[12], ppParam
[13], ppParam
[14], ppParam
[15]);
324 void LegacyFuncData::Unadvice( double nHandle
)
326 #ifdef DISABLE_DYNLOADING
329 osl::Module
* pLib
= pModuleData
->GetInstance();
330 oslGenericFunction fProc
= pLib
->getFunctionSymbol(UNADVICE
);
331 if (fProc
!= nullptr)
333 reinterpret_cast< ::Unadvice
>(fProc
)(nHandle
);
338 const OUString
& LegacyFuncData::GetModuleName() const
340 return pModuleData
->GetName();
343 void LegacyFuncData::getParamDesc( OUString
& aName
, OUString
& aDesc
, sal_uInt16 nParam
) const
345 #ifdef DISABLE_DYNLOADING
351 if ( nParam
<= nParamCount
)
353 osl::Module
* pLib
= pModuleData
->GetInstance();
354 oslGenericFunction fProc
= pLib
->getFunctionSymbol(GETPARAMDESC
);
355 if ( fProc
!= nullptr )
359 *pcName
= *pcDesc
= 0;
360 sal_uInt16 nFuncNo
= nNumber
; // don't let it mess up via reference...
361 reinterpret_cast< ::GetParamDesc
>(fProc
)( nFuncNo
, nParam
, pcName
, pcDesc
);
362 aName
= OUString( pcName
, 256, osl_getThreadTextEncoding() );
363 aDesc
= OUString( pcDesc
, 256, osl_getThreadTextEncoding() );
375 LegacyFuncCollection::LegacyFuncCollection() {}
376 LegacyFuncCollection::LegacyFuncCollection(const LegacyFuncCollection
& r
)
378 for (auto const& it
: r
.m_Data
)
380 m_Data
.insert(std::make_pair(it
.first
, std::make_unique
<LegacyFuncData
>(*it
.second
)));
384 const LegacyFuncData
* LegacyFuncCollection::findByName(const OUString
& rName
) const
386 MapType::const_iterator it
= m_Data
.find(rName
);
387 return it
== m_Data
.end() ? nullptr : it
->second
.get();
390 LegacyFuncData
* LegacyFuncCollection::findByName(const OUString
& rName
)
392 MapType::iterator it
= m_Data
.find(rName
);
393 return it
== m_Data
.end() ? nullptr : it
->second
.get();
396 void LegacyFuncCollection::insert(LegacyFuncData
* pNew
)
398 OUString aName
= pNew
->GetInternalName();
399 m_Data
.insert(std::make_pair(aName
, std::unique_ptr
<LegacyFuncData
>(pNew
)));
402 LegacyFuncCollection::const_iterator
LegacyFuncCollection::begin() const
404 return m_Data
.begin();
407 LegacyFuncCollection::const_iterator
LegacyFuncCollection::end() const
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */