1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Helper functions/classes for the wxPython extension module 
   7 // Created:     1-July-1997 
   9 // Copyright:   (c) 1998 by Total Control Software 
  10 // Licence:     wxWindows license 
  11 ///////////////////////////////////////////////////////////////////////////// 
  16 #include "wx/wxPython/wxPython_int.h" 
  17 #include "wx/wxPython/pyistream.h" 
  18 #include "wx/wxPython/swigver.h" 
  19 #include "wx/wxPython/twoitem.h" 
  22 #include <wx/msw/private.h> 
  23 #include <wx/msw/winundef.h> 
  24 #include <wx/msw/msvcrt.h> 
  31 #include <gdk/gdkprivate.h> 
  33 #include <wx/gtk/win_gtk.h> 
  35 #include <wx/gtk1/win_gtk.h> 
  37 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \ 
  38                           GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \ 
  39                           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) 
  44 #include "wx/x11/privx.h" 
  45 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle()) 
  49 #include <wx/mac/private.h> 
  52 #include <wx/clipbrd.h> 
  53 #include <wx/mimetype.h> 
  56 //---------------------------------------------------------------------- 
  58 #if PYTHON_API_VERSION < 1009 && wxUSE_UNICODE 
  59 #error Python must support Unicode to use wxWindows Unicode 
  62 //---------------------------------------------------------------------- 
  64 wxPyApp
* wxPythonApp 
= NULL
;  // Global instance of application object 
  65 bool wxPyDoCleanup 
= false; 
  66 bool wxPyDoingCleanup 
