]> git.saurik.com Git - wxWidgets.git/commitdiff
Refactor wxEventLoopSource-related code.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 22 Oct 2009 11:36:35 +0000 (11:36 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 22 Oct 2009 11:36:35 +0000 (11:36 +0000)
Currently wxEventLoopSource can't be created directly and can only be used to
monitor file descriptors so reduce the API to just wxEventLoop::AddSourceForFD()
and remove AddSource(), RemoveSource() and RemoveAllSources() which couldn't
be implemented for all ports. This makes the code much simpler without any
loss of functionality.

Make wxEventLoopSource responsible for removing itself from the event loop
when it is deleted. This allows to remove IsOk() and Invalidate() methods
making the code simpler and gets rid of various sets/maps which were used
before.

This also allows to support event loop sources in Carbon as well: wxOSX/Carbon
now compiles and works with wxUSE_FSWATCHER==1.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62475 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

25 files changed:
Makefile.in
build/bakefiles/files.bkl
include/wx/evtloop.h
include/wx/evtloopsrc.h [new file with mode: 0644]
include/wx/gtk/evtloop.h
include/wx/gtk/evtloopsrc.h [new file with mode: 0644]
include/wx/osx/carbon/evtloop.h
include/wx/osx/cocoa/evtloop.h
include/wx/osx/core/cfref.h
include/wx/osx/evtloop.h
include/wx/osx/evtloopsrc.h [new file with mode: 0644]
include/wx/private/fswatcher.h
include/wx/unix/evtloop.h
include/wx/unix/evtloopsrc.h [new file with mode: 0644]
include/wx/unix/private/fswatcher_inotify.h
include/wx/unix/private/fswatcher_kqueue.h
samples/fswatcher/fswatcher.cpp
src/common/evtloopcmn.cpp
src/gtk/evtloop.cpp
src/osx/carbon/evtloop.cpp
src/osx/cocoa/evtloop.mm
src/osx/core/evtloop_cf.cpp [new file with mode: 0644]
src/unix/evtloopunix.cpp
src/unix/fswatcher_inotify.cpp
src/unix/fswatcher_kqueue.cpp

index 2b6de3e20a4983e3f7984cd67bb08123699a7160..48d0fa717ed21eeb92efcac6f088e32bd68a9b4d 100644 (file)
@@ -2046,6 +2046,7 @@ COND_TOOLKIT__BASE_OSX_SRC =  \
        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
@@ -2068,6 +2069,7 @@ COND_TOOLKIT_COCOA_BASE_OSX_SRC =  \
        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
@@ -2090,6 +2092,7 @@ COND_TOOLKIT_GTK_BASE_OSX_SRC =  \
        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
@@ -2112,6 +2115,7 @@ COND_TOOLKIT_MOTIF_BASE_OSX_SRC =  \
        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
@@ -2119,6 +2123,7 @@ COND_TOOLKIT_MOTIF_BASE_OSX_SRC =  \
 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 \
@@ -2141,6 +2146,7 @@ COND_TOOLKIT_OSX_CARBON_BASE_OSX_SRC =  \
 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 \
@@ -2178,6 +2184,7 @@ COND_TOOLKIT_X11_BASE_OSX_SRC =  \
        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
@@ -3960,6 +3967,7 @@ COND_USE_SOVERSOLARIS_1___monodll___so_symlinks_uninst_cmd = rm -f \
 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 \
@@ -5777,6 +5785,7 @@ COND_MONOLITHIC_1_SHARED_0___monolib___depname = \
 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 \
@@ -7647,6 +7656,7 @@ COND_USE_SOVERSOLARIS_1___basedll___so_symlinks_uninst_cmd = rm -f \
 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 \
@@ -7746,6 +7756,7 @@ COND_MONOLITHIC_0_SHARED_0___baselib___depname = \
 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 \
@@ -14866,6 +14877,9 @@ monodll_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(MONODLL_ODEP)
 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
 
@@ -19660,6 +19674,9 @@ monolib_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(MONOLIB_ODEP)
 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
 
@@ -24454,6 +24471,9 @@ basedll_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(BASEDLL_ODEP)
 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
 
@@ -24946,6 +24966,9 @@ baselib_core_mimetype.o: $(srcdir)/src/osx/core/mimetype.cpp $(BASELIB_ODEP)
 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
 
index edcf05e6a8f5f651a674f13dd27e9ea2f3932de1..7b9e19a7aec54556d4483f90c85760cfbfc9a3e7 100644 (file)
@@ -79,6 +79,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     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
@@ -186,6 +187,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
 <!-- 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
@@ -892,6 +894,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     wx/docview.h
     wx/effects.h
     wx/evtloop.h
+    wx/evtloopsrc.h
     wx/fdrepdlg.h
     wx/filectrl.h
     wx/filepicker.h
@@ -1057,6 +1060,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     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
@@ -2367,6 +2371,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     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
index 31db6dc9db58c80a644a5a0d7c2823ab2c9d1ec3..7a9495afbfc0ffb613d784634385049185ccf2ee 100644 (file)
 
 #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
     ------------------------------------------
@@ -267,67 +79,11 @@ public:
     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
     // -------------------
@@ -414,13 +170,6 @@ public:
 
 
 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)
