#if wxUSE_EVENTLOOP_SOURCE
// create a new event loop source wrapping the given file descriptor and
- // start monitoring it
- virtual wxEventLoopSource *
- AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags) = 0;
+ // monitor it for events occurring on this descriptor in all event loops
+ static wxEventLoopSource *
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
#endif // wxUSE_EVENTLOOP_SOURCE
// dispatch&processing
wxGUIEventLoop() { m_impl = NULL; }
virtual ~wxGUIEventLoop();
-#if wxUSE_EVENTLOOP_SOURCE
- // We need to define a base class pure virtual method but we can't provide
- // a generic implementation for it so simply fail.
- virtual wxEventLoopSource *
- AddSourceForFD(int WXUNUSED(fd),
- wxEventLoopSourceHandler * WXUNUSED(handler),
- int WXUNUSED(flags))
- {
- wxFAIL_MSG( "support for event loop sources not implemented" );
- return NULL;
- }
-#endif // wxUSE_EVENTLOOP_SOURCE
-
virtual void ScheduleExit(int rc = 0);
virtual bool Pending() const;
virtual bool Dispatch();
virtual void WakeUp();
virtual bool YieldFor(long eventsToProcess);
-#if wxUSE_EVENTLOOP_SOURCE
- virtual wxEventLoopSource *
- AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
void StoreGdkEventForLaterProcessing(GdkEvent* ev)
{ m_arrGdkEvents.Add(ev); }
virtual bool YieldFor(long eventsToProcess);
-#if wxUSE_EVENTLOOP_SOURCE
- virtual wxEventLoopSource *
- AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
bool ShouldProcessIdleEvents() const { return m_processIdleEvents ; }
#if wxUSE_UIACTIONSIMULATOR
// wxCFEventLoopSource: CoreFoundation-based wxEventLoopSource for OS X
// ----------------------------------------------------------------------------
-class wxCFEventLoopSource : public wxEventLoopSource
+class WXDLLIMPEXP_BASE wxCFEventLoopSource : public wxEventLoopSource
{
public:
wxCFEventLoopSource(wxEventLoopSourceHandler *handler, int flags)
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/private/eventloopsourcesmanager.h
+// Purpose: declares wxEventLoopSourcesManagerBase class
+// Author: Rob Bresalier
+// Created: 2013-06-19
+// RCS-ID: $Id$
+// Copyright: (c) 2013 Rob Bresalier
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
+#define _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
+
+// For pulling in the value of wxUSE_EVENTLOOP_SOURCE
+#include "wx/evtloop.h"
+
+class WXDLLIMPEXP_BASE wxEventLoopSourcesManagerBase
+{
+public:
+#if wxUSE_EVENTLOOP_SOURCE
+ virtual wxEventLoopSource*
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags) = 0;
+#endif
+};
+
+#endif // _WX_PRIVATE_EVENTLOOPSOURCESMANAGER_H_
struct wxEndProcessData;
struct wxExecuteData;
class wxFDIOManager;
+class wxEventLoopSourcesManagerBase;
// ----------------------------------------------------------------------------
// wxAppTraits: the Unix version adds extra hooks needed by Unix code
virtual wxFDIOManager *GetFDIOManager();
#endif // wxUSE_SOCKETS
+ // Return a non-NULL pointer to the object responsible for managing the
+ // event loop sources in this kind of application.
+ virtual wxEventLoopSourcesManagerBase* GetEventLoopSourcesManager();
+
protected:
// a helper for the implementation of WaitForChild() in wxGUIAppTraits:
// checks the streams used for redirected IO in execData and returns true
#endif
#endif // wxUSE_SOCKETS
+
+ virtual wxEventLoopSourcesManagerBase* GetEventLoopSourcesManager();
};
#endif // wxUSE_GUI
virtual bool IsOk() const { return m_dispatcher != NULL; }
virtual bool YieldFor(long WXUNUSED(eventsToProcess)) { return true; }
-#if wxUSE_EVENTLOOP_SOURCE
- virtual wxEventLoopSource *
- AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
-#endif // wxUSE_EVENTLOOP_SOURCE
-
protected:
virtual void OnNextIteration();
#endif //WX_PRECOMP
#include "wx/scopeguard.h"
+#include "wx/apptrait.h"
+#include "wx/private/eventloopsourcesmanager.h"
// ----------------------------------------------------------------------------
// wxEventLoopBase
return YieldFor(wxEVT_CATEGORY_ALL);
}
+#if wxUSE_EVENTLOOP_SOURCE
+
+wxEventLoopSource*
+wxEventLoopBase::AddSourceForFD(int fd,
+ wxEventLoopSourceHandler *handler,
+ int flags)
+{
+ // Ensure that we have some valid traits.
+ wxConsoleAppTraits traitsConsole;
+ wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
+ if ( !traits )
+ traits = &traitsConsole;
+
+ // And delegate to the event loop sources manager defined by it.
+ wxEventLoopSourcesManagerBase* const
+ manager = traits->GetEventLoopSourcesManager();
+ wxCHECK_MSG( manager, NULL, wxS("Must have wxEventLoopSourcesManager") );
+
+ return manager->AddSourceForFD(fd, handler, flags);
+}
+
+#endif // wxUSE_EVENTLOOP_SOURCE
+
// wxEventLoopManual is unused in the other ports
#if defined(__WINDOWS__) || defined(__WXDFB__) || ( ( defined(__UNIX__) && !defined(__WXOSX__) ) && wxUSE_BASE)
#include "wx/log.h"
#endif // WX_PRECOMP
+#include "wx/private/eventloopsourcesmanager.h"
+#include "wx/apptrait.h"
+
#include <gtk/gtk.h>
#include <glib.h>
}
}
-wxEventLoopSource *
-wxGUIEventLoop::AddSourceForFD(int fd,
- wxEventLoopSourceHandler *handler,
- int flags)
+class wxGUIEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
{
- wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
-
- int condition = 0;
- if (flags & wxEVENT_SOURCE_INPUT)
- condition |= G_IO_IN | G_IO_PRI;
- if (flags & wxEVENT_SOURCE_OUTPUT)
- condition |= G_IO_OUT;
- if (flags & wxEVENT_SOURCE_EXCEPTION)
- condition |= G_IO_ERR | G_IO_HUP | G_IO_NVAL;
-
- GIOChannel* channel = g_io_channel_unix_new(fd);
- const unsigned sourceId = g_io_add_watch
- (
- channel,
- (GIOCondition)condition,
- &wx_on_channel_event,
- handler
- );
- // it was ref'd by g_io_add_watch() so we can unref it here
- g_io_channel_unref(channel);
-
- if ( !sourceId )
- return NULL;
-
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "Adding event loop source for fd=%d with GTK id=%u",
- fd, sourceId);
+public:
+ virtual wxEventLoopSource*
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
+ {
+ wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+
+ int condition = 0;
+ if ( flags & wxEVENT_SOURCE_INPUT )
+ condition |= G_IO_IN | G_IO_PRI | G_IO_HUP;
+ if ( flags & wxEVENT_SOURCE_OUTPUT )
+ condition |= G_IO_OUT;
+ if ( flags & wxEVENT_SOURCE_EXCEPTION )
+ condition |= G_IO_ERR | G_IO_NVAL;
+
+ GIOChannel* channel = g_io_channel_unix_new(fd);
+ const unsigned sourceId = g_io_add_watch
+ (
+ channel,
+ (GIOCondition)condition,
+ &wx_on_channel_event,
+ handler
+ );
+ // it was ref'd by g_io_add_watch() so we can unref it here
+ g_io_channel_unref(channel);
+
+ if ( !sourceId )
+ return NULL;
+
+ wxLogTrace(wxTRACE_EVT_SOURCE,
+ "Adding event loop source for fd=%d with GTK id=%u",
+ fd, sourceId);
+
+
+ return new wxGTKEventLoopSource(sourceId, handler, flags);
+ }
+};
+wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
+{
+ static wxGUIEventLoopSourcesManager s_eventLoopSourcesManager;
- return new wxGTKEventLoopSource(sourceId, handler, flags);
+ return &s_eventLoopSourcesManager;
}
wxGTKEventLoopSource::~wxGTKEventLoopSource()
#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<wxCFEventLoopSource *>(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<wxCFEventLoopSource>
- source(new wxCFEventLoopSource(handler, flags));
-
- CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL };
- wxCFRef<CFFileDescriptorRef>
- cffd(CFFileDescriptorCreate
- (
- kCFAllocatorDefault,
- fd,
- true, // close on invalidate
- wx_cffiledescriptor_callback,
- &ctx
- ));
- if ( !cffd )
- return NULL;
-
- wxCFRef<CFRunLoopSourceRef>
- 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)
{
wxASSERT_MSG( !m_cffd, "shouldn't be called more than once" );
#include "wx/thread.h"
#include "wx/process.h"
+#include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
+#include "wx/private/eventloopsourcesmanager.h"
+
#include <sys/wait.h>
+#include <CoreFoundation/CFFileDescriptor.h>
#include <CoreFoundation/CFSocket.h>
/*!
return ++s_last_tag;
}
+#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<wxCFEventLoopSource *>(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
+
+class wxCFEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
+{
+public:
+ wxEventLoopSource *
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
+ {
+ wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+
+ wxScopedPtr<wxCFEventLoopSource>
+ source(new wxCFEventLoopSource(handler, flags));
+
+ CFFileDescriptorContext ctx = { 0, source.get(), NULL, NULL, NULL };
+ wxCFRef<CFFileDescriptorRef>
+ cffd(CFFileDescriptorCreate
+ (
+ kCFAllocatorDefault,
+ fd,
+ true, // close on invalidate
+ wx_cffiledescriptor_callback,
+ &ctx
+ ));
+ if ( !cffd )
+ return NULL;
+
+ wxCFRef<CFRunLoopSourceRef>
+ cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
+ if ( !cfsrc )
+ return NULL;
+
+ CFRunLoopRef cfloop = CFRunLoopGetCurrent();
+ CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode);
+
+ // Enable the callbacks initially.
+ EnableDescriptorCallBacks(cffd, source->GetFlags());
+
+ source->SetFileDescriptor(cffd.release());
+
+ return source.release();
+ }
+};
+
+wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
+{
+ static wxCFEventLoopSourcesManager s_eventLoopSourcesManager;
+
+ return &s_eventLoopSourcesManager;
+}
+
+#endif // wxUSE_EVENTLOOP_SOURCE
+
/////////////////////////////////////////////////////////////////////////////
// NOTE: This doesn't really belong here but this was a handy file to
#include "wx/unix/private/epolldispatcher.h"
#include "wx/unix/private/wakeuppipe.h"
#include "wx/private/selectdispatcher.h"
+#include "wx/private/eventloopsourcesmanager.h"
#include "wx/private/fdioeventloopsourcehandler.h"
+#include "wx/private/eventloopsourcesmanager.h"
#if wxUSE_EVENTLOOP_SOURCE
#include "wx/evtloopsrc.h"
#if wxUSE_EVENTLOOP_SOURCE
-wxEventLoopSource *
-wxConsoleEventLoop::AddSourceForFD(int fd,
- wxEventLoopSourceHandler *handler,
- int flags)
+class wxConsoleEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
{
- wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
+public:
+ wxEventLoopSource* AddSourceForFD( int fd,
+ wxEventLoopSourceHandler *handler,
+ int flags)
+ {
+ wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "Adding event loop source for fd=%d", fd);
+ wxLogTrace(wxTRACE_EVT_SOURCE,
+ "Adding event loop source for fd=%d", fd);
+
+ // we need a bridge to wxFDIODispatcher
+ //
+ // TODO: refactor the code so that only wxEventLoopSourceHandler is used
+ wxScopedPtr<wxFDIOHandler>
+ fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
- // we need a bridge to wxFDIODispatcher
- //
- // TODO: refactor the code so that only wxEventLoopSourceHandler is used
- wxScopedPtr<wxFDIOHandler>
- fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
+ if ( !wxFDIODispatcher::Get()->RegisterFD(fd, fdioHandler.get(), flags) )
+ return NULL;
- if ( !m_dispatcher->RegisterFD(fd, fdioHandler.get(), flags) )
- return NULL;
+ return new wxUnixEventLoopSource(wxFDIODispatcher::Get(), fdioHandler.release(),
+ fd, handler, flags);
+ }
+};
+
+wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
+{
+ static wxConsoleEventLoopSourcesManager s_eventLoopSourcesManager;
- return new wxUnixEventLoopSource(m_dispatcher, fdioHandler.release(),
- fd, handler, flags);
+ return &s_eventLoopSourcesManager;
}
wxUnixEventLoopSource::~wxUnixEventLoopSource()