add wx/log.h for non-PCH build
[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 // License: 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, _T("should have been deleted in Run()") );
66 }
67
68 int wxGUIEventLoop::Run()
69 {
70 // event loops are not recursive, you need to create another loop!
71 wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
72
73 wxEventLoopActivator activate(this);
74
75 m_impl = new wxEventLoopImpl;
76
77 gtk_main();
78
79 OnExit();
80
81 int exitcode = m_impl->GetExitCode();
82 delete m_impl;
83 m_impl = NULL;
84
85 return exitcode;
86 }
87
88 void wxGUIEventLoop::Exit(int rc)
89 {
90 wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
91
92 m_impl->SetExitCode(rc);
93
94 gtk_main_quit();
95 }
96
97 // ----------------------------------------------------------------------------
98 // wxEventLoop message processing dispatching
99 // ----------------------------------------------------------------------------
100
101 bool wxGUIEventLoop::Pending() const
102 {
103 if (wxTheApp)
104 {
105 // We need to remove idle callbacks or gtk_events_pending will
106 // never return false.
107 wxTheApp->RemoveIdleTag();
108 }
109
110 return gtk_events_pending();
111 }
112
113 bool wxGUIEventLoop::Dispatch()
114 {
115 wxCHECK_MSG( IsRunning(), false, _T("can't call Dispatch() if not running") );
116
117 gtk_main_iteration();
118
119 return true;
120 }
121
122 //-----------------------------------------------------------------------------
123 // wxYield
124 //-----------------------------------------------------------------------------
125
126 bool wxGUIEventLoop::YieldFor(long eventsToProcess)
127 {
128 #if wxUSE_THREADS
129 if ( !wxThread::IsMain() )
130 {
131 // can't call gtk_main_iteration() from other threads like this
132 return true;
133 }
134 #endif // wxUSE_THREADS
135
136 m_isInsideYield = true;
137 m_eventsToProcessInsideYield = eventsToProcess;
138
139 // We need to remove idle callbacks or the loop will
140 // never finish.
141 wxTheApp->RemoveIdleTag();
142
143 #if wxUSE_LOG
144 // disable log flushing from here because a call to wxYield() shouldn't
145 // normally result in message boxes popping up &c
146 wxLog::Suspend();
147 #endif
148
149 // TODO: implement event filtering using the eventsToProcess mask
150 while (gtk_events_pending())
151 gtk_main_iteration();
152
153 // It's necessary to call ProcessIdle() to update the frames sizes which
154 // might have been changed (it also will update other things set from
155 // OnUpdateUI() which is a nice (and desired) side effect). But we
156 // call ProcessIdle() only once since this is not meant for longish
157 // background jobs (controlled by wxIdleEvent::RequestMore() and the
158 // return value of Processidle().
159 ProcessIdle();
160
161 #if wxUSE_LOG
162 // let the logs be flashed again
163 wxLog::Resume();
164 #endif
165
166 m_isInsideYield = false;
167
168 return true;
169 }