///////////////////////////////////////////////////////////////////////////// // Name: src/dfb/evtloop.cpp // Purpose: wxEventLoop implementation // Author: Vaclav Slavik // Created: 2006-08-16 // RCS-ID: $Id: evtloop.cpp 54748 2008-07-21 17:01:35Z VZ $ // Copyright: (c) 2006 REA Elektronik GmbH // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // =========================================================================== // declarations // =========================================================================== // --------------------------------------------------------------------------- // headers // --------------------------------------------------------------------------- // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #include "wx/evtloop.h" #ifndef WX_PRECOMP #include "wx/app.h" #endif #include "wx/thread.h" #include "wx/timer.h" #include "wx/toplevel.h" #include "wx/private/socketevtdispatch.h" #include "wx/dfb/private.h" #define TRACE_EVENTS _T("events") // =========================================================================== // implementation // =========================================================================== //----------------------------------------------------------------------------- // wxEventLoop initialization //----------------------------------------------------------------------------- wxIDirectFBEventBufferPtr wxEventLoop::ms_buffer; wxEventLoop::wxEventLoop() { if ( !ms_buffer ) InitBuffer(); } /* static */ void wxEventLoop::InitBuffer() { ms_buffer = wxIDirectFB::Get()->CreateEventBuffer(); } /* static */ void wxEventLoop::CleanUp() { ms_buffer.Reset(); } /* static */ wxIDirectFBEventBufferPtr wxEventLoop::GetDirectFBEventBuffer() { if ( !ms_buffer ) InitBuffer(); return ms_buffer; } //----------------------------------------------------------------------------- // events dispatch and loop handling //----------------------------------------------------------------------------- bool wxEventLoop::Pending() const { wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") ); return ms_buffer->HasEvent(); } bool wxEventLoop::Dispatch() { wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") ); // NB: we don't block indefinitely waiting for an event, but instead // time out after a brief period in order to make sure that // OnNextIteration() will be called frequently enough const int TIMEOUT = 100; // release the GUI mutex so that other threads have a chance to post // events: wxMutexGuiLeave(); bool rv = ms_buffer->WaitForEventWithTimeout(0, TIMEOUT); // and acquire it back before calling any event handlers: wxMutexGuiEnter(); if ( rv ) { switch ( ms_buffer->GetLastResult() ) { case DFB_OK: { wxDFBEvent e; ms_buffer->GetEvent(e); HandleDFBEvent(e); break; } case DFB_TIMEOUT: // timed out, pretend we processed an event so that // OnNextIteration is called break; default: // don't terminate the loop due to errors (they were reported // already by ms_buffer) break; } } return true; } void wxEventLoop::WakeUp() { wxCHECK_RET( ms_buffer, _T("invalid event buffer") ); ms_buffer->WakeUp(); } void wxEventLoop::OnNextIteration() { #if wxUSE_TIMER wxTimer::NotifyTimers(); #endif #if wxUSE_SOCKETS // handle any pending socket events: wxSocketEventDispatcher::Get().RunLoop(); #endif } void wxEventLoop::Yield() { // process all pending events: while ( Pending() ) Dispatch(); // handle timers, sockets etc. OnNextIteration(); } //----------------------------------------------------------------------------- // DirectFB -> wxWidgets events translation //----------------------------------------------------------------------------- void wxEventLoop::HandleDFBEvent(const wxDFBEvent& event) { switch ( event.GetClass() ) { case DFEC_WINDOW: { wxDFBWindowEvent winevent(((const DFBEvent&)event).window); wxTopLevelWindowDFB::HandleDFBWindowEvent(winevent); break; } case DFEC_NONE: case DFEC_INPUT: case DFEC_USER: #if wxCHECK_DFB_VERSION(0,9,23) case DFEC_UNIVERSAL: #endif { wxLogTrace(TRACE_EVENTS, _T("ignoring event of unsupported class %i"), (int)event.GetClass()); } } }