1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/evtloop.cpp
3 // Purpose: implements wxEventLoop for GTK+
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/evtloop.h"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 class WXDLLEXPORT wxEventLoopImpl
44 wxEventLoopImpl() { SetExitCode(0); }
46 // set/get the exit code
47 void SetExitCode(int exitcode
) { m_exitcode
= exitcode
; }
48 int GetExitCode() const { return m_exitcode
; }
51 // the exit code of the event loop
55 // ============================================================================
56 // wxGUIEventLoop implementation
57 // ============================================================================
59 // ----------------------------------------------------------------------------
60 // wxGUIEventLoop running and exiting
61 // ----------------------------------------------------------------------------
63 wxGUIEventLoop::~wxGUIEventLoop()
65 wxASSERT_MSG( !m_impl
, wxT("should have been deleted in Run()") );
68 int wxGUIEventLoop::DoRun()
70 m_impl
= new wxEventLoopImpl
;
72 guint loopLevel
= gtk_main_level();
74 // This is placed inside of a loop to take into account nested
75 // event loops. For example, inside this event loop, we may recieve
76 // Exit() for a different event loop (which we are currently inside of)
77 // That Exit() will cause this gtk_main() to exit so we need to re-enter it.
78 while ( !m_shouldExit
)
83 // Force the enclosing event loop to also exit to see if it is done
84 // in case that event loop ended inside of this one. If it is not time
85 // yet for that event loop to exit, it will be executed again due to
86 // the while() loop on m_shouldExit().
88 // This is unnecessary if we are the top level loop, i.e. loop of level 0.
96 int exitcode
= m_impl
->GetExitCode();
102 void wxGUIEventLoop::ScheduleExit(int rc
)
104 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
106 m_impl
->SetExitCode(rc
);
113 // ----------------------------------------------------------------------------
114 // wxEventLoop message processing dispatching
115 // ----------------------------------------------------------------------------
117 bool wxGUIEventLoop::Pending() const
121 // We need to remove idle callbacks or gtk_events_pending will
122 // never return false.
123 wxTheApp
->RemoveIdleTag();
126 return gtk_events_pending();
129 bool wxGUIEventLoop::Dispatch()
131 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
133 gtk_main_iteration();
138 //-----------------------------------------------------------------------------
140 //-----------------------------------------------------------------------------
142 bool wxGUIEventLoop::YieldFor(long eventsToProcess
)
145 if ( !wxThread::IsMain() )
147 // can't call gtk_main_iteration() from other threads like this
150 #endif // wxUSE_THREADS
152 m_isInsideYield
= true;
153 m_eventsToProcessInsideYield
= eventsToProcess
;
155 // We need to remove idle callbacks or the loop will
157 wxTheApp
->RemoveIdleTag();
160 // disable log flushing from here because a call to wxYield() shouldn't
161 // normally result in message boxes popping up &c
165 // TODO: implement event filtering using the eventsToProcess mask
166 while (gtk_events_pending())
167 gtk_main_iteration();
169 // It's necessary to call ProcessIdle() to update the frames sizes which
170 // might have been changed (it also will update other things set from
171 // OnUpdateUI() which is a nice (and desired) side effect). But we
172 // call ProcessIdle() only once since this is not meant for longish
173 // background jobs (controlled by wxIdleEvent::RequestMore() and the
174 // return value of Processidle().
178 // let the logs be flashed again
182 m_isInsideYield
= false;