1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxTimer implementation 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "timer.h" 
  16 #include "wx/wxprec.h" 
  20 #if !USE_SHARED_LIBRARY 
  21 IMPLEMENT_ABSTRACT_CLASS(wxTimer
, wxEvtHandler
) 
  25 #include "wx/mac/private.h" 
  31 #include "wx/dynarray.h" 
  33 #define wxMAC_USE_CARBON_TIMER 1 
  35 #if wxMAC_USE_CARBON_TIMER 
  37 typedef struct MacTimerInfo
 
  40     EventLoopTimerUPP m_proc 
; 
  41     EventLoopTimerRef   m_timerRef 
; 
  44 static pascal void wxProcessTimer( EventLoopTimerRef  theTimer 
, void *data 
) ; 
  45 static pascal void wxProcessTimer( EventLoopTimerRef theTimer 
, void *data 
) 
  50     wxTimer
* timer 
= (wxTimer
*) data 
; 
  52     if ( timer
->IsOneShot() ) 
  60     m_info 
= new MacTimerInfo() ; 
  61     m_info
->m_timer 
= this ; 
  62     m_info
->m_proc 
= NULL 
; 
  63     m_info
->m_timerRef 
= kInvalidID 
; 
  66 bool wxTimer::IsRunning() const  
  68     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
); 
  89     verify_noerr( InstallEventLoopTimer ( 
  91         m_milli
*kEventDurationMillisecond
, 
  92         IsOneShot() ? 0 : m_milli
*kEventDurationMillisecond 
, 
  95         &m_info
->m_timerRef
) ) ; 
 101     if (m_info
->m_timerRef
) 
 102         RemoveEventLoopTimer( m_info
->m_timerRef 
) ;  
 104         DisposeEventLoopTimerUPP(m_info
->m_proc
) ; 
 105     m_info
->m_proc 
= NULL 
; 
 106     m_info
->m_timerRef 
= kInvalidID 
; 
 111 typedef struct MacTimerInfo
 
 114     wxMacNotifierTableRef m_table 
; 
 118 static void wxProcessTimer( unsigned long event 
, void *data 
) ; 
 120 static pascal void MacTimerProc( TMTask 
* t 
) 
 122     MacTimerInfo 
* tm 
= (MacTimerInfo
*)  t 
; 
 123     wxMacAddEvent( tm
->m_table 
, wxProcessTimer
, 0 , (void*) tm
->m_timer 
, TRUE 
) ; 
 126 // we need this array to track timers that are being deleted within the Notify procedure 
 127 // adding the timer before the Notify call and checking after whether it still is in there  
 128 // as the destructor would have removed it from the array 
 130 wxArrayPtrVoid gTimersInProcess 
; 
 132 static void wxProcessTimer( unsigned long event 
, void *data 
) 
 137     wxTimer
* timer 
= (wxTimer
*) data 
; 
 139     if ( timer
->IsOneShot() ) 
 142     gTimersInProcess
.Add( timer 
) ; 
 146     int index 
= gTimersInProcess
.Index( timer 
) ; 
 148     if ( index 
!= wxNOT_FOUND 
) 
 150         gTimersInProcess
.RemoveAt( index 
) ; 
 152         if ( !timer
->IsOneShot() && timer
->m_info
->m_task
.tmAddr 
) 
 154             PrimeTime( (QElemPtr
)  &timer
->m_info
->m_task 
, timer
->GetInterval() ) ; 
 162     m_info 
= new MacTimerInfo() ; 
 163     m_info
->m_task
.tmAddr 
= NULL 
; 
 164     m_info
->m_task
.tmWakeUp 
= 0 ; 
 165     m_info
->m_task
.tmReserved 
= 0 ; 
 166     m_info
->m_task
.qType 
= 0 ; 
 167     m_info
->m_table 
= wxMacGetNotifierTable() ; 
 168     m_info
->m_timer 
= this ; 
 171 bool wxTimer::IsRunning() const  
 173     // as the qType may already indicate it is elapsed, but it 
 174     // was not handled internally yet 
 175     return ( m_info
->m_task
.tmAddr 
!= NULL 
) ; 
 181     if (m_info 
!= 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 
) ; 
 209     if ( m_info
->m_task
.tmAddr 
) 
 211         RmvTime(  (QElemPtr
) &m_info
->m_task 
) ; 
 212         DisposeTimerUPP(m_info
->m_task
.tmAddr
) ; 
 213         m_info
->m_task
.tmAddr 
= NULL 
; 
 215     wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;