]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/evtloop.cpp
fix building with WXWIN_COMPATIBILITY_2_8 == 0
[wxWidgets.git] / src / gtk1 / evtloop.cpp
CommitLineData
8000ae7f 1///////////////////////////////////////////////////////////////////////////////
670f9935 2// Name: src/gtk1/evtloop.cpp
8000ae7f
VZ
3// Purpose: implements wxEventLoop for GTK+
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 10.07.01
8000ae7f 7// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
526954c5 8// Licence: wxWindows licence
8000ae7f
VZ
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
8000ae7f
VZ
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
8000ae7f 26#include "wx/evtloop.h"
71693601 27#include "wx/private/eventloopsourcesmanager.h"
8059d88d 28#include "wx/apptrait.h"
670f9935
WS
29
30#ifndef WX_PRECOMP
31 #include "wx/app.h"
6918257d 32 #include "wx/log.h"
670f9935 33#endif // WX_PRECOMP
8000ae7f
VZ
34
35#include <gtk/gtk.h>
36
37// ----------------------------------------------------------------------------
38// wxEventLoopImpl
39// ----------------------------------------------------------------------------
40
41class WXDLLEXPORT wxEventLoopImpl
42{
43public:
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
51private:
52 // the exit code of the event loop
53 int m_exitcode;
54};
55
56// ============================================================================
b46b1d59 57// wxGUIEventLoop implementation
8000ae7f
VZ
58// ============================================================================
59
60// ----------------------------------------------------------------------------
b46b1d59 61// wxGUIEventLoop running and exiting
8000ae7f
VZ
62// ----------------------------------------------------------------------------
63
b46b1d59 64wxGUIEventLoop::~wxGUIEventLoop()
8000ae7f 65{
9a83f860 66 wxASSERT_MSG( !m_impl, wxT("should have been deleted in Run()") );
8000ae7f
VZ
67}
68
c738d187 69int wxGUIEventLoop::DoRun()
8000ae7f 70{
8000ae7f
VZ
71 m_impl = new wxEventLoopImpl;
72
d3ad22bd
VZ
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.
67afffcd
JJ
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 )
d3ad22bd 87 {
67afffcd
JJ
88#endif
89 gtk_main();
90#if 0
d3ad22bd
VZ
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 }
67afffcd 103#endif
8000ae7f 104
16d17da6
VZ
105 OnExit();
106
8000ae7f 107 int exitcode = m_impl->GetExitCode();
5276b0a5 108 wxDELETE(m_impl);
8000ae7f
VZ
109
110 return exitcode;
111}
112
d3ad22bd 113void wxGUIEventLoop::ScheduleExit(int rc)
8000ae7f 114{
d3ad22bd 115 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
8000ae7f
VZ
116
117 m_impl->SetExitCode(rc);
118
d3ad22bd
VZ
119 m_shouldExit = true;
120
8000ae7f
VZ
121 gtk_main_quit();
122}
123
124// ----------------------------------------------------------------------------
125// wxEventLoop message processing dispatching
126// ----------------------------------------------------------------------------
127
b46b1d59 128bool wxGUIEventLoop::Pending() const
8000ae7f 129{
c263eb03 130 if (wxTheApp)
9213ca5d
RD
131 {
132 // We need to remove idle callbacks or gtk_events_pending will
133 // never return false.
fe593cc5 134 wxTheApp->RemoveIdleTag();
9213ca5d
RD
135 }
136
137 return gtk_events_pending();
8000ae7f
VZ
138}
139
b46b1d59 140bool wxGUIEventLoop::Dispatch()
8000ae7f 141{
9a83f860 142 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
8000ae7f
VZ
143
144 gtk_main_iteration();
145
670f9935 146 return true;
8000ae7f 147}
dde19c21
FM
148
149//-----------------------------------------------------------------------------
150// wxYield
151//-----------------------------------------------------------------------------
152
153bool 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}
67afffcd
JJ
197
198class 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
212wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
213{
214 static wxGUIEventLoopSourcesManager s_eventLoopSourcesManager;
215
216 return &s_eventLoopSourcesManager;
217}