#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
}
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);
}
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();