Make wxEventLoop::AddSourceForFD() static.
[wxWidgets.git] / src / unix / evtloopunix.cpp
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
22 #if wxUSE_CONSOLE_EVENTLOOP
23
24 #include "wx/evtloop.h"
25
26 #ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29 #endif
30
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"
39 #include "wx/private/eventloopsourcesmanager.h"
40 #include "wx/private/fdioeventloopsourcehandler.h"
41 #include "wx/private/eventloopsourcesmanager.h"
42
43 #if wxUSE_EVENTLOOP_SOURCE
44 #include "wx/evtloopsrc.h"
45 #endif // wxUSE_EVENTLOOP_SOURCE
46
47 // ===========================================================================
48 // wxEventLoop implementation
49 // ===========================================================================
50
51 //-----------------------------------------------------------------------------
52 // initialization
53 //-----------------------------------------------------------------------------
54
55 wxConsoleEventLoop::wxConsoleEventLoop()
56 {
57 m_wakeupPipe = new wxWakeUpPipeMT;
58 const int pipeFD = m_wakeupPipe->GetReadFd();
59 if ( pipeFD == wxPipe::INVALID_FD )
60 {
61 wxDELETE(m_wakeupPipe);
62 m_dispatcher = NULL;
63 return;
64 }
65
66 m_dispatcher = wxFDIODispatcher::Get();
67 if ( !m_dispatcher )
68 return;
69
70 m_dispatcher->RegisterFD(pipeFD, m_wakeupPipe, wxFDIO_INPUT);
71 }
72
73 wxConsoleEventLoop::~wxConsoleEventLoop()
74 {
75 if ( m_wakeupPipe )
76 {
77 if ( m_dispatcher )
78 {
79 m_dispatcher->UnregisterFD(m_wakeupPipe->GetReadFd());
80 }
81
82 delete m_wakeupPipe;
83 }
84 }
85
86 //-----------------------------------------------------------------------------
87 // adding & removing sources
88 //-----------------------------------------------------------------------------
89
90 #if wxUSE_EVENTLOOP_SOURCE
91
92 class wxConsoleEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
93 {
94 public:
95 wxEventLoopSource* AddSourceForFD( int fd,
96 wxEventLoopSourceHandler *handler,
97 int flags)
98 {
99 wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
100
101 wxLogTrace(wxTRACE_EVT_SOURCE,
102 "Adding event loop source for fd=%d", fd);
103
104 // we need a bridge to wxFDIODispatcher
105 //
106 // TODO: refactor the code so that only wxEventLoopSourceHandler is used
107 wxScopedPtr<wxFDIOHandler>
108 fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
109
110 if ( !wxFDIODispatcher::Get()->RegisterFD(fd, fdioHandler.get(), flags) )
111 return NULL;
112
113 return new wxUnixEventLoopSource(wxFDIODispatcher::Get(), fdioHandler.release(),
114 fd, handler, flags);
115 }
116 };
117
118 wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
119 {
120 static wxConsoleEventLoopSourcesManager s_eventLoopSourcesManager;
121
122 return &s_eventLoopSourcesManager;
123 }
124
125 wxUnixEventLoopSource::~wxUnixEventLoopSource()
126 {
127 wxLogTrace(wxTRACE_EVT_SOURCE,
128 "Removing event loop source for fd=%d", m_fd);
129
130 m_dispatcher->UnregisterFD(m_fd);
131
132 delete m_fdioHandler;
133 }
134
135 #endif // wxUSE_EVENTLOOP_SOURCE
136
137 //-----------------------------------------------------------------------------
138 // events dispatch and loop handling
139 //-----------------------------------------------------------------------------
140
141 bool wxConsoleEventLoop::Pending() const
142 {
143 if ( m_dispatcher->HasPending() )
144 return true;
145
146 #if wxUSE_TIMER
147 wxUsecClock_t nextTimer;
148 if ( wxTimerScheduler::Get().GetNext(&nextTimer) &&
149 !wxMilliClockToLong(nextTimer) )
150 return true;
151 #endif // wxUSE_TIMER
152
153 return false;
154 }
155
156 bool wxConsoleEventLoop::Dispatch()
157 {
158 DispatchTimeout(static_cast<unsigned long>(
159 wxFDIODispatcher::TIMEOUT_INFINITE));
160
161 return true;
162 }
163
164 int wxConsoleEventLoop::DispatchTimeout(unsigned long timeout)
165 {
166 #if wxUSE_TIMER
167 // check if we need to decrease the timeout to account for a timer
168 wxUsecClock_t nextTimer;
169 if ( wxTimerScheduler::Get().GetNext(&nextTimer) )
170 {
171 unsigned long timeUntilNextTimer = wxMilliClockToLong(nextTimer / 1000);
172 if ( timeUntilNextTimer < timeout )
173 timeout = timeUntilNextTimer;
174 }
175 #endif // wxUSE_TIMER
176
177 bool hadEvent = m_dispatcher->Dispatch(timeout) > 0;
178
179 #if wxUSE_TIMER
180 if ( wxTimerScheduler::Get().NotifyExpired() )
181 hadEvent = true;
182 #endif // wxUSE_TIMER
183
184 return hadEvent ? 1 : -1;
185 }
186
187 void wxConsoleEventLoop::WakeUp()
188 {
189 m_wakeupPipe->WakeUp();
190 }
191
192 void wxConsoleEventLoop::OnNextIteration()
193 {
194 // call the signal handlers for any signals we caught recently
195 wxTheApp->CheckSignal();
196 }
197
198
199 wxEventLoopBase *wxConsoleAppTraits::CreateEventLoop()
200 {
201 return new wxEventLoop();
202 }
203
204 #endif // wxUSE_CONSOLE_EVENTLOOP