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