]> git.saurik.com Git - wxWidgets.git/blobdiff - src/dfb/evtloop.cpp
don't assume there's always an active wxEventLoop instance
[wxWidgets.git] / src / dfb / evtloop.cpp
index 647e52ec7b0fe5b4565b620bab68bb82a5f91c03..ee7154ff1ef0dd2b9d6c66d0d3cd4de023f5f5c8 100644 (file)
     #include "wx/app.h"
 #endif
 
+#include "wx/thread.h"
 #include "wx/timer.h"
+#include "wx/private/socketevtdispatch.h"
 #include "wx/dfb/private.h"
+#include "wx/nonownedwnd.h"
 
 #define TRACE_EVENTS _T("events")
 
@@ -38,7 +41,7 @@
 // wxEventLoop initialization
 //-----------------------------------------------------------------------------
 
-IDirectFBEventBufferPtr wxEventLoop::ms_buffer;
+wxIDirectFBEventBufferPtr wxEventLoop::ms_buffer;
 
 wxEventLoop::wxEventLoop()
 {
@@ -49,12 +52,17 @@ wxEventLoop::wxEventLoop()
 /* static */
 void wxEventLoop::InitBuffer()
 {
-    IDirectFBPtr dfb(wxTheApp->GetDirectFBInterface());
-    DFB_CALL( dfb->CreateEventBuffer(dfb, &ms_buffer) );
+    ms_buffer = wxIDirectFB::Get()->CreateEventBuffer();
 }
 
 /* static */
-IDirectFBEventBufferPtr wxEventLoop::GetDirectFBEventBuffer()
+void wxEventLoop::CleanUp()
+{
+    ms_buffer.Reset();
+}
+
+/* static */
+wxIDirectFBEventBufferPtr wxEventLoop::GetDirectFBEventBuffer()
 {
     if ( !ms_buffer )
         InitBuffer();
@@ -70,8 +78,7 @@ bool wxEventLoop::Pending() const
 {
     wxCHECK_MSG( ms_buffer, false, _T("invalid event buffer") );
 
-    // returns DFB_OK if there is >=1 event, DFB_BUFFER_EMPTY otherwise
-    return ms_buffer->HasEvent(ms_buffer) == DFB_OK;
+    return ms_buffer->HasEvent();
 }
 
 bool wxEventLoop::Dispatch()
@@ -81,31 +88,39 @@ bool wxEventLoop::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
-    //
-    //     FIXME: call NotifyTimers() from here (and loop) instead?
     const int TIMEOUT = 100;
 
-    DFBResult ret = ms_buffer->WaitForEventWithTimeout(ms_buffer, 0, TIMEOUT);
+    // release the GUI mutex so that other threads have a chance to post
+    // events:
+    wxMutexGuiLeave();
 
-    switch ( ret )
+    bool rv = ms_buffer->WaitForEventWithTimeout(0, TIMEOUT);
+
+    // and acquire it back before calling any event handlers:
+    wxMutexGuiEnter();
+
+    if ( rv )
     {
-        case DFB_OK:
+        switch ( ms_buffer->GetLastResult() )
         {
-            wxDFBEvent e;
-            ms_buffer->GetEvent(ms_buffer, &e);
-            HandleDFBEvent(e);
-            break;
+            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;
         }
-
-        case DFB_TIMEOUT:
-            // timed out, pretend we processed an event so that OnNextIteration
-            // is called
-            break;
-
-        default:
-            // report any errors, but don't terminate the loop due to them
-            wxDfbCheckReturn(ret);
-            break;
     }
 
     return true;
@@ -115,18 +130,30 @@ void wxEventLoop::WakeUp()
 {
     wxCHECK_RET( ms_buffer, _T("invalid event buffer") );
 
-    DFB_CALL( ms_buffer->WakeUp(ms_buffer) );
+    ms_buffer->WakeUp();
 }
 
 void wxEventLoop::OnNextIteration()
 {
 #if wxUSE_TIMER
-    // see the comment in Dispatch
     wxTimer::NotifyTimers();
 #endif
+
+#if wxUSE_SOCKETS
+    // handle any pending socket events:
+    wxSocketEventDispatcher::Get().RunLoop();
+#endif
 }
 
-#warning "FIXME: cleanup wxEventLoop::ms_buffer before exiting"
+void wxEventLoop::Yield()
+{
+    // process all pending events:
+    while ( Pending() )
+        Dispatch();
+
+    // handle timers, sockets etc.
+    OnNextIteration();
+}
 
 
 //-----------------------------------------------------------------------------
@@ -140,7 +167,7 @@ void wxEventLoop::HandleDFBEvent(const wxDFBEvent& event)
         case DFEC_WINDOW:
         {
             wxDFBWindowEvent winevent(((const DFBEvent&)event).window);
-            wxTopLevelWindowDFB::HandleDFBWindowEvent(winevent);
+            wxNonOwnedWindow::HandleDFBWindowEvent(winevent);
             break;
         }