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