Add wxEventLoopBase::DoRun().
[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 // RCS-ID: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #include "wx/evtloop.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/log.h"
32 #endif // WX_PRECOMP
33
34 #include <gtk/gtk.h>
35
36 // ----------------------------------------------------------------------------
37 // wxEventLoopImpl
38 // ----------------------------------------------------------------------------
39
40 class WXDLLEXPORT wxEventLoopImpl
41 {
42 public:
43 // ctor
44 wxEventLoopImpl() { SetExitCode(0); }
45
46 // set/get the exit code
47 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
48 int GetExitCode() const { return m_exitcode; }
49
50 private:
51 // the exit code of the event loop
52 int m_exitcode;
53 };
54
55 // ============================================================================
56 // wxGUIEventLoop implementation
57 // ============================================================================
58
59 // ----------------------------------------------------------------------------
60 // wxGUIEventLoop running and exiting
61 // ----------------------------------------------------------------------------
62
63 wxGUIEventLoop::~wxGUIEventLoop()
64 {
65 wxASSERT_MSG( !m_impl, wxT("should have been deleted in Run()") );
66 }
67
68 int wxGUIEventLoop::DoRun()
69 {
70 m_impl = new wxEventLoopImpl;
71
72 gtk_main();
73
74 OnExit();
75
76 int exitcode = m_impl->GetExitCode();
77 wxDELETE(m_impl);
78
79 return exitcode;
80 }
81
82 void wxGUIEventLoop::Exit(int rc)
83 {
84 wxCHECK_RET( IsRunning(), wxT("can't call Exit() if not running") );
85
86 m_impl->SetExitCode(rc);
87
88 gtk_main_quit();
89 }
90
91 // ----------------------------------------------------------------------------
92 // wxEventLoop message processing dispatching
93 // ----------------------------------------------------------------------------
94
95 bool wxGUIEventLoop::Pending() const
96 {
97 if (wxTheApp)
98 {
99 // We need to remove idle callbacks or gtk_events_pending will
100 // never return false.
101 wxTheApp->RemoveIdleTag();
102 }
103
104 return gtk_events_pending();
105 }
106
107 bool wxGUIEventLoop::Dispatch()
108 {
109 wxCHECK_MSG( IsRunning(), false, wxT("can't call Dispatch() if not running") );
110
111 gtk_main_iteration();
112
113 return true;
114 }
115
116 //-----------------------------------------------------------------------------
117 // wxYield
118 //-----------------------------------------------------------------------------
119
120 bool wxGUIEventLoop::YieldFor(long eventsToProcess)
121 {
122 #if wxUSE_THREADS
123 if ( !wxThread::IsMain() )
124 {
125 // can't call gtk_main_iteration() from other threads like this
126 return true;
127 }
128 #endif // wxUSE_THREADS
129
130 m_isInsideYield = true;
131 m_eventsToProcessInsideYield = eventsToProcess;
132
133 // We need to remove idle callbacks or the loop will
134 // never finish.
135 wxTheApp->RemoveIdleTag();
136
137 #if wxUSE_LOG
138 // disable log flushing from here because a call to wxYield() shouldn't
139 // normally result in message boxes popping up &c
140 wxLog::Suspend();
141 #endif
142
143 // TODO: implement event filtering using the eventsToProcess mask
144 while (gtk_events_pending())
145 gtk_main_iteration();
146
147 // It's necessary to call ProcessIdle() to update the frames sizes which
148 // might have been changed (it also will update other things set from
149 // OnUpdateUI() which is a nice (and desired) side effect). But we
150 // call ProcessIdle() only once since this is not meant for longish
151 // background jobs (controlled by wxIdleEvent::RequestMore() and the
152 // return value of Processidle().
153 ProcessIdle();
154
155 #if wxUSE_LOG
156 // let the logs be flashed again
157 wxLog::Resume();
158 #endif
159
160 m_isInsideYield = false;
161
162 return true;
163 }