]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/helpers.cpp
added a test to check how exception handling works with Win32 SEH; corrected copyright
[wxWidgets.git] / wxPython / src / helpers.cpp
index b8abb1edec832956fd70fc9d9e4e2f676409180d..d3f1aebbb8df7ea308972242060acdc7076839f9 100644 (file)
@@ -49,7 +49,7 @@
 
 //----------------------------------------------------------------------
 
 
 //----------------------------------------------------------------------
 
-#if PYTHON_API_VERSION <= 1007 && wxUSE_UNICODE
+#if PYTHON_API_VERSION < 1009 && wxUSE_UNICODE
 #error Python must support Unicode to use wxWindows Unicode
 #endif
 
 #error Python must support Unicode to use wxWindows Unicode
 #endif
 
@@ -78,6 +78,8 @@ wxPyThreadStateArray* wxPyTStates = NULL;
 wxMutex*              wxPyTMutex = NULL;
 #endif
 
 wxMutex*              wxPyTMutex = NULL;
 #endif
 
+#define DEFAULTENCODING_SIZE 64
+static char wxPyDefaultEncoding[DEFAULTENCODING_SIZE] = "ascii";
 
 static PyObject* wxPython_dict = NULL;
 static PyObject* wxPyAssertionError = NULL;
 
 static PyObject* wxPython_dict = NULL;
 static PyObject* wxPyAssertionError = NULL;
@@ -421,10 +423,10 @@ void wxPyApp::_BootstrapApp()
             goto error;
         }
 
             goto error;
         }
 
-        // 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__
+        // On wxGTK the locale will be changed to match the system settings,
+        // but Python before 2.4 needs to have LC_NUMERIC set to "C" in order
+        // for the floating point conversions and such to work right.
+#if defined(__WXGTK__) && PY_VERSION_HEX < 0x02040000
         setlocale(LC_NUMERIC, "C");
 #endif
     
         setlocale(LC_NUMERIC, "C");
 #endif
     
@@ -635,7 +637,7 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args)
     PyDict_SetItemString(wxPython_dict, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE));
     PyDict_SetItemString(wxPython_dict, "__WXDEBUG__", PyInt_FromLong(wxdebug));
 
     PyDict_SetItemString(wxPython_dict, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE));
     PyDict_SetItemString(wxPython_dict, "__WXDEBUG__", PyInt_FromLong(wxdebug));
 
-    
+    // Make a tuple of strings that gives more info about the platform.
     PyObject* PlatInfo = PyList_New(0);
     PyObject* obj;
 
     PyObject* PlatInfo = PyList_New(0);
     PyObject* obj;
 
@@ -649,7 +651,7 @@ PyObject* __wxPySetDictionary(PyObject* /* self */, PyObject* args)
 #if wxUSE_UNICODE
     _AddInfoString("unicode");
 #else
 #if wxUSE_UNICODE
     _AddInfoString("unicode");
 #else
-    _AddInfoString("ascii");
+    _AddInfoString("ansi");
 #endif
 #ifdef __WXGTK__
 #ifdef __WXGTK20__
 #endif
 #ifdef __WXGTK__
 #ifdef __WXGTK20__
@@ -864,10 +866,8 @@ bool wxPyCheckForApp() {
 
 //---------------------------------------------------------------------------
 
 
 //---------------------------------------------------------------------------
 
-
-void wxPyClientData_dtor(wxPyClientData* self) {
-    if (! wxPyDoingCleanup) {           // Don't do it during cleanup as Python
-                                        // may have already garbage collected the object...
+void wxPyUserData_dtor(wxPyUserData* self) {
+    if (! wxPyDoingCleanup) {
         bool blocked = wxPyBeginBlockThreads();
         Py_DECREF(self->m_obj);
         self->m_obj = NULL;
         bool blocked = wxPyBeginBlockThreads();
         Py_DECREF(self->m_obj);
         self->m_obj = NULL;
@@ -875,16 +875,21 @@ void wxPyClientData_dtor(wxPyClientData* self) {
     }
 }
 
     }
 }
 
-void wxPyUserData_dtor(wxPyUserData* self) {
-    if (! wxPyDoingCleanup) {
-        bool blocked = wxPyBeginBlockThreads();
-        Py_DECREF(self->m_obj);
+
+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();
+            Py_DECREF(self->m_obj);
+            wxPyEndBlockThreads(blocked);
+        }
         self->m_obj = NULL;
         self->m_obj = NULL;
-        wxPyEndBlockThreads(blocked);
     }
 }
 
 
     }
 }
 
 
