1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/evtloop.cpp
3 // Purpose: implements wxEventLoop for GTK+
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #include "wx/evtloop.h"
27 #include "wx/private/eventloopsourcesmanager.h"
28 #include "wx/apptrait.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 class WXDLLEXPORT wxEventLoopImpl
45 wxEventLoopImpl() { SetExitCode(0); }
47 // set/get the exit code
48 void SetExitCode(int exitcode
) { m_exitcode
= exitcode
; }
49 int GetExitCode() const { return m_exitcode
; }
52 // the exit code of the event loop
56 // ============================================================================
57 // wxGUIEventLoop implementation
58 // ============================================================================
60 // ----------------------------------------------------------------------------
61 // wxGUIEventLoop running and exiting
62 // ----------------------------------------------------------------------------
64 wxGUIEventLoop::~wxGUIEventLoop()
66 wxASSERT_MSG( !m_impl
, wxT("should have been deleted in Run()") );
69 int wxGUIEventLoop::DoRun()
71 m_impl
= new wxEventLoopImpl
;
73 guint loopLevel
= gtk_main_level();
75 // This is placed inside of a loop to take into account nested
76 // event loops. For example, inside this event loop, we may recieve
77 // Exit() for a different event loop (which we are currently inside of)
78 // That Exit() will cause this gtk_main() to exit so we need to re-enter it.
81 // this code was intended to support nested event loops. However,
82 // exiting a dialog will result in a application hang (because
83 // gtk_main_quit is called when closing the dialog????)
84 // So for the moment this code is disabled and nested event loops
85 // probably fail for wxGTK1
86 while ( !m_shouldExit
)
93 // Force the enclosing event loop to also exit to see if it is done
94 // in case that event loop ended inside of this one. If it is not time
95 // yet for that event loop to exit, it will be executed again due to
96 // the while() loop on m_shouldExit().
98 // This is unnecessary if we are the top level loop, i.e. loop of level 0.
107 int exitcode
= m_impl
->GetExitCode();
113 void wxGUIEventLoop::ScheduleExit(int rc
)
115 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
117 m_impl
->SetExitCode(rc
);
124 // ----------------------------------------------------------------------------
125 // wxEventLoop message processing dispatching
126 // ----------------------------------------------------------------------------
128 bool wxGUIEventLoop::Pending() const
132 // We need to remove idle callbacks or gtk_events_pending will
133 // never return false.
134 wxTheApp
->RemoveIdleTag();
137 return gtk_events_pending();
140 bool wxGUIEventLoop::Dispatch()
142 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
144 gtk_main_iteration();
149 //-----------------------------------------------------------------------------
151 //-----------------------------------------------------------------------------
153 bool wxGUIEventLoop::YieldFor(long eventsToProcess
)
156 if ( !wxThread::IsMain() )
158 // can't call gtk_main_iteration() from other threads like this
161 #endif // wxUSE_THREADS
163 m_isInsideYield
= true;
164 m_eventsToProcessInsideYield
= eventsToProcess
;
166 // We need to remove idle callbacks or the loop will
168 wxTheApp
->RemoveIdleTag();
171 // disable log flushing from here because a call to wxYield() shouldn't
172 // normally result in message boxes popping up &c
176 // TODO: implement event filtering using the eventsToProcess mask
177 while (gtk_events_pending())
178 gtk_main_iteration();
180 // It's necessary to call ProcessIdle() to update the frames sizes which
181 // might have been changed (it also will update other things set from
182 // OnUpdateUI() which is a nice (and desired) side effect). But we
183 // call ProcessIdle() only once since this is not meant for longish
184 // background jobs (controlled by wxIdleEvent::RequestMore() and the
185 // return value of Processidle().
189 // let the logs be flashed again
193 m_isInsideYield
= false;
198 class wxGUIEventLoopSourcesManager
: public wxEventLoopSourcesManagerBase
202 AddSourceForFD(int WXUNUSED(fd
),
203 wxEventLoopSourceHandler
* WXUNUSED(handler
),
206 wxFAIL_MSG("Monitoring FDs in the main loop is not implemented in wxGTK1");
212 wxEventLoopSourcesManagerBase
* wxGUIAppTraits::GetEventLoopSourcesManager()
214 static wxGUIEventLoopSourcesManager s_eventLoopSourcesManager
;
216 return &s_eventLoopSourcesManager
;