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