]> git.saurik.com Git - wxWidgets.git/blame - src/unix/evtloopunix.cpp
Treat G_IO_HUP as read, not error, event because EOF is not exceptional.
[wxWidgets.git] / src / unix / evtloopunix.cpp
CommitLineData
b46b1d59
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/unix/evtloopunix.cpp
3// Purpose: wxEventLoop implementation
4// Author: Lukasz Michalski (lm@zork.pl)
5// Created: 2007-05-07
6// RCS-ID: $Id$
7// Copyright: (c) 2006 Zork Lukasz Michalski
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ===========================================================================
12// declarations
13// ===========================================================================
14
15// ---------------------------------------------------------------------------
16// headers
17// ---------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
a1873279 22#if wxUSE_CONSOLE_EVENTLOOP
b46b1d59 23
1e04d2bf
PC
24#include "wx/evtloop.h"
25
b46b1d59
VZ
26#ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29#endif
30
37ab9399 31#include "wx/apptrait.h"
5cd99866 32#include "wx/scopedptr.h"
b46b1d59
VZ
33#include "wx/thread.h"
34#include "wx/module.h"
ba752031 35#include "wx/unix/private/timer.h"
b46b1d59 36#include "wx/unix/private/epolldispatcher.h"
2ccfebab 37#include "wx/unix/private/wakeuppipe.h"
b46b1d59 38#include "wx/private/selectdispatcher.h"
71e9885b 39#include "wx/private/eventloopsourcesmanager.h"
5e382463 40#include "wx/private/fdioeventloopsourcehandler.h"
71e9885b 41#include "wx/private/eventloopsourcesmanager.h"
b46b1d59 42
5cd99866
VZ
43#if wxUSE_EVENTLOOP_SOURCE
44 #include "wx/evtloopsrc.h"
45#endif // wxUSE_EVENTLOOP_SOURCE
46
b46b1d59
VZ
47// ===========================================================================
48// wxEventLoop implementation
49// ===========================================================================
50
51//-----------------------------------------------------------------------------
52// initialization
53//-----------------------------------------------------------------------------
54
55wxConsoleEventLoop::wxConsoleEventLoop()
56{
39bc0168
VZ
57 // Be pessimistic initially and assume that we failed to initialize.
58 m_dispatcher = NULL;
59 m_wakeupPipe = NULL;
60 m_wakeupSource = NULL;
61
62 // Create the pipe.
63 wxScopedPtr<wxWakeUpPipeMT> wakeupPipe(new wxWakeUpPipeMT);
64 const int pipeFD = wakeupPipe->GetReadFd();
2ccfebab 65 if ( pipeFD == wxPipe::INVALID_FD )
b46b1d59 66 return;
b46b1d59 67
39bc0168
VZ
68 // And start monitoring it in our event loop.
69 m_wakeupSource = wxEventLoopBase::AddSourceForFD
70 (
71 pipeFD,
72 wakeupPipe.get(),
73 wxFDIO_INPUT
74 );
75
76 if ( !m_wakeupSource )
5e1eac14 77 return;
b46b1d59 78
39bc0168
VZ
79 // This is a bit ugly but we know that AddSourceForFD() used the currently
80 // active dispatcher to register this source, so use the same one for our
81 // other operations. Of course, currently the dispatcher returned by
82 // wxFDIODispatcher::Get() is always the same one anyhow so it doesn't
83 // really matter, but if we started returning different things later, it
84 // would.
85 m_dispatcher = wxFDIODispatcher::Get();
86
87 m_wakeupPipe = wakeupPipe.release();
3ef595d5 88}
b46b1d59 89
3f8cdda4
VS
90wxConsoleEventLoop::~wxConsoleEventLoop()
91{
c8299fa8
VZ
92 if ( m_wakeupPipe )
93 {
39bc0168 94 delete m_wakeupSource;
c8299fa8
VZ
95
96 delete m_wakeupPipe;
97 }
3f8cdda4
VS
98}
99
6b8ef0b3
VZ
100//-----------------------------------------------------------------------------
101// adding & removing sources
102//-----------------------------------------------------------------------------
103
104#if wxUSE_EVENTLOOP_SOURCE
105
71e9885b 106class wxConsoleEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
6b8ef0b3 107{
71e9885b
VZ
108public:
109 wxEventLoopSource* AddSourceForFD( int fd,
110 wxEventLoopSourceHandler *handler,
111 int flags)
112 {
113 wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
6b8ef0b3 114
71e9885b
VZ
115 wxLogTrace(wxTRACE_EVT_SOURCE,
116 "Adding event loop source for fd=%d", fd);
117
118 // we need a bridge to wxFDIODispatcher
119 //
120 // TODO: refactor the code so that only wxEventLoopSourceHandler is used
121 wxScopedPtr<wxFDIOHandler>
122 fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
6b8ef0b3 123
71e9885b
VZ
124 if ( !wxFDIODispatcher::Get()->RegisterFD(fd, fdioHandler.get(), flags) )
125 return NULL;
6b8ef0b3 126
71e9885b
VZ
127 return new wxUnixEventLoopSource(wxFDIODispatcher::Get(), fdioHandler.release(),
128 fd, handler, flags);
129 }
130};
131
132wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
133{
134 static wxConsoleEventLoopSourcesManager s_eventLoopSourcesManager;
5cd99866 135
71e9885b 136 return &s_eventLoopSourcesManager;
6b8ef0b3
VZ
137}
138
5cd99866 139wxUnixEventLoopSource::~wxUnixEventLoopSource()
6b8ef0b3 140{
6b8ef0b3 141 wxLogTrace(wxTRACE_EVT_SOURCE,
5cd99866 142 "Removing event loop source for fd=%d", m_fd);
6b8ef0b3 143
5cd99866
VZ
144 m_dispatcher->UnregisterFD(m_fd);
145
146 delete m_fdioHandler;
6b8ef0b3 147}
5cd99866
VZ
148
149#endif // wxUSE_EVENTLOOP_SOURCE
6b8ef0b3 150
b46b1d59
VZ
151//-----------------------------------------------------------------------------
152// events dispatch and loop handling
153//-----------------------------------------------------------------------------
154
155bool wxConsoleEventLoop::Pending() const
156{
a12698ab
VZ
157 if ( m_dispatcher->HasPending() )
158 return true;
159
160#if wxUSE_TIMER
161 wxUsecClock_t nextTimer;
162 if ( wxTimerScheduler::Get().GetNext(&nextTimer) &&
163 !wxMilliClockToLong(nextTimer) )
164 return true;
165#endif // wxUSE_TIMER
166
167 return false;
b46b1d59
VZ
168}
169
170bool wxConsoleEventLoop::Dispatch()
b46b1d59 171{
c22ace4d
VZ
172 DispatchTimeout(static_cast<unsigned long>(
173 wxFDIODispatcher::TIMEOUT_INFINITE));
b46b1d59 174
9af42efd
VZ
175 return true;
176}
177
178int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout)
179{
b46b1d59 180#if wxUSE_TIMER
9af42efd 181 // check if we need to decrease the timeout to account for a timer
b46b1d59
VZ
182 wxUsecClock_t nextTimer;
183 if ( wxTimerScheduler::Get().GetNext(&nextTimer) )
184 {
9af42efd
VZ
185 unsigned long timeUntilNextTimer = wxMilliClockToLong(nextTimer / 1000);
186 if ( timeUntilNextTimer < timeout )
187 timeout = timeUntilNextTimer;
b46b1d59 188 }
b46b1d59 189#endif // wxUSE_TIMER
b46b1d59 190
a12698ab 191 bool hadEvent = m_dispatcher->Dispatch(timeout) > 0;
b46b1d59
VZ
192
193#if wxUSE_TIMER
9af42efd
VZ
194 if ( wxTimerScheduler::Get().NotifyExpired() )
195 hadEvent = true;
196#endif // wxUSE_TIMER
b46b1d59 197
9af42efd 198 return hadEvent ? 1 : -1;
438febca
VZ
199}
200
201void wxConsoleEventLoop::WakeUp()
202{
3f8cdda4 203 m_wakeupPipe->WakeUp();
438febca
VZ
204}
205
206void wxConsoleEventLoop::OnNextIteration()
207{
b46b1d59
VZ
208 // call the signal handlers for any signals we caught recently
209 wxTheApp->CheckSignal();
210}
211
37ab9399
SN
212
213wxEventLoopBase *wxConsoleAppTraits::CreateEventLoop()
214{
215 return new wxEventLoop();
216}
217
a1873279 218#endif // wxUSE_CONSOLE_EVENTLOOP