+
 // This is called when an OOR controled object is being destroyed.  Although
 // the C++ object is going away there is no way to force the Python object
 // (and all references to it) to die too.  This causes problems (crashes) in
 // This is called when an OOR controled object is being destroyed.  Although
 // the C++ object is going away there is no way to force the Python object
 // (and all references to it) to die too.  This causes problems (crashes) in
@@ -907,8 +912,9 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) {
     }
 
 
     }
 
 
-    // Only if there is more than one reference to the object
-    if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 ) {
+    // Only if there is more than one reference to the object and we are
+    // holding the OOR reference:
+    if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 && self->m_incRef) {
         // bool isInstance = wxPyInstance_Check(self->m_obj);
         // TODO same here
         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!"));
         // bool isInstance = wxPyInstance_Check(self->m_obj);
         // TODO same here
         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!"));
@@ -1088,11 +1094,12 @@ void wxPySaveThreadState(PyThreadState* tstate) {
             if (info.tstate != tstate)
                 wxLogMessage("*** tstate mismatch!???");
 #endif
             if (info.tstate != tstate)
                 wxLogMessage("*** tstate mismatch!???");
 #endif
-            // info.tstate = tstate;    *** DO NOT update existing ones???
+            info.tstate = tstate;    // allow for transient tstates
             // Normally it will never change, but apparently COM callbacks
             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient
             // tstate which will then be garbage the next time we try to use
             // it...
             // Normally it will never change, but apparently COM callbacks
             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient
             // tstate which will then be garbage the next time we try to use
             // it...
+            
             wxPyTMutex->Unlock();
             return;
         }
             wxPyTMutex->Unlock();
             return;
         }
@@ -1183,7 +1190,8 @@ bool wxPyInputStream::eof() {
 }
 
 wxPyInputStream::~wxPyInputStream() {
 }
 
 wxPyInputStream::~wxPyInputStream() {
-    /* do nothing */
+    if (m_wxis)
+        delete m_wxis;
 }
 
 
 }
 
 
@@ -1384,7 +1392,7 @@ PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) {
 }
 
 
 }
 
 
-size_t wxPyCBInputStream::GetSize() const {
+wxFileOffset wxPyCBInputStream::GetLength() const {
     wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
     if (m_seek && m_tell) {
         wxFileOffset temp = self->OnSysTell();
     wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
     if (m_seek && m_tell) {
         wxFileOffset temp = self->OnSysTell();
@@ -1393,7 +1401,7 @@ size_t wxPyCBInputStream::GetSize() const {
         return ret;
     }
     else
         return ret;
     }
     else
-        return 0;
+        return wxInvalidOffset;
 }
 
 
 }
 
 
@@ -1428,14 +1436,20 @@ size_t wxPyCBInputStream::OnSysWrite(const void *buffer, size_t bufsize) {
     return 0;
 }
 
     return 0;
 }
 
