Remove obsolete VisualAge-related files.
[wxWidgets.git] / src / gtk1 / evtloop.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/evtloop.cpp
3 // Purpose: implements wxEventLoop for GTK+
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 10.07.01
7 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/evtloop.h"
27 #include "wx/private/eventloopsourcesmanager.h"
28 #include "wx/apptrait.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/app.h"
32 #include "wx/log.h"
33 #endif // WX_PRECOMP
34
35 #include <gtk/gtk.h>
36
37 // ----------------------------------------------------------------------------
38 // wxEventLoopImpl
39 // ----------------------------------------------------------------------------
40
41 class WXDLLEXPORT wxEventLoopImpl
42 {
43 public:
44 // ctor
45 wxEventLoopImpl() { SetExitCode(0); }
46
47 // set/get the exit code
48 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
49 int GetExitCode() const { return m_exitcode; }
50
51 private:
52 // the exit code of the event loop
53 int m_exitcode;
54 };
55
56 // ============================================================================
57 // wxGUIEventLoop implementation
58 // ============================================================================
59
60 // ----------------------------------------------------------------------------
61 // wxGUIEventLoop running and exiting
62 // ----------------------------------------------------------------------------
63
64 wxGUIEventLoop::~wxGUIEventLoop()
65 {
66 wxASSERT_MSG( !m_impl, wxT("should have been deleted in Run()") );
67 }
68
69 int wxGUIEventLoop::DoRun()
70 {
71 m_impl = new wxEventLoopImpl;
72
73 guint loopLevel = gtk_main_level();
74
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.
79 #if 0
80 // changed by JJ
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 )
87 {
88 #endif
89 gtk_main();
90 #if 0
91 }
92
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().
97 //
98 // This is unnecessary if we are the top level loop, i.e. loop of level 0.
99 if ( loopLevel )
100 {
101 gtk_main_quit();
102 }
103 #endif
104
105 OnExit();
106
107 int exitcode = m_impl->GetExitCode();
108 wxDELETE(m_impl);
109
110 return exitcode;
111 }
112
113 void wxGUIEventLoop::ScheduleExit(int rc)
114 {
115 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
116
117 m_impl->SetExitCode(rc);
118
119 m_shouldExit = true;
120
121 gtk_main_quit();
122 }
123
124 // ----------------------------------------------------------------------------
125 // wxEventLoop message processing dispatching
126 // ----------------------------------------------------------------------------
127
128 bool wxGUIEventLoop::Pending() const
129 {
130 if (wxTheApp)
131 {
132 // We need to remove idle callbacks or gtk_events_pending will
133 // never return false.
134 wxTheApp->RemoveIdleTag();
135 }
136
137 return gtk_events_pending();
138 }
139
140 bool wxGUIEventLoop::Dispatch()
141 {
142 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
143
144 gtk_main_iteration();
145
146 return true;
147 }
148
149 //-----------------------------------------------------------------------------
150 // wxYield
151 //-----------------------------------------------------------------------------
152
153 bool wxGUIEventLoop::YieldFor(long eventsToProcess)
154 {
155 #if wxUSE_THREADS
156 if ( !wxThread::IsMain() )
157 {
158 // can't call gtk_main_iteration() from other threads like this
159 return true;
160 }
161 #endif // wxUSE_THREADS
162
163 m_isInsideYield = true;
164 m_eventsToProcessInsideYield = eventsToProcess;
165
166 // We need to remove idle callbacks or the loop will
167 // never finish.
168 wxTheApp->RemoveIdleTag();
169
170 #if wxUSE_LOG
171 // disable log flushing from here because a call to wxYield() shouldn't
172 // normally result in message boxes popping up &c
173 wxLog::Suspend();
174 #endif
175
176 // TODO: implement event filtering using the eventsToProcess mask
177 while (gtk_events_pending())
178 gtk_main_iteration();
179
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().
186 ProcessIdle();
187
188 #if wxUSE_LOG
189 // let the logs be flashed again
190 wxLog::Resume();
191 #endif
192
193 m_isInsideYield = false;
194
195 return true;
196 }
197
198 class wxGUIEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
199 {
200 public:
201 wxEventLoopSource *
202 AddSourceForFD(int WXUNUSED(fd),
203 wxEventLoopSourceHandler* WXUNUSED(handler),
204 int WXUNUSED(flags))
205 {
206 wxFAIL_MSG("Monitoring FDs in the main loop is not implemented in wxGTK1");
207
208 return NULL;
209 }
210 };
211
212 wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
213 {
214 static wxGUIEventLoopSourcesManager s_eventLoopSourcesManager;
215
216 return &s_eventLoopSourcesManager;
217 }