diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-09-12 10:26:52 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-10-02 11:24:00 +0200 |
commit | 1698debed2993fc5f262aa3ebbdb32fc112ac556 (patch) | |
tree | 0848ab3850845d3d6a088ace1b9561c99fcd6fef /vcl/win/app | |
parent | 3d9809bb6a20c34ef9f5ef0f4a6bc4eab7d8551f (diff) |
Implement Windows VCL backend as plugin
Change-Id: If9c7c67f48311ac68ecc9f8e3a07f9bb7c73d962
Reviewed-on: https://gerrit.libreoffice.org/61101
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/win/app')
-rw-r--r-- | vcl/win/app/salinst.cxx | 76 | ||||
-rw-r--r-- | vcl/win/app/salplug.cxx | 199 |
2 files changed, 217 insertions, 58 deletions
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx index 1c67113322dc..d5fca66f6bd2 100644 --- a/vcl/win/app/salinst.cxx +++ b/vcl/win/app/salinst.cxx @@ -32,6 +32,7 @@ #include <vcl/opengl/OpenGLHelper.hxx> #include <vcl/opengl/OpenGLContext.hxx> #include <vcl/timer.hxx> +#include <vclpluginapi.h> #include <opengl/salbmp.hxx> #include <opengl/win/gdiimpl.hxx> @@ -299,55 +300,33 @@ SalData::SalData() SetSalData( this ); initNWF(); + + CoInitialize(nullptr); // put main thread in Single Threaded Apartment (STA) + static Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr); } SalData::~SalData() { deInitNWF(); SetSalData( nullptr ); -} - -void InitSalData() -{ - SalData* pSalData = new SalData; - CoInitialize(nullptr); // put main thread in Single Threaded Apartment (STA) - - // init GDIPlus - static Gdiplus::GdiplusStartupInput gdiplusStartupInput; - Gdiplus::GdiplusStartup(&pSalData->gdiplusToken, &gdiplusStartupInput, nullptr); -} -void DeInitSalData() -{ CoUninitialize(); - SalData* pSalData = GetSalData(); - // deinit GDIPlus - if(pSalData) - { - Gdiplus::GdiplusShutdown(pSalData->gdiplusToken); - } - - delete pSalData; + if (gdiplusToken) + Gdiplus::GdiplusShutdown(gdiplusToken); } -void InitSalMain() +extern "C" { +VCLPLUG_WIN_PUBLIC SalInstance* create_SalInstance() { - // remember data, copied from WinMain - SalData* pData = GetSalData(); - if ( pData ) // Im AppServer NULL - { - STARTUPINFOW aSI; - aSI.cb = sizeof( aSI ); - GetStartupInfoW( &aSI ); - pData->mhInst = GetModuleHandleW( nullptr ); - pData->mnCmdShow = aSI.wShowWindow; - } -} + SalData* pSalData = new SalData(); -SalInstance* CreateSalInstance() -{ - SalData* pSalData = GetSalData(); + STARTUPINFOW aSI; + aSI.cb = sizeof( aSI ); + GetStartupInfoW( &aSI ); + pSalData->mhInst = GetModuleHandleW( nullptr ); + pSalData->mnCmdShow = aSI.wShowWindow; pSalData->mnAppThreadId = GetCurrentThreadId(); @@ -405,20 +384,6 @@ SalInstance* CreateSalInstance() return pInst; } - -void DestroySalInstance( SalInstance* pInst ) -{ - SalData* pSalData = GetSalData(); - - // (only one instance in this version !!!) - - ImplFreeSalGDI(); - - // reset instance - if ( pSalData->mpInstance == pInst ) - pSalData->mpInstance = nullptr; - - delete pInst; } WinSalInstance::WinSalInstance() @@ -426,12 +391,13 @@ WinSalInstance::WinSalInstance() , mhComWnd( nullptr ) , m_nNoYieldLock( 0 ) { - GetYieldMutex()->acquire(); + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mxToolkitName = OUString("win"); } WinSalInstance::~WinSalInstance() { - GetYieldMutex()->release(); + ImplFreeSalGDI(); DestroyWindow( mhComWnd ); } @@ -1000,12 +966,6 @@ std::shared_ptr<SalBitmap> WinSalInstance::CreateSalBitmap() return std::make_shared<WinSalBitmap>(); } -const OUString& SalGetDesktopEnvironment() -{ - static OUString aDesktopEnvironment( "Windows" ); - return aDesktopEnvironment; -} - int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo) { // Decide if an exception is a c++ (mostly UNO) exception or a process violation. diff --git a/vcl/win/app/salplug.cxx b/vcl/win/app/salplug.cxx new file mode 100644 index 000000000000..1ef61976a23d --- /dev/null +++ b/vcl/win/app/salplug.cxx @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <osl/module.hxx> +#include <osl/process.h> + +#include <rtl/bootstrap.hxx> +#include <rtl/process.h> +#include <sal/log.hxx> + +#include <salinst.hxx> +#include <saldatabasic.hxx> +#include <config_vclplug.h> +#include <desktop/crashreport.hxx> + +#include <cstdio> +#include <Windows.h> + +extern "C" { +typedef SalInstance*(*salFactoryProc)(); +} + +namespace { + +// HACK to obtain Application::IsHeadlessModeEnabled early on, before +// Application::EnableHeadlessMode has potentially been called: +bool IsHeadlessModeRequested() +{ + if (Application::IsHeadlessModeEnabled()) { + return true; + } + sal_uInt32 n = rtl_getAppCommandArgCount(); + for (sal_uInt32 i = 0; i < n; ++i) { + OUString arg; + rtl_getAppCommandArg(i, &arg.pData); + if ( arg == "--headless" || arg == "-headless" ) { + return true; + } + } + return false; +} + +} + +static oslModule pCloseModule = nullptr; + +static SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = false ) +{ + SalInstance* pInst = nullptr; + OUString aModule( +#ifdef SAL_DLLPREFIX + SAL_DLLPREFIX +#endif + "vclplug_" + rModuleBase + "lo" SAL_DLLEXTENSION ); + + osl::Module aMod; + if (aMod.loadRelative(reinterpret_cast<oslGenericFunction>(&tryInstance), aModule, SAL_LOADMODULE_GLOBAL)) + { + salFactoryProc aProc = reinterpret_cast<salFactoryProc>(aMod.getFunctionSymbol("create_SalInstance")); + if (aProc) + { + pInst = aProc(); + SAL_INFO( + "vcl.plugadapt", + "sal plugin " << aModule << " produced instance " << pInst); + if (pInst) + { + pCloseModule = static_cast<oslModule>(aMod); + aMod.release(); + pCloseModule = nullptr; + } + } + else + { + SAL_WARN( + "vcl.plugadapt", + "could not load symbol create_SalInstance from shared object " + << aModule); + } + } + else if (bForce) + { + SAL_WARN("vcl.plugadapt", "could not load shared object " << aModule); + } + else + { + SAL_INFO("vcl.plugadapt", "could not load shared object " << aModule); + } + + // coverity[leaked_storage] - this is on purpose + return pInst; +} + +SalInstance *CreateSalInstance() +{ + SalInstance *pInst = nullptr; + + OUString aUsePlugin; + rtl::Bootstrap::get( "SAL_USE_VCLPLUGIN", aUsePlugin ); + + if( !aUsePlugin.isEmpty() ) + pInst = tryInstance( aUsePlugin, true ); + + // fallback, try everything + static const char* const pPlugin[] = { "win" }; + + for ( int i = 0; !pInst && i != SAL_N_ELEMENTS(pPlugin); ++i ) + pInst = tryInstance( OUString::createFromAscii( pPlugin[ i ] ) ); + + if( ! pInst ) + { + std::fprintf( stderr, "no suitable windowing system found, exiting.\n" ); + _exit( 1 ); + } + + // acquire SolarMutex + pInst->AcquireYieldMutex(); + + return pInst; +} + +void DestroySalInstance( SalInstance *pInst ) +{ + // release SolarMutex + pInst->ReleaseYieldMutexAll(); + + delete pInst; + if( pCloseModule ) + osl_unloadModule( pCloseModule ); +} + +void InitSalData() +{ +} + +void DeInitSalData() +{ +} + +void InitSalMain() +{ +} + +void SalAbort( const OUString& rErrorText, bool bDumpCore ) +{ + if( rErrorText.isEmpty() ) + std::fprintf( stderr, "Application Error\n" ); + else + { + CrashReporter::AddKeyValue("AbortMessage", rErrorText); + std::fprintf( stderr, "%s\n", OUStringToOString(rErrorText, osl_getThreadTextEncoding()).getStr() ); + } + if( bDumpCore ) + abort(); + else + _exit(1); +} + +const OUString& SalGetDesktopEnvironment() +{ + static OUString aDesktopEnvironment( "Windows" ); + return aDesktopEnvironment; +} + +SalData::SalData() : + m_pInstance(nullptr), + m_pPIManager(nullptr) +{ +} + +SalData::~SalData() COVERITY_NOEXCEPT_FALSE +{ +} + +bool HasAtHook() +{ + BOOL bIsRunning = FALSE; + // pvParam must be BOOL + return SystemParametersInfoW(SPI_GETSCREENREADER, 0, &bIsRunning, 0) + && bIsRunning; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |