1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/evtloopunix.cpp
3 // Purpose: wxEventLoop implementation
4 // Author: Lukasz Michalski (lm@zork.pl)
7 // Copyright: (c) 2006 Zork Lukasz Michalski
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #if wxUSE_CONSOLE_EVENTLOOP
24 #include "wx/evtloop.h"
31 #include "wx/apptrait.h"
32 #include "wx/scopedptr.h"
33 #include "wx/thread.h"
34 #include "wx/module.h"
35 #include "wx/unix/private/timer.h"
36 #include "wx/unix/private/epolldispatcher.h"
37 #include "wx/unix/private/wakeuppipe.h"
38 #include "wx/private/selectdispatcher.h"
40 #if wxUSE_EVENTLOOP_SOURCE
41 #include "wx/evtloopsrc.h"
42 #endif // wxUSE_EVENTLOOP_SOURCE
44 // ===========================================================================
45 // wxEventLoop implementation
46 // ===========================================================================
48 //-----------------------------------------------------------------------------
50 //-----------------------------------------------------------------------------
52 wxConsoleEventLoop::wxConsoleEventLoop()
54 m_wakeupPipe
= new wxWakeUpPipeMT
;
55 const int pipeFD
= m_wakeupPipe
->GetReadFd();
56 if ( pipeFD
== wxPipe::INVALID_FD
)
58 wxDELETE(m_wakeupPipe
);
63 m_dispatcher
= wxFDIODispatcher::Get();
67 m_dispatcher
->RegisterFD(pipeFD
, m_wakeupPipe
, wxFDIO_INPUT
);
70 wxConsoleEventLoop::~wxConsoleEventLoop()
76 m_dispatcher
->UnregisterFD(m_wakeupPipe
->GetReadFd());
83 //-----------------------------------------------------------------------------
84 // adding & removing sources
85 //-----------------------------------------------------------------------------
87 #if wxUSE_EVENTLOOP_SOURCE
89 // This class is a temporary bridge between event loop sources and
90 // FDIODispatcher. It is going to be removed soon, when all subject interfaces
92 class wxFDIOEventLoopSourceHandler
: public wxFDIOHandler
95 wxFDIOEventLoopSourceHandler(wxEventLoopSourceHandler
* handler
) :
98 virtual void OnReadWaiting()
100 m_impl
->OnReadWaiting();
102 virtual void OnWriteWaiting()
104 m_impl
->OnWriteWaiting();
107 virtual void OnExceptionWaiting()
109 m_impl
->OnExceptionWaiting();
113 wxEventLoopSourceHandler
* m_impl
;
117 wxConsoleEventLoop::AddSourceForFD(int fd
,
118 wxEventLoopSourceHandler
*handler
,
121 wxCHECK_MSG( fd
!= -1, NULL
, "can't monitor invalid fd" );
123 wxLogTrace(wxTRACE_EVT_SOURCE
,
124 "Adding event loop source for fd=%d", fd
);
126 // we need a bridge to wxFDIODispatcher
128 // TODO: refactor the code so that only wxEventLoopSourceHandler is used
129 wxScopedPtr
<wxFDIOHandler
>
130 fdioHandler(new wxFDIOEventLoopSourceHandler(handler
));
132 if ( !m_dispatcher
->RegisterFD(fd
, fdioHandler
.get(), flags
) )
135 return new wxUnixEventLoopSource(m_dispatcher
, fdioHandler
.release(),
139 wxUnixEventLoopSource::~wxUnixEventLoopSource()
141 wxLogTrace(wxTRACE_EVT_SOURCE
,
142 "Removing event loop source for fd=%d", m_fd
);
144 m_dispatcher
->UnregisterFD(m_fd
);
146 delete m_fdioHandler
;
149 #endif // wxUSE_EVENTLOOP_SOURCE
151 //-----------------------------------------------------------------------------
152 // events dispatch and loop handling
153 //-----------------------------------------------------------------------------
155 bool wxConsoleEventLoop::Pending() const
157 if ( m_dispatcher
->HasPending() )
161 wxUsecClock_t nextTimer
;
162 if ( wxTimerScheduler::Get().GetNext(&nextTimer
) &&
163 !wxMilliClockToLong(nextTimer
) )
165 #endif // wxUSE_TIMER
170 bool wxConsoleEventLoop::Dispatch()
172 DispatchTimeout(static_cast<unsigned long>(
173 wxFDIODispatcher::TIMEOUT_INFINITE
));
178 int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout
)
181 // check if we need to decrease the timeout to account for a timer
182 wxUsecClock_t nextTimer
;
183 if ( wxTimerScheduler::Get().GetNext(&nextTimer
) )
185 unsigned long timeUntilNextTimer
= wxMilliClockToLong(nextTimer
/ 1000);
186 if ( timeUntilNextTimer
< timeout
)
187 timeout
= timeUntilNextTimer
;
189 #endif // wxUSE_TIMER
191 bool hadEvent
= m_dispatcher
->Dispatch(timeout
) > 0;
194 if ( wxTimerScheduler::Get().NotifyExpired() )
196 #endif // wxUSE_TIMER
198 return hadEvent
? 1 : -1;
201 void wxConsoleEventLoop::WakeUp()
203 m_wakeupPipe
->WakeUp();
206 void wxConsoleEventLoop::OnNextIteration()
208 // call the signal handlers for any signals we caught recently
209 wxTheApp
->CheckSignal();
213 wxEventLoopBase
*wxConsoleAppTraits::CreateEventLoop()
215 return new wxEventLoop();
218 #endif // wxUSE_CONSOLE_EVENTLOOP