monodll_generic_icon.o \
monodll_generic_imaglist.o \
monodll_mask.o \
- monodll_generic_timer.o \
monodll_dfb_app.o \
monodll_dfb_bitmap.o \
monodll_dfb_brush.o \
monodll_generic_icon.o \
monodll_generic_imaglist.o \
monodll_mask.o \
- monodll_generic_timer.o \
monodll_dfb_app.o \
monodll_dfb_bitmap.o \
monodll_dfb_brush.o \
monolib_generic_icon.o \
monolib_generic_imaglist.o \
monolib_mask.o \
- monolib_generic_timer.o \
monolib_dfb_app.o \
monolib_dfb_bitmap.o \
monolib_dfb_brush.o \
monolib_generic_icon.o \
monolib_generic_imaglist.o \
monolib_mask.o \
- monolib_generic_timer.o \
monolib_dfb_app.o \
monolib_dfb_bitmap.o \
monolib_dfb_brush.o \
coredll_generic_icon.o \
coredll_generic_imaglist.o \
coredll_mask.o \
- coredll_generic_timer.o \
coredll_dfb_app.o \
coredll_dfb_bitmap.o \
coredll_dfb_brush.o \
coredll_generic_icon.o \
coredll_generic_imaglist.o \
coredll_mask.o \
- coredll_generic_timer.o \
coredll_dfb_app.o \
coredll_dfb_bitmap.o \
coredll_dfb_brush.o \
corelib_generic_icon.o \
corelib_generic_imaglist.o \
corelib_mask.o \
- corelib_generic_timer.o \
corelib_dfb_app.o \
corelib_dfb_bitmap.o \
corelib_dfb_brush.o \
corelib_generic_icon.o \
corelib_generic_imaglist.o \
corelib_mask.o \
- corelib_generic_timer.o \
corelib_dfb_app.o \
corelib_dfb_bitmap.o \
corelib_dfb_brush.o \
@COND_TOOLKIT_MGL_USE_GUI_1@monodll_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(MONODLL_ODEP)
@COND_TOOLKIT_MGL_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-@COND_TOOLKIT_DFB_USE_GUI_1@monodll_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(MONODLL_ODEP)
-@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-
@COND_TOOLKIT_X11_USE_GUI_1@monodll_x11_app.o: $(srcdir)/src/x11/app.cpp $(MONODLL_ODEP)
@COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/x11/app.cpp
@COND_TOOLKIT_MGL_USE_GUI_1@monolib_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(MONOLIB_ODEP)
@COND_TOOLKIT_MGL_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-@COND_TOOLKIT_DFB_USE_GUI_1@monolib_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(MONOLIB_ODEP)
-@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-
@COND_TOOLKIT_X11_USE_GUI_1@monolib_x11_app.o: $(srcdir)/src/x11/app.cpp $(MONOLIB_ODEP)
@COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/x11/app.cpp
@COND_TOOLKIT_MGL_USE_GUI_1@coredll_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(COREDLL_ODEP)
@COND_TOOLKIT_MGL_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-@COND_TOOLKIT_DFB_USE_GUI_1@coredll_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(COREDLL_ODEP)
-@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-
@COND_TOOLKIT_X11_USE_GUI_1@coredll_x11_app.o: $(srcdir)/src/x11/app.cpp $(COREDLL_ODEP)
@COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/x11/app.cpp
@COND_TOOLKIT_MGL_USE_GUI_1@corelib_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(CORELIB_ODEP)
@COND_TOOLKIT_MGL_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-@COND_TOOLKIT_DFB_USE_GUI_1@corelib_generic_timer.o: $(srcdir)/src/generic/timer.cpp $(CORELIB_ODEP)
-@COND_TOOLKIT_DFB_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/timer.cpp
-
@COND_TOOLKIT_X11_USE_GUI_1@corelib_x11_app.o: $(srcdir)/src/x11/app.cpp $(CORELIB_ODEP)
@COND_TOOLKIT_X11_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/x11/app.cpp
#endif
#include "wx/thread.h"
-#include "wx/generic/private/timer.h"
#include "wx/private/fdiodispatcher.h"
#include "wx/dfb/private.h"
#include "wx/nonownedwnd.h"
+#include "wx/buffer.h"
#define TRACE_EVENTS "events"
// implementation
// ===========================================================================
+//-----------------------------------------------------------------------------
+// wxDFBEventsHandler
+//-----------------------------------------------------------------------------
+
+// This handler is installed to process input on DirectFB's events socket (
+// obtained using CreateFileDescriptor()). When IDirectFBEventBuffer is used
+// in this mode, events are written to the file descriptor and we read them
+// in OnReadWaiting() below.
+class wxDFBEventsHandler : public wxFDIOHandler
+{
+public:
+ wxDFBEventsHandler()
+ : m_fd(-1), m_offset(0)
+ {}
+
+ void SetFD(int fd) { m_fd = fd; }
+
+ void Reset()
+ {
+ m_fd = -1;
+ m_offset = 0;
+ }
+
+ // implement wxFDIOHandler pure virtual methods
+ virtual void OnReadWaiting();
+ virtual void OnWriteWaiting()
+ { wxFAIL_MSG("OnWriteWaiting shouldn't be called"); }
+ virtual void OnExceptionWaiting()
+ { wxFAIL_MSG("OnExceptionWaiting shouldn't be called"); }
+
+private:
+ // DirectFB -> wxWidgets events translation
+ void HandleDFBEvent(const wxDFBEvent& event);
+
+ int m_fd;
+ size_t m_offset;
+ DFBEvent m_event;
+};
+
+void wxDFBEventsHandler::OnReadWaiting()
+{
+ for ( ;; )
+ {
+ int size = read(m_fd,
+ ((char*)&m_event) + m_offset,
+ sizeof(m_event) - m_offset);
+
+ if ( size == 0 || (size == -1 && (errno == EAGAIN || errno == EINTR)) )
+ {
+ // nothing left in the pipe (EAGAIN is expected for an FD with
+ // O_NONBLOCK)
+ break;
+ }
+
+ if ( size == -1 )
+ {
+ wxLogSysError(_("Failed to read event from DirectFB pipe"));
+ break;
+ }
+
+ size += m_offset;
+ m_offset = 0;
+
+ if ( size != sizeof(m_event) )
+ {
+ m_offset = size;
+ break;
+ }
+
+ HandleDFBEvent(m_event);
+ }
+}
+
+void wxDFBEventsHandler::HandleDFBEvent(const wxDFBEvent& event)
+{
+ switch ( event.GetClass() )
+ {
+ case DFEC_WINDOW:
+ {
+ wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
+ wxNonOwnedWindow::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,
+ "ignoring event of unsupported class %i",
+ (int)event.GetClass());
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// 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 */
// events dispatch and loop handling
//-----------------------------------------------------------------------------
-bool wxGUIEventLoop::Pending() const
-{
- wxCHECK_MSG( ms_buffer, false, "invalid event buffer" );
-
- return ms_buffer->HasEvent();
-}
-
-bool wxGUIEventLoop::Dispatch()
-{
- // 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
- //
- // TODO: remove this hack, instead use CreateFileDescriptor() to properly
- // multiplex GUI and socket input
- const int TIMEOUT = 100;
-
- // treat time out (-1 return value) as normal successful return so that
- // OnNextIteration() is called
- return !!DispatchTimeout(TIMEOUT);
-}
-
-int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
-{
- wxCHECK_MSG( ms_buffer, 0, "invalid event buffer" );
-
- // 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:
- return -1;
-
- default:
- // don't terminate the loop due to errors (they were reported
- // already by ms_buffer)
- break;
- }
- }
-
- return 1;
-}
-
-void wxGUIEventLoop::WakeUp()
-{
- wxCHECK_RET( ms_buffer, "invalid event buffer" );
-
- ms_buffer->WakeUp();
-}
-
-void wxGUIEventLoop::OnNextIteration()
-{
-#if wxUSE_TIMER
- wxGenericTimerImpl::NotifyTimers();
-#endif
-
-#if wxUSE_SOCKETS
- // handle any pending socket events:
- wxFDIODispatcher::DispatchPending();
-#endif
-}
-
void wxGUIEventLoop::Yield()
{
// process all pending events:
// handle timers, sockets etc.
OnNextIteration();
}
-
-
-//-----------------------------------------------------------------------------
-// DirectFB -> wxWidgets events translation
-//-----------------------------------------------------------------------------
-
-void wxGUIEventLoop::HandleDFBEvent(const wxDFBEvent& event)
-{
- switch ( event.GetClass() )
- {
- case DFEC_WINDOW:
- {
- wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
- wxNonOwnedWindow::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,
- "ignoring event of unsupported class %i",
- (int)event.GetClass());
- }
- }
-}