X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/de20db997ddf7ee903076e72e9918caa2e269c19..27a97d02eb2f3dcf031c5cbcd3c1321c6d35fce8:/wxPython/src/helpers.cpp diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index 4495879274..9d12d8962a 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -38,15 +38,6 @@ #endif -//--------------------------------------------------------------------------- - -//wxHashTable* wxPyWindows = NULL; - - -wxPoint wxPyDefaultPosition; //wxDefaultPosition); -wxSize wxPyDefaultSize; //wxDefaultSize); -wxString wxPyEmptyStr(""); - #ifdef __WXMSW__ // If building for win32... @@ -118,7 +109,6 @@ 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... @@ -132,8 +122,13 @@ void __wxPreStart() #endif #ifdef WXP_WITH_THREAD +#if 0 // OLD THREAD STUFF PyEval_InitThreads(); wxPyEventThreadState = PyThreadState_Get(); +#else + PyEval_InitThreads(); + wxPyEventThreadState = PyThreadState_New(PyThreadState_Get()->interp); +#endif #endif // Bail out if there is already windows created. This means that the @@ -168,7 +163,7 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args) if (!PyArg_ParseTuple(args, "O", &onInitFunc)) return NULL; -#if 0 // Try it out without this check, soo how it does... +#if 0 // Try it out without this check, see how it does... if (wxTopLevelWindows.Number() > 0) { PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!"); return NULL; @@ -257,8 +252,8 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) //--------------------------------------------------------------------------- PyObject* wxPyConstructObject(void* ptr, - const char* className, - int setThisOwn) { + const char* className, + int setThisOwn) { PyObject* obj; PyObject* arg; @@ -301,8 +296,6 @@ PyObject* wxPyConstructObject(void* ptr, //--------------------------------------------------------------------------- -static unsigned int _wxPyNestCount = 0; - static PyThreadState* myPyThreadState_Get() { PyThreadState* current; current = PyThreadState_Swap(NULL); @@ -311,7 +304,7 @@ static PyThreadState* myPyThreadState_Get() { } -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 @@ -320,23 +313,35 @@ HELPEREXPORT bool wxPyRestoreThread() { // already have the lock. (I hope!) // #ifdef WXP_WITH_THREAD - _wxPyNestCount += 1; +#if 0 // OLD THREAD STUFF if (wxPyEventThreadState != myPyThreadState_Get()) { PyEval_RestoreThread(wxPyEventThreadState); return TRUE; } else +#else + if (wxPyEventThreadState != myPyThreadState_Get()) { + PyEval_AcquireThread(wxPyEventThreadState); + return TRUE; + } + else +#endif #endif return FALSE; } -HELPEREXPORT void wxPySaveThread(bool doSave) { +void wxPySaveThread(bool doSave) { #ifdef WXP_WITH_THREAD +#if 0 // OLD THREAD STUFF if (doSave) { wxPyEventThreadState = PyEval_SaveThread(); } - _wxPyNestCount -= 1; +#else + if (doSave) { + PyEval_ReleaseThread(wxPyEventThreadState); + } +#endif #endif } @@ -398,23 +403,6 @@ void wxPyCallback::EventThunker(wxEvent& event) { //---------------------------------------------------------------------- -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; @@ -477,7 +465,6 @@ int wxPyCallbackHelper::callCallback(PyObject* argTuple) const { // 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 { - wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const PyObject* result; // Save a copy of the pointer in case the callback generates another @@ -495,6 +482,31 @@ PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const { } +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); +} //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -745,43 +757,120 @@ char** string_LIST_helper(PyObject* source) { return temp; } +//-------------------------------- +// Part of patch from Tim Hochberg +static inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point) { + if (PyInt_Check(o1) && PyInt_Check(o2)) { + point->x = PyInt_AS_LONG(o1); + point->y = PyInt_AS_LONG(o2); + return true; + } + if (PyFloat_Check(o1) && PyFloat_Check(o2)) { + point->x = (int)PyFloat_AS_DOUBLE(o1); + point->y = (int)PyFloat_AS_DOUBLE(o2); + return true; + } + if (PyInstance_Check(o1) || PyInstance_Check(o2)) { + // Disallow instances because they can cause havok + return false; + } + if (PyNumber_Check(o1) && PyNumber_Check(o2)) { + // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2 + point->x = PyInt_AsLong(o1); + point->y = PyInt_AsLong(o2); + return true; + } + return false; +} -wxPoint* wxPoint_LIST_helper(PyObject* source) { - if (!PyList_Check(source)) { - PyErr_SetString(PyExc_TypeError, "Expected a list object."); - return NULL; +#if PYTHON_API_VERSION < 1009 +#define PySequence_Fast_GET_ITEM(o, i)\ + (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) +#endif + +wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) { + // Putting all of the declarations here allows + // us to put the error handling all in one place. + int x; + wxPoint* temp; + PyObject *o, *o1, *o2; + int isFast = PyList_Check(source) || PyTuple_Check(source); + + // The length of the sequence is returned in count. + if (!PySequence_Check(source)) { + goto error0; } - int count = PyList_Size(source); - wxPoint* temp = new wxPoint[count]; - if (! temp) { + *count = PySequence_Length(source); + if (*count < 0) { + goto error0; + } + + temp = new wxPoint[*count]; + if (!temp) { PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array"); return NULL; } - for (int x=0; x