]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/evtloop.cpp
correct base for carbon is 10.6 max
[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"
670f9935
WS
27
28#ifndef WX_PRECOMP
29 #include "wx/app.h"
6918257d 30 #include "wx/log.h"
670f9935 31#endif // WX_PRECOMP
8000ae7f
VZ
32
33#include <gtk/gtk.h>
34
35// ----------------------------------------------------------------------------
36// wxEventLoopImpl
37// ----------------------------------------------------------------------------
38
39class WXDLLEXPORT wxEventLoopImpl
40{
41public:
42 // ctor
43 wxEventLoopImpl() { SetExitCode(0); }
44
45 // set/get the exit code
46 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
47 int GetExitCode() const { return m_exitcode; }
48
49private:
50 // the exit code of the event loop
51 int m_exitcode;
52};
53
54// ============================================================================
b46b1d59 55// wxGUIEventLoop implementation
8000ae7f
VZ
56// ============================================================================
57
58// ----------------------------------------------------------------------------
b46b1d59 59// wxGUIEventLoop running and exiting
8000ae7f
VZ
60// ----------------------------------------------------------------------------
61
b46b1d59 62wxGUIEventLoop::~wxGUIEventLoop()
8000ae7f 63{
9a83f860 64 wxASSERT_MSG( !m_impl, wxT("should have been deleted in Run()") );
8000ae7f
VZ
65}
66
c738d187 67int wxGUIEventLoop::DoRun()
8000ae7f 68{
8000ae7f
VZ
69 m_impl = new wxEventLoopImpl;
70
d3ad22bd
VZ
71 guint loopLevel = gtk_main_level();
72
73 // This is placed inside of a loop to take into account nested
74 // event loops. For example, inside this event loop, we may recieve
75 // Exit() for a different event loop (which we are currently inside of)
76 // That Exit() will cause this gtk_main() to exit so we need to re-enter it.
77 while ( !m_shouldExit )
78 {
79 gtk_main();
80 }
81
82 // Force the enclosing event loop to also exit to see if it is done
83 // in case that event loop ended inside of this one. If it is not time
84 // yet for that event loop to exit, it will be executed again due to
85 // the while() loop on m_shouldExit().
86 //
87 // This is unnecessary if we are the top level loop, i.e. loop of level 0.
88 if ( loopLevel )
89 {
90 gtk_main_quit();
91 }
8000ae7f 92
16d17da6
VZ
93 OnExit();
94
8000ae7f 95 int exitcode = m_impl->GetExitCode();
5276b0a5 96 wxDELETE(m_impl);
8000ae7f
VZ
97
98 return exitcode;
99}
100
d3ad22bd 101void wxGUIEventLoop::ScheduleExit(int rc)
8000ae7f 102{
d3ad22bd 103 wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
8000ae7f
VZ
104
105 m_impl->SetExitCode(rc);
106
d3ad22bd
VZ
107 m_shouldExit = true;
108
8000ae7f
VZ
109 gtk_main_quit();
110}
111
112// ----------------------------------------------------------------------------
113// wxEventLoop message processing dispatching
114// ----------------------------------------------------------------------------
115
b46b1d59 116bool wxGUIEventLoop::Pending() const
8000ae7f 117{
c263eb03 118 if (wxTheApp)
9213ca5d
RD
119 {
120 // We need to remove idle callbacks or gtk_events_pending will
121 // never return false.
fe593cc5 122 wxTheApp->RemoveIdleTag();
9213ca5d
RD
123 }
124
125 return gtk_events_pending();
8000ae7f
VZ
126}
127
b46b1d59 128bool wxGUIEventLoop::Dispatch()
8000ae7f 129{
9a83f860 130 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
8000ae7f
VZ
131
132 gtk_main_iteration();
133
670f9935 134 return true;
8000ae7f 135}
dde19c21
FM
136
137//-----------------------------------------------------------------------------
138// wxYield
139//-----------------------------------------------------------------------------
140
141bool wxGUIEventLoop::YieldFor(long eventsToProcess)
142{
143#if wxUSE_THREADS
144 if ( !wxThread::IsMain() )
145 {
146 // can't call gtk_main_iteration() from other threads like this
147 return true;
148 }
149#endif // wxUSE_THREADS
150
151 m_isInsideYield = true;
152 m_eventsToProcessInsideYield = eventsToProcess;
153
154 // We need to remove idle callbacks or the loop will
155 // never finish.
156 wxTheApp->RemoveIdleTag();
157
158#if wxUSE_LOG
159 // disable log flushing from here because a call to wxYield() shouldn't
160 // normally result in message boxes popping up &c
161 wxLog::Suspend();
162#endif
163
164 // TODO: implement event filtering using the eventsToProcess mask
165 while (gtk_events_pending())
166 gtk_main_iteration();
167
168 // It's necessary to call ProcessIdle() to update the frames sizes which
169 // might have been changed (it also will update other things set from
170 // OnUpdateUI() which is a nice (and desired) side effect). But we
171 // call ProcessIdle() only once since this is not meant for longish
172 // background jobs (controlled by wxIdleEvent::RequestMore() and the
173 // return value of Processidle().
174 ProcessIdle();
175
176#if wxUSE_LOG
177 // let the logs be flashed again
178 wxLog::Resume();
179#endif
180
181 m_isInsideYield = false;
182
183 return true;
184}