X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4519a2d9113d2ea6c17d3cee54a6e0ed354521f8..26f26e06c4eb7d21c3c74a35ffd5d1a28bc8bd3c:/wxPython/src/helpers.cpp diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index dc4666b41d..2a568e3e38 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -28,7 +28,9 @@ #include #include #include -#define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) +#define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \ + GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \ + GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) #include #endif @@ -47,7 +49,7 @@ //---------------------------------------------------------------------- -#if PYTHON_API_VERSION <= 1007 && wxUSE_UNICODE +#if PYTHON_API_VERSION < 1009 && wxUSE_UNICODE #error Python must support Unicode to use wxWindows Unicode #endif @@ -59,6 +61,7 @@ bool wxPyDoingCleanup = false; #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE struct wxPyThreadState { unsigned long tid; PyThreadState* tstate; @@ -74,9 +77,14 @@ WX_DEFINE_OBJARRAY(wxPyThreadStateArray); wxPyThreadStateArray* wxPyTStates = NULL; wxMutex* wxPyTMutex = NULL; + +#endif #endif +#define DEFAULTENCODING_SIZE 64 +static char wxPyDefaultEncoding[DEFAULTENCODING_SIZE] = "ascii"; + static PyObject* wxPython_dict = NULL; static PyObject* wxPyAssertionError = NULL; static PyObject* wxPyNoAppError = NULL; @@ -95,8 +103,8 @@ BOOL WINAPI DllMain( LPVOID lpvReserved // reserved ) { - // If wxPython is embedded in another wxWindows app then - // the inatance has already been set. + // If wxPython is embedded in another wxWidgets app then + // the instance has already been set. if (! wxGetInstance()) wxSetInstance(hinstDLL); return true; @@ -146,7 +154,7 @@ int wxPyApp::MainLoop() { bool wxPyApp::OnInitGui() { bool rval=true; wxApp::OnInitGui(); // in this case always call the base class version - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "OnInitGui")) rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); wxPyEndBlockThreads(blocked); @@ -156,7 +164,7 @@ bool wxPyApp::OnInitGui() { int wxPyApp::OnExit() { int rval=0; - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "OnExit")) rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); wxPyEndBlockThreads(blocked); @@ -187,7 +195,7 @@ void wxPyApp::OnAssert(const wxChar *file, // If the OnAssert is overloaded in the Python class then call it... bool found; - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if ((found = wxPyCBH_findCallback(m_myInst, "OnAssert"))) { PyObject* fso = wx2PyString(file); PyObject* cso = wx2PyString(file); @@ -221,7 +229,7 @@ void wxPyApp::OnAssert(const wxChar *file, } // set the exception - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* s = wx2PyString(buf); PyErr_SetObject(wxPyAssertionError, s); Py_DECREF(s); @@ -256,7 +264,7 @@ void wxPyApp::OnAssert(const wxChar *file, // For catching Apple Events void wxPyApp::MacOpenFile(const wxString &fileName) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "MacOpenFile")) { PyObject* s = wx2PyString(fileName); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", s)); @@ -267,7 +275,7 @@ void wxPyApp::MacOpenFile(const wxString &fileName) void wxPyApp::MacPrintFile(const wxString &fileName) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "MacPrintFile")) { PyObject* s = wx2PyString(fileName); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", s)); @@ -278,7 +286,7 @@ void wxPyApp::MacPrintFile(const wxString &fileName) void wxPyApp::MacNewFile() { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "MacNewFile")) wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); wxPyEndBlockThreads(blocked); @@ -286,7 +294,7 @@ void wxPyApp::MacNewFile() void wxPyApp::MacReopenApp() { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "MacReopenApp")) wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); wxPyEndBlockThreads(blocked); @@ -379,14 +387,15 @@ void wxPyApp::SetMacHelpMenuTitleName(const wxString& val) { void wxPyApp::_BootstrapApp() { static bool haveInitialized = false; - bool result, blocked; + bool result; + wxPyBlock_t blocked; PyObject* retval = NULL; PyObject* pyint = NULL; - + // Only initialize wxWidgets once if (! haveInitialized) { - + // Get any command-line args passed to this program from the sys module int argc = 0; char** argv = NULL; @@ -419,13 +428,13 @@ void wxPyApp::_BootstrapApp() goto error; } - // On wxGTK the locale will be changed to match the system settings, but - // Python needs to have LC_NUMERIC set to "C" in order for the floating - // point conversions and such to work right. -#ifdef __WXGTK__ + // On wxGTK the locale will be changed to match the system settings, + // but Python before 2.4 needs to have LC_NUMERIC set to "C" in order + // for the floating point conversions and such to work right. +#if defined(__WXGTK__) && PY_VERSION_HEX < 0x02040000 setlocale(LC_NUMERIC, "C"); #endif - + // The stock objects were all NULL when they were loaded into // SWIG generated proxies, so re-init those now... wxPy_ReinitStockObjects(3); @@ -433,7 +442,7 @@ void wxPyApp::_BootstrapApp() wxPyEndBlockThreads(blocked); haveInitialized = true; } - + // It's now ok to generate exceptions for assertion errors. wxPythonApp->SetStartupComplete(true); @@ -530,11 +539,14 @@ void __wxPyPreStart(PyObject* moduleDict) #ifdef __WXMSW__ // wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF // | _CRTDBG_CHECK_ALWAYS_DF -// | _CRTDBG_DELAY_FREE_MEM_DF +// | _CRTDBG_DELAY_FREE_MEM_DF // ); #endif #ifdef WXP_WITH_THREAD +#if wxPyUSE_GIL_STATE + PyEval_InitThreads(); +#else PyEval_InitThreads(); wxPyTStates = new wxPyThreadStateArray; wxPyTMutex = new wxMutex; @@ -542,6 +554,7 @@ void __wxPyPreStart(PyObject* moduleDict) // Save the current (main) thread state in our array PyThreadState* tstate = wxPyBeginAllowThreads(); wxPyEndAllowThreads(tstate); +#endif #endif // Ensure that the build options in the DLL (or whatever) match this build @@ -562,12 +575,14 @@ void __wxPyCleanup() { wxEntryCleanup(); } #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE delete wxPyTMutex; wxPyTMutex = NULL; wxPyTStates->Empty(); delete wxPyTStates; wxPyTStates = NULL; #endif +#endif } @@ -598,7 +613,7 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args) wxPyNoAppError = PyErr_NewException("wx._core.PyNoAppError", PyExc_RuntimeError, NULL); PyDict_SetItemString(wxPython_dict, "PyNoAppError", wxPyNoAppError); - + #ifdef __WXMOTIF__ @@ -633,7 +648,7 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args) PyDict_SetItemString(wxPython_dict, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE)); PyDict_SetItemString(wxPython_dict, "__WXDEBUG__", PyInt_FromLong(wxdebug)); - + // Make a tuple of strings that gives more info about the platform. PyObject* PlatInfo = PyList_New(0); PyObject* obj; @@ -647,7 +662,7 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args) #if wxUSE_UNICODE _AddInfoString("unicode"); #else - _AddInfoString("ascii"); + _AddInfoString("ansi"); #endif #ifdef __WXGTK__ #ifdef __WXGTK20__ @@ -661,13 +676,13 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args) #else _AddInfoString("wx-assertions-off"); #endif - + #undef _AddInfoString PyObject* PlatInfoTuple = PyList_AsTuple(PlatInfo); Py_DECREF(PlatInfo); PyDict_SetItemString(wxPython_dict, "PlatformInfo", PlatInfoTuple); - + RETURN_NONE(); } @@ -781,7 +796,7 @@ void wxPy_ReinitStockObjects(int pass) if (pass == 1) { } \ else if (pass == 2) { rsoPass2(#name); } \ else if (pass == 3) { rsoPass3(#name, #classname, (void*)&name); } - + REINITOBJ(wxNORMAL_FONT, wxFont); REINITOBJ(wxSMALL_FONT, wxFont); @@ -862,27 +877,30 @@ bool wxPyCheckForApp() { //--------------------------------------------------------------------------- - -void wxPyClientData_dtor(wxPyClientData* self) { - if (! wxPyDoingCleanup) { // Don't do it during cleanup as Python - // may have already garbage collected the object... - bool blocked = wxPyBeginBlockThreads(); +void wxPyUserData_dtor(wxPyUserData* self) { + if (! wxPyDoingCleanup) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(self->m_obj); self->m_obj = NULL; wxPyEndBlockThreads(blocked); } } -void wxPyUserData_dtor(wxPyUserData* self) { - if (! wxPyDoingCleanup) { - bool blocked = wxPyBeginBlockThreads(); - Py_DECREF(self->m_obj); + +void wxPyClientData_dtor(wxPyClientData* self) { + if (! wxPyDoingCleanup) { // Don't do it during cleanup as Python + // may have already garbage collected the object... + if (self->m_incRef) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + Py_DECREF(self->m_obj); + wxPyEndBlockThreads(blocked); + } self->m_obj = NULL; - wxPyEndBlockThreads(blocked); } } + // This is called when an OOR controled object is being destroyed. Although // the C++ object is going away there is no way to force the Python object // (and all references to it) to die too. This causes problems (crashes) in @@ -895,7 +913,7 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) { static PyObject* deadObjectClass = NULL; - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (deadObjectClass == NULL) { deadObjectClass = PyDict_GetItemString(wxPython_dict, "_wxPyDeadObject"); // TODO: Can not wxASSERT here because inside a wxPyBeginBlock Threads, @@ -905,8 +923,9 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) { } - // Only if there is more than one reference to the object - if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 ) { + // Only if there is more than one reference to the object and we are + // holding the OOR reference: + if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 && self->m_incRef) { // bool isInstance = wxPyInstance_Check(self->m_obj); // TODO same here //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!")); @@ -1042,6 +1061,8 @@ PyObject* wxPyMake_wxSizer(wxSizer* source, bool setThisOwn) { #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE + inline unsigned long wxPyGetCurrentThreadId() { return wxThread::GetCurrentId(); @@ -1086,11 +1107,12 @@ void wxPySaveThreadState(PyThreadState* tstate) { if (info.tstate != tstate) wxLogMessage("*** tstate mismatch!???"); #endif - // info.tstate = tstate; *** DO NOT update existing ones??? + info.tstate = tstate; // allow for transient tstates // Normally it will never change, but apparently COM callbacks // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient // tstate which will then be garbage the next time we try to use // it... + wxPyTMutex->Unlock(); return; } @@ -1101,6 +1123,7 @@ void wxPySaveThreadState(PyThreadState* tstate) { } #endif +#endif @@ -1110,7 +1133,9 @@ void wxPySaveThreadState(PyThreadState* tstate) { PyThreadState* wxPyBeginAllowThreads() { #ifdef WXP_WITH_THREAD PyThreadState* saved = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS; +#if !wxPyUSE_GIL_STATE wxPySaveThreadState(saved); +#endif return saved; #else return NULL; @@ -1128,17 +1153,18 @@ void wxPyEndAllowThreads(PyThreadState* saved) { // Calls from wxWindows back to Python code, or even any PyObject // manipulations, PyDECREF's and etc. are wrapped in calls to these functions: -bool wxPyBeginBlockThreads() { +wxPyBlock_t wxPyBeginBlockThreads() { #ifdef WXP_WITH_THREAD - // This works in for 2.3, maybe a good alternative to find the needed tstate? - // PyThreadState *check = PyGILState_GetThisThreadState(); - +#if wxPyUSE_GIL_STATE + PyGILState_STATE state = PyGILState_Ensure(); + return state; +#else PyThreadState *current = _PyThreadState_Current; // Only block if there wasn't already a tstate, or if the current one is // not the one we are wanting to change to. This should prevent deadlock // if there are nested calls to wxPyBeginBlockThreads - bool blocked = false; + wxPyBlock_t blocked = false; wxPyThreadState* tstate = wxPyGetThreadState(); if (current != tstate->tstate) { PyEval_RestoreThread(tstate->tstate); @@ -1146,11 +1172,17 @@ bool wxPyBeginBlockThreads() { } return blocked; #endif +#else + return false; +#endif } -void wxPyEndBlockThreads(bool blocked) { +void wxPyEndBlockThreads(wxPyBlock_t blocked) { #ifdef WXP_WITH_THREAD +#if wxPyUSE_GIL_STATE + PyGILState_Release(blocked); +#else // Only unblock if we blocked in the last call to wxPyBeginBlockThreads. // The value of blocked passed in needs to be the same as that returned // from wxPyBeginBlockThreads at the same nesting level. @@ -1158,6 +1190,7 @@ void wxPyEndBlockThreads(bool blocked) { PyEval_SaveThread(); } #endif +#endif } @@ -1181,7 +1214,8 @@ bool wxPyInputStream::eof() { } wxPyInputStream::~wxPyInputStream() { - /* do nothing */ + if (m_wxis) + delete m_wxis; } @@ -1194,7 +1228,7 @@ PyObject* wxPyInputStream::read(int size) { // check if we have a real wxInputStream to work with if (!m_wxis) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyErr_SetString(PyExc_IOError, "no valid C-wxInputStream"); wxPyEndBlockThreads(blocked); return NULL; @@ -1213,7 +1247,7 @@ PyObject* wxPyInputStream::read(int size) { } // error check - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); wxStreamError err = m_wxis->GetLastError(); if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); @@ -1235,7 +1269,7 @@ PyObject* wxPyInputStream::readline(int size) { // check if we have a real wxInputStream to work with if (!m_wxis) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream"); wxPyEndBlockThreads(blocked); return NULL; @@ -1248,7 +1282,7 @@ PyObject* wxPyInputStream::readline(int size) { } // errorcheck - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); wxStreamError err = m_wxis->GetLastError(); if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); @@ -1267,19 +1301,19 @@ PyObject* wxPyInputStream::readlines(int sizehint) { // check if we have a real wxInputStream to work with if (!m_wxis) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream"); wxPyEndBlockThreads(blocked); return NULL; } // init list - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); pylist = PyList_New(0); wxPyEndBlockThreads(blocked); - + if (!pylist) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyErr_NoMemory(); wxPyEndBlockThreads(blocked); return NULL; @@ -1290,12 +1324,12 @@ PyObject* wxPyInputStream::readlines(int sizehint) { for (i=0; (m_wxis->CanRead()) && ((sizehint < 0) || (i < sizehint));) { PyObject* s = this->readline(); if (s == NULL) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(pylist); wxPyEndBlockThreads(blocked); return NULL; } - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyList_Append(pylist, s); i += PyString_Size(s); wxPyEndBlockThreads(blocked); @@ -1304,7 +1338,7 @@ PyObject* wxPyInputStream::readlines(int sizehint) { // error check wxStreamError err = m_wxis->GetLastError(); if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(pylist); PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); wxPyEndBlockThreads(blocked); @@ -1333,9 +1367,20 @@ wxPyCBInputStream::wxPyCBInputStream(PyObject *r, PyObject *s, PyObject *t, bool : wxInputStream(), m_read(r), m_seek(s), m_tell(t), m_block(block) {} +wxPyCBInputStream::wxPyCBInputStream(const wxPyCBInputStream& other) +{ + m_read = other.m_read; + m_seek = other.m_seek; + m_tell = other.m_tell; + m_block = other.m_block; + Py_INCREF(m_read); + Py_INCREF(m_seek); + Py_INCREF(m_tell); +} + wxPyCBInputStream::~wxPyCBInputStream() { - bool blocked=false; + wxPyBlock_t blocked; if (m_block) blocked = wxPyBeginBlockThreads(); Py_XDECREF(m_read); Py_XDECREF(m_seek); @@ -1345,7 +1390,7 @@ wxPyCBInputStream::~wxPyCBInputStream() { wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) { - bool blocked=false; + wxPyBlock_t blocked; if (block) blocked = wxPyBeginBlockThreads(); PyObject* read = getMethod(py, "read"); @@ -1370,6 +1415,10 @@ wxPyCBInputStream* wxPyCBInputStream_create(PyObject *py, bool block) { return wxPyCBInputStream::create(py, block); } +wxPyCBInputStream* wxPyCBInputStream_copy(wxPyCBInputStream* other) { + return new wxPyCBInputStream(*other); +} + PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) { if (!PyObject_HasAttrString(py, name)) return NULL; @@ -1382,16 +1431,16 @@ PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) { } -size_t wxPyCBInputStream::GetSize() const { +wxFileOffset wxPyCBInputStream::GetLength() const { wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const if (m_seek && m_tell) { - off_t temp = self->OnSysTell(); - off_t ret = self->OnSysSeek(0, wxFromEnd); + wxFileOffset temp = self->OnSysTell(); + wxFileOffset ret = self->OnSysSeek(0, wxFromEnd); self->OnSysSeek(temp, wxFromStart); return ret; } else - return 0; + return wxInvalidOffset; } @@ -1399,7 +1448,7 @@ size_t wxPyCBInputStream::OnSysRead(void *buffer, size_t bufsize) { if (bufsize == 0) return 0; - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* arglist = Py_BuildValue("(i)", bufsize); PyObject* result = PyEval_CallObject(m_read, arglist); Py_DECREF(arglist); @@ -1426,14 +1475,20 @@ size_t wxPyCBInputStream::OnSysWrite(const void *buffer, size_t bufsize) { return 0; } -off_t wxPyCBInputStream::OnSysSeek(off_t off, wxSeekMode mode) { - bool blocked = wxPyBeginBlockThreads(); -#ifdef _LARGE_FILES - // off_t is a 64-bit value... - PyObject* arglist = Py_BuildValue("(Li)", off, mode); -#else - PyObject* arglist = Py_BuildValue("(ii)", off, mode); -#endif + +wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + PyObject* arglist = PyTuple_New(2); + + if (sizeof(wxFileOffset) > sizeof(long)) + // wxFileOffset is a 64-bit value... + PyTuple_SET_ITEM(arglist, 0, PyLong_FromLongLong(off)); + else + PyTuple_SET_ITEM(arglist, 0, PyInt_FromLong(off)); + + PyTuple_SET_ITEM(arglist, 1, PyInt_FromLong(mode)); + + PyObject* result = PyEval_CallObject(m_seek, arglist); Py_DECREF(arglist); Py_XDECREF(result); @@ -1442,18 +1497,16 @@ off_t wxPyCBInputStream::OnSysSeek(off_t off, wxSeekMode mode) { } -off_t wxPyCBInputStream::OnSysTell() const { - bool blocked = wxPyBeginBlockThreads(); +wxFileOffset wxPyCBInputStream::OnSysTell() const { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* arglist = Py_BuildValue("()"); PyObject* result = PyEval_CallObject(m_tell, arglist); Py_DECREF(arglist); - off_t o = 0; + wxFileOffset o = 0; if (result != NULL) { -#ifdef _LARGE_FILES if (PyLong_Check(result)) o = PyLong_AsLongLong(result); else -#endif o = PyInt_AsLong(result); Py_DECREF(result); }; @@ -1476,7 +1529,7 @@ wxPyCallback::wxPyCallback(const wxPyCallback& other) { } wxPyCallback::~wxPyCallback() { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(m_func); wxPyEndBlockThreads(blocked); } @@ -1494,7 +1547,7 @@ void wxPyCallback::EventThunker(wxEvent& event) { PyObject* tuple; bool checkSkip = false; - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); wxString className = event.GetClassInfo()->GetClassName(); // If the event is one of these types then pass the original @@ -1521,7 +1574,7 @@ void wxPyCallback::EventThunker(wxEvent& event) { s_preName = PyString_FromString(wxPy_PRECALLINIT); s_postName = PyString_FromString(wxPy_POSTCALLCLEANUP); } - + // Check if the event object needs some preinitialization if (PyObject_HasAttr(arg, s_preName)) { result = PyObject_CallMethodObjArgs(arg, s_preName, arg, NULL); @@ -1530,9 +1583,9 @@ void wxPyCallback::EventThunker(wxEvent& event) { PyErr_Clear(); // Just in case... } else { PyErr_Print(); - } + } } - + // Call the event handler, passing the event object tuple = PyTuple_New(1); PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg @@ -1552,7 +1605,7 @@ void wxPyCallback::EventThunker(wxEvent& event) { PyErr_Clear(); // Just in case... } else { PyErr_Print(); - } + } } if ( checkSkip ) { @@ -1754,7 +1807,7 @@ PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTu void wxPyCBH_delete(wxPyCallbackHelper* cbh) { if (cbh->m_incRef) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_XDECREF(cbh->m_self); Py_XDECREF(cbh->m_class); wxPyEndBlockThreads(blocked); @@ -1775,14 +1828,14 @@ wxPyEvtSelfRef::wxPyEvtSelfRef() { } wxPyEvtSelfRef::~wxPyEvtSelfRef() { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (m_cloned) Py_DECREF(m_self); wxPyEndBlockThreads(blocked); } void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); if (m_cloned) Py_DECREF(m_self); m_self = self; @@ -1849,7 +1902,7 @@ PyObject* wxPy_ConvertList(wxListBase* listbase) { wxObject* wxObj; wxNode* node = list->GetFirst(); - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); pyList = PyList_New(0); while (node) { wxObj = node->GetData(); @@ -1872,7 +1925,7 @@ long wxPyGetWinHandle(wxWindow* win) { #if defined(__WXGTK__) || defined(__WXX11) return (long)GetXWindow(win); #endif - + #ifdef __WXMAC__ //return (long)MAC_WXHWND(win->MacGetTopLevelWindowRef()); return (long)win->GetHandle(); @@ -1895,7 +1948,7 @@ wxString* wxString_in_helper(PyObject* source) { #if wxUSE_UNICODE PyObject* uni = source; if (PyString_Check(source)) { - uni = PyUnicode_FromObject(source); + uni = PyUnicode_FromEncodedObject(source, wxPyDefaultEncoding, "strict"); if (PyErr_Occurred()) return NULL; } target = new wxString(); @@ -1908,14 +1961,24 @@ wxString* wxString_in_helper(PyObject* source) { if (PyString_Check(source)) Py_DECREF(uni); #else - char* tmpPtr; int tmpSize; - if (PyString_AsStringAndSize(source, &tmpPtr, &tmpSize) == -1) { - PyErr_SetString(PyExc_TypeError, "Unable to convert string"); - return NULL; + // Convert to a string object if it isn't already, then to wxString + PyObject* str = source; + if (PyUnicode_Check(source)) { + str = PyUnicode_AsEncodedString(source, wxPyDefaultEncoding, "strict"); + if (PyErr_Occurred()) return NULL; + } + else if (!PyString_Check(source)) { + str = PyObject_Str(source); + if (PyErr_Occurred()) return NULL; } + char* tmpPtr; int tmpSize; + PyString_AsStringAndSize(str, &tmpPtr, &tmpSize); target = new wxString(tmpPtr, tmpSize); + + if (!PyString_Check(source)) + Py_DECREF(str); #endif // wxUSE_UNICODE - + return target; } @@ -1929,28 +1992,32 @@ wxString Py2wxString(PyObject* source) // Convert to a unicode object, if not already, then to a wxString PyObject* uni = source; if (!PyUnicode_Check(source)) { - uni = PyUnicode_FromObject(source); + uni = PyUnicode_FromEncodedObject(source, wxPyDefaultEncoding, "strict"); if (PyErr_Occurred()) return wxEmptyString; // TODO: should we PyErr_Clear? - } + } size_t len = PyUnicode_GET_SIZE(uni); if (len) { PyUnicode_AsWideChar((PyUnicodeObject*)uni, target.GetWriteBuf(len), len); target.UngetWriteBuf(); } - + if (!PyUnicode_Check(source)) Py_DECREF(uni); #else // Convert to a string object if it isn't already, then to wxString PyObject* str = source; - if (!PyString_Check(source)) { + if (PyUnicode_Check(source)) { + str = PyUnicode_AsEncodedString(source, wxPyDefaultEncoding, "strict"); + if (PyErr_Occurred()) return wxEmptyString; // TODO: should we PyErr_Clear? + } + else if (!PyString_Check(source)) { str = PyObject_Str(source); if (PyErr_Occurred()) return wxEmptyString; // TODO: should we PyErr_Clear? } char* tmpPtr; int tmpSize; PyString_AsStringAndSize(str, &tmpPtr, &tmpSize); target = wxString(tmpPtr, tmpSize); - + if (!PyString_Check(source)) Py_DECREF(str); #endif // wxUSE_UNICODE @@ -1972,6 +2039,17 @@ PyObject* wx2PyString(const wxString& src) } + +void wxSetDefaultPyEncoding(const char* encoding) +{ + strncpy(wxPyDefaultEncoding, encoding, DEFAULTENCODING_SIZE); +} + +const char* wxGetDefaultPyEncoding() +{ + return wxPyDefaultEncoding; +} + //----------------------------------------------------------------------