X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a69561317309e7b6d29dbdd3465e16f8ceba8fb7..683df83d51c0f080e2e5210dc8115be0cb30d1ad:/src/osx/core/evtloop_cf.cpp diff --git a/src/osx/core/evtloop_cf.cpp b/src/osx/core/evtloop_cf.cpp index 20f01f8fd6..ef70c2368e 100644 --- a/src/osx/core/evtloop_cf.cpp +++ b/src/osx/core/evtloop_cf.cpp @@ -5,6 +5,7 @@ // Created: 2009-10-18 // RCS-ID: $Id$ // Copyright: (c) 2009 Vadim Zeitlin +// (c) 2013 Rob Bresalier // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -42,97 +43,28 @@ #include "wx/nonownedwnd.h" #endif +#include + // ============================================================================ // wxCFEventLoopSource and wxCFEventLoop implementation // ============================================================================ #if wxUSE_EVENTLOOP_SOURCE -namespace -{ - -void EnableDescriptorCallBacks(CFFileDescriptorRef cffd, int flags) -{ - if ( flags & wxEVENT_SOURCE_INPUT ) - CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack); - if ( flags & wxEVENT_SOURCE_OUTPUT ) - CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack); -} - -void -wx_cffiledescriptor_callback(CFFileDescriptorRef cffd, - CFOptionFlags flags, - void *ctxData) -{ - wxLogTrace(wxTRACE_EVT_SOURCE, - "CFFileDescriptor callback, flags=%d", flags); - - wxCFEventLoopSource * const - source = static_cast(ctxData); - - wxEventLoopSourceHandler * const - handler = source->GetHandler(); - if ( flags & kCFFileDescriptorReadCallBack ) - handler->OnReadWaiting(); - if ( flags & kCFFileDescriptorWriteCallBack ) - handler->OnWriteWaiting(); - - // we need to re-enable callbacks to be called again - EnableDescriptorCallBacks(cffd, source->GetFlags()); -} - -} // anonymous namespace - -wxEventLoopSource * -wxCFEventLoop::AddSourceForFD(int fd, - wxEventLoopSourceHandler *handler, - int flags) -{ - wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" ); - - wxScopedPtr - source(new wxCFEventLoopSource(handler, flags)); - - CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL }; - wxCFRef - cffd(CFFileDescriptorCreate - ( - kCFAllocatorDefault, - fd, - true, // close on invalidate - wx_cffiledescriptor_callback, - &ctx - )); - if ( !cffd ) - return NULL; - - wxCFRef - cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0)); - if ( !cfsrc ) - return NULL; - - CFRunLoopRef cfloop = CFGetCurrentRunLoop(); - CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode); - - // Enable the callbacks initially. - EnableDescriptorCallBacks(cffd, source->GetFlags()); - - source->SetFileDescriptor(cffd.release()); - - return source.release(); -} - -void wxCFEventLoopSource::SetFileDescriptor(CFFileDescriptorRef cffd) +void wxCFEventLoopSource::InitSourceSocket(CFSocketRef cfSocket) { - wxASSERT_MSG( !m_cffd, "shouldn't be called more than once" ); + wxASSERT_MSG( !m_cfSocket, "shouldn't be called more than once" ); - m_cffd = cffd; + m_cfSocket = cfSocket; } wxCFEventLoopSource::~wxCFEventLoopSource() { - if ( m_cffd ) - CFRelease(m_cffd); + if ( m_cfSocket ) + { + CFSocketInvalidate(m_cfSocket); + CFRelease(m_cfSocket); + } } #endif // wxUSE_EVENTLOOP_SOURCE @@ -163,13 +95,13 @@ void wxCFEventLoop::CommonModeObserverCallBack(CFRunLoopObserverRef WXUNUSED(obs // and this input is only removed from it when pending event handlers are // executed) - if ( wxTheApp ) + if ( wxTheApp && ShouldProcessIdleEvents() ) wxTheApp->ProcessPendingEvents(); } if ( activity & kCFRunLoopBeforeWaiting ) { - if ( m_processIdleEvents && ProcessIdle() ) + if ( ShouldProcessIdleEvents() && ProcessIdle() ) { WakeUp(); } @@ -203,6 +135,10 @@ wxCFEventLoop::wxCFEventLoop() m_shouldExit = false; m_processIdleEvents = true; +#if wxUSE_UIACTIONSIMULATOR + m_shouldWaitForEvent = false; +#endif + m_runLoop = CFGetCurrentRunLoop(); CFRunLoopObserverContext ctxt; @@ -298,7 +234,17 @@ bool wxCFEventLoop::Pending() const int wxCFEventLoop::DoProcessEvents() { - return DispatchTimeout( 0 ); +#if wxUSE_UIACTIONSIMULATOR + if ( m_shouldWaitForEvent ) + { + int handled = DispatchTimeout( 1000 ); + wxASSERT_MSG( handled == 1, "No Event Available"); + m_shouldWaitForEvent = false; + return handled; + } + else +#endif + return DispatchTimeout( 0 ); } bool wxCFEventLoop::Dispatch() @@ -350,7 +296,7 @@ int wxCFEventLoop::DoDispatchTimeout(unsigned long timeout) return 1; } -void wxCFEventLoop::DoRun() +void wxCFEventLoop::OSXDoRun() { for ( ;; ) { @@ -371,23 +317,15 @@ void wxCFEventLoop::DoRun() } } -void wxCFEventLoop::DoStop() +void wxCFEventLoop::OSXDoStop() { CFRunLoopStop(CFGetCurrentRunLoop()); } // enters a loop calling OnNextIteration(), Pending() and Dispatch() and // terminating when Exit() is called -int wxCFEventLoop::Run() +int wxCFEventLoop::DoRun() { - // event loops are not recursive, you need to create another loop! - wxCHECK_MSG( !IsRunning(), -1, wxT("can't reenter a message loop") ); - - // ProcessIdle() and ProcessEvents() below may throw so the code here should - // be exception-safe, hence we must use local objects for all actions we - // should undo - wxEventLoopActivator activate(this); - // we must ensure that OnExit() is called even if an exception is thrown // from inside ProcessEvents() but we must call it from Exit() in normal // situations because it is supposed to be called synchronously, @@ -400,7 +338,7 @@ int wxCFEventLoop::Run() { #endif // wxUSE_EXCEPTIONS - DoRun(); + OSXDoRun(); #if wxUSE_EXCEPTIONS // exit the outer loop as well @@ -434,25 +372,30 @@ int wxCFEventLoop::Run() // sets the "should exit" flag and wakes up the loop so that it terminates // soon -void wxCFEventLoop::Exit(int rc) +void wxCFEventLoop::ScheduleExit(int rc) { m_exitcode = rc; m_shouldExit = true; - DoStop(); + OSXDoStop(); } wxCFEventLoopPauseIdleEvents::wxCFEventLoopPauseIdleEvents() { wxCFEventLoop* cfl = dynamic_cast(wxEventLoopBase::GetActive()); if ( cfl ) + { + m_formerState = cfl->ShouldProcessIdleEvents(); cfl->SetProcessIdleEvents(false); + } + else + m_formerState = true; } wxCFEventLoopPauseIdleEvents::~wxCFEventLoopPauseIdleEvents() { wxCFEventLoop* cfl = dynamic_cast(wxEventLoopBase::GetActive()); if ( cfl ) - cfl->SetProcessIdleEvents(true); + cfl->SetProcessIdleEvents(m_formerState); } // TODO Move to thread_osx.cpp