]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/evtloop.cpp
implementing rollover and pressed image for bitmapbutton on osx_cocoa
[wxWidgets.git] / src / osx / carbon / evtloop.cpp
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
40 wxGUIEventLoop::wxGUIEventLoop()
41 {
42 m_sleepTime = kEventDurationNoWait;
43 }
44
45 void wxGUIEventLoop::WakeUp()
46 {
47 extern void wxMacWakeUp();
48
49 wxMacWakeUp();
50 }
51
52 void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent)
53 {
54 if ( wxTheApp )
55 wxTheApp->MacSetCurrentEvent( theEvent, NULL );
56
57 OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget());
58 if (status == eventNotHandledErr && wxTheApp)
59 wxTheApp->MacHandleUnhandledEvent(theEvent);
60
61 ReleaseEvent( theEvent );
62 }
63
64 bool wxGUIEventLoop::Pending() const
65 {
66 EventRef theEvent;
67
68 return ReceiveNextEvent
69 (
70 0, // we want any event at all so we don't specify neither
71 NULL, // the number of event types nor the types themselves
72 kEventDurationNoWait,
73 false, // don't remove the event from queue
74 &theEvent
75 ) == noErr;
76 }
77
78 bool wxGUIEventLoop::Dispatch()
79 {
80 if ( !wxTheApp )
81 return false;
82
83 wxMacAutoreleasePool autoreleasepool;
84
85 EventRef theEvent;
86
87 OSStatus status = ReceiveNextEvent(0, NULL, m_sleepTime, true, &theEvent) ;
88
89 switch (status)
90 {
91 case eventLoopTimedOutErr :
92 // process pending wx events before sending idle events
93 wxTheApp->ProcessPendingEvents();
94 if ( wxTheApp->ProcessIdle() )
95 m_sleepTime = kEventDurationNoWait ;
96 else
97 {
98 m_sleepTime = kEventDurationSecond;
99 #if wxUSE_THREADS
100 wxMutexGuiLeave();
101 wxMilliSleep(20);
102 wxMutexGuiEnter();
103 #endif
104 }
105 break;
106
107 case eventLoopQuitErr :
108 // according to QA1061 this may also occur
109 // when a WakeUp Process is executed
110 break;
111
112 default:
113 DispatchAndReleaseEvent(theEvent);
114 m_sleepTime = kEventDurationNoWait ;
115 break;
116 }
117
118 return true;
119 }
120
121 int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
122 {
123 EventRef event;
124 OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
125 switch ( status )
126 {
127 default:
128 wxFAIL_MSG( "unexpected ReceiveNextEvent() error" );
129 // fall through
130
131 case eventLoopTimedOutErr:
132 return -1;
133
134 case eventLoopQuitErr:
135 return 0;
136
137 case noErr:
138 DispatchAndReleaseEvent(event);
139 return 1;
140 }
141 }
142
143 bool wxGUIEventLoop::YieldFor(long eventsToProcess)
144 {
145 #if wxUSE_THREADS
146 // Yielding from a non-gui thread needs to bail out, otherwise we end up
147 // possibly sending events in the thread too.
148 if ( !wxThread::IsMain() )
149 {
150 return true;
151 }
152 #endif // wxUSE_THREADS
153
154 m_isInsideYield = true;
155 m_eventsToProcessInsideYield = eventsToProcess;
156
157 #if wxUSE_LOG
158 // disable log flushing from here because a call to wxYield() shouldn't
159 // normally result in message boxes popping up &c
160 wxLog::Suspend();
161 #endif // wxUSE_LOG
162
163 // process all pending events:
164 while ( Pending() )
165 Dispatch();
166
167 // it's necessary to call ProcessIdle() to update the frames sizes which
168 // might have been changed (it also will update other things set from
169 // OnUpdateUI() which is a nice (and desired) side effect)
170 while ( ProcessIdle() ) {}
171
172 // if there are pending events, we must process them.
173 if (wxTheApp)
174 wxTheApp->ProcessPendingEvents();
175
176 #if wxUSE_LOG
177 wxLog::Resume();
178 #endif // wxUSE_LOG
179 m_isInsideYield = false;
180
181 return true;
182 }