+ wxPySaveThread(doSave);
+}
+
+
+//----------------------------------------------------------------------
+
+wxPyCallbackHelper::wxPyCallbackHelper() {
+ m_self = NULL;
+ m_lastFound = NULL;
+ m_incRef = FALSE;
+}
+
+
+wxPyCallbackHelper::~wxPyCallbackHelper() {
+ bool doSave = wxPyRestoreThread();
+ if (m_incRef)
+ Py_XDECREF(m_self);
+ wxPySaveThread(doSave);
+}
+
+wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
+ m_lastFound = NULL;
+ m_self = other.m_self;
+ if (m_self)
+ Py_INCREF(m_self);
+}
+
+
+void wxPyCallbackHelper::setSelf(PyObject* self, int incref) {
+ m_self = self;
+ m_incRef = incref;
+ if (incref)
+ 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...
+ }
+ 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;