X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d559219f4016139d6c52d3b386903821a99c54d2..c5fb56c07a3718798459a69c74b3124ab58c65b5:/utils/wxPython/src/helpers.cpp diff --git a/utils/wxPython/src/helpers.cpp b/utils/wxPython/src/helpers.cpp index c74c75de36..47c2f51730 100644 --- a/utils/wxPython/src/helpers.cpp +++ b/utils/wxPython/src/helpers.cpp @@ -121,6 +121,10 @@ int wxPyApp::MainLoop(void) { // 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. @@ -141,7 +145,11 @@ void __wxPreStart() 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; @@ -274,36 +282,30 @@ PyObject* wxPyConstructObject(void* ptr, char* className) { //--------------------------------------------------------------------------- -//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; @@ -313,8 +315,7 @@ HELPEREXPORT bool wxPyRestoreThread() { HELPEREXPORT void wxPySaveThread(bool doSave) { #ifdef WXP_WITH_THREAD if (doSave) { - PyEval_SaveThread(); - //_wxPyInEvent = false; + wxPyEventThreadState = PyEval_SaveThread(); } _wxPyNestCount -= 1; #endif @@ -323,11 +324,18 @@ HELPEREXPORT void wxPySaveThread(bool doSave) { //--------------------------------------------------------------------------- +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); @@ -336,7 +344,6 @@ wxPyCallback::~wxPyCallback() { - // This function is used for all events destined for Python event handlers. void wxPyCallback::EventThunker(wxEvent& event) { wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData; @@ -377,9 +384,18 @@ wxPyCallbackHelper::~wxPyCallbackHelper() { 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); } @@ -453,53 +469,35 @@ void wxPyTimer::Notify() { } -//---------------------------------------------------------------------- - -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); - } -} +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Convert a wxList to a Python List +PyObject* wxPy_ConvertList(wxListBase* list, char* className) { + PyObject* pyList; + PyObject* pyObj; + wxObject* wxObj; + wxNode* node = list->First(); -wxPyEvent::~wxPyEvent() { bool doSave = wxPyRestoreThread(); - if (m_userData != Py_None) { - Py_DECREF(m_userData); - m_userData = Py_None; + pyList = PyList_New(0); + while (node) { + wxObj = node->Data(); + pyObj = wxPyConstructObject(wxObj, className); + PyList_Append(pyList, pyObj); + node = node->Next(); } wxPySaveThread(doSave); + return pyList; } - -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; -} - -//---------------------------------------------------------------------- //---------------------------------------------------------------------- // Some helper functions for typemaps in my_typemaps.i, so they won't be -// imcluded in every file... +// 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; @@ -522,7 +520,7 @@ HELPEREXPORT byte* byte_LIST_helper(PyObject* source) { } -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; @@ -545,7 +543,7 @@ HELPEREXPORT int* int_LIST_helper(PyObject* source) { } -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; @@ -568,7 +566,7 @@ HELPEREXPORT long* long_LIST_helper(PyObject* source) { } -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; @@ -592,7 +590,7 @@ HELPEREXPORT char** string_LIST_helper(PyObject* source) { -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; @@ -629,7 +627,7 @@ HELPEREXPORT wxPoint* wxPoint_LIST_helper(PyObject* source) { } -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; @@ -642,10 +640,9 @@ HELPEREXPORT wxBitmap** wxBitmap_LIST_helper(PyObject* source) { } for (int x=0; x