1*9f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9f62ea84SAndrew Rist * distributed with this work for additional information 6*9f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 9*9f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*9f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9f62ea84SAndrew Rist * software distributed under the License is distributed on an 15*9f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 17*9f62ea84SAndrew Rist * specific language governing permissions and limitations 18*9f62ea84SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*9f62ea84SAndrew Rist *************************************************************/ 21*9f62ea84SAndrew Rist 22*9f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <string.h> 28cdf0e10cSrcweir #include <tools/svwin.h> 29cdf0e10cSrcweir #ifdef WNT 30cdf0e10cSrcweir #include <process.h> 31cdf0e10cSrcweir #endif 32cdf0e10cSrcweir #ifdef __MINGW32__ 33cdf0e10cSrcweir #include <excpt.h> 34cdf0e10cSrcweir #endif 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include <osl/file.hxx> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <vos/mutex.hxx> 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include <tools/solarmutex.hxx> 41cdf0e10cSrcweir #include <tools/debug.hxx> 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include <vcl/timer.hxx> 44cdf0e10cSrcweir #include <vcl/apptypes.hxx> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include <win/wincomp.hxx> 47cdf0e10cSrcweir #include <win/salids.hrc> 48cdf0e10cSrcweir #include <win/saldata.hxx> 49cdf0e10cSrcweir #include <win/salinst.h> 50cdf0e10cSrcweir #include <win/salframe.h> 51cdf0e10cSrcweir #include <win/salobj.h> 52cdf0e10cSrcweir #include <win/saltimer.h> 53cdf0e10cSrcweir #include <win/salbmp.h> 54cdf0e10cSrcweir 55cdf0e10cSrcweir #include <salimestatus.hxx> 56cdf0e10cSrcweir #include <salsys.hxx> 57cdf0e10cSrcweir 58cdf0e10cSrcweir #ifndef min 59cdf0e10cSrcweir #define min(a,b) (((a) < (b)) ? (a) : (b)) 60cdf0e10cSrcweir #endif 61cdf0e10cSrcweir #ifndef max 62cdf0e10cSrcweir #define max(a,b) (((a) > (b)) ? (a) : (b)) 63cdf0e10cSrcweir #endif 64cdf0e10cSrcweir 65cdf0e10cSrcweir #if defined _MSC_VER 66cdf0e10cSrcweir #pragma warning(push, 1) 67cdf0e10cSrcweir #pragma warning( disable: 4917 ) 68cdf0e10cSrcweir #endif 69cdf0e10cSrcweir 70cdf0e10cSrcweir #include <GdiPlus.h> 71cdf0e10cSrcweir #include <GdiPlusEnums.h> 72cdf0e10cSrcweir #include <GdiPlusColor.h> 73cdf0e10cSrcweir #include <Shlobj.h> 74cdf0e10cSrcweir 75cdf0e10cSrcweir #if defined _MSC_VER 76cdf0e10cSrcweir #pragma warning(pop) 77cdf0e10cSrcweir #endif 78cdf0e10cSrcweir 79cdf0e10cSrcweir // ======================================================================= 80cdf0e10cSrcweir 81cdf0e10cSrcweir void SalAbort( const XubString& rErrorText ) 82cdf0e10cSrcweir { 83cdf0e10cSrcweir ImplFreeSalGDI(); 84cdf0e10cSrcweir 85cdf0e10cSrcweir if ( !rErrorText.Len() ) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir // #112255# make sure crash reporter is triggered 88cdf0e10cSrcweir RaiseException( 0, EXCEPTION_NONCONTINUABLE, 0, NULL ); 89cdf0e10cSrcweir FatalAppExit( 0, "Application Error" ); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir else 92cdf0e10cSrcweir { 93cdf0e10cSrcweir // #112255# make sure crash reporter is triggered 94cdf0e10cSrcweir RaiseException( 0, EXCEPTION_NONCONTINUABLE, 0, NULL ); 95cdf0e10cSrcweir ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) ); 96cdf0e10cSrcweir FatalAppExit( 0, aErrorText.GetBuffer() ); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir // ======================================================================= 101cdf0e10cSrcweir 102cdf0e10cSrcweir LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); 103cdf0e10cSrcweir LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); 104cdf0e10cSrcweir 105cdf0e10cSrcweir // ======================================================================= 106cdf0e10cSrcweir 107cdf0e10cSrcweir class SalYieldMutex : public vos::OMutex 108cdf0e10cSrcweir { 109cdf0e10cSrcweir public: // for ImplSalYield() 110cdf0e10cSrcweir WinSalInstance* mpInstData; 111cdf0e10cSrcweir sal_uLong mnCount; 112cdf0e10cSrcweir DWORD mnThreadId; 113cdf0e10cSrcweir 114cdf0e10cSrcweir public: 115cdf0e10cSrcweir SalYieldMutex( WinSalInstance* pInstData ); 116cdf0e10cSrcweir 117cdf0e10cSrcweir virtual void SAL_CALL acquire(); 118cdf0e10cSrcweir virtual void SAL_CALL release(); 119cdf0e10cSrcweir virtual sal_Bool SAL_CALL tryToAcquire(); 120cdf0e10cSrcweir 121cdf0e10cSrcweir sal_uLong GetAcquireCount( sal_uLong nThreadId ); 122cdf0e10cSrcweir }; 123cdf0e10cSrcweir 124cdf0e10cSrcweir // ----------------------------------------------------------------------- 125cdf0e10cSrcweir 126cdf0e10cSrcweir SalYieldMutex::SalYieldMutex( WinSalInstance* pInstData ) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir mpInstData = pInstData; 129cdf0e10cSrcweir mnCount = 0; 130cdf0e10cSrcweir mnThreadId = 0; 131cdf0e10cSrcweir } 132cdf0e10cSrcweir 133cdf0e10cSrcweir // ----------------------------------------------------------------------- 134cdf0e10cSrcweir 135cdf0e10cSrcweir void SAL_CALL SalYieldMutex::acquire() 136cdf0e10cSrcweir { 137cdf0e10cSrcweir OMutex::acquire(); 138cdf0e10cSrcweir mnCount++; 139cdf0e10cSrcweir mnThreadId = GetCurrentThreadId(); 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir // ----------------------------------------------------------------------- 143cdf0e10cSrcweir 144cdf0e10cSrcweir void SAL_CALL SalYieldMutex::release() 145cdf0e10cSrcweir { 146cdf0e10cSrcweir DWORD nThreadId = GetCurrentThreadId(); 147cdf0e10cSrcweir if ( mnThreadId != nThreadId ) 148cdf0e10cSrcweir OMutex::release(); 149cdf0e10cSrcweir else 150cdf0e10cSrcweir { 151cdf0e10cSrcweir SalData* pSalData = GetSalData(); 152cdf0e10cSrcweir if ( pSalData->mnAppThreadId != nThreadId ) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir if ( mnCount == 1 ) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir // If we don't call these message, the Output from the 157cdf0e10cSrcweir // Java clients doesn't come in the right order 158cdf0e10cSrcweir GdiFlush(); 159cdf0e10cSrcweir 160cdf0e10cSrcweir mpInstData->mpSalWaitMutex->acquire(); 161cdf0e10cSrcweir if ( mpInstData->mnYieldWaitCount ) 162cdf0e10cSrcweir ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ); 163cdf0e10cSrcweir mnThreadId = 0; 164cdf0e10cSrcweir mnCount--; 165cdf0e10cSrcweir OMutex::release(); 166cdf0e10cSrcweir mpInstData->mpSalWaitMutex->release(); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir else 169cdf0e10cSrcweir { 170cdf0e10cSrcweir mnCount--; 171cdf0e10cSrcweir OMutex::release(); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir } 174cdf0e10cSrcweir else 175cdf0e10cSrcweir { 176cdf0e10cSrcweir if ( mnCount == 1 ) 177cdf0e10cSrcweir mnThreadId = 0; 178cdf0e10cSrcweir mnCount--; 179cdf0e10cSrcweir OMutex::release(); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir } 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir // ----------------------------------------------------------------------- 185cdf0e10cSrcweir 186cdf0e10cSrcweir sal_Bool SAL_CALL SalYieldMutex::tryToAcquire() 187cdf0e10cSrcweir { 188cdf0e10cSrcweir if( OMutex::tryToAcquire() ) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir mnCount++; 191cdf0e10cSrcweir mnThreadId = GetCurrentThreadId(); 192cdf0e10cSrcweir return sal_True; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir else 195cdf0e10cSrcweir return sal_False; 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir // ----------------------------------------------------------------------- 199cdf0e10cSrcweir 200cdf0e10cSrcweir sal_uLong SalYieldMutex::GetAcquireCount( sal_uLong nThreadId ) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir if ( nThreadId == mnThreadId ) 203cdf0e10cSrcweir return mnCount; 204cdf0e10cSrcweir else 205cdf0e10cSrcweir return 0; 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir // ----------------------------------------------------------------------- 209cdf0e10cSrcweir 210cdf0e10cSrcweir void ImplSalYieldMutexAcquireWithWait() 211cdf0e10cSrcweir { 212cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 213cdf0e10cSrcweir if ( !pInst ) 214cdf0e10cSrcweir return; 215cdf0e10cSrcweir 216cdf0e10cSrcweir // If we are the main thread, then we must wait with wait, because 217cdf0e10cSrcweir // in if we don't reschedule, then we create deadlocks if a Windows 218cdf0e10cSrcweir // Function is called from another thread. If we arn't the main thread, 219cdf0e10cSrcweir // than we call qcquire directly. 220cdf0e10cSrcweir DWORD nThreadId = GetCurrentThreadId(); 221cdf0e10cSrcweir SalData* pSalData = GetSalData(); 222cdf0e10cSrcweir if ( pSalData->mnAppThreadId == nThreadId ) 223cdf0e10cSrcweir { 224cdf0e10cSrcweir // Wenn wir den Mutex nicht bekommen, muessen wir solange 225cdf0e10cSrcweir // warten, bis wir Ihn bekommen 226cdf0e10cSrcweir sal_Bool bAcquire = FALSE; 227cdf0e10cSrcweir do 228cdf0e10cSrcweir { 229cdf0e10cSrcweir if ( pInst->mpSalYieldMutex->tryToAcquire() ) 230cdf0e10cSrcweir bAcquire = TRUE; 231cdf0e10cSrcweir else 232cdf0e10cSrcweir { 233cdf0e10cSrcweir pInst->mpSalWaitMutex->acquire(); 234cdf0e10cSrcweir if ( pInst->mpSalYieldMutex->tryToAcquire() ) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir bAcquire = TRUE; 237cdf0e10cSrcweir pInst->mpSalWaitMutex->release(); 238cdf0e10cSrcweir } 239cdf0e10cSrcweir else 240cdf0e10cSrcweir { 241cdf0e10cSrcweir pInst->mnYieldWaitCount++; 242cdf0e10cSrcweir pInst->mpSalWaitMutex->release(); 243cdf0e10cSrcweir MSG aTmpMsg; 244cdf0e10cSrcweir ImplGetMessage( &aTmpMsg, pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD ); 245cdf0e10cSrcweir pInst->mnYieldWaitCount--; 246cdf0e10cSrcweir if ( pInst->mnYieldWaitCount ) 247cdf0e10cSrcweir ImplPostMessage( pInst->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir } 250cdf0e10cSrcweir } 251cdf0e10cSrcweir while ( !bAcquire ); 252cdf0e10cSrcweir } 253cdf0e10cSrcweir else 254cdf0e10cSrcweir pInst->mpSalYieldMutex->acquire(); 255cdf0e10cSrcweir } 256cdf0e10cSrcweir 257cdf0e10cSrcweir // ----------------------------------------------------------------------- 258cdf0e10cSrcweir 259cdf0e10cSrcweir sal_Bool ImplSalYieldMutexTryToAcquire() 260cdf0e10cSrcweir { 261cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 262cdf0e10cSrcweir if ( pInst ) 263cdf0e10cSrcweir return pInst->mpSalYieldMutex->tryToAcquire(); 264cdf0e10cSrcweir else 265cdf0e10cSrcweir return FALSE; 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir // ----------------------------------------------------------------------- 269cdf0e10cSrcweir 270cdf0e10cSrcweir void ImplSalYieldMutexAcquire() 271cdf0e10cSrcweir { 272cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 273cdf0e10cSrcweir if ( pInst ) 274cdf0e10cSrcweir pInst->mpSalYieldMutex->acquire(); 275cdf0e10cSrcweir } 276cdf0e10cSrcweir 277cdf0e10cSrcweir // ----------------------------------------------------------------------- 278cdf0e10cSrcweir 279cdf0e10cSrcweir void ImplSalYieldMutexRelease() 280cdf0e10cSrcweir { 281cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 282cdf0e10cSrcweir if ( pInst ) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir GdiFlush(); 285cdf0e10cSrcweir pInst->mpSalYieldMutex->release(); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir } 288cdf0e10cSrcweir 289cdf0e10cSrcweir // ----------------------------------------------------------------------- 290cdf0e10cSrcweir 291cdf0e10cSrcweir sal_uLong ImplSalReleaseYieldMutex() 292cdf0e10cSrcweir { 293cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 294cdf0e10cSrcweir if ( !pInst ) 295cdf0e10cSrcweir return 0; 296cdf0e10cSrcweir 297cdf0e10cSrcweir SalYieldMutex* pYieldMutex = pInst->mpSalYieldMutex; 298cdf0e10cSrcweir sal_uLong nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() ); 299cdf0e10cSrcweir sal_uLong n = nCount; 300cdf0e10cSrcweir while ( n ) 301cdf0e10cSrcweir { 302cdf0e10cSrcweir pYieldMutex->release(); 303cdf0e10cSrcweir n--; 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir return nCount; 307cdf0e10cSrcweir } 308cdf0e10cSrcweir 309cdf0e10cSrcweir // ----------------------------------------------------------------------- 310cdf0e10cSrcweir 311cdf0e10cSrcweir void ImplSalAcquireYieldMutex( sal_uLong nCount ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 314cdf0e10cSrcweir if ( !pInst ) 315cdf0e10cSrcweir return; 316cdf0e10cSrcweir 317cdf0e10cSrcweir SalYieldMutex* pYieldMutex = pInst->mpSalYieldMutex; 318cdf0e10cSrcweir while ( nCount ) 319cdf0e10cSrcweir { 320cdf0e10cSrcweir pYieldMutex->acquire(); 321cdf0e10cSrcweir nCount--; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir // ----------------------------------------------------------------------- 326cdf0e10cSrcweir 327cdf0e10cSrcweir bool WinSalInstance::CheckYieldMutex() 328cdf0e10cSrcweir { 329cdf0e10cSrcweir bool bRet = true; 330cdf0e10cSrcweir SalData* pSalData = GetSalData(); 331cdf0e10cSrcweir DWORD nCurThreadId = GetCurrentThreadId(); 332cdf0e10cSrcweir if ( pSalData->mnAppThreadId != nCurThreadId ) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir if ( pSalData->mpFirstInstance ) 335cdf0e10cSrcweir { 336cdf0e10cSrcweir SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; 337cdf0e10cSrcweir if ( pYieldMutex->mnThreadId != nCurThreadId ) 338cdf0e10cSrcweir { 339cdf0e10cSrcweir bRet = false; 340cdf0e10cSrcweir } 341cdf0e10cSrcweir } 342cdf0e10cSrcweir } 343cdf0e10cSrcweir else 344cdf0e10cSrcweir { 345cdf0e10cSrcweir if ( pSalData->mpFirstInstance ) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; 348cdf0e10cSrcweir if ( pYieldMutex->mnThreadId != nCurThreadId ) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir bRet = false; 351cdf0e10cSrcweir } 352cdf0e10cSrcweir } 353cdf0e10cSrcweir } 354cdf0e10cSrcweir return bRet; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir 357cdf0e10cSrcweir // ======================================================================= 358cdf0e10cSrcweir 359cdf0e10cSrcweir void SalData::initKeyCodeMap() 360cdf0e10cSrcweir { 361cdf0e10cSrcweir UINT nKey = 0xffffffff; 362cdf0e10cSrcweir #define initKey( a, b )\ 363cdf0e10cSrcweir nKey = LOWORD( VkKeyScan( a ) );\ 364cdf0e10cSrcweir if( nKey < 0xffff )\ 365cdf0e10cSrcweir maVKMap[ nKey ] = b; 366cdf0e10cSrcweir 367cdf0e10cSrcweir initKey( '+', KEY_ADD ); 368cdf0e10cSrcweir initKey( '-', KEY_SUBTRACT ); 369cdf0e10cSrcweir initKey( '*', KEY_MULTIPLY ); 370cdf0e10cSrcweir initKey( '/', KEY_DIVIDE ); 371cdf0e10cSrcweir initKey( '.', KEY_POINT ); 372cdf0e10cSrcweir initKey( ',', KEY_COMMA ); 373cdf0e10cSrcweir initKey( '<', KEY_LESS ); 374cdf0e10cSrcweir initKey( '>', KEY_GREATER ); 375cdf0e10cSrcweir initKey( '=', KEY_EQUAL ); 376cdf0e10cSrcweir initKey( '~', KEY_TILDE ); 377cdf0e10cSrcweir initKey( '`', KEY_QUOTELEFT ); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir 380cdf0e10cSrcweir // ======================================================================= 381cdf0e10cSrcweir // ------- 382cdf0e10cSrcweir // SalData 383cdf0e10cSrcweir // ------- 384cdf0e10cSrcweir 385cdf0e10cSrcweir SalData::SalData() 386cdf0e10cSrcweir { 387cdf0e10cSrcweir mhInst = 0; // default instance handle 388cdf0e10cSrcweir mhPrevInst = 0; // previous instance handle 389cdf0e10cSrcweir mnCmdShow = 0; // default frame show style 390cdf0e10cSrcweir mhDitherPal = 0; // dither palette 391cdf0e10cSrcweir mhDitherDIB = 0; // dither memory handle 392cdf0e10cSrcweir mpDitherDIB = 0; // dither memory 393cdf0e10cSrcweir mpDitherDIBData = 0; // beginning of DIB data 394cdf0e10cSrcweir mpDitherDiff = 0; // Dither mapping table 395cdf0e10cSrcweir mpDitherLow = 0; // Dither mapping table 396cdf0e10cSrcweir mpDitherHigh = 0; // Dither mapping table 397cdf0e10cSrcweir mnTimerMS = 0; // Current Time (in MS) of the Timer 398cdf0e10cSrcweir mnTimerOrgMS = 0; // Current Original Time (in MS) 399cdf0e10cSrcweir mnNextTimerTime = 0; 400cdf0e10cSrcweir mnLastEventTime = 0; 401cdf0e10cSrcweir mnTimerId = 0; // windows timer id 402cdf0e10cSrcweir mbInTimerProc = FALSE; // timer event is currently being dispatched 403cdf0e10cSrcweir mhSalObjMsgHook = 0; // hook to get interesting msg for SalObject 404cdf0e10cSrcweir mhWantLeaveMsg = 0; // window handle, that want a MOUSELEAVE message 405cdf0e10cSrcweir mpMouseLeaveTimer = 0; // Timer for MouseLeave Test 406cdf0e10cSrcweir mpFirstInstance = 0; // pointer of first instance 407cdf0e10cSrcweir mpFirstFrame = 0; // pointer of first frame 408cdf0e10cSrcweir mpFirstObject = 0; // pointer of first object window 409cdf0e10cSrcweir mpFirstVD = 0; // first VirDev 410cdf0e10cSrcweir mpFirstPrinter = 0; // first printing printer 411cdf0e10cSrcweir mpHDCCache = 0; // Cache for three DC's 412cdf0e10cSrcweir mh50Bmp = 0; // 50% Bitmap 413cdf0e10cSrcweir mh50Brush = 0; // 50% Brush 414cdf0e10cSrcweir int i; 415cdf0e10cSrcweir for(i=0; i<MAX_STOCKPEN; i++) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir maStockPenColorAry[i] = 0; 418cdf0e10cSrcweir mhStockPenAry[i] = 0; 419cdf0e10cSrcweir } 420cdf0e10cSrcweir for(i=0; i<MAX_STOCKBRUSH; i++) 421cdf0e10cSrcweir { 422cdf0e10cSrcweir maStockBrushColorAry[i] = 0; 423cdf0e10cSrcweir mhStockBrushAry[i] = 0; 424cdf0e10cSrcweir } 425cdf0e10cSrcweir mnStockPenCount = 0; // count of static pens 426cdf0e10cSrcweir mnStockBrushCount = 0; // count of static brushes 427cdf0e10cSrcweir mnSalObjWantKeyEvt = 0; // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll 428cdf0e10cSrcweir mnCacheDCInUse = 0; // count of CacheDC in use 429cdf0e10cSrcweir mbObjClassInit = FALSE; // is SALOBJECTCLASS initialised 430cdf0e10cSrcweir mbInPalChange = FALSE; // is in WM_QUERYNEWPALETTE 431cdf0e10cSrcweir mnAppThreadId = 0; // Id from Applikation-Thread 432cdf0e10cSrcweir mbScrSvrEnabled = FALSE; // ScreenSaver enabled 433cdf0e10cSrcweir mnSageStatus = 0; // status of Sage-DLL (DISABLE_AGENT == nicht vorhanden) 434cdf0e10cSrcweir mpSageEnableProc = 0; // funktion to deactivate the system agent 435cdf0e10cSrcweir mpFirstIcon = 0; // icon cache, points to first icon, NULL if none 436cdf0e10cSrcweir mpTempFontItem = 0; 437cdf0e10cSrcweir mbThemeChanged = FALSE; // true if visual theme was changed: throw away theme handles 438cdf0e10cSrcweir mbThemeMenuSupport = FALSE; 439cdf0e10cSrcweir 440cdf0e10cSrcweir // init with NULL 441cdf0e10cSrcweir gdiplusToken = 0; 442cdf0e10cSrcweir maDwmLib = 0; 443cdf0e10cSrcweir mpDwmIsCompositionEnabled = 0; 444cdf0e10cSrcweir 445cdf0e10cSrcweir initKeyCodeMap(); 446cdf0e10cSrcweir 447cdf0e10cSrcweir SetSalData( this ); 448cdf0e10cSrcweir initNWF(); 449cdf0e10cSrcweir } 450cdf0e10cSrcweir 451cdf0e10cSrcweir SalData::~SalData() 452cdf0e10cSrcweir { 453cdf0e10cSrcweir deInitNWF(); 454cdf0e10cSrcweir SetSalData( NULL ); 455cdf0e10cSrcweir } 456cdf0e10cSrcweir 457cdf0e10cSrcweir void InitSalData() 458cdf0e10cSrcweir { 459cdf0e10cSrcweir SalData* pSalData = new SalData; 460cdf0e10cSrcweir CoInitialize(0); 461cdf0e10cSrcweir 462cdf0e10cSrcweir // init GDIPlus 463cdf0e10cSrcweir static Gdiplus::GdiplusStartupInput gdiplusStartupInput; 464cdf0e10cSrcweir Gdiplus::GdiplusStartup(&pSalData->gdiplusToken, &gdiplusStartupInput, NULL); 465cdf0e10cSrcweir } 466cdf0e10cSrcweir 467cdf0e10cSrcweir 468cdf0e10cSrcweir void DeInitSalData() 469cdf0e10cSrcweir { 470cdf0e10cSrcweir CoUninitialize(); 471cdf0e10cSrcweir SalData* pSalData = GetSalData(); 472cdf0e10cSrcweir 473cdf0e10cSrcweir // deinit GDIPlus 474cdf0e10cSrcweir if(pSalData) 475cdf0e10cSrcweir { 476cdf0e10cSrcweir Gdiplus::GdiplusShutdown(pSalData->gdiplusToken); 477cdf0e10cSrcweir } 478cdf0e10cSrcweir 479cdf0e10cSrcweir delete pSalData; 480cdf0e10cSrcweir } 481cdf0e10cSrcweir 482cdf0e10cSrcweir // ----------------------------------------------------------------------- 483cdf0e10cSrcweir 484cdf0e10cSrcweir void InitSalMain() 485cdf0e10cSrcweir { 486cdf0e10cSrcweir // remember data, copied from WinMain 487cdf0e10cSrcweir SalData* pData = GetAppSalData(); 488cdf0e10cSrcweir if ( pData ) // Im AppServer NULL 489cdf0e10cSrcweir { 490cdf0e10cSrcweir STARTUPINFO aSI; 491cdf0e10cSrcweir aSI.cb = sizeof( aSI ); 492cdf0e10cSrcweir GetStartupInfo( &aSI ); 493cdf0e10cSrcweir pData->mhInst = GetModuleHandle( NULL ); 494cdf0e10cSrcweir pData->mhPrevInst = NULL; 495cdf0e10cSrcweir pData->mnCmdShow = aSI.wShowWindow; 496cdf0e10cSrcweir } 497cdf0e10cSrcweir } 498cdf0e10cSrcweir 499cdf0e10cSrcweir void DeInitSalMain() 500cdf0e10cSrcweir { 501cdf0e10cSrcweir } 502cdf0e10cSrcweir 503cdf0e10cSrcweir // ----------------------------------------------------------------------- 504cdf0e10cSrcweir 505cdf0e10cSrcweir SalInstance* CreateSalInstance() 506cdf0e10cSrcweir { 507cdf0e10cSrcweir SalData* pSalData = GetSalData(); 508cdf0e10cSrcweir 509cdf0e10cSrcweir // determine the windows version 510cdf0e10cSrcweir aSalShlData.mbWXP = 0; 511cdf0e10cSrcweir aSalShlData.mbWPrinter = 0; 512cdf0e10cSrcweir WORD nVer = (WORD)GetVersion(); 513cdf0e10cSrcweir aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer); 514cdf0e10cSrcweir if ( aSalShlData.mnVersion >= 400 ) 515cdf0e10cSrcweir aSalShlData.mbW40 = 1; 516cdf0e10cSrcweir rtl_zeroMemory( &aSalShlData.maVersionInfo, sizeof(aSalShlData.maVersionInfo) ); 517cdf0e10cSrcweir aSalShlData.maVersionInfo.dwOSVersionInfoSize = sizeof( aSalShlData.maVersionInfo ); 518cdf0e10cSrcweir if ( GetVersionEx( &aSalShlData.maVersionInfo ) ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) 521cdf0e10cSrcweir { 522cdf0e10cSrcweir // Windows XP ? 523cdf0e10cSrcweir if ( aSalShlData.maVersionInfo.dwMajorVersion > 5 || 524cdf0e10cSrcweir ( aSalShlData.maVersionInfo.dwMajorVersion == 5 && aSalShlData.maVersionInfo.dwMinorVersion >= 1 ) ) 525cdf0e10cSrcweir aSalShlData.mbWXP = 1; 526cdf0e10cSrcweir if( aSalShlData.maVersionInfo.dwMajorVersion >= 5 ) 527cdf0e10cSrcweir aSalShlData.mbWPrinter = 1; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir } 530cdf0e10cSrcweir 531cdf0e10cSrcweir pSalData->mnAppThreadId = GetCurrentThreadId(); 532cdf0e10cSrcweir 533cdf0e10cSrcweir // register frame class 534cdf0e10cSrcweir if ( !pSalData->mhPrevInst ) 535cdf0e10cSrcweir { 536cdf0e10cSrcweir WNDCLASSEXW aWndClassEx; 537cdf0e10cSrcweir aWndClassEx.cbSize = sizeof( aWndClassEx ); 538cdf0e10cSrcweir aWndClassEx.style = CS_OWNDC; 539cdf0e10cSrcweir aWndClassEx.lpfnWndProc = SalFrameWndProcW; 540cdf0e10cSrcweir aWndClassEx.cbClsExtra = 0; 541cdf0e10cSrcweir aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA; 542cdf0e10cSrcweir aWndClassEx.hInstance = pSalData->mhInst; 543cdf0e10cSrcweir aWndClassEx.hCursor = 0; 544cdf0e10cSrcweir aWndClassEx.hbrBackground = 0; 545cdf0e10cSrcweir aWndClassEx.lpszMenuName = 0; 546cdf0e10cSrcweir aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEW; 547cdf0e10cSrcweir ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm ); 548cdf0e10cSrcweir if ( !RegisterClassExW( &aWndClassEx ) ) 549cdf0e10cSrcweir return NULL; 550cdf0e10cSrcweir 551cdf0e10cSrcweir aWndClassEx.hIcon = 0; 552cdf0e10cSrcweir aWndClassEx.hIconSm = 0; 553cdf0e10cSrcweir aWndClassEx.style |= CS_SAVEBITS; 554cdf0e10cSrcweir aWndClassEx.lpszClassName = SAL_SUBFRAME_CLASSNAMEW; 555cdf0e10cSrcweir if ( !RegisterClassExW( &aWndClassEx ) ) 556cdf0e10cSrcweir return NULL; 557cdf0e10cSrcweir 558cdf0e10cSrcweir // shadow effect for popups on XP 559cdf0e10cSrcweir if( aSalShlData.mbWXP ) 560cdf0e10cSrcweir aWndClassEx.style |= CS_DROPSHADOW; 561cdf0e10cSrcweir aWndClassEx.lpszClassName = SAL_TMPSUBFRAME_CLASSNAMEW; 562cdf0e10cSrcweir if ( !RegisterClassExW( &aWndClassEx ) ) 563cdf0e10cSrcweir return NULL; 564cdf0e10cSrcweir 565cdf0e10cSrcweir aWndClassEx.style = 0; 566cdf0e10cSrcweir aWndClassEx.lpfnWndProc = SalComWndProcW; 567cdf0e10cSrcweir aWndClassEx.cbWndExtra = 0; 568cdf0e10cSrcweir aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW; 569cdf0e10cSrcweir if ( !RegisterClassExW( &aWndClassEx ) ) 570cdf0e10cSrcweir return NULL; 571cdf0e10cSrcweir } 572cdf0e10cSrcweir 573cdf0e10cSrcweir HWND hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW, 574cdf0e10cSrcweir L"", WS_POPUP, 0, 0, 0, 0, 0, 0, 575cdf0e10cSrcweir pSalData->mhInst, NULL ); 576cdf0e10cSrcweir if ( !hComWnd ) 577cdf0e10cSrcweir return NULL; 578cdf0e10cSrcweir 579cdf0e10cSrcweir WinSalInstance* pInst = new WinSalInstance; 580cdf0e10cSrcweir 581cdf0e10cSrcweir // init instance (only one instance in this version !!!) 582cdf0e10cSrcweir pSalData->mpFirstInstance = pInst; 583cdf0e10cSrcweir pInst->mhInst = pSalData->mhInst; 584cdf0e10cSrcweir pInst->mhComWnd = hComWnd; 585cdf0e10cSrcweir 586cdf0e10cSrcweir // init static GDI Data 587cdf0e10cSrcweir ImplInitSalGDI(); 588cdf0e10cSrcweir 589cdf0e10cSrcweir return pInst; 590cdf0e10cSrcweir } 591cdf0e10cSrcweir 592cdf0e10cSrcweir // ----------------------------------------------------------------------- 593cdf0e10cSrcweir 594cdf0e10cSrcweir void DestroySalInstance( SalInstance* pInst ) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir SalData* pSalData = GetSalData(); 597cdf0e10cSrcweir 598cdf0e10cSrcweir // (only one instance in this version !!!) 599cdf0e10cSrcweir 600cdf0e10cSrcweir ImplFreeSalGDI(); 601cdf0e10cSrcweir 602cdf0e10cSrcweir // reset instance 603cdf0e10cSrcweir if ( pSalData->mpFirstInstance == pInst ) 604cdf0e10cSrcweir pSalData->mpFirstInstance = NULL; 605cdf0e10cSrcweir 606cdf0e10cSrcweir delete pInst; 607cdf0e10cSrcweir } 608cdf0e10cSrcweir 609cdf0e10cSrcweir // ----------------------------------------------------------------------- 610cdf0e10cSrcweir 611cdf0e10cSrcweir WinSalInstance::WinSalInstance() 612cdf0e10cSrcweir { 613cdf0e10cSrcweir mhComWnd = 0; 614cdf0e10cSrcweir mpSalYieldMutex = new SalYieldMutex( this ); 615cdf0e10cSrcweir mpSalWaitMutex = new vos::OMutex; 616cdf0e10cSrcweir mnYieldWaitCount = 0; 617cdf0e10cSrcweir mpSalYieldMutex->acquire(); 618cdf0e10cSrcweir ::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex ); 619cdf0e10cSrcweir } 620cdf0e10cSrcweir 621cdf0e10cSrcweir // ----------------------------------------------------------------------- 622cdf0e10cSrcweir 623cdf0e10cSrcweir WinSalInstance::~WinSalInstance() 624cdf0e10cSrcweir { 625cdf0e10cSrcweir ::tools::SolarMutex::SetSolarMutex( 0 ); 626cdf0e10cSrcweir mpSalYieldMutex->release(); 627cdf0e10cSrcweir delete mpSalYieldMutex; 628cdf0e10cSrcweir delete mpSalWaitMutex; 629cdf0e10cSrcweir DestroyWindow( mhComWnd ); 630cdf0e10cSrcweir } 631cdf0e10cSrcweir 632cdf0e10cSrcweir // ----------------------------------------------------------------------- 633cdf0e10cSrcweir 634cdf0e10cSrcweir vos::IMutex* WinSalInstance::GetYieldMutex() 635cdf0e10cSrcweir { 636cdf0e10cSrcweir return mpSalYieldMutex; 637cdf0e10cSrcweir } 638cdf0e10cSrcweir 639cdf0e10cSrcweir // ----------------------------------------------------------------------- 640cdf0e10cSrcweir 641cdf0e10cSrcweir sal_uLong WinSalInstance::ReleaseYieldMutex() 642cdf0e10cSrcweir { 643cdf0e10cSrcweir return ImplSalReleaseYieldMutex(); 644cdf0e10cSrcweir } 645cdf0e10cSrcweir 646cdf0e10cSrcweir // ----------------------------------------------------------------------- 647cdf0e10cSrcweir 648cdf0e10cSrcweir void WinSalInstance::AcquireYieldMutex( sal_uLong nCount ) 649cdf0e10cSrcweir { 650cdf0e10cSrcweir ImplSalAcquireYieldMutex( nCount ); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir // ----------------------------------------------------------------------- 654cdf0e10cSrcweir 655cdf0e10cSrcweir static void ImplSalDispatchMessage( MSG* pMsg ) 656cdf0e10cSrcweir { 657cdf0e10cSrcweir SalData* pSalData = GetSalData(); 658cdf0e10cSrcweir if ( pSalData->mpFirstObject ) 659cdf0e10cSrcweir { 660cdf0e10cSrcweir if ( ImplSalPreDispatchMsg( pMsg ) ) 661cdf0e10cSrcweir return; 662cdf0e10cSrcweir } 663cdf0e10cSrcweir LRESULT lResult = ImplDispatchMessage( pMsg ); 664cdf0e10cSrcweir if ( pSalData->mpFirstObject ) 665cdf0e10cSrcweir ImplSalPostDispatchMsg( pMsg, lResult ); 666cdf0e10cSrcweir } 667cdf0e10cSrcweir 668cdf0e10cSrcweir // ----------------------------------------------------------------------- 669cdf0e10cSrcweir 670cdf0e10cSrcweir void ImplSalYield( sal_Bool bWait, sal_Bool bHandleAllCurrentEvents ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir MSG aMsg; 673cdf0e10cSrcweir bool bWasMsg = false, bOneEvent = false; 674cdf0e10cSrcweir 675cdf0e10cSrcweir int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1; 676cdf0e10cSrcweir do 677cdf0e10cSrcweir { 678cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) 679cdf0e10cSrcweir { 680cdf0e10cSrcweir if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) 681cdf0e10cSrcweir { 682cdf0e10cSrcweir TranslateMessage( &aMsg ); 683cdf0e10cSrcweir ImplSalDispatchMessage( &aMsg ); 684cdf0e10cSrcweir } 685cdf0e10cSrcweir 686cdf0e10cSrcweir bOneEvent = bWasMsg = true; 687cdf0e10cSrcweir } 688cdf0e10cSrcweir else 689cdf0e10cSrcweir bOneEvent = false; 690cdf0e10cSrcweir } while( --nMaxEvents && bOneEvent ); 691cdf0e10cSrcweir 692cdf0e10cSrcweir if ( bWait && ! bWasMsg ) 693cdf0e10cSrcweir { 694cdf0e10cSrcweir if ( ImplGetMessage( &aMsg, 0, 0, 0 ) ) 695cdf0e10cSrcweir { 696cdf0e10cSrcweir if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) 697cdf0e10cSrcweir { 698cdf0e10cSrcweir TranslateMessage( &aMsg ); 699cdf0e10cSrcweir ImplSalDispatchMessage( &aMsg ); 700cdf0e10cSrcweir } 701cdf0e10cSrcweir } 702cdf0e10cSrcweir } 703cdf0e10cSrcweir } 704cdf0e10cSrcweir 705cdf0e10cSrcweir // ----------------------------------------------------------------------- 706cdf0e10cSrcweir 707cdf0e10cSrcweir void WinSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) 708cdf0e10cSrcweir { 709cdf0e10cSrcweir SalYieldMutex* pYieldMutex = mpSalYieldMutex; 710cdf0e10cSrcweir SalData* pSalData = GetSalData(); 711cdf0e10cSrcweir DWORD nCurThreadId = GetCurrentThreadId(); 712cdf0e10cSrcweir sal_uLong nCount = pYieldMutex->GetAcquireCount( nCurThreadId ); 713cdf0e10cSrcweir sal_uLong n = nCount; 714cdf0e10cSrcweir while ( n ) 715cdf0e10cSrcweir { 716cdf0e10cSrcweir pYieldMutex->release(); 717cdf0e10cSrcweir n--; 718cdf0e10cSrcweir } 719cdf0e10cSrcweir if ( pSalData->mnAppThreadId != nCurThreadId ) 720cdf0e10cSrcweir { 721cdf0e10cSrcweir // #97739# A SendMessage call blocks until the called thread (here: the main thread) 722cdf0e10cSrcweir // returns. During a yield however, messages are processed in the main thread that might 723cdf0e10cSrcweir // result in a new message loop due to opening a dialog. Thus, SendMessage would not 724cdf0e10cSrcweir // return which will block this thread! 725cdf0e10cSrcweir // Solution: just give up the time slice and hope that messages are processed 726cdf0e10cSrcweir // by the main thread anyway (where all windows are created) 727cdf0e10cSrcweir // If the mainthread is not currently handling messages, then our SendMessage would 728cdf0e10cSrcweir // also do nothing, so this seems to be reasonable. 729cdf0e10cSrcweir 730cdf0e10cSrcweir // #i18883# only sleep if potential deadlock scenario, ie, when a dialog is open 731cdf0e10cSrcweir if( ImplGetSVData()->maAppData.mnModalMode ) 732cdf0e10cSrcweir Sleep(1); 733cdf0e10cSrcweir else 734cdf0e10cSrcweir ImplSendMessage( mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)bHandleAllCurrentEvents ); 735cdf0e10cSrcweir 736cdf0e10cSrcweir n = nCount; 737cdf0e10cSrcweir while ( n ) 738cdf0e10cSrcweir { 739cdf0e10cSrcweir pYieldMutex->acquire(); 740cdf0e10cSrcweir n--; 741cdf0e10cSrcweir } 742cdf0e10cSrcweir } 743cdf0e10cSrcweir else 744cdf0e10cSrcweir { 745cdf0e10cSrcweir ImplSalYield( bWait, bHandleAllCurrentEvents ); 746cdf0e10cSrcweir 747cdf0e10cSrcweir n = nCount; 748cdf0e10cSrcweir while ( n ) 749cdf0e10cSrcweir { 750cdf0e10cSrcweir ImplSalYieldMutexAcquireWithWait(); 751cdf0e10cSrcweir n--; 752cdf0e10cSrcweir } 753cdf0e10cSrcweir } 754cdf0e10cSrcweir } 755cdf0e10cSrcweir 756cdf0e10cSrcweir // ----------------------------------------------------------------------- 757cdf0e10cSrcweir 758cdf0e10cSrcweir LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) 759cdf0e10cSrcweir { 760cdf0e10cSrcweir LRESULT nRet = 0; 761cdf0e10cSrcweir 762cdf0e10cSrcweir 763cdf0e10cSrcweir switch ( nMsg ) 764cdf0e10cSrcweir { 765cdf0e10cSrcweir case SAL_MSG_PRINTABORTJOB: 766cdf0e10cSrcweir ImplSalPrinterAbortJobAsync( (HDC)wParam ); 767cdf0e10cSrcweir rDef = FALSE; 768cdf0e10cSrcweir break; 769cdf0e10cSrcweir case SAL_MSG_THREADYIELD: 770cdf0e10cSrcweir ImplSalYield( (sal_Bool)wParam, (sal_Bool)lParam ); 771cdf0e10cSrcweir rDef = FALSE; 772cdf0e10cSrcweir break; 773cdf0e10cSrcweir // If we get this message, because another GetMessage() call 774cdf0e10cSrcweir // has recieved this message, we must post this message to 775cdf0e10cSrcweir // us again, because in the other case we wait forever. 776cdf0e10cSrcweir case SAL_MSG_RELEASEWAITYIELD: 777cdf0e10cSrcweir { 778cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance; 779cdf0e10cSrcweir if ( pInst && pInst->mnYieldWaitCount ) 780cdf0e10cSrcweir ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam ); 781cdf0e10cSrcweir } 782cdf0e10cSrcweir rDef = FALSE; 783cdf0e10cSrcweir break; 784cdf0e10cSrcweir case SAL_MSG_STARTTIMER: 785cdf0e10cSrcweir ImplSalStartTimer( (sal_uLong) lParam, FALSE ); 786cdf0e10cSrcweir rDef = FALSE; 787cdf0e10cSrcweir break; 788cdf0e10cSrcweir case SAL_MSG_CREATEFRAME: 789cdf0e10cSrcweir nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (sal_uLong)wParam ); 790cdf0e10cSrcweir rDef = FALSE; 791cdf0e10cSrcweir break; 792cdf0e10cSrcweir case SAL_MSG_RECREATEHWND: 793cdf0e10cSrcweir nRet = (LRESULT)ImplSalReCreateHWND( (HWND)wParam, (HWND)lParam, FALSE ); 794cdf0e10cSrcweir rDef = FALSE; 795cdf0e10cSrcweir break; 796cdf0e10cSrcweir case SAL_MSG_RECREATECHILDHWND: 797cdf0e10cSrcweir nRet = (LRESULT)ImplSalReCreateHWND( (HWND)wParam, (HWND)lParam, TRUE ); 798cdf0e10cSrcweir rDef = FALSE; 799cdf0e10cSrcweir break; 800cdf0e10cSrcweir case SAL_MSG_DESTROYFRAME: 801cdf0e10cSrcweir delete (SalFrame*)lParam; 802cdf0e10cSrcweir rDef = FALSE; 803cdf0e10cSrcweir break; 804cdf0e10cSrcweir case SAL_MSG_DESTROYHWND: 805cdf0e10cSrcweir //We only destroy the native window here. We do NOT destroy the SalFrame contained 806cdf0e10cSrcweir //in the structure (GetWindowPtr()). 807cdf0e10cSrcweir if (DestroyWindow((HWND)lParam) == 0) 808cdf0e10cSrcweir { 809cdf0e10cSrcweir OSL_ENSURE(0, "DestroyWindow failed!"); 810cdf0e10cSrcweir //Failure: We remove the SalFrame from the window structure. So we avoid that 811cdf0e10cSrcweir // the window structure may contain an invalid pointer, once the SalFrame is deleted. 812cdf0e10cSrcweir SetWindowPtr((HWND)lParam, 0); 813cdf0e10cSrcweir } 814cdf0e10cSrcweir rDef = FALSE; 815cdf0e10cSrcweir break; 816cdf0e10cSrcweir case SAL_MSG_CREATEOBJECT: 817cdf0e10cSrcweir nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (WinSalFrame*)lParam ); 818cdf0e10cSrcweir rDef = FALSE; 819cdf0e10cSrcweir break; 820cdf0e10cSrcweir case SAL_MSG_DESTROYOBJECT: 821cdf0e10cSrcweir delete (SalObject*)lParam; 822cdf0e10cSrcweir rDef = FALSE; 823cdf0e10cSrcweir break; 824cdf0e10cSrcweir case SAL_MSG_GETDC: 825cdf0e10cSrcweir nRet = (LRESULT)GetDCEx( (HWND)wParam, 0, DCX_CACHE ); 826cdf0e10cSrcweir rDef = FALSE; 827cdf0e10cSrcweir break; 828cdf0e10cSrcweir case SAL_MSG_RELEASEDC: 829cdf0e10cSrcweir ReleaseDC( (HWND)wParam, (HDC)lParam ); 830cdf0e10cSrcweir rDef = FALSE; 831cdf0e10cSrcweir break; 832cdf0e10cSrcweir case SAL_MSG_POSTTIMER: 833cdf0e10cSrcweir SalTimerProc( 0, 0, SALTIMERPROC_RECURSIVE, lParam ); 834cdf0e10cSrcweir break; 835cdf0e10cSrcweir } 836cdf0e10cSrcweir 837cdf0e10cSrcweir return nRet; 838cdf0e10cSrcweir } 839cdf0e10cSrcweir 840cdf0e10cSrcweir LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 841cdf0e10cSrcweir { 842cdf0e10cSrcweir int bDef = TRUE; 843cdf0e10cSrcweir LRESULT nRet = 0; 844cdf0e10cSrcweir #ifdef __MINGW32__ 845cdf0e10cSrcweir jmp_buf jmpbuf; 846cdf0e10cSrcweir __SEHandler han; 847cdf0e10cSrcweir if (__builtin_setjmp(jmpbuf) == 0) 848cdf0e10cSrcweir { 849cdf0e10cSrcweir han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); 850cdf0e10cSrcweir #else 851cdf0e10cSrcweir __try 852cdf0e10cSrcweir { 853cdf0e10cSrcweir #endif 854cdf0e10cSrcweir nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef ); 855cdf0e10cSrcweir } 856cdf0e10cSrcweir #ifdef __MINGW32__ 857cdf0e10cSrcweir han.Reset(); 858cdf0e10cSrcweir #else 859cdf0e10cSrcweir __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation())) 860cdf0e10cSrcweir { 861cdf0e10cSrcweir } 862cdf0e10cSrcweir #endif 863cdf0e10cSrcweir if ( bDef ) 864cdf0e10cSrcweir { 865cdf0e10cSrcweir if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) ) 866cdf0e10cSrcweir nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam ); 867cdf0e10cSrcweir } 868cdf0e10cSrcweir return nRet; 869cdf0e10cSrcweir } 870cdf0e10cSrcweir 871cdf0e10cSrcweir LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir int bDef = TRUE; 874cdf0e10cSrcweir LRESULT nRet = 0; 875cdf0e10cSrcweir #ifdef __MINGW32__ 876cdf0e10cSrcweir jmp_buf jmpbuf; 877cdf0e10cSrcweir __SEHandler han; 878cdf0e10cSrcweir if (__builtin_setjmp(jmpbuf) == 0) 879cdf0e10cSrcweir { 880cdf0e10cSrcweir han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); 881cdf0e10cSrcweir #else 882cdf0e10cSrcweir __try 883cdf0e10cSrcweir { 884cdf0e10cSrcweir #endif 885cdf0e10cSrcweir nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef ); 886cdf0e10cSrcweir } 887cdf0e10cSrcweir #ifdef __MINGW32__ 888cdf0e10cSrcweir han.Reset(); 889cdf0e10cSrcweir #else 890cdf0e10cSrcweir __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation())) 891cdf0e10cSrcweir { 892cdf0e10cSrcweir } 893cdf0e10cSrcweir #endif 894cdf0e10cSrcweir if ( bDef ) 895cdf0e10cSrcweir { 896cdf0e10cSrcweir if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) ) 897cdf0e10cSrcweir nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam ); 898cdf0e10cSrcweir } 899cdf0e10cSrcweir return nRet; 900cdf0e10cSrcweir } 901cdf0e10cSrcweir 902cdf0e10cSrcweir // ----------------------------------------------------------------------- 903cdf0e10cSrcweir 904cdf0e10cSrcweir bool WinSalInstance::AnyInput( sal_uInt16 nType ) 905cdf0e10cSrcweir { 906cdf0e10cSrcweir MSG aMsg; 907cdf0e10cSrcweir 908cdf0e10cSrcweir if ( (nType & (INPUT_ANY)) == (INPUT_ANY) ) 909cdf0e10cSrcweir { 910cdf0e10cSrcweir // revert bugfix for #108919# which never reported timeouts when called from the timer handler 911cdf0e10cSrcweir // which made the application completely unresponsive during background formatting 912cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ) 913cdf0e10cSrcweir return true; 914cdf0e10cSrcweir } 915cdf0e10cSrcweir else 916cdf0e10cSrcweir { 917cdf0e10cSrcweir if ( nType & INPUT_MOUSE ) 918cdf0e10cSrcweir { 919cdf0e10cSrcweir // Test for mouse input 920cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST, 921cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 922cdf0e10cSrcweir return true; 923cdf0e10cSrcweir } 924cdf0e10cSrcweir 925cdf0e10cSrcweir if ( nType & INPUT_KEYBOARD ) 926cdf0e10cSrcweir { 927cdf0e10cSrcweir // Test for key input 928cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN, 929cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 930cdf0e10cSrcweir { 931cdf0e10cSrcweir if ( (aMsg.wParam == VK_SHIFT) || 932cdf0e10cSrcweir (aMsg.wParam == VK_CONTROL) || 933cdf0e10cSrcweir (aMsg.wParam == VK_MENU) ) 934cdf0e10cSrcweir return false; 935cdf0e10cSrcweir else 936cdf0e10cSrcweir return true; 937cdf0e10cSrcweir } 938cdf0e10cSrcweir } 939cdf0e10cSrcweir 940cdf0e10cSrcweir if ( nType & INPUT_PAINT ) 941cdf0e10cSrcweir { 942cdf0e10cSrcweir // Test for paint input 943cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT, 944cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 945cdf0e10cSrcweir return true; 946cdf0e10cSrcweir 947cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_SIZE, WM_SIZE, 948cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 949cdf0e10cSrcweir return true; 950cdf0e10cSrcweir 951cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, SAL_MSG_POSTCALLSIZE, SAL_MSG_POSTCALLSIZE, 952cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 953cdf0e10cSrcweir return true; 954cdf0e10cSrcweir 955cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_MOVE, WM_MOVE, 956cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 957cdf0e10cSrcweir return true; 958cdf0e10cSrcweir 959cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, SAL_MSG_POSTMOVE, SAL_MSG_POSTMOVE, 960cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 961cdf0e10cSrcweir return true; 962cdf0e10cSrcweir } 963cdf0e10cSrcweir 964cdf0e10cSrcweir if ( nType & INPUT_TIMER ) 965cdf0e10cSrcweir { 966cdf0e10cSrcweir // Test for timer input 967cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER, 968cdf0e10cSrcweir PM_NOREMOVE | PM_NOYIELD ) ) 969cdf0e10cSrcweir return true; 970cdf0e10cSrcweir 971cdf0e10cSrcweir } 972cdf0e10cSrcweir 973cdf0e10cSrcweir if ( nType & INPUT_OTHER ) 974cdf0e10cSrcweir { 975cdf0e10cSrcweir // Test for any input 976cdf0e10cSrcweir if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ) 977cdf0e10cSrcweir return true; 978cdf0e10cSrcweir } 979cdf0e10cSrcweir } 980cdf0e10cSrcweir 981cdf0e10cSrcweir return FALSE; 982cdf0e10cSrcweir } 983cdf0e10cSrcweir 984cdf0e10cSrcweir // ----------------------------------------------------------------------- 985cdf0e10cSrcweir 986cdf0e10cSrcweir void SalTimer::Start( sal_uLong nMS ) 987cdf0e10cSrcweir { 988cdf0e10cSrcweir // Um auf Main-Thread umzuschalten 989cdf0e10cSrcweir SalData* pSalData = GetSalData(); 990cdf0e10cSrcweir if ( pSalData->mpFirstInstance ) 991cdf0e10cSrcweir { 992cdf0e10cSrcweir if ( pSalData->mnAppThreadId != GetCurrentThreadId() ) 993cdf0e10cSrcweir ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS ); 994cdf0e10cSrcweir else 995cdf0e10cSrcweir ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS ); 996cdf0e10cSrcweir } 997cdf0e10cSrcweir else 998cdf0e10cSrcweir ImplSalStartTimer( nMS, FALSE ); 999cdf0e10cSrcweir } 1000cdf0e10cSrcweir 1001cdf0e10cSrcweir // ----------------------------------------------------------------------- 1002cdf0e10cSrcweir 1003cdf0e10cSrcweir SalFrame* WinSalInstance::CreateChildFrame( SystemParentData* pSystemParentData, sal_uLong nSalFrameStyle ) 1004cdf0e10cSrcweir { 1005cdf0e10cSrcweir // Um auf Main-Thread umzuschalten 1006cdf0e10cSrcweir return (SalFrame*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd ); 1007cdf0e10cSrcweir } 1008cdf0e10cSrcweir 1009cdf0e10cSrcweir // ----------------------------------------------------------------------- 1010cdf0e10cSrcweir 1011cdf0e10cSrcweir SalFrame* WinSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nSalFrameStyle ) 1012cdf0e10cSrcweir { 1013cdf0e10cSrcweir // Um auf Main-Thread umzuschalten 1014cdf0e10cSrcweir HWND hWndParent; 1015cdf0e10cSrcweir if ( pParent ) 1016cdf0e10cSrcweir hWndParent = static_cast<WinSalFrame*>(pParent)->mhWnd; 1017cdf0e10cSrcweir else 1018cdf0e10cSrcweir hWndParent = 0; 1019cdf0e10cSrcweir return (SalFrame*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent ); 1020cdf0e10cSrcweir } 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir // ----------------------------------------------------------------------- 1023cdf0e10cSrcweir 1024cdf0e10cSrcweir void WinSalInstance::DestroyFrame( SalFrame* pFrame ) 1025cdf0e10cSrcweir { 1026cdf0e10cSrcweir ImplSendMessage( mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame ); 1027cdf0e10cSrcweir } 1028cdf0e10cSrcweir 1029cdf0e10cSrcweir // ----------------------------------------------------------------------- 1030cdf0e10cSrcweir 1031cdf0e10cSrcweir SalObject* WinSalInstance::CreateObject( SalFrame* pParent, 1032cdf0e10cSrcweir SystemWindowData* /*pWindowData*/, // SystemWindowData meaningless on Windows 1033cdf0e10cSrcweir sal_Bool /*bShow*/ ) 1034cdf0e10cSrcweir { 1035cdf0e10cSrcweir // Um auf Main-Thread umzuschalten 1036cdf0e10cSrcweir return (SalObject*)ImplSendMessage( mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)static_cast<WinSalFrame*>(pParent) ); 1037cdf0e10cSrcweir } 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir // ----------------------------------------------------------------------- 1040cdf0e10cSrcweir 1041cdf0e10cSrcweir void WinSalInstance::DestroyObject( SalObject* pObject ) 1042cdf0e10cSrcweir { 1043cdf0e10cSrcweir ImplSendMessage( mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject ); 1044cdf0e10cSrcweir } 1045cdf0e10cSrcweir 1046cdf0e10cSrcweir // ----------------------------------------------------------------------- 1047cdf0e10cSrcweir 1048cdf0e10cSrcweir void* WinSalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ) 1049cdf0e10cSrcweir { 1050cdf0e10cSrcweir rReturnedBytes = 1; 1051cdf0e10cSrcweir rReturnedType = AsciiCString; 1052cdf0e10cSrcweir return const_cast<char *>(""); 1053cdf0e10cSrcweir } 1054cdf0e10cSrcweir 1055cdf0e10cSrcweir // ----------------------------------------------------------------------- 1056cdf0e10cSrcweir 1057cdf0e10cSrcweir /** Add a file to the system shells recent document list if there is any. 1058cdf0e10cSrcweir This function may have no effect under Unix because there is no 1059cdf0e10cSrcweir standard API among the different desktop managers. 1060cdf0e10cSrcweir 1061cdf0e10cSrcweir @param aFileUrl 1062cdf0e10cSrcweir The file url of the document. 1063cdf0e10cSrcweir */ 1064cdf0e10cSrcweir void WinSalInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& /*rMimeType*/) 1065cdf0e10cSrcweir { 1066cdf0e10cSrcweir rtl::OUString system_path; 1067cdf0e10cSrcweir osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL(rFileUrl, system_path); 1068cdf0e10cSrcweir 1069cdf0e10cSrcweir OSL_ENSURE(osl::FileBase::E_None == rc, "Invalid file url"); 1070cdf0e10cSrcweir 1071cdf0e10cSrcweir if (osl::FileBase::E_None == rc) 1072cdf0e10cSrcweir SHAddToRecentDocs(SHARD_PATHW, system_path.getStr()); 1073cdf0e10cSrcweir } 1074cdf0e10cSrcweir 1075cdf0e10cSrcweir // ----------------------------------------------------------------------- 1076cdf0e10cSrcweir 1077cdf0e10cSrcweir SalTimer* WinSalInstance::CreateSalTimer() 1078cdf0e10cSrcweir { 1079cdf0e10cSrcweir return new WinSalTimer(); 1080cdf0e10cSrcweir } 1081cdf0e10cSrcweir 1082cdf0e10cSrcweir // ----------------------------------------------------------------------- 1083cdf0e10cSrcweir 1084cdf0e10cSrcweir SalBitmap* WinSalInstance::CreateSalBitmap() 1085cdf0e10cSrcweir { 1086cdf0e10cSrcweir return new WinSalBitmap(); 1087cdf0e10cSrcweir } 1088cdf0e10cSrcweir 1089cdf0e10cSrcweir class WinImeStatus : public SalI18NImeStatus 1090cdf0e10cSrcweir { 1091cdf0e10cSrcweir public: 1092cdf0e10cSrcweir WinImeStatus() {} 1093cdf0e10cSrcweir virtual ~WinImeStatus() {} 1094cdf0e10cSrcweir 1095cdf0e10cSrcweir // asks whether there is a status window available 1096cdf0e10cSrcweir // to toggle into menubar 1097cdf0e10cSrcweir virtual bool canToggle() { return false; } 1098cdf0e10cSrcweir virtual void toggle() {} 1099cdf0e10cSrcweir }; 1100cdf0e10cSrcweir 1101cdf0e10cSrcweir SalI18NImeStatus* WinSalInstance::CreateI18NImeStatus() 1102cdf0e10cSrcweir { 1103cdf0e10cSrcweir return new WinImeStatus(); 1104cdf0e10cSrcweir } 1105cdf0e10cSrcweir 1106cdf0e10cSrcweir // ----------------------------------------------------------------------- 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir const ::rtl::OUString& SalGetDesktopEnvironment() 1109cdf0e10cSrcweir { 1110cdf0e10cSrcweir static ::rtl::OUString aDesktopEnvironment( RTL_CONSTASCII_USTRINGPARAM( "Windows" ) ); 1111cdf0e10cSrcweir return aDesktopEnvironment; 1112cdf0e10cSrcweir } 1113cdf0e10cSrcweir 1114cdf0e10cSrcweir SalSession* WinSalInstance::CreateSalSession() 1115cdf0e10cSrcweir { 1116cdf0e10cSrcweir return NULL; 1117cdf0e10cSrcweir } 1118cdf0e10cSrcweir 1119cdf0e10cSrcweir #ifndef __MINGW32__ 1120cdf0e10cSrcweir // ----------------------------------------------------------------------- 1121cdf0e10cSrcweir int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo) 1122cdf0e10cSrcweir { 1123cdf0e10cSrcweir // Decide if an exception is a c++ (mostly UNO) exception or a process violation. 1124cdf0e10cSrcweir // Depending on this information we pass process violations directly to our signal handler ... 1125cdf0e10cSrcweir // and c++ (UNO) exceptions are sended to the following code on the current stack. 1126cdf0e10cSrcweir // Problem behind: user32.dll sometime consumes exceptions/process violations .-) 1127cdf0e10cSrcweir // see also #112221# 1128cdf0e10cSrcweir 1129cdf0e10cSrcweir static DWORD EXCEPTION_MSC_CPP_EXCEPTION = 0xE06D7363; 1130cdf0e10cSrcweir 1131cdf0e10cSrcweir if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_MSC_CPP_EXCEPTION) 1132cdf0e10cSrcweir return EXCEPTION_CONTINUE_SEARCH; 1133cdf0e10cSrcweir 1134cdf0e10cSrcweir return UnhandledExceptionFilter( pExceptionInfo ); 1135cdf0e10cSrcweir } 1136cdf0e10cSrcweir #endif 1137