= false; 
  69 #ifdef WXP_WITH_THREAD 
  70 #if !wxPyUSE_GIL_STATE 
  71 struct wxPyThreadState 
{ 
  73     PyThreadState
* tstate
; 
  75     wxPyThreadState(unsigned long _tid
=0, PyThreadState
* _tstate
=NULL
) 
  76         : tid(_tid
), tstate(_tstate
) {} 
  79 #include <wx/dynarray.h> 
  80 WX_DECLARE_OBJARRAY(wxPyThreadState
, wxPyThreadStateArray
); 
  81 #include <wx/arrimpl.cpp> 
  82 WX_DEFINE_OBJARRAY(wxPyThreadStateArray
); 
  84 wxPyThreadStateArray
* wxPyTStates 
= NULL
; 
  85 wxMutex
*              wxPyTMutex 
= NULL
; 
  91 #define DEFAULTENCODING_SIZE 64 
  92 static char wxPyDefaultEncoding
[DEFAULTENCODING_SIZE
] = "ascii"; 
  94 static PyObject
* wxPython_dict 
= NULL
; 
  95 static PyObject
* wxPyAssertionError 
= NULL
; 
  96 static PyObject
* wxPyNoAppError 
= NULL
; 
  98 PyObject
* wxPyPtrTypeMap 
= NULL
; 
 101 #ifdef __WXMSW__             // If building for win32... 
 102 //---------------------------------------------------------------------- 
 103 // This gets run when the DLL is loaded.  We just need to save a handle. 
 104 //---------------------------------------------------------------------- 
 108     HINSTANCE   hinstDLL
,    // handle to DLL module 
 109     DWORD       fdwReason
,   // reason for calling function 
 110     LPVOID      lpvReserved  
// reserved 
 113     // If wxPython is embedded in another wxWidgets app then 
 114     // the instance has already been set. 
 115     if (! wxGetInstance()) 
 116         wxSetInstance(hinstDLL
); 
 121 //---------------------------------------------------------------------- 
 122 // Classes for implementing the wxp main application shell. 
 123 //---------------------------------------------------------------------- 
 125 IMPLEMENT_ABSTRACT_CLASS(wxPyApp
, wxApp
); 
 129     m_assertMode 
= wxPYAPP_ASSERT_EXCEPTION
; 
 130     m_startupComplete 
= false; 
 134 wxPyApp::~wxPyApp() { 
 136     wxApp::SetInstance(NULL
); 
 140 // This one isn't acutally called...  We fake it with _BootstrapApp 
 141 bool wxPyApp::OnInit() { 
 146 int  wxPyApp::MainLoop() { 
 149     DeletePendingObjects(); 
 150     bool initialized 
= wxTopLevelWindows
.GetCount() != 0; 
 152         if ( m_exitOnFrameDelete 
== Later 
) { 
 153             m_exitOnFrameDelete 
= Yes
; 
 156         retval 
= wxApp::MainLoop(); 
 163 bool wxPyApp::OnInitGui() { 
 165     wxApp::OnInitGui();  // in this case always call the base class version 
 166     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 167     if (wxPyCBH_findCallback(m_myInst
, "OnInitGui")) 
 168         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 169     wxPyEndBlockThreads(blocked
); 
 174 int wxPyApp::OnExit() { 
 176     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 177     if (wxPyCBH_findCallback(m_myInst
, "OnExit")) 
 178         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 179     wxPyEndBlockThreads(blocked
); 
 180     wxApp::OnExit();  // in this case always call the base class version 
 186 void wxPyApp::ExitMainLoop() { 
 188     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 189     if ((found 
= wxPyCBH_findCallback(m_myInst
, "ExitMainLoop"))) 
 190         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 191     wxPyEndBlockThreads(blocked
); 
 193         wxApp::ExitMainLoop(); 
 198 void wxPyApp::OnAssertFailure(const wxChar 
*file
, 
 204     // if we're not fully initialized then just log the error 
 205     if (! m_startupComplete
) { 
 208         buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 211             buf 
<< wxT(" in ") << func 
<< wxT("()"); 
 213             buf 
<< wxT(": ") << msg
; 
 219     // If the OnAssert is overloaded in the Python class then call it... 
 221     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 222     if ((found 
= wxPyCBH_findCallback(m_myInst
, "OnAssert"))) { 
 223         PyObject
* fso 
= wx2PyString(file
); 
 224         PyObject
* cso 
= wx2PyString(file
); 
 227             mso 
= wx2PyString(file
); 
 229             mso 
= Py_None
; Py_INCREF(Py_None
); 
 231         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(OiOO)", fso
, line
, cso
, mso
)); 
 236     wxPyEndBlockThreads(blocked
); 
 238     // ...otherwise do our own thing with it 
 241         if (m_assertMode 
& wxPYAPP_ASSERT_SUPPRESS
) 
 244         // turn it into a Python exception? 
 245         if (m_assertMode 
& wxPYAPP_ASSERT_EXCEPTION
) { 
 248             buf
.Printf(wxT("C++ assertion \"%s\" failed at %s(%d)"), cond
, file
, line
); 
 250                 buf 
<< wxT(" in ") << func 
<< wxT("()"); 
 252                 buf 
<< wxT(": ") << msg
; 
 256             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 257             PyObject
* s 
= wx2PyString(buf
); 
 258             PyErr_SetObject(wxPyAssertionError
, s
); 
 260             wxPyEndBlockThreads(blocked
); 
 262             // Now when control returns to whatever API wrapper was called from 
 263             // Python it should detect that an exception is set and will return 
 264             // NULL, signalling the exception to Python. 
 267         // Send it to the normal log destination, but only if 
 268         // not _DIALOG because it will call this too 
 269         if ( (m_assertMode 
& wxPYAPP_ASSERT_LOG
) && !(m_assertMode 
& wxPYAPP_ASSERT_DIALOG
)) { 
 272             buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 275                 buf 
<< wxT(" in ") << func 
<< wxT("()"); 
 277                 buf 
<< wxT(": ") << msg
; 
 281         // do the normal wx assert dialog? 
 282         if (m_assertMode 
& wxPYAPP_ASSERT_DIALOG
) 
 283             wxApp::OnAssertFailure(file
, line
, func
, cond
, msg
); 
 288     // For catching Apple Events 
 289 void wxPyApp::MacOpenFile(const wxString 
&fileName
) 
 291     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 292     if (wxPyCBH_findCallback(m_myInst
, "MacOpenFile")) { 
 293         PyObject
* s 
= wx2PyString(fileName
); 
 294         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 297     wxPyEndBlockThreads(blocked
); 
 300 void wxPyApp::MacOpenURL(const wxString 
&url
) 
 302     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 303     if (wxPyCBH_findCallback(m_myInst
, "MacOpenURL")) { 
 304         PyObject
* s 
= wx2PyString(url
); 
 305         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 308     wxPyEndBlockThreads(blocked
); 
 311 void wxPyApp::MacPrintFile(const wxString 
&fileName
) 
 313     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 314     if (wxPyCBH_findCallback(m_myInst
, "MacPrintFile")) { 
 315         PyObject
* s 
= wx2PyString(fileName
); 
 316         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 319     wxPyEndBlockThreads(blocked
); 
 322 void wxPyApp::MacNewFile() 
 324     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 325     if (wxPyCBH_findCallback(m_myInst
, "MacNewFile")) 
 326         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 327     wxPyEndBlockThreads(blocked
); 
 330 void wxPyApp::MacReopenApp() 
 332     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 333     if (wxPyCBH_findCallback(m_myInst
, "MacReopenApp")) 
 334         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 335     wxPyEndBlockThreads(blocked
); 
 340 bool wxPyApp::GetMacSupportPCMenuShortcuts() { 
 345 long wxPyApp::GetMacAboutMenuItemId() { 
 347     return s_macAboutMenuItemId
; 
 354 long wxPyApp::GetMacPreferencesMenuItemId() { 
 356     return s_macPreferencesMenuItemId
; 
 363 long wxPyApp::GetMacExitMenuItemId() { 
 365     return s_macExitMenuItemId
; 
 372 wxString 
wxPyApp::GetMacHelpMenuTitleName() { 
 374     return s_macHelpMenuTitleName
; 
 376     return wxEmptyString
; 
 381 void wxPyApp::SetMacSupportPCMenuShortcuts(bool) { 
 385 void wxPyApp::SetMacAboutMenuItemId(long val
) { 
 387     s_macAboutMenuItemId 
= val
; 
 392 void wxPyApp::SetMacPreferencesMenuItemId(long val
) { 
 394     s_macPreferencesMenuItemId 
= val
; 
 399 void wxPyApp::SetMacExitMenuItemId(long val
) { 
 401     s_macExitMenuItemId 
= val
; 
 406 void wxPyApp::SetMacHelpMenuTitleName(const wxString
& val
) { 
 408     s_macHelpMenuTitleName 
= val
; 
 413 // This finishes the initialization of wxWindows and then calls the OnInit 
 414 // that should be present in the derived (Python) class. 
 415 void wxPyApp::_BootstrapApp() 
 417     static      bool haveInitialized 
= false; 
 420     PyObject
*   retval 
= NULL
; 
 421     PyObject
*   pyint  
= NULL
; 
 424     // Only initialize wxWidgets once 
 425     if (! haveInitialized
) { 
 427         // Get any command-line args passed to this program from the sys module 
 430         blocked 
= wxPyBeginBlockThreads(); 
 432         PyObject
* sysargv 
= PySys_GetObject("argv"); 
 433         PyObject
* executable 
= PySys_GetObject("executable"); 
 435         if (sysargv 
!= NULL 
&& executable 
!= NULL
) { 
 436             argc 
= PyList_Size(sysargv
) + 1; 
 437             argv 
= new char*[argc
+1]; 
 438             argv
[0] = strdup(PyString_AsString(executable
)); 
 440             for(x
=1; x
<argc
; x
++) { 
 441                 PyObject 
*pyArg 
= PyList_GetItem(sysargv
, x
-1); 
 442                 argv
[x
] = strdup(PyString_AsString(pyArg
)); 
 446         wxPyEndBlockThreads(blocked
); 
 448         // Initialize wxWidgets 
 449         result 
= wxEntryStart(argc
, argv
); 
 450         // wxApp takes ownership of the argv array, don't delete it here 
 452         blocked 
= wxPyBeginBlockThreads(); 
 454             PyErr_SetString(PyExc_SystemError
, 
 455                             "wxEntryStart failed, unable to initialize wxWidgets!" 
 457                             "  (Is DISPLAY set properly?)" 
 463         // On wxGTK the locale will be changed to match the system settings, 
 464         // but Python before 2.4 needs to have LC_NUMERIC set to "C" in order 
 465         // for the floating point conversions and such to work right. 
 466 #if defined(__WXGTK__) && PY_VERSION_HEX < 0x02040000 
 467         setlocale(LC_NUMERIC
, "C"); 
 470 //        wxSystemOptions::SetOption(wxT("mac.textcontrol-use-mlte"), 1); 
 472         wxPyEndBlockThreads(blocked
); 
 473         haveInitialized 
= true; 
 481     // It's now ok to generate exceptions for assertion errors. 
 482     wxPythonApp
->SetStartupComplete(true); 
 485     // Call the Python wxApp's OnPreInit and OnInit functions 
 486     blocked 
= wxPyBeginBlockThreads(); 
 487     if (wxPyCBH_findCallback(m_myInst
, "OnPreInit")) { 
 488         PyObject
* method 
= m_myInst
.GetLastFound(); 
 489         PyObject
* argTuple 
= PyTuple_New(0); 
 490         retval 
= PyEval_CallObject(method
, argTuple
); 
 491         m_myInst
.clearRecursionGuard(method
); 
 497     if (wxPyCBH_findCallback(m_myInst
, "OnInit")) { 
 499         PyObject
* method 
= m_myInst
.GetLastFound(); 
 500         PyObject
* argTuple 
= PyTuple_New(0); 
 501         retval 
= PyEval_CallObject(method
, argTuple
); 
 502         m_myInst
.clearRecursionGuard(method
); 
 506             // Don't PyErr_Print here, let the exception in this case go back 
 507             // up to the wx.PyApp.__init__ scope. 
 510         pyint 
= PyNumber_Int(retval
); 
 512             PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value"); 
 515         result 
= PyInt_AS_LONG(pyint
); 
 518         // Is it okay if there is no OnInit?  Probably so... 
 523         PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting..."); 
 530     wxPyEndBlockThreads(blocked
); 
 533 //--------------------------------------------------------------------- 
 534 //---------------------------------------------------------------------- 
 538 static char* wxPyCopyCString(const wxChar
* src
) 
 540     wxWX2MBbuf buff 
= (wxWX2MBbuf
)wxConvCurrent
->cWX2MB(src
); 
 541     size_t len 
= strlen(buff
); 
 542     char*  dest 
= new char[len
+1]; 
 548 static char* wxPyCopyCString(const char* src
)   // we need a char version too 
 550     size_t len 
= strlen(src
); 
 551     char*  dest 
= new char[len
+1]; 
 557 static wxChar
* wxPyCopyWString(const char *src
) 
 559     //wxMB2WXbuf buff = wxConvCurrent->cMB2WX(src); 
 560     wxString 
str(src
, *wxConvCurrent
); 
 561     return copystring(str
); 
 565 static wxChar
* wxPyCopyWString(const wxChar 
*src
) 
 567     return copystring(src
); 
 573 inline const char* dropwx(const char* name
) { 
 574     if (name
[0] == 'w' && name
[1] == 'x') 
 580 //---------------------------------------------------------------------- 
 582 // This function is called when the wx._core_ module is imported to do some 
 583 // initial setup.  (Before there is a wxApp object.)  The rest happens in 
 584 // wxPyApp::_BootstrapApp 
 585 void __wxPyPreStart(PyObject
* moduleDict
) 
 589 //     wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF 
 590 //                     | _CRTDBG_CHECK_ALWAYS_DF 
 591 //                     | _CRTDBG_DELAY_FREE_MEM_DF 
 595 #ifdef WXP_WITH_THREAD 
 596 #if wxPyUSE_GIL_STATE 
 597     PyEval_InitThreads(); 
 599     PyEval_InitThreads(); 
 600     wxPyTStates 
= new wxPyThreadStateArray
; 
 601     wxPyTMutex 
= new wxMutex
; 
 603     // Save the current (main) thread state in our array 
 604     PyThreadState
* tstate 
= wxPyBeginAllowThreads(); 
 605     wxPyEndAllowThreads(tstate
); 
 609     // Ensure that the build options in the DLL (or whatever) match this build 
 610     wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE
, "wxPython"); 
 612     wxInitAllImageHandlers(); 
 617 void __wxPyCleanup() { 
 618     wxPyDoingCleanup 
= true; 
 620         wxPyDoCleanup 
= false; 
 623 #ifdef WXP_WITH_THREAD 
 624 #if !wxPyUSE_GIL_STATE 
 627     wxPyTStates
->Empty(); 
 635 // Save a reference to the dictionary of the wx._core module, and inject 
 636 // a few more things into it. 
 637 PyObject
* __wxPySetDictionary(PyObject
* /* self */, PyObject
* args
) 
 640     if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
)) 
 643     if (!PyDict_Check(wxPython_dict
)) { 
 644         PyErr_SetString(PyExc_TypeError
, 
 645                         "_wxPySetDictionary must have dictionary object!"); 
 649     if (! wxPyPtrTypeMap
) 
 650         wxPyPtrTypeMap 
= PyDict_New(); 
 651     PyDict_SetItemString(wxPython_dict
, "__wxPyPtrTypeMap", wxPyPtrTypeMap
); 
 653     // Create an exception object to use for wxASSERTions 
 654     wxPyAssertionError 
= PyErr_NewException("wx._core.PyAssertionError", 
 655                                             PyExc_AssertionError
, NULL
); 
 656     PyDict_SetItemString(wxPython_dict
, "PyAssertionError", wxPyAssertionError
); 
 658     // Create an exception object to use when the app object hasn't been created yet 
 659     wxPyNoAppError 
= PyErr_NewException("wx._core.PyNoAppError", 
 660                                         PyExc_RuntimeError
, NULL
); 
 661     PyDict_SetItemString(wxPython_dict
, "PyNoAppError", wxPyNoAppError
); 
 666 #define wxPlatform "__WXMOTIF__" 
 667 #define wxPlatName "wxMotif" 
 670 #define wxPlatform "__WXX11__" 
 671 #define wxPlatName "wxX11" 
 674 #define wxPlatform "__WXGTK__" 
 675 #define wxPlatName "wxGTK" 
 678 #define wxPlatform "__WXMSW__" 
 679 #define wxPlatName "wxMSW" 
 682 #define wxPlatform "__WXMAC__" 
 683 #define wxPlatName "wxMac" 
 692     // These should be deprecated in favor of the PlatformInfo tuple built below... 
 693     PyDict_SetItemString(wxPython_dict
, "Platform", PyString_FromString(wxPlatform
)); 
 694     PyDict_SetItemString(wxPython_dict
, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE
)); 
 695     PyDict_SetItemString(wxPython_dict
, "__WXDEBUG__", PyInt_FromLong(wxdebug
)); 
 697     // Make a tuple of strings that gives more info about the platform. 
 698     PyObject
* PlatInfo 
= PyList_New(0); 
 701 #define _AddInfoString(st) \ 
 702     obj = PyString_FromString(st); \ 
 703     PyList_Append(PlatInfo, obj); \ 
 706     _AddInfoString(wxPlatform
); 
 707     _AddInfoString(wxPlatName
); 
 709     _AddInfoString("unicode"); 
 711     _AddInfoString("ansi"); 
 715     _AddInfoString("gtk2"); 
 717     _AddInfoString("gtk1"); 
 721     _AddInfoString("wx-assertions-on"); 
 723     _AddInfoString("wx-assertions-off"); 
 725     _AddInfoString(wxPy_SWIG_VERSION
);     
 727     #if wxMAC_USE_CORE_GRAPHICS 
 728         _AddInfoString("mac-cg"); 
 730         _AddInfoString("mac-qd"); 
 732     #if wxMAC_USE_NATIVE_TOOLBAR 
 733         _AddInfoString("mac-native-tb"); 
 735         _AddInfoString("mac-no-native-tb"); 
 739 #undef _AddInfoString 
 741     PyObject
* PlatInfoTuple 
= PyList_AsTuple(PlatInfo
); 
 743     PyDict_SetItemString(wxPython_dict
, "PlatformInfo", PlatInfoTuple
); 
 750 //--------------------------------------------------------------------------- 
 752 // Check for existence of a wxApp, setting an exception if there isn't one. 
 753 // This doesn't need to aquire the GIL because it should only be called from 
 754 // an %exception before the lock is released. 
 756 bool wxPyCheckForApp() { 
 757     if (wxTheApp 
!= NULL
) 
 760         PyErr_SetString(wxPyNoAppError
, "The wx.App object must be created first!"); 
 765 //--------------------------------------------------------------------------- 
 767 void wxPyUserData_dtor(wxPyUserData
* self
) { 
 768     if (! wxPyDoingCleanup
) { 
 769         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 770         Py_DECREF(self
->m_obj
); 
 772         wxPyEndBlockThreads(blocked
); 
 777 void wxPyClientData_dtor(wxPyClientData
* self
) { 
 778     if (! wxPyDoingCleanup
) {           // Don't do it during cleanup as Python 
 779                                         // may have already garbage collected the object... 
 780         if (self
->m_incRef
) { 
 781             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 782             Py_DECREF(self
->m_obj
); 
 783             wxPyEndBlockThreads(blocked
); 
 791 // This is called when an OOR controled object is being destroyed.  Although 
 792 // the C++ object is going away there is no way to force the Python object 
 793 // (and all references to it) to die too.  This causes problems (crashes) in 
 794 // wxPython when a python shadow object attempts to call a C++ method using 
 795 // the now bogus pointer... So to try and prevent this we'll do a little black 
 796 // magic and change the class of the python instance to a class that will 
 797 // raise an exception for any attempt to call methods with it.  See 
 798 // _wxPyDeadObject in _core_ex.py for the implementation of this class. 
 799 void wxPyOORClientData_dtor(wxPyOORClientData
* self
) { 
 801     static PyObject
* deadObjectClass 
= NULL
; 
 803     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 804     if (deadObjectClass 
== NULL
) { 
 805         deadObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyDeadObject"); 
 806         // TODO:  Can not wxASSERT here because inside a wxPyBeginBlock Threads, 
 807         // will lead to a deadlock when it tries to aquire the GIL again. 
 808         //wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!")); 
 809         Py_INCREF(deadObjectClass
); 
 813     // Only if there is more than one reference to the object and we are 
 814     // holding the OOR reference: 
 815     if ( !wxPyDoingCleanup 
&& self
->m_obj
->ob_refcnt 
> 1 && self
->m_incRef
) { 
 816         // bool isInstance = wxPyInstance_Check(self->m_obj); 
 818         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!")); 
 820         // Call __del__, if there is one. 
 821         PyObject
* func 
= PyObject_GetAttrString(self
->m_obj
, "__del__"); 
 823             PyObject
* rv 
= PyObject_CallMethod(self
->m_obj
, "__del__", NULL
); 
 827         if (PyErr_Occurred()) 
 828             PyErr_Clear();      // just ignore it for now 
 831         PyObject
* dict 
= PyObject_GetAttrString(self
->m_obj
, "__dict__"); 
 833             // Clear the instance's dictionary 
 836             // put the name of the old class into the instance, and then reset the 
 837             // class to be the dead class. 
 838             PyObject
* klass 
= PyObject_GetAttrString(self
->m_obj
, "__class__"); 
 839             PyObject
* name 
=  PyObject_GetAttrString(klass
, "__name__"); 
 840             PyDict_SetItemString(dict
, "_name", name
); 
 841             PyObject_SetAttrString(self
->m_obj
, "__class__",  deadObjectClass
); 
 842             //Py_INCREF(deadObjectClass); 
 848     // m_obj is DECREF'd in the base class dtor... 
 849     wxPyEndBlockThreads(blocked
); 
 853 //--------------------------------------------------------------------------- 
 854 // Stuff used by OOR to find the right wxPython class type to return and to 
 858 // The pointer type map is used when the "pointer" type name generated by SWIG 
 859 // is not the same as the shadow class name, for example wxPyTreeCtrl 
 860 // vs. wxTreeCtrl.  It needs to be referenced in Python as well as from C++, 
 861 // so we'll just make it a Python dictionary in the wx module's namespace. 
 862 // (See __wxSetDictionary) 
 863 void wxPyPtrTypeMap_Add(const char* commonName
, const char* ptrName
) { 
 864     if (! wxPyPtrTypeMap
) 
 865         wxPyPtrTypeMap 
= PyDict_New(); 
 866     PyDict_SetItemString(wxPyPtrTypeMap
, 
 868                          PyString_FromString((char*)ptrName
)); 
 874 PyObject
*  wxPyMake_wxObject(wxObject
* source
, bool setThisOwn
, bool checkEvtHandler
) { 
 875     PyObject
* target 
= NULL
; 
 876     bool      isEvtHandler 
= false; 
 877     bool      isSizer 
= false; 
 880         // If it's derived from wxEvtHandler then there may 
 881         // already be a pointer to a Python object that we can use 
 883         if (checkEvtHandler 
&& wxIsKindOf(source
, wxEvtHandler
)) { 
 885             wxEvtHandler
* eh 
= (wxEvtHandler
*)source
; 
 886             wxPyOORClientData
* data 
= (wxPyOORClientData
*)eh
->GetClientObject(); 
 888                 target 
= data
->m_obj
; 
 894         // Also check for wxSizer 
 895         if (!target 
&& wxIsKindOf(source
, wxSizer
)) { 
 897             wxSizer
* sz 
= (wxSizer
*)source
; 
 898             wxPyOORClientData
* data 
= (wxPyOORClientData
*)sz
->GetClientObject(); 
 900                 target 
= data
->m_obj
; 
 907             // Otherwise make it the old fashioned way by making a new shadow 
 908             // object and putting this pointer in it.  Look up the class 
 909             // heirarchy until we find a class name that is located in the 
 911             const wxClassInfo
* info   
= source
->GetClassInfo(); 
 912             wxString           name   
= info
->GetClassName(); 
 913             bool               exists 
= wxPyCheckSwigType(name
); 
 914             while (info 
&& !exists
) { 
 915                 info 
= info
->GetBaseClass1(); 
 916                 name 
= info
->GetClassName(); 
 917                 exists 
= wxPyCheckSwigType(name
); 
 920                 target 
= wxPyConstructObject((void*)source
, name
, setThisOwn
); 
 921                 if (target 
&& isEvtHandler
) 
 922                     ((wxEvtHandler
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
 923                 if (target 
&& isSizer
) 
 924                     ((wxSizer
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
 926                 wxString 
msg(wxT("wxPython class not found for ")); 
 927                 msg 
+= source
->GetClassInfo()->GetClassName(); 
 928                 PyErr_SetString(PyExc_NameError
, msg
.mbc_str()); 
 932     } else {  // source was NULL so return None. 
 933         Py_INCREF(Py_None
); target 
= Py_None
; 
 939 PyObject
*  wxPyMake_wxSizer(wxSizer
* source
, bool setThisOwn
) { 
 941     return wxPyMake_wxObject(source
, setThisOwn
); 
 945 //--------------------------------------------------------------------------- 
 948 #ifdef WXP_WITH_THREAD 
 949 #if !wxPyUSE_GIL_STATE 
 952 unsigned long wxPyGetCurrentThreadId() { 
 953     return wxThread::GetCurrentId(); 
 956 static wxPyThreadState gs_shutdownTState
; 
 959 wxPyThreadState
* wxPyGetThreadState() { 
 960     if (wxPyTMutex 
== NULL
) // Python is shutting down... 
 961         return &gs_shutdownTState
; 
 963     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
 964     wxPyThreadState
* tstate 
= NULL
; 
 967     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
 968         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
 969         if (info
.tid 
== ctid
) { 
 974     wxPyTMutex
->Unlock(); 
 975     wxASSERT_MSG(tstate
, wxT("PyThreadState should not be NULL!")); 
 981 void wxPySaveThreadState(PyThreadState
* tstate
) { 
 982     if (wxPyTMutex 
== NULL
) { // Python is shutting down, assume a single thread... 
 983         gs_shutdownTState
.tstate 
= tstate
; 
 986     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
 988     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
 989         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
 990         if (info
.tid 
== ctid
) { 
 992             if (info
.tstate 
!= tstate
) 
 993                 wxLogMessage("*** tstate mismatch!???"); 
 995             info
.tstate 
= tstate
;    // allow for transient tstates 
 996             // Normally it will never change, but apparently COM callbacks 
 997             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient 
 998             // tstate which will then be garbage the next time we try to use 
1001             wxPyTMutex
->Unlock(); 
1005     // not found, so add it... 
1006     wxPyTStates
->Add(new wxPyThreadState(ctid
, tstate
)); 
1007     wxPyTMutex
->Unlock(); 
1015 // Calls from Python to wxWindows code are wrapped in calls to these 
1018 PyThreadState
* wxPyBeginAllowThreads() { 
1019 #ifdef WXP_WITH_THREAD 
1020     PyThreadState
* saved 
= PyEval_SaveThread();  // Py_BEGIN_ALLOW_THREADS; 
1021 #if !wxPyUSE_GIL_STATE 
1022     wxPySaveThreadState(saved
); 
1030 void wxPyEndAllowThreads(PyThreadState
* saved
) { 
1031 #ifdef WXP_WITH_THREAD 
1032     PyEval_RestoreThread(saved
);   // Py_END_ALLOW_THREADS; 
1038 // Calls from wxWindows back to Python code, or even any PyObject 
1039 // manipulations, PyDECREF's and etc. are wrapped in calls to these functions: 
1041 wxPyBlock_t 
wxPyBeginBlockThreads() { 
1042 #ifdef WXP_WITH_THREAD 
1043     if (! Py_IsInitialized()) { 
1044         return (wxPyBlock_t
)0; 
1046 #if wxPyUSE_GIL_STATE 
1047     PyGILState_STATE state 
= PyGILState_Ensure(); 
1050     PyThreadState 
*current 
= _PyThreadState_Current
; 
1052     // Only block if there wasn't already a tstate, or if the current one is 
1053     // not the one we are wanting to change to.  This should prevent deadlock 
1054     // if there are nested calls to wxPyBeginBlockThreads 
1055     wxPyBlock_t blocked 
= false; 
1056     wxPyThreadState
* tstate 
= wxPyGetThreadState(); 
1057     if (current 
!= tstate
->tstate
) { 
1058         PyEval_RestoreThread(tstate
->tstate
); 
1064     return (wxPyBlock_t
)0; 
1069 void wxPyEndBlockThreads(wxPyBlock_t blocked
) { 
1070 #ifdef WXP_WITH_THREAD 
1071     if (! Py_IsInitialized()) { 
1074 #if wxPyUSE_GIL_STATE 
1075     PyGILState_Release(blocked
); 
1077     // Only unblock if we blocked in the last call to wxPyBeginBlockThreads. 
1078     // The value of blocked passed in needs to be the same as that returned 
1079     // from wxPyBeginBlockThreads at the same nesting level. 
1081         PyEval_SaveThread(); 
1088 //--------------------------------------------------------------------------- 
1089 // wxPyInputStream and wxPyCBInputStream methods 
1092 void wxPyInputStream::close() { 
1093     /* do nothing for now */ 
1096 void wxPyInputStream::flush() { 
1097     /* do nothing for now */ 
1100 bool wxPyInputStream::eof() { 
1102         return m_wxis
->Eof(); 
1107 wxPyInputStream::~wxPyInputStream() { 
1115 PyObject
* wxPyInputStream::read(int size
) { 
1116     PyObject
* obj 
= NULL
; 
1118     const int BUFSIZE 
= 1024; 
1120     // check if we have a real wxInputStream to work with 
1122         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1123         PyErr_SetString(PyExc_IOError
, "no valid C-wxInputStream"); 
1124         wxPyEndBlockThreads(blocked
); 
1129         // read while bytes are available on the stream 
1130         while ( m_wxis
->CanRead() ) { 
1131             m_wxis
->Read(buf
.GetAppendBuf(BUFSIZE
), BUFSIZE
); 
1132             buf
.UngetAppendBuf(m_wxis
->LastRead()); 
1135     } else {  // Read only size number of characters 
1136         m_wxis
->Read(buf
.GetWriteBuf(size
), size
); 
1137         buf
.UngetWriteBuf(m_wxis
->LastRead()); 
1141     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1142     wxStreamError err 
= m_wxis
->GetLastError(); 
1143     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1144         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1147         // We use only strings for the streams, not unicode 
1148         obj 
= PyString_FromStringAndSize(buf
, buf
.GetDataLen()); 
1150     wxPyEndBlockThreads(blocked
); 
1155 PyObject
* wxPyInputStream::readline(int size
) { 
1156     PyObject
* obj 
= NULL
; 
1161     // check if we have a real wxInputStream to work with 
1163         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1164         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1165         wxPyEndBlockThreads(blocked
); 
1169     // read until \n or byte limit reached 
1170     for (i
=ch
=0; (ch 
!= '\n') && (m_wxis
->CanRead()) && ((size 
< 0) || (i 
< size
)); i
++) { 
1171         ch 
= m_wxis
->GetC(); 
1176     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1177     wxStreamError err 
= m_wxis
->GetLastError(); 
1178     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1179         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1182         // We use only strings for the streams, not unicode 
1183         obj 
= PyString_FromStringAndSize((char*)buf
.GetData(), buf
.GetDataLen()); 
1185     wxPyEndBlockThreads(blocked
); 
1190 PyObject
* wxPyInputStream::readlines(int sizehint
) { 
1193     // check if we have a real wxInputStream to work with 
1195         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1196         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1197         wxPyEndBlockThreads(blocked
); 
1202     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1203     pylist 
= PyList_New(0); 
1204     wxPyEndBlockThreads(blocked
); 
1207         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1209         wxPyEndBlockThreads(blocked
); 
1213     // read sizehint bytes or until EOF 
1215     for (i
=0; (m_wxis
->CanRead()) && ((sizehint 
< 0) || (i 
< sizehint
));) { 
1216         PyObject
* s 
= this->readline(); 
1218             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1220             wxPyEndBlockThreads(blocked
); 
1223         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1224         PyList_Append(pylist
, s
); 
1225         i 
+= PyString_Size(s
); 
1226         wxPyEndBlockThreads(blocked
); 
1230     wxStreamError err 
= m_wxis
->GetLastError(); 
1231     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1232         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1234         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1235         wxPyEndBlockThreads(blocked
); 
1243 void wxPyInputStream::seek(int offset
, int whence
) { 
1245         m_wxis
->SeekI(offset
, wxSeekMode(whence
)); 
1248 int wxPyInputStream::tell(){ 
1250         return m_wxis
->TellI(); 
1257 wxPyCBInputStream::wxPyCBInputStream(PyObject 
*r
, PyObject 
*s
, PyObject 
*t
, bool block
) 
1258     : wxInputStream(), m_read(r
), m_seek(s
), m_tell(t
), m_block(block
) 
1261 wxPyCBInputStream::wxPyCBInputStream(const wxPyCBInputStream
& other
) 
1263     m_read  
= other
.m_read
; 
1264     m_seek  
= other
.m_seek
; 
1265     m_tell  
= other
.m_tell
; 
1266     m_block 
= other
.m_block
; 
1273 wxPyCBInputStream::~wxPyCBInputStream() { 
1274     wxPyBlock_t blocked 
= wxPyBlock_t_default
; 
1275     if (m_block
) blocked 
= wxPyBeginBlockThreads(); 
1279     if (m_block
) wxPyEndBlockThreads(blocked
); 
1283 wxPyCBInputStream
* wxPyCBInputStream::create(PyObject 
*py
, bool block
) { 
1284     wxPyBlock_t blocked 
= wxPyBlock_t_default
; 
1285     if (block
) blocked 
= wxPyBeginBlockThreads(); 
1287     PyObject
* read 
= getMethod(py
, "read"); 
1288     PyObject
* seek 
= getMethod(py
, "seek"); 
1289     PyObject
* tell 
= getMethod(py
, "tell"); 
1292         PyErr_SetString(PyExc_TypeError
, "Not a file-like object"); 
1296         if (block
) wxPyEndBlockThreads(blocked
); 
1300     if (block
) wxPyEndBlockThreads(blocked
); 
1301     return new wxPyCBInputStream(read
, seek
, tell
, block
); 
1305 wxPyCBInputStream
* wxPyCBInputStream_create(PyObject 
*py
, bool block
) { 
1306     return wxPyCBInputStream::create(py
, block
); 
1309 wxPyCBInputStream
* wxPyCBInputStream_copy(wxPyCBInputStream
* other
) { 
1310     return new wxPyCBInputStream(*other
); 
1313 PyObject
* wxPyCBInputStream::getMethod(PyObject
* py
, char* name
) { 
1314     if (!PyObject_HasAttrString(py
, name
)) 
1316     PyObject
* o 
= PyObject_GetAttrString(py
, name
); 
1317     if (!PyMethod_Check(o
) && !PyCFunction_Check(o
)) { 
1325 wxFileOffset 
wxPyCBInputStream::GetLength() const { 
1326     wxPyCBInputStream
* self 
= (wxPyCBInputStream
*)this; // cast off const 
1327     if (m_seek 
&& m_tell
) { 
1328         wxFileOffset temp 
= self
->OnSysTell(); 
1329         wxFileOffset ret 
= self
->OnSysSeek(0, wxFromEnd
); 
1330         self
->OnSysSeek(temp
, wxFromStart
); 
1334         return wxInvalidOffset
; 
1338 size_t wxPyCBInputStream::OnSysRead(void *buffer
, size_t bufsize
) { 
1342     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1343     PyObject
* arglist 
= Py_BuildValue("(i)", bufsize
); 
1344     PyObject
* result 
= PyEval_CallObject(m_read
, arglist
); 
1348     if ((result 
!= NULL
) && PyString_Check(result
)) { 
1349         o 
= PyString_Size(result
); 
1351             m_lasterror 
= wxSTREAM_EOF
; 
1354         memcpy((char*)buffer
, PyString_AsString(result
), o
);  // strings only, not unicode... 
1359         m_lasterror 
= wxSTREAM_READ_ERROR
; 
1360     wxPyEndBlockThreads(blocked
); 
1364 size_t wxPyCBInputStream::OnSysWrite(const void *buffer
, size_t bufsize
) { 
1365     m_lasterror 
= wxSTREAM_WRITE_ERROR
; 
1370 wxFileOffset 
wxPyCBInputStream::OnSysSeek(wxFileOffset off
, wxSeekMode mode
) { 
1371     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1372     PyObject
* arglist 
= PyTuple_New(2); 
1374     if (sizeof(wxFileOffset
) > sizeof(long)) 
1375         // wxFileOffset is a 64-bit value... 
1376         PyTuple_SET_ITEM(arglist
, 0, PyLong_FromLongLong(off
)); 
1378         PyTuple_SET_ITEM(arglist
, 0, PyInt_FromLong(off
)); 
1380     PyTuple_SET_ITEM(arglist
, 1, PyInt_FromLong(mode
)); 
1383     PyObject
* result 
= PyEval_CallObject(m_seek
, arglist
); 
1386     wxPyEndBlockThreads(blocked
); 
1391 wxFileOffset 
wxPyCBInputStream::OnSysTell() const { 
1392     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1393     PyObject
* arglist 
= Py_BuildValue("()"); 
1394     PyObject
* result 
= PyEval_CallObject(m_tell
, arglist
); 
1397     if (result 
!= NULL
) { 
1398         if (PyLong_Check(result
)) 
1399             o 
= PyLong_AsLongLong(result
); 
1401             o 
= PyInt_AsLong(result
); 
1404     wxPyEndBlockThreads(blocked
); 
1408 //---------------------------------------------------------------------- 
1410 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback
, wxObject
); 
1412 wxPyCallback::wxPyCallback(PyObject
* func
) { 
1417 wxPyCallback::wxPyCallback(const wxPyCallback
& other
) { 
1418     m_func 
= other
.m_func
; 
1422 wxPyCallback::~wxPyCallback() { 
1423     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1425     wxPyEndBlockThreads(blocked
); 
1429 #define wxPy_PRECALLINIT     "_preCallInit" 
1430 #define wxPy_POSTCALLCLEANUP "_postCallCleanup" 
1432 // This function is used for all events destined for Python event handlers. 
1433 void wxPyCallback::EventThunker(wxEvent
& event
) { 
1434     wxPyCallback
*   cb 
= (wxPyCallback
*)event
.m_callbackUserData
; 
1435     PyObject
*       func 
= cb
->m_func
; 
1439     bool            checkSkip 
= false; 
1441     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1442     wxString className 
= event
.GetClassInfo()->GetClassName(); 
1444     // If the event is one of these types then pass the original 
1445     // event object instead of the one passed to us. 
1446     if ( className 
== wxT("wxPyEvent") ) { 
1447         arg 
=       ((wxPyEvent
*)&event
)->GetSelf(); 
1448         checkSkip 
= ((wxPyEvent
*)&event
)->GetCloned(); 
1450     else if ( className 
== wxT("wxPyCommandEvent") ) { 
1451         arg 
=       ((wxPyCommandEvent
*)&event
)->GetSelf(); 
1452         checkSkip 
= ((wxPyCommandEvent
*)&event
)->GetCloned(); 
1455         arg 
= wxPyConstructObject((void*)&event
, className
); 
1461         // "intern" the pre/post method names to speed up the HasAttr 
1462         static PyObject
* s_preName  
= NULL
; 
1463         static PyObject
* s_postName 
= NULL
; 
1464         if (s_preName 
== NULL
) { 
1465             s_preName  
= PyString_FromString(wxPy_PRECALLINIT
); 
1466             s_postName 
= PyString_FromString(wxPy_POSTCALLCLEANUP
); 
1469         // Check if the event object needs some preinitialization 
1470         if (PyObject_HasAttr(arg
, s_preName
)) { 
1471             result 
= PyObject_CallMethodObjArgs(arg
, s_preName
, arg
, NULL
); 
1473                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1474                 PyErr_Clear();       // Just in case... 
1480         // Call the event handler, passing the event object 
1481         tuple 
= PyTuple_New(1); 
1482         PyTuple_SET_ITEM(tuple
, 0, arg
);  // steals ref to arg 
1483         result 
= PyEval_CallObject(func
, tuple
); 
1485             Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1486             PyErr_Clear();       // Just in case... 
1491         // Check if the event object needs some post cleanup 
1492         if (PyObject_HasAttr(arg
, s_postName
)) { 
1493             result 
= PyObject_CallMethodObjArgs(arg
, s_postName
, arg
, NULL
); 
1495                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1496                 PyErr_Clear();       // Just in case... 
1503             // if the event object was one of our special types and 
1504             // it had been cloned, then we need to extract the Skipped 
1505             // value from the original and set it in the clone. 
1506             result 
= PyObject_CallMethod(arg
, "GetSkipped", ""); 
1508                 event
.Skip(PyInt_AsLong(result
)); 
1516     wxPyEndBlockThreads(blocked
); 
1520 //---------------------------------------------------------------------- 
1522 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper
& other
) { 
1524       m_self 
= other
.m_self
; 
1525       m_class 
= other
.m_class
; 
1533 void wxPyCallbackHelper::setSelf(PyObject
* self
, PyObject
* klass
, int incref
) { 
1544 #if PYTHON_API_VERSION >= 1011 
1546 // Prior to Python 2.2 PyMethod_GetClass returned the class object 
1547 // in which the method was defined.  Starting with 2.2 it returns 
1548 // "class that asked for the method" which seems totally bogus to me 
1549 // but apprently it fixes some obscure problem waiting to happen in 
1550 // Python.  Since the API was not documented Guido and the gang felt 
1551 // safe in changing it.  Needless to say that totally screwed up the 
1552 // logic below in wxPyCallbackHelper::findCallback, hence this icky 
1553 // code to find the class where the method is actually defined... 
1556 PyObject
* PyFindClassWithAttr(PyObject 
*klass
, PyObject 
*name
) 
1560     if (PyType_Check(klass
)) {      // new style classes 
1561         // This code is borrowed/adapted from _PyType_Lookup in typeobject.c 
1562         PyTypeObject
* type 
= (PyTypeObject
*)klass
; 
1563         PyObject 
*mro
, *res
, *base
, *dict
; 
1564         /* Look in tp_dict of types in MRO */ 
1566         assert(PyTuple_Check(mro
)); 
1567         n 
= PyTuple_GET_SIZE(mro
); 
1568         for (i 
= 0; i 
< n
; i
++) { 
1569             base 
= PyTuple_GET_ITEM(mro
, i
); 
1570             if (PyClass_Check(base
)) 
1571                 dict 
= ((PyClassObject 
*)base
)->cl_dict
; 
1573                 assert(PyType_Check(base
)); 
1574                 dict 
= ((PyTypeObject 
*)base
)->tp_dict
; 
1576             assert(dict 
&& PyDict_Check(dict
)); 
1577             res 
= PyDict_GetItem(dict
, name
); 
1584     else if (PyClass_Check(klass
)) { // old style classes 
1585         // This code is borrowed/adapted from class_lookup in classobject.c 
1586         PyClassObject
* cp 
= (PyClassObject
*)klass
; 
1587         PyObject 
*value 
= PyDict_GetItem(cp
->cl_dict
, name
); 
1588         if (value 
!= NULL
) { 
1589             return (PyObject
*)cp
; 
1591         n 
= PyTuple_Size(cp
->cl_bases
); 
1592         for (i 
= 0; i 
< n
; i
++) { 
1593             PyObject
* base 
= PyTuple_GetItem(cp
->cl_bases
, i
); 
1594             PyObject 
*v 
= PyFindClassWithAttr(base
, name
); 
1606 PyObject
* PyMethod_GetDefiningClass(PyObject
* method
, PyObject
* nameo
) 
1608     PyObject
* mgc 
= PyMethod_GET_CLASS(method
); 
1610 #if PYTHON_API_VERSION <= 1010    // prior to Python 2.2, the easy way 
1612 #else                             // 2.2 and after, the hard way... 
1613     return PyFindClassWithAttr(mgc
, nameo
); 
1619 // To avoid recursion when an overridden virtual method wants to call the base 
1620 // class version, temporarily set an attribute in the instance with the same 
1621 // name as the method.  Then the PyObject_GetAttr in the next findCallback 
1622 // will return this attribute and the PyMethod_Check will fail. 
1624 void wxPyCallbackHelper::setRecursionGuard(PyObject
* method
) const 
1626     PyFunctionObject
* func 
= (PyFunctionObject
*)PyMethod_Function(method
); 
1627     PyObject_SetAttr(m_self
, func
->func_name
, Py_None
); 
1630 void wxPyCallbackHelper::clearRecursionGuard(PyObject
* method
) const 
1632     PyFunctionObject
* func 
= (PyFunctionObject
*)PyMethod_Function(method
); 
1633     if (PyObject_HasAttr(m_self
, func
->func_name
)) { 
1634         PyObject_DelAttr(m_self
, func
->func_name
); 
1638 // bool wxPyCallbackHelper::hasRecursionGuard(PyObject* method) const 
1640 //     PyFunctionObject* func = (PyFunctionObject*)PyMethod_Function(method); 
1641 //     if (PyObject_HasAttr(m_self, func->func_name)) { 
1642 //         PyObject* attr = PyObject_GetAttr(m_self, func->func_name); 
1643 //         bool retval = (attr == Py_None); 
1651 bool wxPyCallbackHelper::findCallback(const char* name
, bool setGuard
) const { 
1652     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
1653     PyObject 
*method
, *klass
; 
1654     PyObject
* nameo 
= PyString_FromString(name
); 
1655     self
->m_lastFound 
= NULL
; 
1657     // If the object (m_self) has an attibute of the given name... 
1658     if (m_self 
&& PyObject_HasAttr(m_self
, nameo
)) { 
1659         method 
= PyObject_GetAttr(m_self
, nameo
); 
1661         // ...and if that attribute is a method, and if that method's class is 
1662         // not from the registered class or a base class... 
1663         if (PyMethod_Check(method
) && 
1664             (klass 
= PyMethod_GetDefiningClass(method
, nameo
)) != NULL 
&& 
1665             (klass 
!= m_class
) && 
1666             PyObject_IsSubclass(klass
, m_class
)) { 
1668             // ...then we'll save a pointer to the method so callCallback can 
1669             // call it.  But first, set a recursion guard in case the 
1670             // overridden method wants to call the base class version. 
1672                 setRecursionGuard(method
); 
1673             self
->m_lastFound 
= method
; 
1681     return m_lastFound 
!= NULL
; 
1685 int wxPyCallbackHelper::callCallback(PyObject
* argTuple
) const { 
1689     result 
= callCallbackObj(argTuple
); 
1690     if (result
) {                       // Assumes an integer return type... 
1691         retval 
= PyInt_AsLong(result
); 
1693         PyErr_Clear();                  // forget about it if it's not... 
1698 // Invoke the Python callable object, returning the raw PyObject return 
1699 // value.  Caller should DECREF the return value and also manage the GIL. 
1700 PyObject
* wxPyCallbackHelper::callCallbackObj(PyObject
* argTuple
) const { 
1703     // Save a copy of the pointer in case the callback generates another 
1704     // callback.  In that case m_lastFound will have a different value when 
1705     // it gets back here... 
1706     PyObject
* method 
= m_lastFound
; 
1708     result 
= PyEval_CallObject(method
, argTuple
); 
1709     clearRecursionGuard(method
); 
1711     Py_DECREF(argTuple
); 
1720 void wxPyCBH_setCallbackInfo(wxPyCallbackHelper
& cbh
, PyObject
* self
, PyObject
* klass
, int incref
) { 
1721     cbh
.setSelf(self
, klass
, incref
); 
1724 bool wxPyCBH_findCallback(const wxPyCallbackHelper
& cbh
, const char* name
, bool setGuard
) { 
1725     return cbh
.findCallback(name
, setGuard
); 
1728 int  wxPyCBH_callCallback(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1729     return cbh
.callCallback(argTuple
); 
1732 PyObject
* wxPyCBH_callCallbackObj(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1733     return cbh
.callCallbackObj(argTuple
); 
1737 void wxPyCBH_delete(wxPyCallbackHelper
* cbh
) { 
1738     if (cbh
->m_incRef 
&& Py_IsInitialized()) { 
1739         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1740         Py_XDECREF(cbh
->m_self
); 
1741         Py_XDECREF(cbh
->m_class
); 
1742         wxPyEndBlockThreads(blocked
); 
1746 //--------------------------------------------------------------------------- 
1747 //--------------------------------------------------------------------------- 
1748 // These event classes can be derived from in Python and passed through the event 
1749 // system without losing anything.  They do this by keeping a reference to 
1750 // themselves and some special case handling in wxPyCallback::EventThunker. 
1753 wxPyEvtSelfRef::wxPyEvtSelfRef() { 
1754     //m_self = Py_None;         // **** We don't do normal ref counting to prevent 
1755     //Py_INCREF(m_self);        //      circular loops... 
1759 wxPyEvtSelfRef::~wxPyEvtSelfRef() { 
1760     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1763     wxPyEndBlockThreads(blocked
); 
1766 void wxPyEvtSelfRef::SetSelf(PyObject
* self
, bool clone
) { 
1767     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1775     wxPyEndBlockThreads(blocked
); 
1778 PyObject
* wxPyEvtSelfRef::GetSelf() const { 
1784 IMPLEMENT_ABSTRACT_CLASS(wxPyEvent
, wxEvent
); 
1785 IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent
, wxCommandEvent
); 
1788 wxPyEvent::wxPyEvent(int winid
, wxEventType commandType
) 
1789     : wxEvent(winid
, commandType
) { 
1793 wxPyEvent::wxPyEvent(const wxPyEvent
& evt
) 
1796     SetSelf(evt
.m_self
, true); 
1800 wxPyEvent::~wxPyEvent() { 
1804 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType
, int id
) 
1805     : wxCommandEvent(commandType
, id
) { 
1809 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent
& evt
) 
1810     : wxCommandEvent(evt
) 
1812     SetSelf(evt
.m_self
, true); 
1816 wxPyCommandEvent::~wxPyCommandEvent() { 
1823 //--------------------------------------------------------------------------- 
1824 //--------------------------------------------------------------------------- 
1825 // Convert a wxList to a Python List, only works for lists of wxObjects 
1827 PyObject
* wxPy_ConvertList(wxListBase
* listbase
) { 
1828     wxList
*     list 
= (wxList
*)listbase
;  // this is probably bad... 
1832     wxNode
*     node 
= list
->GetFirst(); 
1834     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1835     pyList 
= PyList_New(0); 
1837         wxObj 
= node
->GetData(); 
1838         pyObj 
= wxPyMake_wxObject(wxObj
,false); 
1839         PyList_Append(pyList
, pyObj
); 
1840         Py_DECREF(pyObj
);  // the Append also does an INCREF, that's one more than we need. 
1841         node 
= node
->GetNext(); 
1843     wxPyEndBlockThreads(blocked
); 
1847 //---------------------------------------------------------------------- 
1849 long wxPyGetWinHandle(wxWindow
* win
) { 
1852     return (long)win
->GetHandle(); 
1855 #if defined(__WXGTK__) || defined(__WXX11) 
1856     return (long)GetXWindow(win
); 
1860     //return (long)MAC_WXHWND(win->MacGetTopLevelWindowRef()); 
1861     return (long)win
->GetHandle(); 
1867 //---------------------------------------------------------------------- 
1868 // Some helper functions for typemaps in my_typemaps.i, so they won't be 
1869 // included in every file over and over again... 
1871 wxString
* wxString_in_helper(PyObject
* source
) { 
1872     wxString
* target 
= NULL
; 
1874     if (!PyString_Check(source
) && !PyUnicode_Check(source
)) { 
1875         PyErr_SetString(PyExc_TypeError
, "String or Unicode type required"); 
1879     PyObject
* uni 
= source
; 
1880     if (PyString_Check(source
)) { 
1881         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
1882         if (PyErr_Occurred()) return NULL
; 
1884     target 
= new wxString(); 
1885     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1887         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, wxStringBuffer(*target
, len
), len
); 
1890     if (PyString_Check(source
)) 
1893     // Convert to a string object if it isn't already, then to wxString 
1894     PyObject
* str 
= source
; 
1895     if (PyUnicode_Check(source
)) { 
1896         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
1897         if (PyErr_Occurred()) return NULL
; 
1899     else if (!PyString_Check(source
)) { 
1900         str 
= PyObject_Str(source
); 
1901         if (PyErr_Occurred()) return NULL
; 
1903     char* tmpPtr
; Py_ssize_t tmpSize
; 
1904     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1905     target 
= new wxString(tmpPtr
, tmpSize
); 
1907     if (!PyString_Check(source
)) 
1909 #endif // wxUSE_UNICODE 
1915 // Similar to above except doesn't use "new" and doesn't set an exception 
1916 wxString 
Py2wxString(PyObject
* source
) 
1921     // Convert to a unicode object, if not already, then to a wxString 
1922     PyObject
* uni 
= source
; 
1923     if (!PyUnicode_Check(source
)) { 
1924         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
1925         if (PyErr_Occurred()) return wxEmptyString
;  // TODO:  should we PyErr_Clear? 
1927     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1929         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, wxStringBuffer(target
, len
), len
); 
1932     if (!PyUnicode_Check(source
)) 
1935     // Convert to a string object if it isn't already, then to wxString 
1936     PyObject
* str 
= source
; 
1937     if (PyUnicode_Check(source
)) { 
1938         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
1939         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
1941     else if (!PyString_Check(source
)) { 
1942         str 
= PyObject_Str(source
); 
1943         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
1945     char* tmpPtr
; Py_ssize_t tmpSize
; 
1946     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1947     target 
= wxString(tmpPtr
, tmpSize
); 
1949     if (!PyString_Check(source
)) 
1951 #endif // wxUSE_UNICODE 
1957 // Make either a Python String or Unicode object, depending on build mode 
1958 PyObject
* wx2PyString(const wxString
& src
) 
1962     str 
= PyUnicode_FromWideChar(src
.c_str(), src
.Len()); 
1964     str 
= PyString_FromStringAndSize(src
.c_str(), src
.Len()); 
1971 void wxSetDefaultPyEncoding(const char* encoding
) 
1973     strncpy(wxPyDefaultEncoding
, encoding
, DEFAULTENCODING_SIZE
); 
1976 const char* wxGetDefaultPyEncoding() 
1978     return wxPyDefaultEncoding
; 
1981 //---------------------------------------------------------------------- 
1984 byte
* byte_LIST_helper(PyObject
* source
) { 
1985     if (!PyList_Check(source
)) { 
1986         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
1989     int count 
= PyList_Size(source
); 
1990     byte
* temp 
= new byte
[count
]; 
1992         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
1995     for (int x
=0; x
<count
; x
++) { 
1996         PyObject
* o 
= PyList_GetItem(source
, x
); 
1997         if (! PyInt_Check(o
)) { 
1998             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2001         temp
[x
] = (byte
)PyInt_AsLong(o
); 
2007 int* int_LIST_helper(PyObject
* source
) { 
2008     if (!PyList_Check(source
)) { 
2009         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2012     int count 
= PyList_Size(source
); 
2013     int* temp 
= new int[count
]; 
2015         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2018     for (int x
=0; x
<count
; x
++) { 
2019         PyObject
* o 
= PyList_GetItem(source
, x
); 
2020         if (! PyInt_Check(o
)) { 
2021             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2024         temp
[x
] = PyInt_AsLong(o
); 
2030 long* long_LIST_helper(PyObject
* source
) { 
2031     if (!PyList_Check(source
)) { 
2032         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2035     int count 
= PyList_Size(source
); 
2036     long* temp 
= new long[count
]; 
2038         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2041     for (int x
=0; x
<count
; x
++) { 
2042         PyObject
* o 
= PyList_GetItem(source
, x
); 
2043         if (! PyInt_Check(o
)) { 
2044             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2047         temp
[x
] = PyInt_AsLong(o
); 
2053 char** string_LIST_helper(PyObject
* source
) { 
2054     if (!PyList_Check(source
)) { 
2055         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2058     int count 
= PyList_Size(source
); 
2059     char** temp 
= new char*[count
]; 
2061         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2064     for (int x
=0; x
<count
; x
++) { 
2065         PyObject
* o 
= PyList_GetItem(source
, x
); 
2066         if (! PyString_Check(o
)) { 
2067             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2070         temp
[x
] = PyString_AsString(o
); 
2075 //--------------------------------------------------------------------------- 
2076 // NOTE: The following functions could really use some refactoring using 
2077 // templates to make things somewhat simpler... 
2079 inline bool wxPointFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint
* point
) 
2082     if (PyInt_Check(o1
)) 
2083         point
->x 
= (int)PyInt_AS_LONG(o1
); 
2084     else if (PyFloat_Check(o1
)) 
2085         point
->x 
= (int)PyFloat_AS_DOUBLE(o1
); 
2086     else if (PyNumber_Check(o1
)) 
2087         point
->x 
= (int)PyInt_AsLong(o1
); 
2092     if (PyInt_Check(o2
)) 
2093         point
->y 
= (int)PyInt_AS_LONG(o2
); 
2094     else if (PyFloat_Check(o2
)) 
2095         point
->y 
= (int)PyFloat_AS_DOUBLE(o2
); 
2096     else if (PyNumber_Check(o2
)) 
2097         point
->y 
= (int)PyInt_AsLong(o2
); 
2103 // NOTE: This function used to have this code in it, but I don't know why it 
2104 // is a problem nor what havok it will cause, so removing for now... 
2105 //     if (wxPySwigInstance_Check(o1) || wxPySwigInstance_Check(o2)) {   
2106 //         // Disallow instances because they can cause havok 
2112 inline bool wxPoint2DFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint2D
* point
) 
2115     if (PyInt_Check(o1
)) 
2116         point
->m_x 
= (double)PyInt_AS_LONG(o1
); 
2117     else if (PyFloat_Check(o1
)) 
2118         point
->m_x 
= (double)PyFloat_AS_DOUBLE(o1
); 
2119     else if (PyNumber_Check(o1
)) 
2120         point
->m_x 
= (double)PyFloat_AsDouble(o1
); 
2125     if (PyInt_Check(o2
)) 
2126         point
->m_y 
= (double)PyInt_AS_LONG(o2
); 
2127     else if (PyFloat_Check(o2
)) 
2128         point
->m_y 
= (double)PyFloat_AS_DOUBLE(o2
); 
2129     else if (PyNumber_Check(o2
)) 
2130         point
->m_y 
= (double)PyFloat_AsDouble(o2
); 
2139 wxPoint
* wxPoint_LIST_helper(PyObject
* source
, int *count
) 
2143     PyObject 
*o
, *o1
, *o2
; 
2144     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2146     if (!PySequence_Check(source
)) { 
2150     // The length of the sequence is returned in count. 
2151     *count 
= PySequence_Length(source
); 
2156     temp 
= new wxPoint
[*count
]; 
2158         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2161     for (idx
=0; idx
<*count
; idx
++) { 
2162         // Get an item: try fast way first. 
2164             o 
= PySequence_Fast_GET_ITEM(source
, idx
); 
2167             o 
= PySequence_GetItem(source
, idx
); 
2173         // Convert o to wxPoint. 
2174         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2175             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2176             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2177             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2178             if (!wxPointFromObjects(o1
, o2
, &temp
[idx
])) { 
2182         else if (wxPySwigInstance_Check(o
)) { 
2184             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint"))) { 
2189         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2190             o1 
= PySequence_GetItem(o
, 0); 
2191             o2 
= PySequence_GetItem(o
, 1); 
2192             if (!wxPointFromObjects(o1
, o2
, &temp
[idx
])) { 
2216     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoints."); 
2222 wxPoint2D
* wxPoint2D_LIST_helper(PyObject
* source
, size_t *count
) 
2226     PyObject 
*o
, *o1
, *o2
; 
2227     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2229     if (!PySequence_Check(source
)) { 
2233     // The length of the sequence is returned in count. 
2234     *count 
= PySequence_Length(source
); 
2239     temp 
= new wxPoint2D
[*count
]; 
2241         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2244     for (idx
=0; idx
<*count
; idx
++) { 
2245         // Get an item: try fast way first. 
2247             o 
= PySequence_Fast_GET_ITEM(source
, idx
); 
2250             o 
= PySequence_GetItem(source
, idx
); 
2256         // Convert o to wxPoint. 
2257         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2258             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2259             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2260             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2261             if (!wxPoint2DFromObjects(o1
, o2
, &temp
[idx
])) { 
2265         else if (wxPySwigInstance_Check(o
)) { 
2267             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint2D"))) { 
2272         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2273             o1 
= PySequence_GetItem(o
, 0); 
2274             o2 
= PySequence_GetItem(o
, 1); 
2275             if (!wxPoint2DFromObjects(o1
, o2
, &temp
[idx
])) { 
2299     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoint2Ds."); 
2303 //--------------------------------------------------------------------------- 
2306 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) { 
2307     if (!PyList_Check(source
)) { 
2308         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2311     int count 
= PyList_Size(source
); 
2312     wxBitmap
** temp 
= new wxBitmap
*[count
]; 
2314         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2317     for (int x
=0; x
<count
; x
++) { 
2318         PyObject
* o 
= PyList_GetItem(source
, x
); 
2319         if (wxPySwigInstance_Check(o
)) { 
2321             if (! wxPyConvertSwigPtr(o
, (void **) &pt
, wxT("wxBitmap"))) { 
2322                 PyErr_SetString(PyExc_TypeError
,"Expected wxBitmap."); 
2328             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps."); 
2337 wxString
* wxString_LIST_helper(PyObject
* source
) { 
2338     if (!PyList_Check(source
)) { 
2339         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2342     int count 
= PyList_Size(source
); 
2343     wxString
* temp 
= new wxString
[count
]; 
2345         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2348     for (int x
=0; x
<count
; x
++) { 
2349         PyObject
* o 
= PyList_GetItem(source
, x
); 
2350 #if PYTHON_API_VERSION >= 1009 
2351         if (! PyString_Check(o
) && ! PyUnicode_Check(o
)) { 
2352             PyErr_SetString(PyExc_TypeError
, "Expected a list of string or unicode objects."); 
2356         if (! PyString_Check(o
)) { 
2357             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2362         wxString
* pStr 
= wxString_in_helper(o
); 
2370 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) { 
2371     if (!PyList_Check(source
)) { 
2372         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2375     int count                
= PyList_Size(source
); 
2376     wxAcceleratorEntry
* temp 
= new wxAcceleratorEntry
[count
]; 
2378         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2381     for (int x
=0; x
<count
; x
++) { 
2382         PyObject
* o 
= PyList_GetItem(source
, x
); 
2383         if (wxPySwigInstance_Check(o
)) { 
2384             wxAcceleratorEntry
* ae
; 
2385             if (! wxPyConvertSwigPtr(o
, (void **) &ae
, wxT("wxAcceleratorEntry"))) { 
2386                 PyErr_SetString(PyExc_TypeError
,"Expected wxAcceleratorEntry."); 
2391         else if (PyTuple_Check(o
)) { 
2392             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
2393             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
2394             PyObject
* o3 
= PyTuple_GetItem(o
, 2); 
2395             temp
[x
].Set(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2398             PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects."); 
2406 wxPen
** wxPen_LIST_helper(PyObject
* source
) { 
2407     if (!PyList_Check(source
)) { 
2408         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2411     int count 
= PyList_Size(source
); 
2412     wxPen
** temp 
= new wxPen
*[count
]; 
2414         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2417     for (int x
=0; x
<count
; x
++) { 
2418         PyObject
* o 
= PyList_GetItem(source
, x
); 
2419         if (wxPySwigInstance_Check(o
)) { 
2421             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPen"))) { 
2423                 PyErr_SetString(PyExc_TypeError
,"Expected wxPen."); 
2430             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxPens."); 
2438 bool wxPy2int_seq_helper(PyObject
* source
, int* i1
, int* i2
) { 
2439     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2442     if (!PySequence_Check(source
) || PySequence_Length(source
) != 2) 
2446         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2447         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2450         o1 
= PySequence_GetItem(source
, 0); 
2451         o2 
= PySequence_GetItem(source
, 1); 
2454     *i1 
= PyInt_AsLong(o1
); 
2455     *i2 
= PyInt_AsLong(o2
); 
2465 bool wxPy4int_seq_helper(PyObject
* source
, int* i1
, int* i2
, int* i3
, int* i4
) { 
2466     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2467     PyObject 
*o1
, *o2
, *o3
, *o4
; 
2469     if (!PySequence_Check(source
) || PySequence_Length(source
) != 4) 
2473         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2474         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2475         o3 
= PySequence_Fast_GET_ITEM(source
, 2); 
2476         o4 
= PySequence_Fast_GET_ITEM(source
, 3); 
2479         o1 
= PySequence_GetItem(source
, 0); 
2480         o2 
= PySequence_GetItem(source
, 1); 
2481         o3 
= PySequence_GetItem(source
, 2); 
2482         o4 
= PySequence_GetItem(source
, 3); 
2485     *i1 
= PyInt_AsLong(o1
); 
2486     *i2 
= PyInt_AsLong(o2
); 
2487     *i3 
= PyInt_AsLong(o3
); 
2488     *i4 
= PyInt_AsLong(o4
); 
2500 //---------------------------------------------------------------------- 
2502 bool wxPySimple_typecheck(PyObject
* source
, const wxChar
* classname
, int seqLen
) 
2506     if (wxPySwigInstance_Check(source
) && 
2507         wxPyConvertSwigPtr(source
, (void **)&ptr
, classname
)) 
2511     if (PySequence_Check(source
) && PySequence_Length(source
) == seqLen
) 
2517 bool wxSize_helper(PyObject
* source
, wxSize
** obj
) 
2519     if (source 
== Py_None
) { 
2520         **obj 
= wxSize(-1,-1); 
2523     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxSize")); 
2527 bool wxPoint_helper(PyObject
* source
, wxPoint
** obj
) 
2529     if (source 
== Py_None
) { 
2530         **obj 
= wxPoint(-1,-1); 
2533     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxPoint")); 
2538 bool wxPosition_helper(PyObject
* source
, wxPosition
** obj
) 
2540     if (source 
== Py_None
) { 
2541         **obj 
= wxPosition(-1,-1); 
2544     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxPosition")); 
2549 bool wxRealPoint_helper(PyObject
* source
, wxRealPoint
** obj
) { 
2551     if (source 
== Py_None
) { 
2552         **obj 
= wxRealPoint(-1,-1); 
2556     // If source is an object instance then it may already be the right type 
2557     if (wxPySwigInstance_Check(source
)) { 
2559         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRealPoint"))) 
2564     // otherwise a 2-tuple of floats is expected 
2565     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
2566         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2567         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2568         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2573         **obj 
= wxRealPoint(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2580     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxRealPoint object."); 
2586 bool wxRect_helper(PyObject
* source
, wxRect
** obj
) { 
2588     if (source 
== Py_None
) { 
2589         **obj 
= wxRect(-1,-1,-1,-1); 
2593     // If source is an object instance then it may already be the right type 
2594     if (wxPySwigInstance_Check(source
)) { 
2596         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect"))) 
2601     // otherwise a 4-tuple of integers is expected 
2602     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2603         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2604         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2605         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2606         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2607         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2608             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2615         **obj 
= wxRect(PyInt_AsLong(o1
), PyInt_AsLong(o2
), 
2616                        PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2625     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of integers or a wxRect object."); 
2631 bool wxColour_helper(PyObject
* source
, wxColour
** obj
) { 
2633     if (source 
== Py_None
) { 
2634         **obj 
= wxNullColour
; 
2638     // If source is an object instance then it may already be the right type 
2639     if (wxPySwigInstance_Check(source
)) { 
2641         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxColour"))) 
2646     // otherwise check for a string 
2647     else if (PyString_Check(source
) || PyUnicode_Check(source
)) { 
2648         wxString spec 
= Py2wxString(source
); 
2649         if (spec
.GetChar(0) == '#' && spec
.Length() == 7) {  // It's  #RRGGBB 
2650             long red
, green
, blue
; 
2651             red 
= green 
= blue 
= 0; 
2652             spec
.Mid(1,2).ToLong(&red
,   16); 
2653             spec
.Mid(3,2).ToLong(&green
, 16); 
2654             spec
.Mid(5,2).ToLong(&blue
,  16); 
2656             **obj 
= wxColour(red
, green
, blue
); 
2659         else {                                       // it's a colour name 
2660             **obj 
= wxColour(spec
); 
2664     // last chance: 3-tuple or 4-tuple of integers is expected 
2665     else if (PySequence_Check(source
) && PyObject_Length(source
) == 3) { 
2666         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2667         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2668         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2669         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
)) { 
2675         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2681     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2682         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2683         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2684         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2685         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2686         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2693         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2702     PyErr_SetString(PyExc_TypeError
, 
2703                     "Expected a wxColour object, a string containing a colour name or '#RRGGBB', or a 3- or 4-tuple of integers."); 
2708 bool wxColour_typecheck(PyObject
* source
) { 
2710     if (wxPySimple_typecheck(source
, wxT("wxColour"), 3)) 
2713     if (PyString_Check(source
) || PyUnicode_Check(source
)) 
2721 bool wxPoint2D_helper(PyObject
* source
, wxPoint2D
** obj
) { 
2723     if (source 
== Py_None
) { 
2724         **obj 
= wxPoint2D(-1,-1); 
2728     // If source is an object instance then it may already be the right type 
2729     if (wxPySwigInstance_Check(source
)) { 
2731         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxPoint2D"))) 
2736     // otherwise a length-2 sequence of floats is expected 
2737     if (PySequence_Check(source
) && PySequence_Length(source
) == 2) { 
2738         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2739         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2740         // This should really check for floats, not numbers -- but that would break code. 
2741         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2746         **obj 
= wxPoint2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2752     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wx.Point2D object."); 
2758 bool wxRect2D_helper(PyObject
* source
, wxRect2D
** obj
) { 
2760     if (source 
== Py_None
) { 
2761         **obj 
= wxRect2D(-1,-1,-1,-1); 
2765     // If source is an object instance then it may already be the right type 
2766     if (wxPySwigInstance_Check(source
)) { 
2768         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect2D"))) 
2773     // otherwise a length-4 sequence of floats is expected 
2774     if (PySequence_Check(source
) && PySequence_Length(source
) == 4) { 
2775         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2776         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2777         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2778         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2779         // This should really check for floats, not numbers -- but that would break code. 
2780         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2781             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2788         **obj 
= wxRect2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
), 
2789                          PyFloat_AsDouble(o3
), PyFloat_AsDouble(o4
)); 
2797     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of floats or a wx.Rect2D object."); 
2802 //---------------------------------------------------------------------- 
2804 PyObject
* wxArrayString2PyList_helper(const wxArrayString
& arr
) 
2806     PyObject
* list 
= PyList_New(0); 
2807     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2809         PyObject
* str 
= PyUnicode_FromWideChar(arr
[i
].c_str(), arr
[i
].Len()); 
2811         PyObject
* str 
= PyString_FromStringAndSize(arr
[i
].c_str(), arr
[i
].Len()); 
2813         PyList_Append(list
, str
); 
2820 PyObject
* wxArrayInt2PyList_helper(const wxArrayInt
& arr
) 
2822     PyObject
* list 
= PyList_New(0); 
2823     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2824         PyObject
* number 
= PyInt_FromLong(arr
[i
]); 
2825         PyList_Append(list
, number
); 
2832 PyObject
* wxArrayDouble2PyList_helper(const wxArrayDouble
& arr
) 
2834     PyObject
* list 
= PyList_New(0); 
2835     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2836         PyObject
* number 
= PyFloat_FromDouble(arr
[i
]); 
2837         PyList_Append(list
, number
); 
2844 //---------------------------------------------------------------------- 
2845 // wxPyImageHandler methods 
2847 // TODO: Switch these to use wxPython's standard macros and helper classes 
2848 //       for calling callbacks. 
2850 PyObject
* wxPyImageHandler::m_DoCanRead_Name 
= NULL
; 
2851 PyObject
* wxPyImageHandler::m_GetImageCount_Name 
= NULL
; 
2852 PyObject
* wxPyImageHandler::m_LoadFile_Name 
= NULL
; 
2853 PyObject
* wxPyImageHandler::m_SaveFile_Name 
= NULL
; 
2855 PyObject
* wxPyImageHandler::py_InputStream(wxInputStream
* stream
) { 
2856     return wxPyConstructObject(new wxPyInputStream(stream
), 
2857                                wxT("wxPyInputStream"), 0); 
2860 PyObject
* wxPyImageHandler::py_Image(wxImage
* image
) { 
2861     return wxPyConstructObject(image
, wxT("wxImage"), 0); 
2864 PyObject
* wxPyImageHandler::py_OutputStream(wxOutputStream
* stream
) { 
2865     return wxPyConstructObject(stream
, wxT("wxOutputStream"), 0); 
2868 wxPyImageHandler::wxPyImageHandler(): 
2871     if (!m_DoCanRead_Name
) { 
2872         m_DoCanRead_Name 
= PyString_FromString("DoCanRead"); 
2873         m_GetImageCount_Name 
= PyString_FromString("GetImageCount"); 
2874         m_LoadFile_Name 
= PyString_FromString("LoadFile"); 
2875         m_SaveFile_Name 
= PyString_FromString("SaveFile"); 
2879 wxPyImageHandler::~wxPyImageHandler() { 
2886 void wxPyImageHandler::_SetSelf(PyObject 
*self
) { 
2887     // should check here for isinstance(PyImageHandler) ?? 
2892 bool wxPyImageHandler::DoCanRead(wxInputStream
& stream
) { 
2893     // check if our object has this method 
2894     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2895     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_DoCanRead_Name
)) { 
2896         wxPyEndBlockThreads(blocked
); 
2900     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_DoCanRead_Name
, 
2901                                                py_InputStream(&stream
), NULL
); 
2902     bool retval 
= false; 
2904         retval 
= PyInt_AsLong(res
); 
2910     wxPyEndBlockThreads(blocked
); 
2914 bool wxPyImageHandler::LoadFile( wxImage
* image
, wxInputStream
& stream
, 
2915                                  bool verbose
, int index 
) { 
2916     // check if our object has this method 
2917     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2918     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_LoadFile_Name
)) { 
2919         wxPyEndBlockThreads(blocked
); 
2922     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_LoadFile_Name
, 
2924                                                py_InputStream(&stream
), 
2925                                                PyInt_FromLong(verbose
), 
2926                                                PyInt_FromLong(index
), 
2928     bool retval 
= false; 
2930         retval 
= PyInt_AsLong(res
); 
2935     wxPyEndBlockThreads(blocked
); 
2939 bool wxPyImageHandler::SaveFile( wxImage
* image
, wxOutputStream
& stream
, 
2941     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2942     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_SaveFile_Name
)) { 
2943         wxPyEndBlockThreads(blocked
); 
2946     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_SaveFile_Name
, 
2948                                                py_OutputStream(&stream
), 
2949                                                PyInt_FromLong(verbose
), 
2951     bool retval 
= false; 
2953         retval
=PyInt_AsLong(res
); 
2958     wxPyEndBlockThreads(blocked
); 
2962 int wxPyImageHandler::GetImageCount( wxInputStream
& stream 
) { 
2963     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2964     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_GetImageCount_Name
)) { 
2965         wxPyEndBlockThreads(blocked
); 
2968     PyObject 
*res
=PyObject_CallMethodObjArgs(m_self
, m_GetImageCount_Name
, 
2969                                              py_InputStream(&stream
), 
2973         retval
=PyInt_AsLong(res
); 
2978     wxPyEndBlockThreads(blocked
); 
2983 //---------------------------------------------------------------------- 
2984 // Function to test if the Display (or whatever is the platform equivallent) 
2985 // can be connected to.  This is accessable from wxPython as a staticmethod of 
2986 // wx.App called DisplayAvailable(). 
2989 bool wxPyTestDisplayAvailable() 
2993     display 
= XOpenDisplay(NULL
); 
2994     if (display 
== NULL
) 
2996     XCloseDisplay(display
); 
3001     // This is adapted from Python's Mac/Modules/MacOS.c in the 
3002     // MacOS_WMAvailable function. 
3004     ProcessSerialNumber psn
; 
3007     ** This is a fairly innocuous call to make if we don't have a window 
3008     ** manager, or if we have no permission to talk to it. It will print 
3009     ** a message on stderr, but at least it won't abort the process. 
3010     ** It appears the function caches the result itself, and it's cheap, so 
3011     ** no need for us to cache. 
3013 #ifdef kCGNullDirectDisplay 
3014     /* On 10.1 CGMainDisplayID() isn't available, and 
3015     ** kCGNullDirectDisplay isn't defined. 
3017     if (CGMainDisplayID() == 0) { 
3022         // Also foreground the application on the first call as a side-effect. 
3023         if (GetCurrentProcess(&psn
) < 0 || SetFrontProcess(&psn
) < 0) { 
3039 //---------------------------------------------------------------------- 
3040 //----------------------------------------------------------------------