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