]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/helpers.cpp
Allow comparrisons with None
[wxWidgets.git] / wxPython / src / helpers.cpp
index 74e229aa8112d4c94eb50e488ab0e8b84d405fef..99fdb3ce2781796172ffa84b5326ab47aa25365e 100644 (file)
@@ -4,7 +4,7 @@
 //
 // Author:      Robin Dunn
 //
-// Created:     7/1/97
+// Created:     1-July-1997
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 by Total Control Software
 // Licence:     wxWindows license
@@ -13,8 +13,8 @@
 
 #undef DEBUG
 #include <Python.h>
-#include "helpers.h"
-#include "pyistream.h"
+#include "wx/wxPython/wxPython_int.h"
+#include "wx/wxPython/pyistream.h"
 
 #ifdef __WXMSW__
 #include <wx/msw/private.h>
 #include <wx/gtk/win_gtk.h>
 #endif
 
+#ifdef __WXMAC__
+#include <wx/mac/private.h>
+#endif
+
 #include <wx/clipbrd.h>
 #include <wx/mimetype.h>
 #include <wx/image.h>
 //----------------------------------------------------------------------
 
 wxPyApp* wxPythonApp = NULL;  // Global instance of application object
-bool wxPyDoCleanup = FALSE;
-bool wxPyDoingCleanup = FALSE;
+bool wxPyDoCleanup = False;
+bool wxPyDoingCleanup = False;
 
 
 #ifdef WXP_WITH_THREAD
 struct wxPyThreadState {
     unsigned long  tid;
     PyThreadState* tstate;
+    int            blocked;
 
     wxPyThreadState(unsigned long _tid=0, PyThreadState* _tstate=NULL)
-        : tid(_tid), tstate(_tstate) {}
+        : tid(_tid), tstate(_tstate), blocked(1) {}
 };
 
 #include <wx/dynarray.h>
@@ -65,9 +70,10 @@ wxMutex*              wxPyTMutex = NULL;
 
 
 static PyObject* wxPython_dict = NULL;
-static PyObject* wxPyPtrTypeMap = NULL;
 static PyObject* wxPyAssertionError = NULL;
 
+PyObject* wxPyPtrTypeMap = NULL;
+
 
 #ifdef __WXMSW__             // If building for win32...
 //----------------------------------------------------------------------
@@ -84,7 +90,7 @@ BOOL WINAPI DllMain(
     // the inatance has already been set.
     if (! wxGetInstance())
         wxSetInstance(hinstDLL);
-    return TRUE;
+    return True;
 }
 #endif
 
@@ -97,6 +103,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxPyApp, wxApp);
 
 wxPyApp::wxPyApp() {
     m_assertMode = wxPYAPP_ASSERT_EXCEPTION;
+    m_startupComplete = False;
 }
 
 
@@ -104,9 +111,9 @@ wxPyApp::~wxPyApp() {
 }
 
 
-// This one isn't acutally called...  We fake it with __wxStart()
+// This one isn't acutally called...  We fake it with _BootstrapApp
 bool wxPyApp::OnInit() {
-    return FALSE;
+    return False;
 }
 
 
