src/unix/fswatcher_kqueue.cpp \
src/unix/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp
src/unix/fswatcher_kqueue.cpp \
src/unix/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp
src/unix/fswatcher_kqueue.cpp \
src/unix/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp
src/unix/fswatcher_kqueue.cpp \
src/unix/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp
COND_TOOLKIT_OSX_CARBON_BASE_OSX_SRC = \
src/osx/core/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp \
COND_TOOLKIT_OSX_COCOA_BASE_OSX_SRC = \
src/osx/core/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp \
src/unix/fswatcher_kqueue.cpp \
src/unix/mimetype.cpp \
src/osx/core/cfstring.cpp \
+ src/osx/core/evtloop_cf.cpp \
src/osx/core/stdpaths_cf.cpp \
src/osx/core/strconv_cf.cpp \
src/osx/core/utilsexc_base.cpp
COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS = \
monodll_core_mimetype.o \
monodll_cfstring.o \
+ monodll_evtloop_cf.o \
monodll_stdpaths_cf.o \
monodll_strconv_cf.o \
monodll_utilsexc_base.o \
COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_1 = \
monolib_core_mimetype.o \
monolib_cfstring.o \
+ monolib_evtloop_cf.o \
monolib_stdpaths_cf.o \
monolib_strconv_cf.o \
monolib_utilsexc_base.o \
COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_2 = \
basedll_core_mimetype.o \
basedll_cfstring.o \
+ basedll_evtloop_cf.o \
basedll_stdpaths_cf.o \
basedll_strconv_cf.o \
basedll_utilsexc_base.o \
COND_PLATFORM_MACOSX_1___BASE_PLATFORM_SRC_OBJECTS_3 = \
baselib_core_mimetype.o \
baselib_cfstring.o \
+ baselib_evtloop_cf.o \
baselib_stdpaths_cf.o \
baselib_strconv_cf.o \
baselib_utilsexc_base.o \
monodll_cfstring.o: $(srcdir)/src/osx/core/cfstring.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/cfstring.cpp
+monodll_evtloop_cf.o: $(srcdir)/src/osx/core/evtloop_cf.cpp $(MONODLL_ODEP)
+ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/evtloop_cf.cpp
+
monodll_stdpaths_cf.o: $(srcdir)/src/osx/core/stdpaths_cf.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/osx/core/stdpaths_cf.cpp
monolib_cfstring.o: $(srcdir)/src/osx/core/cfstring.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/cfstring.cpp
+monolib_evtloop_cf.o: $(srcdir)/src/osx/core/evtloop_cf.cpp $(MONOLIB_ODEP)
+ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/evtloop_cf.cpp
+
monolib_stdpaths_cf.o: $(srcdir)/src/osx/core/stdpaths_cf.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/osx/core/stdpaths_cf.cpp
basedll_cfstring.o: $(srcdir)/src/osx/core/cfstring.cpp $(BASEDLL_ODEP)
$(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/cfstring.cpp
+basedll_evtloop_cf.o: $(srcdir)/src/osx/core/evtloop_cf.cpp $(BASEDLL_ODEP)
+ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/evtloop_cf.cpp
+
basedll_stdpaths_cf.o: $(srcdir)/src/osx/core/stdpaths_cf.cpp $(BASEDLL_ODEP)
$(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/osx/core/stdpaths_cf.cpp
baselib_cfstring.o: $(srcdir)/src/osx/core/cfstring.cpp $(BASELIB_ODEP)
$(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/cfstring.cpp
+baselib_evtloop_cf.o: $(srcdir)/src/osx/core/evtloop_cf.cpp $(BASELIB_ODEP)
+ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/evtloop_cf.cpp
+
baselib_stdpaths_cf.o: $(srcdir)/src/osx/core/stdpaths_cf.cpp $(BASELIB_ODEP)
$(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/osx/core/stdpaths_cf.cpp
wx/unix/apptrait.h
wx/unix/chkconf.h
wx/unix/evtloop.h
+ wx/unix/evtloopsrc.h
wx/unix/pipe.h
wx/unix/stdpaths.h
wx/unix/stackwalk.h
<!-- Used on Mac OS X wxMac base, and Mac OS X darwin base -->
<set var="BASE_COREFOUNDATION_SRC" hints="files">
src/osx/core/cfstring.cpp
+ src/osx/core/evtloop_cf.cpp
src/osx/core/stdpaths_cf.cpp
src/osx/core/strconv_cf.cpp
src/osx/core/utilsexc_base.cpp
wx/docview.h
wx/effects.h
wx/evtloop.h
+ wx/evtloopsrc.h
wx/fdrepdlg.h
wx/filectrl.h
wx/filepicker.h
wx/gtk/dcscreen.h
wx/gtk/dnd.h
wx/gtk/evtloop.h
+ wx/gtk/evtloopsrc.h
wx/gtk/font.h
wx/gtk/minifram.h
wx/gtk/pen.h
wx/osx/dirdlg.h
wx/osx/dnd.h
wx/osx/evtloop.h
+ wx/osx/evtloopsrc.h
wx/osx/filedlg.h
wx/osx/font.h
wx/osx/fontdlg.h
#include "wx/event.h"
#include "wx/utils.h"
-#include "wx/hashset.h"
-// ----------------------------------------------------------------------------
-// wxEventLoopSource: source of i/o for wxEventLoop
-// ----------------------------------------------------------------------------
-
-#define wxTRACE_EVT_SOURCE "EventSource"
-
-#if defined(__UNIX__) && (wxUSE_CONSOLE_EVENTLOOP || defined(__WXGTK__) || \
- defined(__WXOSX_COCOA__))
+// TODO: implement wxEventLoopSource for MSW (it should wrap a HANDLE and be
+// monitored using MsgWaitForMultipleObjects())
+#if defined(__WXOSX__) || defined(__WXGTK20__) || defined(__WXDFB__) || \
+ (!wxUSE_GUI && defined(__UNIX__))
#define wxUSE_EVENTLOOP_SOURCE 1
#else
#define wxUSE_EVENTLOOP_SOURCE 0
#endif
#if wxUSE_EVENTLOOP_SOURCE
-
-// handler used to process events on event loop sources
-class WXDLLIMPEXP_BASE wxEventLoopSourceHandler
-{
-public:
- // called when descriptor is available for non-blocking read
- virtual void OnReadWaiting() = 0;
-
- // called when descriptor is available for non-blocking write
- virtual void OnWriteWaiting() = 0;
-
- // called when there is exception on descriptor
- virtual void OnExceptionWaiting() = 0;
-
- // virtual dtor for the base class
- virtual ~wxEventLoopSourceHandler() { }
-};
-
-// those flags describes what events should be reported
-enum
-{
- wxEVENT_SOURCE_INPUT = 0x01,
- wxEVENT_SOURCE_OUTPUT = 0x02,
- wxEVENT_SOURCE_EXCEPTION = 0x04,
- wxEVENT_SOURCE_ALL = wxEVENT_SOURCE_INPUT | wxEVENT_SOURCE_OUTPUT |
- wxEVENT_SOURCE_EXCEPTION,
-};
-
-class wxAbstractEventLoopSource
-{
-public:
- wxAbstractEventLoopSource() :
- m_handler(NULL), m_flags(-1)
- {}
-
- wxAbstractEventLoopSource(wxEventLoopSourceHandler* handler, int flags) :
- m_handler(handler), m_flags(flags)
- {}
-
- virtual ~wxAbstractEventLoopSource() { }
-
- virtual bool IsOk() const = 0;
-
- virtual void Invalidate() = 0;
-
- void SetHandler(wxEventLoopSourceHandler* handler)
- {
- m_handler = handler;
- }
-
- wxEventLoopSourceHandler* GetHandler() const
- {
- return m_handler;
- }
-
- void SetFlags(int flags)
- {
- m_flags = flags;
- }
-
- int GetFlags() const
- {
- return m_flags;
- }
-
-protected:
- wxEventLoopSourceHandler* m_handler;
- int m_flags;
-};
-
-// This class is a simple wrapper for OS specific resources than can be a
-// source of I/O. On Unix,for instance these are file descriptors.
-//
-// Instances of this class doesn't take resposibility of any resource you pass
-// to them, I.E. you have to release them yourself.
-template<class T>
-class WXDLLIMPEXP_BASE wxEventLoopSourceBase : public wxAbstractEventLoopSource
-{
-public:
- typedef T Resource;
-
- // copy ctor
- wxEventLoopSourceBase(const wxEventLoopSourceBase& source) :
- wxAbstractEventLoopSource(source.GetHandler(), source.GetFlags()),
- m_res(source.GetResource())
- {
- }
-
- virtual const T InvalidResource() const
- {
- return (T)-1;
- }
-
- virtual void Invalidate()
- {
- SetResource(InvalidResource());
- SetHandler(NULL);
- }
-
- // sets internal value to res
- void SetResource(T res)
- {
- m_res = res;
- }
-
- // returns associated resource
- T GetResource() const
- {
- return m_res;
- }
-
- virtual bool IsOk() const
- {
- // flags < 0 are invalid and flags == 0 mean monitoring for nothing
- return m_res != InvalidResource() && m_handler && m_flags >=1;
- }
-
-protected:
- // empty ctor, beacuse we often store event sources as values
- wxEventLoopSourceBase() :
- wxAbstractEventLoopSource(),
- m_res(InvalidResource())
- {
- }
-
- // ctor setting internal value to the os resource res
- wxEventLoopSourceBase(T res, wxEventLoopSourceHandler* handler,
- int flags) :
- wxAbstractEventLoopSource(handler, flags),
- m_res(res)
- { }
-
- T m_res;
-};
-
-#if defined(__WXMAC__)
-class wxMacEventLoopSource : public wxEventLoopSourceBase<CFRunLoopSourceRef>
-{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- int GetFileDescriptor() const
- {
- return m_fd;
- }
-#endif
-protected:
- wxMacEventLoopSource() : wxEventLoopSourceBase<CFRunLoopSourceRef>() { }
-
- // ctor setting internal value to the os resource res
- wxMacEventLoopSource(CFRunLoopSourceRef res,
- wxEventLoopSourceHandler* handler, int flags) :
- wxEventLoopSourceBase<CFRunLoopSourceRef>(res, handler, flags)
- {
- }
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- int m_fd;
+ class wxEventLoopSource;
+ class wxEventLoopSourceHandler;
#endif
- friend class wxGUIEventLoop;
-};
-#endif
-
-#if defined(__UNIX__)
-class wxUnixEventLoopSource : public wxEventLoopSourceBase<int>
-{
-protected:
- wxUnixEventLoopSource() : wxEventLoopSourceBase<int>() { }
-
- // ctor setting internal value to the os resource res
- wxUnixEventLoopSource(int res, wxEventLoopSourceHandler* handler,
- int flags) :
- wxEventLoopSourceBase<int>(res, handler, flags)
- {
- }
-
- friend class wxConsoleEventLoop;
- friend class wxGUIEventLoop;
-};
-#endif
-
-// the list of watched sources
-WX_DECLARE_HASH_SET(wxAbstractEventLoopSource*, wxPointerHash, wxPointerEqual,
- wxEventLoopSourceHashSet);
-
-#endif
-
-
/*
NOTE ABOUT wxEventLoopBase::YieldFor LOGIC
------------------------------------------
bool IsMain() const;
#if wxUSE_EVENTLOOP_SOURCE
- virtual wxAbstractEventLoopSource* CreateSource() const = 0;
-
- virtual wxAbstractEventLoopSource* CreateSource(int WXUNUSED(res),
- wxEventLoopSourceHandler* WXUNUSED(handler),
- int WXUNUSED(flags)) const
- {
- return NULL;
- }
-
- // adds source to be monitored for I/O events specified in flags. Upon an
- // event the appropriate method of handler will be called. The handler is
- // owned be the calling client and will not be freed in any case.
- // Returns true if the source was successfully added, false if it failed
- // (this may happen for example when this source is already monitored)
- virtual bool AddSource(wxAbstractEventLoopSource* source)
- {
- wxCHECK_MSG( source && source->IsOk(), false, "Invalid source" );
-
- wxEventLoopSourceHashSet::value_type val(source);
- if (!m_sourceMap.insert(val).second)
- {
- return false;
- }
-
- bool ret = DoAddSource(source);
- if (!ret)
- {
- (void) m_sourceMap.erase(source);
- }
- return ret;
- }
-
- // removes the source from the list of monitored sources.
- // Returns true if the source was successfully removed, false otherwise
- virtual bool RemoveSource(wxAbstractEventLoopSource* source)
- {
- wxCHECK_MSG( source && source->IsOk(), false, "Invalid source" );
-
- if (m_sourceMap.find(source) == m_sourceMap.end())
- {
- return false;
- }
-
- bool ret = DoRemoveSource(source);
- m_sourceMap.erase(source);
- return ret;
- }
-
- bool RemoveAllSources()
- {
- wxEventLoopSourceHashSet::iterator it = m_sourceMap.begin();
- while ( !m_sourceMap.empty() )
- {
- (void) RemoveSource(*it);
- m_sourceMap.erase(it);
- it = m_sourceMap.begin();
- }
-
- return true;
- }
-#endif
+ // 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;
+#endif // wxUSE_EVENTLOOP_SOURCE
// dispatch&processing
// -------------------
protected:
-#if wxUSE_EVENTLOOP_SOURCE
- virtual bool DoAddSource(wxAbstractEventLoopSource* source) = 0;
- virtual bool DoRemoveSource(wxAbstractEventLoopSource* source) = 0;
-
- wxEventLoopSourceHashSet m_sourceMap;
-#endif
-
// this function should be called before the event loop terminates, whether
// this happens normally (because of Exit() call) or abnormally (because of
// an exception thrown from inside the loop)
#endif // platforms using "manual" loop
+// include the header defining wxConsoleEventLoop for Unix systems
+#if defined(__UNIX__)
+ #include "wx/unix/evtloop.h"
+#endif
+
// we're moving away from old m_impl wxEventLoop model as otherwise the user
// code doesn't have access to platform-specific wxEventLoop methods and this
// can sometimes be very useful (e.g. under MSW this is necessary for
-// integration with MFC) but currently this is done for MSW only, other ports
-// should follow a.s.a.p.
+// integration with MFC) but currently this is not done for all ports yet (e.g.
+// wxX11) so fall back to the old wxGUIEventLoop definition below for them
+
#if defined(__WXPALMOS__)
#include "wx/palmos/evtloop.h"
#elif defined(__WXMSW__)
+ // this header defines both console and GUI loops for MSW
#include "wx/msw/evtloop.h"
-#elif defined(__WXMAC__)
+#elif defined(__WXOSX__)
+ // CoreFoundation-based event loop is currently in wxBase so include it in
+ // any case too (although maybe it actually shouldn't be there at all)
#include "wx/osx/evtloop.h"
-#elif defined(__WXCOCOA__)
+#elif wxUSE_GUI
+
+// include the appropriate header defining wxGUIEventLoop
+
+#if defined(__WXCOCOA__)
#include "wx/cocoa/evtloop.h"
#elif defined(__WXDFB__)
#include "wx/dfb/evtloop.h"
#endif // platforms
-// also include the header defining wxConsoleEventLoop for Unix systems
-#if defined(__UNIX__)
- #include "wx/unix/evtloop.h"
-#endif
+#endif // wxUSE_GUI
-// we use a class rather than a typedef because wxEventLoop is forward-declared
-// in many places
#if wxUSE_GUI
+ // we use a class rather than a typedef because wxEventLoop is
+ // forward-declared in many places
class wxEventLoop : public wxGUIEventLoop { };
-#else // !GUI
+#else // !wxUSE_GUI
// we can't define wxEventLoop differently in GUI and base libraries so use
// a #define to still allow writing wxEventLoop in the user code
#if wxUSE_CONSOLE_EVENTLOOP && (defined(__WXMSW__) || defined(__UNIX__))
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/evtloopsrc.h
+// Purpose: declaration of wxEventLoopSource class
+// Author: Vadim Zeitlin
+// Created: 2009-10-21
+// RCS-ID: $Id: wxhead.h,v 1.11 2009-06-29 10:23:04 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_EVTLOOPSRC_H_
+#define _WX_EVTLOOPSRC_H_
+
+// ----------------------------------------------------------------------------
+// wxEventLoopSource: a source of events which may be added to wxEventLoop
+// ----------------------------------------------------------------------------
+
+// TODO: refactor wxSocket under Unix to reuse wxEventLoopSource instead of
+// duplicating much of its logic
+//
+// TODO: freeze the API and document it
+
+#if wxUSE_EVENTLOOP_SOURCE
+
+#define wxTRACE_EVT_SOURCE "EventSource"
+
+// handler used to process events on event loop sources
+class wxEventLoopSourceHandler
+{
+public:
+ // called when descriptor is available for non-blocking read
+ virtual void OnReadWaiting() = 0;
+
+ // called when descriptor is available for non-blocking write
+ virtual void OnWriteWaiting() = 0;
+
+ // called when there is exception on descriptor
+ virtual void OnExceptionWaiting() = 0;
+
+ // virtual dtor for the base class
+ virtual ~wxEventLoopSourceHandler() { }
+};
+
+// flags describing which kind of IO events we're interested in
+enum
+{
+ wxEVENT_SOURCE_INPUT = 0x01,
+ wxEVENT_SOURCE_OUTPUT = 0x02,
+ wxEVENT_SOURCE_EXCEPTION = 0x04,
+ wxEVENT_SOURCE_ALL = wxEVENT_SOURCE_INPUT |
+ wxEVENT_SOURCE_OUTPUT |
+ wxEVENT_SOURCE_EXCEPTION,
+};
+
+// wxEventLoopSource itself is an ABC and can't be created directly, currently
+// the only way to create it is by using wxEventLoop::AddSourceForFD().
+class wxEventLoopSource
+{
+public:
+ // dtor is pure virtual because it must be overridden to remove the source
+ // from the event loop monitoring it
+ virtual ~wxEventLoopSource() = 0;
+
+ void SetHandler(wxEventLoopSourceHandler* handler) { m_handler = handler; }
+ wxEventLoopSourceHandler* GetHandler() const { return m_handler; }
+
+ void SetFlags(int flags) { m_flags = flags; }
+ int GetFlags() const { return m_flags; }
+
+protected:
+ // ctor is only used by the derived classes
+ wxEventLoopSource(wxEventLoopSourceHandler *handler, int flags)
+ : m_handler(handler),
+ m_flags(flags)
+ {
+ }
+
+ wxEventLoopSourceHandler* m_handler;
+ int m_flags;
+
+ wxDECLARE_NO_COPY_CLASS(wxEventLoopSource);
+};
+
+inline wxEventLoopSource::~wxEventLoopSource() { }
+
+#if defined(__UNIX__)
+ #include "wx/unix/evtloopsrc.h"
+#endif // __UNIX__
+
+#if defined(__WXGTK20__)
+ #include "wx/gtk/evtloopsrc.h"
+#elif defined(__WXOSX__)
+ #include "wx/osx/evtloopsrc.h"
+#endif // platform
+
+#endif // wxUSE_EVENTLOOP_SOURCE
+
+#endif // _WX_EVTLOOPSRC_H_
+
typedef union _GdkEvent GdkEvent;
-#if wxUSE_EVENTLOOP_SOURCE
-// maps event loop sources to gtk source ids
-WX_DECLARE_HASH_MAP(wxUnixEventLoopSource*, int, wxPointerHash, wxPointerEqual,
- wxEventLoopSourceIdMap);
-#endif
-
-class WXDLLIMPEXP_BASE wxGUIEventLoop : public wxEventLoopBase
+class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopBase
{
public:
- typedef wxUnixEventLoopSource Source;
-
wxGUIEventLoop();
virtual int Run();
virtual void WakeUp();
virtual bool YieldFor(long eventsToProcess);
- void StoreGdkEventForLaterProcessing(GdkEvent* ev)
- { m_arrGdkEvents.Add(ev); }
-
#if wxUSE_EVENTLOOP_SOURCE
- virtual wxUnixEventLoopSource* CreateSource() const
- {
- return new wxUnixEventLoopSource();
- }
+ virtual wxEventLoopSource *
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
+#endif // wxUSE_EVENTLOOP_SOURCE
- virtual wxUnixEventLoopSource* CreateSource(int res,
- wxEventLoopSourceHandler* handler,
- int flags) const
- {
- return new wxUnixEventLoopSource(res, handler, flags);
- }
-#endif
-
-protected:
-#if wxUSE_EVENTLOOP_SOURCE
- // adding/removing sources
- virtual bool DoAddSource(wxAbstractEventLoopSource* source);
- virtual bool DoRemoveSource(wxAbstractEventLoopSource* source);
-
- // map of event loop sources gtk ids
- wxEventLoopSourceIdMap m_sourceIdMap;
-#endif
+ void StoreGdkEventForLaterProcessing(GdkEvent* ev)
+ { m_arrGdkEvents.Add(ev); }
+private:
// the exit code of this event loop
int m_exitcode;
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/gtk/evtloopsrc.h
+// Purpose: wxGTKEventLoopSource class
+// Author: Vadim Zeitlin
+// Created: 2009-10-21
+// RCS-ID: $Id: wxhead.h,v 1.11 2009-06-29 10:23:04 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_GTK_EVTLOOPSRC_H_
+#define _WX_GTK_EVTLOOPSRC_H_
+
+// ----------------------------------------------------------------------------
+// wxGTKEventLoopSource: wxEventLoopSource for GTK port
+// ----------------------------------------------------------------------------
+
+class wxGTKEventLoopSource : public wxEventLoopSource
+{
+public:
+ // sourceId is the id of the watch in GTK context, not the FD of the file
+ // this source corresponds to
+ wxGTKEventLoopSource(unsigned sourceId,
+ wxEventLoopSourceHandler *handler,
+ int flags)
+ : wxEventLoopSource(handler, flags),
+ m_sourceId(sourceId)
+ {
+ }
+
+ virtual ~wxGTKEventLoopSource();
+
+private:
+ const unsigned m_sourceId;
+
+ wxDECLARE_NO_COPY_CLASS(wxGTKEventLoopSource);
+};
+
+#endif // _WX_GTK_EVTLOOPSRC_H_
+
class OpaqueEventRef;
typedef OpaqueEventRef *EventRef;
-class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopManual
+class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxCFEventLoop
{
public:
wxGUIEventLoop();
virtual void WakeUp();
virtual bool YieldFor(long eventsToProcess);
+protected:
+ virtual CFRunLoopRef CFGetCurrentRunLoop() const;
+
private:
// dispatch an event and release it
void DispatchAndReleaseEvent(EventRef event);
#ifndef _WX_OSX_COCOA_EVTLOOP_H_
#define _WX_OSX_COCOA_EVTLOOP_H_
-class WXDLLIMPEXP_BASE wxGUIEventLoop : public wxEventLoopManual
+class WXDLLIMPEXP_BASE wxGUIEventLoop : public wxCFEventLoop
{
public:
- typedef wxMacEventLoopSource Source;
-
wxGUIEventLoop();
// implement/override base class pure virtual
virtual void WakeUp();
virtual bool YieldFor(long eventsToProcess);
-#if wxUSE_EVENTLOOP_SOURCE
- virtual wxMacEventLoopSource* CreateSource() const
- {
- return new wxMacEventLoopSource();
- }
-
- virtual wxMacEventLoopSource* CreateSource(int res,
- wxEventLoopSourceHandler* handler,
- int flags) const;
-
- virtual wxMacEventLoopSource* CreateSource(CFRunLoopSourceRef res,
- wxEventLoopSourceHandler* handler,
- int flags) const
- {
- return new wxMacEventLoopSource(res, handler, flags);
- }
-#endif
-
protected:
-#if wxUSE_EVENTLOOP_SOURCE
- // adding/removing sources
- virtual bool DoAddSource(wxAbstractEventLoopSource* source);
- virtual bool DoRemoveSource(wxAbstractEventLoopSource* source);
-#endif
+ virtual CFRunLoopRef CFGetCurrentRunLoop() const;
private:
double m_sleepTime;
wxCFRelease(m_ptr);
m_ptr = p; // Automatic conversion should occur
}
+
+ // Release the pointer, i.e. give up its ownership.
+ refType release()
+ {
+ refType p = m_ptr;
+ m_ptr = NULL;
+ return p;
+ }
+
protected:
/*! @var m_ptr The raw pointer.
*/
///////////////////////////////////////////////////////////////////////////////
-// Name: include/wx/mac/evtloop.h
+// Name: include/wx/osx/evtloop.h
// Purpose: simply forwards to wx/mac/carbon/evtloop.h for consistency with
// the other Mac headers
// Author: Vadim Zeitlin
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-#ifdef __WXOSX_COCOA__
- #include "wx/osx/cocoa/evtloop.h"
-#else
- #include "wx/osx/carbon/evtloop.h"
-#endif
+#ifndef _WX_OSX_EVTLOOP_H_
+#define _WX_OSX_EVTLOOP_H_
+typedef struct __CFRunLoop * CFRunLoopRef;
+
+class WXDLLIMPEXP_BASE wxCFEventLoop : public wxEventLoopManual
+{
+public:
+#if wxUSE_EVENTLOOP_SOURCE
+ virtual wxEventLoopSource *
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
+#endif // wxUSE_EVENTLOOP_SOURCE
+
+protected:
+ // get the currently executing CFRunLoop
+ virtual CFRunLoopRef CFGetCurrentRunLoop() const = 0;
+};
+
+#if wxUSE_GUI
+ #ifdef __WXOSX_COCOA__
+ #include "wx/osx/cocoa/evtloop.h"
+ #else
+ #include "wx/osx/carbon/evtloop.h"
+ #endif
+#endif // wxUSE_GUI
+
+#endif // _WX_OSX_EVTLOOP_H_
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/osx/evtloopsrc.h
+// Purpose: wxCFEventLoopSource class
+// Author: Vadim Zeitlin
+// Created: 2009-10-21
+// RCS-ID: $Id: wxhead.h,v 1.11 2009-06-29 10:23:04 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_OSX_EVTLOOPSRC_H_
+#define _WX_OSX_EVTLOOPSRC_H_
+
+typedef struct __CFFileDescriptor *CFFileDescriptorRef;
+
+// ----------------------------------------------------------------------------
+// wxCFEventLoopSource: CoreFoundation-based wxEventLoopSource for OS X
+// ----------------------------------------------------------------------------
+
+class wxCFEventLoopSource : public wxEventLoopSource
+{
+public:
+ wxCFEventLoopSource(wxEventLoopSourceHandler *handler, int flags)
+ : wxEventLoopSource(handler, flags)
+ {
+ m_cffd = NULL;
+ }
+
+ // we take ownership of this CFFileDescriptorRef
+ void SetFileDescriptor(CFFileDescriptorRef cffd);
+
+ virtual ~wxCFEventLoopSource();
+
+private:
+ CFFileDescriptorRef m_cffd;
+
+ wxDECLARE_NO_COPY_CLASS(wxCFEventLoopSource);
+};
+
+#endif // _WX_OSX_EVTLOOPSRC_H_
+
wxCHECK_MSG( m_watches.find(winfo.GetPath()) == m_watches.end(), false,
"Path '%s' is already watched");
- // conctruct watch entry
+ // construct watch entry
wxSharedPtr<wxFSWatchEntry> watch(new wxFSWatchEntry(winfo));
if (!DoAdd(watch))
- ///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
// Name: wx/unix/evtloop.h
// Purpose: declares wxEventLoop class
// Author: Lukasz Michalski (lm@zork.pl)
// ----------------------------------------------------------------------------
class wxFDIODispatcher;
+class wxUnixEventLoopSource;
namespace wxPrivate
{
class WXDLLIMPEXP_BASE wxConsoleEventLoop : public wxEventLoopManual
{
public:
- typedef wxUnixEventLoopSource Source;
-
// initialize the event loop, use IsOk() to check if we were successful
wxConsoleEventLoop();
virtual ~wxConsoleEventLoop();
virtual bool YieldFor(long WXUNUSED(eventsToProcess)) { return true; }
#if wxUSE_EVENTLOOP_SOURCE
- virtual wxUnixEventLoopSource* CreateSource() const
- {
- return new wxUnixEventLoopSource();
- }
-
- virtual wxUnixEventLoopSource* CreateSource(int res,
- wxEventLoopSourceHandler* handler,
- int flags) const
- {
- return new wxUnixEventLoopSource(res, handler, flags);
- }
-#endif
+ virtual wxEventLoopSource *
+ AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
+#endif // wxUSE_EVENTLOOP_SOURCE
protected:
-#if wxUSE_EVENTLOOP_SOURCE
- // adding/removing sources
- virtual bool DoAddSource(wxAbstractEventLoopSource* source);
- virtual bool DoRemoveSource(wxAbstractEventLoopSource* source);
-#endif
-
virtual void OnNextIteration();
private:
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/unix/evtloopsrc.h
+// Purpose: wxUnixEventLoopSource class
+// Author: Vadim Zeitlin
+// Created: 2009-10-21
+// RCS-ID: $Id: wxhead.h,v 1.11 2009-06-29 10:23:04 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_UNIX_EVTLOOPSRC_H_
+#define _WX_UNIX_EVTLOOPSRC_H_
+
+class wxFDIODispatcher;
+class wxFDIOHandler;
+
+// ----------------------------------------------------------------------------
+// wxUnixEventLoopSource: wxEventLoopSource for Unix-like toolkits using fds
+// ----------------------------------------------------------------------------
+
+class wxUnixEventLoopSource : public wxEventLoopSource
+{
+public:
+ // dispatcher and fdioHandler are only used here to allow us to unregister
+ // from the event loop when we're destroyed
+ wxUnixEventLoopSource(wxFDIODispatcher *dispatcher,
+ wxFDIOHandler *fdioHandler,
+ int fd,
+ wxEventLoopSourceHandler *handler,
+ int flags)
+ : wxEventLoopSource(handler, flags),
+ m_dispatcher(dispatcher),
+ m_fdioHandler(fdioHandler),
+ m_fd(fd)
+ {
+ }
+
+ virtual ~wxUnixEventLoopSource();
+
+private:
+ wxFDIODispatcher * const m_dispatcher;
+ wxFDIOHandler * const m_fdioHandler;
+ const int m_fd;
+
+ wxDECLARE_NO_COPY_CLASS(wxUnixEventLoopSource);
+};
+
+#endif // _WX_UNIX_EVTLOOPSRC_H_
+
#define WX_UNIX_PRIVATE_FSWATCHER_INOTIFY_H_
#include "wx/filename.h"
+#include "wx/evtloopsrc.h"
// ============================================================================
// wxFSWatcherEntry implementation & helper declarations
wxDECLARE_NO_COPY_CLASS(wxFSWatchEntryKq);
};
-
-// ============================================================================
-// wxFSWSourceHandler helper class
-// ============================================================================
-
-class wxFSWatcherImplKqueue;
-
-/**
- * Handler for handling i/o from inotify descriptor
- */
-class wxFSWSourceHandler : public wxEventLoopSourceHandler
-{
-public:
- wxFSWSourceHandler(wxFSWatcherImplKqueue* service) :
- m_service(service)
- { }
-
- virtual void OnReadWaiting();
- virtual void OnWriteWaiting();
- virtual void OnExceptionWaiting();
-
-protected:
- wxFSWatcherImplKqueue* m_service;
-};
-
#endif /* WX_UNIX_PRIVATE_FSWATCHER_KQUEUE_H_ */
// 'Main program' equivalent: the program execution "starts" here
virtual bool OnInit()
{
- // TODO remove then this code becomes rock-solid
- wxLog::AddTraceMask(wxTRACE_EVT_SOURCE);
+ wxLog::AddTraceMask("EventSource");
wxLog::AddTraceMask(wxTRACE_FSWATCHER);
// create the main application window
{
if (wxTheApp)
wxTheApp->OnEventLoopExit(this);
-
-#if wxUSE_EVENTLOOP_SOURCE
- // unregister all sources
- (void) RemoveAllSources();
-#endif
}
void wxEventLoopBase::WakeUpIdle()
#endif
#include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
#ifndef WX_PRECOMP
#include "wx/app.h"
// wxEventLoop adding & removing sources
// ----------------------------------------------------------------------------
+#if wxUSE_EVENTLOOP_SOURCE
+
extern "C"
{
static gboolean wx_on_channel_event(GIOChannel *channel,
- GIOCondition condition, gpointer data)
+ GIOCondition condition,
+ gpointer data)
{
- wxLogTrace(wxTRACE_EVT_SOURCE, "wx_on_channel_event, gtk_source_id=%d",
- g_io_channel_unix_get_fd(channel));
+ wxLogTrace(wxTRACE_EVT_SOURCE,
+ "wx_on_channel_event, fd=%d, condition=%08x",
+ g_io_channel_unix_get_fd(channel), condition);
- wxEventLoopSourceHandler* handler =
- static_cast<wxEventLoopSourceHandler*>(data);
+ wxEventLoopSourceHandler * const
+ handler = static_cast<wxEventLoopSourceHandler *>(data);
if (condition & G_IO_IN || condition & G_IO_PRI)
- {
handler->OnReadWaiting();
- }
- else if (condition & G_IO_OUT)
- {
+ if (condition & G_IO_OUT)
handler->OnWriteWaiting();
- }
else if (condition & G_IO_ERR || condition & G_IO_NVAL)
- {
handler->OnExceptionWaiting();
- }
- else
- {
- wxFAIL_MSG(wxString::Format("Inavlid condition=%d", condition));
- }
// we never want to remove source here, so always return true
return TRUE;
}
}
-bool wxGUIEventLoop::DoAddSource(wxAbstractEventLoopSource* src)
+wxEventLoopSource *
+wxGUIEventLoop::AddSourceForFD(int fd,
+ wxEventLoopSourceHandler *handler,
+ int flags)
{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
+ wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::DoAddSource() source=%d",
- source->GetResource());
-
- int flags = source->GetFlags();
int condition = 0;
if (flags & wxEVENT_SOURCE_INPUT)
condition |= G_IO_IN | G_IO_PRI;
if (flags & wxEVENT_SOURCE_EXCEPTION)
condition |= G_IO_ERR | G_IO_HUP | G_IO_NVAL;
- GIOChannel* channel = g_io_channel_unix_new(source->GetResource());
- int gtk_id = g_io_add_watch(channel, (GIOCondition)condition,
- &wx_on_channel_event, source->GetHandler());
+ 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);
- wxEventLoopSourceIdMap::value_type val(source, gtk_id);
- return m_sourceIdMap.insert(val).second;
+ 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);
}
-bool wxGUIEventLoop::DoRemoveSource(wxAbstractEventLoopSource* src)
+wxGTKEventLoopSource::~wxGTKEventLoopSource()
{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::DoRemoveSource() source=%d",
- source->GetResource());
+ "Removing event loop source with GTK id=%u", m_sourceId);
- wxEventLoopSourceIdMap::iterator it = m_sourceIdMap.find(source);
- wxCHECK_MSG( it != m_sourceIdMap.end(), false, "Source not on the list" );
-
- int gtk_id = it->second;
- m_sourceIdMap.erase(it);
- return g_source_remove(gtk_id);
+ g_source_remove(m_sourceId);
}
+#endif // wxUSE_EVENTLOOP_SOURCE
+
// ----------------------------------------------------------------------------
// wxEventLoop message processing dispatching
// ----------------------------------------------------------------------------
wxMacWakeUp();
}
+CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
+{
+ return CFRunLoopGetCurrent();
+}
+
void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent)
{
if ( wxTheApp )
wxMacWakeUp();
}
-//-----------------------------------------------------------------------------
-// event loop sources operations
-//-----------------------------------------------------------------------------
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-extern "C"
-{
-struct wx_cffd_data
-{
- wxEventLoopSourceHandler* handler;
- int flags;
-};
-
-static void wx_cffiledescriptor_callback(CFFileDescriptorRef cffd,
- CFOptionFlags flags, void* ctxData)
-{
- wxLogTrace(wxTRACE_EVT_SOURCE, "CFFileDescriptor Callback");
-
- wx_cffd_data* data = static_cast<wx_cffd_data*>(ctxData);
- wxEventLoopSourceHandler* handler = data->handler;
- if (flags & kCFFileDescriptorReadCallBack)
- handler->OnReadWaiting();
- if (flags & kCFFileDescriptorWriteCallBack)
- handler->OnWriteWaiting();
-
- // reenable callbacks
- if (data->flags & wxEVENT_SOURCE_INPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
- if (data->flags & wxEVENT_SOURCE_OUTPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
-}
-}
-
-wxMacEventLoopSource* wxGUIEventLoop::CreateSource(int fd,
- wxEventLoopSourceHandler* handler,
- int flags) const
-{
- wxMacEventLoopSource* source = new wxMacEventLoopSource();
- // FIXME this is currently a leak :-)
- wx_cffd_data* data = new wx_cffd_data;
- data->handler = handler;
- data->flags = flags;
- CFFileDescriptorContext ctx = { 0, data, NULL, NULL, NULL };
- CFFileDescriptorRef cffd = CFFileDescriptorCreate(kCFAllocatorDefault, fd,
- true, wx_cffiledescriptor_callback, &ctx);
-
- if (flags & wxEVENT_SOURCE_INPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
- if (flags & wxEVENT_SOURCE_OUTPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
-
- source->SetResource(
- CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
- source->SetHandler(handler);
- source->SetFlags(flags);
- return source;
-}
-#elif
-wxMacEventLoopSource* wxGUIEventLoop::CreateSource(int fd,
- wxEventLoopSourceHandler* handler,
- int flags) const
-{
- return NULL;
-}
-#endif
-
-bool wxGUIEventLoop::DoAddSource(wxAbstractEventLoopSource* src)
-{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::AddSource() source=%d",
- source->GetResource());
-
- NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
- CFRunLoopRef cfloop = [nsloop getCFRunLoop];
- CFRunLoopAddSource(cfloop, source->GetResource(), kCFRunLoopDefaultMode);
-
- return true;
-}
-
-bool wxGUIEventLoop::DoRemoveSource(wxAbstractEventLoopSource* src)
+CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::RemoveSource() source=%d",
- source->GetResource());
-
NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
- CFRunLoopRef cfloop = [nsloop getCFRunLoop];
- CFRunLoopRemoveSource(cfloop, source->GetResource(), kCFRunLoopDefaultMode);
-
- return true;
+ return [nsloop getCFRunLoop];
}
//-----------------------------------------------------------------------------
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: src/osx/core/evtloop_cf.cpp
+// Purpose: wxEventLoop implementation common to both Carbon and Cocoa
+// Author: Vadim Zeitlin
+// Created: 2009-10-18
+// RCS-ID: $Id: wxhead.cpp,v 1.10 2009-06-29 10:23:04 zeitlin Exp $
+// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/evtloop.h"
+
+#if wxUSE_EVENTLOOP_SOURCE
+
+#include "wx/evtloopsrc.h"
+
+#include "wx/scopedptr.h"
+
+#include "wx/osx/private.h"
+#include "wx/osx/core/cfref.h"
+
+// ============================================================================
+// wxCFEventLoopSource and wxCFEventLoop implementation
+// ============================================================================
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+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;
+
+ source->SetFileDescriptor(cffd.release());
+
+ wxCFRef<CFRunLoopSourceRef>
+ cfsrc(CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
+ if ( !cfsrc )
+ return NULL;
+
+ CFRunLoopRef cfloop = CFGetCurrentRunLoop();
+ CFRunLoopAddSource(cfloop, cfsrc, kCFRunLoopDefaultMode);
+
+ return source.release();
+}
+
+void wxCFEventLoopSource::SetFileDescriptor(CFFileDescriptorRef cffd)
+{
+ wxASSERT_MSG( !m_cffd, "shouldn't be called more than once" );
+
+ m_cffd = cffd;
+}
+
+wxCFEventLoopSource::~wxCFEventLoopSource()
+{
+ if ( m_cffd )
+ CFRelease(m_cffd);
+}
+
+#else // OS X < 10.5
+
+wxEventLoopSource *
+wxCFEventLoop::AddSourceForFD(int WXUNUSED(fd),
+ wxEventLoopSourceHandler * WXUNUSED(handler),
+ int WXUNUSED(flags))
+{
+ return NULL;
+}
+
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED
+
+#endif // wxUSE_EVENTLOOP_SOURCE
#include <errno.h>
#include "wx/apptrait.h"
+#include "wx/scopedptr.h"
#include "wx/thread.h"
#include "wx/module.h"
#include "wx/unix/pipe.h"
#include "wx/unix/private/epolldispatcher.h"
#include "wx/private/selectdispatcher.h"
+#if wxUSE_EVENTLOOP_SOURCE
+ #include "wx/evtloopsrc.h"
+#endif // wxUSE_EVENTLOOP_SOURCE
+
#define TRACE_EVENTS wxT("events")
// ===========================================================================
wxEventLoopSourceHandler* m_impl;
};
-bool wxConsoleEventLoop::DoAddSource(wxAbstractEventLoopSource* src)
+wxEventLoopSource *
+wxConsoleEventLoop::AddSourceForFD(int fd,
+ wxEventLoopSourceHandler *handler,
+ int flags)
{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
+ wxCHECK_MSG( fd != -1, NULL, "can't monitor invalid fd" );
wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxConsoleEventLoop::AddSource() source=%d",
- source->GetResource());
+ "Adding event loop source for fd=%d", fd);
- // translating into wxFDIOHandler
- // XXX this is a memory leak of course, but this is really temporary, so
- // we are not creating another map of handlers
- wxFDIOHandler* h = new wxFDIOEventLoopSourceHandler(source->GetHandler());
+ // we need a bridge to wxFDIODispatcher
+ //
+ // TODO: refactor the code so that only wxEventLoopSourceHandler is used
+ wxScopedPtr<wxFDIOHandler>
+ fdioHandler(new wxFDIOEventLoopSourceHandler(handler));
- return m_dispatcher->RegisterFD(source->GetResource(), h,
- source->GetFlags());
+ if ( !m_dispatcher->RegisterFD(fd, fdioHandler.get(), flags) )
+ return NULL;
+
+ return new wxUnixEventLoopSource(m_dispatcher, fdioHandler.release(),
+ fd, handler, flags);
}
-bool wxConsoleEventLoop::DoRemoveSource(wxAbstractEventLoopSource* src)
+wxUnixEventLoopSource::~wxUnixEventLoopSource()
{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxConsoleEventLoop::RemoveSource() source=%d",
- source->GetResource());
+ "Removing event loop source for fd=%d", m_fd);
- return m_dispatcher->UnregisterFD(source->GetResource());
+ m_dispatcher->UnregisterFD(m_fd);
+
+ delete m_fdioHandler;
}
-#endif
+
+#endif // wxUSE_EVENTLOOP_SOURCE
//-----------------------------------------------------------------------------
// events dispatch and loop handling
public:
wxFSWatcherImplUnix(wxFileSystemWatcherBase* watcher) :
wxFSWatcherImpl(watcher),
- m_loop(NULL),
- m_source(NULL)
+ m_source(NULL),
+ m_ifd(-1)
{
m_handler = new wxFSWSourceHandler(this);
}
bool Init()
{
wxCHECK_MSG( !IsOk(), false, "Inotify already initialized" );
- wxCHECK_MSG( m_loop == NULL, false, "Event loop != NULL");
- m_loop = (wxEventLoopBase::GetActive());
- wxCHECK_MSG( m_loop, false, "File system watcher needs an active loop" );
+ wxEventLoopBase *loop = wxEventLoopBase::GetActive();
+ wxCHECK_MSG( loop, false, "File system watcher needs an event loop" );
- int fd = inotify_init();
- if (fd == -1)
+ m_ifd = inotify_init();
+ if ( m_ifd == -1 )
{
wxLogSysError( _("Unable to create inotify instance") );
return false;
}
- int flags = wxEVENT_SOURCE_INPUT | wxEVENT_SOURCE_EXCEPTION;
- m_source = static_cast<wxUnixEventLoopSource*>(
- m_loop->CreateSource(fd, m_handler, flags));
- return RegisterSource();
+ m_source = loop->AddSourceForFD
+ (
+ m_ifd,
+ m_handler,
+ wxEVENT_SOURCE_INPUT | wxEVENT_SOURCE_EXCEPTION
+ );
+
+ return m_source != NULL;
}
- bool Close()
+ void Close()
{
- wxCHECK_MSG( IsOk(), false,
+ wxCHECK_RET( IsOk(),
"Inotify not initialized or invalid inotify descriptor" );
- wxCHECK_MSG( m_loop, false,
- "m_loop shouldn't be null if inotify is initialized" );
- // ignore errors
- (void) UnregisterSource();
+ delete m_source;
+ m_source = NULL;
- int ret = close(m_source->GetResource());
- if (ret == -1)
+ if ( close(m_ifd) != 0 )
{
wxLogSysError( _("Unable to close inotify instance") );
}
- m_source->Invalidate();
-
- return ret != -1;
}
virtual bool DoAdd(wxSharedPtr<wxFSWatchEntryUnix> watch)
return event_count;
}
- bool IsOk()
+ bool IsOk() const
{
- return m_source && m_source->IsOk();
+ return m_source != NULL;
}
protected:
- bool RegisterSource()
- {
- wxCHECK_MSG( IsOk(), false,
- "Inotify not initialized or invalid inotify descriptor" );
-
- bool ret = m_loop->AddSource(m_source);
- return ret;
- }
-
- bool UnregisterSource()
- {
- wxCHECK_MSG( IsOk(), false,
- "Inotify not initialized or invalid inotify descriptor" );
- wxCHECK_MSG( m_loop, false,
- "m_loop shouldn't be null if inotify is initialized" );
-
- bool ret = m_loop->RemoveSource(m_source);
- m_loop = NULL;
- return ret;
- }
-
int DoAddInotify(wxFSWatchEntry* watch)
{
int flags = Watcher2NativeFlags(watch->GetFlags());
- int wd = inotify_add_watch(m_source->GetResource(),
- watch->GetPath().fn_str(),
- flags);
+ int wd = inotify_add_watch(m_ifd, watch->GetPath().fn_str(), flags);
// finally we can set watch descriptor
watch->SetWatchDescriptor(wd);
return wd;
int DoRemoveInotify(wxFSWatchEntry* watch)
{
- return inotify_rm_watch(m_source->GetResource(),
- watch->GetWatchDescriptor());
+ return inotify_rm_watch(m_ifd, watch->GetWatchDescriptor());
}
void ProcessNativeEvent(const inotify_event& inevt)
"Inotify not initialized or invalid inotify descriptor" );
memset(buf, 0, size);
- ssize_t left = read(m_source->GetResource(), buf, size);
+ ssize_t left = read(m_ifd, buf, size);
if (left == -1)
{
wxLogSysError(_("Unable to read from inotify descriptor"));
wxFSWSourceHandler* m_handler; // handler for inotify event source
wxFSWatchEntryDescriptors m_watchMap; // inotify wd=>wxFSWatchEntry* map
wxInotifyCookies m_cookies; // map to track renames
- wxEventLoopBase* m_loop;
- wxUnixEventLoopSource* m_source; // our event loop source
+ wxEventLoopSource* m_source; // our event loop source
+
+ // file descriptor created by inotify_init()
+ int m_ifd;
};
#include <sys/types.h>
#include <sys/event.h>
+
#include "wx/dynarray.h"
+#include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
+
#include "wx/private/fswatcher.h"
+// ============================================================================
+// wxFSWSourceHandler helper class
+// ============================================================================
+
+class wxFSWatcherImplKqueue;
+
+/**
+ * Handler for handling i/o from inotify descriptor
+ */
+class wxFSWSourceHandler : public wxEventLoopSourceHandler
+{
+public:
+ wxFSWSourceHandler(wxFSWatcherImplKqueue* service) :
+ m_service(service)
+ { }
+
+ virtual void OnReadWaiting();
+ virtual void OnWriteWaiting();
+ virtual void OnExceptionWaiting();
+
+protected:
+ wxFSWatcherImplKqueue* m_service;
+};
+
// ============================================================================
// wxFSWatcherImpl implementation & helper wxFSWSourceHandler implementation
// ============================================================================
public:
wxFSWatcherImplKqueue(wxFileSystemWatcherBase* watcher) :
wxFSWatcherImpl(watcher),
- m_loop(NULL),
m_source(NULL),
m_kfd(-1)
{
m_handler = new wxFSWSourceHandler(this);
}
- ~wxFSWatcherImplKqueue()
+ virtual ~wxFSWatcherImplKqueue()
{
// we close kqueue only if initialized before
if (IsOk())
{
wxCHECK_MSG( !IsOk(), false,
"Kqueue appears to be already initialized" );
- wxCHECK_MSG( m_loop == NULL, false, "Event loop != NULL");
- m_loop = (wxEventLoopBase::GetActive());
- wxCHECK_MSG( m_loop, false, "File system watcher needs an active loop" );
+ wxEventLoopBase *loop = wxEventLoopBase::GetActive();
+ wxCHECK_MSG( loop, false, "File system watcher needs an active loop" );
// create kqueue
m_kfd = kqueue();
}
// create source
- int flags = wxEVENT_SOURCE_INPUT;
- m_source = m_loop->CreateSource(m_kfd, m_handler, flags);
- wxCHECK_MSG( m_source, false,
- "Active loop has no support for fd-based sources" );
+ m_source = loop->AddSourceForFD(m_kfd, m_handler, wxEVENT_SOURCE_INPUT);
- return RegisterSource();
+ return m_source != NULL;
}
- bool Close()
+ void Close()
{
- wxCHECK_MSG( IsOk(), false,
+ wxCHECK_RET( IsOk(),
"Kqueue not initialized or invalid kqueue descriptor" );
- wxCHECK_MSG( m_loop, false,
- "m_loop shouldn't be null if kqueue is initialized" );
-
- // ignore errors
- (void) UnregisterSource();
- int ret = close(m_kfd);
- if (ret == -1)
+ if ( close(m_kfd) != 0 )
{
- wxLogSysError(_("Unable to close kqueue instance"));
+ wxLogSysError(_("Error closing kqueue instance"));
}
- m_source->Invalidate();
- return ret != -1;
+ delete m_source;
+ m_source = NULL;
}
virtual bool DoAdd(wxSharedPtr<wxFSWatchEntryKq> watch)
return true;
}
- bool IsOk()
+ bool IsOk() const
{
- return m_source && m_source->IsOk();
+ return m_source != NULL;
}
-/*
- wxAbstractEventLoopSource* GetSource() const
- {
- return m_source;
- }*/
-
protected:
- bool RegisterSource()
- {
- wxCHECK_MSG( IsOk(), false,
- "Kqueue not initialized or invalid kqueue descriptor" );
-
- return m_loop->AddSource(m_source);
- }
-
- bool UnregisterSource()
- {
- wxCHECK_MSG( IsOk(), false,
- "Kqueue not initialized or invalid kqueue descriptor" );
- wxCHECK_MSG( m_loop, false,
- "m_loop shouldn't be null if kqueue is initialized" );
-
- bool ret = m_loop->RemoveSource(m_source);
- m_loop = NULL;
- return ret;
- }
-
// returns all new dirs/files present in the immediate level of the dir
// pointed by watch.GetPath(). "new" means created between the last time
// the state of watch was computed and now
- void FindChanges(wxFSWatchEntryKq& watch, wxArrayString& changedFiles,
- wxArrayInt& changedFlags)
+ void FindChanges(wxFSWatchEntryKq& watch,
+ wxArrayString& changedFiles,
+ wxArrayInt& changedFlags)
{
wxFSWatchEntryKq::wxDirState old = watch.GetLastState();
watch.RefreshState();
}
wxFSWSourceHandler* m_handler; // handler for kqueue event source
- wxEventLoopBase* m_loop; // event loop we have registered with
- wxAbstractEventLoopSource* m_source; // our event loop source
+ wxEventLoopSource* m_source; // our event loop source
+
+ // descriptor created by kqueue()
int m_kfd;
};