]> git.saurik.com Git - wxWidgets.git/commitdiff
Lots more support for event-less callbacks
authorRobin Dunn <robin@alldunn.com>
Fri, 10 Sep 1999 06:05:32 +0000 (06:05 +0000)
committerRobin Dunn <robin@alldunn.com>
Fri, 10 Sep 1999 06:05:32 +0000 (06:05 +0000)
Exported some symbols for the other modules to use
etc.

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

utils/wxPython/src/helpers.cpp
utils/wxPython/src/helpers.h
utils/wxPython/src/my_typemaps.i

index 1cd1d149374c6ecd27d6dfb697326ddc4b9c39de..c74c75de36903bb17c20f6dd89a224dedaaec99b 100644 (file)
@@ -154,7 +154,6 @@ void __wxPreStart()
 
 #ifdef WXP_WITH_THREAD
 PyThreadState*  wxPyEventThreadState = NULL;
-bool            wxPyInEvent = false;
 #endif
 static char* __nullArgv[1] = { 0 };
 
@@ -252,8 +251,7 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
 
 //---------------------------------------------------------------------------
 
-PyObject* wxPyConstructObject(void* ptr, char* className)
-{
+PyObject* wxPyConstructObject(void* ptr, char* className) {
     char    buff[64];               // should always be big enough...
     char    swigptr[64];
 
@@ -274,27 +272,68 @@ PyObject* wxPyConstructObject(void* ptr, char* className)
     return obj;
 }
 
+//---------------------------------------------------------------------------
 
+//static bool _wxPyInEvent = false;
+static unsigned int _wxPyNestCount = 0;
 
-wxPyCallback::wxPyCallback(PyObject* func) {
-    m_func = func;
-    Py_INCREF(m_func);
-}
-
-wxPyCallback::~wxPyCallback() {
+HELPEREXPORT bool wxPyRestoreThread() {
+//  #ifdef WXP_WITH_THREAD
+//      //if (wxPyEventThreadState != PyThreadState_Get()) {
+//      if (! _wxPyInEvent) {
+//          PyEval_RestoreThread(wxPyEventThreadState);
+//          _wxPyInEvent = true;
+//          return TRUE;
+//      } else
+//  #endif
+//          return FALSE;
+
+    // NOTE: The Python API docs state that if a thread already has the
+    // interpreter lock and calls PyEval_RestoreThread again a deadlock
+    // occurs, so I put in the above code as a guard condition since there are
+    // many possibilites for nested events and callbacks in wxPython.
+    //
+    // Unfortunately, it seems like somebody was lying (or I'm not
+    // understanding...) because each of the nested calls to this function
+    // MUST call PyEval_RestoreThread or Python pukes with a thread error (at
+    // least on Win32.)
+    //
+    // until I know better, this is how I am doing it instead:
 #ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
-        PyEval_RestoreThread(wxPyEventThreadState);
+    PyEval_RestoreThread(wxPyEventThreadState);
+    _wxPyNestCount += 1;
+    if (_wxPyNestCount == 1)
+        return TRUE;
+    else
 #endif
+        return FALSE;
+}
 
-    Py_DECREF(m_func);
 
+HELPEREXPORT void wxPySaveThread(bool doSave) {
 #ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
+    if (doSave) {
         PyEval_SaveThread();
+        //_wxPyInEvent = false;
+    }
+    _wxPyNestCount -= 1;
 #endif
 }
 
+//---------------------------------------------------------------------------
+
+
+wxPyCallback::wxPyCallback(PyObject* func) {
+    m_func = func;
+    Py_INCREF(m_func);
+}
+
+wxPyCallback::~wxPyCallback() {
+    bool doSave = wxPyRestoreThread();
+    Py_DECREF(m_func);
+    wxPySaveThread(doSave);
+}
+
 
 
 
@@ -307,10 +346,7 @@ void wxPyCallback::EventThunker(wxEvent& event) {
     PyObject*       tuple;
 
 
-#ifdef WXP_WITH_THREAD
-    PyEval_RestoreThread(wxPyEventThreadState);
-    wxPyInEvent = true;
-#endif
+    bool doSave = wxPyRestoreThread();
     arg = wxPyConstructObject((void*)&event, event.GetClassInfo()->GetClassName());
 
     tuple = PyTuple_New(1);
@@ -323,101 +359,85 @@ void wxPyCallback::EventThunker(wxEvent& event) {
     } else {
         PyErr_Print();
     }
-#ifdef WXP_WITH_THREAD
-    PyEval_SaveThread();
-    wxPyInEvent = false;
-#endif
+    wxPySaveThread(doSave);
 }
 
 
-//---------------------------------------------------------------------------
+//----------------------------------------------------------------------
 
-//  wxPyMenu::wxPyMenu(const wxString& title, PyObject* _func)
-//      : wxMenu(title, (wxFunction)(func ? MenuCallback : NULL)), func(0) {
+wxPyCallbackHelper::wxPyCallbackHelper() {
+    m_self = NULL;
+    m_lastFound = NULL;
+}
 
-//      if (_func) {
-//          func = _func;
-//          Py_INCREF(func);
-//      }
-//  }
 
-//  wxPyMenu::~wxPyMenu() {
-//  #ifdef WXP_WITH_THREAD
-//      //if (! wxPyInEvent)
-//          PyEval_RestoreThread(wxPyEventThreadState);
-//  #endif
+wxPyCallbackHelper::~wxPyCallbackHelper() {
+    bool doSave = wxPyRestoreThread();
+    Py_XDECREF(m_self);
+    wxPySaveThread(doSave);
+}
 
-//      if (func)
-//          Py_DECREF(func);
+void wxPyCallbackHelper::setSelf(PyObject* self) {
+    m_self = self;
+    Py_INCREF(m_self);
+}
 
-//  #ifdef WXP_WITH_THREAD
-//      //if (! wxPyInEvent)
-//          PyEval_SaveThread();
-//  #endif
-//  }
 
+bool wxPyCallbackHelper::findCallback(const wxString& name) {
+    m_lastFound = NULL;
+    if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
+        m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
 
-//  void wxPyMenu::MenuCallback(wxMenu& menu, wxCommandEvent& evt) {
-//      PyObject* evtobj;
-//      PyObject* menuobj;
-//      PyObject* func;
-//      PyObject* args;
-//      PyObject* res;
+    return m_lastFound != NULL;
+}
 
-//  #ifdef WXP_WITH_THREAD
-//      PyEval_RestoreThread(wxPyEventThreadState);
-//      wxPyInEvent = true;
-//  #endif
-//      evtobj  = wxPyConstructObject((void*)&evt, "wxCommandEvent");
-//      menuobj = wxPyConstructObject((void*)&menu, "wxMenu");
-//      if (PyErr_Occurred()) {
-//          // bail out if a problem
-//          PyErr_Print();
-//          goto done;
-//      }
-//      // Now call the callback...
-//      func = ((wxPyMenu*)&menu)->func;
-//      args = PyTuple_New(2);
-//      PyTuple_SET_ITEM(args, 0, menuobj);
-//      PyTuple_SET_ITEM(args, 1, evtobj);
-//      res  = PyEval_CallObject(func, args);
-//      Py_DECREF(args);
-//      Py_XDECREF(res); /* In case res is a NULL pointer */
-//   done:
-//  #ifdef WXP_WITH_THREAD
-//      PyEval_SaveThread();
-//      wxPyInEvent = false;
-//  #endif
-//      return;
-//  }
+
+int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
+    PyObject*   result;
+    int         retval = FALSE;
+
+    result = callCallbackObj(argTuple);
+    if (result) {                       // Assumes an integer return type...
+        retval = PyInt_AsLong(result);
+        Py_DECREF(result);
+        PyErr_Clear();                  // forget about it if it's not...
+    }
+    return retval;
+}
+
+// Invoke the Python callable object, returning the raw PyObject return
+// value.  Caller should DECREF the return value and also call PyEval_SaveThread.
+PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
+    PyObject*   result;
+
+    result = PyEval_CallObject(m_lastFound, argTuple);
+    Py_DECREF(argTuple);
+    if (!result) {
+        PyErr_Print();
+    }
+    return result;
+}
 
 
+
+//---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 
+
 wxPyTimer::wxPyTimer(PyObject* callback) {
     func = callback;
     Py_INCREF(func);
 }
 
 wxPyTimer::~wxPyTimer() {
-#ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
-        PyEval_RestoreThread(wxPyEventThreadState);
-#endif
-
+    bool doSave = wxPyRestoreThread();
     Py_DECREF(func);
-
-#ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
-        PyEval_SaveThread();
-#endif
+    wxPySaveThread(doSave);
 }
 
 void wxPyTimer::Notify() {
-#ifdef WXP_WITH_THREAD
-    PyEval_RestoreThread(wxPyEventThreadState);
-    wxPyInEvent = true;
-#endif
+    bool doSave = wxPyRestoreThread();
+
     PyObject*   result;
     PyObject*   args = Py_BuildValue("()");
 
@@ -429,10 +449,7 @@ void wxPyTimer::Notify() {
     } else {
         PyErr_Print();
     }
-#ifdef WXP_WITH_THREAD
-    PyEval_SaveThread();
-    wxPyInEvent = false;
-#endif
+    wxPySaveThread(doSave);
 }
 
 
