14905a190SSebastian Spaeth /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
244cfc7cbSMichael Meeks /*
344cfc7cbSMichael Meeks * This file is part of the LibreOffice project.
48ab086b6SJens-Heiner Rechtien *
544cfc7cbSMichael Meeks * This Source Code Form is subject to the terms of the Mozilla Public
644cfc7cbSMichael Meeks * License, v. 2.0. If a copy of the MPL was not distributed with this
744cfc7cbSMichael Meeks * file, You can obtain one at http://mozilla.org/MPL/2.0/.
877b6bbe4SRüdiger Timm *
944cfc7cbSMichael Meeks * This file incorporates work covered by the following license notice:
1077b6bbe4SRüdiger Timm *
1144cfc7cbSMichael Meeks * Licensed to the Apache Software Foundation (ASF) under one or more
1244cfc7cbSMichael Meeks * contributor license agreements. See the NOTICE file distributed
1344cfc7cbSMichael Meeks * with this work for additional information regarding copyright
1444cfc7cbSMichael Meeks * ownership. The ASF licenses this file to you under the Apache
1544cfc7cbSMichael Meeks * License, Version 2.0 (the "License"); you may not use this file
1644cfc7cbSMichael Meeks * except in compliance with the License. You may obtain a copy of
1744cfc7cbSMichael Meeks * the License at http://www.apache.org/licenses/LICENSE-2.0 .
1844cfc7cbSMichael Meeks */
198ab086b6SJens-Heiner Rechtien
208ab086b6SJens-Heiner Rechtien #include <string.h>
21a18b02e8SFridrich Štrba #include <svsys.h>
228ab086b6SJens-Heiner Rechtien #include <process.h>
2319ba1fafSPhilipp Lohmann [pl]
24ce3951edSStephan Bergmann #include <osl/conditn.hxx>
259e18c9eeSVladimir Glazounov #include <osl/file.hxx>
26a43b79f6SGabor Kelemen #include <sal/log.hxx>
276256797dSGabor Kelemen #include <tools/debug.hxx>
28fa12f373SStephan Bergmann #include <tools/time.hxx>
2903157610SJan-Marek Glogowski #include <comphelper/processfactory.hxx>
3011fd73acSStephan Bergmann #include <comphelper/solarmutex.hxx>
31dbac52a2SJan-Marek Glogowski #include <comphelper/windowserrorstring.hxx>
3203157610SJan-Marek Glogowski #include <com/sun/star/uno/Reference.h>
331944e3ddSMike Kaganski #include <o3tl/char16_t2wchar_t.hxx>
340bcb62c6SMike Kaganski #include <o3tl/temporary.hxx>
3519ba1fafSPhilipp Lohmann [pl]
3603157610SJan-Marek Glogowski #include <dndhelper.hxx>
37249e3d6dSChris Sherlock #include <vcl/inputtypes.hxx>
380bea1d80SMichael Meeks #include <vcl/opengl/OpenGLContext.hxx>
3903157610SJan-Marek Glogowski #include <vcl/sysdata.hxx>
40d9fbaf24SJan Holesovsky #include <vcl/timer.hxx>
411698debeSJan-Marek Glogowski #include <vclpluginapi.h>
4219ba1fafSPhilipp Lohmann [pl]
4303157610SJan-Marek Glogowski #include <win/dnd_source.hxx>
4403157610SJan-Marek Glogowski #include <win/dnd_target.hxx>
45e0ac7685SStephan Bergmann #include <win/wincomp.hxx>
46e0ac7685SStephan Bergmann #include <win/salids.hrc>
47e0ac7685SStephan Bergmann #include <win/saldata.hxx>
48e0ac7685SStephan Bergmann #include <win/salinst.h>
49e0ac7685SStephan Bergmann #include <win/salframe.h>
50e0ac7685SStephan Bergmann #include <win/salobj.h>
51e0ac7685SStephan Bergmann #include <win/saltimer.h>
52e0ac7685SStephan Bergmann #include <win/salbmp.h>
53e0ac7685SStephan Bergmann #include <win/winlayout.hxx>
5419ba1fafSPhilipp Lohmann [pl]
555c4f872aSLuboš Luňák #include <config_features.h>
565c4f872aSLuboš Luňák #include <vcl/skia/SkiaHelper.hxx>
57994b8e52SLuboš Luňák #include <config_skia.h>
585c4f872aSLuboš Luňák #include <skia/salbmp.hxx>
5931b2c104SLuboš Luňák #include <skia/win/gdiimpl.hxx>
605c4f872aSLuboš Luňák
61e0ac7685SStephan Bergmann #include <salsys.hxx>
622f382d6cSJens-Heiner Rechtien
631b206f37SMarkus Mohrhard #include <desktop/crashreport.hxx>
641b206f37SMarkus Mohrhard
65e0ac7685SStephan Bergmann #include <prewin.h>
661a494d9aSAshod Nakashian
671f7e587cSTor Lillqvist #include <gdiplus.h>
681f7e587cSTor Lillqvist #include <shlobj.h>
6950afe624SJens-Heiner Rechtien
70e0ac7685SStephan Bergmann #include <postwin.h>
71ba68436eSMichael Stahl
72928b1b04SStephan Bergmann static LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam );
738ab086b6SJens-Heiner Rechtien
744c93de2cSNoel Grandin class SalYieldMutex : public comphelper::SolarMutex
758ab086b6SJens-Heiner Rechtien {
769771e616SStephan Bergmann public: // for ImplSalYield() and ImplSalYieldMutexAcquireWithWait()
779771e616SStephan Bergmann osl::Condition m_condition; /// for MsgWaitForMultipleObjects()
789771e616SStephan Bergmann
793840aedeSJan-Marek Glogowski protected:
803840aedeSJan-Marek Glogowski virtual void doAcquire( sal_uInt32 nLockCount ) override;
813840aedeSJan-Marek Glogowski virtual sal_uInt32 doRelease( bool bUnlockAll ) override;
823840aedeSJan-Marek Glogowski
833840aedeSJan-Marek Glogowski static void BeforeReleaseHandler();
848ab086b6SJens-Heiner Rechtien
858ab086b6SJens-Heiner Rechtien public:
863840aedeSJan-Marek Glogowski explicit SalYieldMutex();
878ab086b6SJens-Heiner Rechtien
883840aedeSJan-Marek Glogowski virtual bool IsCurrentThread() const override;
894baec725SJan-Marek Glogowski virtual bool tryToAcquire() override;
908ab086b6SJens-Heiner Rechtien };
918ab086b6SJens-Heiner Rechtien
SalYieldMutex()923840aedeSJan-Marek Glogowski SalYieldMutex::SalYieldMutex()
938ab086b6SJens-Heiner Rechtien {
943840aedeSJan-Marek Glogowski SetBeforeReleaseHandler( &SalYieldMutex::BeforeReleaseHandler );
958ab086b6SJens-Heiner Rechtien }
968ab086b6SJens-Heiner Rechtien
BeforeReleaseHandler()973840aedeSJan-Marek Glogowski void SalYieldMutex::BeforeReleaseHandler()
989c997095SArmin Le Grand {
9916b0e217SMichael Meeks OpenGLContext::prepareForYield();
1000bea1d80SMichael Meeks
1013840aedeSJan-Marek Glogowski if ( GetSalData()->mnAppThreadId != GetCurrentThreadId() )
102edac9385SMichael Stahl {
1036bd12d86Sth // If we don't call these message, the Output from the
1046bd12d86Sth // Java clients doesn't come in the right order
1056bd12d86Sth GdiFlush();
1068ab086b6SJens-Heiner Rechtien }
1078ab086b6SJens-Heiner Rechtien }
1088ab086b6SJens-Heiner Rechtien
109ea2be4efSMichael Stahl /// note: while VCL is fully up and running (other threads started and
110ea2be4efSMichael Stahl /// before shutdown), the main thread must acquire SolarMutex only via
111ea2be4efSMichael Stahl /// this function to avoid deadlock
doAcquire(sal_uInt32 nLockCount)1123840aedeSJan-Marek Glogowski void SalYieldMutex::doAcquire( sal_uInt32 nLockCount )
1138ab086b6SJens-Heiner Rechtien {
1147c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
1159771e616SStephan Bergmann if ( pInst && pInst->IsMainThread() )
1168ab086b6SJens-Heiner Rechtien {
1179771e616SStephan Bergmann if ( pInst->m_nNoYieldLock )
1184baec725SJan-Marek Glogowski return;
1199771e616SStephan Bergmann // tdf#96887 If this is the main thread, then we must wait for two things:
1209771e616SStephan Bergmann // - the yield mutex being unlocked
1219771e616SStephan Bergmann // - SendMessage() being triggered
1229771e616SStephan Bergmann // This can nicely be done using MsgWaitForMultipleObjects, which is called in
1239771e616SStephan Bergmann // m_condition.wait(). The 2nd one is
1249771e616SStephan Bergmann // needed because if we don't reschedule, then we create deadlocks if a
1259771e616SStephan Bergmann // Window's create/destroy is called via SendMessage() from another thread.
1269771e616SStephan Bergmann // Have a look at the osl_waitCondition implementation for more info.
1279771e616SStephan Bergmann do {
1287b4b032dSNoel Grandin // Calling Condition::reset frequently turns out to be a little expensive,
1297b4b032dSNoel Grandin // and the vast majority of the time there is no contention, so first
1307b4b032dSNoel Grandin // try just acquiring the mutex.
1317b4b032dSNoel Grandin if (m_aMutex.tryToAcquire())
1327b4b032dSNoel Grandin break;
1339771e616SStephan Bergmann // reset condition *before* acquiring!
1349771e616SStephan Bergmann m_condition.reset();
1359771e616SStephan Bergmann if (m_aMutex.tryToAcquire())
1369771e616SStephan Bergmann break;
1379771e616SStephan Bergmann // wait for SalYieldMutex::release() to set the condition
1389771e616SStephan Bergmann osl::Condition::Result res = m_condition.wait();
1399771e616SStephan Bergmann assert(osl::Condition::Result::result_ok == res);
14043768200SStephan Bergmann (void) res;
1411b9d48f5SJan-Marek Glogowski }
1429771e616SStephan Bergmann while ( true );
1439771e616SStephan Bergmann }
1449771e616SStephan Bergmann else
1453840aedeSJan-Marek Glogowski m_aMutex.acquire();
1463840aedeSJan-Marek Glogowski ++m_nCount;
1473840aedeSJan-Marek Glogowski --nLockCount;
1483840aedeSJan-Marek Glogowski
1494c93de2cSNoel Grandin comphelper::SolarMutex::doAcquire( nLockCount );
1503840aedeSJan-Marek Glogowski }
1513840aedeSJan-Marek Glogowski
doRelease(const bool bUnlockAll)1523840aedeSJan-Marek Glogowski sal_uInt32 SalYieldMutex::doRelease( const bool bUnlockAll )
1533840aedeSJan-Marek Glogowski {
1547c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
155bf0a63dcSJan-Marek Glogowski if ( pInst && pInst->m_nNoYieldLock && pInst->IsMainThread() )
1564baec725SJan-Marek Glogowski return 1;
1573840aedeSJan-Marek Glogowski
1589771e616SStephan Bergmann sal_uInt32 nCount = comphelper::SolarMutex::doRelease( bUnlockAll );
1599771e616SStephan Bergmann // wake up ImplSalYieldMutexAcquireWithWait() after release
1609771e616SStephan Bergmann if ( 0 == m_nCount )
1619771e616SStephan Bergmann m_condition.set();
1629771e616SStephan Bergmann return nCount;
1633840aedeSJan-Marek Glogowski }
1643840aedeSJan-Marek Glogowski
tryToAcquire()1654baec725SJan-Marek Glogowski bool SalYieldMutex::tryToAcquire()
1664baec725SJan-Marek Glogowski {
1677c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
1684baec725SJan-Marek Glogowski if ( pInst )
1694baec725SJan-Marek Glogowski {
170bf0a63dcSJan-Marek Glogowski if ( pInst->m_nNoYieldLock && pInst->IsMainThread() )
1714baec725SJan-Marek Glogowski return true;
1724baec725SJan-Marek Glogowski else
1734c93de2cSNoel Grandin return comphelper::SolarMutex::tryToAcquire();
1744baec725SJan-Marek Glogowski }
1754baec725SJan-Marek Glogowski else
1764baec725SJan-Marek Glogowski return false;
1774baec725SJan-Marek Glogowski }
1784baec725SJan-Marek Glogowski
ImplSalYieldMutexAcquireWithWait(sal_uInt32 nCount)179adbf7da7SStephan Bergmann void ImplSalYieldMutexAcquireWithWait( sal_uInt32 nCount )
1803840aedeSJan-Marek Glogowski {
1817c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
1823840aedeSJan-Marek Glogowski if ( pInst )
1830c27134fSJan-Marek Glogowski pInst->GetYieldMutex()->acquire( nCount );
1849c997095SArmin Le Grand }
1858ab086b6SJens-Heiner Rechtien
ImplSalYieldMutexTryToAcquire()186381f8a56SChris Sherlock bool ImplSalYieldMutexTryToAcquire()
1878ab086b6SJens-Heiner Rechtien {
1887c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
1890c27134fSJan-Marek Glogowski return pInst && pInst->GetYieldMutex()->tryToAcquire();
1908ab086b6SJens-Heiner Rechtien }
1918ab086b6SJens-Heiner Rechtien
ImplSalYieldMutexRelease()1928ab086b6SJens-Heiner Rechtien void ImplSalYieldMutexRelease()
1938ab086b6SJens-Heiner Rechtien {
1947c52d86fSNoel Grandin WinSalInstance* pInst = GetSalData()->mpInstance;
1958ab086b6SJens-Heiner Rechtien if ( pInst )
1966bd12d86Sth {
1976bd12d86Sth GdiFlush();
1980c27134fSJan-Marek Glogowski pInst->GetYieldMutex()->release();
1998ab086b6SJens-Heiner Rechtien }
2006bd12d86Sth }
2018ab086b6SJens-Heiner Rechtien
IsCurrentThread() const2023840aedeSJan-Marek Glogowski bool SalYieldMutex::IsCurrentThread() const
2038ab086b6SJens-Heiner Rechtien {
204bf0a63dcSJan-Marek Glogowski if ( !GetSalData()->mpInstance->m_nNoYieldLock )
205ec3916d4SStephan Bergmann return SolarMutex::IsCurrentThread();
2064baec725SJan-Marek Glogowski else
2077c52d86fSNoel Grandin return GetSalData()->mpInstance->IsMainThread();
2088ab086b6SJens-Heiner Rechtien }
2098ab086b6SJens-Heiner Rechtien
initKeyCodeMap()21015641441SOliver Bolte void SalData::initKeyCodeMap()
2118ab086b6SJens-Heiner Rechtien {
212d6b1e563SMike Kaganski auto initKey = [this](wchar_t ch, sal_uInt16 key)
213d6b1e563SMike Kaganski {
214d6b1e563SMike Kaganski if (UINT vkey = LOWORD(VkKeyScanW(ch)); vkey < 0xffff)
215d6b1e563SMike Kaganski maVKMap[vkey] = key;
216d6b1e563SMike Kaganski };
21715641441SOliver Bolte
2180761614cSJuergen Funk maVKMap.clear();
2190761614cSJuergen Funk
220362a21d3SMike Kaganski initKey( L'+', KEY_ADD );
221362a21d3SMike Kaganski initKey( L'-', KEY_SUBTRACT );
222362a21d3SMike Kaganski initKey( L'*', KEY_MULTIPLY );
223362a21d3SMike Kaganski initKey( L'/', KEY_DIVIDE );
224362a21d3SMike Kaganski initKey( L'.', KEY_POINT );
225362a21d3SMike Kaganski initKey( L',', KEY_COMMA );
226362a21d3SMike Kaganski initKey( L'<', KEY_LESS );
227362a21d3SMike Kaganski initKey( L'>', KEY_GREATER );
228362a21d3SMike Kaganski initKey( L'=', KEY_EQUAL );
229362a21d3SMike Kaganski initKey( L'~', KEY_TILDE );
230362a21d3SMike Kaganski initKey( L'`', KEY_QUOTELEFT );
231362a21d3SMike Kaganski initKey( L'[', KEY_BRACKETLEFT );
232362a21d3SMike Kaganski initKey( L']', KEY_BRACKETRIGHT );
233362a21d3SMike Kaganski initKey( L';', KEY_SEMICOLON );
234362a21d3SMike Kaganski initKey( L'\'', KEY_QUOTERIGHT );
235d156e891SNoel Grandin initKey( L'}', KEY_RIGHTCURLYBRACKET );
236ca745119SGökay Şatır initKey( L'#', KEY_NUMBERSIGN);
237e056c1ceSJulien Nabet initKey( L':', KEY_COLON );
2388ab086b6SJens-Heiner Rechtien }
2398ab086b6SJens-Heiner Rechtien
240a45bdc49SJens-Heiner Rechtien // SalData
2410ce0c369SAlexander Wilms
SalData()242a45bdc49SJens-Heiner Rechtien SalData::SalData()
243c35f8114SMike Kaganski : sal::systools::CoInitializeGuard(COINIT_APARTMENTTHREADED, false,
244c35f8114SMike Kaganski sal::systools::CoInitializeGuard::WhenFailed::NoThrow)
245c35f8114SMike Kaganski // put main thread in Single Threaded Apartment (STA)
246a45bdc49SJens-Heiner Rechtien {
24748b1c889SStephan Bergmann mhInst = nullptr; // default instance handle
248a45bdc49SJens-Heiner Rechtien mnCmdShow = 0; // default frame show style
24948b1c889SStephan Bergmann mhSalObjMsgHook = nullptr; // hook to get interesting msg for SalObject
25048b1c889SStephan Bergmann mhWantLeaveMsg = nullptr; // window handle, that want a MOUSELEAVE message
2517c52d86fSNoel Grandin mpInstance = nullptr; // pointer of first instance
25248b1c889SStephan Bergmann mpFirstFrame = nullptr; // pointer of first frame
25348b1c889SStephan Bergmann mpFirstObject = nullptr; // pointer of first object window
25448b1c889SStephan Bergmann mpFirstVD = nullptr; // first VirDev
25548b1c889SStephan Bergmann mpFirstPrinter = nullptr; // first printing printer
25648b1c889SStephan Bergmann mh50Bmp = nullptr; // 50% Bitmap
25748b1c889SStephan Bergmann mh50Brush = nullptr; // 50% Brush
258a45bdc49SJens-Heiner Rechtien int i;
259a45bdc49SJens-Heiner Rechtien for(i=0; i<MAX_STOCKPEN; i++)
260a45bdc49SJens-Heiner Rechtien {
261a45bdc49SJens-Heiner Rechtien maStockPenColorAry[i] = 0;
26248b1c889SStephan Bergmann mhStockPenAry[i] = nullptr;
263a45bdc49SJens-Heiner Rechtien }
264a45bdc49SJens-Heiner Rechtien for(i=0; i<MAX_STOCKBRUSH; i++)
265a45bdc49SJens-Heiner Rechtien {
266a45bdc49SJens-Heiner Rechtien maStockBrushColorAry[i] = 0;
26748b1c889SStephan Bergmann mhStockBrushAry[i] = nullptr;
268a45bdc49SJens-Heiner Rechtien }
269a45bdc49SJens-Heiner Rechtien mnStockPenCount = 0; // count of static pens
270a45bdc49SJens-Heiner Rechtien mnStockBrushCount = 0; // count of static brushes
271275dbf60SChristian M. Heller mnSalObjWantKeyEvt = 0; // KeyEvent for the SalObj hook
2727790b6a4SMichael Stahl mbObjClassInit = false; // is SALOBJECTCLASS initialised
273b5a2dbdbSAndrea Gelmini mnAppThreadId = 0; // Id from Application-Thread
27448b1c889SStephan Bergmann mpFirstIcon = nullptr; // icon cache, points to first icon, NULL if none
275*87ef0041SMike Kaganski mpTempFontItem = nullptr;
2767790b6a4SMichael Stahl mbThemeChanged = false; // true if visual theme was changed: throw away theme handles
2777790b6a4SMichael Stahl mbThemeMenuSupport = false;
278a45bdc49SJens-Heiner Rechtien
27950afe624SJens-Heiner Rechtien // init with NULL
28050afe624SJens-Heiner Rechtien gdiplusToken = 0;
28150afe624SJens-Heiner Rechtien
28215641441SOliver Bolte initKeyCodeMap();
28315641441SOliver Bolte
284a45bdc49SJens-Heiner Rechtien SetSalData( this );
285a45bdc49SJens-Heiner Rechtien initNWF();
2861698debeSJan-Marek Glogowski
2871698debeSJan-Marek Glogowski static Gdiplus::GdiplusStartupInput gdiplusStartupInput;
2881698debeSJan-Marek Glogowski Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
289a45bdc49SJens-Heiner Rechtien }
290a45bdc49SJens-Heiner Rechtien
~SalData()291a45bdc49SJens-Heiner Rechtien SalData::~SalData()
292a45bdc49SJens-Heiner Rechtien {
293a45bdc49SJens-Heiner Rechtien deInitNWF();
29448b1c889SStephan Bergmann SetSalData( nullptr );
2958ab086b6SJens-Heiner Rechtien
2961698debeSJan-Marek Glogowski if (gdiplusToken)
2971698debeSJan-Marek Glogowski Gdiplus::GdiplusShutdown(gdiplusToken);
29850afe624SJens-Heiner Rechtien }
29950afe624SJens-Heiner Rechtien
OSSupportsDarkMode()300a3f40088SCaolán McNamara bool OSSupportsDarkMode()
301a3f40088SCaolán McNamara {
3020bf5756bSMichael Weghorn return WinSalInstance::getWindowsBuildNumber() >= 18362;
303a3f40088SCaolán McNamara }
304a3f40088SCaolán McNamara
305a0202e0bSStephan Bergmann namespace {
306a0202e0bSStephan Bergmann
307a3f40088SCaolán McNamara enum PreferredAppMode
308a3f40088SCaolán McNamara {
309a3f40088SCaolán McNamara Default,
310a3f40088SCaolán McNamara AllowDark,
311a3f40088SCaolán McNamara ForceDark,
312a3f40088SCaolán McNamara ForceLight,
313a3f40088SCaolán McNamara Max
314a3f40088SCaolán McNamara };
315a3f40088SCaolán McNamara
316a0202e0bSStephan Bergmann }
317a0202e0bSStephan Bergmann
3181698debeSJan-Marek Glogowski extern "C" {
create_SalInstance()3191698debeSJan-Marek Glogowski VCLPLUG_WIN_PUBLIC SalInstance* create_SalInstance()
3201698debeSJan-Marek Glogowski {
3211698debeSJan-Marek Glogowski SalData* pSalData = new SalData();
3228ab086b6SJens-Heiner Rechtien
323e143c83bSMike Kaganski STARTUPINFOW aSI{ .cb = sizeof(aSI) };
324362a21d3SMike Kaganski GetStartupInfoW( &aSI );
3251698debeSJan-Marek Glogowski pSalData->mhInst = GetModuleHandleW( nullptr );
3261698debeSJan-Marek Glogowski pSalData->mnCmdShow = aSI.wShowWindow;
3278ab086b6SJens-Heiner Rechtien
3288ab086b6SJens-Heiner Rechtien pSalData->mnAppThreadId = GetCurrentThreadId();
3298ab086b6SJens-Heiner Rechtien
330a3f40088SCaolán McNamara static bool bSetAllowDarkMode = OSSupportsDarkMode(); // too early to additionally check LibreOffice's config
331a3f40088SCaolán McNamara if (bSetAllowDarkMode)
332a3f40088SCaolán McNamara {
333a3f40088SCaolán McNamara typedef PreferredAppMode(WINAPI* SetPreferredAppMode_t)(PreferredAppMode);
334a3f40088SCaolán McNamara if (HINSTANCE hUxthemeLib = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
335a3f40088SCaolán McNamara {
336a3f40088SCaolán McNamara if (auto SetPreferredAppMode = reinterpret_cast<SetPreferredAppMode_t>(GetProcAddress(hUxthemeLib, MAKEINTRESOURCEA(135))))
337a3f40088SCaolán McNamara SetPreferredAppMode(AllowDark);
338a3f40088SCaolán McNamara FreeLibrary(hUxthemeLib);
339a3f40088SCaolán McNamara }
340a3f40088SCaolán McNamara }
341a3f40088SCaolán McNamara
3428ab086b6SJens-Heiner Rechtien // register frame class
3438ab086b6SJens-Heiner Rechtien WNDCLASSEXW aWndClassEx;
3448ab086b6SJens-Heiner Rechtien aWndClassEx.cbSize = sizeof( aWndClassEx );
3458ab086b6SJens-Heiner Rechtien aWndClassEx.style = CS_OWNDC;
3468ab086b6SJens-Heiner Rechtien aWndClassEx.lpfnWndProc = SalFrameWndProcW;
3478ab086b6SJens-Heiner Rechtien aWndClassEx.cbClsExtra = 0;
3488ab086b6SJens-Heiner Rechtien aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA;
3498ab086b6SJens-Heiner Rechtien aWndClassEx.hInstance = pSalData->mhInst;
35048b1c889SStephan Bergmann aWndClassEx.hCursor = nullptr;
35148b1c889SStephan Bergmann aWndClassEx.hbrBackground = nullptr;
35248b1c889SStephan Bergmann aWndClassEx.lpszMenuName = nullptr;
3538ab086b6SJens-Heiner Rechtien aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEW;
35430febe79SJan Holesovsky ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm );
35537c198cfSJesús Corrius if ( !RegisterClassExW( &aWndClassEx ) )
35648b1c889SStephan Bergmann return nullptr;
3570c2a2e1aSth
35848b1c889SStephan Bergmann aWndClassEx.hIcon = nullptr;
35948b1c889SStephan Bergmann aWndClassEx.hIconSm = nullptr;
3608ab086b6SJens-Heiner Rechtien aWndClassEx.style |= CS_SAVEBITS;
3610c2a2e1aSth aWndClassEx.lpszClassName = SAL_SUBFRAME_CLASSNAMEW;
36237c198cfSJesús Corrius if ( !RegisterClassExW( &aWndClassEx ) )
36348b1c889SStephan Bergmann return nullptr;
3648ab086b6SJens-Heiner Rechtien
3652f382d6cSJens-Heiner Rechtien // shadow effect for popups on XP
3662f382d6cSJens-Heiner Rechtien aWndClassEx.style |= CS_DROPSHADOW;
3672f382d6cSJens-Heiner Rechtien aWndClassEx.lpszClassName = SAL_TMPSUBFRAME_CLASSNAMEW;
36837c198cfSJesús Corrius if ( !RegisterClassExW( &aWndClassEx ) )
36948b1c889SStephan Bergmann return nullptr;
3702f382d6cSJens-Heiner Rechtien
3718ab086b6SJens-Heiner Rechtien aWndClassEx.style = 0;
3728ab086b6SJens-Heiner Rechtien aWndClassEx.lpfnWndProc = SalComWndProcW;
3738ab086b6SJens-Heiner Rechtien aWndClassEx.cbWndExtra = 0;
3748ab086b6SJens-Heiner Rechtien aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW;
37537c198cfSJesús Corrius if ( !RegisterClassExW( &aWndClassEx ) )
37648b1c889SStephan Bergmann return nullptr;
3778ab086b6SJens-Heiner Rechtien
37837c198cfSJesús Corrius HWND hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW,
37948b1c889SStephan Bergmann L"", WS_POPUP, 0, 0, 0, 0, nullptr, nullptr,
38048b1c889SStephan Bergmann pSalData->mhInst, nullptr );
3818ab086b6SJens-Heiner Rechtien if ( !hComWnd )
38248b1c889SStephan Bergmann return nullptr;
3838ab086b6SJens-Heiner Rechtien
384f3d5aa2bSKurt Zenker WinSalInstance* pInst = new WinSalInstance;
3858ab086b6SJens-Heiner Rechtien
3868ab086b6SJens-Heiner Rechtien // init instance (only one instance in this version !!!)
3877c52d86fSNoel Grandin pSalData->mpInstance = pInst;
388f3d5aa2bSKurt Zenker pInst->mhInst = pSalData->mhInst;
389f3d5aa2bSKurt Zenker pInst->mhComWnd = hComWnd;
3908ab086b6SJens-Heiner Rechtien
3918ab086b6SJens-Heiner Rechtien // init static GDI Data
3928ab086b6SJens-Heiner Rechtien ImplInitSalGDI();
3938ab086b6SJens-Heiner Rechtien
3948ab086b6SJens-Heiner Rechtien return pInst;
3958ab086b6SJens-Heiner Rechtien }
3968ab086b6SJens-Heiner Rechtien }
3978ab086b6SJens-Heiner Rechtien
WinSalInstance()398f3d5aa2bSKurt Zenker WinSalInstance::WinSalInstance()
39943635b47SGabor Kelemen : SalInstance(std::make_unique<SalYieldMutex>())
400f222cec7SCaolán McNamara , mhInst( nullptr )
4010c27134fSJan-Marek Glogowski , mhComWnd( nullptr )
402bf0a63dcSJan-Marek Glogowski , m_nNoYieldLock( 0 )
4038ab086b6SJens-Heiner Rechtien {
4041698debeSJan-Marek Glogowski ImplSVData* pSVData = ImplGetSVData();
4051698debeSJan-Marek Glogowski pSVData->maAppData.mxToolkitName = OUString("win");
40650238bddSJan-Marek Glogowski m_bSupportsOpenGL = true;
407a3d3e076SLuboš Luňák WinSkiaSalGraphicsImpl::prepareSkia();
4088ab086b6SJens-Heiner Rechtien }
4098ab086b6SJens-Heiner Rechtien
~WinSalInstance()410f3d5aa2bSKurt Zenker WinSalInstance::~WinSalInstance()
4118ab086b6SJens-Heiner Rechtien {
4121698debeSJan-Marek Glogowski ImplFreeSalGDI();
413f3d5aa2bSKurt Zenker DestroyWindow( mhComWnd );
414ea5eb463SLuboš Luňák SkiaHelper::cleanup();
4158ab086b6SJens-Heiner Rechtien }
4168ab086b6SJens-Heiner Rechtien
AfterAppInit()4174ff2ee08SNoel Grandin void WinSalInstance::AfterAppInit()
4184ff2ee08SNoel Grandin {
4194ff2ee08SNoel Grandin // (1) Ideally this would be done at the place that creates the thread, but since this thread is normally
4204ff2ee08SNoel Grandin // just the default/main thread, that is not possible.
4214ff2ee08SNoel Grandin // (2) Don't do this on unix, where it causes tools like pstree on Linux to
4224ff2ee08SNoel Grandin // confusingly report soffice.bin as VCL Main instead.
4234ff2ee08SNoel Grandin osl_setThreadName("VCL Main");
4244ff2ee08SNoel Grandin }
4254ff2ee08SNoel Grandin
ImplSalDispatchMessage(const MSG * pMsg)4268ba60ca4SJan-Marek Glogowski static LRESULT ImplSalDispatchMessage( const MSG* pMsg )
4278ab086b6SJens-Heiner Rechtien {
4288ab086b6SJens-Heiner Rechtien SalData* pSalData = GetSalData();
42947ee8098SJan-Marek Glogowski if ( pSalData->mpFirstObject && ImplSalPreDispatchMsg( pMsg ) )
43047ee8098SJan-Marek Glogowski return 0;
43150c62725STor Lillqvist LRESULT lResult = DispatchMessageW( pMsg );
4328ab086b6SJens-Heiner Rechtien if ( pSalData->mpFirstObject )
4338ba60ca4SJan-Marek Glogowski ImplSalPostDispatchMsg( pMsg );
43447ee8098SJan-Marek Glogowski return lResult;
4358ab086b6SJens-Heiner Rechtien }
4368ab086b6SJens-Heiner Rechtien
437dbac52a2SJan-Marek Glogowski // probably can't be static, because of SalTimer friend? (static gives C4211)
ImplSalYield(const bool bWait,const bool bHandleAllCurrentEvents)438dbac52a2SJan-Marek Glogowski bool ImplSalYield(const bool bWait, const bool bHandleAllCurrentEvents)
4398ab086b6SJens-Heiner Rechtien {
440dbac52a2SJan-Marek Glogowski // used to abort further message processing on tick count wraps
4419679fb26SJan-Marek Glogowski static sal_uInt32 nLastTicks = 0;
44235a25475SJan-Marek Glogowski
443dbac52a2SJan-Marek Glogowski // we should never yield in m_nNoYieldLock mode!
444dbac52a2SJan-Marek Glogowski const bool bNoYieldLock = (GetSalData()->mpInstance->m_nNoYieldLock > 0);
44535a25475SJan-Marek Glogowski assert(!bNoYieldLock);
44635a25475SJan-Marek Glogowski if (bNoYieldLock)
44735a25475SJan-Marek Glogowski return false;
4488ab086b6SJens-Heiner Rechtien
449dbac52a2SJan-Marek Glogowski MSG aMsg;
450dbac52a2SJan-Marek Glogowski bool bWasMsg = false, bWasTimeoutMsg = false;
451dbac52a2SJan-Marek Glogowski WinSalTimer* pTimer = static_cast<WinSalTimer*>(ImplGetSVData()->maSchedCtx.mpSalTimer);
4529679fb26SJan-Marek Glogowski
453dbac52a2SJan-Marek Glogowski sal_uInt32 nCurTicks = GetTickCount();
454dbac52a2SJan-Marek Glogowski
45576c27ae4SOliver Bolte do
4568ab086b6SJens-Heiner Rechtien {
457dbac52a2SJan-Marek Glogowski if (!PeekMessageW(&aMsg, nullptr, 0, 0, PM_REMOVE))
458dbac52a2SJan-Marek Glogowski break;
459dbac52a2SJan-Marek Glogowski
46037436815SJan-Marek Glogowski bWasMsg = true;
4618ab086b6SJens-Heiner Rechtien TranslateMessage(&aMsg);
46247ee8098SJan-Marek Glogowski LRESULT nRet = ImplSalDispatchMessage(&aMsg);
46347ee8098SJan-Marek Glogowski
464dbac52a2SJan-Marek Glogowski bWasTimeoutMsg |= (SAL_MSG_TIMER_CALLBACK == aMsg.message) && static_cast<bool>(nRet);
46547ee8098SJan-Marek Glogowski
466dbac52a2SJan-Marek Glogowski if (!bHandleAllCurrentEvents)
467dbac52a2SJan-Marek Glogowski break;
468fb4e7be5SJan-Marek Glogowski
469dbac52a2SJan-Marek Glogowski if ((aMsg.time > nCurTicks) && (nLastTicks <= nCurTicks || aMsg.time < nLastTicks))
4709679fb26SJan-Marek Glogowski break;
471448e9da1SJan-Marek Glogowski }
4729679fb26SJan-Marek Glogowski while( true );
4739679fb26SJan-Marek Glogowski
474fb4e7be5SJan-Marek Glogowski // 0ms timeouts are handled out-of-bounds to prevent busy-locking the
47596a0adacSAndrea Gelmini // event loop with timeout messages.
4761a97b9abSAndrea Gelmini // We ensure we never handle more than one timeout per call.
477fb4e7be5SJan-Marek Glogowski // This way we'll always process a normal system message.
478fb4e7be5SJan-Marek Glogowski if ( !bWasTimeoutMsg && pTimer && pTimer->IsDirectTimeout() )
479fb4e7be5SJan-Marek Glogowski {
480fb4e7be5SJan-Marek Glogowski pTimer->ImplHandleElapsedTimer();
481fb4e7be5SJan-Marek Glogowski bWasMsg = true;
482fb4e7be5SJan-Marek Glogowski }
483fb4e7be5SJan-Marek Glogowski
4849679fb26SJan-Marek Glogowski nLastTicks = nCurTicks;
48576c27ae4SOliver Bolte
486fb4e7be5SJan-Marek Glogowski if ( bWait && !bWasMsg )
48776c27ae4SOliver Bolte {
488dbac52a2SJan-Marek Glogowski switch (GetMessageW(&aMsg, nullptr, 0, 0))
48976c27ae4SOliver Bolte {
490dbac52a2SJan-Marek Glogowski case -1:
4912a20616dSvarshneydevansh SAL_WARN("vcl.schedule", "GetMessageW failed: " << comphelper::WindowsErrorString(GetLastError()));
492dbac52a2SJan-Marek Glogowski // should we std::abort() / SalAbort here?
493dbac52a2SJan-Marek Glogowski break;
494dbac52a2SJan-Marek Glogowski case 0:
495dbac52a2SJan-Marek Glogowski SAL_INFO("vcl.schedule", "GetMessageW received WM_QUIT while waiting");
496dbac52a2SJan-Marek Glogowski break;
497dbac52a2SJan-Marek Glogowski default:
498448e9da1SJan-Marek Glogowski bWasMsg = true;
49976c27ae4SOliver Bolte TranslateMessage(&aMsg);
50076c27ae4SOliver Bolte ImplSalDispatchMessage(&aMsg);
501dbac52a2SJan-Marek Glogowski break;
5028ab086b6SJens-Heiner Rechtien }
5038ab086b6SJens-Heiner Rechtien }
5049679fb26SJan-Marek Glogowski
505c6ff20f1SAndrea Gelmini // If we enabled ForceRealTimer mode skipping our direct timeout processing,
506c6ff20f1SAndrea Gelmini // mainly because some Windows API call spawns its own nested message loop,
507dbac52a2SJan-Marek Glogowski // switch back to our own processing (like after window resize or move)
508abe3af8eSJan-Marek Glogowski if ( pTimer )
509abe3af8eSJan-Marek Glogowski pTimer->SetForceRealTimer( false );
510abe3af8eSJan-Marek Glogowski
511d348035aSJan-Marek Glogowski return bWasMsg;
5128ab086b6SJens-Heiner Rechtien }
5138ab086b6SJens-Heiner Rechtien
IsMainThread() const514c0710abfSJan-Marek Glogowski bool WinSalInstance::IsMainThread() const
515c0710abfSJan-Marek Glogowski {
516c0710abfSJan-Marek Glogowski const SalData* pSalData = GetSalData();
517c0710abfSJan-Marek Glogowski return pSalData->mnAppThreadId == GetCurrentThreadId();
518c0710abfSJan-Marek Glogowski }
519c0710abfSJan-Marek Glogowski
DoYield(bool bWait,bool bHandleAllCurrentEvents)5204baec725SJan-Marek Glogowski bool WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents)
5218ab086b6SJens-Heiner Rechtien {
522d348035aSJan-Marek Glogowski bool bDidWork = false;
5234baec725SJan-Marek Glogowski SolarMutexReleaser aReleaser;
524c0710abfSJan-Marek Glogowski if ( !IsMainThread() )
5258ab086b6SJens-Heiner Rechtien {
526ce8bbb78SJan-Marek Glogowski bDidWork = SendMessageW( mhComWnd, SAL_MSG_THREADYIELD,
5279af8f190SStephan Bergmann WPARAM(false), static_cast<LPARAM>(bHandleAllCurrentEvents) );
528ce8bbb78SJan-Marek Glogowski if ( !bDidWork && bWait )
5294baec725SJan-Marek Glogowski {
5304baec725SJan-Marek Glogowski maWaitingYieldCond.reset();
5314baec725SJan-Marek Glogowski maWaitingYieldCond.wait();
5324baec725SJan-Marek Glogowski bDidWork = true;
5334baec725SJan-Marek Glogowski }
5348ab086b6SJens-Heiner Rechtien }
5358ab086b6SJens-Heiner Rechtien else
5368ab086b6SJens-Heiner Rechtien {
537d348035aSJan-Marek Glogowski bDidWork = ImplSalYield( bWait, bHandleAllCurrentEvents );
5384baec725SJan-Marek Glogowski if ( bDidWork )
5394baec725SJan-Marek Glogowski maWaitingYieldCond.set();
540ea3ce0b3SMichael Stahl }
5418ab086b6SJens-Heiner Rechtien
542d348035aSJan-Marek Glogowski return bDidWork;
5438ab086b6SJens-Heiner Rechtien }
5448ab086b6SJens-Heiner Rechtien
545d6b1e563SMike Kaganski namespace
546d6b1e563SMike Kaganski {
547d6b1e563SMike Kaganski struct NoYieldLockGuard
548d6b1e563SMike Kaganski {
NoYieldLockGuard__anonc363b8950311::NoYieldLockGuard549d6b1e563SMike Kaganski NoYieldLockGuard()
550d6b1e563SMike Kaganski : counter(InSendMessage() ? GetSalData()->mpInstance->m_nNoYieldLock : dummy())
551d6b1e563SMike Kaganski {
552d6b1e563SMike Kaganski ++counter;
553d6b1e563SMike Kaganski }
~NoYieldLockGuard__anonc363b8950311::NoYieldLockGuard554d6b1e563SMike Kaganski ~NoYieldLockGuard() { --counter; }
dummy__anonc363b8950311::NoYieldLockGuard555d6b1e563SMike Kaganski static decltype(WinSalInstance::m_nNoYieldLock)& dummy()
556d6b1e563SMike Kaganski {
557d6b1e563SMike Kaganski DBG_TESTSOLARMUTEX(); // called when !InSendMessage()
558d6b1e563SMike Kaganski static decltype(WinSalInstance::m_nNoYieldLock) n = 0;
559d6b1e563SMike Kaganski return n;
560d6b1e563SMike Kaganski }
561d6b1e563SMike Kaganski decltype(WinSalInstance::m_nNoYieldLock)& counter;
562d6b1e563SMike Kaganski };
563d6b1e563SMike Kaganski }
5648ba60ca4SJan-Marek Glogowski
SalComWndProc(HWND,UINT nMsg,WPARAM wParam,LPARAM lParam,bool & rDef)5658ba60ca4SJan-Marek Glogowski LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, bool& rDef )
5668ab086b6SJens-Heiner Rechtien {
5678ab086b6SJens-Heiner Rechtien LRESULT nRet = 0;
5688ba60ca4SJan-Marek Glogowski WinSalTimer *const pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
5698ab086b6SJens-Heiner Rechtien
57035a25475SJan-Marek Glogowski SAL_INFO("vcl.gdi.wndproc", "SalComWndProc(nMsg=" << nMsg << ", wParam=" << wParam
571d6b1e563SMike Kaganski << ", lParam=" << lParam << "); inSendMsg: " << InSendMessage());
572bb2443ccSThorsten Behrens
57314eff34dSNoel Grandin if (ImplGetSVData()->mbDeInit)
57414eff34dSNoel Grandin {
57514eff34dSNoel Grandin SAL_WARN("vcl.gdi.wndproc", "ignoring timer event because we are shutting down");
57614eff34dSNoel Grandin return 0;
57714eff34dSNoel Grandin }
57814eff34dSNoel Grandin
5798ab086b6SJens-Heiner Rechtien switch ( nMsg )
5808ab086b6SJens-Heiner Rechtien {
5818ab086b6SJens-Heiner Rechtien case SAL_MSG_THREADYIELD:
5829af8f190SStephan Bergmann assert( !static_cast<bool>(wParam) );
5838ba60ca4SJan-Marek Glogowski nRet = static_cast<LRESULT>(ImplSalYield(
5848ba60ca4SJan-Marek Glogowski false, static_cast<bool>( lParam ) ));
5858ab086b6SJens-Heiner Rechtien break;
5868ba60ca4SJan-Marek Glogowski
5878ab086b6SJens-Heiner Rechtien case SAL_MSG_STARTTIMER:
5885229f159SJan-Marek Glogowski {
589e23f811cSStephan Bergmann auto const nParam = static_cast<sal_uInt64>( lParam );
590448e9da1SJan-Marek Glogowski sal_uInt64 nTime = tools::Time::GetSystemTicks();
591e23f811cSStephan Bergmann if ( nTime < nParam )
592e23f811cSStephan Bergmann nTime = nParam - nTime;
5935229f159SJan-Marek Glogowski else
5945229f159SJan-Marek Glogowski nTime = 0;
5958ba60ca4SJan-Marek Glogowski assert( pTimer != nullptr );
5968ba60ca4SJan-Marek Glogowski pTimer->ImplStart( nTime );
5978ab086b6SJens-Heiner Rechtien break;
5985229f159SJan-Marek Glogowski }
5998ba60ca4SJan-Marek Glogowski
6008a0e6b25SMichael Stahl case SAL_MSG_STOPTIMER:
6018ba60ca4SJan-Marek Glogowski assert( pTimer != nullptr );
6028ba60ca4SJan-Marek Glogowski pTimer->ImplStop();
6038a0e6b25SMichael Stahl break;
6048ba60ca4SJan-Marek Glogowski
605d6b1e563SMike Kaganski case (SAL_MSG_CREATEFRAME):
606d6b1e563SMike Kaganski {
607d6b1e563SMike Kaganski NoYieldLockGuard g;
608d6b1e563SMike Kaganski nRet = reinterpret_cast<LRESULT>(
609d6b1e563SMike Kaganski ImplSalCreateFrame(GetSalData()->mpInstance, reinterpret_cast<HWND>(lParam),
610d6b1e563SMike Kaganski static_cast<SalFrameStyleFlags>(wParam)));
611d6b1e563SMike Kaganski }
612d6b1e563SMike Kaganski break;
613d6b1e563SMike Kaganski case (SAL_MSG_RECREATEHWND):
614d6b1e563SMike Kaganski {
615d6b1e563SMike Kaganski NoYieldLockGuard g;
616d6b1e563SMike Kaganski nRet = reinterpret_cast<LRESULT>(ImplSalReCreateHWND(
617d6b1e563SMike Kaganski reinterpret_cast<HWND>(wParam), reinterpret_cast<HWND>(lParam), false));
618d6b1e563SMike Kaganski }
619d6b1e563SMike Kaganski break;
620d6b1e563SMike Kaganski case (SAL_MSG_RECREATECHILDHWND):
621d6b1e563SMike Kaganski {
622d6b1e563SMike Kaganski NoYieldLockGuard g;
623d6b1e563SMike Kaganski nRet = reinterpret_cast<LRESULT>(ImplSalReCreateHWND(
624d6b1e563SMike Kaganski reinterpret_cast<HWND>(wParam), reinterpret_cast<HWND>(lParam), true));
625d6b1e563SMike Kaganski }
626d6b1e563SMike Kaganski break;
627d6b1e563SMike Kaganski case (SAL_MSG_DESTROYFRAME):
628d6b1e563SMike Kaganski {
629d6b1e563SMike Kaganski NoYieldLockGuard g;
630d6b1e563SMike Kaganski delete reinterpret_cast<SalFrame*>(lParam);
631d6b1e563SMike Kaganski }
632d6b1e563SMike Kaganski break;
6338ba60ca4SJan-Marek Glogowski
63427bb6f2bSOliver Bolte case SAL_MSG_DESTROYHWND:
63527bb6f2bSOliver Bolte // We only destroy the native window here. We do NOT destroy the SalFrame contained
63627bb6f2bSOliver Bolte // in the structure (GetWindowPtr()).
63748b1c889SStephan Bergmann if (DestroyWindow(reinterpret_cast<HWND>(lParam)) == 0)
63827bb6f2bSOliver Bolte {
6390c35d637SThomas Arnhold OSL_FAIL("DestroyWindow failed!");
64027bb6f2bSOliver Bolte // Failure: We remove the SalFrame from the window structure. So we avoid that
64127bb6f2bSOliver Bolte // the window structure may contain an invalid pointer, once the SalFrame is deleted.
64248b1c889SStephan Bergmann SetWindowPtr(reinterpret_cast<HWND>(lParam), nullptr);
64327bb6f2bSOliver Bolte }
64427bb6f2bSOliver Bolte break;
6458ba60ca4SJan-Marek Glogowski
646d6b1e563SMike Kaganski case (SAL_MSG_CREATEOBJECT):
647d6b1e563SMike Kaganski {
648d6b1e563SMike Kaganski NoYieldLockGuard g;
649d6b1e563SMike Kaganski nRet = reinterpret_cast<LRESULT>(ImplSalCreateObject(
650d6b1e563SMike Kaganski GetSalData()->mpInstance, reinterpret_cast<WinSalFrame*>(lParam)));
651d6b1e563SMike Kaganski }
652d6b1e563SMike Kaganski break;
653d6b1e563SMike Kaganski case (SAL_MSG_DESTROYOBJECT):
654d6b1e563SMike Kaganski {
655d6b1e563SMike Kaganski NoYieldLockGuard g;
656d6b1e563SMike Kaganski delete reinterpret_cast<SalObject*>(lParam);
657d6b1e563SMike Kaganski }
658d6b1e563SMike Kaganski break;
659fa5b2905SNoel Grandin case (SAL_MSG_GETCACHEDDC):
660fa5b2905SNoel Grandin {
661fa5b2905SNoel Grandin NoYieldLockGuard g;
662fa5b2905SNoel Grandin nRet = reinterpret_cast<LRESULT>(
663fa5b2905SNoel Grandin GetDCEx(reinterpret_cast<HWND>(wParam), nullptr, 0x00000002L));
664fa5b2905SNoel Grandin }
665fa5b2905SNoel Grandin break;
666d6b1e563SMike Kaganski case (SAL_MSG_RELEASEDC):
667d6b1e563SMike Kaganski {
668d6b1e563SMike Kaganski NoYieldLockGuard g;
669d6b1e563SMike Kaganski ReleaseDC(reinterpret_cast<HWND>(wParam), reinterpret_cast<HDC>(lParam));
670d6b1e563SMike Kaganski }
671d6b1e563SMike Kaganski break;
6728ba60ca4SJan-Marek Glogowski
673211b3192SJan Holesovsky case SAL_MSG_TIMER_CALLBACK:
674448e9da1SJan-Marek Glogowski assert( pTimer != nullptr );
6754c356a3eSJan-Marek Glogowski pTimer->ImplHandleTimerEvent( wParam );
676b0aec7c6SVladimir Glazounov break;
6778ba60ca4SJan-Marek Glogowski
678abe3af8eSJan-Marek Glogowski case WM_TIMER:
679abe3af8eSJan-Marek Glogowski assert( pTimer != nullptr );
6804c356a3eSJan-Marek Glogowski pTimer->ImplHandle_WM_TIMER( wParam );
681abe3af8eSJan-Marek Glogowski break;
6828ba60ca4SJan-Marek Glogowski
6835bb798a9SJan-Marek Glogowski case SAL_MSG_FORCE_REAL_TIMER:
6845bb798a9SJan-Marek Glogowski assert(pTimer != nullptr);
6855bb798a9SJan-Marek Glogowski pTimer->SetForceRealTimer(true);
6865bb798a9SJan-Marek Glogowski break;
6875bb798a9SJan-Marek Glogowski
6888ba60ca4SJan-Marek Glogowski case SAL_MSG_DUMMY:
6898ba60ca4SJan-Marek Glogowski break;
6908ba60ca4SJan-Marek Glogowski
6918ba60ca4SJan-Marek Glogowski default:
6928ba60ca4SJan-Marek Glogowski rDef = true;
6938ba60ca4SJan-Marek Glogowski break;
694448e9da1SJan-Marek Glogowski }
6958ab086b6SJens-Heiner Rechtien
6968ab086b6SJens-Heiner Rechtien return nRet;
6978ab086b6SJens-Heiner Rechtien }
6988ab086b6SJens-Heiner Rechtien
SalComWndProcW(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)6998ab086b6SJens-Heiner Rechtien LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
7008ab086b6SJens-Heiner Rechtien {
7018ba60ca4SJan-Marek Glogowski bool bDef = false;
7026f221e09SJens-Heiner Rechtien LRESULT nRet = 0;
7036f221e09SJens-Heiner Rechtien __try
7046f221e09SJens-Heiner Rechtien {
7056f221e09SJens-Heiner Rechtien nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef );
7066f221e09SJens-Heiner Rechtien }
707b2cf2780SOliver Bolte __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
7086f221e09SJens-Heiner Rechtien {
7096f221e09SJens-Heiner Rechtien }
7108ab086b6SJens-Heiner Rechtien if ( bDef )
7118ab086b6SJens-Heiner Rechtien {
7128ab086b6SJens-Heiner Rechtien if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) )
71337c198cfSJesús Corrius nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam );
7148ab086b6SJens-Heiner Rechtien }
7158ab086b6SJens-Heiner Rechtien return nRet;
7168ab086b6SJens-Heiner Rechtien }
7178ab086b6SJens-Heiner Rechtien
AnyInput(VclInputFlags nType)7188aa3cb98SNoel Grandin bool WinSalInstance::AnyInput( VclInputFlags nType )
7198ab086b6SJens-Heiner Rechtien {
7203bf6c970SJan-Marek Glogowski if ( nType & VclInputFlags::TIMER )
7213bf6c970SJan-Marek Glogowski {
7223bf6c970SJan-Marek Glogowski const WinSalTimer* pTimer = static_cast<WinSalTimer*>( ImplGetSVData()->maSchedCtx.mpSalTimer );
7233bf6c970SJan-Marek Glogowski if ( pTimer && pTimer->HasTimerElapsed() )
7243bf6c970SJan-Marek Glogowski return true;
7253bf6c970SJan-Marek Glogowski }
7263bf6c970SJan-Marek Glogowski
727843af72bSLuboš Luňák // Note: Do not use PeekMessage(), despite the name it may dispatch events,
728843af72bSLuboš Luňák // even with PM_NOREMOVE specified, which may lead to unwanted recursion.
729843af72bSLuboš Luňák
7308aa3cb98SNoel Grandin if ( (nType & VCL_INPUT_ANY) == VCL_INPUT_ANY )
7318ab086b6SJens-Heiner Rechtien {
732ca3ae26fSRüdiger Timm // revert bugfix for #108919# which never reported timeouts when called from the timer handler
733ca3ae26fSRüdiger Timm // which made the application completely unresponsive during background formatting
734843af72bSLuboš Luňák if ( GetQueueStatus( QS_ALLEVENTS ))
735ca3ae26fSRüdiger Timm return true;
7368ab086b6SJens-Heiner Rechtien }
7378ab086b6SJens-Heiner Rechtien else
7388ab086b6SJens-Heiner Rechtien {
739843af72bSLuboš Luňák UINT flags = 0;
7403bf6c970SJan-Marek Glogowski
741843af72bSLuboš Luňák // This code previously considered modifier keys as OTHER,
742843af72bSLuboš Luňák // but that makes this hard to do without PeekMessage,
743843af72bSLuboš Luňák // is inconsistent with the X11 backend, and I see no good reason.
744843af72bSLuboš Luňák if ( nType & VclInputFlags::KEYBOARD )
745843af72bSLuboš Luňák flags |= QS_KEY;
7463bf6c970SJan-Marek Glogowski
7478aa3cb98SNoel Grandin if ( nType & VclInputFlags::MOUSE )
748843af72bSLuboš Luňák flags |= QS_MOUSE;
7498ab086b6SJens-Heiner Rechtien
7508aa3cb98SNoel Grandin if ( nType & VclInputFlags::PAINT )
751843af72bSLuboš Luňák flags |= QS_PAINT;
752f244634bSJens-Heiner Rechtien
753843af72bSLuboš Luňák if ( nType & VclInputFlags::TIMER )
754843af72bSLuboš Luňák flags |= QS_TIMER;
755f244634bSJens-Heiner Rechtien
756843af72bSLuboš Luňák if( nType & VclInputFlags::OTHER )
757843af72bSLuboš Luňák flags |= QS_ALLEVENTS & ~QS_KEY & ~QS_MOUSE & ~QS_PAINT & ~QS_TIMER;
758f244634bSJens-Heiner Rechtien
759843af72bSLuboš Luňák if( GetQueueStatus( flags ))
760f244634bSJens-Heiner Rechtien return true;
7618ab086b6SJens-Heiner Rechtien }
7628ab086b6SJens-Heiner Rechtien
7637790b6a4SMichael Stahl return false;
7648ab086b6SJens-Heiner Rechtien }
7658ab086b6SJens-Heiner Rechtien
CreateChildFrame(SystemParentData * pSystemParentData,SalFrameStyleFlags nSalFrameStyle)7660e30af6fSNoel Grandin SalFrame* WinSalInstance::CreateChildFrame( SystemParentData* pSystemParentData, SalFrameStyleFlags nSalFrameStyle )
7678ab086b6SJens-Heiner Rechtien {
768275dbf60SChristian M. Heller // to switch to Main-Thread
7699af8f190SStephan Bergmann return reinterpret_cast<SalFrame*>(static_cast<sal_IntPtr>(SendMessageW( mhComWnd, SAL_MSG_CREATEFRAME, static_cast<WPARAM>(nSalFrameStyle), reinterpret_cast<LPARAM>(pSystemParentData->hWnd) )));
7708ab086b6SJens-Heiner Rechtien }
7718ab086b6SJens-Heiner Rechtien
CreateFrame(SalFrame * pParent,SalFrameStyleFlags nSalFrameStyle)7720e30af6fSNoel Grandin SalFrame* WinSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags nSalFrameStyle )
7738ab086b6SJens-Heiner Rechtien {
774275dbf60SChristian M. Heller // to switch to Main-Thread
7758ab086b6SJens-Heiner Rechtien HWND hWndParent;
7768ab086b6SJens-Heiner Rechtien if ( pParent )
777f3d5aa2bSKurt Zenker hWndParent = static_cast<WinSalFrame*>(pParent)->mhWnd;
7788ab086b6SJens-Heiner Rechtien else
77948b1c889SStephan Bergmann hWndParent = nullptr;
7809af8f190SStephan Bergmann return reinterpret_cast<SalFrame*>(static_cast<sal_IntPtr>(SendMessageW( mhComWnd, SAL_MSG_CREATEFRAME, static_cast<WPARAM>(nSalFrameStyle), reinterpret_cast<LPARAM>(hWndParent) )));
7818ab086b6SJens-Heiner Rechtien }
7828ab086b6SJens-Heiner Rechtien
DestroyFrame(SalFrame * pFrame)783f3d5aa2bSKurt Zenker void WinSalInstance::DestroyFrame( SalFrame* pFrame )
7848ab086b6SJens-Heiner Rechtien {
78529ec512eSMiklos Vajna OpenGLContext::prepareForYield();
78648b1c889SStephan Bergmann SendMessageW( mhComWnd, SAL_MSG_DESTROYFRAME, 0, reinterpret_cast<LPARAM>(pFrame) );
7878ab086b6SJens-Heiner Rechtien }
7888ab086b6SJens-Heiner Rechtien
CreateObject(SalFrame * pParent,SystemWindowData *,bool)7890f1a0371SKurt Zenker SalObject* WinSalInstance::CreateObject( SalFrame* pParent,
7904bd692d1SVladimir Glazounov SystemWindowData* /*pWindowData*/, // SystemWindowData meaningless on Windows
791381f8a56SChris Sherlock bool /*bShow*/ )
7928ab086b6SJens-Heiner Rechtien {
793275dbf60SChristian M. Heller // to switch to Main-Thread
7949af8f190SStephan Bergmann return reinterpret_cast<SalObject*>(static_cast<sal_IntPtr>(SendMessageW( mhComWnd, SAL_MSG_CREATEOBJECT, 0, reinterpret_cast<LPARAM>(static_cast<WinSalFrame*>(pParent)) )));
7958ab086b6SJens-Heiner Rechtien }
7968ab086b6SJens-Heiner Rechtien
DestroyObject(SalObject * pObject)797f3d5aa2bSKurt Zenker void WinSalInstance::DestroyObject( SalObject* pObject )
7988ab086b6SJens-Heiner Rechtien {
79948b1c889SStephan Bergmann SendMessageW( mhComWnd, SAL_MSG_DESTROYOBJECT, 0, reinterpret_cast<LPARAM>(pObject) );
8008ab086b6SJens-Heiner Rechtien }
801489c112aSPhilipp Lohmann
8029e18c9eeSVladimir Glazounov /** Add a file to the system shells recent document list if there is any.
8039e18c9eeSVladimir Glazounov This function may have no effect under Unix because there is no
8049e18c9eeSVladimir Glazounov standard API among the different desktop managers.
8059e18c9eeSVladimir Glazounov
8069e18c9eeSVladimir Glazounov @param aFileUrl
8079e18c9eeSVladimir Glazounov The file url of the document.
8089e18c9eeSVladimir Glazounov */
AddToRecentDocumentList(const OUString & rFileUrl,const OUString &,const OUString & rDocumentService)809e62fec40SJesús Corrius void WinSalInstance::AddToRecentDocumentList(const OUString& rFileUrl, const OUString& /*rMimeType*/, const OUString& rDocumentService)
8109e18c9eeSVladimir Glazounov {
811b07e8a7eSMichael Stahl if (Application::IsHeadlessModeEnabled())
81294c26485SMichael Stahl return;
81394c26485SMichael Stahl
8141946794aSLuboš Luňák OUString system_path;
8159e18c9eeSVladimir Glazounov osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL(rFileUrl, system_path);
8169e18c9eeSVladimir Glazounov
8179e18c9eeSVladimir Glazounov OSL_ENSURE(osl::FileBase::E_None == rc, "Invalid file url");
8189e18c9eeSVladimir Glazounov
8199e18c9eeSVladimir Glazounov if (osl::FileBase::E_None == rc)
820e62fec40SJesús Corrius {
82148b1c889SStephan Bergmann IShellItem* pShellItem = nullptr;
822e62fec40SJesús Corrius
8231944e3ddSMike Kaganski HRESULT hr = SHCreateItemFromParsingName(o3tl::toW(system_path.getStr()), nullptr, IID_PPV_ARGS(&pShellItem));
824e62fec40SJesús Corrius
825e62fec40SJesús Corrius if ( SUCCEEDED(hr) && pShellItem )
826e62fec40SJesús Corrius {
827e62fec40SJesús Corrius OUString sApplicationName;
828e62fec40SJesús Corrius
829e62fec40SJesús Corrius if ( rDocumentService == "com.sun.star.text.TextDocument" ||
830e62fec40SJesús Corrius rDocumentService == "com.sun.star.text.GlobalDocument" ||
831e62fec40SJesús Corrius rDocumentService == "com.sun.star.text.WebDocument" ||
832e62fec40SJesús Corrius rDocumentService == "com.sun.star.xforms.XMLFormDocument" )
833e62fec40SJesús Corrius sApplicationName = "Writer";
834e62fec40SJesús Corrius else if ( rDocumentService == "com.sun.star.sheet.SpreadsheetDocument" ||
835e62fec40SJesús Corrius rDocumentService == "com.sun.star.chart2.ChartDocument" )
836e62fec40SJesús Corrius sApplicationName = "Calc";
837e62fec40SJesús Corrius else if ( rDocumentService == "com.sun.star.presentation.PresentationDocument" )
838e62fec40SJesús Corrius sApplicationName = "Impress";
839e62fec40SJesús Corrius else if ( rDocumentService == "com.sun.star.drawing.DrawingDocument" )
840e62fec40SJesús Corrius sApplicationName = "Draw";
841e62fec40SJesús Corrius else if ( rDocumentService == "com.sun.star.formula.FormulaProperties" )
842e62fec40SJesús Corrius sApplicationName = "Math";
843e62fec40SJesús Corrius else if ( rDocumentService == "com.sun.star.sdb.DatabaseDocument" ||
844e62fec40SJesús Corrius rDocumentService == "com.sun.star.sdb.OfficeDatabaseDocument" ||
845e62fec40SJesús Corrius rDocumentService == "com.sun.star.sdb.RelationDesign" ||
846e62fec40SJesús Corrius rDocumentService == "com.sun.star.sdb.QueryDesign" ||
847e62fec40SJesús Corrius rDocumentService == "com.sun.star.sdb.TableDesign" ||
848e62fec40SJesús Corrius rDocumentService == "com.sun.star.sdb.DataSourceBrowser" )
849e62fec40SJesús Corrius sApplicationName = "Base";
850e62fec40SJesús Corrius
851e62fec40SJesús Corrius if ( !sApplicationName.isEmpty() )
852e62fec40SJesús Corrius {
853044eba71SStephan Bergmann OUString sApplicationID("TheDocumentFoundation.LibreOffice." + sApplicationName);
854e62fec40SJesús Corrius
855b411470bSMichael Stahl SHARDAPPIDINFO info;
856e62fec40SJesús Corrius info.psi = pShellItem;
8571944e3ddSMike Kaganski info.pszAppID = o3tl::toW(sApplicationID.getStr());
858e62fec40SJesús Corrius
859e62fec40SJesús Corrius SHAddToRecentDocs ( SHARD_APPIDINFO, &info );
860e62fec40SJesús Corrius return;
861e62fec40SJesús Corrius }
862e62fec40SJesús Corrius }
863918ddde5SFridrich Štrba // For whatever reason, we could not use the SHARD_APPIDINFO semantics
86448b1c889SStephan Bergmann SHAddToRecentDocs(SHARD_PATHW, system_path.getStr());
8659e18c9eeSVladimir Glazounov }
866e62fec40SJesús Corrius }
8679e18c9eeSVladimir Glazounov
CreateSalTimer()868f3d5aa2bSKurt Zenker SalTimer* WinSalInstance::CreateSalTimer()
869f3d5aa2bSKurt Zenker {
870f3d5aa2bSKurt Zenker return new WinSalTimer();
871f3d5aa2bSKurt Zenker }
872f3d5aa2bSKurt Zenker
CreateSalBitmap()8738447d31eSNoel Grandin std::shared_ptr<SalBitmap> WinSalInstance::CreateSalBitmap()
874f3d5aa2bSKurt Zenker {
87507f480b7SNoel Grandin assert(SkiaHelper::isVCLSkiaEnabled() && "Windows requires skia");
87671a07e88SLuboš Luňák return std::make_shared<SkiaSalBitmap>();
877f3d5aa2bSKurt Zenker }
878f3d5aa2bSKurt Zenker
WorkaroundExceptionHandlingInUSER32Lib(int,LPEXCEPTION_POINTERS pExceptionInfo)8792bd4648bSJens-Heiner Rechtien int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo)
880b2cf2780SOliver Bolte {
881b2cf2780SOliver Bolte // Decide if an exception is a c++ (mostly UNO) exception or a process violation.
882b2cf2780SOliver Bolte // Depending on this information we pass process violations directly to our signal handler ...
883b2cf2780SOliver Bolte // and c++ (UNO) exceptions are sended to the following code on the current stack.
884b2cf2780SOliver Bolte // Problem behind: user32.dll sometime consumes exceptions/process violations .-)
885b2cf2780SOliver Bolte // see also #112221#
886b2cf2780SOliver Bolte
88722767810STakeshi Abe static const DWORD EXCEPTION_MSC_CPP_EXCEPTION = 0xE06D7363;
888b2cf2780SOliver Bolte
889b2cf2780SOliver Bolte if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_MSC_CPP_EXCEPTION)
890b2cf2780SOliver Bolte return EXCEPTION_CONTINUE_SEARCH;
891b2cf2780SOliver Bolte
8928f461cd1SKurt Zenker return UnhandledExceptionFilter( pExceptionInfo );
893b2cf2780SOliver Bolte }
89456a95946SMichael Meeks
895b7e4e851SMike Kaganski typedef LONG NTSTATUS;
896b7e4e851SMike Kaganski typedef NTSTATUS(WINAPI* RtlGetVersion_t)(PRTL_OSVERSIONINFOW);
897b7e4e851SMike Kaganski constexpr NTSTATUS STATUS_SUCCESS = 0x00000000;
898b7e4e851SMike Kaganski
getWinArch()8990bcb62c6SMike Kaganski static OUString getWinArch()
9000bcb62c6SMike Kaganski {
9010bcb62c6SMike Kaganski USHORT nNativeMachine = IMAGE_FILE_MACHINE_UNKNOWN;
9020bcb62c6SMike Kaganski
9030bcb62c6SMike Kaganski using LPFN_ISWOW64PROCESS2 = BOOL(WINAPI*)(HANDLE, USHORT*, USHORT*);
9040bcb62c6SMike Kaganski auto fnIsWow64Process2 = reinterpret_cast<LPFN_ISWOW64PROCESS2>(
9050bcb62c6SMike Kaganski GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2"));
9060bcb62c6SMike Kaganski if (fnIsWow64Process2)
9070bcb62c6SMike Kaganski fnIsWow64Process2(GetCurrentProcess(), &o3tl::temporary(USHORT()), &nNativeMachine);
9080bcb62c6SMike Kaganski
9090bcb62c6SMike Kaganski if (nNativeMachine == IMAGE_FILE_MACHINE_UNKNOWN)
910dc03e4fdSkubak {
911dc03e4fdSkubak #if _WIN64
912dc03e4fdSkubak
9130bcb62c6SMike Kaganski nNativeMachine = IMAGE_FILE_MACHINE_AMD64;
914dc03e4fdSkubak
915dc03e4fdSkubak #else
916dc03e4fdSkubak
917dc03e4fdSkubak BOOL isWow64 = FALSE;
918dc03e4fdSkubak
919dc03e4fdSkubak IsWow64Process(GetCurrentProcess(), &isWow64);
920dc03e4fdSkubak
921dc03e4fdSkubak if (isWow64)
9220bcb62c6SMike Kaganski nNativeMachine = IMAGE_FILE_MACHINE_AMD64; // 32-bit process on 64-bit Windows
923dc03e4fdSkubak else
9240bcb62c6SMike Kaganski nNativeMachine = IMAGE_FILE_MACHINE_I386;
925dc03e4fdSkubak
926dc03e4fdSkubak #endif
927dc03e4fdSkubak }
928dc03e4fdSkubak
9290bcb62c6SMike Kaganski switch (nNativeMachine)
9300bcb62c6SMike Kaganski {
9310bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_I386:
9320bcb62c6SMike Kaganski return u" X86_32"_ustr;
9330bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_R3000:
9340bcb62c6SMike Kaganski return u" R3000"_ustr;
9350bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_R4000:
9360bcb62c6SMike Kaganski return u" R4000"_ustr;
9370bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_R10000:
9380bcb62c6SMike Kaganski return u" R10000"_ustr;
9390bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_WCEMIPSV2:
9400bcb62c6SMike Kaganski return u" WCEMIPSV2"_ustr;
9410bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_ALPHA:
9420bcb62c6SMike Kaganski return u" ALPHA"_ustr;
9430bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_SH3:
9440bcb62c6SMike Kaganski return u" SH3"_ustr;
9450bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_SH3DSP:
9460bcb62c6SMike Kaganski return u" SH3DSP"_ustr;
9470bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_SH3E:
9480bcb62c6SMike Kaganski return u" SH3E"_ustr;
9490bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_SH4:
9500bcb62c6SMike Kaganski return u" SH4"_ustr;
9510bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_SH5:
9520bcb62c6SMike Kaganski return u" SH5"_ustr;
9530bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_ARM:
9540bcb62c6SMike Kaganski return u" ARM"_ustr;
9550bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_THUMB:
9560bcb62c6SMike Kaganski return u" THUMB"_ustr;
9570bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_ARMNT:
9580bcb62c6SMike Kaganski return u" ARMNT"_ustr;
9590bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_AM33:
9600bcb62c6SMike Kaganski return u" AM33"_ustr;
9610bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_POWERPC:
9620bcb62c6SMike Kaganski return u" POWERPC"_ustr;
9630bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_POWERPCFP:
9640bcb62c6SMike Kaganski return u" POWERPCFP"_ustr;
9650bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_IA64:
9660bcb62c6SMike Kaganski return u" IA64"_ustr;
9670bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_MIPS16:
9680bcb62c6SMike Kaganski return u" MIPS16"_ustr;
9690bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_ALPHA64:
9700bcb62c6SMike Kaganski return u" ALPHA64"_ustr;
9710bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_MIPSFPU:
9720bcb62c6SMike Kaganski return u" MIPSFPU"_ustr;
9730bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_MIPSFPU16:
9740bcb62c6SMike Kaganski return u" MIPSFPU16"_ustr;
9750bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_TRICORE:
9760bcb62c6SMike Kaganski return u" TRICORE"_ustr;
9770bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_CEF:
9780bcb62c6SMike Kaganski return u" CEF"_ustr;
9790bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_EBC:
9800bcb62c6SMike Kaganski return u" EBC"_ustr;
9810bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_AMD64:
9820bcb62c6SMike Kaganski return u" X86_64"_ustr;
9830bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_M32R:
9840bcb62c6SMike Kaganski return u" M32R"_ustr;
9850bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_ARM64:
9860bcb62c6SMike Kaganski return u" ARM64"_ustr;
9870bcb62c6SMike Kaganski case IMAGE_FILE_MACHINE_CEE:
9880bcb62c6SMike Kaganski return u" CEE"_ustr;
9890bcb62c6SMike Kaganski default:
9900bcb62c6SMike Kaganski assert(!"Yet unhandled case");
9910bcb62c6SMike Kaganski return OUString();
9920bcb62c6SMike Kaganski }
9930bcb62c6SMike Kaganski }
9940bcb62c6SMike Kaganski
getOSVersionString(DWORD nBuildNumber)9955f00b748SMichael Weghorn static OUString getOSVersionString(DWORD nBuildNumber)
9962db558b5Skubak {
9970bcb62c6SMike Kaganski OUStringBuffer result = u"Windows";
9982db558b5Skubak if (nBuildNumber >= 22000)
9990bcb62c6SMike Kaganski result.append(" 11");
10005f00b748SMichael Weghorn else if (nBuildNumber > 0)
10010bcb62c6SMike Kaganski result.append(" 10");
10020bcb62c6SMike Kaganski else // We don't know what Windows it is
10030bcb62c6SMike Kaganski result.append(" unknown");
10040bcb62c6SMike Kaganski
10050bcb62c6SMike Kaganski result.append(getWinArch());
10060bcb62c6SMike Kaganski
10070bcb62c6SMike Kaganski if (nBuildNumber)
10085f00b748SMichael Weghorn result.append(" (build " + OUString::number(nBuildNumber) + ")");
10090bcb62c6SMike Kaganski
10100bcb62c6SMike Kaganski return result.makeStringAndClear();
10112db558b5Skubak }
10122db558b5Skubak
getWindowsBuildNumber()10135f00b748SMichael Weghorn DWORD WinSalInstance::getWindowsBuildNumber()
101456a95946SMichael Meeks {
10155f00b748SMichael Weghorn static const DWORD nResult = []
10160bcb62c6SMike Kaganski {
10175f00b748SMichael Weghorn DWORD nBuildNumber = 0;
10185f00b748SMichael Weghorn // use RtlGetVersion to get build number
1019b7e4e851SMike Kaganski if (HMODULE h_ntdll = GetModuleHandleW(L"ntdll.dll"))
1020b7e4e851SMike Kaganski {
1021b7e4e851SMike Kaganski if (auto RtlGetVersion
1022b7e4e851SMike Kaganski = reinterpret_cast<RtlGetVersion_t>(GetProcAddress(h_ntdll, "RtlGetVersion")))
1023b7e4e851SMike Kaganski {
1024b7e4e851SMike Kaganski RTL_OSVERSIONINFOW vi2{}; // initialize with zeroes - a better alternative to memset
1025b7e4e851SMike Kaganski vi2.dwOSVersionInfoSize = sizeof(vi2);
1026b7e4e851SMike Kaganski if (STATUS_SUCCESS == RtlGetVersion(&vi2))
1027b7e4e851SMike Kaganski {
10285f00b748SMichael Weghorn nBuildNumber = vi2.dwBuildNumber;
1029b7e4e851SMike Kaganski }
1030b7e4e851SMike Kaganski }
1031b7e4e851SMike Kaganski }
10325f00b748SMichael Weghorn return nBuildNumber;
10330bcb62c6SMike Kaganski }();
10345f00b748SMichael Weghorn return nResult;
1035a43b5e3dSMichael Weghorn }
1036a43b5e3dSMichael Weghorn
getOSVersion()1037a43b5e3dSMichael Weghorn OUString WinSalInstance::getOSVersion()
1038a43b5e3dSMichael Weghorn {
10395f00b748SMichael Weghorn return getOSVersionString(getWindowsBuildNumber());
104056a95946SMichael Meeks }
10414905a190SSebastian Spaeth
BeforeAbort(const OUString &,bool)1042b6518bebSJan-Marek Glogowski void WinSalInstance::BeforeAbort(const OUString&, bool)
1043b6518bebSJan-Marek Glogowski {
1044b6518bebSJan-Marek Glogowski ImplFreeSalGDI();
1045b6518bebSJan-Marek Glogowski }
1046b6518bebSJan-Marek Glogowski
10475016881dSMichael Weghorn css::uno::Reference<css::datatransfer::dnd::XDragSource>
ImplCreateDragSource(const SystemEnvData & rSysEnv)10486003d197SMichael Weghorn WinSalInstance::ImplCreateDragSource(const SystemEnvData& rSysEnv)
104903157610SJan-Marek Glogowski {
105055f6bd0aSMichael Weghorn rtl::Reference<DragSource> xDragSource = new DragSource(comphelper::getProcessComponentContext());
10516003d197SMichael Weghorn vcl::OleDnDHelper(xDragSource, reinterpret_cast<sal_IntPtr>(rSysEnv.hWnd), vcl::DragOrDrop::Drag);
10525016881dSMichael Weghorn return xDragSource;
105303157610SJan-Marek Glogowski }
105403157610SJan-Marek Glogowski
1055828b8f91SMichael Weghorn css::uno::Reference<css::datatransfer::dnd::XDropTarget>
ImplCreateDropTarget(const SystemEnvData & rSysEnv)10566003d197SMichael Weghorn WinSalInstance::ImplCreateDropTarget(const SystemEnvData& rSysEnv)
105703157610SJan-Marek Glogowski {
105855f6bd0aSMichael Weghorn rtl::Reference<DropTarget> xDropTarget = new DropTarget(comphelper::getProcessComponentContext());
10596003d197SMichael Weghorn vcl::OleDnDHelper(xDropTarget, reinterpret_cast<sal_IntPtr>(rSysEnv.hWnd), vcl::DragOrDrop::Drop);
1060828b8f91SMichael Weghorn return xDropTarget;
106103157610SJan-Marek Glogowski }
106203157610SJan-Marek Glogowski
10634905a190SSebastian Spaeth /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1064