1 /////////////////////////////////////////////////////////////////////////////
2 // Name: sec/mac/carbon/timer.cpp
3 // Purpose: wxTimer implementation
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
17 #include "wx/dynarray.h"
20 #include "wx/mac/private/timer.h"
23 #include "wx/mac/private.h"
30 #define wxMAC_USE_CARBON_TIMER 1
32 #if wxMAC_USE_CARBON_TIMER
36 wxCarbonTimerImpl
* m_timer
;
37 EventLoopTimerUPP m_proc
;
38 EventLoopTimerRef m_timerRef
;
41 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
)
46 wxCarbonTimerImpl
* timer
= (wxCarbonTimerImpl
*)data
;
48 if ( timer
->IsOneShot() )
54 wxCarbonTimerImpl::wxCarbonTimerImpl(wxTimer
*timer
)
57 m_info
= new MacTimerInfo();
58 m_info
->m_timer
= this;
59 m_info
->m_proc
= NULL
;
60 m_info
->m_timerRef
= kInvalidID
;
63 bool wxCarbonTimerImpl::IsRunning() const
65 return ( m_info
->m_timerRef
!= kInvalidID
);
68 wxCarbonTimerImpl::~wxCarbonTimerImpl()
73 bool wxCarbonTimerImpl::Start( int milliseconds
, bool mode
)
75 (void)wxTimerImpl::Start(milliseconds
, mode
);
77 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeout") );
78 wxCHECK_MSG( m_info
->m_timerRef
== NULL
, false, wxT("attempting to restart a timer") );
80 m_info
->m_timer
= this;
81 m_info
->m_proc
= NewEventLoopTimerUPP( &wxProcessTimer
);
83 OSStatus err
= InstallEventLoopTimer(
85 m_milli
*kEventDurationMillisecond
,
86 IsOneShot() ? 0 : m_milli
* kEventDurationMillisecond
,
89 &m_info
->m_timerRef
);
95 void wxCarbonTimerImpl::Stop()
97 if (m_info
->m_timerRef
)
98 RemoveEventLoopTimer( m_info
->m_timerRef
);
100 DisposeEventLoopTimerUPP( m_info
->m_proc
);
102 m_info
->m_proc
= NULL
;
103 m_info
->m_timerRef
= kInvalidID
;
106 #else // !wxMAC_USE_CARBON_TIMER
108 typedef struct MacTimerInfo
111 wxMacNotifierTableRef m_table
;
112 wxCarbonTimerImpl
* m_timer
;
115 static void wxProcessTimer( unsigned long event
, void *data
);
117 static pascal void MacTimerProc( TMTask
* t
)
119 MacTimerInfo
* tm
= (MacTimerInfo
*) t
;
120 wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0, (void*) tm
->m_timer
, true );
123 // we need this array to track timers that are being deleted within the Notify procedure
124 // adding the timer before the Notify call and checking after whether it still is in there
125 // as the destructor would have removed it from the array
127 wxArrayPtrVoid gTimersInProcess
;
129 static void wxProcessTimer( unsigned long event
, void *data
)
134 wxCarbonTimerImpl
* timer
= (wxCarbonTimerImpl
*) data
;
135 if ( timer
->m_oneShot
)
138 gTimersInProcess
.Add( timer
);
141 int index
= gTimersInProcess
.Index( timer
);
142 if ( index
!= wxNOT_FOUND
)
144 gTimersInProcess
.RemoveAt( index
);
146 if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr
)
147 PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() );
151 void wxCarbonTimerImpl::Init()
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;
162 bool wxCarbonTimerImpl::IsRunning() const
164 // as the qType may already indicate it is elapsed, but it
165 // was not handled internally yet
166 return ( m_info
->m_task
.tmAddr
!= NULL
);
169 wxCarbonTimerImpl::~wxCarbonTimerImpl()
178 int index
= gTimersInProcess
.Index( this );
179 if ( index
!= wxNOT_FOUND
)
180 gTimersInProcess
.RemoveAt( index
);
183 bool wxCarbonTimerImpl::Start( int milliseconds
, bool mode
)
185 (void)wxTimerBase::Start( milliseconds
, mode
);
187 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeout") );
188 wxCHECK_MSG( m_info
->m_task
.tmAddr
== NULL
, false, wxT("attempting to restart a timer") );
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
);
201 void wxCarbonTimerImpl::Stop()
203 if ( m_info
->m_task
.tmAddr
)
205 RmvTime( (QElemPtr
) &m_info
->m_task
);
206 DisposeTimerUPP( m_info
->m_task
.tmAddr
);
207 m_info
->m_task
.tmAddr
= NULL
;
210 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable(), this );
213 #endif // wxMAC_USE_CARBON_TIMER/!wxMAC_USE_CARBON_TIMER
215 #endif // wxUSE_TIMER