1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salinst.cxx,v $
10 * $Revision: 1.42.154.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
35 #include <tools/svwin.h>
42 #include <osl/file.hxx>
43 #include <vos/mutex.hxx>
44 #include <tools/debug.hxx>
45 #include <wincomp.hxx>
47 #include <saldata.hxx>
51 #include <vcl/salsys.hxx>
53 #include <vcl/salatype.hxx>
55 #include <vcl/salimestatus.hxx>
56 #include <vcl/timer.hxx>
57 #include <wincomp.hxx> // CS_DROPSHADOW
60 #define min(a,b) (((a) < (b)) ? (a) : (b))
63 #define max(a,b) (((a) > (b)) ? (a) : (b))
67 #pragma warning(push, 1)
68 #pragma warning( disable: 4917 )
72 #include <GdiPlusEnums.h>
73 #include <GdiPlusColor.h>
80 // =======================================================================
82 void SalAbort( const XubString
& rErrorText
)
86 if ( !rErrorText
.Len() )
88 // #112255# make sure crash reporter is triggered
89 RaiseException( 0, EXCEPTION_NONCONTINUABLE
, 0, NULL
);
90 FatalAppExit( 0, "Application Error" );
94 // #112255# make sure crash reporter is triggered
95 RaiseException( 0, EXCEPTION_NONCONTINUABLE
, 0, NULL
);
96 ByteString
aErrorText( ImplSalGetWinAnsiString( rErrorText
) );
97 FatalAppExit( 0, aErrorText
.GetBuffer() );
101 // =======================================================================
103 LRESULT CALLBACK
SalComWndProcA( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
);
104 LRESULT CALLBACK
SalComWndProcW( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
);
106 // =======================================================================
108 class SalYieldMutex
: public vos::OMutex
110 public: // for ImplSalYield()
111 WinSalInstance
* mpInstData
;
116 SalYieldMutex( WinSalInstance
* pInstData
);
118 virtual void SAL_CALL
acquire();
119 virtual void SAL_CALL
release();
120 virtual sal_Bool SAL_CALL
tryToAcquire();
122 ULONG
GetAcquireCount( ULONG nThreadId
);
125 // -----------------------------------------------------------------------
127 SalYieldMutex::SalYieldMutex( WinSalInstance
* pInstData
)
129 mpInstData
= pInstData
;
134 // -----------------------------------------------------------------------
136 void SAL_CALL
SalYieldMutex::acquire()
140 mnThreadId
= GetCurrentThreadId();
143 // -----------------------------------------------------------------------
145 void SAL_CALL
SalYieldMutex::release()
147 DWORD nThreadId
= GetCurrentThreadId();
148 if ( mnThreadId
!= nThreadId
)
152 SalData
* pSalData
= GetSalData();
153 if ( pSalData
->mnAppThreadId
!= nThreadId
)
157 // If we don't call these message, the Output from the
158 // Java clients doesn't come in the right order
161 mpInstData
->mpSalWaitMutex
->acquire();
162 if ( mpInstData
->mnYieldWaitCount
)
163 ImplPostMessage( mpInstData
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, 0, 0 );
167 mpInstData
->mpSalWaitMutex
->release();
185 // -----------------------------------------------------------------------
187 sal_Bool SAL_CALL
SalYieldMutex::tryToAcquire()
189 if( OMutex::tryToAcquire() )
192 mnThreadId
= GetCurrentThreadId();
199 // -----------------------------------------------------------------------
201 ULONG
SalYieldMutex::GetAcquireCount( ULONG nThreadId
)
203 if ( nThreadId
== mnThreadId
)
209 // -----------------------------------------------------------------------
211 void ImplSalYieldMutexAcquireWithWait()
213 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
217 // If we are the main thread, then we must wait with wait, because
218 // in if we don't reschedule, then we create deadlocks if a Windows
219 // Function is called from another thread. If we arn't the main thread,
220 // than we call qcquire directly.
221 DWORD nThreadId
= GetCurrentThreadId();
222 SalData
* pSalData
= GetSalData();
223 if ( pSalData
->mnAppThreadId
== nThreadId
)
225 // Wenn wir den Mutex nicht bekommen, muessen wir solange
226 // warten, bis wir Ihn bekommen
227 BOOL bAcquire
= FALSE
;
230 if ( pInst
->mpSalYieldMutex
->tryToAcquire() )
234 pInst
->mpSalWaitMutex
->acquire();
235 if ( pInst
->mpSalYieldMutex
->tryToAcquire() )
238 pInst
->mpSalWaitMutex
->release();
242 pInst
->mnYieldWaitCount
++;
243 pInst
->mpSalWaitMutex
->release();
245 ImplGetMessage( &aTmpMsg
, pInst
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, SAL_MSG_RELEASEWAITYIELD
);
246 pInst
->mnYieldWaitCount
--;
247 if ( pInst
->mnYieldWaitCount
)
248 ImplPostMessage( pInst
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, 0, 0 );
255 pInst
->mpSalYieldMutex
->acquire();
258 // -----------------------------------------------------------------------
260 BOOL
ImplSalYieldMutexTryToAcquire()
262 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
264 return pInst
->mpSalYieldMutex
->tryToAcquire();
269 // -----------------------------------------------------------------------
271 void ImplSalYieldMutexAcquire()
273 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
275 pInst
->mpSalYieldMutex
->acquire();
278 // -----------------------------------------------------------------------
280 void ImplSalYieldMutexRelease()
282 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
286 pInst
->mpSalYieldMutex
->release();
290 // -----------------------------------------------------------------------
292 ULONG
ImplSalReleaseYieldMutex()
294 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
298 SalYieldMutex
* pYieldMutex
= pInst
->mpSalYieldMutex
;
299 ULONG nCount
= pYieldMutex
->GetAcquireCount( GetCurrentThreadId() );
303 pYieldMutex
->release();
310 // -----------------------------------------------------------------------
312 void ImplSalAcquireYieldMutex( ULONG nCount
)
314 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
318 SalYieldMutex
* pYieldMutex
= pInst
->mpSalYieldMutex
;
321 pYieldMutex
->acquire();
326 // -----------------------------------------------------------------------
330 void ImplDbgTestSolarMutex()
332 SalData
* pSalData
= GetSalData();
333 DWORD nCurThreadId
= GetCurrentThreadId();
334 if ( pSalData
->mnAppThreadId
!= nCurThreadId
)
336 if ( pSalData
->mpFirstInstance
)
338 SalYieldMutex
* pYieldMutex
= pSalData
->mpFirstInstance
->mpSalYieldMutex
;
339 if ( pYieldMutex
->mnThreadId
!= nCurThreadId
)
341 DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
347 if ( pSalData
->mpFirstInstance
)
349 SalYieldMutex
* pYieldMutex
= pSalData
->mpFirstInstance
->mpSalYieldMutex
;
350 if ( pYieldMutex
->mnThreadId
!= nCurThreadId
)
352 DBG_ERROR( "SolarMutex not locked in the main thread" );
360 // =======================================================================
362 void SalData::initKeyCodeMap()
364 UINT nKey
= 0xffffffff;
365 #define initKey( a, b )\
366 nKey = LOWORD( VkKeyScan( a ) );\
370 initKey( '+', KEY_ADD
);
371 initKey( '-', KEY_SUBTRACT
);
372 initKey( '*', KEY_MULTIPLY
);
373 initKey( '/', KEY_DIVIDE
);
374 initKey( '.', KEY_POINT
);
375 initKey( ',', KEY_COMMA
);
376 initKey( '<', KEY_LESS
);
377 initKey( '>', KEY_GREATER
);
378 initKey( '=', KEY_EQUAL
);
379 initKey( '~', KEY_TILDE
);
380 initKey( '`', KEY_QUOTELEFT
);
381 initKey( '[', KEY_BRACKETLEFT
);
382 initKey( ']', KEY_BRACKETRIGHT
);
385 // =======================================================================
392 mhInst
= 0; // default instance handle
393 mhPrevInst
= 0; // previous instance handle
394 mnCmdShow
= 0; // default frame show style
395 mhDitherPal
= 0; // dither palette
396 mhDitherDIB
= 0; // dither memory handle
397 mpDitherDIB
= 0; // dither memory
398 mpDitherDIBData
= 0; // beginning of DIB data
399 mpDitherDiff
= 0; // Dither mapping table
400 mpDitherLow
= 0; // Dither mapping table
401 mpDitherHigh
= 0; // Dither mapping table
402 mnTimerMS
= 0; // Current Time (in MS) of the Timer
403 mnTimerOrgMS
= 0; // Current Original Time (in MS)
406 mnTimerId
= 0; // windows timer id
407 mbInTimerProc
= FALSE
; // timer event is currently being dispatched
408 mhSalObjMsgHook
= 0; // hook to get interesting msg for SalObject
409 mhWantLeaveMsg
= 0; // window handle, that want a MOUSELEAVE message
410 mpMouseLeaveTimer
= 0; // Timer for MouseLeave Test
411 mpFirstInstance
= 0; // pointer of first instance
412 mpFirstFrame
= 0; // pointer of first frame
413 mpFirstObject
= 0; // pointer of first object window
414 mpFirstVD
= 0; // first VirDev
415 mpFirstPrinter
= 0; // first printing printer
416 mpHDCCache
= 0; // Cache for three DC's
417 mh50Bmp
= 0; // 50% Bitmap
418 mh50Brush
= 0; // 50% Brush
420 for(i
=0; i
<MAX_STOCKPEN
; i
++)
422 maStockPenColorAry
[i
] = 0;
423 mhStockPenAry
[i
] = 0;
425 for(i
=0; i
<MAX_STOCKBRUSH
; i
++)
427 maStockBrushColorAry
[i
] = 0;
428 mhStockBrushAry
[i
] = 0;
430 mnStockPenCount
= 0; // count of static pens
431 mnStockBrushCount
= 0; // count of static brushes
432 mnSalObjWantKeyEvt
= 0; // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll
433 mnCacheDCInUse
= 0; // count of CacheDC in use
434 mbObjClassInit
= FALSE
; // is SALOBJECTCLASS initialised
435 mbInPalChange
= FALSE
; // is in WM_QUERYNEWPALETTE
436 mnAppThreadId
= 0; // Id from Applikation-Thread
437 mbScrSvrEnabled
= FALSE
; // ScreenSaver enabled
438 mnSageStatus
= 0; // status of Sage-DLL (DISABLE_AGENT == nicht vorhanden)
439 mpSageEnableProc
= 0; // funktion to deactivate the system agent
440 mpFirstIcon
= 0; // icon cache, points to first icon, NULL if none
442 mbThemeChanged
= FALSE
; // true if visual theme was changed: throw away theme handles
461 SalData
* pSalData
= new SalData
;
465 static Gdiplus::GdiplusStartupInput gdiplusStartupInput
;
466 Gdiplus::GdiplusStartup(&pSalData
->gdiplusToken
, &gdiplusStartupInput
, NULL
);
473 SalData
* pSalData
= GetSalData();
478 Gdiplus::GdiplusShutdown(pSalData
->gdiplusToken
);
484 // -----------------------------------------------------------------------
488 // remember data, copied from WinMain
489 SalData
* pData
= GetAppSalData();
490 if ( pData
) // Im AppServer NULL
493 aSI
.cb
= sizeof( aSI
);
494 GetStartupInfo( &aSI
);
495 pData
->mhInst
= GetModuleHandle( NULL
);
496 pData
->mhPrevInst
= NULL
;
497 pData
->mnCmdShow
= aSI
.wShowWindow
;
505 // -----------------------------------------------------------------------
507 SalInstance
* CreateSalInstance()
509 SalData
* pSalData
= GetSalData();
511 // determine the windows version
512 aSalShlData
.mbWNT
= 0;
513 aSalShlData
.mbWXP
= 0;
514 aSalShlData
.mbWPrinter
= 0;
515 WORD nVer
= (WORD
)GetVersion();
516 aSalShlData
.mnVersion
= (((WORD
)LOBYTE(nVer
)) * 100) + HIBYTE(nVer
);
517 if ( aSalShlData
.mnVersion
>= 400 )
518 aSalShlData
.mbW40
= 1;
519 rtl_zeroMemory( &aSalShlData
.maVersionInfo
, sizeof(aSalShlData
.maVersionInfo
) );
520 aSalShlData
.maVersionInfo
.dwOSVersionInfoSize
= sizeof( aSalShlData
.maVersionInfo
);
521 if ( GetVersionEx( &aSalShlData
.maVersionInfo
) )
523 if ( aSalShlData
.maVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
525 aSalShlData
.mbWNT
= 1;
527 if ( aSalShlData
.maVersionInfo
.dwMajorVersion
> 5 ||
528 ( aSalShlData
.maVersionInfo
.dwMajorVersion
== 5 && aSalShlData
.maVersionInfo
.dwMinorVersion
>= 1 ) )
529 aSalShlData
.mbWXP
= 1;
530 if( aSalShlData
.maVersionInfo
.dwMajorVersion
>= 5 )
531 aSalShlData
.mbWPrinter
= 1;
535 pSalData
->mnAppThreadId
= GetCurrentThreadId();
537 // register frame class
538 if ( !pSalData
->mhPrevInst
)
540 if ( aSalShlData
.mbWNT
)
542 WNDCLASSEXW aWndClassEx
;
543 aWndClassEx
.cbSize
= sizeof( aWndClassEx
);
544 aWndClassEx
.style
= CS_OWNDC
;
545 aWndClassEx
.lpfnWndProc
= SalFrameWndProcW
;
546 aWndClassEx
.cbClsExtra
= 0;
547 aWndClassEx
.cbWndExtra
= SAL_FRAME_WNDEXTRA
;
548 aWndClassEx
.hInstance
= pSalData
->mhInst
;
549 aWndClassEx
.hCursor
= 0;
550 aWndClassEx
.hbrBackground
= 0;
551 aWndClassEx
.lpszMenuName
= 0;
552 aWndClassEx
.lpszClassName
= SAL_FRAME_CLASSNAMEW
;
553 ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT
, aWndClassEx
.hIcon
, aWndClassEx
.hIconSm
);
554 if ( !RegisterClassExW( &aWndClassEx
) )
557 aWndClassEx
.hIcon
= 0;
558 aWndClassEx
.hIconSm
= 0;
559 aWndClassEx
.style
|= CS_SAVEBITS
;
560 aWndClassEx
.lpszClassName
= SAL_SUBFRAME_CLASSNAMEW
;
561 if ( !RegisterClassExW( &aWndClassEx
) )
564 // shadow effect for popups on XP
565 if( aSalShlData
.mbWXP
)
566 aWndClassEx
.style
|= CS_DROPSHADOW
;
567 aWndClassEx
.lpszClassName
= SAL_TMPSUBFRAME_CLASSNAMEW
;
568 if ( !RegisterClassExW( &aWndClassEx
) )
571 aWndClassEx
.style
= 0;
572 aWndClassEx
.lpfnWndProc
= SalComWndProcW
;
573 aWndClassEx
.cbWndExtra
= 0;
574 aWndClassEx
.lpszClassName
= SAL_COM_CLASSNAMEW
;
575 if ( !RegisterClassExW( &aWndClassEx
) )
580 WNDCLASSEXA aWndClassEx
;
581 aWndClassEx
.cbSize
= sizeof( aWndClassEx
);
582 aWndClassEx
.style
= CS_OWNDC
;
583 aWndClassEx
.lpfnWndProc
= SalFrameWndProcA
;
584 aWndClassEx
.cbClsExtra
= 0;
585 aWndClassEx
.cbWndExtra
= SAL_FRAME_WNDEXTRA
;
586 aWndClassEx
.hInstance
= pSalData
->mhInst
;
587 aWndClassEx
.hCursor
= 0;
588 aWndClassEx
.hbrBackground
= 0;
589 aWndClassEx
.lpszMenuName
= 0;
590 aWndClassEx
.lpszClassName
= SAL_FRAME_CLASSNAMEA
;
591 ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT
, aWndClassEx
.hIcon
, aWndClassEx
.hIconSm
);
592 if ( !RegisterClassExA( &aWndClassEx
) )
595 aWndClassEx
.hIcon
= 0;
596 aWndClassEx
.hIconSm
= 0;
597 aWndClassEx
.style
|= CS_SAVEBITS
;
598 aWndClassEx
.lpszClassName
= SAL_SUBFRAME_CLASSNAMEA
;
599 if ( !RegisterClassExA( &aWndClassEx
) )
602 aWndClassEx
.style
= 0;
603 aWndClassEx
.lpfnWndProc
= SalComWndProcA
;
604 aWndClassEx
.cbWndExtra
= 0;
605 aWndClassEx
.lpszClassName
= SAL_COM_CLASSNAMEA
;
606 if ( !RegisterClassExA( &aWndClassEx
) )
612 if ( aSalShlData
.mbWNT
)
614 hComWnd
= CreateWindowExW( WS_EX_TOOLWINDOW
, SAL_COM_CLASSNAMEW
,
615 L
"", WS_POPUP
, 0, 0, 0, 0, 0, 0,
616 pSalData
->mhInst
, NULL
);
620 hComWnd
= CreateWindowExA( WS_EX_TOOLWINDOW
, SAL_COM_CLASSNAMEA
,
621 "", WS_POPUP
, 0, 0, 0, 0, 0, 0,
622 pSalData
->mhInst
, NULL
);
627 WinSalInstance
* pInst
= new WinSalInstance
;
629 // init instance (only one instance in this version !!!)
630 pSalData
->mpFirstInstance
= pInst
;
631 pInst
->mhInst
= pSalData
->mhInst
;
632 pInst
->mhComWnd
= hComWnd
;
634 // init static GDI Data
640 // -----------------------------------------------------------------------
642 void DestroySalInstance( SalInstance
* pInst
)
644 SalData
* pSalData
= GetSalData();
646 // (only one instance in this version !!!)
651 if ( pSalData
->mpFirstInstance
== pInst
)
652 pSalData
->mpFirstInstance
= NULL
;
657 // -----------------------------------------------------------------------
659 WinSalInstance::WinSalInstance()
662 mpSalYieldMutex
= new SalYieldMutex( this );
663 mpSalWaitMutex
= new vos::OMutex
;
664 mnYieldWaitCount
= 0;
665 mpSalYieldMutex
->acquire();
668 // -----------------------------------------------------------------------
670 WinSalInstance::~WinSalInstance()
672 mpSalYieldMutex
->release();
673 delete mpSalYieldMutex
;
674 delete mpSalWaitMutex
;
675 DestroyWindow( mhComWnd
);
678 // -----------------------------------------------------------------------
680 vos::IMutex
* WinSalInstance::GetYieldMutex()
682 return mpSalYieldMutex
;
685 // -----------------------------------------------------------------------
687 ULONG
WinSalInstance::ReleaseYieldMutex()
689 return ImplSalReleaseYieldMutex();
692 // -----------------------------------------------------------------------
694 void WinSalInstance::AcquireYieldMutex( ULONG nCount
)
696 ImplSalAcquireYieldMutex( nCount
);
699 // -----------------------------------------------------------------------
701 static void ImplSalDispatchMessage( MSG
* pMsg
)
703 SalData
* pSalData
= GetSalData();
704 if ( pSalData
->mpFirstObject
)
706 if ( ImplSalPreDispatchMsg( pMsg
) )
709 LRESULT lResult
= ImplDispatchMessage( pMsg
);
710 if ( pSalData
->mpFirstObject
)
711 ImplSalPostDispatchMsg( pMsg
, lResult
);
714 // -----------------------------------------------------------------------
716 void ImplSalYield( BOOL bWait
, BOOL bHandleAllCurrentEvents
)
719 bool bWasMsg
= false, bOneEvent
= false;
721 int nMaxEvents
= bHandleAllCurrentEvents
? 100 : 1;
724 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_REMOVE
) )
726 TranslateMessage( &aMsg
);
727 ImplSalDispatchMessage( &aMsg
);
728 bOneEvent
= bWasMsg
= true;
732 } while( --nMaxEvents
&& bOneEvent
);
734 if ( bWait
&& ! bWasMsg
)
736 if ( ImplGetMessage( &aMsg
, 0, 0, 0 ) )
738 TranslateMessage( &aMsg
);
739 ImplSalDispatchMessage( &aMsg
);
744 // -----------------------------------------------------------------------
746 void WinSalInstance::Yield( bool bWait
, bool bHandleAllCurrentEvents
)
748 SalYieldMutex
* pYieldMutex
= mpSalYieldMutex
;
749 SalData
* pSalData
= GetSalData();
750 DWORD nCurThreadId
= GetCurrentThreadId();
751 ULONG nCount
= pYieldMutex
->GetAcquireCount( nCurThreadId
);
755 pYieldMutex
->release();
758 if ( pSalData
->mnAppThreadId
!= nCurThreadId
)
760 // #97739# A SendMessage call blocks until the called thread (here: the main thread)
761 // returns. During a yield however, messages are processed in the main thread that might
762 // result in a new message loop due to opening a dialog. Thus, SendMessage would not
763 // return which will block this thread!
764 // Solution: just give up the time slice and hope that messages are processed
765 // by the main thread anyway (where all windows are created)
766 // If the mainthread is not currently handling messages, then our SendMessage would
767 // also do nothing, so this seems to be reasonable.
769 // #i18883# only sleep if potential deadlock scenario, ie, when a dialog is open
770 if( ImplGetSVData()->maAppData
.mnModalMode
)
773 ImplSendMessage( mhComWnd
, SAL_MSG_THREADYIELD
, (WPARAM
)bWait
, (LPARAM
)bHandleAllCurrentEvents
);
778 pYieldMutex
->acquire();
784 ImplSalYield( bWait
, bHandleAllCurrentEvents
);
789 ImplSalYieldMutexAcquireWithWait();
795 // -----------------------------------------------------------------------
797 LRESULT CALLBACK
SalComWndProc( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
, int& rDef
)
804 case SAL_MSG_PRINTABORTJOB
:
805 ImplSalPrinterAbortJobAsync( (HDC
)wParam
);
808 case SAL_MSG_THREADYIELD
:
809 ImplSalYield( (BOOL
)wParam
, (BOOL
)lParam
);
812 // If we get this message, because another GetMessage() call
813 // has recieved this message, we must post this message to
814 // us again, because in the other case we wait forever.
815 case SAL_MSG_RELEASEWAITYIELD
:
817 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
818 if ( pInst
&& pInst
->mnYieldWaitCount
)
819 ImplPostMessage( hWnd
, SAL_MSG_RELEASEWAITYIELD
, wParam
, lParam
);
823 case SAL_MSG_STARTTIMER
:
824 ImplSalStartTimer( (ULONG
) lParam
, FALSE
);
827 case SAL_MSG_CREATEFRAME
:
828 nRet
= (LRESULT
)ImplSalCreateFrame( GetSalData()->mpFirstInstance
, (HWND
)lParam
, (ULONG
)wParam
);
831 case SAL_MSG_RECREATEHWND
:
832 nRet
= (LRESULT
)ImplSalReCreateHWND( (HWND
)wParam
, (HWND
)lParam
, FALSE
);
835 case SAL_MSG_RECREATECHILDHWND
:
836 nRet
= (LRESULT
)ImplSalReCreateHWND( (HWND
)wParam
, (HWND
)lParam
, TRUE
);
839 case SAL_MSG_DESTROYFRAME
:
840 delete (SalFrame
*)lParam
;
843 case SAL_MSG_DESTROYHWND
:
844 //We only destroy the native window here. We do NOT destroy the SalFrame contained
845 //in the structure (GetWindowPtr()).
846 if (DestroyWindow((HWND
)lParam
) == 0)
848 OSL_ENSURE(0, "DestroyWindow failed!");
849 //Failure: We remove the SalFrame from the window structure. So we avoid that
850 // the window structure may contain an invalid pointer, once the SalFrame is deleted.
851 SetWindowPtr((HWND
)lParam
, 0);
855 case SAL_MSG_CREATEOBJECT
:
856 nRet
= (LRESULT
)ImplSalCreateObject( GetSalData()->mpFirstInstance
, (WinSalFrame
*)lParam
);
859 case SAL_MSG_DESTROYOBJECT
:
860 delete (SalObject
*)lParam
;
864 nRet
= (LRESULT
)GetDCEx( (HWND
)wParam
, 0, DCX_CACHE
);
867 case SAL_MSG_RELEASEDC
:
868 ReleaseDC( (HWND
)wParam
, (HDC
)lParam
);
871 case SAL_MSG_POSTTIMER
:
872 SalTimerProc( 0, 0, SALTIMERPROC_RECURSIVE
, lParam
);
879 LRESULT CALLBACK
SalComWndProcA( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
886 if (__builtin_setjmp(jmpbuf
) == 0)
888 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
893 nRet
= SalComWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
898 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
904 if ( !ImplHandleGlobalMsg( hWnd
, nMsg
, wParam
, lParam
, nRet
) )
905 nRet
= DefWindowProcA( hWnd
, nMsg
, wParam
, lParam
);
910 LRESULT CALLBACK
SalComWndProcW( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
917 if (__builtin_setjmp(jmpbuf
) == 0)
919 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
924 nRet
= SalComWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
929 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
935 if ( !ImplHandleGlobalMsg( hWnd
, nMsg
, wParam
, lParam
, nRet
) )
936 nRet
= DefWindowProcW( hWnd
, nMsg
, wParam
, lParam
);
941 // -----------------------------------------------------------------------
943 bool WinSalInstance::AnyInput( USHORT nType
)
947 if ( (nType
& (INPUT_ANY
)) == (INPUT_ANY
) )
949 // revert bugfix for #108919# which never reported timeouts when called from the timer handler
950 // which made the application completely unresponsive during background formatting
951 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_NOREMOVE
| PM_NOYIELD
) )
956 if ( nType
& INPUT_MOUSE
)
958 // Test for mouse input
959 if ( ImplPeekMessage( &aMsg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
,
960 PM_NOREMOVE
| PM_NOYIELD
) )
964 if ( nType
& INPUT_KEYBOARD
)
966 // Test for key input
967 if ( ImplPeekMessage( &aMsg
, 0, WM_KEYDOWN
, WM_KEYDOWN
,
968 PM_NOREMOVE
| PM_NOYIELD
) )
970 if ( (aMsg
.wParam
== VK_SHIFT
) ||
971 (aMsg
.wParam
== VK_CONTROL
) ||
972 (aMsg
.wParam
== VK_MENU
) )
979 if ( nType
& INPUT_PAINT
)
981 // Test for paint input
982 if ( ImplPeekMessage( &aMsg
, 0, WM_PAINT
, WM_PAINT
,
983 PM_NOREMOVE
| PM_NOYIELD
) )
986 if ( ImplPeekMessage( &aMsg
, 0, WM_SIZE
, WM_SIZE
,
987 PM_NOREMOVE
| PM_NOYIELD
) )
990 if ( ImplPeekMessage( &aMsg
, 0, SAL_MSG_POSTCALLSIZE
, SAL_MSG_POSTCALLSIZE
,
991 PM_NOREMOVE
| PM_NOYIELD
) )
994 if ( ImplPeekMessage( &aMsg
, 0, WM_MOVE
, WM_MOVE
,
995 PM_NOREMOVE
| PM_NOYIELD
) )
998 if ( ImplPeekMessage( &aMsg
, 0, SAL_MSG_POSTMOVE
, SAL_MSG_POSTMOVE
,
999 PM_NOREMOVE
| PM_NOYIELD
) )
1003 if ( nType
& INPUT_TIMER
)
1005 // Test for timer input
1006 if ( ImplPeekMessage( &aMsg
, 0, WM_TIMER
, WM_TIMER
,
1007 PM_NOREMOVE
| PM_NOYIELD
) )
1012 if ( nType
& INPUT_OTHER
)
1014 // Test for any input
1015 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_NOREMOVE
| PM_NOYIELD
) )
1023 // -----------------------------------------------------------------------
1025 void SalTimer::Start( ULONG nMS
)
1027 // Um auf Main-Thread umzuschalten
1028 SalData
* pSalData
= GetSalData();
1029 if ( pSalData
->mpFirstInstance
)
1031 if ( pSalData
->mnAppThreadId
!= GetCurrentThreadId() )
1032 ImplPostMessage( pSalData
->mpFirstInstance
->mhComWnd
, SAL_MSG_STARTTIMER
, 0, (LPARAM
)nMS
);
1034 ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
, SAL_MSG_STARTTIMER
, 0, (LPARAM
)nMS
);
1037 ImplSalStartTimer( nMS
, FALSE
);
1040 // -----------------------------------------------------------------------
1042 SalFrame
* WinSalInstance::CreateChildFrame( SystemParentData
* pSystemParentData
, ULONG nSalFrameStyle
)
1044 // Um auf Main-Thread umzuschalten
1045 return (SalFrame
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEFRAME
, nSalFrameStyle
, (LPARAM
)pSystemParentData
->hWnd
);
1048 // -----------------------------------------------------------------------
1050 SalFrame
* WinSalInstance::CreateFrame( SalFrame
* pParent
, ULONG nSalFrameStyle
)
1052 // Um auf Main-Thread umzuschalten
1055 hWndParent
= static_cast<WinSalFrame
*>(pParent
)->mhWnd
;
1058 return (SalFrame
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEFRAME
, nSalFrameStyle
, (LPARAM
)hWndParent
);
1061 // -----------------------------------------------------------------------
1063 void WinSalInstance::DestroyFrame( SalFrame
* pFrame
)
1065 ImplSendMessage( mhComWnd
, SAL_MSG_DESTROYFRAME
, 0, (LPARAM
)pFrame
);
1068 // -----------------------------------------------------------------------
1070 SalObject
* WinSalInstance::CreateObject( SalFrame
* pParent
,
1071 SystemWindowData
* /*pWindowData*/, // SystemWindowData meaningless on Windows
1074 // Um auf Main-Thread umzuschalten
1075 return (SalObject
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEOBJECT
, 0, (LPARAM
)static_cast<WinSalFrame
*>(pParent
) );
1078 // -----------------------------------------------------------------------
1080 void WinSalInstance::DestroyObject( SalObject
* pObject
)
1082 ImplSendMessage( mhComWnd
, SAL_MSG_DESTROYOBJECT
, 0, (LPARAM
)pObject
);
1085 // -----------------------------------------------------------------------
1087 void* WinSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
1090 rReturnedType
= AsciiCString
;
1091 return const_cast<char *>("");
1094 // -----------------------------------------------------------------------
1096 /** Add a file to the system shells recent document list if there is any.
1097 This function may have no effect under Unix because there is no
1098 standard API among the different desktop managers.
1101 The file url of the document.
1103 void WinSalInstance::AddToRecentDocumentList(const rtl::OUString
& rFileUrl
, const rtl::OUString
& /*rMimeType*/)
1105 rtl::OUString system_path
;
1106 osl::FileBase::RC rc
= osl::FileBase::getSystemPathFromFileURL(rFileUrl
, system_path
);
1108 OSL_ENSURE(osl::FileBase::E_None
== rc
, "Invalid file url");
1110 if (osl::FileBase::E_None
== rc
)
1111 SHAddToRecentDocs(SHARD_PATHW
, system_path
.getStr());
1114 // -----------------------------------------------------------------------
1116 SalTimer
* WinSalInstance::CreateSalTimer()
1118 return new WinSalTimer();
1121 // -----------------------------------------------------------------------
1123 SalBitmap
* WinSalInstance::CreateSalBitmap()
1125 return new WinSalBitmap();
1128 class WinImeStatus
: public SalI18NImeStatus
1132 virtual ~WinImeStatus() {}
1134 // asks whether there is a status window available
1135 // to toggle into menubar
1136 virtual bool canToggle() { return false; }
1137 virtual void toggle() {}
1140 SalI18NImeStatus
* WinSalInstance::CreateI18NImeStatus()
1142 return new WinImeStatus();
1145 // -----------------------------------------------------------------------
1147 const ::rtl::OUString
& SalGetDesktopEnvironment()
1149 static ::rtl::OUString
aDesktopEnvironment( RTL_CONSTASCII_USTRINGPARAM( "Windows" ) );
1150 return aDesktopEnvironment
;
1153 SalSession
* WinSalInstance::CreateSalSession()
1159 // -----------------------------------------------------------------------
1160 int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo
)
1162 // Decide if an exception is a c++ (mostly UNO) exception or a process violation.
1163 // Depending on this information we pass process violations directly to our signal handler ...
1164 // and c++ (UNO) exceptions are sended to the following code on the current stack.
1165 // Problem behind: user32.dll sometime consumes exceptions/process violations .-)
1166 // see also #112221#
1168 static DWORD EXCEPTION_MSC_CPP_EXCEPTION
= 0xE06D7363;
1170 if (pExceptionInfo
->ExceptionRecord
->ExceptionCode
== EXCEPTION_MSC_CPP_EXCEPTION
)
1171 return EXCEPTION_CONTINUE_SEARCH
;
1173 return UnhandledExceptionFilter( pExceptionInfo
);