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