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>
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)
71 #include <GdiPlusEnums.h>
72 #include <GdiPlusColor.h>
78 // =======================================================================
80 void SalAbort( const XubString
& rErrorText
)
84 if ( !rErrorText
.Len() )
86 // #112255# make sure crash reporter is triggered
87 RaiseException( 0, EXCEPTION_NONCONTINUABLE
, 0, NULL
);
88 FatalAppExit( 0, "Application Error" );
92 // #112255# make sure crash reporter is triggered
93 RaiseException( 0, EXCEPTION_NONCONTINUABLE
, 0, NULL
);
94 ByteString
aErrorText( ImplSalGetWinAnsiString( rErrorText
) );
95 FatalAppExit( 0, aErrorText
.GetBuffer() );
99 // =======================================================================
101 LRESULT CALLBACK
SalComWndProcA( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
);
102 LRESULT CALLBACK
SalComWndProcW( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
);
104 // =======================================================================
106 class SalYieldMutex
: public vos::OMutex
108 public: // for ImplSalYield()
109 WinSalInstance
* mpInstData
;
114 SalYieldMutex( WinSalInstance
* pInstData
);
116 virtual void SAL_CALL
acquire();
117 virtual void SAL_CALL
release();
118 virtual sal_Bool SAL_CALL
tryToAcquire();
120 ULONG
GetAcquireCount( ULONG nThreadId
);
123 // -----------------------------------------------------------------------
125 SalYieldMutex::SalYieldMutex( WinSalInstance
* pInstData
)
127 mpInstData
= pInstData
;
132 // -----------------------------------------------------------------------
134 void SAL_CALL
SalYieldMutex::acquire()
138 mnThreadId
= GetCurrentThreadId();
141 // -----------------------------------------------------------------------
143 void SAL_CALL
SalYieldMutex::release()
145 DWORD nThreadId
= GetCurrentThreadId();
146 if ( mnThreadId
!= nThreadId
)
150 SalData
* pSalData
= GetSalData();
151 if ( pSalData
->mnAppThreadId
!= nThreadId
)
155 // If we don't call these message, the Output from the
156 // Java clients doesn't come in the right order
159 mpInstData
->mpSalWaitMutex
->acquire();
160 if ( mpInstData
->mnYieldWaitCount
)
161 ImplPostMessage( mpInstData
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, 0, 0 );
165 mpInstData
->mpSalWaitMutex
->release();
183 // -----------------------------------------------------------------------
185 sal_Bool SAL_CALL
SalYieldMutex::tryToAcquire()
187 if( OMutex::tryToAcquire() )
190 mnThreadId
= GetCurrentThreadId();
197 // -----------------------------------------------------------------------
199 ULONG
SalYieldMutex::GetAcquireCount( ULONG nThreadId
)
201 if ( nThreadId
== mnThreadId
)
207 // -----------------------------------------------------------------------
209 void ImplSalYieldMutexAcquireWithWait()
211 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
215 // If we are the main thread, then we must wait with wait, because
216 // in if we don't reschedule, then we create deadlocks if a Windows
217 // Function is called from another thread. If we arn't the main thread,
218 // than we call qcquire directly.
219 DWORD nThreadId
= GetCurrentThreadId();
220 SalData
* pSalData
= GetSalData();
221 if ( pSalData
->mnAppThreadId
== nThreadId
)
223 // Wenn wir den Mutex nicht bekommen, muessen wir solange
224 // warten, bis wir Ihn bekommen
225 BOOL bAcquire
= FALSE
;
228 if ( pInst
->mpSalYieldMutex
->tryToAcquire() )
232 pInst
->mpSalWaitMutex
->acquire();
233 if ( pInst
->mpSalYieldMutex
->tryToAcquire() )
236 pInst
->mpSalWaitMutex
->release();
240 pInst
->mnYieldWaitCount
++;
241 pInst
->mpSalWaitMutex
->release();
243 ImplGetMessage( &aTmpMsg
, pInst
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, SAL_MSG_RELEASEWAITYIELD
);
244 pInst
->mnYieldWaitCount
--;
245 if ( pInst
->mnYieldWaitCount
)
246 ImplPostMessage( pInst
->mhComWnd
, SAL_MSG_RELEASEWAITYIELD
, 0, 0 );
253 pInst
->mpSalYieldMutex
->acquire();
256 // -----------------------------------------------------------------------
258 BOOL
ImplSalYieldMutexTryToAcquire()
260 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
262 return pInst
->mpSalYieldMutex
->tryToAcquire();
267 // -----------------------------------------------------------------------
269 void ImplSalYieldMutexAcquire()
271 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
273 pInst
->mpSalYieldMutex
->acquire();
276 // -----------------------------------------------------------------------
278 void ImplSalYieldMutexRelease()
280 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
284 pInst
->mpSalYieldMutex
->release();
288 // -----------------------------------------------------------------------
290 ULONG
ImplSalReleaseYieldMutex()
292 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
296 SalYieldMutex
* pYieldMutex
= pInst
->mpSalYieldMutex
;
297 ULONG nCount
= pYieldMutex
->GetAcquireCount( GetCurrentThreadId() );
301 pYieldMutex
->release();
308 // -----------------------------------------------------------------------
310 void ImplSalAcquireYieldMutex( ULONG nCount
)
312 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
316 SalYieldMutex
* pYieldMutex
= pInst
->mpSalYieldMutex
;
319 pYieldMutex
->acquire();
324 // -----------------------------------------------------------------------
328 void ImplDbgTestSolarMutex()
330 SalData
* pSalData
= GetSalData();
331 DWORD nCurThreadId
= GetCurrentThreadId();
332 if ( pSalData
->mnAppThreadId
!= nCurThreadId
)
334 if ( pSalData
->mpFirstInstance
)
336 SalYieldMutex
* pYieldMutex
= pSalData
->mpFirstInstance
->mpSalYieldMutex
;
337 if ( pYieldMutex
->mnThreadId
!= nCurThreadId
)
339 DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" );
345 if ( pSalData
->mpFirstInstance
)
347 SalYieldMutex
* pYieldMutex
= pSalData
->mpFirstInstance
->mpSalYieldMutex
;
348 if ( pYieldMutex
->mnThreadId
!= nCurThreadId
)
350 DBG_ERROR( "SolarMutex not locked in the main thread" );
358 // =======================================================================
360 void SalData::initKeyCodeMap()
362 UINT nKey
= 0xffffffff;
363 #define initKey( a, b )\
364 nKey = LOWORD( VkKeyScan( a ) );\
368 initKey( '+', KEY_ADD
);
369 initKey( '-', KEY_SUBTRACT
);
370 initKey( '*', KEY_MULTIPLY
);
371 initKey( '/', KEY_DIVIDE
);
372 initKey( '.', KEY_POINT
);
373 initKey( ',', KEY_COMMA
);
374 initKey( '<', KEY_LESS
);
375 initKey( '>', KEY_GREATER
);
376 initKey( '=', KEY_EQUAL
);
377 initKey( '~', KEY_TILDE
);
378 initKey( '`', KEY_QUOTELEFT
);
379 initKey( '[', KEY_BRACKETLEFT
);
380 initKey( ']', KEY_BRACKETRIGHT
);
383 // =======================================================================
390 mhInst
= 0; // default instance handle
391 mhPrevInst
= 0; // previous instance handle
392 mnCmdShow
= 0; // default frame show style
393 mhDitherPal
= 0; // dither palette
394 mhDitherDIB
= 0; // dither memory handle
395 mpDitherDIB
= 0; // dither memory
396 mpDitherDIBData
= 0; // beginning of DIB data
397 mpDitherDiff
= 0; // Dither mapping table
398 mpDitherLow
= 0; // Dither mapping table
399 mpDitherHigh
= 0; // Dither mapping table
400 mnTimerMS
= 0; // Current Time (in MS) of the Timer
401 mnTimerOrgMS
= 0; // Current Original Time (in MS)
404 mnTimerId
= 0; // windows timer id
405 mbInTimerProc
= FALSE
; // timer event is currently being dispatched
406 mhSalObjMsgHook
= 0; // hook to get interesting msg for SalObject
407 mhWantLeaveMsg
= 0; // window handle, that want a MOUSELEAVE message
408 mpMouseLeaveTimer
= 0; // Timer for MouseLeave Test
409 mpFirstInstance
= 0; // pointer of first instance
410 mpFirstFrame
= 0; // pointer of first frame
411 mpFirstObject
= 0; // pointer of first object window
412 mpFirstVD
= 0; // first VirDev
413 mpFirstPrinter
= 0; // first printing printer
414 mpHDCCache
= 0; // Cache for three DC's
415 mh50Bmp
= 0; // 50% Bitmap
416 mh50Brush
= 0; // 50% Brush
418 for(i
=0; i
<MAX_STOCKPEN
; i
++)
420 maStockPenColorAry
[i
] = 0;
421 mhStockPenAry
[i
] = 0;
423 for(i
=0; i
<MAX_STOCKBRUSH
; i
++)
425 maStockBrushColorAry
[i
] = 0;
426 mhStockBrushAry
[i
] = 0;
428 mnStockPenCount
= 0; // count of static pens
429 mnStockBrushCount
= 0; // count of static brushes
430 mnSalObjWantKeyEvt
= 0; // KeyEvent, welcher vom SalObj-Hook verarbeitet werden soll
431 mnCacheDCInUse
= 0; // count of CacheDC in use
432 mbObjClassInit
= FALSE
; // is SALOBJECTCLASS initialised
433 mbInPalChange
= FALSE
; // is in WM_QUERYNEWPALETTE
434 mnAppThreadId
= 0; // Id from Applikation-Thread
435 mbScrSvrEnabled
= FALSE
; // ScreenSaver enabled
436 mnSageStatus
= 0; // status of Sage-DLL (DISABLE_AGENT == nicht vorhanden)
437 mpSageEnableProc
= 0; // funktion to deactivate the system agent
438 mpFirstIcon
= 0; // icon cache, points to first icon, NULL if none
440 mbThemeChanged
= FALSE
; // true if visual theme was changed: throw away theme handles
459 SalData
* pSalData
= new SalData
;
463 static Gdiplus::GdiplusStartupInput gdiplusStartupInput
;
464 Gdiplus::GdiplusStartup(&pSalData
->gdiplusToken
, &gdiplusStartupInput
, NULL
);
471 SalData
* pSalData
= GetSalData();
476 Gdiplus::GdiplusShutdown(pSalData
->gdiplusToken
);
482 // -----------------------------------------------------------------------
486 // remember data, copied from WinMain
487 SalData
* pData
= GetAppSalData();
488 if ( pData
) // Im AppServer NULL
491 aSI
.cb
= sizeof( aSI
);
492 GetStartupInfo( &aSI
);
493 pData
->mhInst
= GetModuleHandle( NULL
);
494 pData
->mhPrevInst
= NULL
;
495 pData
->mnCmdShow
= aSI
.wShowWindow
;
503 // -----------------------------------------------------------------------
505 SalInstance
* CreateSalInstance()
507 SalData
* pSalData
= GetSalData();
509 // determine the windows version
510 aSalShlData
.mbWNT
= 0;
511 aSalShlData
.mbWXP
= 0;
512 aSalShlData
.mbWPrinter
= 0;
513 WORD nVer
= (WORD
)GetVersion();
514 aSalShlData
.mnVersion
= (((WORD
)LOBYTE(nVer
)) * 100) + HIBYTE(nVer
);
515 if ( aSalShlData
.mnVersion
>= 400 )
516 aSalShlData
.mbW40
= 1;
517 rtl_zeroMemory( &aSalShlData
.maVersionInfo
, sizeof(aSalShlData
.maVersionInfo
) );
518 aSalShlData
.maVersionInfo
.dwOSVersionInfoSize
= sizeof( aSalShlData
.maVersionInfo
);
519 if ( GetVersionEx( &aSalShlData
.maVersionInfo
) )
521 if ( aSalShlData
.maVersionInfo
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
523 aSalShlData
.mbWNT
= 1;
525 if ( aSalShlData
.maVersionInfo
.dwMajorVersion
> 5 ||
526 ( aSalShlData
.maVersionInfo
.dwMajorVersion
== 5 && aSalShlData
.maVersionInfo
.dwMinorVersion
>= 1 ) )
527 aSalShlData
.mbWXP
= 1;
528 if( aSalShlData
.maVersionInfo
.dwMajorVersion
>= 5 )
529 aSalShlData
.mbWPrinter
= 1;
533 pSalData
->mnAppThreadId
= GetCurrentThreadId();
535 // register frame class
536 if ( !pSalData
->mhPrevInst
)
538 if ( aSalShlData
.mbWNT
)
540 WNDCLASSEXW aWndClassEx
;
541 aWndClassEx
.cbSize
= sizeof( aWndClassEx
);
542 aWndClassEx
.style
= CS_OWNDC
;
543 aWndClassEx
.lpfnWndProc
= SalFrameWndProcW
;
544 aWndClassEx
.cbClsExtra
= 0;
545 aWndClassEx
.cbWndExtra
= SAL_FRAME_WNDEXTRA
;
546 aWndClassEx
.hInstance
= pSalData
->mhInst
;
547 aWndClassEx
.hCursor
= 0;
548 aWndClassEx
.hbrBackground
= 0;
549 aWndClassEx
.lpszMenuName
= 0;
550 aWndClassEx
.lpszClassName
= SAL_FRAME_CLASSNAMEW
;
551 ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT
, aWndClassEx
.hIcon
, aWndClassEx
.hIconSm
);
552 if ( !RegisterClassExW( &aWndClassEx
) )
555 aWndClassEx
.hIcon
= 0;
556 aWndClassEx
.hIconSm
= 0;
557 aWndClassEx
.style
|= CS_SAVEBITS
;
558 aWndClassEx
.lpszClassName
= SAL_SUBFRAME_CLASSNAMEW
;
559 if ( !RegisterClassExW( &aWndClassEx
) )
562 // shadow effect for popups on XP
563 if( aSalShlData
.mbWXP
)
564 aWndClassEx
.style
|= CS_DROPSHADOW
;
565 aWndClassEx
.lpszClassName
= SAL_TMPSUBFRAME_CLASSNAMEW
;
566 if ( !RegisterClassExW( &aWndClassEx
) )
569 aWndClassEx
.style
= 0;
570 aWndClassEx
.lpfnWndProc
= SalComWndProcW
;
571 aWndClassEx
.cbWndExtra
= 0;
572 aWndClassEx
.lpszClassName
= SAL_COM_CLASSNAMEW
;
573 if ( !RegisterClassExW( &aWndClassEx
) )
578 WNDCLASSEXA aWndClassEx
;
579 aWndClassEx
.cbSize
= sizeof( aWndClassEx
);
580 aWndClassEx
.style
= CS_OWNDC
;
581 aWndClassEx
.lpfnWndProc
= SalFrameWndProcA
;
582 aWndClassEx
.cbClsExtra
= 0;
583 aWndClassEx
.cbWndExtra
= SAL_FRAME_WNDEXTRA
;
584 aWndClassEx
.hInstance
= pSalData
->mhInst
;
585 aWndClassEx
.hCursor
= 0;
586 aWndClassEx
.hbrBackground
= 0;
587 aWndClassEx
.lpszMenuName
= 0;
588 aWndClassEx
.lpszClassName
= SAL_FRAME_CLASSNAMEA
;
589 ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT
, aWndClassEx
.hIcon
, aWndClassEx
.hIconSm
);
590 if ( !RegisterClassExA( &aWndClassEx
) )
593 aWndClassEx
.hIcon
= 0;
594 aWndClassEx
.hIconSm
= 0;
595 aWndClassEx
.style
|= CS_SAVEBITS
;
596 aWndClassEx
.lpszClassName
= SAL_SUBFRAME_CLASSNAMEA
;
597 if ( !RegisterClassExA( &aWndClassEx
) )
600 aWndClassEx
.style
= 0;
601 aWndClassEx
.lpfnWndProc
= SalComWndProcA
;
602 aWndClassEx
.cbWndExtra
= 0;
603 aWndClassEx
.lpszClassName
= SAL_COM_CLASSNAMEA
;
604 if ( !RegisterClassExA( &aWndClassEx
) )
610 if ( aSalShlData
.mbWNT
)
612 hComWnd
= CreateWindowExW( WS_EX_TOOLWINDOW
, SAL_COM_CLASSNAMEW
,
613 L
"", WS_POPUP
, 0, 0, 0, 0, 0, 0,
614 pSalData
->mhInst
, NULL
);
618 hComWnd
= CreateWindowExA( WS_EX_TOOLWINDOW
, SAL_COM_CLASSNAMEA
,
619 "", WS_POPUP
, 0, 0, 0, 0, 0, 0,
620 pSalData
->mhInst
, NULL
);
625 WinSalInstance
* pInst
= new WinSalInstance
;
627 // init instance (only one instance in this version !!!)
628 pSalData
->mpFirstInstance
= pInst
;
629 pInst
->mhInst
= pSalData
->mhInst
;
630 pInst
->mhComWnd
= hComWnd
;
632 // init static GDI Data
638 // -----------------------------------------------------------------------
640 void DestroySalInstance( SalInstance
* pInst
)
642 SalData
* pSalData
= GetSalData();
644 // (only one instance in this version !!!)
649 if ( pSalData
->mpFirstInstance
== pInst
)
650 pSalData
->mpFirstInstance
= NULL
;
655 // -----------------------------------------------------------------------
657 WinSalInstance::WinSalInstance()
660 mpSalYieldMutex
= new SalYieldMutex( this );
661 mpSalWaitMutex
= new vos::OMutex
;
662 mnYieldWaitCount
= 0;
663 mpSalYieldMutex
->acquire();
666 // -----------------------------------------------------------------------
668 WinSalInstance::~WinSalInstance()
670 mpSalYieldMutex
->release();
671 delete mpSalYieldMutex
;
672 delete mpSalWaitMutex
;
673 DestroyWindow( mhComWnd
);
676 // -----------------------------------------------------------------------
678 vos::IMutex
* WinSalInstance::GetYieldMutex()
680 return mpSalYieldMutex
;
683 // -----------------------------------------------------------------------
685 ULONG
WinSalInstance::ReleaseYieldMutex()
687 return ImplSalReleaseYieldMutex();
690 // -----------------------------------------------------------------------
692 void WinSalInstance::AcquireYieldMutex( ULONG nCount
)
694 ImplSalAcquireYieldMutex( nCount
);
697 // -----------------------------------------------------------------------
699 static void ImplSalDispatchMessage( MSG
* pMsg
)
701 SalData
* pSalData
= GetSalData();
702 if ( pSalData
->mpFirstObject
)
704 if ( ImplSalPreDispatchMsg( pMsg
) )
707 LRESULT lResult
= ImplDispatchMessage( pMsg
);
708 if ( pSalData
->mpFirstObject
)
709 ImplSalPostDispatchMsg( pMsg
, lResult
);
712 // -----------------------------------------------------------------------
714 void ImplSalYield( BOOL bWait
, BOOL bHandleAllCurrentEvents
)
717 bool bWasMsg
= false, bOneEvent
= false;
719 int nMaxEvents
= bHandleAllCurrentEvents
? 100 : 1;
722 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_REMOVE
) )
724 TranslateMessage( &aMsg
);
725 ImplSalDispatchMessage( &aMsg
);
726 bOneEvent
= bWasMsg
= true;
730 } while( --nMaxEvents
&& bOneEvent
);
732 if ( bWait
&& ! bWasMsg
)
734 if ( ImplGetMessage( &aMsg
, 0, 0, 0 ) )
736 TranslateMessage( &aMsg
);
737 ImplSalDispatchMessage( &aMsg
);
742 // -----------------------------------------------------------------------
744 void WinSalInstance::Yield( bool bWait
, bool bHandleAllCurrentEvents
)
746 SalYieldMutex
* pYieldMutex
= mpSalYieldMutex
;
747 SalData
* pSalData
= GetSalData();
748 DWORD nCurThreadId
= GetCurrentThreadId();
749 ULONG nCount
= pYieldMutex
->GetAcquireCount( nCurThreadId
);
753 pYieldMutex
->release();
756 if ( pSalData
->mnAppThreadId
!= nCurThreadId
)
758 // #97739# A SendMessage call blocks until the called thread (here: the main thread)
759 // returns. During a yield however, messages are processed in the main thread that might
760 // result in a new message loop due to opening a dialog. Thus, SendMessage would not
761 // return which will block this thread!
762 // Solution: just give up the time slice and hope that messages are processed
763 // by the main thread anyway (where all windows are created)
764 // If the mainthread is not currently handling messages, then our SendMessage would
765 // also do nothing, so this seems to be reasonable.
767 // #i18883# only sleep if potential deadlock scenario, ie, when a dialog is open
768 if( ImplGetSVData()->maAppData
.mnModalMode
)
771 ImplSendMessage( mhComWnd
, SAL_MSG_THREADYIELD
, (WPARAM
)bWait
, (LPARAM
)bHandleAllCurrentEvents
);
776 pYieldMutex
->acquire();
782 ImplSalYield( bWait
, bHandleAllCurrentEvents
);
787 ImplSalYieldMutexAcquireWithWait();
793 // -----------------------------------------------------------------------
795 LRESULT CALLBACK
SalComWndProc( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
, int& rDef
)
802 case SAL_MSG_PRINTABORTJOB
:
803 ImplSalPrinterAbortJobAsync( (HDC
)wParam
);
806 case SAL_MSG_THREADYIELD
:
807 ImplSalYield( (BOOL
)wParam
, (BOOL
)lParam
);
810 // If we get this message, because another GetMessage() call
811 // has recieved this message, we must post this message to
812 // us again, because in the other case we wait forever.
813 case SAL_MSG_RELEASEWAITYIELD
:
815 WinSalInstance
* pInst
= GetSalData()->mpFirstInstance
;
816 if ( pInst
&& pInst
->mnYieldWaitCount
)
817 ImplPostMessage( hWnd
, SAL_MSG_RELEASEWAITYIELD
, wParam
, lParam
);
821 case SAL_MSG_STARTTIMER
:
822 ImplSalStartTimer( (ULONG
) lParam
, FALSE
);
825 case SAL_MSG_CREATEFRAME
:
826 nRet
= (LRESULT
)ImplSalCreateFrame( GetSalData()->mpFirstInstance
, (HWND
)lParam
, (ULONG
)wParam
);
829 case SAL_MSG_RECREATEHWND
:
830 nRet
= (LRESULT
)ImplSalReCreateHWND( (HWND
)wParam
, (HWND
)lParam
, FALSE
);
833 case SAL_MSG_RECREATECHILDHWND
:
834 nRet
= (LRESULT
)ImplSalReCreateHWND( (HWND
)wParam
, (HWND
)lParam
, TRUE
);
837 case SAL_MSG_DESTROYFRAME
:
838 delete (SalFrame
*)lParam
;
841 case SAL_MSG_DESTROYHWND
:
842 //We only destroy the native window here. We do NOT destroy the SalFrame contained
843 //in the structure (GetWindowPtr()).
844 if (DestroyWindow((HWND
)lParam
) == 0)
846 OSL_ENSURE(0, "DestroyWindow failed!");
847 //Failure: We remove the SalFrame from the window structure. So we avoid that
848 // the window structure may contain an invalid pointer, once the SalFrame is deleted.
849 SetWindowPtr((HWND
)lParam
, 0);
853 case SAL_MSG_CREATEOBJECT
:
854 nRet
= (LRESULT
)ImplSalCreateObject( GetSalData()->mpFirstInstance
, (WinSalFrame
*)lParam
);
857 case SAL_MSG_DESTROYOBJECT
:
858 delete (SalObject
*)lParam
;
862 nRet
= (LRESULT
)GetDCEx( (HWND
)wParam
, 0, DCX_CACHE
);
865 case SAL_MSG_RELEASEDC
:
866 ReleaseDC( (HWND
)wParam
, (HDC
)lParam
);
869 case SAL_MSG_POSTTIMER
:
870 SalTimerProc( 0, 0, SALTIMERPROC_RECURSIVE
, lParam
);
877 LRESULT CALLBACK
SalComWndProcA( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
884 if (__builtin_setjmp(jmpbuf
) == 0)
886 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
891 nRet
= SalComWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
896 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
902 if ( !ImplHandleGlobalMsg( hWnd
, nMsg
, wParam
, lParam
, nRet
) )
903 nRet
= DefWindowProcA( hWnd
, nMsg
, wParam
, lParam
);
908 LRESULT CALLBACK
SalComWndProcW( HWND hWnd
, UINT nMsg
, WPARAM wParam
, LPARAM lParam
)
915 if (__builtin_setjmp(jmpbuf
) == 0)
917 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
922 nRet
= SalComWndProc( hWnd
, nMsg
, wParam
, lParam
, bDef
);
927 __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
933 if ( !ImplHandleGlobalMsg( hWnd
, nMsg
, wParam
, lParam
, nRet
) )
934 nRet
= DefWindowProcW( hWnd
, nMsg
, wParam
, lParam
);
939 // -----------------------------------------------------------------------
941 bool WinSalInstance::AnyInput( USHORT nType
)
945 if ( (nType
& (INPUT_ANY
)) == (INPUT_ANY
) )
947 // revert bugfix for #108919# which never reported timeouts when called from the timer handler
948 // which made the application completely unresponsive during background formatting
949 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_NOREMOVE
| PM_NOYIELD
) )
954 if ( nType
& INPUT_MOUSE
)
956 // Test for mouse input
957 if ( ImplPeekMessage( &aMsg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
,
958 PM_NOREMOVE
| PM_NOYIELD
) )
962 if ( nType
& INPUT_KEYBOARD
)
964 // Test for key input
965 if ( ImplPeekMessage( &aMsg
, 0, WM_KEYDOWN
, WM_KEYDOWN
,
966 PM_NOREMOVE
| PM_NOYIELD
) )
968 if ( (aMsg
.wParam
== VK_SHIFT
) ||
969 (aMsg
.wParam
== VK_CONTROL
) ||
970 (aMsg
.wParam
== VK_MENU
) )
977 if ( nType
& INPUT_PAINT
)
979 // Test for paint input
980 if ( ImplPeekMessage( &aMsg
, 0, WM_PAINT
, WM_PAINT
,
981 PM_NOREMOVE
| PM_NOYIELD
) )
984 if ( ImplPeekMessage( &aMsg
, 0, WM_SIZE
, WM_SIZE
,
985 PM_NOREMOVE
| PM_NOYIELD
) )
988 if ( ImplPeekMessage( &aMsg
, 0, SAL_MSG_POSTCALLSIZE
, SAL_MSG_POSTCALLSIZE
,
989 PM_NOREMOVE
| PM_NOYIELD
) )
992 if ( ImplPeekMessage( &aMsg
, 0, WM_MOVE
, WM_MOVE
,
993 PM_NOREMOVE
| PM_NOYIELD
) )
996 if ( ImplPeekMessage( &aMsg
, 0, SAL_MSG_POSTMOVE
, SAL_MSG_POSTMOVE
,
997 PM_NOREMOVE
| PM_NOYIELD
) )
1001 if ( nType
& INPUT_TIMER
)
1003 // Test for timer input
1004 if ( ImplPeekMessage( &aMsg
, 0, WM_TIMER
, WM_TIMER
,
1005 PM_NOREMOVE
| PM_NOYIELD
) )
1010 if ( nType
& INPUT_OTHER
)
1012 // Test for any input
1013 if ( ImplPeekMessage( &aMsg
, 0, 0, 0, PM_NOREMOVE
| PM_NOYIELD
) )
1021 // -----------------------------------------------------------------------
1023 void SalTimer::Start( ULONG nMS
)
1025 // Um auf Main-Thread umzuschalten
1026 SalData
* pSalData
= GetSalData();
1027 if ( pSalData
->mpFirstInstance
)
1029 if ( pSalData
->mnAppThreadId
!= GetCurrentThreadId() )
1030 ImplPostMessage( pSalData
->mpFirstInstance
->mhComWnd
, SAL_MSG_STARTTIMER
, 0, (LPARAM
)nMS
);
1032 ImplSendMessage( pSalData
->mpFirstInstance
->mhComWnd
, SAL_MSG_STARTTIMER
, 0, (LPARAM
)nMS
);
1035 ImplSalStartTimer( nMS
, FALSE
);
1038 // -----------------------------------------------------------------------
1040 SalFrame
* WinSalInstance::CreateChildFrame( SystemParentData
* pSystemParentData
, ULONG nSalFrameStyle
)
1042 // Um auf Main-Thread umzuschalten
1043 return (SalFrame
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEFRAME
, nSalFrameStyle
, (LPARAM
)pSystemParentData
->hWnd
);
1046 // -----------------------------------------------------------------------
1048 SalFrame
* WinSalInstance::CreateFrame( SalFrame
* pParent
, ULONG nSalFrameStyle
)
1050 // Um auf Main-Thread umzuschalten
1053 hWndParent
= static_cast<WinSalFrame
*>(pParent
)->mhWnd
;
1056 return (SalFrame
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEFRAME
, nSalFrameStyle
, (LPARAM
)hWndParent
);
1059 // -----------------------------------------------------------------------
1061 void WinSalInstance::DestroyFrame( SalFrame
* pFrame
)
1063 ImplSendMessage( mhComWnd
, SAL_MSG_DESTROYFRAME
, 0, (LPARAM
)pFrame
);
1066 // -----------------------------------------------------------------------
1068 SalObject
* WinSalInstance::CreateObject( SalFrame
* pParent
,
1069 SystemWindowData
* /*pWindowData*/, // SystemWindowData meaningless on Windows
1072 // Um auf Main-Thread umzuschalten
1073 return (SalObject
*)ImplSendMessage( mhComWnd
, SAL_MSG_CREATEOBJECT
, 0, (LPARAM
)static_cast<WinSalFrame
*>(pParent
) );
1076 // -----------------------------------------------------------------------
1078 void WinSalInstance::DestroyObject( SalObject
* pObject
)
1080 ImplSendMessage( mhComWnd
, SAL_MSG_DESTROYOBJECT
, 0, (LPARAM
)pObject
);
1083 // -----------------------------------------------------------------------
1085 void* WinSalInstance::GetConnectionIdentifier( ConnectionIdentifierType
& rReturnedType
, int& rReturnedBytes
)
1088 rReturnedType
= AsciiCString
;
1089 return const_cast<char *>("");
1092 // -----------------------------------------------------------------------
1094 SalTimer
* WinSalInstance::CreateSalTimer()
1096 return new WinSalTimer();
1099 // -----------------------------------------------------------------------
1101 SalBitmap
* WinSalInstance::CreateSalBitmap()
1103 return new WinSalBitmap();
1106 class WinImeStatus
: public SalI18NImeStatus
1110 virtual ~WinImeStatus() {}
1112 // asks whether there is a status window available
1113 // to toggle into menubar
1114 virtual bool canToggle() { return false; }
1115 virtual void toggle() {}
1118 SalI18NImeStatus
* WinSalInstance::CreateI18NImeStatus()
1120 return new WinImeStatus();
1123 // -----------------------------------------------------------------------
1125 const ::rtl::OUString
& SalGetDesktopEnvironment()
1127 static ::rtl::OUString
aDesktopEnvironment( RTL_CONSTASCII_USTRINGPARAM( "Windows" ) );
1128 return aDesktopEnvironment
;
1131 SalSession
* WinSalInstance::CreateSalSession()
1137 // -----------------------------------------------------------------------
1138 int WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(int, LPEXCEPTION_POINTERS pExceptionInfo
)
1140 // Decide if an exception is a c++ (mostly UNO) exception or a process violation.
1141 // Depending on this information we pass process violations directly to our signal handler ...
1142 // and c++ (UNO) exceptions are sended to the following code on the current stack.
1143 // Problem behind: user32.dll sometime consumes exceptions/process violations .-)
1144 // see also #112221#
1146 static DWORD EXCEPTION_MSC_CPP_EXCEPTION
= 0xE06D7363;
1148 if (pExceptionInfo
->ExceptionRecord
->ExceptionCode
== EXCEPTION_MSC_CPP_EXCEPTION
)
1149 return EXCEPTION_CONTINUE_SEARCH
;
1151 return UnhandledExceptionFilter( pExceptionInfo
);