X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1fded56b375bf7a4687af1cdb182899614c1b2a8..71aba8333cc915afff9e740c944f7fa7247abacb:/wxPython/src/helpers.cpp?ds=inline diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index a425d6cf1f..57b971ae57 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -28,6 +28,10 @@ #include #endif +#include +#include +#include + //---------------------------------------------------------------------- #if PYTHON_API_VERSION <= 1007 && wxUSE_UNICODE @@ -36,14 +40,6 @@ //---------------------------------------------------------------------- -#ifdef __WXGTK__ -int WXDLLEXPORT wxEntryStart( int& argc, char** argv ); -#else -int WXDLLEXPORT wxEntryStart( int argc, char** argv ); -#endif -int WXDLLEXPORT wxEntryInitGui(); -void WXDLLEXPORT wxEntryCleanup(); - wxPyApp* wxPythonApp = NULL; // Global instance of application object bool wxPyDoCleanup = FALSE; bool wxPyDoingCleanup = FALSE; @@ -334,6 +330,7 @@ void wxPyApp::SetMacHelpMenuTitleName(const wxString& val) { //---------------------------------------------------------------------- +#if 0 static char* wxPyCopyCString(const wxChar* src) { wxWX2MBbuf buff = (wxWX2MBbuf)wxConvCurrent->cWX2MB(src); @@ -366,13 +363,13 @@ static wxChar* wxPyCopyWString(const wxChar *src) return copystring(src); } #endif +#endif //---------------------------------------------------------------------- -// This is where we pick up the first part of the wxEntry functionality... -// The rest is in __wxStart and __wxCleanup. This function is called when -// wxcmodule is imported. (Before there is a wxApp object.) +// This function is called when the wxc module is imported to do some initial +// setup. (Before there is a wxApp object.) void __wxPreStart(PyObject* moduleDict) { @@ -386,76 +383,60 @@ void __wxPreStart(PyObject* moduleDict) wxPyTMutex = new wxMutex; #endif - // Restore default signal handlers, (prevents crash upon Ctrl-C in the - // console that launched a wxPython app...) - PyOS_FiniInterrupts(); - - wxApp::CheckBuildOptions(wxBuildOptions()); + // Ensure that the build options in the DLL (or whatever) match this build + wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "wxPython"); + // Create an exception object to use for wxASSERTions wxPyAssertionError = PyErr_NewException("wxPython.wxc.wxPyAssertionError", PyExc_AssertionError, NULL); PyDict_SetItemString(moduleDict, "wxPyAssertionError", wxPyAssertionError); - - - // Bail out if there is already a wxApp created. This means that the - // toolkit has already been initialized, as in embedding wxPython in - // a C++ wxWindows app, so we don't need to call wxEntryStart. - if (wxTheApp != NULL) { - return; - } - wxPyDoCleanup = TRUE; - - int argc = 0; - char** argv = NULL; - PyObject* sysargv = PySys_GetObject("argv"); - if (sysargv != NULL) { - argc = PyList_Size(sysargv); - argv = new char*[argc+1]; - int x; - for(x=0; xargc = argc; - wxPythonApp->argv = argv; + if (! wxEntryStart(argc, argv) ) { + PyErr_SetString(PyExc_SystemError, // is this the right one? + "wxEntryStart failed!"); + goto error; + } + delete [] argv; - wxEntryInitGui(); - // Call the Python App's OnInit function + // The stock objects were all NULL when they were loaded into + // SWIG generated proxies, so re-init those now... + wxPy_ReinitStockObjects(); + + + // Call the Python wxApp's OnInit function arglist = PyTuple_New(0); result = PyEval_CallObject(onInitFunc, arglist); Py_DECREF(arglist); @@ -463,7 +444,7 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args) return NULL; } - PyObject* pyint = PyNumber_Int(result); + pyint = PyNumber_Int(result); if (! pyint) { PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value"); goto error; @@ -490,6 +471,7 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args) } + void __wxCleanup() { wxPyDoingCleanup = TRUE; if (wxPyDoCleanup) @@ -552,6 +534,102 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) return Py_None; } + +//--------------------------------------------------------------------------- + +// The stock objects are no longer created when the wxc module is imported, but +// only after the app object has been created. This function will be called before +// OnInit is called so we can hack the new pointer values into the obj.this attributes. + +void wxPy_ReinitStockObjects() +{ + char ptrbuf[128]; + PyObject* obj; + PyObject* ptrobj; + + + +#define REINITOBJ(name, type) \ + obj = PyDict_GetItemString(wxPython_dict, #name); \ + wxASSERT_MSG(obj != NULL, wxT("Unable to find stock object for " #name)); \ + SWIG_MakePtr(ptrbuf, (char *) name, "_" #type "_p"); \ + ptrobj = PyString_FromString(ptrbuf); \ + PyObject_SetAttrString(obj, "this", ptrobj); \ + Py_DECREF(ptrobj) + +#define REINITOBJ2(name, type) \ + obj = PyDict_GetItemString(wxPython_dict, #name); \ + wxASSERT_MSG(obj != NULL, wxT("Unable to find stock object for " #name)); \ + SWIG_MakePtr(ptrbuf, (char *) &name, "_" #type "_p"); \ + ptrobj = PyString_FromString(ptrbuf); \ + PyObject_SetAttrString(obj, "this", ptrobj); \ + Py_DECREF(ptrobj) + + + REINITOBJ(wxNORMAL_FONT, wxFont); + REINITOBJ(wxSMALL_FONT, wxFont); + REINITOBJ(wxITALIC_FONT, wxFont); + REINITOBJ(wxSWISS_FONT, wxFont); + + REINITOBJ(wxRED_PEN, wxPen); + REINITOBJ(wxCYAN_PEN, wxPen); + REINITOBJ(wxGREEN_PEN, wxPen); + REINITOBJ(wxBLACK_PEN, wxPen); + REINITOBJ(wxWHITE_PEN, wxPen); + REINITOBJ(wxTRANSPARENT_PEN, wxPen); + REINITOBJ(wxBLACK_DASHED_PEN, wxPen); + REINITOBJ(wxGREY_PEN, wxPen); + REINITOBJ(wxMEDIUM_GREY_PEN, wxPen); + REINITOBJ(wxLIGHT_GREY_PEN, wxPen); + + REINITOBJ(wxBLUE_BRUSH, wxBrush); + REINITOBJ(wxGREEN_BRUSH, wxBrush); + REINITOBJ(wxWHITE_BRUSH, wxBrush); + REINITOBJ(wxBLACK_BRUSH, wxBrush); + REINITOBJ(wxTRANSPARENT_BRUSH, wxBrush); + REINITOBJ(wxCYAN_BRUSH, wxBrush); + REINITOBJ(wxRED_BRUSH, wxBrush); + REINITOBJ(wxGREY_BRUSH, wxBrush); + REINITOBJ(wxMEDIUM_GREY_BRUSH, wxBrush); + REINITOBJ(wxLIGHT_GREY_BRUSH, wxBrush); + + REINITOBJ(wxBLACK, wxColour); + REINITOBJ(wxWHITE, wxColour); + REINITOBJ(wxRED, wxColour); + REINITOBJ(wxBLUE, wxColour); + REINITOBJ(wxGREEN, wxColour); + REINITOBJ(wxCYAN, wxColour); + REINITOBJ(wxLIGHT_GREY, wxColour); + + REINITOBJ(wxSTANDARD_CURSOR, wxCursor); + REINITOBJ(wxHOURGLASS_CURSOR, wxCursor); + REINITOBJ(wxCROSS_CURSOR, wxCursor); + + REINITOBJ2(wxNullBitmap, wxBitmap); + REINITOBJ2(wxNullIcon, wxIcon); + REINITOBJ2(wxNullCursor, wxCursor); + REINITOBJ2(wxNullPen, wxPen); + REINITOBJ2(wxNullBrush, wxBrush); + REINITOBJ2(wxNullPalette, wxPalette); + REINITOBJ2(wxNullFont, wxFont); + REINITOBJ2(wxNullColour, wxColour); + + REINITOBJ(wxTheFontList, wxFontList); + REINITOBJ(wxThePenList, wxPenList); + REINITOBJ(wxTheBrushList, wxBrushList); + REINITOBJ(wxTheColourDatabase, wxColourDatabase); + + + REINITOBJ(wxTheClipboard, wxClipboard); + REINITOBJ(wxTheMimeTypesManager, wxMimeTypesManager); + REINITOBJ2(wxDefaultValidator, wxValidator); + REINITOBJ2(wxNullImage, wxImage); + REINITOBJ2(wxNullAcceleratorTable, wxAcceleratorTable); + +#undef REINITOBJ +#undef REINITOBJ2 +} + //--------------------------------------------------------------------------- void wxPyClientData_dtor(wxPyClientData* self) { @@ -1228,29 +1306,50 @@ void wxPyCallback::EventThunker(wxEvent& event) { PyObject* result; PyObject* arg; PyObject* tuple; - + bool checkSkip = FALSE; wxPyBeginBlockThreads(); wxString className = event.GetClassInfo()->GetClassName(); - if (className == wxT("wxPyEvent")) - arg = ((wxPyEvent*)&event)->GetSelf(); - else if (className == wxT("wxPyCommandEvent")) - arg = ((wxPyCommandEvent*)&event)->GetSelf(); + // If the event is one of these types then pass the original + // event object instead of the one passed to us. + if ( className == wxT("wxPyEvent") ) { + arg = ((wxPyEvent*)&event)->GetSelf(); + checkSkip = ((wxPyEvent*)&event)->GetCloned(); + } + else if ( className == wxT("wxPyCommandEvent") ) { + arg = ((wxPyCommandEvent*)&event)->GetSelf(); + checkSkip = ((wxPyCommandEvent*)&event)->GetCloned(); + } else { arg = wxPyConstructObject((void*)&event, className); } + // Call the event handler, passing the event object tuple = PyTuple_New(1); - PyTuple_SET_ITEM(tuple, 0, arg); + PyTuple_SET_ITEM(tuple, 0, arg); // steals ref to arg result = PyEval_CallObject(func, tuple); - Py_DECREF(tuple); - if (result) { - Py_DECREF(result); + if ( result ) { + Py_DECREF(result); // result is ignored, but we still need to decref it PyErr_Clear(); // Just in case... } else { PyErr_Print(); } + + if ( checkSkip ) { + // if the event object was one of our special types and + // it had been cloned, then we need to extract the Skipped + // value from the original and set it in the clone. + result = PyObject_CallMethod(arg, "GetSkipped", ""); + if ( result ) { + event.Skip(PyInt_AsLong(result)); + Py_DECREF(result); + } else { + PyErr_Print(); + } + } + + Py_DECREF(tuple); wxPyEndBlockThreads(); } @@ -1486,8 +1585,8 @@ IMPLEMENT_ABSTRACT_CLASS(wxPyEvent, wxEvent); IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent, wxCommandEvent); -wxPyEvent::wxPyEvent(int id) - : wxEvent(id) { +wxPyEvent::wxPyEvent(int winid, wxEventType commandType) + : wxEvent(winid, commandType) { }