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" 
  20 #include <wx/msw/private.h> 
  21 #include <wx/msw/winundef.h> 
  22 #include <wx/msw/msvcrt.h> 
  29 #include <gdk/gdkprivate.h> 
  30 #include <wx/gtk/win_gtk.h> 
  31 #define GetXWindow(wxwin) GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) 
  36 #include "wx/x11/privx.h" 
  37 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle()) 
  41 #include <wx/mac/private.h> 
  44 #include <wx/clipbrd.h> 
  45 #include <wx/mimetype.h> 
  48 //---------------------------------------------------------------------- 
  50 #if PYTHON_API_VERSION <= 1007 && wxUSE_UNICODE 
  51 #error Python must support Unicode to use wxWindows Unicode 
  54 //---------------------------------------------------------------------- 
  56 wxPyApp
* wxPythonApp 
= NULL
;  // Global instance of application object 
  57 bool wxPyDoCleanup 
= false; 
  58 bool wxPyDoingCleanup 
= false; 
  61 #ifdef WXP_WITH_THREAD 
  62 struct wxPyThreadState 
{ 
  64     PyThreadState
* tstate
; 
  66     wxPyThreadState(unsigned long _tid
=0, PyThreadState
* _tstate
=NULL
) 
  67         : tid(_tid
), tstate(_tstate
) {} 
  70 #include <wx/dynarray.h> 
  71 WX_DECLARE_OBJARRAY(wxPyThreadState
, wxPyThreadStateArray
); 
  72 #include <wx/arrimpl.cpp> 
  73 WX_DEFINE_OBJARRAY(wxPyThreadStateArray
); 
  75 wxPyThreadStateArray
* wxPyTStates 
= NULL
; 
  76 wxMutex
*              wxPyTMutex 
= NULL
; 
  80 static PyObject
* wxPython_dict 
= NULL
; 
  81 static PyObject
* wxPyAssertionError 
= NULL
; 
  82 static PyObject
* wxPyNoAppError 
= NULL
; 
  84 PyObject
* wxPyPtrTypeMap 
= NULL
; 
  87 #ifdef __WXMSW__             // If building for win32... 
  88 //---------------------------------------------------------------------- 
  89 // This gets run when the DLL is loaded.  We just need to save a handle. 
  90 //---------------------------------------------------------------------- 
  93     HINSTANCE   hinstDLL
,    // handle to DLL module 
  94     DWORD       fdwReason
,   // reason for calling function 
  95     LPVOID      lpvReserved  
// reserved 
  98     // If wxPython is embedded in another wxWindows app then 
  99     // the inatance has already been set. 
 100     if (! wxGetInstance()) 
 101         wxSetInstance(hinstDLL
); 
 106 //---------------------------------------------------------------------- 
 107 // Classes for implementing the wxp main application shell. 
 108 //---------------------------------------------------------------------- 
 110 IMPLEMENT_ABSTRACT_CLASS(wxPyApp
, wxApp
); 
 114     m_assertMode 
= wxPYAPP_ASSERT_EXCEPTION
; 
 115     m_startupComplete 
= false; 
 119 wxPyApp::~wxPyApp() { 
 123 // This one isn't acutally called...  We fake it with _BootstrapApp 
 124 bool wxPyApp::OnInit() { 
 129 int  wxPyApp::MainLoop() { 
 132     DeletePendingObjects(); 
 133     bool initialized 
= wxTopLevelWindows
.GetCount() != 0; 
 135         if ( m_exitOnFrameDelete 
== Later 
) { 
 136             m_exitOnFrameDelete 
= Yes
; 
 139         retval 
= wxApp::MainLoop(); 
 146 bool wxPyApp::OnInitGui() { 
 148     wxApp::OnInitGui();  // in this case always call the base class version 
 149     bool blocked 
= wxPyBeginBlockThreads(); 
 150     if (wxPyCBH_findCallback(m_myInst
, "OnInitGui")) 
 151         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 152     wxPyEndBlockThreads(blocked
); 
 157 int wxPyApp::OnExit() { 
 159     bool blocked 
= wxPyBeginBlockThreads(); 
 160     if (wxPyCBH_findCallback(m_myInst
, "OnExit")) 
 161         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 162     wxPyEndBlockThreads(blocked
); 
 163     wxApp::OnExit();  // in this case always call the base class version 
 169 void wxPyApp::OnAssert(const wxChar 
*file
, 
 174     // if we're not fully initialized then just log the error 
 175     if (! m_startupComplete
) { 
 178         buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 188     // If the OnAssert is overloaded in the Python class then call it... 
 190     bool blocked 
= wxPyBeginBlockThreads(); 
 191     if ((found 
= wxPyCBH_findCallback(m_myInst
, "OnAssert"))) { 
 192         PyObject
* fso 
= wx2PyString(file
); 
 193         PyObject
* cso 
= wx2PyString(file
); 
 196             mso 
= wx2PyString(file
); 
 198             mso 
= Py_None
; Py_INCREF(Py_None
); 
 200         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(OiOO)", fso
, line
, cso
, mso
)); 
 205     wxPyEndBlockThreads(blocked
); 
 207     // ...otherwise do our own thing with it 
 210         if (m_assertMode 
& wxPYAPP_ASSERT_SUPPRESS
) 
 213         // turn it into a Python exception? 
 214         if (m_assertMode 
& wxPYAPP_ASSERT_EXCEPTION
) { 
 217             buf
.Printf(wxT("C++ assertion \"%s\" failed in %s(%d)"), cond
, file
, line
); 
 224             bool blocked 
= wxPyBeginBlockThreads(); 
 225             PyObject
* s 
= wx2PyString(buf
); 
 226             PyErr_SetObject(wxPyAssertionError
, s
); 
 228             wxPyEndBlockThreads(blocked
); 
 230             // Now when control returns to whatever API wrapper was called from 
 231             // Python it should detect that an exception is set and will return 
 232             // NULL, signalling the exception to Python. 
 235         // Send it to the normal log destination, but only if 
 236         // not _DIALOG because it will call this too 
 237         if ( (m_assertMode 
& wxPYAPP_ASSERT_LOG
) && !(m_assertMode 
& wxPYAPP_ASSERT_DIALOG
)) { 
 240             buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 249         // do the normal wx assert dialog? 
 250         if (m_assertMode 
& wxPYAPP_ASSERT_DIALOG
) 
 251             wxApp::OnAssert(file
, line
, cond
, msg
); 
 256     // For catching Apple Events 
 257 void wxPyApp::MacOpenFile(const wxString 
&fileName
) 
 259     bool blocked 
= wxPyBeginBlockThreads(); 
 260     if (wxPyCBH_findCallback(m_myInst
, "MacOpenFile")) { 
 261         PyObject
* s 
= wx2PyString(fileName
); 
 262         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 265     wxPyEndBlockThreads(blocked
); 
 268 void wxPyApp::MacPrintFile(const wxString 
&fileName
) 
 270     bool blocked 
= wxPyBeginBlockThreads(); 
 271     if (wxPyCBH_findCallback(m_myInst
, "MacPrintFile")) { 
 272         PyObject
* s 
= wx2PyString(fileName
); 
 273         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 276     wxPyEndBlockThreads(blocked
); 
 279 void wxPyApp::MacNewFile() 
 281     bool blocked 
= wxPyBeginBlockThreads(); 
 282     if (wxPyCBH_findCallback(m_myInst
, "MacNewFile")) 
 283         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 284     wxPyEndBlockThreads(blocked
); 
 287 void wxPyApp::MacReopenApp() 
 289     bool blocked 
= wxPyBeginBlockThreads(); 
 290     if (wxPyCBH_findCallback(m_myInst
, "MacReopenApp")) 
 291         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 292     wxPyEndBlockThreads(blocked
); 
 297 bool wxPyApp::GetMacSupportPCMenuShortcuts() { 
 299     return s_macSupportPCMenuShortcuts
; 
 306 long wxPyApp::GetMacAboutMenuItemId() { 
 308     return s_macAboutMenuItemId
; 
 315 long wxPyApp::GetMacPreferencesMenuItemId() { 
 317     return s_macPreferencesMenuItemId
; 
 324 long wxPyApp::GetMacExitMenuItemId() { 
 326     return s_macExitMenuItemId
; 
 333 wxString 
wxPyApp::GetMacHelpMenuTitleName() { 
 335     return s_macHelpMenuTitleName
; 
 337     return wxEmptyString
; 
 342 void wxPyApp::SetMacSupportPCMenuShortcuts(bool val
) { 
 344     s_macSupportPCMenuShortcuts 
= val
; 
 349 void wxPyApp::SetMacAboutMenuItemId(long val
) { 
 351     s_macAboutMenuItemId 
= val
; 
 356 void wxPyApp::SetMacPreferencesMenuItemId(long val
) { 
 358     s_macPreferencesMenuItemId 
= val
; 
 363 void wxPyApp::SetMacExitMenuItemId(long val
) { 
 365     s_macExitMenuItemId 
= val
; 
 370 void wxPyApp::SetMacHelpMenuTitleName(const wxString
& val
) { 
 372     s_macHelpMenuTitleName 
= val
; 
 377 // This finishes the initialization of wxWindows and then calls the OnInit 
 378 // that should be present in the derived (Python) class. 
 379 void wxPyApp::_BootstrapApp() 
 381     static      bool haveInitialized 
= false; 
 382     bool        result
, blocked
; 
 383     PyObject
*   retval 
= NULL
; 
 384     PyObject
*   pyint  
= NULL
; 
 387     // Only initialize wxWidgets once 
 388     if (! haveInitialized
) { 
 390         // Get any command-line args passed to this program from the sys module 
 393         blocked 
= wxPyBeginBlockThreads(); 
 394         PyObject
* sysargv 
= PySys_GetObject("argv"); 
 395         if (sysargv 
!= NULL
) { 
 396             argc 
= PyList_Size(sysargv
); 
 397             argv 
= new char*[argc
+1]; 
 399             for(x
=0; x
<argc
; x
++) { 
 400                 PyObject 
*pyArg 
= PyList_GetItem(sysargv
, x
); 
 401                 argv
[x
] = PyString_AsString(pyArg
); 
 405         wxPyEndBlockThreads(blocked
); 
 407         // Initialize wxWidgets 
 408         result 
= wxEntryStart(argc
, argv
); 
 411         blocked 
= wxPyBeginBlockThreads(); 
 413             PyErr_SetString(PyExc_SystemError
, 
 414                             "wxEntryStart failed, unable to initialize wxWidgets!" 
 416                             "  (Is DISPLAY set properly?)" 
 422         // On wxGTK the locale will be changed to match the system settings, but 
 423         // Python needs to have LC_NUMERIC set to "C" in order for the floating 
 424         // point conversions and such to work right. 
 426         setlocale(LC_NUMERIC
, "C"); 
 429         // The stock objects were all NULL when they were loaded into 
 430         // SWIG generated proxies, so re-init those now... 
 431         wxPy_ReinitStockObjects(3); 
 433         wxPyEndBlockThreads(blocked
); 
 434         haveInitialized 
= true; 
 437     // It's now ok to generate exceptions for assertion errors. 
 438     wxPythonApp
->SetStartupComplete(true); 
 440     // Call the Python wxApp's OnInit function 
 441     blocked 
= wxPyBeginBlockThreads(); 
 442     if (wxPyCBH_findCallback(m_myInst
, "OnInit")) { 
 444         PyObject
* method 
= m_myInst
.GetLastFound(); 
 445         PyObject
* argTuple 
= PyTuple_New(0); 
 446         retval 
= PyEval_CallObject(method
, argTuple
); 
 452         pyint 
= PyNumber_Int(retval
); 
 454             PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value"); 
 457         result 
= PyInt_AS_LONG(pyint
); 
 460         // Is it okay if there is no OnInit?  Probably so... 
 465         PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting..."); 
 472     wxPyEndBlockThreads(blocked
); 
 475 //--------------------------------------------------------------------- 
 476 //---------------------------------------------------------------------- 
 480 static char* wxPyCopyCString(const wxChar
* src
) 
 482     wxWX2MBbuf buff 
= (wxWX2MBbuf
)wxConvCurrent
->cWX2MB(src
); 
 483     size_t len 
= strlen(buff
); 
 484     char*  dest 
= new char[len
+1]; 
 490 static char* wxPyCopyCString(const char* src
)   // we need a char version too 
 492     size_t len 
= strlen(src
); 
 493     char*  dest 
= new char[len
+1]; 
 499 static wxChar
* wxPyCopyWString(const char *src
) 
 501     //wxMB2WXbuf buff = wxConvCurrent->cMB2WX(src); 
 502     wxString 
str(src
, *wxConvCurrent
); 
 503     return copystring(str
); 
 507 static wxChar
* wxPyCopyWString(const wxChar 
*src
) 
 509     return copystring(src
); 
 515 inline const char* dropwx(const char* name
) { 
 516     if (name
[0] == 'w' && name
[1] == 'x') 
 522 //---------------------------------------------------------------------- 
 524 // This function is called when the wx._core_ module is imported to do some 
 525 // initial setup.  (Before there is a wxApp object.)  The rest happens in 
 526 // wxPyApp::_BootstrapApp 
 527 void __wxPyPreStart(PyObject
* moduleDict
) 
 531 //     wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF 
 532 //                     | _CRTDBG_CHECK_ALWAYS_DF 
 533 //                     | _CRTDBG_DELAY_FREE_MEM_DF                              
 537 #ifdef WXP_WITH_THREAD 
 538     PyEval_InitThreads(); 
 539     wxPyTStates 
= new wxPyThreadStateArray
; 
 540     wxPyTMutex 
= new wxMutex
; 
 542     // Save the current (main) thread state in our array 
 543     PyThreadState
* tstate 
= wxPyBeginAllowThreads(); 
 544     wxPyEndAllowThreads(tstate
); 
 547     // Ensure that the build options in the DLL (or whatever) match this build 
 548     wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE
, "wxPython"); 
 550     // Init the stock objects to a non-NULL value so SWIG doesn't create them as None 
 551     wxPy_ReinitStockObjects(1); 
 553     wxInitAllImageHandlers(); 
 558 void __wxPyCleanup() { 
 559     wxPyDoingCleanup 
= true; 
 561         wxPyDoCleanup 
= false; 
 564 #ifdef WXP_WITH_THREAD 
 567     wxPyTStates
->Empty(); 
 574 // Save a reference to the dictionary of the wx._core module, and inject 
 575 // a few more things into it. 
 576 PyObject
* __wxPySetDictionary(PyObject
* /* self */, PyObject
* args
) 
 579     if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
)) 
 582     if (!PyDict_Check(wxPython_dict
)) { 
 583         PyErr_SetString(PyExc_TypeError
, 
 584                         "_wxPySetDictionary must have dictionary object!"); 
 588     if (! wxPyPtrTypeMap
) 
 589         wxPyPtrTypeMap 
= PyDict_New(); 
 590     PyDict_SetItemString(wxPython_dict
, "__wxPyPtrTypeMap", wxPyPtrTypeMap
); 
 592     // Create an exception object to use for wxASSERTions 
 593     wxPyAssertionError 
= PyErr_NewException("wx._core.PyAssertionError", 
 594                                             PyExc_AssertionError
, NULL
); 
 595     PyDict_SetItemString(wxPython_dict
, "PyAssertionError", wxPyAssertionError
); 
 597     // Create an exception object to use when the app object hasn't been created yet 
 598     wxPyNoAppError 
= PyErr_NewException("wx._core.PyNoAppError", 
 599                                         PyExc_RuntimeError
, NULL
); 
 600     PyDict_SetItemString(wxPython_dict
, "PyNoAppError", wxPyNoAppError
); 
 605 #define wxPlatform "__WXMOTIF__" 
 606 #define wxPlatName "wxMotif" 
 609 #define wxPlatform "__WXX11__" 
 610 #define wxPlatName "wxX11" 
 613 #define wxPlatform "__WXGTK__" 
 614 #define wxPlatName "wxGTK" 
 617 #define wxPlatform "__WXMSW__" 
 618 #define wxPlatName "wxMSW" 
 621 #define wxPlatform "__WXMAC__" 
 622 #define wxPlatName "wxMac" 
 631     // These should be deprecated in favor of the PlatformInfo tuple built below... 
 632     PyDict_SetItemString(wxPython_dict
, "Platform", PyString_FromString(wxPlatform
)); 
 633     PyDict_SetItemString(wxPython_dict
, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE
)); 
 634     PyDict_SetItemString(wxPython_dict
, "__WXDEBUG__", PyInt_FromLong(wxdebug
)); 
 637     PyObject
* PlatInfo 
= PyList_New(0); 
 640 #define _AddInfoString(st) \ 
 641     obj = PyString_FromString(st); \ 
 642     PyList_Append(PlatInfo, obj); \ 
 645     _AddInfoString(wxPlatform
); 
 646     _AddInfoString(wxPlatName
); 
 648     _AddInfoString("unicode"); 
 650     _AddInfoString("ascii"); 
 654     _AddInfoString("gtk2"); 
 656     _AddInfoString("gtk1"); 
 660     _AddInfoString("wx-assertions-on"); 
 662     _AddInfoString("wx-assertions-off"); 
 665 #undef _AddInfoString 
 667     PyObject
* PlatInfoTuple 
= PyList_AsTuple(PlatInfo
); 
 669     PyDict_SetItemString(wxPython_dict
, "PlatformInfo", PlatInfoTuple
); 
 675 //--------------------------------------------------------------------------- 
 677 // Python's PyInstance_Check does not return True for instances of new-style 
 678 // classes.  This should get close enough for both new and old classes but I 
 679 // should re-evaluate the need for doing instance checks... 
 680 bool wxPyInstance_Check(PyObject
* obj
) { 
 681     return PyObject_HasAttrString(obj
, "__class__") != 0; 
 685 // This one checks if the object is an instance of a SWIG proxy class (it has 
 686 // a .this attribute) 
 687 bool wxPySwigInstance_Check(PyObject
* obj
) { 
 688     return PyObject_HasAttrString(obj
, "this") != 0; 
 691 //--------------------------------------------------------------------------- 
 693 // The stock objects are no longer created when the wx._core_ module is 
 694 // imported, but only after the app object has been created.  The 
 695 // wxPy_ReinitStockObjects function will be called 3 times to pass the stock 
 696 // objects though various stages of evolution: 
 698 //   pass 1: Set all the pointers to a non-NULL value so the Python proxy 
 699 //           object will be created (otherwise SWIG will just use None.) 
 701 //   pass 2: After the module has been imported and the python proxys have 
 702 //           been created, then set the __class__ to be _wxPyUnbornObject so 
 703 //           it will catch any access to the object and will raise an exception. 
 705 //   pass 3: Finally, from BootstrapApp patch things up so the stock objects 
 709 PyObject
* __wxPyFixStockObjects(PyObject
* /* self */, PyObject
* args
) 
 711     wxPy_ReinitStockObjects(2); 
 716 static void rsoPass2(const char* name
) 
 718     static PyObject
* unbornObjectClass 
= NULL
; 
 721     if (unbornObjectClass 
== NULL
) { 
 722         unbornObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyUnbornObject"); 
 723         Py_INCREF(unbornObjectClass
); 
 726     // Find the object instance 
 727     obj 
= PyDict_GetItemString(wxPython_dict
, (char*)dropwx(name
)); 
 728     wxCHECK_RET(obj 
!= NULL
, wxT("Unable to find stock object")); 
 729     wxCHECK_RET(wxPySwigInstance_Check(obj
), wxT("Not a swig instance")); 
 732     PyObject_SetAttrString(obj
, "__class__",  unbornObjectClass
); 
 736 static void rsoPass3(const char* name
, const char* classname
, void* ptr
) 
 742     // Find the object instance 
 743     obj 
= PyDict_GetItemString(wxPython_dict
, (char*)dropwx(name
)); 
 744     wxCHECK_RET(obj 
!= NULL
, wxT("Unable to find stock object")); 
 745     wxCHECK_RET(wxPySwigInstance_Check(obj
), wxT("Not a swig instance")); 
 747     // Find the class object and put it back in the instance 
 748     classobj 
= PyDict_GetItemString(wxPython_dict
, (char*)dropwx(classname
)); 
 749     wxCHECK_RET(classobj 
!= NULL
, wxT("Unable to find stock class object")); 
 750     PyObject_SetAttrString(obj
, "__class__",  classobj
); 
 752     // Rebuild the .this swigified pointer with the new value of the C++ pointer 
 753     ptrobj 
= wxPyMakeSwigPtr(ptr
, wxString(classname
, *wxConvCurrent
)); 
 754     PyObject_SetAttrString(obj
, "this", ptrobj
); 
 760 void wxPy_ReinitStockObjects(int pass
) 
 763     // If there is already an App object then wxPython is probably embedded in 
 764     // a wx C++ application, so there is no need to do all this. 
 765     static bool embedded 
= false; 
 766     if ((pass 
== 1 || pass 
== 2) && wxTheApp
) { 
 770     if (pass 
== 3 && embedded
) 
 774 #define REINITOBJ(name, classname) \ 
 775     if (pass == 1) { name = (classname*)0xC0C0C0C0; } \ 
 776     else if (pass == 2) { rsoPass2(#name); } \ 
 777     else if (pass == 3) { rsoPass3(#name, #classname, (void*)name); } 
 780 #define REINITOBJ2(name, classname) \ 
 782     else if (pass == 2) { rsoPass2(#name); } \ 
 783     else if (pass == 3) { rsoPass3(#name, #classname, (void*)&name); } 
 786     REINITOBJ(wxNORMAL_FONT
, wxFont
); 
 787     REINITOBJ(wxSMALL_FONT
, wxFont
); 
 788     REINITOBJ(wxITALIC_FONT
, wxFont
); 
 789     REINITOBJ(wxSWISS_FONT
, wxFont
); 
 791     REINITOBJ(wxRED_PEN
, wxPen
); 
 792     REINITOBJ(wxCYAN_PEN
, wxPen
); 
 793     REINITOBJ(wxGREEN_PEN
, wxPen
); 
 794     REINITOBJ(wxBLACK_PEN
, wxPen
); 
 795     REINITOBJ(wxWHITE_PEN
, wxPen
); 
 796     REINITOBJ(wxTRANSPARENT_PEN
, wxPen
); 
 797     REINITOBJ(wxBLACK_DASHED_PEN
, wxPen
); 
 798     REINITOBJ(wxGREY_PEN
, wxPen
); 
 799     REINITOBJ(wxMEDIUM_GREY_PEN
, wxPen
); 
 800     REINITOBJ(wxLIGHT_GREY_PEN
, wxPen
); 
 802     REINITOBJ(wxBLUE_BRUSH
, wxBrush
); 
 803     REINITOBJ(wxGREEN_BRUSH
, wxBrush
); 
 804     REINITOBJ(wxWHITE_BRUSH
, wxBrush
); 
 805     REINITOBJ(wxBLACK_BRUSH
, wxBrush
); 
 806     REINITOBJ(wxTRANSPARENT_BRUSH
, wxBrush
); 
 807     REINITOBJ(wxCYAN_BRUSH
, wxBrush
); 
 808     REINITOBJ(wxRED_BRUSH
, wxBrush
); 
 809     REINITOBJ(wxGREY_BRUSH
, wxBrush
); 
 810     REINITOBJ(wxMEDIUM_GREY_BRUSH
, wxBrush
); 
 811     REINITOBJ(wxLIGHT_GREY_BRUSH
, wxBrush
); 
 813     REINITOBJ(wxBLACK
, wxColour
); 
 814     REINITOBJ(wxWHITE
, wxColour
); 
 815     REINITOBJ(wxRED
, wxColour
); 
 816     REINITOBJ(wxBLUE
, wxColour
); 
 817     REINITOBJ(wxGREEN
, wxColour
); 
 818     REINITOBJ(wxCYAN
, wxColour
); 
 819     REINITOBJ(wxLIGHT_GREY
, wxColour
); 
 821     REINITOBJ(wxSTANDARD_CURSOR
, wxCursor
); 
 822     REINITOBJ(wxHOURGLASS_CURSOR
, wxCursor
); 
 823     REINITOBJ(wxCROSS_CURSOR
, wxCursor
); 
 825     REINITOBJ2(wxNullBitmap
, wxBitmap
); 
 826     REINITOBJ2(wxNullIcon
, wxIcon
); 
 827     REINITOBJ2(wxNullCursor
, wxCursor
); 
 828     REINITOBJ2(wxNullPen
, wxPen
); 
 829     REINITOBJ2(wxNullBrush
, wxBrush
); 
 830     REINITOBJ2(wxNullPalette
, wxPalette
); 
 831     REINITOBJ2(wxNullFont
, wxFont
); 
 832     REINITOBJ2(wxNullColour
, wxColour
); 
 834     REINITOBJ(wxTheFontList
, wxFontList
); 
 835     REINITOBJ(wxThePenList
, wxPenList
); 
 836     REINITOBJ(wxTheBrushList
, wxBrushList
); 
 837     REINITOBJ(wxTheColourDatabase
, wxColourDatabase
); 
 840     REINITOBJ2(wxDefaultValidator
, wxValidator
); 
 841     REINITOBJ2(wxNullImage
, wxImage
); 
 842     REINITOBJ2(wxNullAcceleratorTable
, wxAcceleratorTable
); 
 848 //--------------------------------------------------------------------------- 
 850 // Check for existence of a wxApp, setting an exception if there isn't one. 
 851 // This doesn't need to aquire the GIL because it should only be called from 
 852 // an %exception before the lock is released. 
 854 bool wxPyCheckForApp() { 
 855     if (wxTheApp 
!= NULL
) 
 858         PyErr_SetString(wxPyNoAppError
, "The wx.App object must be created first!"); 
 863 //--------------------------------------------------------------------------- 
 866 void wxPyClientData_dtor(wxPyClientData
* self
) { 
 867     if (! wxPyDoingCleanup
) {           // Don't do it during cleanup as Python 
 868                                         // may have already garbage collected the object... 
 869         bool blocked 
= wxPyBeginBlockThreads(); 
 870         Py_DECREF(self
->m_obj
); 
 872         wxPyEndBlockThreads(blocked
); 
 876 void wxPyUserData_dtor(wxPyUserData
* self
) { 
 877     if (! wxPyDoingCleanup
) { 
 878         bool blocked 
= wxPyBeginBlockThreads(); 
 879         Py_DECREF(self
->m_obj
); 
 881         wxPyEndBlockThreads(blocked
); 
 886 // This is called when an OOR controled object is being destroyed.  Although 
 887 // the C++ object is going away there is no way to force the Python object 
 888 // (and all references to it) to die too.  This causes problems (crashes) in 
 889 // wxPython when a python shadow object attempts to call a C++ method using 
 890 // the now bogus pointer... So to try and prevent this we'll do a little black 
 891 // magic and change the class of the python instance to a class that will 
 892 // raise an exception for any attempt to call methods with it.  See 
 893 // _wxPyDeadObject in _core_ex.py for the implementation of this class. 
 894 void wxPyOORClientData_dtor(wxPyOORClientData
* self
) { 
 896     static PyObject
* deadObjectClass 
= NULL
; 
 898     bool blocked 
= wxPyBeginBlockThreads(); 
 899     if (deadObjectClass 
== NULL
) { 
 900         deadObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyDeadObject"); 
 901         // TODO:  Can not wxASSERT here because inside a wxPyBeginBlock Threads, 
 902         // will lead to a deadlock when it tries to aquire the GIL again. 
 903         //wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!")); 
 904         Py_INCREF(deadObjectClass
); 
 908     // Only if there is more than one reference to the object 
 909     if ( !wxPyDoingCleanup 
&& self
->m_obj
->ob_refcnt 
> 1 ) { 
 910         // bool isInstance = wxPyInstance_Check(self->m_obj); 
 912         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!")); 
 914         // Call __del__, if there is one. 
 915         PyObject
* func 
= PyObject_GetAttrString(self
->m_obj
, "__del__"); 
 917             PyObject
* rv 
= PyObject_CallMethod(self
->m_obj
, "__del__", NULL
); 
 921         if (PyErr_Occurred()) 
 922             PyErr_Clear();      // just ignore it for now 
 925         PyObject
* dict 
= PyObject_GetAttrString(self
->m_obj
, "__dict__"); 
 927             // Clear the instance's dictionary 
 930             // put the name of the old class into the instance, and then reset the 
 931             // class to be the dead class. 
 932             PyObject
* klass 
= PyObject_GetAttrString(self
->m_obj
, "__class__"); 
 933             PyObject
* name 
=  PyObject_GetAttrString(klass
, "__name__"); 
 934             PyDict_SetItemString(dict
, "_name", name
); 
 935             PyObject_SetAttrString(self
->m_obj
, "__class__",  deadObjectClass
); 
 936             //Py_INCREF(deadObjectClass); 
 942     // m_obj is DECREF'd in the base class dtor... 
 943     wxPyEndBlockThreads(blocked
); 
 947 //--------------------------------------------------------------------------- 
 948 // Stuff used by OOR to find the right wxPython class type to return and to 
 952 // The pointer type map is used when the "pointer" type name generated by SWIG 
 953 // is not the same as the shadow class name, for example wxPyTreeCtrl 
 954 // vs. wxTreeCtrl.  It needs to be referenced in Python as well as from C++, 
 955 // so we'll just make it a Python dictionary in the wx module's namespace. 
 956 // (See __wxSetDictionary) 
 957 void wxPyPtrTypeMap_Add(const char* commonName
, const char* ptrName
) { 
 958     if (! wxPyPtrTypeMap
) 
 959         wxPyPtrTypeMap 
= PyDict_New(); 
 960     PyDict_SetItemString(wxPyPtrTypeMap
, 
 962                          PyString_FromString((char*)ptrName
)); 
 968 PyObject
*  wxPyMake_wxObject(wxObject
* source
, bool setThisOwn
, bool checkEvtHandler
) { 
 969     PyObject
* target 
= NULL
; 
 970     bool      isEvtHandler 
= false; 
 973         // If it's derived from wxEvtHandler then there may 
 974         // already be a pointer to a Python object that we can use 
 976         if (checkEvtHandler 
&& wxIsKindOf(source
, wxEvtHandler
)) { 
 978             wxEvtHandler
* eh 
= (wxEvtHandler
*)source
; 
 979             wxPyOORClientData
* data 
= (wxPyOORClientData
*)eh
->GetClientObject(); 
 981                 target 
= data
->m_obj
; 
 988             // Otherwise make it the old fashioned way by making a new shadow 
 989             // object and putting this pointer in it.  Look up the class 
 990             // heirarchy until we find a class name that is located in the 
 992             const wxClassInfo
* info   
= source
->GetClassInfo(); 
 993             wxString           name   
= info
->GetClassName(); 
 994             bool               exists 
= wxPyCheckSwigType(name
); 
 995             while (info 
&& !exists
) { 
 996                 info 
= info
->GetBaseClass1(); 
 997                 name 
= info
->GetClassName(); 
 998                 exists 
= wxPyCheckSwigType(name
); 
1001                 target 
= wxPyConstructObject((void*)source
, name
, setThisOwn
); 
1002                 if (target 
&& isEvtHandler
) 
1003                     ((wxEvtHandler
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
1005                 wxString 
msg(wxT("wxPython class not found for ")); 
1006                 msg 
+= source
->GetClassInfo()->GetClassName(); 
1007                 PyErr_SetString(PyExc_NameError
, msg
.mbc_str()); 
1011     } else {  // source was NULL so return None. 
1012         Py_INCREF(Py_None
); target 
= Py_None
; 
1018 PyObject
*  wxPyMake_wxSizer(wxSizer
* source
, bool setThisOwn
) { 
1019     PyObject
* target 
= NULL
; 
1021     if (source 
&& wxIsKindOf(source
, wxSizer
)) { 
1022         // If it's derived from wxSizer then there may already be a pointer to 
1023         // a Python object that we can use in the OOR data. 
1024         wxSizer
* sz 
= (wxSizer
*)source
; 
1025         wxPyOORClientData
* data 
= (wxPyOORClientData
*)sz
->GetClientObject(); 
1027             target 
= data
->m_obj
; 
1033         target 
= wxPyMake_wxObject(source
, setThisOwn
, false); 
1034         if (target 
!= Py_None
) 
1035             ((wxSizer
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
1041 //--------------------------------------------------------------------------- 
1044 #ifdef WXP_WITH_THREAD 
1046 unsigned long wxPyGetCurrentThreadId() { 
1047     return wxThread::GetCurrentId(); 
1050 static wxPyThreadState gs_shutdownTState
; 
1053 wxPyThreadState
* wxPyGetThreadState() { 
1054     if (wxPyTMutex 
== NULL
) // Python is shutting down... 
1055         return &gs_shutdownTState
; 
1057     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
1058     wxPyThreadState
* tstate 
= NULL
; 
1061     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
1062         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
1063         if (info
.tid 
== ctid
) { 
1068     wxPyTMutex
->Unlock(); 
1069     wxASSERT_MSG(tstate
, wxT("PyThreadState should not be NULL!")); 
1075 void wxPySaveThreadState(PyThreadState
* tstate
) { 
1076     if (wxPyTMutex 
== NULL
) { // Python is shutting down, assume a single thread... 
1077         gs_shutdownTState
.tstate 
= tstate
; 
1080     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
1082     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
1083         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
1084         if (info
.tid 
== ctid
) { 
1086             if (info
.tstate 
!= tstate
) 
1087                 wxLogMessage("*** tstate mismatch!???"); 
1089             // info.tstate = tstate;    *** DO NOT update existing ones??? 
1090             // Normally it will never change, but apparently COM callbacks 
1091             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient 
1092             // tstate which will then be garbage the next time we try to use 
1094             wxPyTMutex
->Unlock(); 
1098     // not found, so add it... 
1099     wxPyTStates
->Add(new wxPyThreadState(ctid
, tstate
)); 
1100     wxPyTMutex
->Unlock(); 
1107 // Calls from Python to wxWindows code are wrapped in calls to these 
1110 PyThreadState
* wxPyBeginAllowThreads() { 
1111 #ifdef WXP_WITH_THREAD 
1112     PyThreadState
* saved 
= PyEval_SaveThread();  // Py_BEGIN_ALLOW_THREADS; 
1113     wxPySaveThreadState(saved
); 
1120 void wxPyEndAllowThreads(PyThreadState
* saved
) { 
1121 #ifdef WXP_WITH_THREAD 
1122     PyEval_RestoreThread(saved
);   // Py_END_ALLOW_THREADS; 
1128 // Calls from wxWindows back to Python code, or even any PyObject 
1129 // manipulations, PyDECREF's and etc. are wrapped in calls to these functions: 
1131 bool wxPyBeginBlockThreads() { 
1132 #ifdef WXP_WITH_THREAD 
1133     // This works in for 2.3, maybe a good alternative to find the needed tstate? 
1134     // PyThreadState *check = PyGILState_GetThisThreadState();   
1136     PyThreadState 
*current 
= _PyThreadState_Current
; 
1138     // Only block if there wasn't already a tstate, or if the current one is 
1139     // not the one we are wanting to change to.  This should prevent deadlock 
1140     // if there are nested calls to wxPyBeginBlockThreads 
1141     bool blocked 
= false; 
1142     wxPyThreadState
* tstate 
= wxPyGetThreadState(); 
1143     if (current 
!= tstate
->tstate
) { 
1144         PyEval_RestoreThread(tstate
->tstate
); 
1152 void wxPyEndBlockThreads(bool blocked
) { 
1153 #ifdef WXP_WITH_THREAD 
1154     // Only unblock if we blocked in the last call to wxPyBeginBlockThreads. 
1155     // The value of blocked passed in needs to be the same as that returned 
1156     // from wxPyBeginBlockThreads at the same nesting level. 
1158         PyEval_SaveThread(); 
1164 //--------------------------------------------------------------------------- 
1165 // wxPyInputStream and wxPyCBInputStream methods 
1168 void wxPyInputStream::close() { 
1169     /* do nothing for now */ 
1172 void wxPyInputStream::flush() { 
1173     /* do nothing for now */ 
1176 bool wxPyInputStream::eof() { 
1178         return m_wxis
->Eof(); 
1183 wxPyInputStream::~wxPyInputStream() { 
1190 PyObject
* wxPyInputStream::read(int size
) { 
1191     PyObject
* obj 
= NULL
; 
1193     const int BUFSIZE 
= 1024; 
1195     // check if we have a real wxInputStream to work with 
1197         bool blocked 
= wxPyBeginBlockThreads(); 
1198         PyErr_SetString(PyExc_IOError
, "no valid C-wxInputStream"); 
1199         wxPyEndBlockThreads(blocked
); 
1204         // read while bytes are available on the stream 
1205         while ( m_wxis
->CanRead() ) { 
1206             m_wxis
->Read(buf
.GetAppendBuf(BUFSIZE
), BUFSIZE
); 
1207             buf
.UngetAppendBuf(m_wxis
->LastRead()); 
1210     } else {  // Read only size number of characters 
1211         m_wxis
->Read(buf
.GetWriteBuf(size
), size
); 
1212         buf
.UngetWriteBuf(m_wxis
->LastRead()); 
1216     bool blocked 
= wxPyBeginBlockThreads(); 
1217     wxStreamError err 
= m_wxis
->GetLastError(); 
1218     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1219         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1222         // We use only strings for the streams, not unicode 
1223         obj 
= PyString_FromStringAndSize(buf
, buf
.GetDataLen()); 
1225     wxPyEndBlockThreads(blocked
); 
1230 PyObject
* wxPyInputStream::readline(int size
) { 
1231     PyObject
* obj 
= NULL
; 
1236     // check if we have a real wxInputStream to work with 
1238         bool blocked 
= wxPyBeginBlockThreads(); 
1239         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1240         wxPyEndBlockThreads(blocked
); 
1244     // read until \n or byte limit reached 
1245     for (i
=ch
=0; (ch 
!= '\n') && (m_wxis
->CanRead()) && ((size 
< 0) || (i 
< size
)); i
++) { 
1246         ch 
= m_wxis
->GetC(); 
1251     bool blocked 
= wxPyBeginBlockThreads(); 
1252     wxStreamError err 
= m_wxis
->GetLastError(); 
1253     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1254         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1257         // We use only strings for the streams, not unicode 
1258         obj 
= PyString_FromStringAndSize((char*)buf
.GetData(), buf
.GetDataLen()); 
1260     wxPyEndBlockThreads(blocked
); 
1265 PyObject
* wxPyInputStream::readlines(int sizehint
) { 
1268     // check if we have a real wxInputStream to work with 
1270         bool blocked 
= wxPyBeginBlockThreads(); 
1271         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1272         wxPyEndBlockThreads(blocked
); 
1277     bool blocked 
= wxPyBeginBlockThreads(); 
1278     pylist 
= PyList_New(0); 
1279     wxPyEndBlockThreads(blocked
); 
1282         bool blocked 
= wxPyBeginBlockThreads(); 
1284         wxPyEndBlockThreads(blocked
); 
1288     // read sizehint bytes or until EOF 
1290     for (i
=0; (m_wxis
->CanRead()) && ((sizehint 
< 0) || (i 
< sizehint
));) { 
1291         PyObject
* s 
= this->readline(); 
1293             bool blocked 
= wxPyBeginBlockThreads(); 
1295             wxPyEndBlockThreads(blocked
); 
1298         bool blocked 
= wxPyBeginBlockThreads(); 
1299         PyList_Append(pylist
, s
); 
1300         i 
+= PyString_Size(s
); 
1301         wxPyEndBlockThreads(blocked
); 
1305     wxStreamError err 
= m_wxis
->GetLastError(); 
1306     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1307         bool blocked 
= wxPyBeginBlockThreads(); 
1309         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1310         wxPyEndBlockThreads(blocked
); 
1318 void wxPyInputStream::seek(int offset
, int whence
) { 
1320         m_wxis
->SeekI(offset
, wxSeekMode(whence
)); 
1323 int wxPyInputStream::tell(){ 
1325         return m_wxis
->TellI(); 
1332 wxPyCBInputStream::wxPyCBInputStream(PyObject 
*r
, PyObject 
*s
, PyObject 
*t
, bool block
) 
1333     : wxInputStream(), m_read(r
), m_seek(s
), m_tell(t
), m_block(block
) 
1337 wxPyCBInputStream::~wxPyCBInputStream() { 
1339     if (m_block
) blocked 
= wxPyBeginBlockThreads(); 
1343     if (m_block
) wxPyEndBlockThreads(blocked
); 
1347 wxPyCBInputStream
* wxPyCBInputStream::create(PyObject 
*py
, bool block
) { 
1349     if (block
) blocked 
= wxPyBeginBlockThreads(); 
1351     PyObject
* read 
= getMethod(py
, "read"); 
1352     PyObject
* seek 
= getMethod(py
, "seek"); 
1353     PyObject
* tell 
= getMethod(py
, "tell"); 
1356         PyErr_SetString(PyExc_TypeError
, "Not a file-like object"); 
1360         if (block
) wxPyEndBlockThreads(blocked
); 
1364     if (block
) wxPyEndBlockThreads(blocked
); 
1365     return new wxPyCBInputStream(read
, seek
, tell
, block
); 
1369 wxPyCBInputStream
* wxPyCBInputStream_create(PyObject 
*py
, bool block
) { 
1370     return wxPyCBInputStream::create(py
, block
); 
1373 PyObject
* wxPyCBInputStream::getMethod(PyObject
* py
, char* name
) { 
1374     if (!PyObject_HasAttrString(py
, name
)) 
1376     PyObject
* o 
= PyObject_GetAttrString(py
, name
); 
1377     if (!PyMethod_Check(o
) && !PyCFunction_Check(o
)) { 
1385 size_t wxPyCBInputStream::GetSize() const { 
1386     wxPyCBInputStream
* self 
= (wxPyCBInputStream
*)this; // cast off const 
1387     if (m_seek 
&& m_tell
) { 
1388         off_t temp 
= self
->OnSysTell(); 
1389         off_t ret 
= self
->OnSysSeek(0, wxFromEnd
); 
1390         self
->OnSysSeek(temp
, wxFromStart
); 
1398 size_t wxPyCBInputStream::OnSysRead(void *buffer
, size_t bufsize
) { 
1402     bool blocked 
= wxPyBeginBlockThreads(); 
1403     PyObject
* arglist 
= Py_BuildValue("(i)", bufsize
); 
1404     PyObject
* result 
= PyEval_CallObject(m_read
, arglist
); 
1408     if ((result 
!= NULL
) && PyString_Check(result
)) { 
1409         o 
= PyString_Size(result
); 
1411             m_lasterror 
= wxSTREAM_EOF
; 
1414         memcpy((char*)buffer
, PyString_AsString(result
), o
);  // strings only, not unicode... 
1419         m_lasterror 
= wxSTREAM_READ_ERROR
; 
1420     wxPyEndBlockThreads(blocked
); 
1424 size_t wxPyCBInputStream::OnSysWrite(const void *buffer
, size_t bufsize
) { 
1425     m_lasterror 
= wxSTREAM_WRITE_ERROR
; 
1429 off_t 
wxPyCBInputStream::OnSysSeek(off_t off
, wxSeekMode mode
) { 
1430     bool blocked 
= wxPyBeginBlockThreads(); 
1432     // off_t is a 64-bit value... 
1433     PyObject
* arglist 
= Py_BuildValue("(Li)", off
, mode
); 
1435     PyObject
* arglist 
= Py_BuildValue("(ii)", off
, mode
); 
1437     PyObject
* result 
= PyEval_CallObject(m_seek
, arglist
); 
1440     wxPyEndBlockThreads(blocked
); 
1445 off_t 
wxPyCBInputStream::OnSysTell() const { 
1446     bool blocked 
= wxPyBeginBlockThreads(); 
1447     PyObject
* arglist 
= Py_BuildValue("()"); 
1448     PyObject
* result 
= PyEval_CallObject(m_tell
, arglist
); 
1451     if (result 
!= NULL
) { 
1453         if (PyLong_Check(result
)) 
1454             o 
= PyLong_AsLongLong(result
); 
1457             o 
= PyInt_AsLong(result
); 
1460     wxPyEndBlockThreads(blocked
); 
1464 //---------------------------------------------------------------------- 
1466 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback
, wxObject
); 
1468 wxPyCallback::wxPyCallback(PyObject
* func
) { 
1473 wxPyCallback::wxPyCallback(const wxPyCallback
& other
) { 
1474     m_func 
= other
.m_func
; 
1478 wxPyCallback::~wxPyCallback() { 
1479     bool blocked 
= wxPyBeginBlockThreads(); 
1481     wxPyEndBlockThreads(blocked
); 
1485 #define wxPy_PRECALLINIT     "_preCallInit" 
1486 #define wxPy_POSTCALLCLEANUP "_postCallCleanup" 
1488 // This function is used for all events destined for Python event handlers. 
1489 void wxPyCallback::EventThunker(wxEvent
& event
) { 
1490     wxPyCallback
*   cb 
= (wxPyCallback
*)event
.m_callbackUserData
; 
1491     PyObject
*       func 
= cb
->m_func
; 
1495     bool            checkSkip 
= false; 
1497     bool blocked 
= wxPyBeginBlockThreads(); 
1498     wxString className 
= event
.GetClassInfo()->GetClassName(); 
1500     // If the event is one of these types then pass the original 
1501     // event object instead of the one passed to us. 
1502     if ( className 
== wxT("wxPyEvent") ) { 
1503         arg 
=       ((wxPyEvent
*)&event
)->GetSelf(); 
1504         checkSkip 
= ((wxPyEvent
*)&event
)->GetCloned(); 
1506     else if ( className 
== wxT("wxPyCommandEvent") ) { 
1507         arg 
=       ((wxPyCommandEvent
*)&event
)->GetSelf(); 
1508         checkSkip 
= ((wxPyCommandEvent
*)&event
)->GetCloned(); 
1511         arg 
= wxPyConstructObject((void*)&event
, className
); 
1517         // "intern" the pre/post method names to speed up the HasAttr 
1518         static PyObject
* s_preName  
= NULL
; 
1519         static PyObject
* s_postName 
= NULL
; 
1520         if (s_preName 
== NULL
) { 
1521             s_preName  
= PyString_FromString(wxPy_PRECALLINIT
); 
1522             s_postName 
= PyString_FromString(wxPy_POSTCALLCLEANUP
); 
1525         // Check if the event object needs some preinitialization 
1526         if (PyObject_HasAttr(arg
, s_preName
)) { 
1527             result 
= PyObject_CallMethodObjArgs(arg
, s_preName
, arg
, NULL
); 
1529                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1530                 PyErr_Clear();       // Just in case... 
1536         // Call the event handler, passing the event object 
1537         tuple 
= PyTuple_New(1); 
1538         PyTuple_SET_ITEM(tuple
, 0, arg
);  // steals ref to arg 
1539         result 
= PyEval_CallObject(func
, tuple
); 
1541             Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1542             PyErr_Clear();       // Just in case... 
1547         // Check if the event object needs some post cleanup 
1548         if (PyObject_HasAttr(arg
, s_postName
)) { 
1549             result 
= PyObject_CallMethodObjArgs(arg
, s_postName
, arg
, NULL
); 
1551                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1552                 PyErr_Clear();       // Just in case... 
1559             // if the event object was one of our special types and 
1560             // it had been cloned, then we need to extract the Skipped 
1561             // value from the original and set it in the clone. 
1562             result 
= PyObject_CallMethod(arg
, "GetSkipped", ""); 
1564                 event
.Skip(PyInt_AsLong(result
)); 
1572     wxPyEndBlockThreads(blocked
); 
1576 //---------------------------------------------------------------------- 
1578 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper
& other
) { 
1580       m_self 
= other
.m_self
; 
1581       m_class 
= other
.m_class
; 
1589 void wxPyCallbackHelper::setSelf(PyObject
* self
, PyObject
* klass
, int incref
) { 
1600 #if PYTHON_API_VERSION >= 1011 
1602 // Prior to Python 2.2 PyMethod_GetClass returned the class object 
1603 // in which the method was defined.  Starting with 2.2 it returns 
1604 // "class that asked for the method" which seems totally bogus to me 
1605 // but apprently it fixes some obscure problem waiting to happen in 
1606 // Python.  Since the API was not documented Guido and the gang felt 
1607 // safe in changing it.  Needless to say that totally screwed up the 
1608 // logic below in wxPyCallbackHelper::findCallback, hence this icky 
1609 // code to find the class where the method is actually defined... 
1612 PyObject
* PyFindClassWithAttr(PyObject 
*klass
, PyObject 
*name
) 
1616     if (PyType_Check(klass
)) {      // new style classes 
1617         // This code is borrowed/adapted from _PyType_Lookup in typeobject.c 
1618         PyTypeObject
* type 
= (PyTypeObject
*)klass
; 
1619         PyObject 
*mro
, *res
, *base
, *dict
; 
1620         /* Look in tp_dict of types in MRO */ 
1622         assert(PyTuple_Check(mro
)); 
1623         n 
= PyTuple_GET_SIZE(mro
); 
1624         for (i 
= 0; i 
< n
; i
++) { 
1625             base 
= PyTuple_GET_ITEM(mro
, i
); 
1626             if (PyClass_Check(base
)) 
1627                 dict 
= ((PyClassObject 
*)base
)->cl_dict
; 
1629                 assert(PyType_Check(base
)); 
1630                 dict 
= ((PyTypeObject 
*)base
)->tp_dict
; 
1632             assert(dict 
&& PyDict_Check(dict
)); 
1633             res 
= PyDict_GetItem(dict
, name
); 
1640     else if (PyClass_Check(klass
)) { // old style classes 
1641         // This code is borrowed/adapted from class_lookup in classobject.c 
1642         PyClassObject
* cp 
= (PyClassObject
*)klass
; 
1643         PyObject 
*value 
= PyDict_GetItem(cp
->cl_dict
, name
); 
1644         if (value 
!= NULL
) { 
1645             return (PyObject
*)cp
; 
1647         n 
= PyTuple_Size(cp
->cl_bases
); 
1648         for (i 
= 0; i 
< n
; i
++) { 
1649             PyObject
* base 
= PyTuple_GetItem(cp
->cl_bases
, i
); 
1650             PyObject 
*v 
= PyFindClassWithAttr(base
, name
); 
1662 PyObject
* PyMethod_GetDefiningClass(PyObject
* method
, const char* name
) 
1664     PyObject
* mgc 
= PyMethod_GET_CLASS(method
); 
1666 #if PYTHON_API_VERSION <= 1010    // prior to Python 2.2, the easy way 
1668 #else                             // 2.2 and after, the hard way... 
1670     PyObject
* nameo 
= PyString_FromString(name
); 
1671     PyObject
* klass 
= PyFindClassWithAttr(mgc
, nameo
); 
1679 bool wxPyCallbackHelper::findCallback(const char* name
) const { 
1680     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
1681     self
->m_lastFound 
= NULL
; 
1683     // If the object (m_self) has an attibute of the given name... 
1684     if (m_self 
&& PyObject_HasAttrString(m_self
, (char*)name
)) { 
1685         PyObject 
*method
, *klass
; 
1686         method 
= PyObject_GetAttrString(m_self
, (char*)name
); 
1688         // ...and if that attribute is a method, and if that method's class is 
1689         // not from a base class... 
1690         if (PyMethod_Check(method
) && 
1691             (klass 
= PyMethod_GetDefiningClass(method
, (char*)name
)) != NULL 
&& 
1692             ((klass 
== m_class
) || PyObject_IsSubclass(klass
, m_class
))) { 
1694             // ...then we'll save a pointer to the method so callCallback can call it. 
1695             self
->m_lastFound 
= method
; 
1701     return m_lastFound 
!= NULL
; 
1705 int wxPyCallbackHelper::callCallback(PyObject
* argTuple
) const { 
1709     result 
= callCallbackObj(argTuple
); 
1710     if (result
) {                       // Assumes an integer return type... 
1711         retval 
= PyInt_AsLong(result
); 
1713         PyErr_Clear();                  // forget about it if it's not... 
1718 // Invoke the Python callable object, returning the raw PyObject return 
1719 // value.  Caller should DECREF the return value and also manage the GIL. 
1720 PyObject
* wxPyCallbackHelper::callCallbackObj(PyObject
* argTuple
) const { 
1723     // Save a copy of the pointer in case the callback generates another 
1724     // callback.  In that case m_lastFound will have a different value when 
1725     // it gets back here... 
1726     PyObject
* method 
= m_lastFound
; 
1728     result 
= PyEval_CallObject(method
, argTuple
); 
1729     Py_DECREF(argTuple
); 
1738 void wxPyCBH_setCallbackInfo(wxPyCallbackHelper
& cbh
, PyObject
* self
, PyObject
* klass
, int incref
) { 
1739     cbh
.setSelf(self
, klass
, incref
); 
1742 bool wxPyCBH_findCallback(const wxPyCallbackHelper
& cbh
, const char* name
) { 
1743     return cbh
.findCallback(name
); 
1746 int  wxPyCBH_callCallback(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1747     return cbh
.callCallback(argTuple
); 
1750 PyObject
* wxPyCBH_callCallbackObj(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1751     return cbh
.callCallbackObj(argTuple
); 
1755 void wxPyCBH_delete(wxPyCallbackHelper
* cbh
) { 
1756     if (cbh
->m_incRef
) { 
1757         bool blocked 
= wxPyBeginBlockThreads(); 
1758         Py_XDECREF(cbh
->m_self
); 
1759         Py_XDECREF(cbh
->m_class
); 
1760         wxPyEndBlockThreads(blocked
); 
1764 //--------------------------------------------------------------------------- 
1765 //--------------------------------------------------------------------------- 
1766 // These event classes can be derived from in Python and passed through the event 
1767 // system without losing anything.  They do this by keeping a reference to 
1768 // themselves and some special case handling in wxPyCallback::EventThunker. 
1771 wxPyEvtSelfRef::wxPyEvtSelfRef() { 
1772     //m_self = Py_None;         // **** We don't do normal ref counting to prevent 
1773     //Py_INCREF(m_self);        //      circular loops... 
1777 wxPyEvtSelfRef::~wxPyEvtSelfRef() { 
1778     bool blocked 
= wxPyBeginBlockThreads(); 
1781     wxPyEndBlockThreads(blocked
); 
1784 void wxPyEvtSelfRef::SetSelf(PyObject
* self
, bool clone
) { 
1785     bool blocked 
= wxPyBeginBlockThreads(); 
1793     wxPyEndBlockThreads(blocked
); 
1796 PyObject
* wxPyEvtSelfRef::GetSelf() const { 
1802 IMPLEMENT_ABSTRACT_CLASS(wxPyEvent
, wxEvent
); 
1803 IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent
, wxCommandEvent
); 
1806 wxPyEvent::wxPyEvent(int winid
, wxEventType commandType
) 
1807     : wxEvent(winid
, commandType
) { 
1811 wxPyEvent::wxPyEvent(const wxPyEvent
& evt
) 
1814     SetSelf(evt
.m_self
, true); 
1818 wxPyEvent::~wxPyEvent() { 
1822 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType
, int id
) 
1823     : wxCommandEvent(commandType
, id
) { 
1827 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent
& evt
) 
1828     : wxCommandEvent(evt
) 
1830     SetSelf(evt
.m_self
, true); 
1834 wxPyCommandEvent::~wxPyCommandEvent() { 
1841 //--------------------------------------------------------------------------- 
1842 //--------------------------------------------------------------------------- 
1843 // Convert a wxList to a Python List, only works for lists of wxObjects 
1845 PyObject
* wxPy_ConvertList(wxListBase
* listbase
) { 
1846     wxList
*     list 
= (wxList
*)listbase
;  // this is probably bad... 
1850     wxNode
*     node 
= list
->GetFirst(); 
1852     bool blocked 
= wxPyBeginBlockThreads(); 
1853     pyList 
= PyList_New(0); 
1855         wxObj 
= node
->GetData(); 
1856         pyObj 
= wxPyMake_wxObject(wxObj
,false); 
1857         PyList_Append(pyList
, pyObj
); 
1858         node 
= node
->GetNext(); 
1860     wxPyEndBlockThreads(blocked
); 
1864 //---------------------------------------------------------------------- 
1866 long wxPyGetWinHandle(wxWindow
* win
) { 
1869     return (long)win
->GetHandle(); 
1872 #if defined(__WXGTK__) || defined(__WXX11) 
1873     return (long)GetXWindow(win
); 
1877     //return (long)MAC_WXHWND(win->MacGetTopLevelWindowRef()); 
1878     return (long)win
->GetHandle(); 
1884 //---------------------------------------------------------------------- 
1885 // Some helper functions for typemaps in my_typemaps.i, so they won't be 
1886 // included in every file over and over again... 
1888 wxString
* wxString_in_helper(PyObject
* source
) { 
1889     wxString
* target 
= NULL
; 
1891     if (!PyString_Check(source
) && !PyUnicode_Check(source
)) { 
1892         PyErr_SetString(PyExc_TypeError
, "String or Unicode type required"); 
1896     PyObject
* uni 
= source
; 
1897     if (PyString_Check(source
)) { 
1898         uni 
= PyUnicode_FromObject(source
); 
1899         if (PyErr_Occurred()) return NULL
; 
1901     target 
= new wxString(); 
1902     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1904         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
->GetWriteBuf(len
), len
); 
1905         target
->UngetWriteBuf(len
); 
1908     if (PyString_Check(source
)) 
1911     char* tmpPtr
; int tmpSize
; 
1912     if (PyString_AsStringAndSize(source
, &tmpPtr
, &tmpSize
) == -1) { 
1913         PyErr_SetString(PyExc_TypeError
, "Unable to convert string"); 
1916     target 
= new wxString(tmpPtr
, tmpSize
); 
1917 #endif // wxUSE_UNICODE 
1923 // Similar to above except doesn't use "new" and doesn't set an exception 
1924 wxString 
Py2wxString(PyObject
* source
) 
1929     // Convert to a unicode object, if not already, then to a wxString 
1930     PyObject
* uni 
= source
; 
1931     if (!PyUnicode_Check(source
)) { 
1932         uni 
= PyUnicode_FromObject(source
); 
1933         if (PyErr_Occurred()) return wxEmptyString
;  // TODO:  should we PyErr_Clear? 
1935     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1937         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
.GetWriteBuf(len
), len
); 
1938         target
.UngetWriteBuf(); 
1941     if (!PyUnicode_Check(source
)) 
1944     // Convert to a string object if it isn't already, then to wxString 
1945     PyObject
* str 
= source
; 
1946     if (!PyString_Check(source
)) { 
1947         str 
= PyObject_Str(source
); 
1948         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
1950     char* tmpPtr
; int tmpSize
; 
1951     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1952     target 
= wxString(tmpPtr
, tmpSize
); 
1954     if (!PyString_Check(source
)) 
1956 #endif // wxUSE_UNICODE 
1962 // Make either a Python String or Unicode object, depending on build mode 
1963 PyObject
* wx2PyString(const wxString
& src
) 
1967     str 
= PyUnicode_FromWideChar(src
.c_str(), src
.Len()); 
1969     str 
= PyString_FromStringAndSize(src
.c_str(), src
.Len()); 
1975 //---------------------------------------------------------------------- 
1978 byte
* byte_LIST_helper(PyObject
* source
) { 
1979     if (!PyList_Check(source
)) { 
1980         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
1983     int count 
= PyList_Size(source
); 
1984     byte
* temp 
= new byte
[count
]; 
1986         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
1989     for (int x
=0; x
<count
; x
++) { 
1990         PyObject
* o 
= PyList_GetItem(source
, x
); 
1991         if (! PyInt_Check(o
)) { 
1992             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
1995         temp
[x
] = (byte
)PyInt_AsLong(o
); 
2001 int* int_LIST_helper(PyObject
* source
) { 
2002     if (!PyList_Check(source
)) { 
2003         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2006     int count 
= PyList_Size(source
); 
2007     int* temp 
= new int[count
]; 
2009         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2012     for (int x
=0; x
<count
; x
++) { 
2013         PyObject
* o 
= PyList_GetItem(source
, x
); 
2014         if (! PyInt_Check(o
)) { 
2015             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2018         temp
[x
] = PyInt_AsLong(o
); 
2024 long* long_LIST_helper(PyObject
* source
) { 
2025     if (!PyList_Check(source
)) { 
2026         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2029     int count 
= PyList_Size(source
); 
2030     long* temp 
= new long[count
]; 
2032         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2035     for (int x
=0; x
<count
; x
++) { 
2036         PyObject
* o 
= PyList_GetItem(source
, x
); 
2037         if (! PyInt_Check(o
)) { 
2038             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2041         temp
[x
] = PyInt_AsLong(o
); 
2047 char** string_LIST_helper(PyObject
* source
) { 
2048     if (!PyList_Check(source
)) { 
2049         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2052     int count 
= PyList_Size(source
); 
2053     char** temp 
= new char*[count
]; 
2055         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2058     for (int x
=0; x
<count
; x
++) { 
2059         PyObject
* o 
= PyList_GetItem(source
, x
); 
2060         if (! PyString_Check(o
)) { 
2061             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2064         temp
[x
] = PyString_AsString(o
); 
2069 //-------------------------------- 
2070 // Part of patch from Tim Hochberg 
2071 static inline bool wxPointFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint
* point
) { 
2072     if (PyInt_Check(o1
) && PyInt_Check(o2
)) { 
2073         point
->x 
= PyInt_AS_LONG(o1
); 
2074         point
->y 
= PyInt_AS_LONG(o2
); 
2077     if (PyFloat_Check(o1
) && PyFloat_Check(o2
)) { 
2078         point
->x 
= (int)PyFloat_AS_DOUBLE(o1
); 
2079         point
->y 
= (int)PyFloat_AS_DOUBLE(o2
); 
2082     if (wxPySwigInstance_Check(o1
) || wxPySwigInstance_Check(o2
)) {  // TODO: Why??? 
2083         // Disallow instances because they can cause havok 
2086     if (PyNumber_Check(o1
) && PyNumber_Check(o2
)) { 
2087         // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2 
2088         point
->x 
= PyInt_AsLong(o1
); 
2089         point
->y 
= PyInt_AsLong(o2
); 
2096 wxPoint
* wxPoint_LIST_helper(PyObject
* source
, int *count
) { 
2097     // Putting all of the declarations here allows 
2098     // us to put the error handling all in one place. 
2101     PyObject 
*o
, *o1
, *o2
; 
2102     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2104     if (!PySequence_Check(source
)) { 
2108     // The length of the sequence is returned in count. 
2109     *count 
= PySequence_Length(source
); 
2114     temp 
= new wxPoint
[*count
]; 
2116         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2119     for (x
=0; x
<*count
; x
++) { 
2120         // Get an item: try fast way first. 
2122             o 
= PySequence_Fast_GET_ITEM(source
, x
); 
2125             o 
= PySequence_GetItem(source
, x
); 
2131         // Convert o to wxPoint. 
2132         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2133             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2134             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2135             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2136             if (!wxPointFromObjects(o1
, o2
, &temp
[x
])) { 
2140         else if (wxPySwigInstance_Check(o
)) { 
2142             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint"))) { 
2147         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2148             o1 
= PySequence_GetItem(o
, 0); 
2149             o2 
= PySequence_GetItem(o
, 1); 
2150             if (!wxPointFromObjects(o1
, o2
, &temp
[x
])) { 
2174     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoints."); 
2178 //------------------------------ 
2181 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) { 
2182     if (!PyList_Check(source
)) { 
2183         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2186     int count 
= PyList_Size(source
); 
2187     wxBitmap
** temp 
= new wxBitmap
*[count
]; 
2189         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2192     for (int x
=0; x
<count
; x
++) { 
2193         PyObject
* o 
= PyList_GetItem(source
, x
); 
2194         if (wxPySwigInstance_Check(o
)) { 
2196             if (! wxPyConvertSwigPtr(o
, (void **) &pt
, wxT("wxBitmap"))) { 
2197                 PyErr_SetString(PyExc_TypeError
,"Expected wxBitmap."); 
2203             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps."); 
2212 wxString
* wxString_LIST_helper(PyObject
* source
) { 
2213     if (!PyList_Check(source
)) { 
2214         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2217     int count 
= PyList_Size(source
); 
2218     wxString
* temp 
= new wxString
[count
]; 
2220         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2223     for (int x
=0; x
<count
; x
++) { 
2224         PyObject
* o 
= PyList_GetItem(source
, x
); 
2225 #if PYTHON_API_VERSION >= 1009 
2226         if (! PyString_Check(o
) && ! PyUnicode_Check(o
)) { 
2227             PyErr_SetString(PyExc_TypeError
, "Expected a list of string or unicode objects."); 
2231         if (! PyString_Check(o
)) { 
2232             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2237         wxString
* pStr 
= wxString_in_helper(o
); 
2245 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) { 
2246     if (!PyList_Check(source
)) { 
2247         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2250     int count                
= PyList_Size(source
); 
2251     wxAcceleratorEntry
* temp 
= new wxAcceleratorEntry
[count
]; 
2253         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2256     for (int x
=0; x
<count
; x
++) { 
2257         PyObject
* o 
= PyList_GetItem(source
, x
); 
2258         if (wxPySwigInstance_Check(o
)) { 
2259             wxAcceleratorEntry
* ae
; 
2260             if (! wxPyConvertSwigPtr(o
, (void **) &ae
, wxT("wxAcceleratorEntry"))) { 
2261                 PyErr_SetString(PyExc_TypeError
,"Expected wxAcceleratorEntry."); 
2266         else if (PyTuple_Check(o
)) { 
2267             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
2268             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
2269             PyObject
* o3 
= PyTuple_GetItem(o
, 2); 
2270             temp
[x
].Set(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2273             PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects."); 
2281 wxPen
** wxPen_LIST_helper(PyObject
* source
) { 
2282     if (!PyList_Check(source
)) { 
2283         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2286     int count 
= PyList_Size(source
); 
2287     wxPen
** temp 
= new wxPen
*[count
]; 
2289         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2292     for (int x
=0; x
<count
; x
++) { 
2293         PyObject
* o 
= PyList_GetItem(source
, x
); 
2294         if (wxPySwigInstance_Check(o
)) { 
2296             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPen"))) { 
2298                 PyErr_SetString(PyExc_TypeError
,"Expected wxPen."); 
2305             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxPens."); 
2313 bool wxPy2int_seq_helper(PyObject
* source
, int* i1
, int* i2
) { 
2314     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2317     if (!PySequence_Check(source
) || PySequence_Length(source
) != 2) 
2321         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2322         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2325         o1 
= PySequence_GetItem(source
, 0); 
2326         o2 
= PySequence_GetItem(source
, 1); 
2329     *i1 
= PyInt_AsLong(o1
); 
2330     *i2 
= PyInt_AsLong(o2
); 
2340 bool wxPy4int_seq_helper(PyObject
* source
, int* i1
, int* i2
, int* i3
, int* i4
) { 
2341     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2342     PyObject 
*o1
, *o2
, *o3
, *o4
; 
2344     if (!PySequence_Check(source
) || PySequence_Length(source
) != 4) 
2348         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2349         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2350         o3 
= PySequence_Fast_GET_ITEM(source
, 2); 
2351         o4 
= PySequence_Fast_GET_ITEM(source
, 3); 
2354         o1 
= PySequence_GetItem(source
, 0); 
2355         o2 
= PySequence_GetItem(source
, 1); 
2356         o3 
= PySequence_GetItem(source
, 2); 
2357         o4 
= PySequence_GetItem(source
, 3); 
2360     *i1 
= PyInt_AsLong(o1
); 
2361     *i2 
= PyInt_AsLong(o2
); 
2362     *i3 
= PyInt_AsLong(o3
); 
2363     *i4 
= PyInt_AsLong(o4
); 
2375 //---------------------------------------------------------------------- 
2377 bool wxPySimple_typecheck(PyObject
* source
, const wxChar
* classname
, int seqLen
) 
2381     if (wxPySwigInstance_Check(source
) && 
2382         wxPyConvertSwigPtr(source
, (void **)&ptr
, classname
)) 
2386     if (PySequence_Check(source
) && PySequence_Length(source
) == seqLen
) 
2392 bool wxSize_helper(PyObject
* source
, wxSize
** obj
) 
2394     if (source 
== Py_None
) { 
2395         **obj 
= wxSize(-1,-1); 
2398     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxSize")); 
2402 bool wxPoint_helper(PyObject
* source
, wxPoint
** obj
) 
2404     if (source 
== Py_None
) { 
2405         **obj 
= wxPoint(-1,-1); 
2408     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxPoint")); 
2413 bool wxRealPoint_helper(PyObject
* source
, wxRealPoint
** obj
) { 
2415     if (source 
== Py_None
) { 
2416         **obj 
= wxRealPoint(-1,-1); 
2420     // If source is an object instance then it may already be the right type 
2421     if (wxPySwigInstance_Check(source
)) { 
2423         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRealPoint"))) 
2428     // otherwise a 2-tuple of floats is expected 
2429     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
2430         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2431         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2432         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2437         **obj 
= wxRealPoint(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2444     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxRealPoint object."); 
2450 bool wxRect_helper(PyObject
* source
, wxRect
** obj
) { 
2452     if (source 
== Py_None
) { 
2453         **obj 
= wxRect(-1,-1,-1,-1); 
2457     // If source is an object instance then it may already be the right type 
2458     if (wxPySwigInstance_Check(source
)) { 
2460         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect"))) 
2465     // otherwise a 4-tuple of integers is expected 
2466     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2467         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2468         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2469         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2470         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2471         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2472             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2479         **obj 
= wxRect(PyInt_AsLong(o1
), PyInt_AsLong(o2
), 
2480                        PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2489     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of integers or a wxRect object."); 
2495 bool wxColour_helper(PyObject
* source
, wxColour
** obj
) { 
2497     if (source 
== Py_None
) { 
2498         **obj 
= wxNullColour
; 
2502     // If source is an object instance then it may already be the right type 
2503     if (wxPySwigInstance_Check(source
)) { 
2505         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxColour"))) 
2510     // otherwise check for a string 
2511     else if (PyString_Check(source
) || PyUnicode_Check(source
)) { 
2512         wxString spec 
= Py2wxString(source
); 
2513         if (spec
.GetChar(0) == '#' && spec
.Length() == 7) {  // It's  #RRGGBB 
2514             long red
, green
, blue
; 
2515             red 
= green 
= blue 
= 0; 
2516             spec
.Mid(1,2).ToLong(&red
,   16); 
2517             spec
.Mid(3,2).ToLong(&green
, 16); 
2518             spec
.Mid(5,2).ToLong(&blue
,  16); 
2520             **obj 
= wxColour(red
, green
, blue
); 
2523         else {                                       // it's a colour name 
2524             **obj 
= wxColour(spec
); 
2528     // last chance: 3-tuple of integers is expected 
2529     else if (PySequence_Check(source
) && PyObject_Length(source
) == 3) { 
2530         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2531         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2532         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2533         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
)) { 
2539         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2547     PyErr_SetString(PyExc_TypeError
, 
2548                     "Expected a wxColour object or a string containing a colour name or '#RRGGBB'."); 
2553 bool wxColour_typecheck(PyObject
* source
) { 
2555     if (wxPySimple_typecheck(source
, wxT("wxColour"), 3)) 
2558     if (PyString_Check(source
) || PyUnicode_Check(source
)) 
2566 bool wxPoint2D_helper(PyObject
* source
, wxPoint2D
** obj
) { 
2568     if (source 
== Py_None
) { 
2569         **obj 
= wxPoint2D(-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("wxPoint2D"))) 
2581     // otherwise a length-2 sequence of floats is expected 
2582     if (PySequence_Check(source
) && PySequence_Length(source
) == 2) { 
2583         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2584         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2585         // This should really check for floats, not numbers -- but that would break code. 
2586         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2591         **obj 
= wxPoint2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2597     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxPoint2D object."); 
2602 //---------------------------------------------------------------------- 
2604 PyObject
* wxArrayString2PyList_helper(const wxArrayString
& arr
) { 
2606     PyObject
* list 
= PyList_New(0); 
2607     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2609         PyObject
* str 
= PyUnicode_FromWideChar(arr
[i
].c_str(), arr
[i
].Len()); 
2611         PyObject
* str 
= PyString_FromStringAndSize(arr
[i
].c_str(), arr
[i
].Len()); 
2613         PyList_Append(list
, str
); 
2620 PyObject
* wxArrayInt2PyList_helper(const wxArrayInt
& arr
) { 
2622     PyObject
* list 
= PyList_New(0); 
2623     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2624         PyObject
* number 
= PyInt_FromLong(arr
[i
]); 
2625         PyList_Append(list
, number
); 
2632 //---------------------------------------------------------------------- 
2633 //----------------------------------------------------------------------