]> git.saurik.com Git - wxWidgets.git/blobdiff - utils/wxPython/src/helpers.h
Lots more support for event-less callbacks
[wxWidgets.git] / utils / wxPython / src / helpers.h
index a8c06a23e024e82bcfb640b4a7702bda736daf1f..54baeab6f644baf2199004eb37610e27c7675208 100644 (file)
 #define wxPy_END_ALLOW_THREADS
 #endif
 
-#ifdef WXP_WITH_THREAD
-extern PyThreadState*   wxPyEventThreadState;
-extern bool             wxPyInEvent;
-#endif
 
 //---------------------------------------------------------------------------
 
@@ -69,6 +65,8 @@ PyObject* __wxSetDictionary(PyObject*, PyObject* args);
 void wxPyEventThunker(wxObject*, wxEvent& event);
 
 HELPEREXPORT PyObject* wxPyConstructObject(void* ptr, char* className);
+HELPEREXPORT bool wxPyRestoreThread();
+HELPEREXPORT void wxPySaveThread(bool doSave);
 
 //----------------------------------------------------------------------
 
@@ -76,6 +74,7 @@ HELPEREXPORT PyObject* wxPyConstructObject(void* ptr, char* className);
 #ifndef SWIGCODE
 extern "C" void SWIG_MakePtr(char *, void *, char *);
 extern "C" char *SWIG_GetPtr(char *, void **, char *);
+extern "C" char *SWIG_GetPtrObj(PyObject *obj, void **ptr, char *type);
 #endif
 
 
@@ -154,6 +153,9 @@ private:
 // method redirections.  For all classes which have virtuals which should be
 // overridable in wxPython, a new subclass is created that contains a
 // wxPyCallbackHelper.
