1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/evtloop.cpp
3 // Purpose: wxEventLoop implementation
4 // Author: Vaclav Slavik
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #include "wx/evtloop.h"
29 #include "wx/thread.h"
30 #include "wx/private/fdiodispatcher.h"
31 #include "wx/dfb/private.h"
32 #include "wx/nonownedwnd.h"
33 #include "wx/buffer.h"
37 #define TRACE_EVENTS "events"
39 // ===========================================================================
41 // ===========================================================================
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
47 // This handler is installed to process input on DirectFB's events socket (
48 // obtained using CreateFileDescriptor()). When IDirectFBEventBuffer is used
49 // in this mode, events are written to the file descriptor and we read them
50 // in OnReadWaiting() below.
51 class wxDFBEventsHandler
: public wxFDIOHandler
55 : m_fd(-1), m_offset(0)
58 void SetFD(int fd
) { m_fd
= fd
; }
66 // implement wxFDIOHandler pure virtual methods
67 virtual void OnReadWaiting();
68 virtual void OnWriteWaiting()
69 { wxFAIL_MSG("OnWriteWaiting shouldn't be called"); }
70 virtual void OnExceptionWaiting()
71 { wxFAIL_MSG("OnExceptionWaiting shouldn't be called"); }
74 // DirectFB -> wxWidgets events translation
75 void HandleDFBEvent(const wxDFBEvent
& event
);
82 void wxDFBEventsHandler::OnReadWaiting()
87 ((char*)&m_event
) + m_offset
,
88 sizeof(m_event
) - m_offset
);
90 if ( size
== 0 || (size
== -1 && (errno
== EAGAIN
|| errno
== EINTR
)) )
92 // nothing left in the pipe (EAGAIN is expected for an FD with
99 wxLogSysError(_("Failed to read event from DirectFB pipe"));
106 if ( size
!= sizeof(m_event
) )
112 HandleDFBEvent(m_event
);
116 void wxDFBEventsHandler::HandleDFBEvent(const wxDFBEvent
& event
)
118 switch ( event
.GetClass() )
122 wxDFBWindowEvent
winevent(((const DFBEvent
&)event
).window
);
123 wxNonOwnedWindow::HandleDFBWindowEvent(winevent
);
130 #if wxCHECK_DFB_VERSION(0,9,23)
134 wxLogTrace(TRACE_EVENTS
,
135 "ignoring event of unsupported class %i",
136 (int)event
.GetClass());
141 //-----------------------------------------------------------------------------
142 // wxEventLoop initialization
143 //-----------------------------------------------------------------------------
145 wxIDirectFBEventBufferPtr
wxGUIEventLoop::ms_buffer
;
146 int wxGUIEventLoop::ms_bufferFd
;
147 static wxDFBEventsHandler gs_DFBEventsHandler
;
149 wxGUIEventLoop::wxGUIEventLoop()
151 // Note that this has to be done here so that the buffer is ready when
152 // an event loop runs; GetDirectFBEventBuffer(), which also calls
153 // InitBuffer(), may be called before or after the first wxGUIEventLoop
154 // instance is created.
160 void wxGUIEventLoop::InitBuffer()
162 // create DirectFB events buffer:
163 ms_buffer
= wxIDirectFB::Get()->CreateEventBuffer();
165 // and setup a file descriptor that we can watch for new events:
167 ms_buffer
->CreateFileDescriptor(&ms_bufferFd
);
168 int flags
= fcntl(ms_bufferFd
, F_GETFL
, 0);
169 if ( flags
== -1 || fcntl(ms_bufferFd
, F_SETFL
, flags
| O_NONBLOCK
) == -1 )
171 wxLogSysError(_("Failed to switch DirectFB pipe to non-blocking mode"));
175 wxFDIODispatcher
*dispatcher
= wxFDIODispatcher::Get();
176 wxCHECK_RET( dispatcher
, "wxDFB requires wxFDIODispatcher" );
178 gs_DFBEventsHandler
.SetFD(ms_bufferFd
);
179 dispatcher
->RegisterFD(ms_bufferFd
, &gs_DFBEventsHandler
, wxFDIO_INPUT
);
183 void wxGUIEventLoop::CleanUp()
185 wxFDIODispatcher
*dispatcher
= wxFDIODispatcher::Get();
186 wxCHECK_RET( dispatcher
, "wxDFB requires wxFDIODispatcher" );
187 dispatcher
->UnregisterFD(ms_bufferFd
);
190 gs_DFBEventsHandler
.Reset();
194 wxIDirectFBEventBufferPtr
wxGUIEventLoop::GetDirectFBEventBuffer()
202 //-----------------------------------------------------------------------------
203 // events dispatch and loop handling
204 //-----------------------------------------------------------------------------
206 bool wxGUIEventLoop::YieldFor(long eventsToProcess
)
209 if ( !wxThread::IsMain() )
210 return true; // can't process events from other threads
211 #endif // wxUSE_THREADS
213 m_isInsideYield
= true;
214 m_eventsToProcessInsideYield
= eventsToProcess
;
220 // TODO: implement event filtering using the eventsToProcess mask
222 // process all pending events:
226 // handle timers, sockets etc.
229 // it's necessary to call ProcessIdle() to update the frames sizes which
230 // might have been changed (it also will update other things set from
231 // OnUpdateUI() which is a nice (and desired) side effect)
232 while ( ProcessIdle() ) {}
238 m_isInsideYield
= false;