@@ -115,10 +122,6 @@ int  wxPyApp::MainLoop() {
 
     DeletePendingObjects();
     bool initialized = wxTopLevelWindows.GetCount() != 0;
-#ifdef __WXGTK__
-    m_initialized = initialized;
-#endif
-
     if (initialized) {
         if ( m_exitOnFrameDelete == Later ) {
             m_exitOnFrameDelete = Yes;
@@ -132,12 +135,12 @@ int  wxPyApp::MainLoop() {
 
 
 bool wxPyApp::OnInitGui() {
-    bool rval=TRUE;
+    bool rval=True;
     wxApp::OnInitGui();  // in this case always call the base class version
-    // wxPyBeginBlockThreads();  *** only called from within __wxStart so we already have the GIL
+    wxPyBeginBlockThreads();  
     if (wxPyCBH_findCallback(m_myInst, "OnInitGui"))
         rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()"));
-    // wxPyEndBlockThreads();    ***
+    wxPyEndBlockThreads();
     return rval;
 }
 
@@ -159,6 +162,20 @@ void wxPyApp::OnAssert(const wxChar *file,
                      const wxChar *cond,
                      const wxChar *msg) {
 
+    // if we're not fully initialized then just log the error
+    if (! m_startupComplete) {
+        wxString buf;
+        buf.Alloc(4096);
+        buf.Printf(wxT("%s(%d): assert \"%s\" failed"),
+                   file, line, cond);
+        if (msg != NULL) {
+            buf += wxT(": ");
+            buf += msg;
+        }
+        wxLogDebug(buf);
+        return;
+    }        
+        
     // If the OnAssert is overloaded in the Python class then call it...
     bool found;
     wxPyBeginBlockThreads();
@@ -228,14 +245,6 @@ void wxPyApp::OnAssert(const wxChar *file,
 #endif
 
 
-/*static*/
-bool wxPyApp::GetMacDefaultEncodingIsPC() {
-#ifdef __WXMAC__
-    return s_macDefaultEncodingIsPC;
-#else
-    return 0;
-#endif
-}
 
 /*static*/
 bool wxPyApp::GetMacSupportPCMenuShortcuts() {
@@ -282,13 +291,6 @@ wxString wxPyApp::GetMacHelpMenuTitleName() {
 #endif
 }
 
-/*static*/
-void wxPyApp::SetMacDefaultEncodingIsPC(bool val) {
-#ifdef __WXMAC__
-    s_macDefaultEncodingIsPC = val;
-#endif
-}
-
 /*static*/
 void wxPyApp::SetMacSupportPCMenuShortcuts(bool val) {
 #ifdef __WXMAC__
@@ -325,6 +327,82 @@ void wxPyApp::SetMacHelpMenuTitleName(const wxString& val) {
 }
 
 
+// This finishes the initialization of wxWindows and then calls the OnInit
+// that should be present in the derived (Python) class.
+void wxPyApp::_BootstrapApp()
+{
+    bool        result;
+    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;
+    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;
+    }
+    wxPyEndBlockThreads();
+
+    result = wxEntryStart(argc, argv);
+    delete [] argv;
+    
+    wxPyBeginBlockThreads();
+    if (! result)  {
+        PyErr_SetString(PyExc_SystemError, "wxEntryStart failed!");
+        goto error;
+    }
+
+    // The stock objects were all NULL when they were loaded into
+    // SWIG generated proxies, so re-init those now...
+    wxPy_ReinitStockObjects(3);
+
+    // It's now ok to generate exceptions for assertion errors.
+    wxPythonApp->SetStartupComplete(True);
+    
+    // Call the Python wxApp's OnInit function
+    if (wxPyCBH_findCallback(m_myInst, "OnInit")) {                
+
+        PyObject* method = m_myInst.GetLastFound();
+        PyObject* argTuple = PyTuple_New(0);
+        retval = PyEval_CallObject(method, argTuple);
+        Py_DECREF(argTuple);
+        Py_DECREF(method);
+        if (retval == NULL)
+            goto error;
+        
+        pyint = PyNumber_Int(retval);        
+        if (! pyint) {
+            PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
+            goto error;
+        }
+        result = PyInt_AS_LONG(pyint);
+    }
+    else {
+        // Is it okay if there is no OnInit?  Probably so...
+        result = True;
+    }
+                                                                                    
+    
+    if (! result) {
+        PyErr_SetString(PyExc_SystemExit, "OnInit returned False, exiting...");
+    }
+
+ error:
+    Py_XDECREF(retval);
+    Py_XDECREF(pyint);
+    
+    wxPyEndBlockThreads();
+};
 
 //---------------------------------------------------------------------
 //----------------------------------------------------------------------
@@ -366,11 +444,19 @@ static wxChar* wxPyCopyWString(const wxChar *src)
 #endif
 
 
+inline const char* dropwx(const char* name) {
+    if (name[0] == 'w' && name[1] == 'x')
+        return name+2;
+    else
+        return name;
+}
+
 //----------------------------------------------------------------------
 
 // 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)
+// setup.  (Before there is a wxApp object.)  The rest happens in
+// wxPyApp::_BootstrapApp
+void __wxPyPreStart(PyObject* moduleDict)
 {
 
 #ifdef __WXMSW__
@@ -381,101 +467,27 @@ void __wxPreStart(PyObject* moduleDict)
     PyEval_InitThreads();
     wxPyTStates = new wxPyThreadStateArray;
     wxPyTMutex = new wxMutex;
-#endif
-
-    // Ensure that the build options in the DLL (or whatever) match this build
-    wxApp::CheckBuildOptions(wxBuildOptions());
-
-    // Create an exception object to use for wxASSERTions
-    wxPyAssertionError = PyErr_NewException("wxPython.wxc.wxPyAssertionError",
-                                            PyExc_AssertionError, NULL);
-    PyDict_SetItemString(moduleDict, "wxPyAssertionError", wxPyAssertionError);
-}
-
-
 
-// Initialize wxWindows and bootstrap the user application by calling the
-// wxApp's OnInit, which is a parameter to this funciton.  See wxApp.__init__
-// in _extras.py to learn how the bootstrap is started.
-PyObject* __wxStart(PyObject* /* self */, PyObject* args)
-{
-    PyObject*   onInitFunc = NULL;
-    PyObject*   arglist= NULL;
-    PyObject*   result = NULL;
-    PyObject*   pyint = NULL;
-    long        bResult;
-
-    if (!PyArg_ParseTuple(args, "O", &onInitFunc))
-        return NULL;
-
-    // Get any command-line args passed to this program from the sys module
-    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; x<argc; x++) {
-            PyObject *pyArg = PyList_GetItem(sysargv, x);
-            argv[x] = PyString_AsString(pyArg);
-        }
-        argv[argc] = NULL;
-    }
-
-    if (! wxEntryStart(argc, argv) ) {
-        PyErr_SetString(PyExc_SystemError,      // is this the right one?
-                        "wxEntryStart failed!");
-        goto error;
-    }
-    delete [] argv;
-
-
-    // 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);
-    if (!result) {      // an exception was raised.
-        return NULL;
-    }
-
-    pyint = PyNumber_Int(result);
-    if (! pyint) {
-        PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
-        goto error;
-    }
-    bResult = PyInt_AS_LONG(pyint);
-    if (! bResult) {
-        PyErr_SetString(PyExc_SystemExit, "OnInit returned FALSE, exiting...");
-        goto error;
-    }
-
-#ifdef __WXGTK__
-    wxTheApp->m_initialized = (wxTopLevelWindows.GetCount() > 0);
+    // Save the current (main) thread state in our array
+    PyThreadState* tstate = wxPyBeginAllowThreads();
+    wxPyEndAllowThreads(tstate);
 #endif
 
-    Py_DECREF(result);
-    Py_DECREF(pyint);
-    Py_INCREF(Py_None);
-    return Py_None;
+    // Ensure that the build options in the DLL (or whatever) match this build
+    wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "wxPython");
 
- error:
-    Py_XDECREF(result);
-    Py_XDECREF(pyint);
-    return NULL;
+    // Init the stock objects to a non-NULL value so SWIG doesn't create them as None
+    wxPy_ReinitStockObjects(1);
 }
 
 
 
-void __wxCleanup() {
-    wxPyDoingCleanup = TRUE;
-    if (wxPyDoCleanup)
+void __wxPyCleanup() {
+    wxPyDoingCleanup = True;
+    if (wxPyDoCleanup) {
+        wxPyDoCleanup = False;
         wxEntryCleanup();
+    }
 #ifdef WXP_WITH_THREAD
     delete wxPyTMutex;
     wxPyTMutex = NULL;
@@ -486,16 +498,16 @@ void __wxCleanup() {
 }
 
 
-
-
-PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
+// 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)
 {
 
     if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
         return NULL;
 
     if (!PyDict_Check(wxPython_dict)) {
-        PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
+        PyErr_SetString(PyExc_TypeError, "_wxPySetDictionary must have dictionary object!");
         return NULL;
     }
 
@@ -503,6 +515,11 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
         wxPyPtrTypeMap = PyDict_New();
     PyDict_SetItemString(wxPython_dict, "__wxPyPtrTypeMap", wxPyPtrTypeMap);
 
+    // Create an exception object to use for wxASSERTions
+    wxPyAssertionError = PyErr_NewException("wx.core.PyAssertionError",
+                                            PyExc_AssertionError, NULL);
+    PyDict_SetItemString(wxPython_dict, "PyAssertionError", wxPyAssertionError);
+
 
 #ifdef __WXMOTIF__
 #define wxPlatform "__WXMOTIF__"
@@ -526,44 +543,112 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
     int wxdebug = 0;
 #endif
 
-    PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
-    PyDict_SetItemString(wxPython_dict, "wxUSE_UNICODE", PyInt_FromLong(wxUSE_UNICODE));
+    PyDict_SetItemString(wxPython_dict, "Platform", PyString_FromString(wxPlatform));
+    PyDict_SetItemString(wxPython_dict, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE));
     PyDict_SetItemString(wxPython_dict, "__WXDEBUG__", PyInt_FromLong(wxdebug));
 
-    Py_INCREF(Py_None);
-    return Py_None;
+    RETURN_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.
+// 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;
+}
+
+//---------------------------------------------------------------------------
+
+// The stock objects are no longer created when the wxc 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.)
+//
+//   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.
+
+
+PyObject* __wxPyFixStockObjects(PyObject* /* self */, PyObject* args)
+{
+    wxPy_ReinitStockObjects(2);    
+    RETURN_NONE();
+}
+
+
+static void rsoPass2(const char* name)
+{
+    static PyObject* unbornObjectClass = NULL;
+    PyObject* obj;
+    
+    if (unbornObjectClass == NULL) {
+        unbornObjectClass = PyDict_GetItemString(wxPython_dict, "_wxPyUnbornObject");
+        Py_INCREF(unbornObjectClass);
+    }
+
+    // Find the object instance
+    obj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(name));
+    wxCHECK_RET(obj != NULL, wxT("Unable to find stock object"));
+    wxCHECK_RET(wxPySwigInstance_Check(obj), wxT("Not a swig instance"));
+
+    // Change its class
+    PyObject_SetAttrString(obj, "__class__",  unbornObjectClass);
+   
+}
 
-void wxPy_ReinitStockObjects()
+static void rsoPass3(const char* name, const char* classname, void* ptr)
 {
-    char ptrbuf[128];
     PyObject* obj;
+    PyObject* classobj;
     PyObject* ptrobj;
 
+    // Find the object instance
+    obj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(name));
+    wxCHECK_RET(obj != NULL, wxT("Unable to find stock object")); 
+    wxCHECK_RET(wxPySwigInstance_Check(obj), wxT("Not a swig instance"));
 
+    // Find the class object and put it back in the instance
+    classobj = PyDict_GetItemString(wxPython_dict, (char*)dropwx(classname));
+    wxCHECK_RET(classobj != NULL, wxT("Unable to find stock class object")); 
+    PyObject_SetAttrString(obj, "__class__",  classobj);
 
-#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)
+    // Rebuild the .this swigified pointer with the new value of the C++ pointer
+    ptrobj = wxPyMakeSwigPtr(ptr, wxString(classname, *wxConvCurrent));
+    PyObject_SetAttrString(obj, "this", ptrobj); 
+    Py_DECREF(ptrobj);
+}
+
+
+
+void wxPy_ReinitStockObjects(int pass)
+{
 
-#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)
+#define REINITOBJ(name, classname) \
+    if (pass == 1) { name = (classname*)0xC0C0C0C0; } \
+    else if (pass == 2) { rsoPass2(#name); } \
+    else if (pass == 3) { rsoPass3(#name, #classname, (void*)name); }
+
+
+#define REINITOBJ2(name, classname) \
+    if (pass == 1) { } \
+    else if (pass == 2) { rsoPass2(#name); } \
+    else if (pass == 3) { rsoPass3(#name, #classname, (void*)&name); }
 
 
     REINITOBJ(wxNORMAL_FONT, wxFont);
@@ -621,7 +706,6 @@ void wxPy_ReinitStockObjects()
 
 
     REINITOBJ(wxTheClipboard, wxClipboard);
-    REINITOBJ(wxTheMimeTypesManager, wxMimeTypesManager);
     REINITOBJ2(wxDefaultValidator, wxValidator);
     REINITOBJ2(wxNullImage, wxImage);
     REINITOBJ2(wxNullAcceleratorTable, wxAcceleratorTable);
@@ -637,6 +721,7 @@ void wxPyClientData_dtor(wxPyClientData* self) {
                                         // may have already garbage collected the object...
         wxPyBeginBlockThreads();
         Py_DECREF(self->m_obj);
+        self->m_obj = NULL;
         wxPyEndBlockThreads();
     }
 }
@@ -645,6 +730,7 @@ void wxPyUserData_dtor(wxPyUserData* self) {
     if (! wxPyDoingCleanup) {
         wxPyBeginBlockThreads();
         Py_DECREF(self->m_obj);
+        self->m_obj = NULL;
         wxPyEndBlockThreads();
     }
 }
@@ -657,7 +743,7 @@ void wxPyUserData_dtor(wxPyUserData* self) {
 // the now bogus pointer... So to try and prevent this we'll do a little black
 // magic and change the class of the python instance to a class that will
 // raise an exception for any attempt to call methods with it.  See
-// _wxPyDeadObject in _extras.py for the implementation of this class.
+// _wxPyDeadObject in _core_ex.py for the implementation of this class.
 void wxPyOORClientData_dtor(wxPyOORClientData* self) {
 
     static PyObject* deadObjectClass = NULL;
@@ -665,14 +751,18 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) {
     wxPyBeginBlockThreads();
     if (deadObjectClass == NULL) {
         deadObjectClass = PyDict_GetItemString(wxPython_dict, "_wxPyDeadObject");
-        wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!"));
+        // TODO:  Can not wxASSERT here because inside a wxPyBeginBlock Threads,
+        // will lead to a deadlock when it tries to aquire the GIL again.
+        //wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!"));
         Py_INCREF(deadObjectClass);
     }
 
 
     // Only if there is more than one reference to the object
     if ( !wxPyDoingCleanup && self->m_obj->ob_refcnt > 1 ) {
-        wxASSERT_MSG(PyInstance_Check(self->m_obj), 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!?!?!"));
 
         // Call __del__, if there is one.
         PyObject* func = PyObject_GetAttrString(self->m_obj, "__del__");
@@ -684,18 +774,25 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) {
         if (PyErr_Occurred())
             PyErr_Clear();      // just ignore it for now
 
-        // Clear the instance's dictionary
-        PyInstanceObject* inst = (PyInstanceObject*)self->m_obj;
-        PyDict_Clear(inst->in_dict);
-
-        // put the name of the old class into the instance, and then reset the
-        // class to be the dead class.
-        PyDict_SetItemString(inst->in_dict, "_name", inst->in_class->cl_name);
-        inst->in_class = (PyClassObject*)deadObjectClass;
-        Py_INCREF(deadObjectClass);
+        
+        PyObject* dict = PyObject_GetAttrString(self->m_obj, "__dict__");
+        if (dict) {
+            // Clear the instance's dictionary 
+            PyDict_Clear(dict);
+
+            // put the name of the old class into the instance, and then reset the
+            // class to be the dead class.
+            PyObject* klass = PyObject_GetAttrString(self->m_obj, "__class__");
+            PyObject* name =  PyObject_GetAttrString(klass, "__name__");
+            PyDict_SetItemString(dict, "_name", name);
+            PyObject_SetAttrString(self->m_obj, "__class__",  deadObjectClass);
+            //Py_INCREF(deadObjectClass);
+            Py_DECREF(klass);
+            Py_DECREF(name);
+        }
     }
 
-    // m_obj is DECREF's in the base class dtor...
+    // m_obj is DECREF'd in the base class dtor...
     wxPyEndBlockThreads();
 }
 
@@ -720,63 +817,41 @@ void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) {
 
 
 
-PyObject* wxPyClassExists(const wxString& className) {
-
-    PyObject* item;
-    wxString  name(className);
-    char      buff[64];               // should always be big enough...
-
-    if (!className)
-        return NULL;
-
-    // Try the name as-is first
-    sprintf(buff, "%sPtr", (const char*)name.mbc_str());
-    PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
-
-    // if not found see if there is a mapped name for it
-    if ( ! classobj) {
-        if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)(const char*)name.mbc_str())) != NULL) {
-            name = wxString(PyString_AsString(item), *wxConvCurrent);
-            sprintf(buff, "%sPtr", (const char*)name.mbc_str());
-            classobj = PyDict_GetItemString(wxPython_dict, buff);
-        }
-    }
-
-    return classobj;  // returns NULL if not found
-}
-
 
 PyObject*  wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) {
     PyObject* target = NULL;
-    bool      isEvtHandler = FALSE;
+    bool      isEvtHandler = False;
 
     if (source) {
         // If it's derived from wxEvtHandler then there may
         // already be a pointer to a Python object that we can use
         // in the OOR data.
         if (checkEvtHandler && wxIsKindOf(source, wxEvtHandler)) {
-            isEvtHandler = TRUE;
+            isEvtHandler = True;
             wxEvtHandler* eh = (wxEvtHandler*)source;
             wxPyOORClientData* data = (wxPyOORClientData*)eh->GetClientObject();
             if (data) {
                 target = data->m_obj;
-                Py_INCREF(target);
+                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.
-            wxClassInfo* info  = source->GetClassInfo();
-            wxString     name  = info->GetClassName();
-            PyObject*    klass = wxPyClassExists(name);
-            while (info && !klass) {
-                name = (wxChar*)info->GetBaseClassName1();
-                info = wxClassInfo::FindClass(name);
-                klass = wxPyClassExists(name);
+            // Otherwise make it the old fashioned way by making a new shadow
+            // object and putting this pointer in it.  Look up the class
+            // heirarchy until we find a class name that is located in the
+            // python module.
+            const wxClassInfo* info   = source->GetClassInfo();
+            wxString           name   = info->GetClassName();
+            bool               exists = wxPyCheckSwigType(name);
+            while (info && !exists) {
+                info = info->GetBaseClass1();
+                name = info->GetClassName();
+                exists = wxPyCheckSwigType(name);
             }
             if (info) {
-                target = wxPyConstructObject(source, name, klass, FALSE);
+                target = wxPyConstructObject((void*)source, name, False);
                 if (target && isEvtHandler)
                     ((wxEvtHandler*)source)->SetClientObject(new wxPyOORClientData(target));
             } else {
@@ -797,18 +872,18 @@ PyObject*  wxPyMake_wxSizer(wxSizer* source) {
     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.
+        // 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;
-            Py_INCREF(target);
+            if (target)
+                Py_INCREF(target);
         }
     }
     if (! target) {
-        target = wxPyMake_wxObject(source, FALSE);
+        target = wxPyMake_wxObject(source, False);
         if (target != Py_None)
             ((wxSizer*)source)->SetClientObject(new wxPyOORClientData(target));
     }
@@ -816,66 +891,6 @@ PyObject*  wxPyMake_wxSizer(wxSizer* source) {
 }
 
 
-
-//---------------------------------------------------------------------------
-
-PyObject* wxPyConstructObject(void* ptr,
-                              const wxString& className,
-                              PyObject* klass,
-                              int setThisOwn) {
-
-    PyObject* obj;
-    PyObject* arg;
-    PyObject* item;
-    wxString  name(className);
-    char      swigptr[64];      // should always be big enough...
-    char      buff[64];
-
-    if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)(const char*)name.mbc_str())) != NULL) {
-        name = wxString(PyString_AsString(item), *wxConvCurrent);
-    }
-    sprintf(buff, "_%s_p", (const char*)name.mbc_str());
-    SWIG_MakePtr(swigptr, ptr, buff);
-
-    arg = Py_BuildValue("(s)", swigptr);
-    obj = PyInstance_New(klass, arg, NULL);
-    Py_DECREF(arg);
-
-    if (setThisOwn) {
-        PyObject* one = PyInt_FromLong(1);
-        PyObject_SetAttrString(obj, "thisown", one);
-        Py_DECREF(one);
-    }
-
-    return obj;
-}
-
-
-PyObject* wxPyConstructObject(void* ptr,
-                              const wxString& className,
-                              int setThisOwn) {
-    if (!ptr) {
-        Py_INCREF(Py_None);
-        return Py_None;
-    }
-
-    char    buff[64];               // should always be big enough...
-    sprintf(buff, "%sPtr", (const char*)className.mbc_str());
-
-    wxASSERT_MSG(wxPython_dict, wxT("wxPython_dict is not set yet!!"));
-
-    PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
-    if (! classobj) {
-        wxString msg(wxT("wxPython class not found for "));
-        msg += className;
-        PyErr_SetString(PyExc_NameError, msg.mbc_str());
-        return NULL;
-    }
-
-    return wxPyConstructObject(ptr, className, classobj, setThisOwn);
-}
-
-
 //---------------------------------------------------------------------------
 
 
@@ -885,20 +900,21 @@ unsigned long wxPyGetCurrentThreadId() {
     return wxThread::GetCurrentId();
 }
 
-static PyThreadState* gs_shutdownTState;
+static wxPyThreadState gs_shutdownTState;
+
 static
-PyThreadState* wxPyGetThreadState() {
+wxPyThreadState* wxPyGetThreadState() {
     if (wxPyTMutex == NULL) // Python is shutting down...
-        return gs_shutdownTState;
+        return &gs_shutdownTState;
 
     unsigned long ctid = wxPyGetCurrentThreadId();
-    PyThreadState* tstate = NULL;
+    wxPyThreadState* tstate = NULL;
 
     wxPyTMutex->Lock();
     for(size_t i=0; i < wxPyTStates->GetCount(); i++) {
         wxPyThreadState& info = wxPyTStates->Item(i);
         if (info.tid == ctid) {
-            tstate = info.tstate;
+            tstate = &info;
             break;
         }
     }
@@ -907,10 +923,11 @@ PyThreadState* wxPyGetThreadState() {
     return tstate;
 }
 
+
 static
 void wxPySaveThreadState(PyThreadState* tstate) {
     if (wxPyTMutex == NULL) { // Python is shutting down, assume a single thread...
-        gs_shutdownTState = tstate;
+        gs_shutdownTState.tstate = tstate;
         return;
     }
     unsigned long ctid = wxPyGetCurrentThreadId();
@@ -939,6 +956,7 @@ void wxPySaveThreadState(PyThreadState* tstate) {
 #endif
 
 
+
 // Calls from Python to wxWindows code are wrapped in calls to these
 // functions:
 
@@ -946,6 +964,7 @@ PyThreadState* wxPyBeginAllowThreads() {
 #ifdef WXP_WITH_THREAD
     PyThreadState* saved = PyEval_SaveThread();  // Py_BEGIN_ALLOW_THREADS;
     wxPySaveThreadState(saved);
+    wxPyGetThreadState()->blocked -= 1;
     return saved;
 #else
     return NULL;
@@ -954,6 +973,7 @@ PyThreadState* wxPyBeginAllowThreads() {
 
 void wxPyEndAllowThreads(PyThreadState* saved) {
 #ifdef WXP_WITH_THREAD
+    wxPyGetThreadState()->blocked += 1;
     PyEval_RestoreThread(saved);   // Py_END_ALLOW_THREADS;
 #endif
 }
@@ -965,17 +985,21 @@ void wxPyEndAllowThreads(PyThreadState* saved) {
 
 void wxPyBeginBlockThreads() {
 #ifdef WXP_WITH_THREAD
-    PyThreadState* tstate = wxPyGetThreadState();
-    PyEval_RestoreThread(tstate);
+    wxPyThreadState* tstate = wxPyGetThreadState();
+    if (tstate->blocked++ == 0) {  // if nested calls then do nothing
+        PyEval_RestoreThread(tstate->tstate);
+    }
 #endif
 }
 
 
 void wxPyEndBlockThreads() {
 #ifdef WXP_WITH_THREAD
-    // Is there any need to save it again?
-    // PyThreadState* tstate =
-    PyEval_SaveThread();
+    wxPyThreadState* tstate = wxPyGetThreadState();
+    tstate->blocked -= 1;
+    if ( tstate->blocked == 0) {  // if nested calls then do nothing
+        PyEval_SaveThread();
+    }
 #endif
 }
 
@@ -996,7 +1020,7 @@ bool wxPyInputStream::eof() {
     if (m_wxis)
         return m_wxis->Eof();
     else
-        return TRUE;
+        return True;
 }
 
 wxPyInputStream::~wxPyInputStream() {
@@ -1268,9 +1292,8 @@ off_t wxPyCBInputStream::OnSysTell() const {
         if (PyLong_Check(result))
             o = PyLong_AsLongLong(result);
         else
-#else
-        o = PyInt_AsLong(result);
 #endif
+            o = PyInt_AsLong(result);
         Py_DECREF(result);
     };
     wxPyEndBlockThreads();
@@ -1306,7 +1329,7 @@ void wxPyCallback::EventThunker(wxEvent& event) {
     PyObject*       result;
     PyObject*       arg;
     PyObject*       tuple;
-    bool            checkSkip = FALSE;
+    bool            checkSkip = False;
 
     wxPyBeginBlockThreads();
     wxString className = event.GetClassInfo()->GetClassName();
@@ -1325,31 +1348,34 @@ void wxPyCallback::EventThunker(wxEvent& event) {
         arg = wxPyConstructObject((void*)&event, className);
     }
 
-    // Call the event handler, passing the event object
-    tuple = PyTuple_New(1);
-    PyTuple_SET_ITEM(tuple, 0, arg);  // steals ref to arg
-    result = PyEval_CallObject(func, tuple);
-    if ( result ) {
-        Py_DECREF(result);   // result is ignored, but we still need to decref it
-        PyErr_Clear();       // Just in case...
-    } else {
+    if (!arg) {
         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", "");
+    } else {
+        // Call the event handler, passing the event object
+        tuple = PyTuple_New(1);
+        PyTuple_SET_ITEM(tuple, 0, arg);  // steals ref to arg
+        result = PyEval_CallObject(func, tuple);
         if ( result ) {
-            event.Skip(PyInt_AsLong(result));
-            Py_DECREF(result);
+            Py_DECREF(result);   // result is ignored, but we still need to decref it
+            PyErr_Clear();       // Just in case...
         } else {
             PyErr_Print();
         }
-    }
 
-    Py_DECREF(tuple);
+        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();
 }
 
@@ -1396,7 +1422,6 @@ PyObject* PyFindClassWithAttr(PyObject *klass, PyObject *name)
 
     if (PyType_Check(klass)) {      // new style classes
         // This code is borrowed/adapted from _PyType_Lookup in typeobject.c
-        // (TODO: This part is not tested yet, so I'm not sure it is correct...)
         PyTypeObject* type = (PyTypeObject*)klass;
         PyObject *mro, *res, *base, *dict;
         /* Look in tp_dict of types in MRO */
@@ -1471,7 +1496,7 @@ bool wxPyCallbackHelper::findCallback(const char* name) const {
         // not from a base class...
         if (PyMethod_Check(method) &&
             (klass = PyMethod_GetDefiningClass(method, (char*)name)) != NULL &&
-            ((klass == m_class) || PyClass_IsSubclass(klass, m_class))) {
+            ((klass == m_class) || PyObject_IsSubclass(klass, m_class))) {
 
             // ...then we'll save a pointer to the method so callCallback can call it.
             self->m_lastFound = method;
@@ -1486,7 +1511,7 @@ bool wxPyCallbackHelper::findCallback(const char* name) const {
 
 int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
     PyObject*   result;
-    int         retval = FALSE;
+    int         retval = False;
 
     result = callCallbackObj(argTuple);
     if (result) {                       // Assumes an integer return type...
@@ -1498,7 +1523,7 @@ int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
 }
 
 // Invoke the Python callable object, returning the raw PyObject return
-// value.  Caller should DECREF the return value and also call PyEval_SaveThread.
+// value.  Caller should DECREF the return value and also manage the GIL.
 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
     PyObject* result;
 
@@ -1553,7 +1578,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
 wxPyEvtSelfRef::wxPyEvtSelfRef() {
     //m_self = Py_None;         // **** We don't do normal ref counting to prevent
     //Py_INCREF(m_self);        //      circular loops...
-    m_cloned = FALSE;
+    m_cloned = False;
 }
 
 wxPyEvtSelfRef::~wxPyEvtSelfRef() {
@@ -1570,7 +1595,7 @@ void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
     m_self = self;
     if (clone) {
         Py_INCREF(m_self);
-        m_cloned = TRUE;
+        m_cloned = True;
     }
     wxPyEndBlockThreads();
 }
@@ -1593,7 +1618,7 @@ wxPyEvent::wxPyEvent(int winid, wxEventType commandType)
 wxPyEvent::wxPyEvent(const wxPyEvent& evt)
     : wxEvent(evt)
 {
-    SetSelf(evt.m_self, TRUE);
+    SetSelf(evt.m_self, True);
 }
 
 
@@ -1609,7 +1634,7 @@ wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent& evt)
     : wxCommandEvent(evt)
 {
-    SetSelf(evt.m_self, TRUE);
+    SetSelf(evt.m_self, True);
 }
 
 
@@ -1619,51 +1644,12 @@ wxPyCommandEvent::~wxPyCommandEvent() {
 
 
 
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-
-
-wxPyTimer::wxPyTimer(PyObject* callback) {
-    func = callback;
-    Py_INCREF(func);
-}
-
-wxPyTimer::~wxPyTimer() {
-    wxPyBeginBlockThreads();
-    Py_DECREF(func);
-    wxPyEndBlockThreads();
-}
-
-void wxPyTimer::Notify() {
-    if (!func || func == Py_None) {
-        wxTimer::Notify();
-    }
-    else {
-        wxPyBeginBlockThreads();
-
-        PyObject*   result;
-        PyObject*   args = Py_BuildValue("()");
-
-        result = PyEval_CallObject(func, args);
-        Py_DECREF(args);
-        if (result) {
-            Py_DECREF(result);
-            PyErr_Clear();
-        } else {
-            PyErr_Print();
-        }
-
-        wxPyEndBlockThreads();
-    }
-}
-
-
 
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-// Convert a wxList to a Python List
+// Convert a wxList to a Python List, only works for lists of wxObjects
 
-PyObject* wxPy_ConvertList(wxListBase* listbase, const char* className) {
+PyObject* wxPy_ConvertList(wxListBase* listbase) {
     wxList*     list = (wxList*)listbase;  // this is probably bad...
     PyObject*   pyList;
     PyObject*   pyObj;
@@ -1674,7 +1660,7 @@ PyObject* wxPy_ConvertList(wxListBase* listbase, const char* className) {
     pyList = PyList_New(0);
     while (node) {
         wxObj = node->GetData();
-        pyObj = wxPyMake_wxObject(wxObj); //wxPyConstructObject(wxObj, className);
+        pyObj = wxPyMake_wxObject(wxObj); 
         PyList_Append(pyList, pyObj);
         node = node->GetNext();
     }
@@ -1685,10 +1671,11 @@ PyObject* wxPy_ConvertList(wxListBase* listbase, const char* className) {
 //----------------------------------------------------------------------
 
 long wxPyGetWinHandle(wxWindow* win) {
+
 #ifdef __WXMSW__
     return (long)win->GetHandle();
 #endif
-
+    
     // Find and return the actual X-Window.
 #ifdef __WXGTK__
     if (win->m_wxwindow) {
@@ -1702,6 +1689,11 @@ long wxPyGetWinHandle(wxWindow* win) {
 #endif
     }
 #endif
+    
+#ifdef __WXMAC__
+    return (long)MAC_WXHWND(win->MacGetRootWindow());
+#endif
+    
     return 0;
 }
 
@@ -1761,13 +1753,13 @@ wxString* wxString_in_helper(PyObject* source) {
 wxString Py2wxString(PyObject* source)
 {
     wxString target;
-    bool     doDecRef = FALSE;
+    bool     doDecRef = False;
 
 #if PYTHON_API_VERSION >= 1009  // Have Python unicode API
     if (!PyString_Check(source) && !PyUnicode_Check(source)) {
         // Convert to String if not one already...  (TODO: Unicode too?)
         source = PyObject_Str(source);
-        doDecRef = TRUE;
+        doDecRef = True;
     }
 
 #if wxUSE_UNICODE
@@ -1793,7 +1785,7 @@ wxString Py2wxString(PyObject* source)
     if (!PyString_Check(source)) {
         // Convert to String if not one already...
         source = PyObject_Str(source);
-        doDecRef = TRUE;
+        doDecRef = True;
     }
     target = wxString(PyString_AS_STRING(source), PyString_GET_SIZE(source));
 #endif
@@ -1917,24 +1909,24 @@ static inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point
     if (PyInt_Check(o1) && PyInt_Check(o2)) {
         point->x = PyInt_AS_LONG(o1);
         point->y = PyInt_AS_LONG(o2);
-        return true;
+        return True;
     }
     if (PyFloat_Check(o1) && PyFloat_Check(o2)) {
         point->x = (int)PyFloat_AS_DOUBLE(o1);
         point->y = (int)PyFloat_AS_DOUBLE(o2);
-        return true;
+        return True;
     }
-    if (PyInstance_Check(o1) || PyInstance_Check(o2)) {
+    if (wxPySwigInstance_Check(o1) || wxPySwigInstance_Check(o2)) {  // TODO: Why???
         // Disallow instances because they can cause havok
-        return false;
+        return False;
     }
     if (PyNumber_Check(o1) && PyNumber_Check(o2)) {
         // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2
         point->x = PyInt_AsLong(o1);
         point->y = PyInt_AsLong(o2);
-        return true;
+        return True;
     }
-    return false;
+    return False;
 }
 
 
@@ -1982,9 +1974,9 @@ wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) {
                 goto error2;
             }
         }
-        else if (PyInstance_Check(o)) {
+        else if (wxPySwigInstance_Check(o)) {
             wxPoint* pt;
-            if (SWIG_GetPtrObj(o, (void **)&pt, "_wxPoint_p")) {
+            if (! wxPyConvertSwigPtr(o, (void **)&pt, wxT("wxPoint"))) {
                 goto error2;
             }
             temp[x] = *pt;
@@ -2036,10 +2028,10 @@ wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
     }
     for (int x=0; x<count; x++) {
         PyObject* o = PyList_GetItem(source, x);
-        if (PyInstance_Check(o)) {
+        if (wxPySwigInstance_Check(o)) {
             wxBitmap*    pt;
-            if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
-                PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
+            if (! wxPyConvertSwigPtr(o, (void **) &pt, wxT("wxBitmap"))) {
+                PyErr_SetString(PyExc_TypeError,"Expected wxBitmap.");
                 return NULL;
             }
             temp[x] = pt;
@@ -2100,10 +2092,10 @@ wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
     }
     for (int x=0; x<count; x++) {
         PyObject* o = PyList_GetItem(source, x);
-        if (PyInstance_Check(o)) {
+        if (wxPySwigInstance_Check(o)) {
             wxAcceleratorEntry* ae;
-            if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
-                PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
+            if (! wxPyConvertSwigPtr(o, (void **) &ae, wxT("wxAcceleratorEntry"))) {
+                PyErr_SetString(PyExc_TypeError,"Expected wxAcceleratorEntry.");
                 return NULL;
             }
             temp[x] = *ae;
@@ -2136,11 +2128,11 @@ wxPen** wxPen_LIST_helper(PyObject* source) {
     }
     for (int x=0; x<count; x++) {
         PyObject* o = PyList_GetItem(source, x);
-        if (PyInstance_Check(o)) {
+        if (wxPySwigInstance_Check(o)) {
             wxPen*  pt;
-            if (SWIG_GetPtrObj(o, (void **) &pt,"_wxPen_p")) {
+            if (! wxPyConvertSwigPtr(o, (void **)&pt, wxT("wxPen"))) {
                 delete temp;
-                PyErr_SetString(PyExc_TypeError,"Expected _wxPen_p.");
+                PyErr_SetString(PyExc_TypeError,"Expected wxPen.");
                 return NULL;
             }
             temp[x] = pt;
@@ -2160,7 +2152,7 @@ bool wxPy2int_seq_helper(PyObject* source, int* i1, int* i2) {
     PyObject *o1, *o2;
 
     if (!PySequence_Check(source) || PySequence_Length(source) != 2)
-        return FALSE;
+        return False;
 
     if (isFast) {
         o1 = PySequence_Fast_GET_ITEM(source, 0);
@@ -2178,7 +2170,7 @@ bool wxPy2int_seq_helper(PyObject* source, int* i1, int* i2) {
         Py_DECREF(o1);
         Py_DECREF(o2);
     }
-    return TRUE;
+    return True;
 }
 
 
@@ -2187,7 +2179,7 @@ bool wxPy4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4) {
     PyObject *o1, *o2, *o3, *o4;
 
     if (!PySequence_Check(source) || PySequence_Length(source) != 4)
-        return FALSE;
+        return False;
 
     if (isFast) {
         o1 = PySequence_Fast_GET_ITEM(source, 0);
@@ -2213,84 +2205,62 @@ bool wxPy4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4) {
         Py_DECREF(o3);
         Py_DECREF(o4);
     }
-    return TRUE;
+    return True;
 }
 
 
 //----------------------------------------------------------------------
 
-bool wxSize_helper(PyObject* source, wxSize** obj) {
-
-    // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
-        wxSize* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
-            goto error;
-        *obj = ptr;
-        return TRUE;
-    }
-    // otherwise a 2-tuple of integers is expected
-    else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
-        PyObject* o1 = PySequence_GetItem(source, 0);
-        PyObject* o2 = PySequence_GetItem(source, 1);
-        if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) {
-            Py_DECREF(o1);
-            Py_DECREF(o2);
-            goto error;
-        }
-        **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
-        Py_DECREF(o1);
-        Py_DECREF(o2);
-        return TRUE;
+bool wxPySimple_typecheck(PyObject* source, const wxChar* classname, int seqLen)
+{
+    void* ptr;
+    
+    if (wxPySwigInstance_Check(source) &&
+        wxPyConvertSwigPtr(source, (void **)&ptr, classname))
+        return True;
+
+    PyErr_Clear();
+    if (PySequence_Check(source) && PySequence_Length(source) == seqLen)
+        return True;
+    
+    return False;
+}    
+
+bool wxSize_helper(PyObject* source, wxSize** obj)
+{
+    if (source == Py_None) {
+        **obj = wxSize(-1,-1);
+        return True;
     }
-
- error:
-    PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
-    return FALSE;
+    return wxPyTwoIntItem_helper(source, obj, wxT("wxSize"));
 }
 
 
-bool wxPoint_helper(PyObject* source, wxPoint** obj) {
-
-    // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
-        wxPoint* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
-            goto error;
-        *obj = ptr;
-        return TRUE;
-    }
-    // otherwise a length-2 sequence of integers is expected
-    if (PySequence_Check(source) && PySequence_Length(source) == 2) {
-        PyObject* o1 = PySequence_GetItem(source, 0);
-        PyObject* o2 = PySequence_GetItem(source, 1);
-        // This should really check for integers, not numbers -- but that would break code.
-        if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) {
-            Py_DECREF(o1);
-            Py_DECREF(o2);
-            goto error;
-        }
-        **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
-        Py_DECREF(o1);
-        Py_DECREF(o2);
-        return TRUE;
+bool wxPoint_helper(PyObject* source, wxPoint** obj)
+{
+    if (source == Py_None) {
+        **obj = wxPoint(-1,-1);
+        return True;
     }
- error:
-    PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
-    return FALSE;
+    return wxPyTwoIntItem_helper(source, obj, wxT("wxPoint"));
 }
 
 
 
 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
 
+    if (source == Py_None) {
+        **obj = wxRealPoint(-1,-1);
+        return True;
+    }
+    
     // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
+    if (wxPySwigInstance_Check(source)) {
         wxRealPoint* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
+        if (! wxPyConvertSwigPtr(source, (void **)&ptr, wxT("wxRealPoint")))
             goto error;
         *obj = ptr;
-        return TRUE;
+        return True;
     }
     // otherwise a 2-tuple of floats is expected
     else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
@@ -2304,26 +2274,30 @@ bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
         **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
         Py_DECREF(o1);
         Py_DECREF(o2);
-        return TRUE;
+        return True;
     }
 
  error:
     PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
-    return FALSE;
+    return False;
 }
 
 
 
-
 bool wxRect_helper(PyObject* source, wxRect** obj) {
 
+    if (source == Py_None) {
+        **obj = wxRect(-1,-1,-1,-1);
+        return True;
+    }
+
     // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
+    if (wxPySwigInstance_Check(source)) {
         wxRect* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
+        if (! wxPyConvertSwigPtr(source, (void **)&ptr, wxT("wxRect")))
             goto error;
         *obj = ptr;
-        return TRUE;
+        return True;
     }
     // otherwise a 4-tuple of integers is expected
     else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
@@ -2345,25 +2319,30 @@ bool wxRect_helper(PyObject* source, wxRect** obj) {
         Py_DECREF(o2);
         Py_DECREF(o3);
         Py_DECREF(o4);
-        return TRUE;
+        return True;
     }
 
  error:
     PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
-    return FALSE;
+    return False;
 }
 
 
 
 bool wxColour_helper(PyObject* source, wxColour** obj) {
 
+    if (source == Py_None) {
+        **obj = wxNullColour;
+        return True;
+    }
+
     // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
+    if (wxPySwigInstance_Check(source)) {
         wxColour* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxColour_p"))
+        if (! wxPyConvertSwigPtr(source, (void **)&ptr, wxT("wxColour")))
             goto error;
         *obj = ptr;
-        return TRUE;
+        return True;
     }
     // otherwise check for a string
     else if (PyString_Check(source) || PyUnicode_Check(source)) {
@@ -2376,11 +2355,11 @@ bool wxColour_helper(PyObject* source, wxColour** obj) {
             spec.Mid(5,2).ToLong(&blue,  16);
 
             **obj = wxColour(red, green, blue);
-            return TRUE;
+            return True;
         }
         else {                                       // it's a colour name
             **obj = wxColour(spec);
-            return TRUE;
+            return True;
         }
     }
     // last chance: 3-tuple of integers is expected
@@ -2398,48 +2377,65 @@ bool wxColour_helper(PyObject* source, wxColour** obj) {
         Py_DECREF(o1);
         Py_DECREF(o2);
         Py_DECREF(o3);
-        return TRUE;
+        return True;
     }
 
  error:
     PyErr_SetString(PyExc_TypeError,
                     "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
-    return FALSE;
+    return False;
 }
 
 
+bool wxColour_typecheck(PyObject* source) {
 
-bool wxPoint2DDouble_helper(PyObject* source, wxPoint2DDouble** obj) {
+    if (wxPySimple_typecheck(source, wxT("wxColour"), 3))
+        return True;
+
+    if (PyString_Check(source) || PyUnicode_Check(source))
+        return True;
+    
+    return False;   
+}
+
+
+
+bool wxPoint2D_helper(PyObject* source, wxPoint2D** obj) {
+
+    if (source == Py_None) {
+        **obj = wxPoint2D(-1,-1);
+        return True;
+    }
+    
     // If source is an object instance then it may already be the right type
-    if (PyInstance_Check(source)) {
-        wxPoint2DDouble* ptr;
-        if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint2DDouble_p"))
+    if (wxPySwigInstance_Check(source)) {
+        wxPoint2D* ptr;
+        if (! wxPyConvertSwigPtr(source, (void **)&ptr, wxT("wxPoint2D")))
             goto error;
         *obj = ptr;
-        return TRUE;
+        return True;
     }
     // otherwise a length-2 sequence of floats is expected
     if (PySequence_Check(source) && PySequence_Length(source) == 2) {
         PyObject* o1 = PySequence_GetItem(source, 0);
         PyObject* o2 = PySequence_GetItem(source, 1);
-        // This should really check for integers, not numbers -- but that would break code.
+        // This should really check for floats, not numbers -- but that would break code.
         if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) {
             Py_DECREF(o1);
             Py_DECREF(o2);
             goto error;
         }
-        **obj = wxPoint2DDouble(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
+        **obj = wxPoint2D(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
         Py_DECREF(o1);
         Py_DECREF(o2);
-        return TRUE;
+        return True;
     }
  error:
-    PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxPoint2DDouble object.");
-    return FALSE;
+    PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxPoint2D object.");
+    return False;
 }
 
 
-
 //----------------------------------------------------------------------
 
 PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) {