]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/osx/carbon/evtloop.cpp
Refactor wxEventLoopSource-related code.
[wxWidgets.git] / src / osx / carbon / evtloop.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/carbon/evtloop.cpp
3// Purpose: implementation of wxEventLoop for wxMac
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 2006-01-12
7// RCS-ID: $Id$
8// Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#include "wx/evtloop.h"
28
29#ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/log.h"
32#endif // WX_PRECOMP
33
34#include "wx/osx/private.h"
35
36// ============================================================================
37// wxEventLoop implementation
38// ============================================================================
39
40wxGUIEventLoop::wxGUIEventLoop()
41{
42 m_sleepTime = kEventDurationNoWait;
43}
44
45void wxGUIEventLoop::WakeUp()
46{
47 extern void wxMacWakeUp();
48
49 wxMacWakeUp();
50}
51
52CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
53{
54 return CFRunLoopGetCurrent();
55}
56
57void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent)
58{
59 if ( wxTheApp )
60 wxTheApp->MacSetCurrentEvent( theEvent, NULL );
61
62 OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget());
63 if (status == eventNotHandledErr && wxTheApp)
64 wxTheApp->MacHandleUnhandledEvent(theEvent);
65
66 ReleaseEvent( theEvent );
67}
68
69bool wxGUIEventLoop::Pending() const
70{
71 EventRef theEvent;
72
73 return ReceiveNextEvent
74 (
75 0, // we want any event at all so we don't specify neither
76 NULL, // the number of event types nor the types themselves
77 kEventDurationNoWait,
78 false, // don't remove the event from queue
79 &theEvent
80 ) == noErr;
81}
82
83bool wxGUIEventLoop::Dispatch()
84{
85 if ( !wxTheApp )
86 return false;
87
88 wxMacAutoreleasePool autoreleasepool;
89
90 EventRef theEvent;
91
92 OSStatus status = ReceiveNextEvent(0, NULL, m_sleepTime, true, &theEvent) ;
93
94 switch (status)
95 {
96 case eventLoopTimedOutErr :
97 // process pending wx events before sending idle events
98 wxTheApp->ProcessPendingEvents();
99 if ( wxTheApp->ProcessIdle() )
100 m_sleepTime = kEventDurationNoWait ;
101 else
102 {
103 m_sleepTime = kEventDurationSecond;
104#if wxUSE_THREADS
105 wxMutexGuiLeave();
106 wxMilliSleep(20);
107 wxMutexGuiEnter();
108#endif
109 }
110 break;
111
112 case eventLoopQuitErr :
113 // according to QA1061 this may also occur
114 // when a WakeUp Process is executed
115 break;
116
117 default:
118 DispatchAndReleaseEvent(theEvent);
119 m_sleepTime = kEventDurationNoWait ;
120 break;
121 }
122
123 return true;
124}
125
126int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
127{
128 EventRef event;
129 OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
130 switch ( status )
131 {
132 default:
133 wxFAIL_MSG( "unexpected ReceiveNextEvent() error" );
134 // fall through
135
136 case eventLoopTimedOutErr:
137 return -1;
138
139 case eventLoopQuitErr:
140 return 0;
141
142 case noErr:
143 DispatchAndReleaseEvent(event);
144 return 1;
145 }
146}
147
148bool wxGUIEventLoop::YieldFor(long eventsToProcess)
149{
150#if wxUSE_THREADS
151 // Yielding from a non-gui thread needs to bail out, otherwise we end up
152 // possibly sending events in the thread too.
153 if ( !wxThread::IsMain() )
154 {
155 return true;
156 }
157#endif // wxUSE_THREADS
158
159 m_isInsideYield = true;
160 m_eventsToProcessInsideYield = eventsToProcess;
161
162#if wxUSE_LOG
163 // disable log flushing from here because a call to wxYield() shouldn't
164 // normally result in message boxes popping up &c
165 wxLog::Suspend();
166#endif // wxUSE_LOG
167
168 // process all pending events:
169 while ( Pending() )
170 Dispatch();
171
172 // it's necessary to call ProcessIdle() to update the frames sizes which
173 // might have been changed (it also will update other things set from
174 // OnUpdateUI() which is a nice (and desired) side effect)
175 while ( ProcessIdle() ) {}
176
177 // if there are pending events, we must process them.
178 if (wxTheApp)
179 wxTheApp->ProcessPendingEvents();
180
181#if wxUSE_LOG
182 wxLog::Resume();
183#endif // wxUSE_LOG
184 m_isInsideYield = false;
185
186 return true;
187}