]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/timer.cpp
Patch by David Brinegar to fix menubar updating after modal dialog shown
[wxWidgets.git] / src / mac / carbon / timer.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: timer.cpp
3// Purpose: wxTimer implementation
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3d1a4878 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
e9576ca5
SC
13#pragma implementation "timer.h"
14#endif
15
3d1a4878
SC
16#include "wx/wxprec.h"
17
e9576ca5
SC
18#include "wx/timer.h"
19
2f1ae414 20#if !USE_SHARED_LIBRARY
313feadc 21IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxEvtHandler)
2f1ae414
SC
22#endif
23
76a5e5d2
SC
24#ifdef __WXMAC__
25#include "wx/mac/private.h"
26#endif
66a09d47
SC
27#ifndef __DARWIN__
28#include <Timer.h>
29#endif
76a5e5d2 30
e5f0419b
SC
31#include "wx/dynarray.h"
32
514982b2
SC
33#define wxMAC_USE_CARBON_TIMER 1
34
35#if wxMAC_USE_CARBON_TIMER
36
37typedef struct MacTimerInfo
38{
39 wxTimer* m_timer ;
40 EventLoopTimerUPP m_proc ;
41 EventLoopTimerRef m_timerRef ;
42} ;
43
44static pascal void wxProcessTimer( EventLoopTimerRef theTimer , void *data ) ;
45static pascal void wxProcessTimer( EventLoopTimerRef theTimer , void *data )
46{
47 if ( !data )
48 return ;
49
50 wxTimer* timer = (wxTimer*) data ;
51
52 if ( timer->IsOneShot() )
53 timer->Stop() ;
54
55 timer->Notify();
56}
57
58void wxTimer::Init()
59{
60 m_info = new MacTimerInfo() ;
61 m_info->m_timer = this ;
62 m_info->m_proc = NULL ;
63 m_info->m_timerRef = kInvalidID ;
64}
65
66bool wxTimer::IsRunning() const
67{
68 return ( m_info->m_timerRef != kInvalidID ) ;
69}
70
71wxTimer::~wxTimer()
72{
73 Stop();
74 if (m_info != NULL) {
75 delete m_info ;
76 m_info = NULL ;
77 }
78}
79
80bool wxTimer::Start(int milliseconds,bool mode)
81{
82 (void)wxTimerBase::Start(milliseconds, mode);
83
84 wxCHECK_MSG( m_milli > 0, FALSE, wxT("invalid value for timer timeout") );
85 wxCHECK_MSG( m_info->m_timerRef == NULL , FALSE, wxT("attempting to restart a timer") );
86
87 m_info->m_timer = this ;
88 m_info->m_proc = NewEventLoopTimerUPP( &wxProcessTimer);
89 verify_noerr( InstallEventLoopTimer (
90 GetMainEventLoop() ,
91 m_milli*kEventDurationMillisecond,
92 IsOneShot() ? 0 : m_milli*kEventDurationMillisecond ,
93 m_info->m_proc,
94 this,
95 &m_info->m_timerRef) ) ;
96 return TRUE;
97}
98
99void wxTimer::Stop()
100{
101 if (m_info->m_timerRef)
102 RemoveEventLoopTimer( m_info->m_timerRef ) ;
103 if (m_info->m_proc)
104 DisposeEventLoopTimerUPP(m_info->m_proc) ;
105 m_info->m_proc = NULL ;
106 m_info->m_timerRef = kInvalidID ;
107}
108
109#else
110
76a5e5d2
SC
111typedef struct MacTimerInfo
112{
113 TMTask m_task;
114 wxMacNotifierTableRef m_table ;
115 wxTimer* m_timer ;
116} ;
117
2f1ae414
SC
118static void wxProcessTimer( unsigned long event , void *data ) ;
119
d015713e 120static pascal void MacTimerProc( TMTask * t )
2f1ae414 121{
e40298d5
JS
122 MacTimerInfo * tm = (MacTimerInfo*) t ;
123 wxMacAddEvent( tm->m_table , wxProcessTimer, 0 , (void*) tm->m_timer , TRUE ) ;
2f1ae414
SC
124}
125
604b66c1
SC
126// we need this array to track timers that are being deleted within the Notify procedure
127// adding the timer before the Notify call and checking after whether it still is in there
128// as the destructor would have removed it from the array
129
e5f0419b
SC
130wxArrayPtrVoid gTimersInProcess ;
131
d015713e 132static void wxProcessTimer( unsigned long event , void *data )
2f1ae414 133{
e40298d5
JS
134 if ( !data )
135 return ;
136
137 wxTimer* timer = (wxTimer*) data ;
138
139 if ( timer->IsOneShot() )
140 timer->Stop() ;
141
142 gTimersInProcess.Add( timer ) ;
143
2f1ae414
SC
144 timer->Notify();
145
e5f0419b
SC
146 int index = gTimersInProcess.Index( timer ) ;
147
148 if ( index != wxNOT_FOUND )
2f1ae414 149 {
e5f0419b
SC
150 gTimersInProcess.RemoveAt( index ) ;
151
152 if ( !timer->IsOneShot() && timer->m_info->m_task.tmAddr )
153 {
e40298d5 154 PrimeTime( (QElemPtr) &timer->m_info->m_task , timer->GetInterval() ) ;
e5f0419b
SC
155 }
156
2f1ae414
SC
157 }
158}
e9576ca5 159
d015713e 160void wxTimer::Init()
e9576ca5 161{
76a5e5d2 162 m_info = new MacTimerInfo() ;
e40298d5
JS
163 m_info->m_task.tmAddr = NULL ;
164 m_info->m_task.tmWakeUp = 0 ;
165 m_info->m_task.tmReserved = 0 ;
166 m_info->m_task.qType = 0 ;
167 m_info->m_table = wxMacGetNotifierTable() ;
168 m_info->m_timer = this ;
2f1ae414
SC
169}
170
171bool wxTimer::IsRunning() const
172{
604b66c1
SC
173 // as the qType may already indicate it is elapsed, but it
174 // was not handled internally yet
175 return ( m_info->m_task.tmAddr != NULL ) ;
e9576ca5
SC
176}
177
178wxTimer::~wxTimer()
179{
180 Stop();
f5bb2251
GD
181 if (m_info != NULL) {
182 delete m_info ;
183 m_info = NULL ;
184 }
e5f0419b
SC
185 int index = gTimersInProcess.Index( this ) ;
186 if ( index != wxNOT_FOUND )
187 gTimersInProcess.RemoveAt( index ) ;
e9576ca5
SC
188}
189
190bool wxTimer::Start(int milliseconds,bool mode)
191{
2f1ae414 192 (void)wxTimerBase::Start(milliseconds, mode);
e9576ca5 193
604b66c1 194 wxCHECK_MSG( m_milli > 0, FALSE, wxT("invalid value for timer timeout") );
76a5e5d2 195 wxCHECK_MSG( m_info->m_task.tmAddr == NULL , FALSE, wxT("attempting to restart a timer") );
e9576ca5 196
76a5e5d2 197 m_info->m_task.tmAddr = NewTimerUPP( MacTimerProc ) ;
76a5e5d2
SC
198 m_info->m_task.tmWakeUp = 0 ;
199 m_info->m_task.tmReserved = 0 ;
e40298d5
JS
200 m_info->m_task.qType = 0 ;
201 m_info->m_timer = this ;
76a5e5d2
SC
202 InsXTime((QElemPtr) &m_info->m_task ) ;
203 PrimeTime( (QElemPtr) &m_info->m_task , m_milli ) ;
c5990c00 204 return TRUE;
e9576ca5
SC
205}
206
207void wxTimer::Stop()
208{
76a5e5d2 209 if ( m_info->m_task.tmAddr )
2f1ae414 210 {
e40298d5
JS
211 RmvTime( (QElemPtr) &m_info->m_task ) ;
212 DisposeTimerUPP(m_info->m_task.tmAddr) ;
213 m_info->m_task.tmAddr = NULL ;
2f1ae414
SC
214 }
215 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;
e9576ca5
SC
216}
217
514982b2 218#endif
e9576ca5 219
2f1ae414 220