+//
+// **** This class should be combined with wxPyCallback defined above.
+//
 //---------------------------------------------------------------------------
 
 class HELPEREXPORT wxPyCallbackHelper {
@@ -180,19 +182,6 @@ private:
 // return type, if any as well as any parameter types.
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__(PCLASS, CBNAME)                                    \
-    void CBNAME() {                                                     \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("()"));                 \
-        else                                                            \
-            PCLASS::CBNAME();                                           \
-    }                                                                   \
-    void base_##CBNAME() {                                              \
-        PCLASS::CBNAME();                                               \
-    }
-
-//---------------------------------------------------------------------------
-
 #define PYPRIVATE                               \
     void _setSelf(PyObject* self) {             \
         m_myInst.setSelf(self);                 \
@@ -201,242 +190,386 @@ private:
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK_BOOL_INTINT(PCLASS, CBNAME)                          \
-    bool CBNAME(int a, int b) {                                         \
+#define DEC_PYCALLBACK__(CBNAME)                        \
+    void CBNAME();                                      \
+    void base_##CBNAME();
+
+
+#define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME)         \
+    void CLASS::CBNAME() {                              \
+        bool doSave = wxPyRestoreThread();              \
+        if (m_myInst.findCallback(#CBNAME))             \
+            m_myInst.callCallback(Py_BuildValue("()")); \
+        else                                            \
+            PCLASS::CBNAME();                           \
+        wxPySaveThread(doSave);                         \
+    }                                                   \
+    void CLASS::base_##CBNAME() {                       \
+        PCLASS::CBNAME();                               \
+    }
+
+//---------------------------------------------------------------------------
+
+#define DEC_PYCALLBACK_BOOL_INTINT(CBNAME)                      \
+    bool CBNAME(int a, int b);                                  \
+    bool base_##CBNAME(int a, int b);
+
+
+#define IMP_PYCALLBACK_BOOL_INTINT(CLASS, PCLASS, CBNAME)               \
+    bool CLASS::CBNAME(int a, int b) {                                  \
+        bool rval;                                                      \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
-            return m_myInst.callCallback(Py_BuildValue("(ii)",a,b));    \
+            rval = m_myInst.callCallback(Py_BuildValue("(ii)",a,b));    \
         else                                                            \
-            return PCLASS::CBNAME(a,b);                                 \
+            rval = PCLASS::CBNAME(a,b);                                 \
+        wxPySaveThread(doSave);                                         \
+        return rval;                                                    \
     }                                                                   \
-    bool base_##CBNAME(int a, int b) {                                  \
+    bool CLASS::base_##CBNAME(int a, int b) {                           \
         return PCLASS::CBNAME(a,b);                                     \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK_BOOL_INT(PCLASS, CBNAME)                             \
-    bool CBNAME(int a) {                                                \
+#define DEC_PYCALLBACK_BOOL_INT(CBNAME)                         \
+    bool CBNAME(int a);                                         \
+    bool base_##CBNAME(int a);
+
+
+#define IMP_PYCALLBACK_BOOL_INT(CLASS, PCLASS, CBNAME)                  \
+    bool CLASS::CBNAME(int a) {                                         \
+        bool rval;                                                      \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
-            return m_myInst.callCallback(Py_BuildValue("(i)",a));       \
+            rval = m_myInst.callCallback(Py_BuildValue("(i)",a));       \
         else                                                            \
-            return PCLASS::CBNAME(a);                                   \
+            rval = PCLASS::CBNAME(a);                                   \
+        wxPySaveThread(doSave);                                         \
+        return rval;                                                    \
     }                                                                   \
-    bool base_##CBNAME(int a) {                                         \
+    bool CLASS::base_##CBNAME(int a) {                                  \
         return PCLASS::CBNAME(a);                                       \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK_BOOL_INT_pure(PCLASS, CBNAME)                        \
-    bool CBNAME(int a) {                                                \
+#define DEC_PYCALLBACK_BOOL_INT_pure(CBNAME)            \
+    bool CBNAME(int a);
+
+
+#define IMP_PYCALLBACK_BOOL_INT_pure(CLASS, PCLASS, CBNAME)             \
+    bool CLASS::CBNAME(int a) {                                         \
+        bool rval;                                                      \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
-            return m_myInst.callCallback(Py_BuildValue("(i)",a));       \
-        else return false;                                              \
+            rval = m_myInst.callCallback(Py_BuildValue("(i)",a));       \
+        else rval = false;                                              \
+        wxPySaveThread(doSave);                                         \
+        return rval;                                                    \
     }
 
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DC(PCLASS, CBNAME)                                  \
-    void CBNAME(wxDC& a) {                                              \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(O)",                  \
-                            wxPyConstructObject(&a, "wxDC")));           \
-        else                                                            \
-            PCLASS::CBNAME(a);                                          \
-    }                                                                   \
-    void base_##CBNAME(wxDC& a) {                                       \
-        PCLASS::CBNAME(a);                                              \
+#define DEC_PYCALLBACK__DC(CBNAME)                      \
+    void CBNAME(wxDC& a);                               \
+    void base_##CBNAME(wxDC& a);
+
+
+#define IMP_PYCALLBACK__DC(CLASS, PCLASS, CBNAME)               \
+    void CLASS::CBNAME(wxDC& a) {                               \
+        bool doSave = wxPyRestoreThread();                      \
+        if (m_myInst.findCallback(#CBNAME))                     \
+            m_myInst.callCallback(Py_BuildValue("(O)",          \
+                            wxPyConstructObject(&a, "wxDC")));  \
+        else                                                    \
+            PCLASS::CBNAME(a);                                  \
+        wxPySaveThread(doSave);                                 \
+    }                                                           \
+    void CLASS::base_##CBNAME(wxDC& a) {                        \
+        PCLASS::CBNAME(a);                                      \
     }
 
 
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DCBOOL(PCLASS, CBNAME)                              \
-    void CBNAME(wxDC& a, bool b) {                                      \
+#define DEC_PYCALLBACK__DCBOOL(CBNAME)                  \
+    void CBNAME(wxDC& a, bool b);                       \
+    void base_##CBNAME(wxDC& a, bool b);
+
+
+#define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME)                   \
+    void CLASS::CBNAME(wxDC& a, bool b) {                               \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
             m_myInst.callCallback(Py_BuildValue("(Oi)",                 \
-                            wxPyConstructObject(&a, "wxDC"), (int)b));   \
+                            wxPyConstructObject(&a, "wxDC"), (int)b));  \
         else                                                            \
             PCLASS::CBNAME(a, b);                                       \
+        wxPySaveThread(doSave);                                         \
     }                                                                   \
-    void base_##CBNAME(wxDC& a, bool b) {                               \
+    void CLASS::base_##CBNAME(wxDC& a, bool b) {                        \
         PCLASS::CBNAME(a, b);                                           \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DCBOOL(PCLASS, CBNAME)                              \
-    void CBNAME(wxDC& a, bool b) {                                      \
+#define DEC_PYCALLBACK__DCBOOL(CBNAME)                          \
+    void CBNAME(wxDC& a, bool b);                               \
+    void base_##CBNAME(wxDC& a, bool b);
+
+
+#define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME)                   \
+    void CLASS::CBNAME(wxDC& a, bool b) {                               \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
             m_myInst.callCallback(Py_BuildValue("(Oi)",                 \
-                            wxPyConstructObject(&a, "wxDC"), (int)b));   \
+                            wxPyConstructObject(&a, "wxDC"), (int)b));  \
         else                                                            \
             PCLASS::CBNAME(a, b);                                       \
+                wxPySaveThread(doSave);                                 \
     }                                                                   \
-    void base_##CBNAME(wxDC& a, bool b) {                               \
+    void CLASS::base_##CBNAME(wxDC& a, bool b) {                        \
         PCLASS::CBNAME(a, b);                                           \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__2DBL(PCLASS, CBNAME)                                \
-    void CBNAME(double a, double b) {                                   \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(dd)",a,b));           \
-        else                                                            \
-            PCLASS::CBNAME(a, b);                                       \
-    }                                                                   \
-    void base_##CBNAME(double a, double b) {                            \
-        PCLASS::CBNAME(a, b);                                           \
+#define DEC_PYCALLBACK__2DBL(CBNAME)                    \
+    void CBNAME(double a, double b);                    \
+    void base_##CBNAME(double a, double b);
+
+
+#define IMP_PYCALLBACK__2DBL(CLASS, PCLASS, CBNAME)             \
+    void CLASS::CBNAME(double a, double b) {                    \
+        bool doSave = wxPyRestoreThread();                      \
+        if (m_myInst.findCallback(#CBNAME))                     \
+            m_myInst.callCallback(Py_BuildValue("(dd)",a,b));   \
+        else                                                    \
+            PCLASS::CBNAME(a, b);                               \
+        wxPySaveThread(doSave);                                 \
+    }                                                           \
+    void CLASS::base_##CBNAME(double a, double b) {             \
+        PCLASS::CBNAME(a, b);                                   \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__2DBL2INT(PCLASS, CBNAME)                            \
-    void CBNAME(double a, double b, int c, int d) {                     \
+#define DEC_PYCALLBACK__2DBL2INT(CBNAME)                        \
+    void CBNAME(double a, double b, int c, int d);              \
+    void base_##CBNAME(double a, double b, int c, int d);
+
+
+#define IMP_PYCALLBACK__2DBL2INT(CLASS, PCLASS, CBNAME)                 \
+    void CLASS::CBNAME(double a, double b, int c, int d) {              \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
             m_myInst.callCallback(Py_BuildValue("(ddii)",               \
                                                        a,b,c,d));       \
         else                                                            \
             PCLASS::CBNAME(a, b, c, d);                                 \
+        wxPySaveThread(doSave);                                         \
     }                                                                   \
-    void base_##CBNAME(double a, double b, int c, int d) {              \
+    void CLASS::base_##CBNAME(double a, double b, int c, int d) {       \
         PCLASS::CBNAME(a, b, c, d);                                     \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DC4DBLBOOL(PCLASS, CBNAME)                          \
-    void CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(Oddddi)",             \
-                                   wxPyConstructObject(&a, "wxDC"),      \
-                                              b, c, d, e, (int)f));     \
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d, e, f);                           \
-    }                                                                   \
-    void base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
-        PCLASS::CBNAME(a, b, c, d, e, f);                               \
+#define DEC_PYCALLBACK__DC4DBLBOOL(CBNAME)                              \
+    void CBNAME(wxDC& a, double b, double c, double d, double e, bool f);       \
+    void base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
+
+
+#define IMP_PYCALLBACK__DC4DBLBOOL(CLASS, PCLASS, CBNAME)                               \
+    void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {       \
+        bool doSave = wxPyRestoreThread();                                              \
+        if (m_myInst.findCallback(#CBNAME))                                             \
+            m_myInst.callCallback(Py_BuildValue("(Oddddi)",                             \
+                                   wxPyConstructObject(&a, "wxDC"),                     \
+                                              b, c, d, e, (int)f));                     \
+        else                                                                            \
+            PCLASS::CBNAME(a, b, c, d, e, f);                                           \
+        wxPySaveThread(doSave);                                                         \
+    }                                                                                   \
+    void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
+        PCLASS::CBNAME(a, b, c, d, e, f);                                               \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK_BOOL_DC4DBLBOOL(PCLASS, CBNAME)                      \
-    bool CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
-        if (m_myInst.findCallback(#CBNAME))                             \
-            return m_myInst.callCallback(Py_BuildValue("(Oddddi)",      \
-                                   wxPyConstructObject(&a, "wxDC"),      \
-                                              b, c, d, e, (int)f));     \
-        else                                                            \
-            return PCLASS::CBNAME(a, b, c, d, e, f);                    \
-    }                                                                   \
-    bool base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
-        return PCLASS::CBNAME(a, b, c, d, e, f);                        \
+#define DEC_PYCALLBACK_BOOL_DC4DBLBOOL(CBNAME)                                  \
+    bool CBNAME(wxDC& a, double b, double c, double d, double e, bool f);       \
+    bool base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
+
+
+#define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME)                           \
+    bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {       \
+        bool doSave = wxPyRestoreThread();                                              \
+        if (m_myInst.findCallback(#CBNAME))                                             \
+            return m_myInst.callCallback(Py_BuildValue("(Oddddi)",                      \
+                                   wxPyConstructObject(&a, "wxDC"),                     \
+                                              b, c, d, e, (int)f));                     \
+        else                                                                            \
+            return PCLASS::CBNAME(a, b, c, d, e, f);                                    \
+        wxPySaveThread(doSave);                                                         \
+    }                                                                                   \
+    bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
+        return PCLASS::CBNAME(a, b, c, d, e, f);                                        \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__BOOL2DBL2INT(PCLASS, CBNAME)                        \
-    void CBNAME(bool a, double b, double c, int d, int e) {             \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(idii)",               \
-                                                (int)a,b,c,d,e));       \
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d, e);                              \
-    }                                                                   \
-    void base_##CBNAME(bool a, double b, double c, int d, int e) {      \
-        PCLASS::CBNAME(a, b, c, d, e);                                  \
+#define DEC_PYCALLBACK__BOOL2DBL2INT(CBNAME)                            \
+    void CBNAME(bool a, double b, double c, int d, int e);              \
+    void base_##CBNAME(bool a, double b, double c, int d, int e);
+
+
+#define IMP_PYCALLBACK__BOOL2DBL2INT(CLASS, PCLASS, CBNAME)                     \
+    void CLASS::CBNAME(bool a, double b, double c, int d, int e) {              \
+        bool doSave = wxPyRestoreThread();                                      \
+        if (m_myInst.findCallback(#CBNAME))                                     \
+            m_myInst.callCallback(Py_BuildValue("(idii)",                       \
+                                                (int)a,b,c,d,e));               \
+        else                                                                    \
+            PCLASS::CBNAME(a, b, c, d, e);                                      \
+        wxPySaveThread(doSave);                                                 \
+    }                                                                           \
+    void CLASS::base_##CBNAME(bool a, double b, double c, int d, int e) {       \
+        PCLASS::CBNAME(a, b, c, d, e);                                          \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DC4DBL(PCLASS, CBNAME)                              \
-    void CBNAME(wxDC& a, double b, double c, double d, double e) {     \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(Odddd)",              \
-                                   wxPyConstructObject(&a, "wxDC"),      \
-                                                     b, c, d, e));      \
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d, e);                              \
-    }                                                                   \
-    void base_##CBNAME(wxDC& a, double b, double c, double d, double e) {\
-        PCLASS::CBNAME(a, b, c, d, e);                                  \
+#define DEC_PYCALLBACK__DC4DBL(CBNAME)                                      \
+    void CBNAME(wxDC& a, double b, double c, double d, double e);               \
+    void base_##CBNAME(wxDC& a, double b, double c, double d, double e);
+
+
+#define IMP_PYCALLBACK__DC4DBL(CLASS, PCLASS, CBNAME)                           \
+    void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e) {       \
+        bool doSave = wxPyRestoreThread();                                      \
+        if (m_myInst.findCallback(#CBNAME))                                     \
+            m_myInst.callCallback(Py_BuildValue("(Odddd)",                      \
+                                   wxPyConstructObject(&a, "wxDC"),             \
+                                                     b, c, d, e));              \
+        else                                                                    \
+            PCLASS::CBNAME(a, b, c, d, e);                                      \
+        wxPySaveThread(doSave);                                                 \
+    }                                                                           \
+    void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e) {\
+        PCLASS::CBNAME(a, b, c, d, e);                                          \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__DCBOOL(PCLASS, CBNAME)                              \
-    void CBNAME(wxDC& a, bool b) {                                      \
+#define DEC_PYCALLBACK__DCBOOL(CBNAME)                  \
+    void CBNAME(wxDC& a, bool b);                       \
+    void base_##CBNAME(wxDC& a, bool b);
+
+
+#define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME)                   \
+    void CLASS::CBNAME(wxDC& a, bool b) {                               \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
             m_myInst.callCallback(Py_BuildValue("(Oi)",                 \
-                                   wxPyConstructObject(&a, "wxDC"),      \
+                                   wxPyConstructObject(&a, "wxDC"),     \
                                                      (int)b));          \
         else                                                            \
             PCLASS::CBNAME(a, b);                                       \
+        wxPySaveThread(doSave);                                         \
     }                                                                   \
-    void base_##CBNAME(wxDC& a, bool b) {                               \
+    void CLASS::base_##CBNAME(wxDC& a, bool b) {                        \
         PCLASS::CBNAME(a, b);                                           \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__WXCPBOOL2DBL2INT(PCLASS, CBNAME)                    \
-    void CBNAME(wxControlPoint* a, bool b, double c, double d,          \
-                int e, int f) {                                         \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(Oiddii)",             \
-                                 wxPyConstructObject(a, "wxControlPoint"),\
-                                 (int)b, c, d, e, f));                  \
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d, e, f);                           \
-    }                                                                   \
-    void base_##CBNAME(wxControlPoint* a, bool b, double c, double d,   \
-                       int e, int f) {                                  \
-        PCLASS::CBNAME(a, b, c, d, e, f);                               \
+#define DEC_PYCALLBACK__WXCPBOOL2DBL2INT(CBNAME)                                \
+    void CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f);   \
+    void base_##CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f);
+
+
+#define IMP_PYCALLBACK__WXCPBOOL2DBL2INT(CLASS, PCLASS, CBNAME)                 \
+    void CLASS::CBNAME(wxControlPoint* a, bool b, double c, double d,           \
+                int e, int f) {                                                 \
+        bool doSave = wxPyRestoreThread();                                      \
+        if (m_myInst.findCallback(#CBNAME))                                     \
+            m_myInst.callCallback(Py_BuildValue("(Oiddii)",                     \
+                                 wxPyConstructObject(a, "wxControlPoint"),      \
+                                 (int)b, c, d, e, f));                          \
+        else                                                                    \
+            PCLASS::CBNAME(a, b, c, d, e, f);                                   \
+        wxPySaveThread(doSave);                                                 \
+    }                                                                           \
+    void CLASS::base_##CBNAME(wxControlPoint* a, bool b, double c, double d,    \
+                       int e, int f) {                                          \
+        PCLASS::CBNAME(a, b, c, d, e, f);                                       \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__WXCP2DBL2INT(PCLASS, CBNAME)                        \
-    void CBNAME(wxControlPoint* a, double b, double c, int d, int e) {  \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(Oddii)",              \
-                                 wxPyConstructObject(a, "wxControlPoint"),\
-                                 b, c, d, e));                          \
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d, e);                              \
-    }                                                                   \
-    void base_##CBNAME(wxControlPoint* a, double b, double c,           \
-                       int d, int e) {                                  \
-        PCLASS::CBNAME(a, b, c, d, e);                                  \
+#define DEC_PYCALLBACK__WXCP2DBL2INT(CBNAME)                                    \
+    void CBNAME(wxControlPoint* a, double b, double c, int d, int e);           \
+    void base_##CBNAME(wxControlPoint* a, double b, double c, int d, int e);
+
+
+#define IMP_PYCALLBACK__WXCP2DBL2INT(CLASS, PCLASS, CBNAME)                     \
+    void CLASS::CBNAME(wxControlPoint* a, double b, double c, int d, int e) {   \
+        bool doSave = wxPyRestoreThread();                                      \
+        if (m_myInst.findCallback(#CBNAME))                                     \
+            m_myInst.callCallback(Py_BuildValue("(Oddii)",                      \
+                                 wxPyConstructObject(a, "wxControlPoint"),      \
+                                 b, c, d, e));                                  \
+        else                                                                    \
+            PCLASS::CBNAME(a, b, c, d, e);                                      \
+        wxPySaveThread(doSave);                                                 \
+    }                                                                           \
+    void CLASS::base_##CBNAME(wxControlPoint* a, double b, double c,            \
+                       int d, int e) {                                          \
+        PCLASS::CBNAME(a, b, c, d, e);                                          \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__2DBLINT(PCLASS, CBNAME)                             \
-    void CBNAME(double a, double b, int c) {                            \
+#define DEC_PYCALLBACK__2DBLINT(CBNAME)                 \
+    void CBNAME(double a, double b, int c);             \
+    void base_##CBNAME(double a, double b, int c);
+
+
+#define IMP_PYCALLBACK__2DBLINT(CLASS, PCLASS, CBNAME)                  \
+    void CLASS::CBNAME(double a, double b, int c) {                     \
+        bool doSave = wxPyRestoreThread();                              \
         if (m_myInst.findCallback(#CBNAME))                             \
             m_myInst.callCallback(Py_BuildValue("(ddi)", a,b,c));       \
         else                                                            \
             PCLASS::CBNAME(a, b, c);                                    \
+        wxPySaveThread(doSave);                                         \
     }                                                                   \
-    void base_##CBNAME(double a, double b, int c) {                     \
+    void CLASS::base_##CBNAME(double a, double b, int c) {              \
         PCLASS::CBNAME(a, b, c);                                        \
     }
 
 //---------------------------------------------------------------------------
 
-#define PYCALLBACK__BOOL2DBLINT(PCLASS, CBNAME)                         \
-    void CBNAME(bool a, double b, double c, int d) {                    \
-        if (m_myInst.findCallback(#CBNAME))                             \
-            m_myInst.callCallback(Py_BuildValue("(iddi)", (int)a,b,c,d));\
-        else                                                            \
-            PCLASS::CBNAME(a, b, c, d);                                 \
-    }                                                                   \
-    void base_##CBNAME(bool a, double b, double c, int d) {             \
-        PCLASS::CBNAME(a, b, c, d);                                     \
+#define DEC_PYCALLBACK__BOOL2DBLINT(CBNAME)                     \
+    void CBNAME(bool a, double b, double c, int d);             \
+    void base_##CBNAME(bool a, double b, double c, int d);
+
+
+#define IMP_PYCALLBACK__BOOL2DBLINT(CLASS, PCLASS, CBNAME)                      \
+    void CLASS::CBNAME(bool a, double b, double c, int d) {                     \
+        bool doSave = wxPyRestoreThread();                                      \
+        if (m_myInst.findCallback(#CBNAME))                                     \
+            m_myInst.callCallback(Py_BuildValue("(iddi)", (int)a,b,c,d));       \
+        else                                                                    \
+            PCLASS::CBNAME(a, b, c, d);                                         \
+        wxPySaveThread(doSave);                                                 \
+    }                                                                           \
+    void CLASS::base_##CBNAME(bool a, double b, double c, int d) {              \
+        PCLASS::CBNAME(a, b, c, d);                                             \
     }
 
 //---------------------------------------------------------------------------