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