]> git.saurik.com Git - wxWidgets.git/blame - src/x11/evtloop.cpp
wxDC::DoDrawRectangle hack is no longer needed
[wxWidgets.git] / src / x11 / evtloop.cpp
CommitLineData
1b0fb34b
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: x11/evtloop.cpp
3// Purpose: implements wxEventLoop for X11
4// Author: Julian Smart
5// Modified by:
6// Created: 01.06.01
7// RCS-ID: $Id$
8// Copyright: (c) 2002 Julian Smart
9// License: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "evtloop.h"
22#endif
23
24#include "wx/window.h"
25#include "wx/app.h"
26#include "wx/evtloop.h"
27#include "wx/tooltip.h"
7266b672
JS
28#if wxUSE_THREADS
29#include "wx/thread.h"
30#endif
1b0fb34b
JS
31#include "wx/x11/private.h"
32#include "X11/Xlib.h"
33
34// ----------------------------------------------------------------------------
35// wxEventLoopImpl
36// ----------------------------------------------------------------------------
37
38class WXDLLEXPORT wxEventLoopImpl
39{
40public:
41 // ctor
42 wxEventLoopImpl() { SetExitCode(0); m_keepGoing = FALSE; }
43
44 // process an XEvent
45 void ProcessEvent(XEvent* event);
46
47 // generate an idle message, return TRUE if more idle time requested
48 bool SendIdleEvent();
49
50 // set/get the exit code
51 void SetExitCode(int exitcode) { m_exitcode = exitcode; }
52 int GetExitCode() const { return m_exitcode; }
53
54public:
55 // preprocess an event, return TRUE if processed (i.e. no further
56 // dispatching required)
7266b672 57 bool PreProcessEvent(XEvent* event);
1b0fb34b
JS
58
59 // the exit code of the event loop
60 int m_exitcode;
61
62 bool m_keepGoing;
63};
64
65// ============================================================================
66// wxEventLoopImpl implementation
67// ============================================================================
68
69// ----------------------------------------------------------------------------
70// wxEventLoopImpl message processing
71// ----------------------------------------------------------------------------
72
73void wxEventLoopImpl::ProcessEvent(XEvent *event)
74{
75 // give us the chance to preprocess the message first
76 if ( !PreProcessEvent(event) )
77 {
78 // if it wasn't done, dispatch it to the corresponding window
79 if (wxTheApp)
80 wxTheApp->ProcessXEvent((WXEvent*) event);
81 }
82}
83
84bool wxEventLoopImpl::PreProcessEvent(XEvent *event)
85{
86 // TODO
87#if 0
88 HWND hWnd = msg->hwnd;
89 wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd);
90
91
92 // try translations first; find the youngest window with a translation
93 // table.
94 wxWindow *wnd;
95 for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
96 {
97 if ( wnd->MSWTranslateMessage((WXMSG *)msg) )
98 return TRUE;
99 }
100
101 // Anyone for a non-translation message? Try youngest descendants first.
102 for ( wnd = wndThis; wnd; wnd = wnd->GetParent() )
103 {
104 if ( wnd->MSWProcessMessage((WXMSG *)msg) )
105 return TRUE;
106 }
107#endif
108
109 return FALSE;
110}
111
112// ----------------------------------------------------------------------------
113// wxEventLoopImpl idle event processing
114// ----------------------------------------------------------------------------
115
116bool wxEventLoopImpl::SendIdleEvent()
117{
118 wxIdleEvent event;
119 event.SetEventObject(wxTheApp);
120
121 return wxTheApp->ProcessEvent(event) && event.MoreRequested();
122}
123
124// ============================================================================
125// wxEventLoop implementation
126// ============================================================================
127
128wxEventLoop *wxEventLoop::ms_activeLoop = NULL;
129
130// ----------------------------------------------------------------------------
131// wxEventLoop running and exiting
132// ----------------------------------------------------------------------------
133
134wxEventLoop::~wxEventLoop()
135{
136 wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
137}
138
139bool wxEventLoop::IsRunning() const
140{
141 return m_impl != NULL;
142}
143
144int wxEventLoop::Run()
145{
146 // event loops are not recursive, you need to create another loop!
147 wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
148
149 m_impl = new wxEventLoopImpl;
150
151 wxEventLoop *oldLoop = ms_activeLoop;
152 ms_activeLoop = this;
153
154 m_impl->m_keepGoing = TRUE;
155 while ( m_impl->m_keepGoing )
156 {
7266b672
JS
157#if 0 // wxUSE_THREADS
158 wxMutexGuiLeaveOrEnter();
1b0fb34b
JS
159#endif // wxUSE_THREADS
160
161 // generate and process idle events for as long as we don't have
162 // anything else to do
163 while ( ! Pending() )
164 {
165 if (!m_impl->SendIdleEvent())
166 {
7266b672 167#if 0 // wxUSE_THREADS
1b0fb34b
JS
168 // leave the main loop to give other threads a chance to
169 // perform their GUI work
170 wxMutexGuiLeave();
171 wxUsleep(20);
172 wxMutexGuiEnter();
173#endif
174 // Break out of while loop
175 break;
176 }
177 }
178
179 // a message came or no more idle processing to do, sit in Dispatch()
180 // waiting for the next message
181 if ( !Dispatch() )
182 {
183 break;
184 }
185 }
186
187 int exitcode = m_impl->GetExitCode();
188 delete m_impl;
189 m_impl = NULL;
190
191 ms_activeLoop = oldLoop;
192
193 return exitcode;
194}
195
196void wxEventLoop::Exit(int rc)
197{
198 wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
199
200 m_impl->SetExitCode(rc);
201 m_impl->m_keepGoing = FALSE;
202}
203
204// ----------------------------------------------------------------------------
205// wxEventLoop message processing dispatching
206// ----------------------------------------------------------------------------
207
208bool wxEventLoop::Pending() const
209{
7266b672
JS
210 XFlush((Display*) wxGetDisplay());
211 return (XPending((Display*) wxGetDisplay()) > 0);
1b0fb34b
JS
212}
213
214bool wxEventLoop::Dispatch()
215{
216 XEvent event;
217
218 // TODO allowing for threads, as per e.g. wxMSW
219
7266b672 220 XNextEvent((Display*) wxGetDisplay(), & event);
1b0fb34b
JS
221 m_impl->ProcessEvent(& event);
222 return TRUE;
223}
224