+
+//-----------------------------------------------------------------------------
+// wxEventLoop initialization
+//-----------------------------------------------------------------------------
+
+wxIDirectFBEventBufferPtr wxGUIEventLoop::ms_buffer;
+int wxGUIEventLoop::ms_bufferFd;
+static wxDFBEventsHandler gs_DFBEventsHandler;
+
+wxGUIEventLoop::wxGUIEventLoop()
+{
+ // Note that this has to be done here so that the buffer is ready when
+ // an event loop runs; GetDirectFBEventBuffer(), which also calls
+ // InitBuffer(), may be called before or after the first wxGUIEventLoop
+ // instance is created.
+ if ( !ms_buffer )
+ InitBuffer();
+}
+
+/* static */
+void wxGUIEventLoop::InitBuffer()
+{
+ // create DirectFB events buffer:
+ ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
+
+ // and setup a file descriptor that we can watch for new events:
+
+ ms_buffer->CreateFileDescriptor(&ms_bufferFd);
+ int flags = fcntl(ms_bufferFd, F_GETFL, 0);
+ if ( flags == -1 || fcntl(ms_bufferFd, F_SETFL, flags | O_NONBLOCK) == -1 )
+ {
+ wxLogSysError(_("Failed to switch DirectFB pipe to non-blocking mode"));
+ return;
+ }
+
+ wxFDIODispatcher *dispatcher = wxFDIODispatcher::Get();
+ wxCHECK_RET( dispatcher, "wxDFB requires wxFDIODispatcher" );
+
+ gs_DFBEventsHandler.SetFD(ms_bufferFd);
+ dispatcher->RegisterFD(ms_bufferFd, &gs_DFBEventsHandler, wxFDIO_INPUT);
+}
+
+/* static */
+void wxGUIEventLoop::CleanUp()
+{
+ wxFDIODispatcher *dispatcher = wxFDIODispatcher::Get();
+ wxCHECK_RET( dispatcher, "wxDFB requires wxFDIODispatcher" );
+ dispatcher->UnregisterFD(ms_bufferFd);
+
+ ms_buffer.Reset();
+ gs_DFBEventsHandler.Reset();
+}
+
+/* static */
+wxIDirectFBEventBufferPtr wxGUIEventLoop::GetDirectFBEventBuffer()
+{
+ if ( !ms_buffer )
+ InitBuffer();
+
+ return ms_buffer;
+}
+
+//-----------------------------------------------------------------------------
+// events dispatch and loop handling
+//-----------------------------------------------------------------------------
+
+bool wxGUIEventLoop::YieldFor(long eventsToProcess)
+{
+#if wxUSE_THREADS
+ if ( !wxThread::IsMain() )
+ return true; // can't process events from other threads
+#endif // wxUSE_THREADS
+
+ m_isInsideYield = true;
+ m_eventsToProcessInsideYield = eventsToProcess;
+
+#if wxUSE_LOG
+ wxLog::Suspend();
+#endif // wxUSE_LOG
+
+ // TODO: implement event filtering using the eventsToProcess mask
+
+ // process all pending events:
+ while ( Pending() )
+ Dispatch();
+
+ // handle timers, sockets etc.
+ OnNextIteration();
+
+ // it's necessary to call ProcessIdle() to update the frames sizes which
+ // might have been changed (it also will update other things set from
+ // OnUpdateUI() which is a nice (and desired) side effect)
+ while ( ProcessIdle() ) {}
+
+#if wxUSE_LOG
+ wxLog::Resume();
+#endif // wxUSE_LOG
+
+ m_isInsideYield = false;
+
+ return true;
+}