@@ -451,18 +468,12 @@ wxPyEvent::wxPyEvent(wxEventType commandType, PyObject* userData)
 
 
 wxPyEvent::~wxPyEvent() {
-#ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
-        PyEval_RestoreThread(wxPyEventThreadState);
-#endif
+    bool doSave = wxPyRestoreThread();
     if (m_userData != Py_None) {
         Py_DECREF(m_userData);
         m_userData = Py_None;
     }
-#ifdef WXP_WITH_THREAD
-    //if (! wxPyInEvent)
-        PyEval_SaveThread();
-#endif
+    wxPySaveThread(doSave);
 }
 
 
@@ -488,7 +499,7 @@ PyObject* wxPyEvent::GetUserData() {
 // imcluded in every file...
 
 
-byte* byte_LIST_helper(PyObject* source) {
+HELPEREXPORT byte* byte_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -511,7 +522,7 @@ byte* byte_LIST_helper(PyObject* source) {
 }
 
 
-int* int_LIST_helper(PyObject* source) {
+HELPEREXPORT int* int_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -534,7 +545,7 @@ int* int_LIST_helper(PyObject* source) {
 }
 
 
-long* long_LIST_helper(PyObject* source) {
+HELPEREXPORT long* long_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -557,7 +568,7 @@ long* long_LIST_helper(PyObject* source) {
 }
 
 
-char** string_LIST_helper(PyObject* source) {
+HELPEREXPORT char** string_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -581,7 +592,7 @@ char** string_LIST_helper(PyObject* source) {
 
 
 
-wxPoint* wxPoint_LIST_helper(PyObject* source) {
+HELPEREXPORT wxPoint* wxPoint_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -594,22 +605,21 @@ wxPoint* wxPoint_LIST_helper(PyObject* source) {
     }
     for (int x=0; x<count; x++) {
         PyObject* o = PyList_GetItem(source, x);
-        if (PyString_Check(o)) {
-            char*       st = PyString_AsString(o);
-            wxPoint*    pt;
-            if (SWIG_GetPtr(st,(void **) &pt,"_wxPoint_p")) {
-                PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
-                return NULL;
-            }
-            temp[x] = *pt;
-        }
-        else if (PyTuple_Check(o)) {
+        if (PyTuple_Check(o)) {
             PyObject* o1 = PyTuple_GetItem(o, 0);
             PyObject* o2 = PyTuple_GetItem(o, 1);
 
             temp[x].x = PyInt_AsLong(o1);
             temp[x].y = PyInt_AsLong(o2);
         }
+        else if (PyInstance_Check(o)) {
+            wxPoint* pt;
+            if (SWIG_GetPtrObj(o,(void **) &pt,"_wxPoint_p")) {
+                PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
+                return NULL;
+            }
+            temp[x] = *pt;
+        }
         else {
             PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
             return NULL;
@@ -619,7 +629,7 @@ wxPoint* wxPoint_LIST_helper(PyObject* source) {
 }
 
 
-wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
+HELPEREXPORT wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -651,7 +661,7 @@ wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
 
 
 
-wxString* wxString_LIST_helper(PyObject* source) {
+HELPEREXPORT wxString* wxString_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -674,7 +684,7 @@ wxString* wxString_LIST_helper(PyObject* source) {
 }
 
 
-wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
+HELPEREXPORT wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
     if (!PyList_Check(source)) {
         PyErr_SetString(PyExc_TypeError, "Expected a list object.");
         return NULL;
@@ -716,76 +726,6 @@ wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
 
 
 //----------------------------------------------------------------------
-//----------------------------------------------------------------------
-
-wxPyCallbackHelper::wxPyCallbackHelper() {
-    m_self = NULL;
-    m_lastFound = NULL;
-}
-
-
-wxPyCallbackHelper::~wxPyCallbackHelper() {
-#ifdef WXP_WITH_THREAD
-    PyEval_RestoreThread(wxPyEventThreadState);
-#endif
-
-    Py_XDECREF(m_self);
-
-#ifdef WXP_WITH_THREAD
-    PyEval_SaveThread();
-#endif
-}
-
-void wxPyCallbackHelper::setSelf(PyObject* self) {
-    m_self = self;
-    Py_INCREF(m_self);
-}
-
-
-
-bool wxPyCallbackHelper::findCallback(const wxString& name) {
-    m_lastFound = NULL;
-    if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
-        m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
-
-    return m_lastFound != NULL;
-}
-
-
-int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
-    PyObject*   result;
-    int         retval = FALSE;
-
-    result = callCallbackObj(argTuple);
-    if (result) {                       // Assumes an integer return type...
-        retval = PyInt_AsLong(result);
-        Py_DECREF(result);
-        PyErr_Clear();                  // forget about it if it's not...
-    }
-#ifdef WXP_WITH_THREAD
-    PyEval_SaveThread();
-#endif
-    return retval;
-}
-
-// Invoke the Python callable object, returning the raw PyObject return
-// value.  Caller should DECREF the return value and also call PyEval_SaveThread.
-PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
-#ifdef WXP_WITH_THREAD
-    PyEval_RestoreThread(wxPyEventThreadState);
-#endif
-    PyObject*   result;
-
-    result = PyEval_CallObject(m_lastFound, argTuple);
-    Py_DECREF(argTuple);
-    if (!result) {
-        PyErr_Print();
-    }
-    return result;
-}
-
-
-
 
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
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);                                             \
     }
 
 //---------------------------------------------------------------------------
index 20d43b33fb20cbc801f8378b4a15ab5c2c5efe2d..225912bdd83598bd62b6bc95a9f4301b617a62bf 100644 (file)
 
 %{
 
-extern byte* byte_LIST_helper(PyObject* source);
-extern int* int_LIST_helper(PyObject* source);
-extern long* long_LIST_helper(PyObject* source);
-extern char** string_LIST_helper(PyObject* source);
-extern wxPoint* wxPoint_LIST_helper(PyObject* source);
-extern wxBitmap** wxBitmap_LIST_helper(PyObject* source);
-extern wxString* wxString_LIST_helper(PyObject* source);
-extern wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source);
+HELPEREXPORT byte* byte_LIST_helper(PyObject* source);
+HELPEREXPORT int* int_LIST_helper(PyObject* source);
+HELPEREXPORT long* long_LIST_helper(PyObject* source);
+HELPEREXPORT char** string_LIST_helper(PyObject* source);
+HELPEREXPORT wxPoint* wxPoint_LIST_helper(PyObject* source);
+HELPEREXPORT wxBitmap** wxBitmap_LIST_helper(PyObject* source);
+HELPEREXPORT wxString* wxString_LIST_helper(PyObject* source);
+HELPEREXPORT wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source);
 
 %}
 
@@ -212,7 +212,13 @@ static char* wxStringErrorMsg = "string type is required for parameter";
 /////////////////////////////////////////////////////////////////////////////
 //
 // $Log$
+// Revision 1.6  1999/09/10 06:05:32  RD
+// Lots more support for event-less callbacks
+// Exported some symbols for the other modules to use
+// etc.
+//
 // Revision 1.5  1999/04/30 03:29:19  RD
+//
 // wxPython 2.0b9, first phase (win32)
 // Added gobs of stuff, see wxPython/README.txt for details
 //