19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file
59f62ea84SAndrew Rist * distributed with this work for additional information
69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file
79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at
109f62ea84SAndrew Rist *
119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist *
139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist * software distributed under the License is distributed on an
159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the
179f62ea84SAndrew Rist * specific language governing permissions and limitations
189f62ea84SAndrew Rist * under the License.
199f62ea84SAndrew Rist *
209f62ea84SAndrew Rist *************************************************************/
219f62ea84SAndrew Rist
229f62ea84SAndrew 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
SalAbort(const XubString & rErrorText)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
SalYieldMutex(WinSalInstance * pInstData)126cdf0e10cSrcweir SalYieldMutex::SalYieldMutex( WinSalInstance* pInstData )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir mpInstData = pInstData;
129cdf0e10cSrcweir mnCount = 0;
130cdf0e10cSrcweir mnThreadId = 0;
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
133cdf0e10cSrcweir // -----------------------------------------------------------------------
134cdf0e10cSrcweir
acquire()135cdf0e10cSrcweir void SAL_CALL SalYieldMutex::acquire()
136cdf0e10cSrcweir {
137cdf0e10cSrcweir OMutex::acquire();
138cdf0e10cSrcweir mnCount++;
139cdf0e10cSrcweir mnThreadId = GetCurrentThreadId();
140cdf0e10cSrcweir }
141cdf0e10cSrcweir
142cdf0e10cSrcweir // -----------------------------------------------------------------------
143cdf0e10cSrcweir
release()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
tryToAcquire()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
GetAcquireCount(sal_uLong nThreadId)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
ImplSalYieldMutexAcquireWithWait()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
ImplSalYieldMutexTryToAcquire()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
ImplSalYieldMutexAcquire()270cdf0e10cSrcweir void ImplSalYieldMutexAcquire()
271cdf0e10cSrcweir {
272cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance;
273cdf0e10cSrcweir if ( pInst )
274cdf0e10cSrcweir pInst->mpSalYieldMutex->acquire();
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir // -----------------------------------------------------------------------
278cdf0e10cSrcweir
ImplSalYieldMutexRelease()279cdf0e10cSrcweir void ImplSalYieldMutexRelease()
280cdf0e10cSrcweir {
281cdf0e10cSrcweir WinSalInstance* pInst = GetSalData()->mpFirstInstance;
282cdf0e10cSrcweir if ( pInst )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir GdiFlush();
285cdf0e10cSrcweir pInst->mpSalYieldMutex->release();
286cdf0e10cSrcweir }
287cdf0e10cSrcweir }
288cdf0e10cSrcweir
289cdf0e10cSrcweir // -----------------------------------------------------------------------
290cdf0e10cSrcweir
ImplSalReleaseYieldMutex()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
ImplSalAcquireYieldMutex(sal_uLong nCount)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
CheckYieldMutex()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
initKeyCodeMap()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
SalData()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
~SalData()451cdf0e10cSrcweir SalData::~SalData()
452cdf0e10cSrcweir {
453cdf0e10cSrcweir deInitNWF();
454cdf0e10cSrcweir SetSalData( NULL );
455cdf0e10cSrcweir }
456cdf0e10cSrcweir
InitSalData()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
DeInitSalData()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
InitSalMain()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
DeInitSalMain()499cdf0e10cSrcweir void DeInitSalMain()
500cdf0e10cSrcweir {
501cdf0e10cSrcweir }
502cdf0e10cSrcweir
503cdf0e10cSrcweir // -----------------------------------------------------------------------
504cdf0e10cSrcweir
CreateSalInstance()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
DestroySalInstance(SalInstance * pInst)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
WinSalInstance()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
~WinSalInstance()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
GetYieldMutex()634cdf0e10cSrcweir vos::IMutex* WinSalInstance::GetYieldMutex()
635cdf0e10cSrcweir {
636cdf0e10cSrcweir return mpSalYieldMutex;
637cdf0e10cSrcweir }
638cdf0e10cSrcweir
639cdf0e10cSrcweir // -----------------------------------------------------------------------
640cdf0e10cSrcweir
ReleaseYieldMutex()641cdf0e10cSrcweir sal_uLong WinSalInstance::ReleaseYieldMutex()
642cdf0e10cSrcweir {
643cdf0e10cSrcweir return ImplSalReleaseYieldMutex();
644cdf0e10cSrcweir }
645cdf0e10cSrcweir
646cdf0e10cSrcweir // -----------------------------------------------------------------------
647cdf0e10cSrcweir
AcquireYieldMutex(sal_uLong nCount)648cdf0e10cSrcweir void WinSalInstance::AcquireYieldMutex( sal_uLong nCount )
649cdf0e10cSrcweir {
650cdf0e10cSrcweir ImplSalAcquireYieldMutex( nCount );
651cdf0e10cSrcweir }
652cdf0e10cSrcweir
653cdf0e10cSrcweir // -----------------------------------------------------------------------
654cdf0e10cSrcweir
ImplSalDispatchMessage(MSG * pMsg)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
ImplSalYield(sal_Bool bWait,sal_Bool bHandleAllCurrentEvents)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
Yield(bool bWait,bool bHandleAllCurrentEvents)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
SalComWndProc(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam,int & rDef)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
774*86e1cf34SPedro Giffuni // has received 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
SalComWndProcA(HWND hWnd,UINT nMsg,WPARAM wParam,LPARAM lParam)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