xref: /aoo41x/main/vcl/win/source/app/saltimer.cxx (revision 79aad27f)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir #include <tools/svwin.h>
27cdf0e10cSrcweir #ifdef __MINGW32__
28cdf0e10cSrcweir #include <excpt.h>
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #include <win/saldata.hxx>
31cdf0e10cSrcweir #include <win/saltimer.h>
32cdf0e10cSrcweir #include <win/salinst.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir // =======================================================================
35cdf0e10cSrcweir 
36cdf0e10cSrcweir // Maximale Periode
37cdf0e10cSrcweir #define MAX_SYSPERIOD	  65533
38cdf0e10cSrcweir 
39cdf0e10cSrcweir // =======================================================================
40cdf0e10cSrcweir 
ImplSalStartTimer(sal_uLong nMS,sal_Bool bMutex)41cdf0e10cSrcweir void ImplSalStartTimer( sal_uLong nMS, sal_Bool bMutex )
42cdf0e10cSrcweir {
43cdf0e10cSrcweir 	SalData* pSalData = GetSalData();
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 	// Remenber the time of the timer
46cdf0e10cSrcweir 	pSalData->mnTimerMS = nMS;
47cdf0e10cSrcweir 	if ( !bMutex )
48cdf0e10cSrcweir 		pSalData->mnTimerOrgMS = nMS;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 	// Periode darf nicht zu gross sein, da Windows mit sal_uInt16 arbeitet
51cdf0e10cSrcweir 	if ( nMS > MAX_SYSPERIOD )
52cdf0e10cSrcweir 		nMS = MAX_SYSPERIOD;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 	// Gibt es einen Timer, dann zerstoren
55cdf0e10cSrcweir 	if ( pSalData->mnTimerId )
56cdf0e10cSrcweir 		KillTimer( 0, pSalData->mnTimerId );
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 	// Make a new timer with new period
59cdf0e10cSrcweir 	pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
60cdf0e10cSrcweir 	pSalData->mnNextTimerTime = pSalData->mnLastEventTime + nMS;
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // -----------------------------------------------------------------------
64cdf0e10cSrcweir 
~WinSalTimer()65cdf0e10cSrcweir WinSalTimer::~WinSalTimer()
66cdf0e10cSrcweir {
67cdf0e10cSrcweir }
68cdf0e10cSrcweir 
Start(sal_uLong nMS)69cdf0e10cSrcweir void WinSalTimer::Start( sal_uLong nMS )
70cdf0e10cSrcweir {
71cdf0e10cSrcweir     // switch to main thread
72cdf0e10cSrcweir     SalData* pSalData = GetSalData();
73cdf0e10cSrcweir     if ( pSalData->mpFirstInstance )
74cdf0e10cSrcweir     {
75cdf0e10cSrcweir         if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
76cdf0e10cSrcweir             ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
77cdf0e10cSrcweir         else
78cdf0e10cSrcweir             ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
79cdf0e10cSrcweir     }
80cdf0e10cSrcweir     else
81cdf0e10cSrcweir         ImplSalStartTimer( nMS, FALSE );
82cdf0e10cSrcweir }
83cdf0e10cSrcweir 
Stop()84cdf0e10cSrcweir void WinSalTimer::Stop()
85cdf0e10cSrcweir {
86cdf0e10cSrcweir 	SalData* pSalData = GetSalData();
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	// If we have a timer, than
89cdf0e10cSrcweir 	if ( pSalData->mnTimerId )
90cdf0e10cSrcweir 	{
91cdf0e10cSrcweir 		KillTimer( 0, pSalData->mnTimerId );
92cdf0e10cSrcweir 		pSalData->mnTimerId = 0;
93cdf0e10cSrcweir 		pSalData->mnNextTimerTime = 0;
94cdf0e10cSrcweir 	}
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir // -----------------------------------------------------------------------
98cdf0e10cSrcweir 
SalTimerProc(HWND,UINT,UINT_PTR nId,DWORD)99cdf0e10cSrcweir void CALLBACK SalTimerProc( HWND, UINT, UINT_PTR nId, DWORD )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir #ifdef __MINGW32__
102cdf0e10cSrcweir     jmp_buf jmpbuf;
103cdf0e10cSrcweir     __SEHandler han;
104cdf0e10cSrcweir     if (__builtin_setjmp(jmpbuf) == 0)
105cdf0e10cSrcweir     {
106cdf0e10cSrcweir         han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
107cdf0e10cSrcweir #else
108cdf0e10cSrcweir     __try
109cdf0e10cSrcweir     {
110cdf0e10cSrcweir #endif
111cdf0e10cSrcweir 	    SalData* pSalData = GetSalData();
112cdf0e10cSrcweir         ImplSVData* pSVData = ImplGetSVData();
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	    // Test for MouseLeave
115cdf0e10cSrcweir 	    SalTestMouseLeave();
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         bool bRecursive = pSalData->mbInTimerProc && (nId != SALTIMERPROC_RECURSIVE);
118cdf0e10cSrcweir 	    if ( pSVData->mpSalTimer && ! bRecursive )
119cdf0e10cSrcweir 	    {
120cdf0e10cSrcweir 		    // Try to aquire the mutex. If we don't get the mutex then we
121cdf0e10cSrcweir 		    // try this a short time later again.
122cdf0e10cSrcweir 		    if ( ImplSalYieldMutexTryToAcquire() )
123cdf0e10cSrcweir 		    {
124cdf0e10cSrcweir                 bRecursive = pSalData->mbInTimerProc && (nId != SALTIMERPROC_RECURSIVE);
125cdf0e10cSrcweir 				if ( pSVData->mpSalTimer && ! bRecursive )
126cdf0e10cSrcweir 				{
127cdf0e10cSrcweir 					pSalData->mbInTimerProc = TRUE;
128cdf0e10cSrcweir 					pSVData->mpSalTimer->CallCallback();
129cdf0e10cSrcweir 					pSalData->mbInTimerProc = FALSE;
130cdf0e10cSrcweir 					ImplSalYieldMutexRelease();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 					// Run the timer in the correct time, if we start this
133cdf0e10cSrcweir 					// with a small timeout, because we don't get the mutex
134cdf0e10cSrcweir 					if ( pSalData->mnTimerId &&
135cdf0e10cSrcweir 						(pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
136cdf0e10cSrcweir 						ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
137cdf0e10cSrcweir 				}
138cdf0e10cSrcweir 		    }
139cdf0e10cSrcweir 		    else
140cdf0e10cSrcweir 			    ImplSalStartTimer( 10, TRUE );
141cdf0e10cSrcweir 	    }
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir #ifdef __MINGW32__
144cdf0e10cSrcweir     han.Reset();
145cdf0e10cSrcweir #else
146cdf0e10cSrcweir     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
147cdf0e10cSrcweir     {
148cdf0e10cSrcweir     }
149cdf0e10cSrcweir #endif
150cdf0e10cSrcweir }
151