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