xref: /trunk/main/vcl/win/source/app/saltimer.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 #include <tools/svwin.h>
31 #ifdef __MINGW32__
32 #include <excpt.h>
33 #endif
34 #include <win/saldata.hxx>
35 #include <win/saltimer.h>
36 #include <win/salinst.h>
37 
38 // =======================================================================
39 
40 // Maximale Periode
41 #define MAX_SYSPERIOD	  65533
42 
43 // =======================================================================
44 
45 void ImplSalStartTimer( sal_uLong nMS, sal_Bool bMutex )
46 {
47 	SalData* pSalData = GetSalData();
48 
49 	// Remenber the time of the timer
50 	pSalData->mnTimerMS = nMS;
51 	if ( !bMutex )
52 		pSalData->mnTimerOrgMS = nMS;
53 
54 	// Periode darf nicht zu gross sein, da Windows mit sal_uInt16 arbeitet
55 	if ( nMS > MAX_SYSPERIOD )
56 		nMS = MAX_SYSPERIOD;
57 
58 	// Gibt es einen Timer, dann zerstoren
59 	if ( pSalData->mnTimerId )
60 		KillTimer( 0, pSalData->mnTimerId );
61 
62 	// Make a new timer with new period
63 	pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc );
64 	pSalData->mnNextTimerTime = pSalData->mnLastEventTime + nMS;
65 }
66 
67 // -----------------------------------------------------------------------
68 
69 WinSalTimer::~WinSalTimer()
70 {
71 }
72 
73 void WinSalTimer::Start( sal_uLong nMS )
74 {
75     // switch to main thread
76     SalData* pSalData = GetSalData();
77     if ( pSalData->mpFirstInstance )
78     {
79         if ( pSalData->mnAppThreadId != GetCurrentThreadId() )
80             ImplPostMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
81         else
82             ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS );
83     }
84     else
85         ImplSalStartTimer( nMS, FALSE );
86 }
87 
88 void WinSalTimer::Stop()
89 {
90 	SalData* pSalData = GetSalData();
91 
92 	// If we have a timer, than
93 	if ( pSalData->mnTimerId )
94 	{
95 		KillTimer( 0, pSalData->mnTimerId );
96 		pSalData->mnTimerId = 0;
97 		pSalData->mnNextTimerTime = 0;
98 	}
99 }
100 
101 // -----------------------------------------------------------------------
102 
103 void CALLBACK SalTimerProc( HWND, UINT, UINT_PTR nId, DWORD )
104 {
105 #ifdef __MINGW32__
106     jmp_buf jmpbuf;
107     __SEHandler han;
108     if (__builtin_setjmp(jmpbuf) == 0)
109     {
110         han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER);
111 #else
112     __try
113     {
114 #endif
115 	    SalData* pSalData = GetSalData();
116         ImplSVData* pSVData = ImplGetSVData();
117 
118 	    // Test for MouseLeave
119 	    SalTestMouseLeave();
120 
121         bool bRecursive = pSalData->mbInTimerProc && (nId != SALTIMERPROC_RECURSIVE);
122 	    if ( pSVData->mpSalTimer && ! bRecursive )
123 	    {
124 		    // Try to aquire the mutex. If we don't get the mutex then we
125 		    // try this a short time later again.
126 		    if ( ImplSalYieldMutexTryToAcquire() )
127 		    {
128                 bRecursive = pSalData->mbInTimerProc && (nId != SALTIMERPROC_RECURSIVE);
129 				if ( pSVData->mpSalTimer && ! bRecursive )
130 				{
131 					pSalData->mbInTimerProc = TRUE;
132 					pSVData->mpSalTimer->CallCallback();
133 					pSalData->mbInTimerProc = FALSE;
134 					ImplSalYieldMutexRelease();
135 
136 					// Run the timer in the correct time, if we start this
137 					// with a small timeout, because we don't get the mutex
138 					if ( pSalData->mnTimerId &&
139 						(pSalData->mnTimerMS != pSalData->mnTimerOrgMS) )
140 						ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE );
141 				}
142 		    }
143 		    else
144 			    ImplSalStartTimer( 10, TRUE );
145 	    }
146     }
147 #ifdef __MINGW32__
148     han.Reset();
149 #else
150     __except(WinSalInstance::WorkaroundExceptionHandlingInUSER32Lib(GetExceptionCode(), GetExceptionInformation()))
151     {
152     }
153 #endif
154 }
155