+
 wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) {
     bool blocked = wxPyBeginBlockThreads();
 wxFileOffset wxPyCBInputStream::OnSysSeek(wxFileOffset off, wxSeekMode mode) {
     bool blocked = wxPyBeginBlockThreads();
-#if defined( __WINCE__) || defined(_LARGE_FILES) || defined(__HUGEFILES_SUPPORTED)
-    // wxFileOffset is a 64-bit value...
-    PyObject* arglist = Py_BuildValue("(Li)", off, mode);
-#else
-    PyObject* arglist = Py_BuildValue("(ii)", off, mode);
-#endif
+    PyObject* arglist = PyTuple_New(2);
+
+    if (sizeof(wxFileOffset) > sizeof(long))
+        // wxFileOffset is a 64-bit value...
+        PyTuple_SET_ITEM(arglist, 0, PyLong_FromLongLong(off));
+    else
+        PyTuple_SET_ITEM(arglist, 0, PyInt_FromLong(off));
+
+    PyTuple_SET_ITEM(arglist, 1, PyInt_FromLong(mode));
+
+    
     PyObject* result = PyEval_CallObject(m_seek, arglist);
     Py_DECREF(arglist);
     Py_XDECREF(result);
     PyObject* result = PyEval_CallObject(m_seek, arglist);
     Py_DECREF(arglist);
     Py_XDECREF(result);
@@ -1451,11 +1465,9 @@ wxFileOffset wxPyCBInputStream::OnSysTell() const {
     Py_DECREF(arglist);
     wxFileOffset o = 0;
     if (result != NULL) {
     Py_DECREF(arglist);
     wxFileOffset o = 0;
     if (result != NULL) {
-#if defined( __WINCE__) || defined(_LARGE_FILES) || defined(__HUGEFILES_SUPPORTED)
         if (PyLong_Check(result))
             o = PyLong_AsLongLong(result);
         else
         if (PyLong_Check(result))
             o = PyLong_AsLongLong(result);
         else
-#endif
             o = PyInt_AsLong(result);
         Py_DECREF(result);
     };
             o = PyInt_AsLong(result);
         Py_DECREF(result);
     };
@@ -1897,7 +1909,7 @@ wxString* wxString_in_helper(PyObject* source) {
 #if wxUSE_UNICODE
     PyObject* uni = source;
     if (PyString_Check(source)) {
 #if wxUSE_UNICODE
     PyObject* uni = source;
     if (PyString_Check(source)) {
-        uni = PyUnicode_FromObject(source);
+        uni = PyUnicode_FromEncodedObject(source, wxPyDefaultEncoding, "strict");
         if (PyErr_Occurred()) return NULL;
     }
     target = new wxString();
         if (PyErr_Occurred()) return NULL;
     }
     target = new wxString();
@@ -1910,12 +1922,22 @@ wxString* wxString_in_helper(PyObject* source) {
     if (PyString_Check(source))
         Py_DECREF(uni);
 #else
     if (PyString_Check(source))
         Py_DECREF(uni);
 #else
-    char* tmpPtr; int tmpSize;
-    if (PyString_AsStringAndSize(source, &tmpPtr, &tmpSize) == -1) {
-        PyErr_SetString(PyExc_TypeError, "Unable to convert string");
-        return NULL;
+    // Convert to a string object if it isn't already, then to wxString
+    PyObject* str = source;
+    if (PyUnicode_Check(source)) {
+        str = PyUnicode_AsEncodedString(source, wxPyDefaultEncoding, "strict");
+        if (PyErr_Occurred()) return NULL;
+    }    
+    else if (!PyString_Check(source)) {
+        str = PyObject_Str(source);
+        if (PyErr_Occurred()) return NULL;
     }
     }
+    char* tmpPtr; int tmpSize;
+    PyString_AsStringAndSize(str, &tmpPtr, &tmpSize);
     target = new wxString(tmpPtr, tmpSize);
     target = new wxString(tmpPtr, tmpSize);
+    
+    if (!PyString_Check(source))
+        Py_DECREF(str);
 #endif // wxUSE_UNICODE
     
     return target;
 #endif // wxUSE_UNICODE
     
     return target;
@@ -1931,7 +1953,7 @@ wxString Py2wxString(PyObject* source)
     // Convert to a unicode object, if not already, then to a wxString
     PyObject* uni = source;
     if (!PyUnicode_Check(source)) {
     // Convert to a unicode object, if not already, then to a wxString
     PyObject* uni = source;
     if (!PyUnicode_Check(source)) {
-        uni = PyUnicode_FromObject(source);
+        uni = PyUnicode_FromEncodedObject(source, wxPyDefaultEncoding, "strict");
         if (PyErr_Occurred()) return wxEmptyString;  // TODO:  should we PyErr_Clear?
     }    
     size_t len = PyUnicode_GET_SIZE(uni);
         if (PyErr_Occurred()) return wxEmptyString;  // TODO:  should we PyErr_Clear?
     }    
     size_t len = PyUnicode_GET_SIZE(uni);
@@ -1945,7 +1967,11 @@ wxString Py2wxString(PyObject* source)
 #else
     // Convert to a string object if it isn't already, then to wxString
     PyObject* str = source;
 #else
     // Convert to a string object if it isn't already, then to wxString
     PyObject* str = source;
-    if (!PyString_Check(source)) {
+    if (PyUnicode_Check(source)) {
+        str = PyUnicode_AsEncodedString(source, wxPyDefaultEncoding, "strict");
+        if (PyErr_Occurred()) return wxEmptyString;    // TODO:  should we PyErr_Clear?
+    }    
+    else if (!PyString_Check(source)) {
         str = PyObject_Str(source);
         if (PyErr_Occurred()) return wxEmptyString;    // TODO:  should we PyErr_Clear?
     }
         str = PyObject_Str(source);
         if (PyErr_Occurred()) return wxEmptyString;    // TODO:  should we PyErr_Clear?
     }
@@ -1974,6 +2000,17 @@ PyObject* wx2PyString(const wxString& src)
 }
 
 
 }
 
 
+
+void wxSetDefaultPyEncoding(const char* encoding)
+{
+    strncpy(wxPyDefaultEncoding, encoding, DEFAULTENCODING_SIZE);
+}
+
+const char* wxGetDefaultPyEncoding()
+{
+    return wxPyDefaultEncoding;
+}
+
 //----------------------------------------------------------------------
 
 
 //----------------------------------------------------------------------