]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/timer.cpp
toolbartool has to send events to parent for tooltips to work
[wxWidgets.git] / src / mac / carbon / timer.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: timer.cpp
3// Purpose: wxTimer implementation
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "timer.h"
14#endif
15
16#include "wx/timer.h"
17
18#if !USE_SHARED_LIBRARY
19IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxEvtHandler)
20#endif
21
22#ifdef __WXMAC__
23#include "wx/mac/private.h"
24#endif
25#ifndef __DARWIN__
26#include <Timer.h>
27#endif
28
29#include "wx/dynarray.h"
30
31#define wxMAC_USE_CARBON_TIMER 1
32
33#if wxMAC_USE_CARBON_TIMER
34
35typedef struct MacTimerInfo
36{
37 wxTimer* m_timer ;
38 EventLoopTimerUPP m_proc ;
39 EventLoopTimerRef m_timerRef ;
40} ;
41
42static pascal void wxProcessTimer( EventLoopTimerRef theTimer , void *data ) ;
43static pascal void wxProcessTimer( EventLoopTimerRef theTimer , void *data )
44{
45 if ( !data )
46 return ;
47
48 wxTimer* timer = (wxTimer*) data ;
49
50 if ( timer->IsOneShot() )
51 timer->Stop() ;
52
53 timer->Notify();
54}
55
56void wxTimer::Init()
57{
58 m_info = new MacTimerInfo() ;
59 m_info->m_timer = this ;
60 m_info->m_proc = NULL ;
61 m_info->m_timerRef = kInvalidID ;
62}
63
64bool wxTimer::IsRunning() const
65{
66 return ( m_info->m_timerRef != kInvalidID ) ;
67}
68
69wxTimer::~wxTimer()
70{
71 Stop();
72 if (m_info != NULL) {
73 delete m_info ;
74 m_info = NULL ;
75 }
76}
77
78bool wxTimer::Start(int milliseconds,bool mode)
79{
80 (void)wxTimerBase::Start(milliseconds, mode);
81
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") );
84
85 m_info->m_timer = this ;
86 m_info->m_proc = NewEventLoopTimerUPP( &wxProcessTimer);
87 verify_noerr( InstallEventLoopTimer (
88 GetMainEventLoop() ,
89 m_milli*kEventDurationMillisecond,
90 IsOneShot() ? 0 : m_milli*kEventDurationMillisecond ,
91 m_info->m_proc,
92 this,
93 &m_info->m_timerRef) ) ;
94 return TRUE;
95}
96
97void wxTimer::Stop()
98{
99 if (m_info->m_timerRef)
100 RemoveEventLoopTimer( m_info->m_timerRef ) ;
101 if (m_info->m_proc)
102 DisposeEventLoopTimerUPP(m_info->m_proc) ;
103 m_info->m_proc = NULL ;
104 m_info->m_timerRef = kInvalidID ;
105}
106
107#else
108
109typedef struct MacTimerInfo
110{
111 TMTask m_task;
112 wxMacNotifierTableRef m_table ;
113 wxTimer* m_timer ;
114} ;
115
116static void wxProcessTimer( unsigned long event , void *data ) ;
117
118static pascal void MacTimerProc( TMTask * t )
119{
120 MacTimerInfo * tm = (MacTimerInfo*) t ;
121 wxMacAddEvent( tm->m_table , wxProcessTimer, 0 , (void*) tm->m_timer , TRUE ) ;
122}
123
124// we need this array to track timers that are being deleted within the Notify procedure
125// adding the timer before the Notify call and checking after whether it still is in there
126// as the destructor would have removed it from the array
127
128wxArrayPtrVoid gTimersInProcess ;
129
130static void wxProcessTimer( unsigned long event , void *data )
131{
132 if ( !data )
133 return ;
134
135 wxTimer* timer = (wxTimer*) data ;
136
137 if ( timer->IsOneShot() )
138 timer->Stop() ;
139
140 gTimersInProcess.Add( timer ) ;
141
142 timer->Notify();
143
144 int index = gTimersInProcess.Index( timer ) ;
145
146 if ( index != wxNOT_FOUND )
147 {
148 gTimersInProcess.RemoveAt( index ) ;
149
150 if ( !timer->IsOneShot() && timer->m_info->m_task.tmAddr )
151 {
152 PrimeTime( (QElemPtr) &timer->m_info->m_task , timer->GetInterval() ) ;
153 }
154
155 }
156}
157
158void wxTimer::Init()
159{
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 ;
167}
168
169bool wxTimer::IsRunning() const
170{
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 ) ;
174}
175
176wxTimer::~wxTimer()
177{
178 Stop();
179 if (m_info != NULL) {
180 delete m_info ;
181 m_info = NULL ;
182 }
183 int index = gTimersInProcess.Index( this ) ;
184 if ( index != wxNOT_FOUND )
185 gTimersInProcess.RemoveAt( index ) ;
186}
187
188bool wxTimer::Start(int milliseconds,bool mode)
189{
190 (void)wxTimerBase::Start(milliseconds, mode);
191
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") );
194
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 ) ;
202 return TRUE;
203}
204
205void wxTimer::Stop()
206{
207 if ( m_info->m_task.tmAddr )
208 {
209 RmvTime( (QElemPtr) &m_info->m_task ) ;
210 DisposeTimerUPP(m_info->m_task.tmAddr) ;
211 m_info->m_task.tmAddr = NULL ;
212 }
213 wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;
214}
215
216#endif
217
218