X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d02ea46cad50bf1bec81a8d5bcaa495b22f98057..962a48f6f991a4924eaf03302988a490e97b2ee5:/wxPython/src/helpers.cpp diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index a299f1ea22..13f89c15e6 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -61,6 +61,7 @@ bool wxPyDoingCleanup = false; #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE struct wxPyThreadState { unsigned long tid; PyThreadState* tstate; @@ -76,8 +77,11 @@ WX_DEFINE_OBJARRAY(wxPyThreadStateArray); wxPyThreadStateArray* wxPyTStates = NULL; wxMutex* wxPyTMutex = NULL; + +#endif #endif + #define DEFAULTENCODING_SIZE 64 static char wxPyDefaultEncoding[DEFAULTENCODING_SIZE] = "ascii"; @@ -93,14 +97,15 @@ PyObject* wxPyPtrTypeMap = NULL; // This gets run when the DLL is loaded. We just need to save a handle. //---------------------------------------------------------------------- +extern "C" BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function 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; @@ -121,6 +126,8 @@ wxPyApp::wxPyApp() { wxPyApp::~wxPyApp() { + wxPythonApp = NULL; + wxApp::SetInstance(NULL); } @@ -150,7 +157,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); @@ -160,7 +167,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); @@ -191,7 +198,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); @@ -225,7 +232,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); @@ -260,7 +267,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)); @@ -271,7 +278,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)); @@ -282,7 +289,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); @@ -290,7 +297,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); @@ -383,7 +390,8 @@ 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; @@ -395,14 +403,18 @@ void wxPyApp::_BootstrapApp() int argc = 0; char** argv = NULL; blocked = wxPyBeginBlockThreads(); + PyObject* sysargv = PySys_GetObject("argv"); - if (sysargv != NULL) { - argc = PyList_Size(sysargv); + PyObject* executable = PySys_GetObject("executable"); + + if (sysargv != NULL && executable != NULL) { + argc = PyList_Size(sysargv) + 1; argv = new char*[argc+1]; + argv[0] = strdup(PyString_AsString(executable)); int x; - for(x=0; xargc = 0; + this->argv = NULL; + } + // It's now ok to generate exceptions for assertion errors. wxPythonApp->SetStartupComplete(true); @@ -539,6 +558,9 @@ void __wxPyPreStart(PyObject* moduleDict) #endif #ifdef WXP_WITH_THREAD +#if wxPyUSE_GIL_STATE + PyEval_InitThreads(); +#else PyEval_InitThreads(); wxPyTStates = new wxPyThreadStateArray; wxPyTMutex = new wxMutex; @@ -546,6 +568,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 @@ -566,12 +589,14 @@ void __wxPyCleanup() { wxEntryCleanup(); } #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE delete wxPyTMutex; wxPyTMutex = NULL; wxPyTStates->Empty(); delete wxPyTStates; wxPyTStates = NULL; #endif +#endif } @@ -676,21 +701,6 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args) } -//--------------------------------------------------------------------------- - -// Python's PyInstance_Check does not return True for instances of new-style -// classes. This should get close enough for both new and old classes but I -// should re-evaluate the need for doing instance checks... -bool wxPyInstance_Check(PyObject* obj) { - return PyObject_HasAttrString(obj, "__class__") != 0; -} - - -// This one checks if the object is an instance of a SWIG proxy class (it has -// a .this attribute) -bool wxPySwigInstance_Check(PyObject* obj) { - return PyObject_HasAttrString(obj, "this") != 0; -} //--------------------------------------------------------------------------- @@ -868,7 +878,7 @@ bool wxPyCheckForApp() { void wxPyUserData_dtor(wxPyUserData* self) { if (! wxPyDoingCleanup) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(self->m_obj); self->m_obj = NULL; wxPyEndBlockThreads(blocked); @@ -880,7 +890,7 @@ 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) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(self->m_obj); wxPyEndBlockThreads(blocked); } @@ -902,7 +912,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, @@ -976,6 +986,7 @@ void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) { PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn, bool checkEvtHandler) { PyObject* target = NULL; bool isEvtHandler = false; + bool isSizer = false; if (source) { // If it's derived from wxEvtHandler then there may @@ -992,6 +1003,18 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn, bool checkEvtHan } } + // Also check for wxSizer + if (!target && wxIsKindOf(source, wxSizer)) { + isSizer = true; + wxSizer* sz = (wxSizer*)source; + wxPyOORClientData* data = (wxPyOORClientData*)sz->GetClientObject(); + if (data) { + target = data->m_obj; + if (target) + Py_INCREF(target); + } + } + if (! target) { // Otherwise make it the old fashioned way by making a new shadow // object and putting this pointer in it. Look up the class @@ -1009,6 +1032,8 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn, bool checkEvtHan target = wxPyConstructObject((void*)source, name, setThisOwn); if (target && isEvtHandler) ((wxEvtHandler*)source)->SetClientObject(new wxPyOORClientData(target)); + if (target && isSizer) + ((wxSizer*)source)->SetClientObject(new wxPyOORClientData(target)); } else { wxString msg(wxT("wxPython class not found for ")); msg += source->GetClassInfo()->GetClassName(); @@ -1024,25 +1049,8 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn, bool checkEvtHan PyObject* wxPyMake_wxSizer(wxSizer* source, bool setThisOwn) { - PyObject* target = NULL; - if (source && wxIsKindOf(source, wxSizer)) { - // If it's derived from wxSizer then there may already be a pointer to - // a Python object that we can use in the OOR data. - wxSizer* sz = (wxSizer*)source; - wxPyOORClientData* data = (wxPyOORClientData*)sz->GetClientObject(); - if (data) { - target = data->m_obj; - if (target) - Py_INCREF(target); - } - } - if (! target) { - target = wxPyMake_wxObject(source, setThisOwn, false); - if (target != Py_None) - ((wxSizer*)source)->SetClientObject(new wxPyOORClientData(target)); - } - return target; + return wxPyMake_wxObject(source, setThisOwn); } @@ -1050,6 +1058,8 @@ PyObject* wxPyMake_wxSizer(wxSizer* source, bool setThisOwn) { #ifdef WXP_WITH_THREAD +#if !wxPyUSE_GIL_STATE + inline unsigned long wxPyGetCurrentThreadId() { return wxThread::GetCurrentId(); @@ -1110,6 +1120,7 @@ void wxPySaveThreadState(PyThreadState* tstate) { } #endif +#endif @@ -1119,7 +1130,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; @@ -1137,17 +1150,21 @@ 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 (! Py_IsInitialized()) { + return (wxPyBlock_t)0; + } +#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); @@ -1155,11 +1172,20 @@ bool wxPyBeginBlockThreads() { } return blocked; #endif +#else + return (wxPyBlock_t)0; +#endif } -void wxPyEndBlockThreads(bool blocked) { +void wxPyEndBlockThreads(wxPyBlock_t blocked) { #ifdef WXP_WITH_THREAD + if (! Py_IsInitialized()) { + return; + } +#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. @@ -1167,6 +1193,7 @@ void wxPyEndBlockThreads(bool blocked) { PyEval_SaveThread(); } #endif +#endif } @@ -1204,7 +1231,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; @@ -1223,7 +1250,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"); @@ -1245,7 +1272,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; @@ -1258,7 +1285,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"); @@ -1277,19 +1304,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; @@ -1300,12 +1327,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); @@ -1314,7 +1341,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); @@ -1356,7 +1383,7 @@ wxPyCBInputStream::wxPyCBInputStream(const wxPyCBInputStream& other) wxPyCBInputStream::~wxPyCBInputStream() { - bool blocked=false; + wxPyBlock_t blocked; if (m_block) blocked = wxPyBeginBlockThreads(); Py_XDECREF(m_read); Py_XDECREF(m_seek); @@ -1366,7 +1393,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"); @@ -1424,7 +1451,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); @@ -1453,7 +1480,7 @@ size_t wxPyCBInputStream::OnSysWrite(const void *buffer, size_t bufsize) { wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* arglist = PyTuple_New(2); if (sizeof(wxFileOffset) > sizeof(long)) @@ -1474,7 +1501,7 @@ wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) { wxFileOffset wxPyCBInputStream::OnSysTell() const { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* arglist = Py_BuildValue("()"); PyObject* result = PyEval_CallObject(m_tell, arglist); Py_DECREF(arglist); @@ -1492,7 +1519,7 @@ wxFileOffset wxPyCBInputStream::OnSysTell() const { //---------------------------------------------------------------------- -IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxEvtHandler); +IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject); wxPyCallback::wxPyCallback(PyObject* func) { m_func = func; @@ -1505,7 +1532,7 @@ wxPyCallback::wxPyCallback(const wxPyCallback& other) { } wxPyCallback::~wxPyCallback() { - bool blocked = wxPyBeginBlockThreads(); + wxPyBlock_t blocked = wxPyBeginBlockThreads(); Py_DECREF(m_func); wxPyEndBlockThreads(blocked); } @@ -1523,7 +1550,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 @@ -1783,7 +1810,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); @@ -1804,14 +1831,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; @@ -1878,7 +1905,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(); @@ -2683,6 +2710,145 @@ PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) { } +//---------------------------------------------------------------------- +// wxPyImageHandler methods +// +// TODO: Switch these to use wxPython's standard macros and helper classes +// for calling callbacks. + +PyObject* wxPyImageHandler::m_DoCanRead_Name = NULL; +PyObject* wxPyImageHandler::m_GetImageCount_Name = NULL; +PyObject* wxPyImageHandler::m_LoadFile_Name = NULL; +PyObject* wxPyImageHandler::m_SaveFile_Name = NULL; + +PyObject* wxPyImageHandler::py_InputStream(wxInputStream* stream) { + return wxPyConstructObject(new wxPyInputStream(stream), + wxT("wxPyInputStream"), 0); +} + +PyObject* wxPyImageHandler::py_Image(wxImage* image) { + return wxPyConstructObject(image, wxT("wxImage"), 0); +} + +PyObject* wxPyImageHandler::py_OutputStream(wxOutputStream* stream) { + return wxPyConstructObject(stream, wxT("wxOutputStream"), 0); +} + +wxPyImageHandler::wxPyImageHandler(): + m_self(NULL) +{ + if (!m_DoCanRead_Name) { + m_DoCanRead_Name = PyString_FromString("DoCanRead"); + m_GetImageCount_Name = PyString_FromString("GetImageCount"); + m_LoadFile_Name = PyString_FromString("LoadFile"); + m_SaveFile_Name = PyString_FromString("SaveFile"); + } +} + +wxPyImageHandler::~wxPyImageHandler() { + if (m_self) { + Py_DECREF(m_self); + m_self = NULL; + } +} + +void wxPyImageHandler::_SetSelf(PyObject *self) { + // should check here for isinstance(PyImageHandler) ?? + m_self = self; + Py_INCREF(m_self); +} + +bool wxPyImageHandler::DoCanRead(wxInputStream& stream) { + // check if our object has this method + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if (!m_self || !PyObject_HasAttr(m_self, m_DoCanRead_Name)) { + wxPyEndBlockThreads(blocked); + return false; + } + + PyObject* res = PyObject_CallMethodObjArgs(m_self, m_DoCanRead_Name, + py_InputStream(&stream), NULL); + bool retval = false; + if (res) { + retval = PyInt_AsLong(res); + Py_DECREF(res); + PyErr_Clear(); + } + else + PyErr_Print(); + wxPyEndBlockThreads(blocked); + return retval; +} + +bool wxPyImageHandler::LoadFile( wxImage* image, wxInputStream& stream, + bool verbose, int index ) { + // check if our object has this method + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if (!m_self || !PyObject_HasAttr(m_self, m_LoadFile_Name)) { + wxPyEndBlockThreads(blocked); + return false; + } + PyObject* res = PyObject_CallMethodObjArgs(m_self, m_LoadFile_Name, + py_Image(image), + py_InputStream(&stream), + PyInt_FromLong(verbose), + PyInt_FromLong(index), + NULL); + bool retval = false; + if (res) { + retval = PyInt_AsLong(res); + Py_DECREF(res); + PyErr_Clear(); + } else + PyErr_Print(); + wxPyEndBlockThreads(blocked); + return retval; +} + +bool wxPyImageHandler::SaveFile( wxImage* image, wxOutputStream& stream, + bool verbose ) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if (!m_self || !PyObject_HasAttr(m_self, m_SaveFile_Name)) { + wxPyEndBlockThreads(blocked); + return false; + } + PyObject* res = PyObject_CallMethodObjArgs(m_self, m_SaveFile_Name, + py_Image(image), + py_OutputStream(&stream), + PyInt_FromLong(verbose), + NULL); + bool retval = false; + if(res) { + retval=PyInt_AsLong(res); + Py_DECREF(res); + PyErr_Clear(); + } else + PyErr_Print(); + wxPyEndBlockThreads(blocked); + return retval; +} + +int wxPyImageHandler::GetImageCount( wxInputStream& stream ) { + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if (!m_self || !PyObject_HasAttr(m_self, m_GetImageCount_Name)) { + wxPyEndBlockThreads(blocked); + return 1; + } + PyObject *res=PyObject_CallMethodObjArgs(m_self, m_GetImageCount_Name, + py_InputStream(&stream), + NULL); + int retval = 1; + if(res) { + retval=PyInt_AsLong(res); + Py_DECREF(res); + PyErr_Clear(); + } else + PyErr_Print(); + wxPyEndBlockThreads(blocked); + return retval; +} + + //---------------------------------------------------------------------- //----------------------------------------------------------------------