// wxcmodule is imported. (Before there is a wxApp object.)
void __wxPreStart()
{
+#ifdef WXP_WITH_THREAD
+ PyEval_InitThreads();
+#endif
+
// Bail out if there is already windows created. This means that the
// toolkit has already been initialized, as in embedding wxPython in
// a C++ wxWindows app.
argv[argc] = NULL;
gtk_set_locale();
+#if wxUSE_WCHAR_T
if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
+#else
+ if (!wxOKlibc()) wxConvCurrent = (wxMBConv*) NULL;
+#endif
gtk_init( &argc, &argv );
wxSetDetectableAutoRepeat( TRUE );
delete [] argv;
//---------------------------------------------------------------------------
-//static bool _wxPyInEvent = false;
static unsigned int _wxPyNestCount = 0;
-HELPEREXPORT bool wxPyRestoreThread() {
-// #ifdef WXP_WITH_THREAD
-// //if (wxPyEventThreadState != PyThreadState_Get()) {
-// if (! _wxPyInEvent) {
-// PyEval_RestoreThread(wxPyEventThreadState);
-// _wxPyInEvent = true;
-// return TRUE;
-// } else
-// #endif
-// return FALSE;
+static PyThreadState* myPyThreadState_Get() {
+ PyThreadState* current;
+ current = PyThreadState_Swap(NULL);
+ PyThreadState_Swap(current);
+ return current;
+}
+
+HELPEREXPORT 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 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.)
+ // occurs, so I put in this code as a guard condition since there are
+ // many possibilites for nested events and callbacks in wxPython. If
+ // The current thread is our thread, then we can assume that we
+ // already have the lock. (I hope!)
//
- // until I know better, this is how I am doing it instead:
#ifdef WXP_WITH_THREAD
- PyEval_RestoreThread(wxPyEventThreadState);
_wxPyNestCount += 1;
- if (_wxPyNestCount == 1)
+ if (wxPyEventThreadState != myPyThreadState_Get()) {
+ PyEval_RestoreThread(wxPyEventThreadState);
return TRUE;
+ }
else
#endif
return FALSE;
HELPEREXPORT void wxPySaveThread(bool doSave) {
#ifdef WXP_WITH_THREAD
if (doSave) {
- PyEval_SaveThread();
- //_wxPyInEvent = false;
+ wxPyEventThreadState = PyEval_SaveThread();
}
_wxPyNestCount -= 1;
#endif
//---------------------------------------------------------------------------
+IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
+
wxPyCallback::wxPyCallback(PyObject* func) {
m_func = func;
Py_INCREF(m_func);
}
+wxPyCallback::wxPyCallback(const wxPyCallback& other) {
+ m_func = other.m_func;
+ Py_INCREF(m_func);
+}
+
wxPyCallback::~wxPyCallback() {
bool doSave = wxPyRestoreThread();
Py_DECREF(m_func);
-
// This function is used for all events destined for Python event handlers.
void wxPyCallback::EventThunker(wxEvent& event) {
wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
wxPySaveThread(doSave);
}
-void wxPyCallbackHelper::setSelf(PyObject* self) {
+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;
- Py_INCREF(m_self);
+ if (incref)
+ Py_INCREF(m_self);
}
}
-//----------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxCommandEvent)
-
-wxPyEvent::wxPyEvent(wxEventType commandType, PyObject* userData)
- : wxCommandEvent(commandType), m_userData(Py_None)
-{
- m_userData = userData;
- if (m_userData != Py_None) {
- Py_INCREF(m_userData);
- }
-}
-
-
-wxPyEvent::~wxPyEvent() {
- bool doSave = wxPyRestoreThread();
- if (m_userData != Py_None) {
- Py_DECREF(m_userData);
- m_userData = Py_None;
- }
- wxPySaveThread(doSave);
-}
-
-
-void wxPyEvent::SetUserData(PyObject* userData) {
- if (m_userData != Py_None) {
- Py_DECREF(m_userData);
- m_userData = Py_None;
- }
- m_userData = userData;
- if (m_userData != Py_None) {
- Py_INCREF(m_userData);
- }
-}
-
-
-PyObject* wxPyEvent::GetUserData() {
- return m_userData;
-}
-//----------------------------------------------------------------------
+//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Convert a wxList to a Python List
// included in every file...
-HELPEREXPORT byte* byte_LIST_helper(PyObject* source) {
+byte* byte_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
-HELPEREXPORT int* int_LIST_helper(PyObject* source) {
+int* int_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
-HELPEREXPORT long* long_LIST_helper(PyObject* source) {
+long* long_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
-HELPEREXPORT char** string_LIST_helper(PyObject* source) {
+char** string_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
-HELPEREXPORT wxPoint* wxPoint_LIST_helper(PyObject* source) {
+wxPoint* wxPoint_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
-HELPEREXPORT wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
+wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
for (int x=0; x<count; x++) {
PyObject* o = PyList_GetItem(source, x);
- if (PyString_Check(o)) {
- char* st = PyString_AsString(o);
+ if (PyInstance_Check(o)) {
wxBitmap* pt;
- if (SWIG_GetPtr(st,(void **) &pt,"_wxBitmap_p")) {
+ if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
return NULL;
}
-HELPEREXPORT wxString* wxString_LIST_helper(PyObject* source) {
+wxString* wxString_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
-HELPEREXPORT wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
+wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
if (!PyList_Check(source)) {
PyErr_SetString(PyExc_TypeError, "Expected a list object.");
return NULL;
}
for (int x=0; x<count; x++) {
PyObject* o = PyList_GetItem(source, x);
- if (PyString_Check(o)) {
- char* st = PyString_AsString(o);
+ if (PyInstance_Check(o)) {
wxAcceleratorEntry* ae;
- if (SWIG_GetPtr(st,(void **) &ae,"_wxAcceleratorEntry_p")) {
+ if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
return NULL;
}
//----------------------------------------------------------------------
+bool wxSize_helper(PyObject* source, wxSize** obj) {
+
+ // If source is an object instance then it may already be the right type
+ if (PyInstance_Check(source)) {
+ wxSize* ptr;
+ if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
+ goto error;
+ *obj = ptr;
+ return TRUE;
+ }
+ // otherwise a 2-tuple of integers is expected
+ else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
+ PyObject* o1 = PySequence_GetItem(source, 0);
+ PyObject* o2 = PySequence_GetItem(source, 1);
+ **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
+ return TRUE;
+ }
+
+ error:
+ PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
+ return FALSE;
+}
+
+bool wxPoint_helper(PyObject* source, wxPoint** obj) {
+
+ // If source is an object instance then it may already be the right type
+ if (PyInstance_Check(source)) {
+ wxPoint* ptr;
+ if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
+ goto error;
+ *obj = ptr;
+ return TRUE;
+ }
+ // otherwise a 2-tuple of integers is expected
+ else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
+ PyObject* o1 = PySequence_GetItem(source, 0);
+ PyObject* o2 = PySequence_GetItem(source, 1);
+ **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
+ return TRUE;
+ }
+
+ error:
+ PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
+ return FALSE;
+}
+
+
+
+bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
+
+ // If source is an object instance then it may already be the right type
+ if (PyInstance_Check(source)) {
+ wxRealPoint* ptr;
+ if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
+ goto error;
+ *obj = ptr;
+ return TRUE;
+ }
+ // otherwise a 2-tuple of floats is expected
+ else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
+ PyObject* o1 = PySequence_GetItem(source, 0);
+ PyObject* o2 = PySequence_GetItem(source, 1);
+ **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
+ return TRUE;
+ }
+
+ error:
+ PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
+ return FALSE;
+}
+
+
+
+
+bool wxRect_helper(PyObject* source, wxRect** obj) {
+
+ // If source is an object instance then it may already be the right type
+ if (PyInstance_Check(source)) {
+ wxRect* ptr;
+ if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
+ goto error;
+ *obj = ptr;
+ return TRUE;
+ }
+ // otherwise a 4-tuple of integers is expected
+ else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
+ PyObject* o1 = PySequence_GetItem(source, 0);
+ PyObject* o2 = PySequence_GetItem(source, 1);
+ PyObject* o3 = PySequence_GetItem(source, 2);
+ PyObject* o4 = PySequence_GetItem(source, 3);
+ **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
+ PyInt_AsLong(o3), PyInt_AsLong(o4));
+ return TRUE;
+ }
+
+ error:
+ PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
+ return FALSE;
+}
+
+
+
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------