@@ -479,18 +228,31 @@ private:
 
 #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"
@@ -538,16 +300,13 @@ protected:
 
 #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__))
diff --git a/include/wx/evtloopsrc.h b/include/wx/evtloopsrc.h
new file mode 100644 (file)
index 0000000..b626bdf
--- /dev/null
@@ -0,0 +1,99 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_
+
index d6e632fa7c1fcbcbfefc5d85f3821a32ea160e06..d08356786232838577439ce8d9736ff1e91e6937 100644 (file)
 
 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();
@@ -38,33 +30,15 @@ public:
     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;
 
diff --git a/include/wx/gtk/evtloopsrc.h b/include/wx/gtk/evtloopsrc.h
new file mode 100644 (file)
index 0000000..11ab82a
--- /dev/null
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_
+
index d704a9c50ca4b284ede5c64e002fb41eddf9e49c..e6d29419d6c2c0ff1950cc27198ed782a49c98c3 100644 (file)
@@ -15,7 +15,7 @@
 class OpaqueEventRef;
 typedef OpaqueEventRef *EventRef;
 
-class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxEventLoopManual
+class WXDLLIMPEXP_CORE wxGUIEventLoop : public wxCFEventLoop
 {
 public:
     wxGUIEventLoop();
@@ -28,6 +28,9 @@ public:
     virtual void WakeUp();
     virtual bool YieldFor(long eventsToProcess);
 
+protected:
+    virtual CFRunLoopRef CFGetCurrentRunLoop() const;
+
 private:
     // dispatch an event and release it
     void DispatchAndReleaseEvent(EventRef event);
index 63c565721c9a0d7f00327a737ac8067b2267d76d..8fc7c332581d1d9bc81b318211bbe8109f22ed2a 100644 (file)
 #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
@@ -26,30 +24,8 @@ public:
     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;
index f5251ab1c07ef335b0b7244e6ffcc0b14a503dd6..eb6adeeee03f22f67c19ff473f611bc084a5ea47 100644 (file)
@@ -308,6 +308,15 @@ public:
         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.
     */
index 7b1b1f5f5db73e8df5edef0c3604b5abd7f26e71..a295706f588a26cc0efc0f3a8d74ff28eeb479ad 100644 (file)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// 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_
diff --git a/include/wx/osx/evtloopsrc.h b/include/wx/osx/evtloopsrc.h
new file mode 100644 (file)
index 0000000..22ab30a
--- /dev/null
@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_
+
index 286fba854728c3eeb17e8ad9d0f296e67f47a1a7..d10b4036da88228a9b56d755ec8f0bc4a2b2db41 100644 (file)
@@ -52,7 +52,7 @@ public:
         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))
index 35d918390c6547bc9cea9946c873ba6a21547535..40d30077874b5e3a96032ea070611e95b85213a2 100644 (file)
@@ -1,4 +1,4 @@
-    ///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
 // Name:        wx/unix/evtloop.h
 // Purpose:     declares wxEventLoop class
 // Author:      Lukasz Michalski (lm@zork.pl)
@@ -18,6 +18,7 @@
 // ----------------------------------------------------------------------------
 
 class wxFDIODispatcher;
