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" 
  15     #include "wx/dynarray.h" 
  21     #include "wx/mac/private.h" 
  28 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
) 
  30 #define wxMAC_USE_CARBON_TIMER 1 
  32 #if wxMAC_USE_CARBON_TIMER 
  37     EventLoopTimerUPP m_proc
; 
  38     EventLoopTimerRef   m_timerRef
; 
  41 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data 
); 
  42 static pascal void wxProcessTimer( EventLoopTimerRef theTimer
, void *data 
) 
  47     wxTimer
* timer 
= (wxTimer
*)data
; 
  49     if ( timer
->IsOneShot() ) 
  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 wxTimer::IsRunning() const 
  65     return ( m_info
->m_timerRef 
!= kInvalidID 
); 
  78 bool wxTimer::Start( int milliseconds
, bool mode 
) 
  80     (void)wxTimerBase::Start(milliseconds
, mode
); 
  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") ); 
  85     m_info
->m_timer 
= this; 
  86     m_info
->m_proc 
= NewEventLoopTimerUPP( &wxProcessTimer 
); 
  88     OSStatus err 
= InstallEventLoopTimer( 
  90         m_milli
*kEventDurationMillisecond
, 
  91         IsOneShot() ? 0 : m_milli 
* kEventDurationMillisecond
, 
  94         &m_info
->m_timerRef 
); 
 102     if (m_info
->m_timerRef
) 
 103         RemoveEventLoopTimer( m_info
->m_timerRef 
); 
 105         DisposeEventLoopTimerUPP( m_info
->m_proc 
); 
 107     m_info
->m_proc 
= NULL
; 
 108     m_info
->m_timerRef 
= kInvalidID
; 
 113 typedef struct MacTimerInfo
 
 116     wxMacNotifierTableRef m_table
; 
 120 static void wxProcessTimer( unsigned long event
, void *data 
); 
 122 static pascal void MacTimerProc( TMTask 
* t 
) 
 124     MacTimerInfo 
* tm 
= (MacTimerInfo
*) t
; 
 125     wxMacAddEvent( tm
->m_table
, wxProcessTimer
, 0, (void*) tm
->m_timer
, true ); 
 128 // we need this array to track timers that are being deleted within the Notify procedure 
 129 // adding the timer before the Notify call and checking after whether it still is in there 
 130 // as the destructor would have removed it from the array 
 132 wxArrayPtrVoid gTimersInProcess
; 
 134 static void wxProcessTimer( unsigned long event
, void *data 
) 
 139     wxTimer
* timer 
= (wxTimer
*) data
; 
 140     if ( timer
->IsOneShot() ) 
 143     gTimersInProcess
.Add( timer 
); 
 146     int index 
= gTimersInProcess
.Index( timer 
); 
 147     if ( index 
!= wxNOT_FOUND 
) 
 149         gTimersInProcess
.RemoveAt( index 
); 
 151         if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr 
) 
 152             PrimeTime( (QElemPtr
) &timer
->m_info
->m_task
, timer
->GetInterval() ); 
 158     m_info 
= new MacTimerInfo(); 
 159     m_info
->m_task
.tmAddr 
= NULL
; 
 160     m_info
->m_task
.tmWakeUp 
= 0; 
 161     m_info
->m_task
.tmReserved 
= 0; 
 162     m_info
->m_task
.qType 
= 0; 
 163     m_info
->m_table 
= wxMacGetNotifierTable(); 
 164     m_info
->m_timer 
= this; 
 167 bool wxTimer::IsRunning() const 
 169     // as the qType may already indicate it is elapsed, but it 
 170     // was not handled internally yet 
 171     return ( m_info
->m_task
.tmAddr 
!= NULL 
); 
 183     int index 
= gTimersInProcess
.Index( this ); 
 184     if ( index 
!= wxNOT_FOUND 
) 
 185         gTimersInProcess
.RemoveAt( index 
); 
 188 bool wxTimer::Start( int milliseconds
, bool mode 
) 
 190     (void)wxTimerBase::Start( milliseconds
, mode 
); 
 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") ); 
 195     m_info
->m_task
.tmAddr 
= NewTimerUPP( MacTimerProc 
); 
 196     m_info
->m_task
.tmWakeUp 
= 0; 
 197     m_info
->m_task
.tmReserved 
= 0; 
 198     m_info
->m_task
.qType 
= 0; 
 199     m_info
->m_timer 
= this; 
 200     InsXTime( (QElemPtr
) &m_info
->m_task 
); 
 201     PrimeTime( (QElemPtr
) &m_info
->m_task
, m_milli 
); 
 208     if ( m_info
->m_task
.tmAddr 
) 
 210         RmvTime( (QElemPtr
) &m_info
->m_task 
); 
 211         DisposeTimerUPP( m_info
->m_task
.tmAddr 
); 
 212         m_info
->m_task
.tmAddr 
= NULL
; 
 215     wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable(), this );