#ifdef WXP_WITH_THREAD
+#if !wxPyUSE_GIL_STATE
struct wxPyThreadState {
unsigned long tid;
PyThreadState* tstate;
wxPyThreadStateArray* wxPyTStates = NULL;
wxMutex* wxPyTMutex = NULL;
+
+#endif
#endif
+
#define DEFAULTENCODING_SIZE 64
static char wxPyDefaultEncoding[DEFAULTENCODING_SIZE] = "ascii";
// 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;
wxPyApp::~wxPyApp() {
+ wxPythonApp = NULL;
+ wxApp::SetInstance(NULL);
}
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);
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);
// 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);
}
// set the exception
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
PyObject* s = wx2PyString(buf);
PyErr_SetObject(wxPyAssertionError, s);
Py_DECREF(s);
// 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));
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));
void wxPyApp::MacNewFile()
{
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
if (wxPyCBH_findCallback(m_myInst, "MacNewFile"))
wxPyCBH_callCallback(m_myInst, Py_BuildValue("()"));
wxPyEndBlockThreads(blocked);
void wxPyApp::MacReopenApp()
{
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
if (wxPyCBH_findCallback(m_myInst, "MacReopenApp"))
wxPyCBH_callCallback(m_myInst, Py_BuildValue("()"));
wxPyEndBlockThreads(blocked);
void wxPyApp::_BootstrapApp()
{
static bool haveInitialized = false;
- bool result, blocked;
+ bool result;
+ wxPyBlock_t blocked;
PyObject* retval = NULL;
PyObject* pyint = NULL;
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; x<argc; x++) {
- PyObject *pyArg = PyList_GetItem(sysargv, x);
- argv[x] = PyString_AsString(pyArg);
+ for(x=1; x<argc; x++) {
+ PyObject *pyArg = PyList_GetItem(sysargv, x-1);
+ argv[x] = strdup(PyString_AsString(pyArg));
}
argv[argc] = NULL;
}
// Initialize wxWidgets
result = wxEntryStart(argc, argv);
- delete [] argv;
+ // wxApp takes ownership of the argv array, don't delete it here
blocked = wxPyBeginBlockThreads();
if (! result) {
setlocale(LC_NUMERIC, "C");
#endif
+// wxSystemOptions::SetOption(wxT("mac.textcontrol-use-mlte"), 1);
+
// The stock objects were all NULL when they were loaded into
// SWIG generated proxies, so re-init those now...
wxPy_ReinitStockObjects(3);
wxPyEndBlockThreads(blocked);
haveInitialized = true;
}
+ else {
+ this->argc = 0;
+ this->argv = NULL;
+ }
+
// It's now ok to generate exceptions for assertion errors.
wxPythonApp->SetStartupComplete(true);
#endif
#ifdef WXP_WITH_THREAD
+#if wxPyUSE_GIL_STATE
+ PyEval_InitThreads();
+#else
PyEval_InitThreads();
wxPyTStates = new wxPyThreadStateArray;
wxPyTMutex = new wxMutex;
// 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
wxEntryCleanup();
}
#ifdef WXP_WITH_THREAD
+#if !wxPyUSE_GIL_STATE
delete wxPyTMutex;
wxPyTMutex = NULL;
wxPyTStates->Empty();
delete wxPyTStates;
wxPyTStates = NULL;
#endif
+#endif
}
}
-//---------------------------------------------------------------------------
-
-// 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;
-}
//---------------------------------------------------------------------------
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);
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);
}
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,
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
}
}
+ // 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
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();
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);
}
#ifdef WXP_WITH_THREAD
+#if !wxPyUSE_GIL_STATE
+
inline
unsigned long wxPyGetCurrentThreadId() {
return wxThread::GetCurrentId();
}
#endif
+#endif
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;
// 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);
}
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.
PyEval_SaveThread();
}
#endif
+#endif
}
// 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;
}
// 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");
// 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;
}
// 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");
// 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;
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);
// 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);
wxPyCBInputStream::~wxPyCBInputStream() {
- bool blocked=false;
+ wxPyBlock_t blocked;
if (m_block) blocked = wxPyBeginBlockThreads();
Py_XDECREF(m_read);
Py_XDECREF(m_seek);
wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) {
- bool blocked=false;
+ wxPyBlock_t blocked;
if (block) blocked = wxPyBeginBlockThreads();
PyObject* read = getMethod(py, "read");
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);
wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) {
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
PyObject* arglist = PyTuple_New(2);
if (sizeof(wxFileOffset) > sizeof(long))
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);
//----------------------------------------------------------------------
-IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxEvtHandler);
+IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
wxPyCallback::wxPyCallback(PyObject* func) {
m_func = func;
}
wxPyCallback::~wxPyCallback() {
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
Py_DECREF(m_func);
wxPyEndBlockThreads(blocked);
}
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
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);
}
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;
wxObject* wxObj;
wxNode* node = list->GetFirst();
- bool blocked = wxPyBeginBlockThreads();
+ wxPyBlock_t blocked = wxPyBeginBlockThreads();
pyList = PyList_New(0);
while (node) {
wxObj = node->GetData();
}
+//----------------------------------------------------------------------
+// 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;
+}
+
+
//----------------------------------------------------------------------
//----------------------------------------------------------------------