+class wxUnixEventLoopSource;
 
 namespace wxPrivate
 {
@@ -27,8 +28,6 @@ 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();
@@ -42,26 +41,11 @@ public:
     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:
diff --git a/include/wx/unix/evtloopsrc.h b/include/wx/unix/evtloopsrc.h
new file mode 100644 (file)
index 0000000..20e2762
--- /dev/null
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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_
+
index ea6f8886c323360163ab533bf4c6c3ed8bb3e829..56ab35892a6b4f06562a58c589fe4ad077fa9bd4 100644 (file)
@@ -12,6 +12,7 @@
 #define WX_UNIX_PRIVATE_FSWATCHER_INOTIFY_H_
 
 #include "wx/filename.h"
+#include "wx/evtloopsrc.h"
 
 // ============================================================================
 // wxFSWatcherEntry implementation & helper declarations
index 1b56887b8e3ead7e73c0a7c37f4ea81782362ef8..181c37531f5a9c279f678dac8f3044fba29da30d 100644 (file)
@@ -106,29 +106,4 @@ private:
     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_ */
index 51014172df941b4c468377910d174531cc5c02ad..7b30d4212e5574157010a2ed2a78e46d42a76c68 100644 (file)
@@ -66,8 +66,7 @@ public:
     // '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
index 9b7265510623ce1090d2fd3d41fd8ffeeadc8b84..5f9894d12501b99563129bcd4b3a1d8005627106 100644 (file)
@@ -54,11 +54,6 @@ void wxEventLoopBase::OnExit()
 {
     if (wxTheApp)
         wxTheApp->OnEventLoopExit(this);
-
-#if wxUSE_EVENTLOOP_SOURCE
-    // unregister all sources
-    (void) RemoveAllSources();
-#endif
 }
 
 void wxEventLoopBase::WakeUpIdle()
index 9d43d56d9e8030c56b96b568f607ec3bd1e9c3f4..1c656d56615c20891d9b7a58b1cf475be9557000 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 
 #include "wx/evtloop.h"
+#include "wx/evtloopsrc.h"
 
 #ifndef WX_PRECOMP
     #include "wx/app.h"
@@ -86,49 +87,40 @@ void wxGUIEventLoop::WakeUp()
 // 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;
@@ -137,32 +129,38 @@ bool wxGUIEventLoop::DoAddSource(wxAbstractEventLoopSource* src)
     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
 // ----------------------------------------------------------------------------
index cdfda0653dac13b3b2344724164b7e8dd70b71b8..928e7f90a76c359f8564e3f5fbc987e5460d7cf3 100644 (file)
@@ -49,6 +49,11 @@ void wxGUIEventLoop::WakeUp()
     wxMacWakeUp();
 }
 
+CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
+{
+    return CFRunLoopGetCurrent();
+}
+
 void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent)
 {
     if ( wxTheApp )
index 78f7749d7ea39c386ae6a892dab057a1bbce94e3..4798214f02d40d2e565fe441f8cc81d893ae7f3f 100644 (file)
@@ -87,102 +87,10 @@ void wxGUIEventLoop::WakeUp()
     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];
 }
 
 //-----------------------------------------------------------------------------
diff --git a/src/osx/core/evtloop_cf.cpp b/src/osx/core/evtloop_cf.cpp
new file mode 100644 (file)
index 0000000..a0e3098
--- /dev/null
@@ -0,0 +1,138 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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
index b082984019b700bf980ce856672b7defb442d972..453f1c354ae6056d8c0c9f6b6764f956016d6dcb 100644 (file)
@@ -30,6 +30,7 @@
 
 #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")
 
 // ===========================================================================
@@ -220,36 +225,40 @@ protected:
     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
index 229af98eee66685b107d8d8ed9f2b407ce8350c2..edb3c52765a4bba4f830e5b997667732e0b05254 100644 (file)
@@ -45,8 +45,8 @@ class wxFSWatcherImplUnix : public wxFSWatcherImpl
 public:
     wxFSWatcherImplUnix(wxFileSystemWatcherBase* watcher) :
         wxFSWatcherImpl(watcher),
-        m_loop(NULL),
-        m_source(NULL)
+        m_source(NULL),
+        m_ifd(-1)
     {
         m_handler = new wxFSWSourceHandler(this);
     }
@@ -65,42 +65,39 @@ public:
     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)
@@ -193,39 +190,16 @@ public:
         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;
@@ -233,8 +207,7 @@ protected:
 
     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)
@@ -352,7 +325,7 @@ protected:
                     "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"));
@@ -451,8 +424,10 @@ protected:
     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;
 };
 
 
index ccadcb609007d7705e12cef473e6bdd2f7efd5ea..e1046e2ea4b3749b61913428c62fad910879d92c 100644 (file)
 
 #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
 // ============================================================================
@@ -38,14 +66,13 @@ class wxFSWatcherImplKqueue : public wxFSWatcherImpl
 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())
@@ -60,10 +87,9 @@ public:
     {
         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();
@@ -74,32 +100,23 @@ public:
         }
 
         // 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)
@@ -186,43 +203,18 @@ public:
         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();
@@ -386,8 +378,9 @@ protected:
     }
 
     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;
 };