diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 48 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.h | 6 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.hxx | 19 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitTypes.h | 6 | ||||
-rw-r--r-- | include/vcl/lok.hxx | 28 | ||||
-rw-r--r-- | vcl/headless/svpinst.cxx | 32 | ||||
-rw-r--r-- | vcl/inc/headless/svpinst.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 6 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 19 |
9 files changed, 150 insertions, 17 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 0842c98ed3e4..0853678a0008 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -39,6 +39,7 @@ #include <sal/log.hxx> #include <vcl/errinf.hxx> +#include <vcl/lok.hxx> #include <osl/file.hxx> #include <osl/process.h> #include <osl/thread.h> @@ -1513,6 +1514,11 @@ static bool lo_signDocument(LibreOfficeKit* pThis, const unsigned char* pPrivateKeyBinary, const int nPrivateKeyBinarySize); +static void lo_runLoop(LibreOfficeKit* pThis, + LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, + void* pData); + LibLibreOffice_Impl::LibLibreOffice_Impl() : m_pOfficeClass( gOfficeClass.lock() ) , maThread(nullptr) @@ -1536,6 +1542,7 @@ LibLibreOffice_Impl::LibLibreOffice_Impl() m_pOfficeClass->getVersionInfo = lo_getVersionInfo; m_pOfficeClass->runMacro = lo_runMacro; m_pOfficeClass->signDocument = lo_signDocument; + m_pOfficeClass->runLoop = lo_runLoop; gOfficeClass = m_pOfficeClass; } @@ -4491,6 +4498,16 @@ static void lo_startmain(void*) Application::ReleaseSolarMutex(); } +static void lo_runLoop(LibreOfficeKit* /*pThis*/, + LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, + void* pData) +{ + SolarMutexGuard aGuard; + vcl::lok::registerPollCallbacks(pPollCallback, pWakeCallback, pData); + lo_startmain(nullptr); +} + static bool bInitialized = false; static void lo_status_indicator_callback(void *data, comphelper::LibreOfficeKit::statusIndicatorCallbackType type, int percent) @@ -4639,7 +4656,24 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char // Did we do a pre-initialize static bool bPreInited = false; - static bool bProfileZones = getenv("SAL_PROFILEZONE_EVENTS") != nullptr; + static bool bUnipoll = false; + static bool bProfileZones = false; + + { // cf. string lifetime for preinit + std::vector<OUString> aOpts; + + // ':' delimited options - avoiding ABI change for new parameters + const char *pOptions = getenv("SAL_LOK_OPTIONS"); + if (pOptions) + aOpts = comphelper::string::split(OUString(pOptions, strlen(pOptions), RTL_TEXTENCODING_UTF8), ':'); + for (auto &it : aOpts) + { + if (it == "unipoll") + bUnipoll = true; + else if (it == "profile_events") + bProfileZones = true; + } + } // What stage are we at ? if (pThis == nullptr) @@ -4857,10 +4891,14 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char RequestHandler::Enable(false); SAL_INFO("lok", "Starting soffice_main"); RequestHandler::SetReady(false); - pLib->maThread = osl_createThread(lo_startmain, nullptr); - SAL_INFO("lok", "Waiting for RequestHandler"); - RequestHandler::WaitForReady(); - SAL_INFO("lok", "RequestHandler ready -- continuing"); + if (!bUnipoll) + { + // Start the main thread only in non-unipoll mode (i.e. multithreaded). + pLib->maThread = osl_createThread(lo_startmain, nullptr); + SAL_INFO("lok", "Waiting for RequestHandler"); + RequestHandler::WaitForReady(); + SAL_INFO("lok", "RequestHandler ready -- continuing"); + } } if (eStage != SECOND_INIT) diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 0e596f5067ba..f2c8dd40f1b3 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -104,6 +104,12 @@ struct _LibreOfficeKitClass const int nCertificateBinarySize, const unsigned char* pPrivateKeyBinary, const int nPrivateKeyBinarySize); + + /// @see lok::Office::runLoop() + void (*runLoop) (LibreOfficeKit* pThis, + LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, + void* pData); }; #define LIBREOFFICEKIT_DOCUMENT_HAS(pDoc,member) LIBREOFFICEKIT_HAS_MEMBER(LibreOfficeKitDocumentClass,member,(pDoc)->pClass->nSize) diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index bd678b0b81d0..6bebf36611dd 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -644,7 +644,6 @@ public: { return mpDoc->pClass->postWindowGestureEvent(mpDoc, nWindowId, pType, nX, nY, nOffset); } - #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; @@ -819,6 +818,24 @@ public: pCertificateBinary, nCertificateBinarySize, pPrivateKeyBinary, nPrivateKeyBinarySize); } + + /** + * Runs the main-loop in the current thread. To trigger this + * mode you need to putenv a SAL_LOK_OPTIONS containing 'unipoll'. + * The @pPollCallback is called to poll for events from the Kit client + * and the @pWakeCallback can be called by internal LibreOfficeKit threads + * to wake the caller of 'runLoop' ie. the main thread. + * + * it is expected that runLoop does not return until Kit exit. + * + * @pData is a context/closure passed to both methods. + */ + void runLoop(LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, + void* pData) + { + mpThis->pClass->runLoop(mpThis, pPollCallback, pWakeCallback, pData); + } }; /// Factory method to create a lok::Office instance. diff --git a/include/LibreOfficeKit/LibreOfficeKitTypes.h b/include/LibreOfficeKit/LibreOfficeKitTypes.h index 2e9078ff4e98..e12ddad19161 100644 --- a/include/LibreOfficeKit/LibreOfficeKitTypes.h +++ b/include/LibreOfficeKit/LibreOfficeKitTypes.h @@ -22,6 +22,12 @@ extern "C" */ typedef void (*LibreOfficeKitCallback)(int nType, const char* pPayload, void* pData); +/** @see lok::Office::runLoop(). + @since LibreOffice 6.3 + */ +typedef int (*LibreOfficeKitPollCallback)(void* pData, int timeoutUs); +typedef void (*LibreOfficeKitWakeCallback)(void* pData); + #ifdef __cplusplus } #endif diff --git a/include/vcl/lok.hxx b/include/vcl/lok.hxx new file mode 100644 index 000000000000..5c30b6290221 --- /dev/null +++ b/include/vcl/lok.hxx @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_VCL_LOK_HXX +#define INCLUDED_VCL_LOK_HXX + +#include <sal/config.h> +#include <vcl/dllapi.h> +#include <LibreOfficeKit/LibreOfficeKitTypes.h> + +namespace vcl +{ +namespace lok +{ +void VCL_DLLPUBLIC registerPollCallbacks(LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, void* pData); +} +} + +#endif // INCLUDE_VCL_LOK_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index 324d976cb95e..69353b104fc3 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -51,6 +51,7 @@ #include <unx/gendata.hxx> // FIXME: remove when we re-work the svp mainloop #include <unx/salunxtime.h> +#include <comphelper/lok.hxx> SvpSalInstance* SvpSalInstance::s_pDefaultInstance = nullptr; @@ -175,12 +176,15 @@ void SvpSalInstance::Wakeup(SvpRequest const request) #ifdef IOS (void)request; #else + ImplSVData* pSVData = ImplGetSVData(); + + if (pSVData->mpWakeCallback) + pSVData->mpWakeCallback(pSVData->mpPollClosure); + SvpSalYieldMutex *const pMutex(static_cast<SvpSalYieldMutex*>(GetYieldMutex())); std::unique_lock<std::mutex> g(pMutex->m_WakeUpMainMutex); if (request != SvpRequest::NONE) - { pMutex->m_Request = request; - } pMutex->m_wakeUpMain = true; pMutex->m_WakeUpMainCond.notify_one(); #endif @@ -373,11 +377,8 @@ sal_uInt32 SvpSalYieldMutex::doRelease(bool const bUnlockAll) // read m_nCount before doRelease bool const isReleased(bUnlockAll || m_nCount == 1); nCount = comphelper::SolarMutex::doRelease( bUnlockAll ); - if (isReleased) { - std::unique_lock<std::mutex> g(m_WakeUpMainMutex); - m_wakeUpMain = true; - m_WakeUpMainCond.notify_one(); - } + if (isReleased && pInst) + pInst->Wakeup(SvpRequest::NONE); } return nCount; } @@ -420,8 +421,8 @@ bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) #endif // first, process current user events - bool bEvent = DispatchUserEvents( bHandleAllCurrentEvents ); - if ( !bHandleAllCurrentEvents && bEvent ) + bool bEvent = DispatchUserEvents(bHandleAllCurrentEvents); + if (!bHandleAllCurrentEvents && bEvent) return true; bEvent = CheckTimeout() || bEvent; @@ -450,7 +451,20 @@ bool SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) else nTimeoutMS = -1; // wait until something happens + ImplSVData* pSVData = ImplGetSVData(); sal_uInt32 nAcquireCount = ReleaseYieldMutexAll(); + + if (pSVData->mpPollCallback) + { + // Poll for events from the LOK client. + if (nTimeoutMS < 0) + nTimeoutMS = 5000; + + // External poll. + if (pSVData->mpPollCallback(pSVData->mpPollClosure, nTimeoutMS * 1000 /* us */) < 0) + pSVData->maAppData.mbAppQuit = true; + } + else { std::unique_lock<std::mutex> g(pMutex->m_WakeUpMainMutex); // wait for doRelease() or Wakeup() to set the condition diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx index dcdd29fc8f07..b552dd9a59bf 100644 --- a/vcl/inc/headless/svpinst.hxx +++ b/vcl/inc/headless/svpinst.hxx @@ -93,7 +93,6 @@ public: virtual ~SvpSalYieldMutex() override; virtual bool IsCurrentThread() const override; - }; SalInstance* svp_create_SalInstance(); @@ -109,7 +108,6 @@ class VCL_DLLPUBLIC SvpSalInstance : public SalGenericInstance, public SalUserEv virtual void TriggerUserEventProcessing() override; virtual void ProcessEvent( SalUserEvent aEvent ) override; - void Wakeup(SvpRequest request = SvpRequest::NONE); public: static SvpSalInstance* s_pDefaultInstance; @@ -119,6 +117,7 @@ public: void CloseWakeupPipe(bool log); void CreateWakeupPipe(bool log); + void Wakeup(SvpRequest request = SvpRequest::NONE); void StartTimer( sal_uInt64 nMS ); void StopTimer(); diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index 714c7c5a36e7..6a98ff4e3185 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -29,6 +29,7 @@ #include <vcl/svapp.hxx> #include <vcl/window.hxx> #include <vcl/task.hxx> +#include <LibreOfficeKit/LibreOfficeKitTypes.h> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/i18n/XCharacterClassification.hpp> @@ -385,6 +386,11 @@ struct ImplSVData css::uno::Reference<css::i18n::XCharacterClassification> m_xCharClass; Link<LinkParamNone*,void> maDeInitHook; + + // LOK & headless backend specific hooks + LibreOfficeKitPollCallback mpPollCallback = nullptr; + LibreOfficeKitWakeCallback mpWakeCallback = nullptr; + void *mpPollClosure = nullptr; }; css::uno::Reference<css::i18n::XCharacterClassification> const& ImplGetCharClass(); diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index ca29108bc37e..0037d35443f9 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -38,6 +38,7 @@ #include <unotools/syslocaleoptions.hxx> #include <vcl/dialog.hxx> +#include <vcl/lok.hxx> #include <vcl/floatwin.hxx> #include <vcl/settings.hxx> #include <vcl/keycod.hxx> @@ -1658,4 +1659,22 @@ void Application::setDeInitHook(Link<LinkParamNone*,void> const & hook) { pSVData->maAppData.mbInAppMain = true; } +namespace vcl { namespace lok { + +void registerPollCallbacks( + LibreOfficeKitPollCallback pPollCallback, + LibreOfficeKitWakeCallback pWakeCallback, + void *pData) { + + ImplSVData * pSVData = ImplGetSVData(); + if (pSVData) + { + pSVData->mpPollCallback = pPollCallback; + pSVData->mpWakeCallback = pWakeCallback; + pSVData->mpPollClosure = pData; + } +} + +} } // namespace lok, namespace vcl + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |