#endif
-//---------------------------------------------------------------------------
-
-//wxHashTable* wxPyWindows = NULL;
-
-
-wxPoint wxPyDefaultPosition; //wxDefaultPosition);
-wxSize wxPyDefaultSize; //wxDefaultSize);
-wxString wxPyEmptyStr("");
-
#ifdef __WXMSW__ // If building for win32...
//---------------------------------------------------------------------
//----------------------------------------------------------------------
+#ifdef __WXMSW__
+#include "wx/msw/msvcrt.h"
+#endif
+
+
int WXDLLEXPORT wxEntryStart( int argc, char** argv );
int WXDLLEXPORT wxEntryInitGui();
void WXDLLEXPORT wxEntryCleanup();
#ifdef WXP_WITH_THREAD
PyThreadState* wxPyEventThreadState = NULL;
#endif
-static char* __nullArgv[1] = { 0 };
// This is where we pick up the first part of the wxEntry functionality...
// wxcmodule is imported. (Before there is a wxApp object.)
void __wxPreStart()
{
+
+#ifdef __WXMSW__
+// wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+#endif
+
#ifdef WXP_WITH_THREAD
PyEval_InitThreads();
wxPyEventThreadState = PyThreadState_Get();
if (!PyArg_ParseTuple(args, "O", &onInitFunc))
return NULL;
+#if 0 // Try it out without this check, soo how it does...
if (wxTopLevelWindows.Number() > 0) {
PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
return NULL;
}
-
+#endif
// This is the next part of the wxEntry functionality...
PyObject* sysargv = PySys_GetObject("argv");
char** argv = new char*[argc+1];
int x;
for(x=0; x<argc; x++)
- argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
+ argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
argv[argc] = NULL;
wxPythonApp->argc = argc;
//---------------------------------------------------------------------------
-PyObject* wxPyConstructObject(void* ptr, const char* className) {
+PyObject* wxPyConstructObject(void* ptr,
+ const char* className,
+ int setThisOwn) {
+ PyObject* obj;
+ PyObject* arg;
+
+ if (!ptr) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
char buff[64]; // should always be big enough...
char swigptr[64];
sprintf(buff, "%sPtr", className);
PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
if (! classobj) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- PyObject* arg = Py_BuildValue("(s)", swigptr);
- PyObject* obj = PyInstance_New(classobj, arg, NULL);
+ //Py_INCREF(Py_None);
+ //return Py_None;
+ char temp[128];
+ sprintf(temp,
+ "*** Unknown class name %s, tell Robin about it please ***",
+ buff);
+ obj = PyString_FromString(temp);
+ return obj;
+ }
+
+ arg = Py_BuildValue("(s)", swigptr);
+ obj = PyInstance_New(classobj, arg, NULL);
Py_DECREF(arg);
+ if (setThisOwn) {
+ PyObject* one = PyInt_FromLong(1);
+ PyObject_SetAttrString(obj, "thisown", one);
+ Py_DECREF(one);
+ }
+
return obj;
}
//---------------------------------------------------------------------------
-static unsigned int _wxPyNestCount = 0;
-
static PyThreadState* myPyThreadState_Get() {
PyThreadState* current;
current = PyThreadState_Swap(NULL);
}
-HELPEREXPORT bool wxPyRestoreThread() {
+bool wxPyRestoreThread() {
// 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 this code as a guard condition since there are
// already have the lock. (I hope!)
//
#ifdef WXP_WITH_THREAD
- _wxPyNestCount += 1;
if (wxPyEventThreadState != myPyThreadState_Get()) {
PyEval_RestoreThread(wxPyEventThreadState);
return TRUE;
}
-HELPEREXPORT void wxPySaveThread(bool doSave) {
+void wxPySaveThread(bool doSave) {
#ifdef WXP_WITH_THREAD
if (doSave) {
wxPyEventThreadState = PyEval_SaveThread();
}
- _wxPyNestCount -= 1;
#endif
}
//----------------------------------------------------------------------
-wxPyCallbackHelper::wxPyCallbackHelper() {
- m_class = NULL;
- m_self = NULL;
- m_lastFound = NULL;
- m_incRef = FALSE;
-}
-
-
-wxPyCallbackHelper::~wxPyCallbackHelper() {
- bool doSave = wxPyRestoreThread();
- if (m_incRef) {
- Py_XDECREF(m_self);
- Py_XDECREF(m_class);
- }
- wxPySaveThread(doSave);
-}
-
wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
m_lastFound = NULL;
m_self = other.m_self;
}
-void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* _class, int incref) {
+void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
m_self = self;
- m_class = _class;
+ m_class = klass;
m_incRef = incref;
if (incref) {
Py_INCREF(m_self);
// If the object (m_self) has an attibute of the given name, and if that
// attribute is a method, and if that method's class is not from a base class,
// then we'll save a pointer to the method so callCallback can call it.
-bool wxPyCallbackHelper::findCallback(const wxString& name) const {
+bool wxPyCallbackHelper::findCallback(const char* name) const {
wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
self->m_lastFound = NULL;
- if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str())) {
+ if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
PyObject* method;
- method = PyObject_GetAttrString(m_self, (char*)name.c_str());
+ method = PyObject_GetAttrString(m_self, (char*)name);
if (PyMethod_Check(method) &&
((PyMethod_GET_CLASS(method) == m_class) ||
self->m_lastFound = method;
}
+ else {
+ Py_DECREF(method);
+ }
}
return m_lastFound != NULL;
}
// 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) const {
- PyObject* result;
+ PyObject* result;
+
+ // Save a copy of the pointer in case the callback generates another
+ // callback. In that case m_lastFound will have a different value when
+ // it gets back here...
+ PyObject* method = m_lastFound;
- result = PyEval_CallObject(m_lastFound, argTuple);
+ result = PyEval_CallObject(method, argTuple);
Py_DECREF(argTuple);
+ Py_DECREF(method);
if (!result) {
PyErr_Print();
}
}
+void wxPyCBH_setSelf(wxPyCallbackHelper& cbh, PyObject* self, PyObject* klass, int incref) {
+ cbh.setSelf(self, klass, incref);
+}
+
+bool wxPyCBH_findCallback(const wxPyCallbackHelper& cbh, const char* name) {
+ return cbh.findCallback(name);
+}
+
+int wxPyCBH_callCallback(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
+ return cbh.callCallback(argTuple);
+}
+
+PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
+ return cbh.callCallbackObj(argTuple);
+}
+
+
+void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
+ bool doSave = wxPyRestoreThread();
+ if (cbh->m_incRef) {
+ Py_XDECREF(cbh->m_self);
+ Py_XDECREF(cbh->m_class);
+ }
+ wxPySaveThread(doSave);
+}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// These classes can be derived from in Python and passed through the event
-// system without loosing anything. They do this by keeping a reference to
+// system without losing anything. They do this by keeping a reference to
// themselves and some special case handling in wxPyCallback::EventThunker.
}
void wxPyTimer::Notify() {
- bool doSave = wxPyRestoreThread();
-
- PyObject* result;
- PyObject* args = Py_BuildValue("()");
+ if (!func || func == Py_None) {
+ wxTimer::Notify();
+ }
+ else {
+ bool doSave = wxPyRestoreThread();
+
+ PyObject* result;
+ PyObject* args = Py_BuildValue("()");
+
+ result = PyEval_CallObject(func, args);
+ Py_DECREF(args);
+ if (result) {
+ Py_DECREF(result);
+ PyErr_Clear();
+ } else {
+ PyErr_Print();
+ }
- result = PyEval_CallObject(func, args);
- Py_DECREF(args);
- if (result) {
- Py_DECREF(result);
- PyErr_Clear();
- } else {
- PyErr_Print();
+ wxPySaveThread(doSave);
}
- wxPySaveThread(doSave);
}
}
error:
- PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or #RRGGBB.");
+ PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
return FALSE;
}
+