#include <gdk/gdkprivate.h>
#include <wx/gtk/win_gtk.h>
#define GetXWindow(wxwin) GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
+#include <locale.h>
#endif
#ifdef __WXX11__
static PyObject* wxPython_dict = NULL;
static PyObject* wxPyAssertionError = NULL;
+static PyObject* wxPyNoAppError = NULL;
PyObject* wxPyPtrTypeMap = NULL;
// that should be present in the derived (Python) class.
void wxPyApp::_BootstrapApp()
{
- bool result;
+ static bool haveInitialized = false;
+ bool result, blocked;
PyObject* retval = NULL;
PyObject* pyint = NULL;
-
- // Get any command-line args passed to this program from the sys module
- int argc = 0;
- char** argv = NULL;
- bool blocked = wxPyBeginBlockThreads();
- PyObject* sysargv = PySys_GetObject("argv");
- if (sysargv != NULL) {
- argc = PyList_Size(sysargv);
- argv = new char*[argc+1];
- int x;
- for(x=0; x<argc; x++) {
- PyObject *pyArg = PyList_GetItem(sysargv, x);
- argv[x] = PyString_AsString(pyArg);
+
+ // 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;
+ blocked = wxPyBeginBlockThreads();
+ PyObject* sysargv = PySys_GetObject("argv");
+ if (sysargv != NULL) {
+ argc = PyList_Size(sysargv);
+ argv = new char*[argc+1];
+ int x;
+ for(x=0; x<argc; x++) {
+ PyObject *pyArg = PyList_GetItem(sysargv, x);
+ argv[x] = PyString_AsString(pyArg);
+ }
+ argv[argc] = NULL;
}
- argv[argc] = NULL;
- }
- wxPyEndBlockThreads(blocked);
+ wxPyEndBlockThreads(blocked);
- result = wxEntryStart(argc, argv);
- delete [] argv;
+ // Initialize wxWidgets
+ result = wxEntryStart(argc, argv);
+ delete [] argv;
- blocked = wxPyBeginBlockThreads();
- if (! result) {
- PyErr_SetString(PyExc_SystemError, "wxEntryStart failed!");
- goto error;
- }
+ blocked = wxPyBeginBlockThreads();
+ if (! result) {
+ PyErr_SetString(PyExc_SystemError,
+ "wxEntryStart failed, unable to initialize wxWidgets!"
+#ifdef __WXGTK__
+ " (Is DISPLAY set properly?)"
+#endif
+ );
+ goto error;
+ }
- // The stock objects were all NULL when they were loaded into
- // SWIG generated proxies, so re-init those now...
- wxPy_ReinitStockObjects(3);
+ // 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__
+ 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);
+ wxPyEndBlockThreads(blocked);
+ haveInitialized = true;
+ }
+
// It's now ok to generate exceptions for assertion errors.
wxPythonApp->SetStartupComplete(True);
// Call the Python wxApp's OnInit function
+ blocked = wxPyBeginBlockThreads();
if (wxPyCBH_findCallback(m_myInst, "OnInit")) {
PyObject* method = m_myInst.GetLastFound();
result = True;
}
-
if (! result) {
PyErr_SetString(PyExc_SystemExit, "OnInit returned False, exiting...");
}
//----------------------------------------------------------------------
-// This function is called when the wxc module is imported to do some initial
-// setup. (Before there is a wxApp object.) The rest happens in
+// This function is called when the wx._core_ module is imported to do some
+// initial setup. (Before there is a wxApp object.) The rest happens in
// wxPyApp::_BootstrapApp
void __wxPyPreStart(PyObject* moduleDict)
{
#ifdef __WXMSW__
-// wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
+// wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF
+// | _CRTDBG_CHECK_ALWAYS_DF
+// | _CRTDBG_DELAY_FREE_MEM_DF
+// );
#endif
#ifdef WXP_WITH_THREAD
// Init the stock objects to a non-NULL value so SWIG doesn't create them as None
wxPy_ReinitStockObjects(1);
+
+ wxInitAllImageHandlers();
}
}
-// Save a reference to the dictionary of the wx.core module, and inject
+// Save a reference to the dictionary of the wx._core module, and inject
// a few more things into it.
PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args)
{
return NULL;
if (!PyDict_Check(wxPython_dict)) {
- PyErr_SetString(PyExc_TypeError, "_wxPySetDictionary must have dictionary object!");
+ PyErr_SetString(PyExc_TypeError,
+ "_wxPySetDictionary must have dictionary object!");
return NULL;
}
PyDict_SetItemString(wxPython_dict, "__wxPyPtrTypeMap", wxPyPtrTypeMap);
// Create an exception object to use for wxASSERTions
- wxPyAssertionError = PyErr_NewException("wx.core.PyAssertionError",
+ wxPyAssertionError = PyErr_NewException("wx._core.PyAssertionError",
PyExc_AssertionError, NULL);
PyDict_SetItemString(wxPython_dict, "PyAssertionError", wxPyAssertionError);
+ // Create an exception object to use when the app object hasn't been created yet
+ wxPyNoAppError = PyErr_NewException("wx._core.PyNoAppError",
+ PyExc_RuntimeError, NULL);
+ PyDict_SetItemString(wxPython_dict, "PyNoAppError", wxPyNoAppError);
+
+
#ifdef __WXMOTIF__
#define wxPlatform "__WXMOTIF__"
_AddInfoString("gtk1");
#endif
#endif
-
+#ifdef __WXDEBUG__
+ _AddInfoString("wx-assertions-on");
+#else
+ _AddInfoString("wx-assertions-off");
+#endif
+
#undef _AddInfoString
PyObject* PlatInfoTuple = PyList_AsTuple(PlatInfo);
//---------------------------------------------------------------------------
-// The stock objects are no longer created when the wxc module is imported,
-// but only after the app object has been created. The
+// The stock objects are no longer created when the wx._core_ module is
+// imported, but only after the app object has been created. The
// wxPy_ReinitStockObjects function will be called 3 times to pass the stock
// objects though various stages of evolution:
//
// pass 1: Set all the pointers to a non-NULL value so the Python proxy
-// object will be created (otherwise it will just use None.)
+// object will be created (otherwise SWIG will just use None.)
//
// pass 2: After the module has been imported and the python proxys have
// been created, then set the __class__ to be _wxPyUnbornObject so
// it will catch any access to the object and will raise an exception.
//
-// pass 3: Finally, from OnInit patch things up so the stock objects can
-// be used.
+// pass 3: Finally, from BootstrapApp patch things up so the stock objects
+// can be used.
PyObject* __wxPyFixStockObjects(PyObject* /* self */, PyObject* args)
void wxPy_ReinitStockObjects(int pass)
{
+ // If there is already an App object then wxPython is probably embedded in
+ // a wx C++ application, so there is no need to do all this.
+ static bool embedded = false;
+ if ((pass == 1 || pass == 2) && wxTheApp) {
+ embedded = true;
+ return;
+ }
+ if (pass == 3 && embedded)
+ return;
+
+
#define REINITOBJ(name, classname) \
if (pass == 1) { name = (classname*)0xC0C0C0C0; } \
else if (pass == 2) { rsoPass2(#name); } \
if (pass == 1) { } \
else if (pass == 2) { rsoPass2(#name); } \
else if (pass == 3) { rsoPass3(#name, #classname, (void*)&name); }
-
- // If there is already an App object then wxPython is probably embedded in
- // a wx C++ application, so there is no need to do all this.
- static bool embedded = false;
- if ((pass == 1 || pass == 2) && wxTheApp) {
- embedded = true;
- return;
- }
- if (pass == 3 && embedded)
- return;
-
+
REINITOBJ(wxNORMAL_FONT, wxFont);
REINITOBJ(wxSMALL_FONT, wxFont);
REINITOBJ(wxTheColourDatabase, wxColourDatabase);
- REINITOBJ(wxTheClipboard, wxClipboard);
REINITOBJ2(wxDefaultValidator, wxValidator);
REINITOBJ2(wxNullImage, wxImage);
REINITOBJ2(wxNullAcceleratorTable, wxAcceleratorTable);
//---------------------------------------------------------------------------
+// Check for existence of a wxApp, setting an exception if there isn't one.
+// This doesn't need to aquire the GIL because it should only be called from
+// an %exception before the lock is released.
+
+bool wxPyCheckForApp() {
+ if (wxTheApp != NULL)
+ return true;
+ else {
+ PyErr_SetString(wxPyNoAppError, "The wx.App object must be created first!");
+ return false;
+ }
+}
+
+//---------------------------------------------------------------------------
+
+
void wxPyClientData_dtor(wxPyClientData* self) {
if (! wxPyDoingCleanup) { // Don't do it during cleanup as Python
// may have already garbage collected the object...
-PyObject* wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) {
+PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn, bool checkEvtHandler) {
PyObject* target = NULL;
bool isEvtHandler = False;
exists = wxPyCheckSwigType(name);
}
if (info) {
- target = wxPyConstructObject((void*)source, name, False);
+ target = wxPyConstructObject((void*)source, name, setThisOwn);
if (target && isEvtHandler)
((wxEvtHandler*)source)->SetClientObject(new wxPyOORClientData(target));
} else {
}
-PyObject* wxPyMake_wxSizer(wxSizer* source) {
+PyObject* wxPyMake_wxSizer(wxSizer* source, bool setThisOwn) {
PyObject* target = NULL;
if (source && wxIsKindOf(source, wxSizer)) {
}
}
if (! target) {
- target = wxPyMake_wxObject(source, False);
+ target = wxPyMake_wxObject(source, setThisOwn, False);
if (target != Py_None)
((wxSizer*)source)->SetClientObject(new wxPyOORClientData(target));
}
wxPyCBInputStream::~wxPyCBInputStream() {
- bool blocked;
+ bool blocked=false;
if (m_block) blocked = wxPyBeginBlockThreads();
Py_XDECREF(m_read);
Py_XDECREF(m_seek);
wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) {
- bool blocked;
+ bool blocked=false;
if (block) blocked = wxPyBeginBlockThreads();
PyObject* read = getMethod(py, "read");
pyList = PyList_New(0);
while (node) {
wxObj = node->GetData();
- pyObj = wxPyMake_wxObject(wxObj);
+ pyObj = wxPyMake_wxObject(wxObj,false);
PyList_Append(pyList, pyObj);
node = node->GetNext();
}
size_t len = PyUnicode_GET_SIZE(uni);
if (len) {
PyUnicode_AsWideChar((PyUnicodeObject*)uni, target->GetWriteBuf(len), len);
- target->UngetWriteBuf();
+ target->UngetWriteBuf(len);
}
if (PyString_Check(source))