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::MacPrintFile(const wxString 
&fileName
) 
 302     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 303     if (wxPyCBH_findCallback(m_myInst
, "MacPrintFile")) { 
 304         PyObject
* s 
= wx2PyString(fileName
); 
 305         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 308     wxPyEndBlockThreads(blocked
); 
 311 void wxPyApp::MacNewFile() 
 313     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 314     if (wxPyCBH_findCallback(m_myInst
, "MacNewFile")) 
 315         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 316     wxPyEndBlockThreads(blocked
); 
 319 void wxPyApp::MacReopenApp() 
 321     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 322     if (wxPyCBH_findCallback(m_myInst
, "MacReopenApp")) 
 323         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 324     wxPyEndBlockThreads(blocked
); 
 329 bool wxPyApp::GetMacSupportPCMenuShortcuts() { 
 334 long wxPyApp::GetMacAboutMenuItemId() { 
 336     return s_macAboutMenuItemId
; 
 343 long wxPyApp::GetMacPreferencesMenuItemId() { 
 345     return s_macPreferencesMenuItemId
; 
 352 long wxPyApp::GetMacExitMenuItemId() { 
 354     return s_macExitMenuItemId
; 
 361 wxString 
wxPyApp::GetMacHelpMenuTitleName() { 
 363     return s_macHelpMenuTitleName
; 
 365     return wxEmptyString
; 
 370 void wxPyApp::SetMacSupportPCMenuShortcuts(bool) { 
 374 void wxPyApp::SetMacAboutMenuItemId(long val
) { 
 376     s_macAboutMenuItemId 
= val
; 
 381 void wxPyApp::SetMacPreferencesMenuItemId(long val
) { 
 383     s_macPreferencesMenuItemId 
= val
; 
 388 void wxPyApp::SetMacExitMenuItemId(long val
) { 
 390     s_macExitMenuItemId 
= val
; 
 395 void wxPyApp::SetMacHelpMenuTitleName(const wxString
& val
) { 
 397     s_macHelpMenuTitleName 
= val
; 
 402 // This finishes the initialization of wxWindows and then calls the OnInit 
 403 // that should be present in the derived (Python) class. 
 404 void wxPyApp::_BootstrapApp() 
 406     static      bool haveInitialized 
= false; 
 409     PyObject
*   retval 
= NULL
; 
 410     PyObject
*   pyint  
= NULL
; 
 413     // Only initialize wxWidgets once 
 414     if (! haveInitialized
) { 
 416         // Get any command-line args passed to this program from the sys module 
 419         blocked 
= wxPyBeginBlockThreads(); 
 421         PyObject
* sysargv 
= PySys_GetObject("argv"); 
 422         PyObject
* executable 
= PySys_GetObject("executable"); 
 424         if (sysargv 
!= NULL 
&& executable 
!= NULL
) { 
 425             argc 
= PyList_Size(sysargv
) + 1; 
 426             argv 
= new char*[argc
+1]; 
 427             argv
[0] = strdup(PyString_AsString(executable
)); 
 429             for(x
=1; x
<argc
; x
++) { 
 430                 PyObject 
*pyArg 
= PyList_GetItem(sysargv
, x
-1); 
 431                 argv
[x
] = strdup(PyString_AsString(pyArg
)); 
 435         wxPyEndBlockThreads(blocked
); 
 437         // Initialize wxWidgets 
 438         result 
= wxEntryStart(argc
, argv
); 
 439         // wxApp takes ownership of the argv array, don't delete it here 
 441         blocked 
= wxPyBeginBlockThreads(); 
 443             PyErr_SetString(PyExc_SystemError
, 
 444                             "wxEntryStart failed, unable to initialize wxWidgets!" 
 446                             "  (Is DISPLAY set properly?)" 
 452         // On wxGTK the locale will be changed to match the system settings, 
 453         // but Python before 2.4 needs to have LC_NUMERIC set to "C" in order 
 454         // for the floating point conversions and such to work right. 
 455 #if defined(__WXGTK__) && PY_VERSION_HEX < 0x02040000 
 456         setlocale(LC_NUMERIC
, "C"); 
 459 //        wxSystemOptions::SetOption(wxT("mac.textcontrol-use-mlte"), 1); 
 461         wxPyEndBlockThreads(blocked
); 
 462         haveInitialized 
= true; 
 470     // It's now ok to generate exceptions for assertion errors. 
 471     wxPythonApp
->SetStartupComplete(true); 
 474     // Call the Python wxApp's OnPreInit and OnInit functions 
 475     blocked 
= wxPyBeginBlockThreads(); 
 476     if (wxPyCBH_findCallback(m_myInst
, "OnPreInit")) { 
 477         PyObject
* method 
= m_myInst
.GetLastFound(); 
 478         PyObject
* argTuple 
= PyTuple_New(0); 
 479         retval 
= PyEval_CallObject(method
, argTuple
); 
 480         m_myInst
.clearRecursionGuard(method
); 
 486     if (wxPyCBH_findCallback(m_myInst
, "OnInit")) { 
 488         PyObject
* method 
= m_myInst
.GetLastFound(); 
 489         PyObject
* argTuple 
= PyTuple_New(0); 
 490         retval 
= PyEval_CallObject(method
, argTuple
); 
 491         m_myInst
.clearRecursionGuard(method
); 
 495             // Don't PyErr_Print here, let the exception in this case go back 
 496             // up to the wx.PyApp.__init__ scope. 
 499         pyint 
= PyNumber_Int(retval
); 
 501             PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value"); 
 504         result 
= PyInt_AS_LONG(pyint
); 
 507         // Is it okay if there is no OnInit?  Probably so... 
 512         PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting..."); 
 519     wxPyEndBlockThreads(blocked
); 
 522 //--------------------------------------------------------------------- 
 523 //---------------------------------------------------------------------- 
 527 static char* wxPyCopyCString(const wxChar
* src
) 
 529     wxWX2MBbuf buff 
= (wxWX2MBbuf
)wxConvCurrent
->cWX2MB(src
); 
 530     size_t len 
= strlen(buff
); 
 531     char*  dest 
= new char[len
+1]; 
 537 static char* wxPyCopyCString(const char* src
)   // we need a char version too 
 539     size_t len 
= strlen(src
); 
 540     char*  dest 
= new char[len
+1]; 
 546 static wxChar
* wxPyCopyWString(const char *src
) 
 548     //wxMB2WXbuf buff = wxConvCurrent->cMB2WX(src); 
 549     wxString 
str(src
, *wxConvCurrent
); 
 550     return copystring(str
); 
 554 static wxChar
* wxPyCopyWString(const wxChar 
*src
) 
 556     return copystring(src
); 
 562 inline const char* dropwx(const char* name
) { 
 563     if (name
[0] == 'w' && name
[1] == 'x') 
 569 //---------------------------------------------------------------------- 
 571 // This function is called when the wx._core_ module is imported to do some 
 572 // initial setup.  (Before there is a wxApp object.)  The rest happens in 
 573 // wxPyApp::_BootstrapApp 
 574 void __wxPyPreStart(PyObject
* moduleDict
) 
 578 //     wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF 
 579 //                     | _CRTDBG_CHECK_ALWAYS_DF 
 580 //                     | _CRTDBG_DELAY_FREE_MEM_DF 
 584 #ifdef WXP_WITH_THREAD 
 585 #if wxPyUSE_GIL_STATE 
 586     PyEval_InitThreads(); 
 588     PyEval_InitThreads(); 
 589     wxPyTStates 
= new wxPyThreadStateArray
; 
 590     wxPyTMutex 
= new wxMutex
; 
 592     // Save the current (main) thread state in our array 
 593     PyThreadState
* tstate 
= wxPyBeginAllowThreads(); 
 594     wxPyEndAllowThreads(tstate
); 
 598     // Ensure that the build options in the DLL (or whatever) match this build 
 599     wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE
, "wxPython"); 
 601     wxInitAllImageHandlers(); 
 606 void __wxPyCleanup() { 
 607     wxPyDoingCleanup 
= true; 
 609         wxPyDoCleanup 
= false; 
 612 #ifdef WXP_WITH_THREAD 
 613 #if !wxPyUSE_GIL_STATE 
 616     wxPyTStates
->Empty(); 
 624 // Save a reference to the dictionary of the wx._core module, and inject 
 625 // a few more things into it. 
 626 PyObject
* __wxPySetDictionary(PyObject
* /* self */, PyObject
* args
) 
 629     if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
)) 
 632     if (!PyDict_Check(wxPython_dict
)) { 
 633         PyErr_SetString(PyExc_TypeError
, 
 634                         "_wxPySetDictionary must have dictionary object!"); 
 638     if (! wxPyPtrTypeMap
) 
 639         wxPyPtrTypeMap 
= PyDict_New(); 
 640     PyDict_SetItemString(wxPython_dict
, "__wxPyPtrTypeMap", wxPyPtrTypeMap
); 
 642     // Create an exception object to use for wxASSERTions 
 643     wxPyAssertionError 
= PyErr_NewException("wx._core.PyAssertionError", 
 644                                             PyExc_AssertionError
, NULL
); 
 645     PyDict_SetItemString(wxPython_dict
, "PyAssertionError", wxPyAssertionError
); 
 647     // Create an exception object to use when the app object hasn't been created yet 
 648     wxPyNoAppError 
= PyErr_NewException("wx._core.PyNoAppError", 
 649                                         PyExc_RuntimeError
, NULL
); 
 650     PyDict_SetItemString(wxPython_dict
, "PyNoAppError", wxPyNoAppError
); 
 655 #define wxPlatform "__WXMOTIF__" 
 656 #define wxPlatName "wxMotif" 
 659 #define wxPlatform "__WXX11__" 
 660 #define wxPlatName "wxX11" 
 663 #define wxPlatform "__WXGTK__" 
 664 #define wxPlatName "wxGTK" 
 667 #define wxPlatform "__WXMSW__" 
 668 #define wxPlatName "wxMSW" 
 671 #define wxPlatform "__WXMAC__" 
 672 #define wxPlatName "wxMac" 
 681     // These should be deprecated in favor of the PlatformInfo tuple built below... 
 682     PyDict_SetItemString(wxPython_dict
, "Platform", PyString_FromString(wxPlatform
)); 
 683     PyDict_SetItemString(wxPython_dict
, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE
)); 
 684     PyDict_SetItemString(wxPython_dict
, "__WXDEBUG__", PyInt_FromLong(wxdebug
)); 
 686     // Make a tuple of strings that gives more info about the platform. 
 687     PyObject
* PlatInfo 
= PyList_New(0); 
 690 #define _AddInfoString(st) \ 
 691     obj = PyString_FromString(st); \ 
 692     PyList_Append(PlatInfo, obj); \ 
 695     _AddInfoString(wxPlatform
); 
 696     _AddInfoString(wxPlatName
); 
 698     _AddInfoString("unicode"); 
 700     _AddInfoString("ansi"); 
 704     _AddInfoString("gtk2"); 
 706     _AddInfoString("gtk1"); 
 710     _AddInfoString("wx-assertions-on"); 
 712     _AddInfoString("wx-assertions-off"); 
 714     _AddInfoString(wxPy_SWIG_VERSION
);     
 716     #if wxMAC_USE_CORE_GRAPHICS 
 717         _AddInfoString("mac-cg"); 
 719         _AddInfoString("mac-qd"); 
 721     #if wxMAC_USE_NATIVE_TOOLBAR 
 722         _AddInfoString("mac-native-tb"); 
 724         _AddInfoString("mac-no-native-tb"); 
 728 #undef _AddInfoString 
 730     PyObject
* PlatInfoTuple 
= PyList_AsTuple(PlatInfo
); 
 732     PyDict_SetItemString(wxPython_dict
, "PlatformInfo", PlatInfoTuple
); 
 739 //--------------------------------------------------------------------------- 
 741 // Check for existence of a wxApp, setting an exception if there isn't one. 
 742 // This doesn't need to aquire the GIL because it should only be called from 
 743 // an %exception before the lock is released. 
 745 bool wxPyCheckForApp() { 
 746     if (wxTheApp 
!= NULL
) 
 749         PyErr_SetString(wxPyNoAppError
, "The wx.App object must be created first!"); 
 754 //--------------------------------------------------------------------------- 
 756 void wxPyUserData_dtor(wxPyUserData
* self
) { 
 757     if (! wxPyDoingCleanup
) { 
 758         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 759         Py_DECREF(self
->m_obj
); 
 761         wxPyEndBlockThreads(blocked
); 
 766 void wxPyClientData_dtor(wxPyClientData
* self
) { 
 767     if (! wxPyDoingCleanup
) {           // Don't do it during cleanup as Python 
 768                                         // may have already garbage collected the object... 
 769         if (self
->m_incRef
) { 
 770             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 771             Py_DECREF(self
->m_obj
); 
 772             wxPyEndBlockThreads(blocked
); 
 780 // This is called when an OOR controled object is being destroyed.  Although 
 781 // the C++ object is going away there is no way to force the Python object 
 782 // (and all references to it) to die too.  This causes problems (crashes) in 
 783 // wxPython when a python shadow object attempts to call a C++ method using 
 784 // the now bogus pointer... So to try and prevent this we'll do a little black 
 785 // magic and change the class of the python instance to a class that will 
 786 // raise an exception for any attempt to call methods with it.  See 
 787 // _wxPyDeadObject in _core_ex.py for the implementation of this class. 
 788 void wxPyOORClientData_dtor(wxPyOORClientData
* self
) { 
 790     static PyObject
* deadObjectClass 
= NULL
; 
 792     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 793     if (deadObjectClass 
== NULL
) { 
 794         deadObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyDeadObject"); 
 795         // TODO:  Can not wxASSERT here because inside a wxPyBeginBlock Threads, 
 796         // will lead to a deadlock when it tries to aquire the GIL again. 
 797         //wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!")); 
 798         Py_INCREF(deadObjectClass
); 
 802     // Only if there is more than one reference to the object and we are 
 803     // holding the OOR reference: 
 804     if ( !wxPyDoingCleanup 
&& self
->m_obj
->ob_refcnt 
> 1 && self
->m_incRef
) { 
 805         // bool isInstance = wxPyInstance_Check(self->m_obj); 
 807         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!")); 
 809         // Call __del__, if there is one. 
 810         PyObject
* func 
= PyObject_GetAttrString(self
->m_obj
, "__del__"); 
 812             PyObject
* rv 
= PyObject_CallMethod(self
->m_obj
, "__del__", NULL
); 
 816         if (PyErr_Occurred()) 
 817             PyErr_Clear();      // just ignore it for now 
 820         PyObject
* dict 
= PyObject_GetAttrString(self
->m_obj
, "__dict__"); 
 822             // Clear the instance's dictionary 
 825             // put the name of the old class into the instance, and then reset the 
 826             // class to be the dead class. 
 827             PyObject
* klass 
= PyObject_GetAttrString(self
->m_obj
, "__class__"); 
 828             PyObject
* name 
=  PyObject_GetAttrString(klass
, "__name__"); 
 829             PyDict_SetItemString(dict
, "_name", name
); 
 830             PyObject_SetAttrString(self
->m_obj
, "__class__",  deadObjectClass
); 
 831             //Py_INCREF(deadObjectClass); 
 837     // m_obj is DECREF'd in the base class dtor... 
 838     wxPyEndBlockThreads(blocked
); 
 842 //--------------------------------------------------------------------------- 
 843 // Stuff used by OOR to find the right wxPython class type to return and to 
 847 // The pointer type map is used when the "pointer" type name generated by SWIG 
 848 // is not the same as the shadow class name, for example wxPyTreeCtrl 
 849 // vs. wxTreeCtrl.  It needs to be referenced in Python as well as from C++, 
 850 // so we'll just make it a Python dictionary in the wx module's namespace. 
 851 // (See __wxSetDictionary) 
 852 void wxPyPtrTypeMap_Add(const char* commonName
, const char* ptrName
) { 
 853     if (! wxPyPtrTypeMap
) 
 854         wxPyPtrTypeMap 
= PyDict_New(); 
 855     PyDict_SetItemString(wxPyPtrTypeMap
, 
 857                          PyString_FromString((char*)ptrName
)); 
 863 PyObject
*  wxPyMake_wxObject(wxObject
* source
, bool setThisOwn
, bool checkEvtHandler
) { 
 864     PyObject
* target 
= NULL
; 
 865     bool      isEvtHandler 
= false; 
 866     bool      isSizer 
= false; 
 869         // If it's derived from wxEvtHandler then there may 
 870         // already be a pointer to a Python object that we can use 
 872         if (checkEvtHandler 
&& wxIsKindOf(source
, wxEvtHandler
)) { 
 874             wxEvtHandler
* eh 
= (wxEvtHandler
*)source
; 
 875             wxPyOORClientData
* data 
= (wxPyOORClientData
*)eh
->GetClientObject(); 
 877                 target 
= data
->m_obj
; 
 883         // Also check for wxSizer 
 884         if (!target 
&& wxIsKindOf(source
, wxSizer
)) { 
 886             wxSizer
* sz 
= (wxSizer
*)source
; 
 887             wxPyOORClientData
* data 
= (wxPyOORClientData
*)sz
->GetClientObject(); 
 889                 target 
= data
->m_obj
; 
 896             // Otherwise make it the old fashioned way by making a new shadow 
 897             // object and putting this pointer in it.  Look up the class 
 898             // heirarchy until we find a class name that is located in the 
 900             const wxClassInfo
* info   
= source
->GetClassInfo(); 
 901             wxString           name   
= info
->GetClassName(); 
 902             bool               exists 
= wxPyCheckSwigType(name
); 
 903             while (info 
&& !exists
) { 
 904                 info 
= info
->GetBaseClass1(); 
 905                 name 
= info
->GetClassName(); 
 906                 exists 
= wxPyCheckSwigType(name
); 
 909                 target 
= wxPyConstructObject((void*)source
, name
, setThisOwn
); 
 910                 if (target 
&& isEvtHandler
) 
 911                     ((wxEvtHandler
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
 912                 if (target 
&& isSizer
) 
 913                     ((wxSizer
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
 915                 wxString 
msg(wxT("wxPython class not found for ")); 
 916                 msg 
+= source
->GetClassInfo()->GetClassName(); 
 917                 PyErr_SetString(PyExc_NameError
, msg
.mbc_str()); 
 921     } else {  // source was NULL so return None. 
 922         Py_INCREF(Py_None
); target 
= Py_None
; 
 928 PyObject
*  wxPyMake_wxSizer(wxSizer
* source
, bool setThisOwn
) { 
 930     return wxPyMake_wxObject(source
, setThisOwn
); 
 934 //--------------------------------------------------------------------------- 
 937 #ifdef WXP_WITH_THREAD 
 938 #if !wxPyUSE_GIL_STATE 
 941 unsigned long wxPyGetCurrentThreadId() { 
 942     return wxThread::GetCurrentId(); 
 945 static wxPyThreadState gs_shutdownTState
; 
 948 wxPyThreadState
* wxPyGetThreadState() { 
 949     if (wxPyTMutex 
== NULL
) // Python is shutting down... 
 950         return &gs_shutdownTState
; 
 952     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
 953     wxPyThreadState
* tstate 
= NULL
; 
 956     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
 957         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
 958         if (info
.tid 
== ctid
) { 
 963     wxPyTMutex
->Unlock(); 
 964     wxASSERT_MSG(tstate
, wxT("PyThreadState should not be NULL!")); 
 970 void wxPySaveThreadState(PyThreadState
* tstate
) { 
 971     if (wxPyTMutex 
== NULL
) { // Python is shutting down, assume a single thread... 
 972         gs_shutdownTState
.tstate 
= tstate
; 
 975     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
 977     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
 978         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
 979         if (info
.tid 
== ctid
) { 
 981             if (info
.tstate 
!= tstate
) 
 982                 wxLogMessage("*** tstate mismatch!???"); 
 984             info
.tstate 
= tstate
;    // allow for transient tstates 
 985             // Normally it will never change, but apparently COM callbacks 
 986             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient 
 987             // tstate which will then be garbage the next time we try to use 
 990             wxPyTMutex
->Unlock(); 
 994     // not found, so add it... 
 995     wxPyTStates
->Add(new wxPyThreadState(ctid
, tstate
)); 
 996     wxPyTMutex
->Unlock(); 
1004 // Calls from Python to wxWindows code are wrapped in calls to these 
1007 PyThreadState
* wxPyBeginAllowThreads() { 
1008 #ifdef WXP_WITH_THREAD 
1009     PyThreadState
* saved 
= PyEval_SaveThread();  // Py_BEGIN_ALLOW_THREADS; 
1010 #if !wxPyUSE_GIL_STATE 
1011     wxPySaveThreadState(saved
); 
1019 void wxPyEndAllowThreads(PyThreadState
* saved
) { 
1020 #ifdef WXP_WITH_THREAD 
1021     PyEval_RestoreThread(saved
);   // Py_END_ALLOW_THREADS; 
1027 // Calls from wxWindows back to Python code, or even any PyObject 
1028 // manipulations, PyDECREF's and etc. are wrapped in calls to these functions: 
1030 wxPyBlock_t 
wxPyBeginBlockThreads() { 
1031 #ifdef WXP_WITH_THREAD 
1032     if (! Py_IsInitialized()) { 
1033         return (wxPyBlock_t
)0; 
1035 #if wxPyUSE_GIL_STATE 
1036     PyGILState_STATE state 
= PyGILState_Ensure(); 
1039     PyThreadState 
*current 
= _PyThreadState_Current
; 
1041     // Only block if there wasn't already a tstate, or if the current one is 
1042     // not the one we are wanting to change to.  This should prevent deadlock 
1043     // if there are nested calls to wxPyBeginBlockThreads 
1044     wxPyBlock_t blocked 
= false; 
1045     wxPyThreadState
* tstate 
= wxPyGetThreadState(); 
1046     if (current 
!= tstate
->tstate
) { 
1047         PyEval_RestoreThread(tstate
->tstate
); 
1053     return (wxPyBlock_t
)0; 
1058 void wxPyEndBlockThreads(wxPyBlock_t blocked
) { 
1059 #ifdef WXP_WITH_THREAD 
1060     if (! Py_IsInitialized()) { 
1063 #if wxPyUSE_GIL_STATE 
1064     PyGILState_Release(blocked
); 
1066     // Only unblock if we blocked in the last call to wxPyBeginBlockThreads. 
1067     // The value of blocked passed in needs to be the same as that returned 
1068     // from wxPyBeginBlockThreads at the same nesting level. 
1070         PyEval_SaveThread(); 
1077 //--------------------------------------------------------------------------- 
1078 // wxPyInputStream and wxPyCBInputStream methods 
1081 void wxPyInputStream::close() { 
1082     /* do nothing for now */ 
1085 void wxPyInputStream::flush() { 
1086     /* do nothing for now */ 
1089 bool wxPyInputStream::eof() { 
1091         return m_wxis
->Eof(); 
1096 wxPyInputStream::~wxPyInputStream() { 
1104 PyObject
* wxPyInputStream::read(int size
) { 
1105     PyObject
* obj 
= NULL
; 
1107     const int BUFSIZE 
= 1024; 
1109     // check if we have a real wxInputStream to work with 
1111         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1112         PyErr_SetString(PyExc_IOError
, "no valid C-wxInputStream"); 
1113         wxPyEndBlockThreads(blocked
); 
1118         // read while bytes are available on the stream 
1119         while ( m_wxis
->CanRead() ) { 
1120             m_wxis
->Read(buf
.GetAppendBuf(BUFSIZE
), BUFSIZE
); 
1121             buf
.UngetAppendBuf(m_wxis
->LastRead()); 
1124     } else {  // Read only size number of characters 
1125         m_wxis
->Read(buf
.GetWriteBuf(size
), size
); 
1126         buf
.UngetWriteBuf(m_wxis
->LastRead()); 
1130     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1131     wxStreamError err 
= m_wxis
->GetLastError(); 
1132     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1133         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1136         // We use only strings for the streams, not unicode 
1137         obj 
= PyString_FromStringAndSize(buf
, buf
.GetDataLen()); 
1139     wxPyEndBlockThreads(blocked
); 
1144 PyObject
* wxPyInputStream::readline(int size
) { 
1145     PyObject
* obj 
= NULL
; 
1150     // check if we have a real wxInputStream to work with 
1152         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1153         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1154         wxPyEndBlockThreads(blocked
); 
1158     // read until \n or byte limit reached 
1159     for (i
=ch
=0; (ch 
!= '\n') && (m_wxis
->CanRead()) && ((size 
< 0) || (i 
< size
)); i
++) { 
1160         ch 
= m_wxis
->GetC(); 
1165     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1166     wxStreamError err 
= m_wxis
->GetLastError(); 
1167     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1168         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1171         // We use only strings for the streams, not unicode 
1172         obj 
= PyString_FromStringAndSize((char*)buf
.GetData(), buf
.GetDataLen()); 
1174     wxPyEndBlockThreads(blocked
); 
1179 PyObject
* wxPyInputStream::readlines(int sizehint
) { 
1182     // check if we have a real wxInputStream to work with 
1184         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1185         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1186         wxPyEndBlockThreads(blocked
); 
1191     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1192     pylist 
= PyList_New(0); 
1193     wxPyEndBlockThreads(blocked
); 
1196         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1198         wxPyEndBlockThreads(blocked
); 
1202     // read sizehint bytes or until EOF 
1204     for (i
=0; (m_wxis
->CanRead()) && ((sizehint 
< 0) || (i 
< sizehint
));) { 
1205         PyObject
* s 
= this->readline(); 
1207             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1209             wxPyEndBlockThreads(blocked
); 
1212         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1213         PyList_Append(pylist
, s
); 
1214         i 
+= PyString_Size(s
); 
1215         wxPyEndBlockThreads(blocked
); 
1219     wxStreamError err 
= m_wxis
->GetLastError(); 
1220     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1221         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1223         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1224         wxPyEndBlockThreads(blocked
); 
1232 void wxPyInputStream::seek(int offset
, int whence
) { 
1234         m_wxis
->SeekI(offset
, wxSeekMode(whence
)); 
1237 int wxPyInputStream::tell(){ 
1239         return m_wxis
->TellI(); 
1246 wxPyCBInputStream::wxPyCBInputStream(PyObject 
*r
, PyObject 
*s
, PyObject 
*t
, bool block
) 
1247     : wxInputStream(), m_read(r
), m_seek(s
), m_tell(t
), m_block(block
) 
1250 wxPyCBInputStream::wxPyCBInputStream(const wxPyCBInputStream
& other
) 
1252     m_read  
= other
.m_read
; 
1253     m_seek  
= other
.m_seek
; 
1254     m_tell  
= other
.m_tell
; 
1255     m_block 
= other
.m_block
; 
1262 wxPyCBInputStream::~wxPyCBInputStream() { 
1263     wxPyBlock_t blocked
; 
1264     if (m_block
) blocked 
= wxPyBeginBlockThreads(); 
1268     if (m_block
) wxPyEndBlockThreads(blocked
); 
1272 wxPyCBInputStream
* wxPyCBInputStream::create(PyObject 
*py
, bool block
) { 
1273     wxPyBlock_t blocked
; 
1274     if (block
) blocked 
= wxPyBeginBlockThreads(); 
1276     PyObject
* read 
= getMethod(py
, "read"); 
1277     PyObject
* seek 
= getMethod(py
, "seek"); 
1278     PyObject
* tell 
= getMethod(py
, "tell"); 
1281         PyErr_SetString(PyExc_TypeError
, "Not a file-like object"); 
1285         if (block
) wxPyEndBlockThreads(blocked
); 
1289     if (block
) wxPyEndBlockThreads(blocked
); 
1290     return new wxPyCBInputStream(read
, seek
, tell
, block
); 
1294 wxPyCBInputStream
* wxPyCBInputStream_create(PyObject 
*py
, bool block
) { 
1295     return wxPyCBInputStream::create(py
, block
); 
1298 wxPyCBInputStream
* wxPyCBInputStream_copy(wxPyCBInputStream
* other
) { 
1299     return new wxPyCBInputStream(*other
); 
1302 PyObject
* wxPyCBInputStream::getMethod(PyObject
* py
, char* name
) { 
1303     if (!PyObject_HasAttrString(py
, name
)) 
1305     PyObject
* o 
= PyObject_GetAttrString(py
, name
); 
1306     if (!PyMethod_Check(o
) && !PyCFunction_Check(o
)) { 
1314 wxFileOffset 
wxPyCBInputStream::GetLength() const { 
1315     wxPyCBInputStream
* self 
= (wxPyCBInputStream
*)this; // cast off const 
1316     if (m_seek 
&& m_tell
) { 
1317         wxFileOffset temp 
= self
->OnSysTell(); 
1318         wxFileOffset ret 
= self
->OnSysSeek(0, wxFromEnd
); 
1319         self
->OnSysSeek(temp
, wxFromStart
); 
1323         return wxInvalidOffset
; 
1327 size_t wxPyCBInputStream::OnSysRead(void *buffer
, size_t bufsize
) { 
1331     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1332     PyObject
* arglist 
= Py_BuildValue("(i)", bufsize
); 
1333     PyObject
* result 
= PyEval_CallObject(m_read
, arglist
); 
1337     if ((result 
!= NULL
) && PyString_Check(result
)) { 
1338         o 
= PyString_Size(result
); 
1340             m_lasterror 
= wxSTREAM_EOF
; 
1343         memcpy((char*)buffer
, PyString_AsString(result
), o
);  // strings only, not unicode... 
1348         m_lasterror 
= wxSTREAM_READ_ERROR
; 
1349     wxPyEndBlockThreads(blocked
); 
1353 size_t wxPyCBInputStream::OnSysWrite(const void *buffer
, size_t bufsize
) { 
1354     m_lasterror 
= wxSTREAM_WRITE_ERROR
; 
1359 wxFileOffset 
wxPyCBInputStream::OnSysSeek(wxFileOffset off
, wxSeekMode mode
) { 
1360     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1361     PyObject
* arglist 
= PyTuple_New(2); 
1363     if (sizeof(wxFileOffset
) > sizeof(long)) 
1364         // wxFileOffset is a 64-bit value... 
1365         PyTuple_SET_ITEM(arglist
, 0, PyLong_FromLongLong(off
)); 
1367         PyTuple_SET_ITEM(arglist
, 0, PyInt_FromLong(off
)); 
1369     PyTuple_SET_ITEM(arglist
, 1, PyInt_FromLong(mode
)); 
1372     PyObject
* result 
= PyEval_CallObject(m_seek
, arglist
); 
1375     wxPyEndBlockThreads(blocked
); 
1380 wxFileOffset 
wxPyCBInputStream::OnSysTell() const { 
1381     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1382     PyObject
* arglist 
= Py_BuildValue("()"); 
1383     PyObject
* result 
= PyEval_CallObject(m_tell
, arglist
); 
1386     if (result 
!= NULL
) { 
1387         if (PyLong_Check(result
)) 
1388             o 
= PyLong_AsLongLong(result
); 
1390             o 
= PyInt_AsLong(result
); 
1393     wxPyEndBlockThreads(blocked
); 
1397 //---------------------------------------------------------------------- 
1399 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback
, wxObject
); 
1401 wxPyCallback::wxPyCallback(PyObject
* func
) { 
1406 wxPyCallback::wxPyCallback(const wxPyCallback
& other
) { 
1407     m_func 
= other
.m_func
; 
1411 wxPyCallback::~wxPyCallback() { 
1412     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1414     wxPyEndBlockThreads(blocked
); 
1418 #define wxPy_PRECALLINIT     "_preCallInit" 
1419 #define wxPy_POSTCALLCLEANUP "_postCallCleanup" 
1421 // This function is used for all events destined for Python event handlers. 
1422 void wxPyCallback::EventThunker(wxEvent
& event
) { 
1423     wxPyCallback
*   cb 
= (wxPyCallback
*)event
.m_callbackUserData
; 
1424     PyObject
*       func 
= cb
->m_func
; 
1428     bool            checkSkip 
= false; 
1430     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1431     wxString className 
= event
.GetClassInfo()->GetClassName(); 
1433     // If the event is one of these types then pass the original 
1434     // event object instead of the one passed to us. 
1435     if ( className 
== wxT("wxPyEvent") ) { 
1436         arg 
=       ((wxPyEvent
*)&event
)->GetSelf(); 
1437         checkSkip 
= ((wxPyEvent
*)&event
)->GetCloned(); 
1439     else if ( className 
== wxT("wxPyCommandEvent") ) { 
1440         arg 
=       ((wxPyCommandEvent
*)&event
)->GetSelf(); 
1441         checkSkip 
= ((wxPyCommandEvent
*)&event
)->GetCloned(); 
1444         arg 
= wxPyConstructObject((void*)&event
, className
); 
1450         // "intern" the pre/post method names to speed up the HasAttr 
1451         static PyObject
* s_preName  
= NULL
; 
1452         static PyObject
* s_postName 
= NULL
; 
1453         if (s_preName 
== NULL
) { 
1454             s_preName  
= PyString_FromString(wxPy_PRECALLINIT
); 
1455             s_postName 
= PyString_FromString(wxPy_POSTCALLCLEANUP
); 
1458         // Check if the event object needs some preinitialization 
1459         if (PyObject_HasAttr(arg
, s_preName
)) { 
1460             result 
= PyObject_CallMethodObjArgs(arg
, s_preName
, arg
, NULL
); 
1462                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1463                 PyErr_Clear();       // Just in case... 
1469         // Call the event handler, passing the event object 
1470         tuple 
= PyTuple_New(1); 
1471         PyTuple_SET_ITEM(tuple
, 0, arg
);  // steals ref to arg 
1472         result 
= PyEval_CallObject(func
, tuple
); 
1474             Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1475             PyErr_Clear();       // Just in case... 
1480         // Check if the event object needs some post cleanup 
1481         if (PyObject_HasAttr(arg
, s_postName
)) { 
1482             result 
= PyObject_CallMethodObjArgs(arg
, s_postName
, arg
, NULL
); 
1484                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1485                 PyErr_Clear();       // Just in case... 
1492             // if the event object was one of our special types and 
1493             // it had been cloned, then we need to extract the Skipped 
1494             // value from the original and set it in the clone. 
1495             result 
= PyObject_CallMethod(arg
, "GetSkipped", ""); 
1497                 event
.Skip(PyInt_AsLong(result
)); 
1505     wxPyEndBlockThreads(blocked
); 
1509 //---------------------------------------------------------------------- 
1511 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper
& other
) { 
1513       m_self 
= other
.m_self
; 
1514       m_class 
= other
.m_class
; 
1522 void wxPyCallbackHelper::setSelf(PyObject
* self
, PyObject
* klass
, int incref
) { 
1533 #if PYTHON_API_VERSION >= 1011 
1535 // Prior to Python 2.2 PyMethod_GetClass returned the class object 
1536 // in which the method was defined.  Starting with 2.2 it returns 
1537 // "class that asked for the method" which seems totally bogus to me 
1538 // but apprently it fixes some obscure problem waiting to happen in 
1539 // Python.  Since the API was not documented Guido and the gang felt 
1540 // safe in changing it.  Needless to say that totally screwed up the 
1541 // logic below in wxPyCallbackHelper::findCallback, hence this icky 
1542 // code to find the class where the method is actually defined... 
1545 PyObject
* PyFindClassWithAttr(PyObject 
*klass
, PyObject 
*name
) 
1549     if (PyType_Check(klass
)) {      // new style classes 
1550         // This code is borrowed/adapted from _PyType_Lookup in typeobject.c 
1551         PyTypeObject
* type 
= (PyTypeObject
*)klass
; 
1552         PyObject 
*mro
, *res
, *base
, *dict
; 
1553         /* Look in tp_dict of types in MRO */ 
1555         assert(PyTuple_Check(mro
)); 
1556         n 
= PyTuple_GET_SIZE(mro
); 
1557         for (i 
= 0; i 
< n
; i
++) { 
1558             base 
= PyTuple_GET_ITEM(mro
, i
); 
1559             if (PyClass_Check(base
)) 
1560                 dict 
= ((PyClassObject 
*)base
)->cl_dict
; 
1562                 assert(PyType_Check(base
)); 
1563                 dict 
= ((PyTypeObject 
*)base
)->tp_dict
; 
1565             assert(dict 
&& PyDict_Check(dict
)); 
1566             res 
= PyDict_GetItem(dict
, name
); 
1573     else if (PyClass_Check(klass
)) { // old style classes 
1574         // This code is borrowed/adapted from class_lookup in classobject.c 
1575         PyClassObject
* cp 
= (PyClassObject
*)klass
; 
1576         PyObject 
*value 
= PyDict_GetItem(cp
->cl_dict
, name
); 
1577         if (value 
!= NULL
) { 
1578             return (PyObject
*)cp
; 
1580         n 
= PyTuple_Size(cp
->cl_bases
); 
1581         for (i 
= 0; i 
< n
; i
++) { 
1582             PyObject
* base 
= PyTuple_GetItem(cp
->cl_bases
, i
); 
1583             PyObject 
*v 
= PyFindClassWithAttr(base
, name
); 
1595 PyObject
* PyMethod_GetDefiningClass(PyObject
* method
, PyObject
* nameo
) 
1597     PyObject
* mgc 
= PyMethod_GET_CLASS(method
); 
1599 #if PYTHON_API_VERSION <= 1010    // prior to Python 2.2, the easy way 
1601 #else                             // 2.2 and after, the hard way... 
1602     return PyFindClassWithAttr(mgc
, nameo
); 
1608 // To avoid recursion when an overridden virtual method wants to call the base 
1609 // class version, temporarily set an attribute in the instance with the same 
1610 // name as the method.  Then the PyObject_GetAttr in the next findCallback 
1611 // will return this attribute and the PyMethod_Check will fail. 
1613 void wxPyCallbackHelper::setRecursionGuard(PyObject
* method
) const 
1615     PyFunctionObject
* func 
= (PyFunctionObject
*)PyMethod_Function(method
); 
1616     PyObject_SetAttr(m_self
, func
->func_name
, Py_None
); 
1619 void wxPyCallbackHelper::clearRecursionGuard(PyObject
* method
) const 
1621     PyFunctionObject
* func 
= (PyFunctionObject
*)PyMethod_Function(method
); 
1622     if (PyObject_HasAttr(m_self
, func
->func_name
)) { 
1623         PyObject_DelAttr(m_self
, func
->func_name
); 
1627 // bool wxPyCallbackHelper::hasRecursionGuard(PyObject* method) const 
1629 //     PyFunctionObject* func = (PyFunctionObject*)PyMethod_Function(method); 
1630 //     if (PyObject_HasAttr(m_self, func->func_name)) { 
1631 //         PyObject* attr = PyObject_GetAttr(m_self, func->func_name); 
1632 //         bool retval = (attr == Py_None); 
1640 bool wxPyCallbackHelper::findCallback(const char* name
, bool setGuard
) const { 
1641     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
1642     PyObject 
*method
, *klass
; 
1643     PyObject
* nameo 
= PyString_FromString(name
); 
1644     self
->m_lastFound 
= NULL
; 
1646     // If the object (m_self) has an attibute of the given name... 
1647     if (m_self 
&& PyObject_HasAttr(m_self
, nameo
)) { 
1648         method 
= PyObject_GetAttr(m_self
, nameo
); 
1650         // ...and if that attribute is a method, and if that method's class is 
1651         // not from the registered class or a base class... 
1652         if (PyMethod_Check(method
) && 
1653             (klass 
= PyMethod_GetDefiningClass(method
, nameo
)) != NULL 
&& 
1654             (klass 
!= m_class
) && 
1655             PyObject_IsSubclass(klass
, m_class
)) { 
1657             // ...then we'll save a pointer to the method so callCallback can 
1658             // call it.  But first, set a recursion guard in case the 
1659             // overridden method wants to call the base class version. 
1661                 setRecursionGuard(method
); 
1662             self
->m_lastFound 
= method
; 
1670     return m_lastFound 
!= NULL
; 
1674 int wxPyCallbackHelper::callCallback(PyObject
* argTuple
) const { 
1678     result 
= callCallbackObj(argTuple
); 
1679     if (result
) {                       // Assumes an integer return type... 
1680         retval 
= PyInt_AsLong(result
); 
1682         PyErr_Clear();                  // forget about it if it's not... 
1687 // Invoke the Python callable object, returning the raw PyObject return 
1688 // value.  Caller should DECREF the return value and also manage the GIL. 
1689 PyObject
* wxPyCallbackHelper::callCallbackObj(PyObject
* argTuple
) const { 
1692     // Save a copy of the pointer in case the callback generates another 
1693     // callback.  In that case m_lastFound will have a different value when 
1694     // it gets back here... 
1695     PyObject
* method 
= m_lastFound
; 
1697     result 
= PyEval_CallObject(method
, argTuple
); 
1698     clearRecursionGuard(method
); 
1700     Py_DECREF(argTuple
); 
1709 void wxPyCBH_setCallbackInfo(wxPyCallbackHelper
& cbh
, PyObject
* self
, PyObject
* klass
, int incref
) { 
1710     cbh
.setSelf(self
, klass
, incref
); 
1713 bool wxPyCBH_findCallback(const wxPyCallbackHelper
& cbh
, const char* name
, bool setGuard
) { 
1714     return cbh
.findCallback(name
, setGuard
); 
1717 int  wxPyCBH_callCallback(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1718     return cbh
.callCallback(argTuple
); 
1721 PyObject
* wxPyCBH_callCallbackObj(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1722     return cbh
.callCallbackObj(argTuple
); 
1726 void wxPyCBH_delete(wxPyCallbackHelper
* cbh
) { 
1727     if (cbh
->m_incRef
) { 
1728         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1729         Py_XDECREF(cbh
->m_self
); 
1730         Py_XDECREF(cbh
->m_class
); 
1731         wxPyEndBlockThreads(blocked
); 
1735 //--------------------------------------------------------------------------- 
1736 //--------------------------------------------------------------------------- 
1737 // These event classes can be derived from in Python and passed through the event 
1738 // system without losing anything.  They do this by keeping a reference to 
1739 // themselves and some special case handling in wxPyCallback::EventThunker. 
1742 wxPyEvtSelfRef::wxPyEvtSelfRef() { 
1743     //m_self = Py_None;         // **** We don't do normal ref counting to prevent 
1744     //Py_INCREF(m_self);        //      circular loops... 
1748 wxPyEvtSelfRef::~wxPyEvtSelfRef() { 
1749     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1752     wxPyEndBlockThreads(blocked
); 
1755 void wxPyEvtSelfRef::SetSelf(PyObject
* self
, bool clone
) { 
1756     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1764     wxPyEndBlockThreads(blocked
); 
1767 PyObject
* wxPyEvtSelfRef::GetSelf() const { 
1773 IMPLEMENT_ABSTRACT_CLASS(wxPyEvent
, wxEvent
); 
1774 IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent
, wxCommandEvent
); 
1777 wxPyEvent::wxPyEvent(int winid
, wxEventType commandType
) 
1778     : wxEvent(winid
, commandType
) { 
1782 wxPyEvent::wxPyEvent(const wxPyEvent
& evt
) 
1785     SetSelf(evt
.m_self
, true); 
1789 wxPyEvent::~wxPyEvent() { 
1793 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType
, int id
) 
1794     : wxCommandEvent(commandType
, id
) { 
1798 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent
& evt
) 
1799     : wxCommandEvent(evt
) 
1801     SetSelf(evt
.m_self
, true); 
1805 wxPyCommandEvent::~wxPyCommandEvent() { 
1812 //--------------------------------------------------------------------------- 
1813 //--------------------------------------------------------------------------- 
1814 // Convert a wxList to a Python List, only works for lists of wxObjects 
1816 PyObject
* wxPy_ConvertList(wxListBase
* listbase
) { 
1817     wxList
*     list 
= (wxList
*)listbase
;  // this is probably bad... 
1821     wxNode
*     node 
= list
->GetFirst(); 
1823     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1824     pyList 
= PyList_New(0); 
1826         wxObj 
= node
->GetData(); 
1827         pyObj 
= wxPyMake_wxObject(wxObj
,false); 
1828         PyList_Append(pyList
, pyObj
); 
1829         Py_DECREF(pyObj
);  // the Append also does an INCREF, that's one more than we need. 
1830         node 
= node
->GetNext(); 
1832     wxPyEndBlockThreads(blocked
); 
1836 //---------------------------------------------------------------------- 
1838 long wxPyGetWinHandle(wxWindow
* win
) { 
1841     return (long)win
->GetHandle(); 
1844 #if defined(__WXGTK__) || defined(__WXX11) 
1845     return (long)GetXWindow(win
); 
1849     //return (long)MAC_WXHWND(win->MacGetTopLevelWindowRef()); 
1850     return (long)win
->GetHandle(); 
1856 //---------------------------------------------------------------------- 
1857 // Some helper functions for typemaps in my_typemaps.i, so they won't be 
1858 // included in every file over and over again... 
1860 wxString
* wxString_in_helper(PyObject
* source
) { 
1861     wxString
* target 
= NULL
; 
1863     if (!PyString_Check(source
) && !PyUnicode_Check(source
)) { 
1864         PyErr_SetString(PyExc_TypeError
, "String or Unicode type required"); 
1868     PyObject
* uni 
= source
; 
1869     if (PyString_Check(source
)) { 
1870         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
1871         if (PyErr_Occurred()) return NULL
; 
1873     target 
= new wxString(); 
1874     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1876         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
->GetWriteBuf(len
), len
); 
1877         target
->UngetWriteBuf(len
); 
1880     if (PyString_Check(source
)) 
1883     // Convert to a string object if it isn't already, then to wxString 
1884     PyObject
* str 
= source
; 
1885     if (PyUnicode_Check(source
)) { 
1886         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
1887         if (PyErr_Occurred()) return NULL
; 
1889     else if (!PyString_Check(source
)) { 
1890         str 
= PyObject_Str(source
); 
1891         if (PyErr_Occurred()) return NULL
; 
1893     char* tmpPtr
; Py_ssize_t tmpSize
; 
1894     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1895     target 
= new wxString(tmpPtr
, tmpSize
); 
1897     if (!PyString_Check(source
)) 
1899 #endif // wxUSE_UNICODE 
1905 // Similar to above except doesn't use "new" and doesn't set an exception 
1906 wxString 
Py2wxString(PyObject
* source
) 
1911     // Convert to a unicode object, if not already, then to a wxString 
1912     PyObject
* uni 
= source
; 
1913     if (!PyUnicode_Check(source
)) { 
1914         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
1915         if (PyErr_Occurred()) return wxEmptyString
;  // TODO:  should we PyErr_Clear? 
1917     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1919         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
.GetWriteBuf(len
), len
); 
1920         target
.UngetWriteBuf(); 
1923     if (!PyUnicode_Check(source
)) 
1926     // Convert to a string object if it isn't already, then to wxString 
1927     PyObject
* str 
= source
; 
1928     if (PyUnicode_Check(source
)) { 
1929         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
1930         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
1932     else if (!PyString_Check(source
)) { 
1933         str 
= PyObject_Str(source
); 
1934         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
1936     char* tmpPtr
; Py_ssize_t tmpSize
; 
1937     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1938     target 
= wxString(tmpPtr
, tmpSize
); 
1940     if (!PyString_Check(source
)) 
1942 #endif // wxUSE_UNICODE 
1948 // Make either a Python String or Unicode object, depending on build mode 
1949 PyObject
* wx2PyString(const wxString
& src
) 
1953     str 
= PyUnicode_FromWideChar(src
.c_str(), src
.Len()); 
1955     str 
= PyString_FromStringAndSize(src
.c_str(), src
.Len()); 
1962 void wxSetDefaultPyEncoding(const char* encoding
) 
1964     strncpy(wxPyDefaultEncoding
, encoding
, DEFAULTENCODING_SIZE
); 
1967 const char* wxGetDefaultPyEncoding() 
1969     return wxPyDefaultEncoding
; 
1972 //---------------------------------------------------------------------- 
1975 byte
* byte_LIST_helper(PyObject
* source
) { 
1976     if (!PyList_Check(source
)) { 
1977         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
1980     int count 
= PyList_Size(source
); 
1981     byte
* temp 
= new byte
[count
]; 
1983         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
1986     for (int x
=0; x
<count
; x
++) { 
1987         PyObject
* o 
= PyList_GetItem(source
, x
); 
1988         if (! PyInt_Check(o
)) { 
1989             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
1992         temp
[x
] = (byte
)PyInt_AsLong(o
); 
1998 int* int_LIST_helper(PyObject
* source
) { 
1999     if (!PyList_Check(source
)) { 
2000         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2003     int count 
= PyList_Size(source
); 
2004     int* temp 
= new int[count
]; 
2006         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2009     for (int x
=0; x
<count
; x
++) { 
2010         PyObject
* o 
= PyList_GetItem(source
, x
); 
2011         if (! PyInt_Check(o
)) { 
2012             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2015         temp
[x
] = PyInt_AsLong(o
); 
2021 long* long_LIST_helper(PyObject
* source
) { 
2022     if (!PyList_Check(source
)) { 
2023         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2026     int count 
= PyList_Size(source
); 
2027     long* temp 
= new long[count
]; 
2029         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2032     for (int x
=0; x
<count
; x
++) { 
2033         PyObject
* o 
= PyList_GetItem(source
, x
); 
2034         if (! PyInt_Check(o
)) { 
2035             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2038         temp
[x
] = PyInt_AsLong(o
); 
2044 char** string_LIST_helper(PyObject
* source
) { 
2045     if (!PyList_Check(source
)) { 
2046         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2049     int count 
= PyList_Size(source
); 
2050     char** temp 
= new char*[count
]; 
2052         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2055     for (int x
=0; x
<count
; x
++) { 
2056         PyObject
* o 
= PyList_GetItem(source
, x
); 
2057         if (! PyString_Check(o
)) { 
2058             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2061         temp
[x
] = PyString_AsString(o
); 
2066 //--------------------------------------------------------------------------- 
2067 // NOTE: The following functions could really use some refactoring using 
2068 // templates to make things somewhat simpler... 
2070 inline bool wxPointFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint
* point
) 
2073     if (PyInt_Check(o1
)) 
2074         point
->x 
= (int)PyInt_AS_LONG(o1
); 
2075     else if (PyFloat_Check(o1
)) 
2076         point
->x 
= (int)PyFloat_AS_DOUBLE(o1
); 
2077     else if (PyNumber_Check(o1
)) 
2078         point
->x 
= (int)PyInt_AsLong(o1
); 
2083     if (PyInt_Check(o2
)) 
2084         point
->y 
= (int)PyInt_AS_LONG(o2
); 
2085     else if (PyFloat_Check(o2
)) 
2086         point
->y 
= (int)PyFloat_AS_DOUBLE(o2
); 
2087     else if (PyNumber_Check(o2
)) 
2088         point
->y 
= (int)PyInt_AsLong(o2
); 
2094 // NOTE: This function used to have this code in it, but I don't know why it 
2095 // is a problem nor what havok it will cause, so removing for now... 
2096 //     if (wxPySwigInstance_Check(o1) || wxPySwigInstance_Check(o2)) {   
2097 //         // Disallow instances because they can cause havok 
2103 inline bool wxPoint2DFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint2D
* point
) 
2106     if (PyInt_Check(o1
)) 
2107         point
->m_x 
= (double)PyInt_AS_LONG(o1
); 
2108     else if (PyFloat_Check(o1
)) 
2109         point
->m_x 
= (double)PyFloat_AS_DOUBLE(o1
); 
2110     else if (PyNumber_Check(o1
)) 
2111         point
->m_x 
= (double)PyFloat_AsDouble(o1
); 
2116     if (PyInt_Check(o2
)) 
2117         point
->m_y 
= (double)PyInt_AS_LONG(o2
); 
2118     else if (PyFloat_Check(o2
)) 
2119         point
->m_y 
= (double)PyFloat_AS_DOUBLE(o2
); 
2120     else if (PyNumber_Check(o2
)) 
2121         point
->m_y 
= (double)PyFloat_AsDouble(o2
); 
2130 wxPoint
* wxPoint_LIST_helper(PyObject
* source
, int *count
) 
2134     PyObject 
*o
, *o1
, *o2
; 
2135     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2137     if (!PySequence_Check(source
)) { 
2141     // The length of the sequence is returned in count. 
2142     *count 
= PySequence_Length(source
); 
2147     temp 
= new wxPoint
[*count
]; 
2149         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2152     for (idx
=0; idx
<*count
; idx
++) { 
2153         // Get an item: try fast way first. 
2155             o 
= PySequence_Fast_GET_ITEM(source
, idx
); 
2158             o 
= PySequence_GetItem(source
, idx
); 
2164         // Convert o to wxPoint. 
2165         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2166             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2167             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2168             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2169             if (!wxPointFromObjects(o1
, o2
, &temp
[idx
])) { 
2173         else if (wxPySwigInstance_Check(o
)) { 
2175             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint"))) { 
2180         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2181             o1 
= PySequence_GetItem(o
, 0); 
2182             o2 
= PySequence_GetItem(o
, 1); 
2183             if (!wxPointFromObjects(o1
, o2
, &temp
[idx
])) { 
2207     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoints."); 
2213 wxPoint2D
* wxPoint2D_LIST_helper(PyObject
* source
, size_t *count
) 
2217     PyObject 
*o
, *o1
, *o2
; 
2218     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2220     if (!PySequence_Check(source
)) { 
2224     // The length of the sequence is returned in count. 
2225     *count 
= PySequence_Length(source
); 
2230     temp 
= new wxPoint2D
[*count
]; 
2232         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2235     for (idx
=0; idx
<*count
; idx
++) { 
2236         // Get an item: try fast way first. 
2238             o 
= PySequence_Fast_GET_ITEM(source
, idx
); 
2241             o 
= PySequence_GetItem(source
, idx
); 
2247         // Convert o to wxPoint. 
2248         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2249             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2250             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2251             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2252             if (!wxPoint2DFromObjects(o1
, o2
, &temp
[idx
])) { 
2256         else if (wxPySwigInstance_Check(o
)) { 
2258             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint2D"))) { 
2263         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2264             o1 
= PySequence_GetItem(o
, 0); 
2265             o2 
= PySequence_GetItem(o
, 1); 
2266             if (!wxPoint2DFromObjects(o1
, o2
, &temp
[idx
])) { 
2290     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoint2Ds."); 
2294 //--------------------------------------------------------------------------- 
2297 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) { 
2298     if (!PyList_Check(source
)) { 
2299         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2302     int count 
= PyList_Size(source
); 
2303     wxBitmap
** temp 
= new wxBitmap
*[count
]; 
2305         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2308     for (int x
=0; x
<count
; x
++) { 
2309         PyObject
* o 
= PyList_GetItem(source
, x
); 
2310         if (wxPySwigInstance_Check(o
)) { 
2312             if (! wxPyConvertSwigPtr(o
, (void **) &pt
, wxT("wxBitmap"))) { 
2313                 PyErr_SetString(PyExc_TypeError
,"Expected wxBitmap."); 
2319             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps."); 
2328 wxString
* wxString_LIST_helper(PyObject
* source
) { 
2329     if (!PyList_Check(source
)) { 
2330         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2333     int count 
= PyList_Size(source
); 
2334     wxString
* temp 
= new wxString
[count
]; 
2336         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2339     for (int x
=0; x
<count
; x
++) { 
2340         PyObject
* o 
= PyList_GetItem(source
, x
); 
2341 #if PYTHON_API_VERSION >= 1009 
2342         if (! PyString_Check(o
) && ! PyUnicode_Check(o
)) { 
2343             PyErr_SetString(PyExc_TypeError
, "Expected a list of string or unicode objects."); 
2347         if (! PyString_Check(o
)) { 
2348             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2353         wxString
* pStr 
= wxString_in_helper(o
); 
2361 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) { 
2362     if (!PyList_Check(source
)) { 
2363         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2366     int count                
= PyList_Size(source
); 
2367     wxAcceleratorEntry
* temp 
= new wxAcceleratorEntry
[count
]; 
2369         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2372     for (int x
=0; x
<count
; x
++) { 
2373         PyObject
* o 
= PyList_GetItem(source
, x
); 
2374         if (wxPySwigInstance_Check(o
)) { 
2375             wxAcceleratorEntry
* ae
; 
2376             if (! wxPyConvertSwigPtr(o
, (void **) &ae
, wxT("wxAcceleratorEntry"))) { 
2377                 PyErr_SetString(PyExc_TypeError
,"Expected wxAcceleratorEntry."); 
2382         else if (PyTuple_Check(o
)) { 
2383             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
2384             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
2385             PyObject
* o3 
= PyTuple_GetItem(o
, 2); 
2386             temp
[x
].Set(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2389             PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects."); 
2397 wxPen
** wxPen_LIST_helper(PyObject
* source
) { 
2398     if (!PyList_Check(source
)) { 
2399         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2402     int count 
= PyList_Size(source
); 
2403     wxPen
** temp 
= new wxPen
*[count
]; 
2405         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2408     for (int x
=0; x
<count
; x
++) { 
2409         PyObject
* o 
= PyList_GetItem(source
, x
); 
2410         if (wxPySwigInstance_Check(o
)) { 
2412             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPen"))) { 
2414                 PyErr_SetString(PyExc_TypeError
,"Expected wxPen."); 
2421             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxPens."); 
2429 bool wxPy2int_seq_helper(PyObject
* source
, int* i1
, int* i2
) { 
2430     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2433     if (!PySequence_Check(source
) || PySequence_Length(source
) != 2) 
2437         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2438         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2441         o1 
= PySequence_GetItem(source
, 0); 
2442         o2 
= PySequence_GetItem(source
, 1); 
2445     *i1 
= PyInt_AsLong(o1
); 
2446     *i2 
= PyInt_AsLong(o2
); 
2456 bool wxPy4int_seq_helper(PyObject
* source
, int* i1
, int* i2
, int* i3
, int* i4
) { 
2457     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2458     PyObject 
*o1
, *o2
, *o3
, *o4
; 
2460     if (!PySequence_Check(source
) || PySequence_Length(source
) != 4) 
2464         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2465         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2466         o3 
= PySequence_Fast_GET_ITEM(source
, 2); 
2467         o4 
= PySequence_Fast_GET_ITEM(source
, 3); 
2470         o1 
= PySequence_GetItem(source
, 0); 
2471         o2 
= PySequence_GetItem(source
, 1); 
2472         o3 
= PySequence_GetItem(source
, 2); 
2473         o4 
= PySequence_GetItem(source
, 3); 
2476     *i1 
= PyInt_AsLong(o1
); 
2477     *i2 
= PyInt_AsLong(o2
); 
2478     *i3 
= PyInt_AsLong(o3
); 
2479     *i4 
= PyInt_AsLong(o4
); 
2491 //---------------------------------------------------------------------- 
2493 bool wxPySimple_typecheck(PyObject
* source
, const wxChar
* classname
, int seqLen
) 
2497     if (wxPySwigInstance_Check(source
) && 
2498         wxPyConvertSwigPtr(source
, (void **)&ptr
, classname
)) 
2502     if (PySequence_Check(source
) && PySequence_Length(source
) == seqLen
) 
2508 bool wxSize_helper(PyObject
* source
, wxSize
** obj
) 
2510     if (source 
== Py_None
) { 
2511         **obj 
= wxSize(-1,-1); 
2514     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxSize")); 
2518 bool wxPoint_helper(PyObject
* source
, wxPoint
** obj
) 
2520     if (source 
== Py_None
) { 
2521         **obj 
= wxPoint(-1,-1); 
2524     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxPoint")); 
2529 bool wxRealPoint_helper(PyObject
* source
, wxRealPoint
** obj
) { 
2531     if (source 
== Py_None
) { 
2532         **obj 
= wxRealPoint(-1,-1); 
2536     // If source is an object instance then it may already be the right type 
2537     if (wxPySwigInstance_Check(source
)) { 
2539         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRealPoint"))) 
2544     // otherwise a 2-tuple of floats is expected 
2545     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
2546         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2547         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2548         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2553         **obj 
= wxRealPoint(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2560     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxRealPoint object."); 
2566 bool wxRect_helper(PyObject
* source
, wxRect
** obj
) { 
2568     if (source 
== Py_None
) { 
2569         **obj 
= wxRect(-1,-1,-1,-1); 
2573     // If source is an object instance then it may already be the right type 
2574     if (wxPySwigInstance_Check(source
)) { 
2576         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect"))) 
2581     // otherwise a 4-tuple of integers is expected 
2582     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2583         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2584         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2585         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2586         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2587         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2588             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2595         **obj 
= wxRect(PyInt_AsLong(o1
), PyInt_AsLong(o2
), 
2596                        PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2605     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of integers or a wxRect object."); 
2611 bool wxColour_helper(PyObject
* source
, wxColour
** obj
) { 
2613     if (source 
== Py_None
) { 
2614         **obj 
= wxNullColour
; 
2618     // If source is an object instance then it may already be the right type 
2619     if (wxPySwigInstance_Check(source
)) { 
2621         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxColour"))) 
2626     // otherwise check for a string 
2627     else if (PyString_Check(source
) || PyUnicode_Check(source
)) { 
2628         wxString spec 
= Py2wxString(source
); 
2629         if (spec
.GetChar(0) == '#' && spec
.Length() == 7) {  // It's  #RRGGBB 
2630             long red
, green
, blue
; 
2631             red 
= green 
= blue 
= 0; 
2632             spec
.Mid(1,2).ToLong(&red
,   16); 
2633             spec
.Mid(3,2).ToLong(&green
, 16); 
2634             spec
.Mid(5,2).ToLong(&blue
,  16); 
2636             **obj 
= wxColour(red
, green
, blue
); 
2639         else {                                       // it's a colour name 
2640             **obj 
= wxColour(spec
); 
2644     // last chance: 3-tuple or 4-tuple of integers is expected 
2645     else if (PySequence_Check(source
) && PyObject_Length(source
) == 3) { 
2646         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2647         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2648         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2649         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
)) { 
2655         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2661     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2662         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2663         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2664         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2665         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2666         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2673         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2682     PyErr_SetString(PyExc_TypeError
, 
2683                     "Expected a wxColour object, a string containing a colour name or '#RRGGBB', or a 3- or 4-tuple of integers."); 
2688 bool wxColour_typecheck(PyObject
* source
) { 
2690     if (wxPySimple_typecheck(source
, wxT("wxColour"), 3)) 
2693     if (PyString_Check(source
) || PyUnicode_Check(source
)) 
2701 bool wxPoint2D_helper(PyObject
* source
, wxPoint2D
** obj
) { 
2703     if (source 
== Py_None
) { 
2704         **obj 
= wxPoint2D(-1,-1); 
2708     // If source is an object instance then it may already be the right type 
2709     if (wxPySwigInstance_Check(source
)) { 
2711         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxPoint2D"))) 
2716     // otherwise a length-2 sequence of floats is expected 
2717     if (PySequence_Check(source
) && PySequence_Length(source
) == 2) { 
2718         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2719         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2720         // This should really check for floats, not numbers -- but that would break code. 
2721         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2726         **obj 
= wxPoint2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2732     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wx.Point2D object."); 
2738 bool wxRect2D_helper(PyObject
* source
, wxRect2D
** obj
) { 
2740     if (source 
== Py_None
) { 
2741         **obj 
= wxRect2D(-1,-1,-1,-1); 
2745     // If source is an object instance then it may already be the right type 
2746     if (wxPySwigInstance_Check(source
)) { 
2748         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect2D"))) 
2753     // otherwise a length-4 sequence of floats is expected 
2754     if (PySequence_Check(source
) && PySequence_Length(source
) == 4) { 
2755         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2756         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2757         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2758         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2759         // This should really check for floats, not numbers -- but that would break code. 
2760         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2761             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2768         **obj 
= wxRect2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
), 
2769                          PyFloat_AsDouble(o3
), PyFloat_AsDouble(o4
)); 
2777     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of floats or a wx.Rect2D object."); 
2782 //---------------------------------------------------------------------- 
2784 PyObject
* wxArrayString2PyList_helper(const wxArrayString
& arr
) 
2786     PyObject
* list 
= PyList_New(0); 
2787     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2789         PyObject
* str 
= PyUnicode_FromWideChar(arr
[i
].c_str(), arr
[i
].Len()); 
2791         PyObject
* str 
= PyString_FromStringAndSize(arr
[i
].c_str(), arr
[i
].Len()); 
2793         PyList_Append(list
, str
); 
2800 PyObject
* wxArrayInt2PyList_helper(const wxArrayInt
& arr
) 
2802     PyObject
* list 
= PyList_New(0); 
2803     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2804         PyObject
* number 
= PyInt_FromLong(arr
[i
]); 
2805         PyList_Append(list
, number
); 
2812 PyObject
* wxArrayDouble2PyList_helper(const wxArrayDouble
& arr
) 
2814     PyObject
* list 
= PyList_New(0); 
2815     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2816         PyObject
* number 
= PyFloat_FromDouble(arr
[i
]); 
2817         PyList_Append(list
, number
); 
2824 //---------------------------------------------------------------------- 
2825 // wxPyImageHandler methods 
2827 // TODO: Switch these to use wxPython's standard macros and helper classes 
2828 //       for calling callbacks. 
2830 PyObject
* wxPyImageHandler::m_DoCanRead_Name 
= NULL
; 
2831 PyObject
* wxPyImageHandler::m_GetImageCount_Name 
= NULL
; 
2832 PyObject
* wxPyImageHandler::m_LoadFile_Name 
= NULL
; 
2833 PyObject
* wxPyImageHandler::m_SaveFile_Name 
= NULL
; 
2835 PyObject
* wxPyImageHandler::py_InputStream(wxInputStream
* stream
) { 
2836     return wxPyConstructObject(new wxPyInputStream(stream
), 
2837                                wxT("wxPyInputStream"), 0); 
2840 PyObject
* wxPyImageHandler::py_Image(wxImage
* image
) { 
2841     return wxPyConstructObject(image
, wxT("wxImage"), 0); 
2844 PyObject
* wxPyImageHandler::py_OutputStream(wxOutputStream
* stream
) { 
2845     return wxPyConstructObject(stream
, wxT("wxOutputStream"), 0); 
2848 wxPyImageHandler::wxPyImageHandler(): 
2851     if (!m_DoCanRead_Name
) { 
2852         m_DoCanRead_Name 
= PyString_FromString("DoCanRead"); 
2853         m_GetImageCount_Name 
= PyString_FromString("GetImageCount"); 
2854         m_LoadFile_Name 
= PyString_FromString("LoadFile"); 
2855         m_SaveFile_Name 
= PyString_FromString("SaveFile"); 
2859 wxPyImageHandler::~wxPyImageHandler() { 
2866 void wxPyImageHandler::_SetSelf(PyObject 
*self
) { 
2867     // should check here for isinstance(PyImageHandler) ?? 
2872 bool wxPyImageHandler::DoCanRead(wxInputStream
& stream
) { 
2873     // check if our object has this method 
2874     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2875     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_DoCanRead_Name
)) { 
2876         wxPyEndBlockThreads(blocked
); 
2880     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_DoCanRead_Name
, 
2881                                                py_InputStream(&stream
), NULL
); 
2882     bool retval 
= false; 
2884         retval 
= PyInt_AsLong(res
); 
2890     wxPyEndBlockThreads(blocked
); 
2894 bool wxPyImageHandler::LoadFile( wxImage
* image
, wxInputStream
& stream
, 
2895                                  bool verbose
, int index 
) { 
2896     // check if our object has this method 
2897     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2898     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_LoadFile_Name
)) { 
2899         wxPyEndBlockThreads(blocked
); 
2902     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_LoadFile_Name
, 
2904                                                py_InputStream(&stream
), 
2905                                                PyInt_FromLong(verbose
), 
2906                                                PyInt_FromLong(index
), 
2908     bool retval 
= false; 
2910         retval 
= PyInt_AsLong(res
); 
2915     wxPyEndBlockThreads(blocked
); 
2919 bool wxPyImageHandler::SaveFile( wxImage
* image
, wxOutputStream
& stream
, 
2921     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2922     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_SaveFile_Name
)) { 
2923         wxPyEndBlockThreads(blocked
); 
2926     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_SaveFile_Name
, 
2928                                                py_OutputStream(&stream
), 
2929                                                PyInt_FromLong(verbose
), 
2931     bool retval 
= false; 
2933         retval
=PyInt_AsLong(res
); 
2938     wxPyEndBlockThreads(blocked
); 
2942 int wxPyImageHandler::GetImageCount( wxInputStream
& stream 
) { 
2943     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2944     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_GetImageCount_Name
)) { 
2945         wxPyEndBlockThreads(blocked
); 
2948     PyObject 
*res
=PyObject_CallMethodObjArgs(m_self
, m_GetImageCount_Name
, 
2949                                              py_InputStream(&stream
), 
2953         retval
=PyInt_AsLong(res
); 
2958     wxPyEndBlockThreads(blocked
); 
2963 //---------------------------------------------------------------------- 
2964 // Function to test if the Display (or whatever is the platform equivallent) 
2965 // can be connected to.  This is accessable from wxPython as a staticmethod of 
2966 // wx.App called DisplayAvailable(). 
2969 bool wxPyTestDisplayAvailable() 
2973     display 
= XOpenDisplay(NULL
); 
2974     if (display 
== NULL
) 
2976     XCloseDisplay(display
); 
2981     // This is adapted from Python's Mac/Modules/MacOS.c in the 
2982     // MacOS_WMAvailable function. 
2984     ProcessSerialNumber psn
; 
2987     ** This is a fairly innocuous call to make if we don't have a window 
2988     ** manager, or if we have no permission to talk to it. It will print 
2989     ** a message on stderr, but at least it won't abort the process. 
2990     ** It appears the function caches the result itself, and it's cheap, so 
2991     ** no need for us to cache. 
2993 #ifdef kCGNullDirectDisplay 
2994     /* On 10.1 CGMainDisplayID() isn't available, and 
2995     ** kCGNullDirectDisplay isn't defined. 
2997     if (CGMainDisplayID() == 0) { 
3002         // Also foreground the application on the first call as a side-effect. 
3003         if (GetCurrentProcess(&psn
) < 0 || SetFrontProcess(&psn
) < 0) { 
3019 //---------------------------------------------------------------------- 
3020 //----------------------------------------------------------------------