1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/evtloop.cpp
3 // Purpose: wxEventLoop implementation
4 // Author: Vaclav Slavik
6 // Copyright: (c) 2006 REA Elektronik GmbH
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // ===========================================================================
12 // ===========================================================================
14 // ---------------------------------------------------------------------------
16 // ---------------------------------------------------------------------------
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
21 #include "wx/evtloop.h"
28 #include "wx/thread.h"
29 #include "wx/private/fdiodispatcher.h"
30 #include "wx/dfb/private.h"
31 #include "wx/nonownedwnd.h"
32 #include "wx/buffer.h"
36 #define TRACE_EVENTS "events"
38 // ===========================================================================
40 // ===========================================================================
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 // This handler is installed to process input on DirectFB's events socket (
47 // obtained using CreateFileDescriptor()). When IDirectFBEventBuffer is used
48 // in this mode, events are written to the file descriptor and we read them
49 // in OnReadWaiting() below.
50 class wxDFBEventsHandler
: public wxFDIOHandler
54 : m_fd(-1), m_offset(0)
57 void SetFD(int fd
) { m_fd
= fd
; }
65 // implement wxFDIOHandler pure virtual methods
66 virtual void OnReadWaiting();
67 virtual void OnWriteWaiting()
68 { wxFAIL_MSG("OnWriteWaiting shouldn't be called"); }
69 virtual void OnExceptionWaiting()
70 { wxFAIL_MSG("OnExceptionWaiting shouldn't be called"); }
73 // DirectFB -> wxWidgets events translation
74 void HandleDFBEvent(const wxDFBEvent
& event
);
81 void wxDFBEventsHandler::OnReadWaiting()
86 ((char*)&m_event
) + m_offset
,
87 sizeof(m_event
) - m_offset
);
89 if ( size
== 0 || (size
== -1 && (errno
== EAGAIN
|| errno
== EINTR
)) )
91 // nothing left in the pipe (EAGAIN is expected for an FD with
98 wxLogSysError(_("Failed to read event from DirectFB pipe"));
105 if ( size
!= sizeof(m_event
) )
111 HandleDFBEvent(m_event
);
115 void wxDFBEventsHandler::HandleDFBEvent(const wxDFBEvent
& event
)
117 switch ( event
.GetClass() )
121 wxDFBWindowEvent
winevent(((const DFBEvent
&)event
).window
);
122 wxNonOwnedWindow::HandleDFBWindowEvent(winevent
);
129 #if wxCHECK_DFB_VERSION(0,9,23)
133 wxLogTrace(TRACE_EVENTS
,
134 "ignoring event of unsupported class %i",
135 (int)event
.GetClass());
140 //-----------------------------------------------------------------------------
141 // wxEventLoop initialization
142 //-----------------------------------------------------------------------------
144 wxIDirectFBEventBufferPtr
wxGUIEventLoop::ms_buffer
;
145 int wxGUIEventLoop::ms_bufferFd
;
146 static wxDFBEventsHandler gs_DFBEventsHandler
;
148 wxGUIEventLoop::wxGUIEventLoop()
150 // Note that this has to be done here so that the buffer is ready when
151 // an event loop runs; GetDirectFBEventBuffer(), which also calls
152 // InitBuffer(), may be called before or after the first wxGUIEventLoop
153 // instance is created.
159 void wxGUIEventLoop::InitBuffer()
161 // create DirectFB events buffer:
162 ms_buffer
= wxIDirectFB::Get()->CreateEventBuffer();
164 // and setup a file descriptor that we can watch for new events:
166 ms_buffer
->CreateFileDescriptor(&ms_bufferFd
);
167 int flags
= fcntl(ms_bufferFd
, F_GETFL
, 0);
168 if ( flags
== -1 || fcntl(ms_bufferFd
, F_SETFL
, flags
| O_NONBLOCK
) == -1 )
170 wxLogSysError(_("Failed to switch DirectFB pipe to non-blocking mode"));
174 wxFDIODispatcher
*dispatcher
= wxFDIODispatcher::Get();
175 wxCHECK_RET( dispatcher
, "wxDFB requires wxFDIODispatcher" );
177 gs_DFBEventsHandler
.SetFD(ms_bufferFd
);
178 dispatcher
->RegisterFD(ms_bufferFd
, &gs_DFBEventsHandler
, wxFDIO_INPUT
);
182 void wxGUIEventLoop::CleanUp()
184 wxFDIODispatcher
*dispatcher
= wxFDIODispatcher::Get();
185 wxCHECK_RET( dispatcher
, "wxDFB requires wxFDIODispatcher" );
186 dispatcher
->UnregisterFD(ms_bufferFd
);
189 gs_DFBEventsHandler
.Reset();
193 wxIDirectFBEventBufferPtr
wxGUIEventLoop::GetDirectFBEventBuffer()
201 //-----------------------------------------------------------------------------
202 // events dispatch and loop handling
203 //-----------------------------------------------------------------------------
205 bool wxGUIEventLoop::YieldFor(long eventsToProcess
)
208 if ( !wxThread::IsMain() )
209 return true; // can't process events from other threads
210 #endif // wxUSE_THREADS
212 m_isInsideYield
= true;
213 m_eventsToProcessInsideYield
= eventsToProcess
;
219 // TODO: implement event filtering using the eventsToProcess mask
221 // process all pending events:
225 // handle timers, sockets etc.
228 // it's necessary to call ProcessIdle() to update the frames sizes which
229 // might have been changed (it also will update other things set from
230 // OnUpdateUI() which is a nice (and desired) side effect)
231 while ( ProcessIdle() ) {}
237 m_isInsideYield
= false;