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"
23 #include "wx/mac/private.h"
30 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
)
32 #define wxMAC_USE_CARBON_TIMER 1
34 #if wxMAC_USE_CARBON_TIMER
39 EventLoopTimerUPP m_proc
;
40 EventLoopTimerRef m_timerRef
;
43 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
);
44 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data
)
49 wxTimer
* timer
= (wxTimer
*)data
;
51 if ( timer
->IsOneShot() )
59 m_info
= new MacTimerInfo();
60 m_info
->m_timer
= this;
61 m_info
->m_proc
= NULL
;
62 m_info
->m_timerRef
= kInvalidID
;
65 bool wxTimer::IsRunning() const
67 return ( m_info
->m_timerRef
!= kInvalidID
);
80 bool wxTimer::Start( int milliseconds
, bool mode
)
82 (void)wxTimerBase::Start(milliseconds
, mode
);
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") );
87 m_info
->m_timer
= this;
88 m_info
->m_proc
= NewEventLoopTimerUPP( &wxProcessTimer
);
90 OSStatus err
= InstallEventLoopTimer(
92 m_milli
*kEventDurationMillisecond
,
93 IsOneShot() ? 0 : m_milli
* kEventDurationMillisecond
,
96 &m_info
->m_timerRef
);
104 if (m_info
->m_timerRef
)
105 RemoveEventLoopTimer( m_info
->m_timerRef
);
107 DisposeEventLoopTimerUPP( m_info
->m_proc
);
109 m_info
->m_proc
= NULL
;
110 m_info
->m_timerRef
= kInvalidID
;
115 typedef struct MacTimerInfo
118 wxMacNotifierTableRef m_table
;
122 static void wxProcessTimer( unsigned long event
, void *data
);
124 static pascal void MacTimerProc( TMTask
* t
)
126 MacTimerInfo
* tm
= (MacTimerInfo
*) t
;
127 wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0, (void*) tm
->m_timer
, true );
130 // we need this array to track timers that are being deleted within the Notify procedure
131 // adding the timer before the Notify call and checking after whether it still is in there
132 // as the destructor would have removed it from the array
134 wxArrayPtrVoid gTimersInProcess
;
136 static void wxProcessTimer( unsigned long event
, void *data
)
141 wxTimer
* timer
= (wxTimer
*) data
;
142 if ( timer
->IsOneShot() )
145 gTimersInProcess
.Add( timer
);
148 int index
= gTimersInProcess
.Index( timer
);
149 if ( index
!= wxNOT_FOUND
)
151 gTimersInProcess
.RemoveAt( index
);
153 if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr
)
154 PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() );
160 m_info
= new MacTimerInfo();
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;
169 bool wxTimer::IsRunning() const
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
);
185 int index
= gTimersInProcess
.Index( this );
186 if ( index
!= wxNOT_FOUND
)
187 gTimersInProcess
.RemoveAt( index
);
190 bool wxTimer::Start( int milliseconds
, bool mode
)
192 (void)wxTimerBase::Start( milliseconds
, mode
);
194 wxCHECK_MSG( m_milli
> 0, false, wxT("invalid value for timer timeout") );
195 wxCHECK_MSG( m_info
->m_task
.tmAddr
== NULL
, false, wxT("attempting to restart a timer") );
197 m_info
->m_task
.tmAddr
= NewTimerUPP( MacTimerProc
);
198 m_info
->m_task
.tmWakeUp
= 0;
199 m_info
->m_task
.tmReserved
= 0;
200 m_info
->m_task
.qType
= 0;
201 m_info
->m_timer
= this;
202 InsXTime( (QElemPtr
) &m_info
->m_task
);
203 PrimeTime( (QElemPtr
) &m_info
->m_task
, m_milli
);
210 if ( m_info
->m_task
.tmAddr
)
212 RmvTime( (QElemPtr
) &m_info
->m_task
);
213 DisposeTimerUPP( m_info
->m_task
.tmAddr
);
214 m_info
->m_task
.tmAddr
= NULL
;
217 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable(), this );
220 #endif // wxMAC_USE_CARBON_TIMER
222 #endif // wxUSE_TIMER