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" 
  21 #include <wx/msw/private.h> 
  22 #include <wx/msw/winundef.h> 
  23 #include <wx/msw/msvcrt.h> 
  30 #include <gdk/gdkprivate.h> 
  31 #include <wx/gtk/win_gtk.h> 
  32 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \ 
  33                           GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \ 
  34                           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window) 
  39 #include "wx/x11/privx.h" 
  40 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle()) 
  44 #include <wx/mac/private.h> 
  47 #include <wx/clipbrd.h> 
  48 #include <wx/mimetype.h> 
  51 //---------------------------------------------------------------------- 
  53 #if PYTHON_API_VERSION < 1009 && wxUSE_UNICODE 
  54 #error Python must support Unicode to use wxWindows Unicode 
  57 //---------------------------------------------------------------------- 
  59 wxPyApp
* wxPythonApp 
= NULL
;  // Global instance of application object 
  60 bool wxPyDoCleanup 
= false; 
  61 bool wxPyDoingCleanup 
= false; 
  64 #ifdef WXP_WITH_THREAD 
  65 #if !wxPyUSE_GIL_STATE 
  66 struct wxPyThreadState 
{ 
  68     PyThreadState
* tstate
; 
  70     wxPyThreadState(unsigned long _tid
=0, PyThreadState
* _tstate
=NULL
) 
  71         : tid(_tid
), tstate(_tstate
) {} 
  74 #include <wx/dynarray.h> 
  75 WX_DECLARE_OBJARRAY(wxPyThreadState
, wxPyThreadStateArray
); 
  76 #include <wx/arrimpl.cpp> 
  77 WX_DEFINE_OBJARRAY(wxPyThreadStateArray
); 
  79 wxPyThreadStateArray
* wxPyTStates 
= NULL
; 
  80 wxMutex
*              wxPyTMutex 
= NULL
; 
  86 #define DEFAULTENCODING_SIZE 64 
  87 static char wxPyDefaultEncoding
[DEFAULTENCODING_SIZE
] = "ascii"; 
  89 static PyObject
* wxPython_dict 
= NULL
; 
  90 static PyObject
* wxPyAssertionError 
= NULL
; 
  91 static PyObject
* wxPyNoAppError 
= NULL
; 
  93 PyObject
* wxPyPtrTypeMap 
= NULL
; 
  96 #ifdef __WXMSW__             // If building for win32... 
  97 //---------------------------------------------------------------------- 
  98 // This gets run when the DLL is loaded.  We just need to save a handle. 
  99 //---------------------------------------------------------------------- 
 103     HINSTANCE   hinstDLL
,    // handle to DLL module 
 104     DWORD       fdwReason
,   // reason for calling function 
 105     LPVOID      lpvReserved  
// reserved 
 108     // If wxPython is embedded in another wxWidgets app then 
 109     // the instance has already been set. 
 110     if (! wxGetInstance()) 
 111         wxSetInstance(hinstDLL
); 
 116 //---------------------------------------------------------------------- 
 117 // Classes for implementing the wxp main application shell. 
 118 //---------------------------------------------------------------------- 
 120 IMPLEMENT_ABSTRACT_CLASS(wxPyApp
, wxApp
); 
 124     m_assertMode 
= wxPYAPP_ASSERT_EXCEPTION
; 
 125     m_startupComplete 
= false; 
 129 wxPyApp::~wxPyApp() { 
 131     wxApp::SetInstance(NULL
); 
 135 // This one isn't acutally called...  We fake it with _BootstrapApp 
 136 bool wxPyApp::OnInit() { 
 141 int  wxPyApp::MainLoop() { 
 144     DeletePendingObjects(); 
 145     bool initialized 
= wxTopLevelWindows
.GetCount() != 0; 
 147         if ( m_exitOnFrameDelete 
== Later 
) { 
 148             m_exitOnFrameDelete 
= Yes
; 
 151         retval 
= wxApp::MainLoop(); 
 158 bool wxPyApp::OnInitGui() { 
 160     wxApp::OnInitGui();  // in this case always call the base class version 
 161     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 162     if (wxPyCBH_findCallback(m_myInst
, "OnInitGui")) 
 163         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 164     wxPyEndBlockThreads(blocked
); 
 169 int wxPyApp::OnExit() { 
 171     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 172     if (wxPyCBH_findCallback(m_myInst
, "OnExit")) 
 173         rval 
= wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 174     wxPyEndBlockThreads(blocked
); 
 175     wxApp::OnExit();  // in this case always call the base class version 
 181 void wxPyApp::OnAssert(const wxChar 
*file
, 
 186     // if we're not fully initialized then just log the error 
 187     if (! m_startupComplete
) { 
 190         buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 200     // If the OnAssert is overloaded in the Python class then call it... 
 202     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 203     if ((found 
= wxPyCBH_findCallback(m_myInst
, "OnAssert"))) { 
 204         PyObject
* fso 
= wx2PyString(file
); 
 205         PyObject
* cso 
= wx2PyString(file
); 
 208             mso 
= wx2PyString(file
); 
 210             mso 
= Py_None
; Py_INCREF(Py_None
); 
 212         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(OiOO)", fso
, line
, cso
, mso
)); 
 217     wxPyEndBlockThreads(blocked
); 
 219     // ...otherwise do our own thing with it 
 222         if (m_assertMode 
& wxPYAPP_ASSERT_SUPPRESS
) 
 225         // turn it into a Python exception? 
 226         if (m_assertMode 
& wxPYAPP_ASSERT_EXCEPTION
) { 
 229             buf
.Printf(wxT("C++ assertion \"%s\" failed in %s(%d)"), cond
, file
, line
); 
 236             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 237             PyObject
* s 
= wx2PyString(buf
); 
 238             PyErr_SetObject(wxPyAssertionError
, s
); 
 240             wxPyEndBlockThreads(blocked
); 
 242             // Now when control returns to whatever API wrapper was called from 
 243             // Python it should detect that an exception is set and will return 
 244             // NULL, signalling the exception to Python. 
 247         // Send it to the normal log destination, but only if 
 248         // not _DIALOG because it will call this too 
 249         if ( (m_assertMode 
& wxPYAPP_ASSERT_LOG
) && !(m_assertMode 
& wxPYAPP_ASSERT_DIALOG
)) { 
 252             buf
.Printf(wxT("%s(%d): assert \"%s\" failed"), 
 261         // do the normal wx assert dialog? 
 262         if (m_assertMode 
& wxPYAPP_ASSERT_DIALOG
) 
 263             wxApp::OnAssert(file
, line
, cond
, msg
); 
 268     // For catching Apple Events 
 269 void wxPyApp::MacOpenFile(const wxString 
&fileName
) 
 271     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 272     if (wxPyCBH_findCallback(m_myInst
, "MacOpenFile")) { 
 273         PyObject
* s 
= wx2PyString(fileName
); 
 274         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 277     wxPyEndBlockThreads(blocked
); 
 280 void wxPyApp::MacPrintFile(const wxString 
&fileName
) 
 282     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 283     if (wxPyCBH_findCallback(m_myInst
, "MacPrintFile")) { 
 284         PyObject
* s 
= wx2PyString(fileName
); 
 285         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("(O)", s
)); 
 288     wxPyEndBlockThreads(blocked
); 
 291 void wxPyApp::MacNewFile() 
 293     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 294     if (wxPyCBH_findCallback(m_myInst
, "MacNewFile")) 
 295         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 296     wxPyEndBlockThreads(blocked
); 
 299 void wxPyApp::MacReopenApp() 
 301     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 302     if (wxPyCBH_findCallback(m_myInst
, "MacReopenApp")) 
 303         wxPyCBH_callCallback(m_myInst
, Py_BuildValue("()")); 
 304     wxPyEndBlockThreads(blocked
); 
 309 bool wxPyApp::GetMacSupportPCMenuShortcuts() { 
 311     return s_macSupportPCMenuShortcuts
; 
 318 long wxPyApp::GetMacAboutMenuItemId() { 
 320     return s_macAboutMenuItemId
; 
 327 long wxPyApp::GetMacPreferencesMenuItemId() { 
 329     return s_macPreferencesMenuItemId
; 
 336 long wxPyApp::GetMacExitMenuItemId() { 
 338     return s_macExitMenuItemId
; 
 345 wxString 
wxPyApp::GetMacHelpMenuTitleName() { 
 347     return s_macHelpMenuTitleName
; 
 349     return wxEmptyString
; 
 354 void wxPyApp::SetMacSupportPCMenuShortcuts(bool val
) { 
 356     s_macSupportPCMenuShortcuts 
= val
; 
 361 void wxPyApp::SetMacAboutMenuItemId(long val
) { 
 363     s_macAboutMenuItemId 
= val
; 
 368 void wxPyApp::SetMacPreferencesMenuItemId(long val
) { 
 370     s_macPreferencesMenuItemId 
= val
; 
 375 void wxPyApp::SetMacExitMenuItemId(long val
) { 
 377     s_macExitMenuItemId 
= val
; 
 382 void wxPyApp::SetMacHelpMenuTitleName(const wxString
& val
) { 
 384     s_macHelpMenuTitleName 
= val
; 
 389 // This finishes the initialization of wxWindows and then calls the OnInit 
 390 // that should be present in the derived (Python) class. 
 391 void wxPyApp::_BootstrapApp() 
 393     static      bool haveInitialized 
= false; 
 396     PyObject
*   retval 
= NULL
; 
 397     PyObject
*   pyint  
= NULL
; 
 400     // Only initialize wxWidgets once 
 401     if (! haveInitialized
) { 
 403         // Get any command-line args passed to this program from the sys module 
 406         blocked 
= wxPyBeginBlockThreads(); 
 408         PyObject
* sysargv 
= PySys_GetObject("argv"); 
 409         PyObject
* executable 
= PySys_GetObject("executable"); 
 411         if (sysargv 
!= NULL 
&& executable 
!= NULL
) { 
 412             argc 
= PyList_Size(sysargv
) + 1; 
 413             argv 
= new char*[argc
+1]; 
 414             argv
[0] = strdup(PyString_AsString(executable
)); 
 416             for(x
=1; x
<argc
; x
++) { 
 417                 PyObject 
*pyArg 
= PyList_GetItem(sysargv
, x
-1); 
 418                 argv
[x
] = strdup(PyString_AsString(pyArg
)); 
 422         wxPyEndBlockThreads(blocked
); 
 424         // Initialize wxWidgets 
 425         result 
= wxEntryStart(argc
, argv
); 
 426         // wxApp takes ownership of the argv array, don't delete it here 
 428         blocked 
= wxPyBeginBlockThreads(); 
 430             PyErr_SetString(PyExc_SystemError
, 
 431                             "wxEntryStart failed, unable to initialize wxWidgets!" 
 433                             "  (Is DISPLAY set properly?)" 
 439         // On wxGTK the locale will be changed to match the system settings, 
 440         // but Python before 2.4 needs to have LC_NUMERIC set to "C" in order 
 441         // for the floating point conversions and such to work right. 
 442 #if defined(__WXGTK__) && PY_VERSION_HEX < 0x02040000 
 443         setlocale(LC_NUMERIC
, "C"); 
 446 //        wxSystemOptions::SetOption(wxT("mac.textcontrol-use-mlte"), 1); 
 448         // The stock objects were all NULL when they were loaded into 
 449         // SWIG generated proxies, so re-init those now... 
 450         wxPy_ReinitStockObjects(3); 
 452         wxPyEndBlockThreads(blocked
); 
 453         haveInitialized 
= true; 
 461     // It's now ok to generate exceptions for assertion errors. 
 462     wxPythonApp
->SetStartupComplete(true); 
 464     // Call the Python wxApp's OnInit function 
 465     blocked 
= wxPyBeginBlockThreads(); 
 466     if (wxPyCBH_findCallback(m_myInst
, "OnInit")) { 
 468         PyObject
* method 
= m_myInst
.GetLastFound(); 
 469         PyObject
* argTuple 
= PyTuple_New(0); 
 470         retval 
= PyEval_CallObject(method
, argTuple
); 
 476         pyint 
= PyNumber_Int(retval
); 
 478             PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value"); 
 481         result 
= PyInt_AS_LONG(pyint
); 
 484         // Is it okay if there is no OnInit?  Probably so... 
 489         PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting..."); 
 496     wxPyEndBlockThreads(blocked
); 
 499 //--------------------------------------------------------------------- 
 500 //---------------------------------------------------------------------- 
 504 static char* wxPyCopyCString(const wxChar
* src
) 
 506     wxWX2MBbuf buff 
= (wxWX2MBbuf
)wxConvCurrent
->cWX2MB(src
); 
 507     size_t len 
= strlen(buff
); 
 508     char*  dest 
= new char[len
+1]; 
 514 static char* wxPyCopyCString(const char* src
)   // we need a char version too 
 516     size_t len 
= strlen(src
); 
 517     char*  dest 
= new char[len
+1]; 
 523 static wxChar
* wxPyCopyWString(const char *src
) 
 525     //wxMB2WXbuf buff = wxConvCurrent->cMB2WX(src); 
 526     wxString 
str(src
, *wxConvCurrent
); 
 527     return copystring(str
); 
 531 static wxChar
* wxPyCopyWString(const wxChar 
*src
) 
 533     return copystring(src
); 
 539 inline const char* dropwx(const char* name
) { 
 540     if (name
[0] == 'w' && name
[1] == 'x') 
 546 //---------------------------------------------------------------------- 
 548 // This function is called when the wx._core_ module is imported to do some 
 549 // initial setup.  (Before there is a wxApp object.)  The rest happens in 
 550 // wxPyApp::_BootstrapApp 
 551 void __wxPyPreStart(PyObject
* moduleDict
) 
 555 //     wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF 
 556 //                     | _CRTDBG_CHECK_ALWAYS_DF 
 557 //                     | _CRTDBG_DELAY_FREE_MEM_DF 
 561 #ifdef WXP_WITH_THREAD 
 562 #if wxPyUSE_GIL_STATE 
 563     PyEval_InitThreads(); 
 565     PyEval_InitThreads(); 
 566     wxPyTStates 
= new wxPyThreadStateArray
; 
 567     wxPyTMutex 
= new wxMutex
; 
 569     // Save the current (main) thread state in our array 
 570     PyThreadState
* tstate 
= wxPyBeginAllowThreads(); 
 571     wxPyEndAllowThreads(tstate
); 
 575     // Ensure that the build options in the DLL (or whatever) match this build 
 576     wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE
, "wxPython"); 
 578     // Init the stock objects to a non-NULL value so SWIG doesn't create them as None 
 579     wxPy_ReinitStockObjects(1); 
 581     wxInitAllImageHandlers(); 
 586 void __wxPyCleanup() { 
 587     wxPyDoingCleanup 
= true; 
 589         wxPyDoCleanup 
= false; 
 592 #ifdef WXP_WITH_THREAD 
 593 #if !wxPyUSE_GIL_STATE 
 596     wxPyTStates
->Empty(); 
 604 // Save a reference to the dictionary of the wx._core module, and inject 
 605 // a few more things into it. 
 606 PyObject
* __wxPySetDictionary(PyObject
* /* self */, PyObject
* args
) 
 609     if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
)) 
 612     if (!PyDict_Check(wxPython_dict
)) { 
 613         PyErr_SetString(PyExc_TypeError
, 
 614                         "_wxPySetDictionary must have dictionary object!"); 
 618     if (! wxPyPtrTypeMap
) 
 619         wxPyPtrTypeMap 
= PyDict_New(); 
 620     PyDict_SetItemString(wxPython_dict
, "__wxPyPtrTypeMap", wxPyPtrTypeMap
); 
 622     // Create an exception object to use for wxASSERTions 
 623     wxPyAssertionError 
= PyErr_NewException("wx._core.PyAssertionError", 
 624                                             PyExc_AssertionError
, NULL
); 
 625     PyDict_SetItemString(wxPython_dict
, "PyAssertionError", wxPyAssertionError
); 
 627     // Create an exception object to use when the app object hasn't been created yet 
 628     wxPyNoAppError 
= PyErr_NewException("wx._core.PyNoAppError", 
 629                                         PyExc_RuntimeError
, NULL
); 
 630     PyDict_SetItemString(wxPython_dict
, "PyNoAppError", wxPyNoAppError
); 
 635 #define wxPlatform "__WXMOTIF__" 
 636 #define wxPlatName "wxMotif" 
 639 #define wxPlatform "__WXX11__" 
 640 #define wxPlatName "wxX11" 
 643 #define wxPlatform "__WXGTK__" 
 644 #define wxPlatName "wxGTK" 
 647 #define wxPlatform "__WXMSW__" 
 648 #define wxPlatName "wxMSW" 
 651 #define wxPlatform "__WXMAC__" 
 652 #define wxPlatName "wxMac" 
 661     // These should be deprecated in favor of the PlatformInfo tuple built below... 
 662     PyDict_SetItemString(wxPython_dict
, "Platform", PyString_FromString(wxPlatform
)); 
 663     PyDict_SetItemString(wxPython_dict
, "USE_UNICODE", PyInt_FromLong(wxUSE_UNICODE
)); 
 664     PyDict_SetItemString(wxPython_dict
, "__WXDEBUG__", PyInt_FromLong(wxdebug
)); 
 666     // Make a tuple of strings that gives more info about the platform. 
 667     PyObject
* PlatInfo 
= PyList_New(0); 
 670 #define _AddInfoString(st) \ 
 671     obj = PyString_FromString(st); \ 
 672     PyList_Append(PlatInfo, obj); \ 
 675     _AddInfoString(wxPlatform
); 
 676     _AddInfoString(wxPlatName
); 
 678     _AddInfoString("unicode"); 
 680     _AddInfoString("ansi"); 
 684     _AddInfoString("gtk2"); 
 686     _AddInfoString("gtk1"); 
 690     _AddInfoString("wx-assertions-on"); 
 692     _AddInfoString("wx-assertions-off"); 
 694     _AddInfoString(wxPy_SWIG_VERSION
);     
 696 #undef _AddInfoString 
 698     PyObject
* PlatInfoTuple 
= PyList_AsTuple(PlatInfo
); 
 700     PyDict_SetItemString(wxPython_dict
, "PlatformInfo", PlatInfoTuple
); 
 707 //--------------------------------------------------------------------------- 
 709 // The stock objects are no longer created when the wx._core_ module is 
 710 // imported, but only after the app object has been created.  The 
 711 // wxPy_ReinitStockObjects function will be called 3 times to pass the stock 
 712 // objects though various stages of evolution: 
 714 //   pass 1: Set all the pointers to a non-NULL value so the Python proxy 
 715 //           object will be created (otherwise SWIG will just use None.) 
 717 //   pass 2: After the module has been imported and the python proxys have 
 718 //           been created, then set the __class__ to be _wxPyUnbornObject so 
 719 //           it will catch any access to the object and will raise an exception. 
 721 //   pass 3: Finally, from BootstrapApp patch things up so the stock objects 
 725 PyObject
* __wxPyFixStockObjects(PyObject
* /* self */, PyObject
* args
) 
 727     wxPy_ReinitStockObjects(2); 
 732 static void rsoPass2(const char* name
) 
 734     static PyObject
* unbornObjectClass 
= NULL
; 
 737     if (unbornObjectClass 
== NULL
) { 
 738         unbornObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyUnbornObject"); 
 739         Py_INCREF(unbornObjectClass
); 
 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")); 
 748     PyObject_SetAttrString(obj
, "__class__",  unbornObjectClass
); 
 752 static void rsoPass3(const char* name
, const char* classname
, void* ptr
) 
 758     // Find the object instance 
 759     obj 
= PyDict_GetItemString(wxPython_dict
, (char*)dropwx(name
)); 
 760     wxCHECK_RET(obj 
!= NULL
, wxT("Unable to find stock object")); 
 761     wxCHECK_RET(wxPySwigInstance_Check(obj
), wxT("Not a swig instance")); 
 763     // Find the class object and put it back in the instance 
 764     classobj 
= PyDict_GetItemString(wxPython_dict
, (char*)dropwx(classname
)); 
 765     wxCHECK_RET(classobj 
!= NULL
, wxT("Unable to find stock class object")); 
 766     PyObject_SetAttrString(obj
, "__class__",  classobj
); 
 768     // Rebuild the .this swigified pointer with the new value of the C++ pointer 
 769     ptrobj 
= wxPyMakeSwigPtr(ptr
, wxString(classname
, *wxConvCurrent
)); 
 770     PyObject_SetAttrString(obj
, "this", ptrobj
); 
 776 void wxPy_ReinitStockObjects(int pass
) 
 779     // If there is already an App object then wxPython is probably embedded in 
 780     // a wx C++ application, so there is no need to do all this. 
 781     static bool embedded 
= false; 
 782     if ((pass 
== 1 || pass 
== 2) && wxTheApp
) { 
 786     if (pass 
== 3 && embedded
) 
 790 #define REINITOBJ(name, classname) \ 
 791     if (pass == 1) { name = (classname*)0xC0C0C0C0; } \ 
 792     else if (pass == 2) { rsoPass2(#name); } \ 
 793     else if (pass == 3) { rsoPass3(#name, #classname, (void*)name); } 
 796 #define REINITOBJ2(name, classname) \ 
 798     else if (pass == 2) { rsoPass2(#name); } \ 
 799     else if (pass == 3) { rsoPass3(#name, #classname, (void*)&name); } 
 802     REINITOBJ(wxNORMAL_FONT
, wxFont
); 
 803     REINITOBJ(wxSMALL_FONT
, wxFont
); 
 804     REINITOBJ(wxITALIC_FONT
, wxFont
); 
 805     REINITOBJ(wxSWISS_FONT
, wxFont
); 
 807     REINITOBJ(wxRED_PEN
, wxPen
); 
 808     REINITOBJ(wxCYAN_PEN
, wxPen
); 
 809     REINITOBJ(wxGREEN_PEN
, wxPen
); 
 810     REINITOBJ(wxBLACK_PEN
, wxPen
); 
 811     REINITOBJ(wxWHITE_PEN
, wxPen
); 
 812     REINITOBJ(wxTRANSPARENT_PEN
, wxPen
); 
 813     REINITOBJ(wxBLACK_DASHED_PEN
, wxPen
); 
 814     REINITOBJ(wxGREY_PEN
, wxPen
); 
 815     REINITOBJ(wxMEDIUM_GREY_PEN
, wxPen
); 
 816     REINITOBJ(wxLIGHT_GREY_PEN
, wxPen
); 
 818     REINITOBJ(wxBLUE_BRUSH
, wxBrush
); 
 819     REINITOBJ(wxGREEN_BRUSH
, wxBrush
); 
 820     REINITOBJ(wxWHITE_BRUSH
, wxBrush
); 
 821     REINITOBJ(wxBLACK_BRUSH
, wxBrush
); 
 822     REINITOBJ(wxTRANSPARENT_BRUSH
, wxBrush
); 
 823     REINITOBJ(wxCYAN_BRUSH
, wxBrush
); 
 824     REINITOBJ(wxRED_BRUSH
, wxBrush
); 
 825     REINITOBJ(wxGREY_BRUSH
, wxBrush
); 
 826     REINITOBJ(wxMEDIUM_GREY_BRUSH
, wxBrush
); 
 827     REINITOBJ(wxLIGHT_GREY_BRUSH
, wxBrush
); 
 829     REINITOBJ(wxBLACK
, wxColour
); 
 830     REINITOBJ(wxWHITE
, wxColour
); 
 831     REINITOBJ(wxRED
, wxColour
); 
 832     REINITOBJ(wxBLUE
, wxColour
); 
 833     REINITOBJ(wxGREEN
, wxColour
); 
 834     REINITOBJ(wxCYAN
, wxColour
); 
 835     REINITOBJ(wxLIGHT_GREY
, wxColour
); 
 837     REINITOBJ(wxSTANDARD_CURSOR
, wxCursor
); 
 838     REINITOBJ(wxHOURGLASS_CURSOR
, wxCursor
); 
 839     REINITOBJ(wxCROSS_CURSOR
, wxCursor
); 
 841     REINITOBJ2(wxNullBitmap
, wxBitmap
); 
 842     REINITOBJ2(wxNullIcon
, wxIcon
); 
 843     REINITOBJ2(wxNullCursor
, wxCursor
); 
 844     REINITOBJ2(wxNullPen
, wxPen
); 
 845     REINITOBJ2(wxNullBrush
, wxBrush
); 
 846     REINITOBJ2(wxNullPalette
, wxPalette
); 
 847     REINITOBJ2(wxNullFont
, wxFont
); 
 848     REINITOBJ2(wxNullColour
, wxColour
); 
 850     REINITOBJ(wxTheFontList
, wxFontList
); 
 851     REINITOBJ(wxThePenList
, wxPenList
); 
 852     REINITOBJ(wxTheBrushList
, wxBrushList
); 
 853     REINITOBJ(wxTheColourDatabase
, wxColourDatabase
); 
 856     REINITOBJ2(wxDefaultValidator
, wxValidator
); 
 857     REINITOBJ2(wxNullImage
, wxImage
); 
 858     REINITOBJ2(wxNullAcceleratorTable
, wxAcceleratorTable
); 
 864 //--------------------------------------------------------------------------- 
 866 // Check for existence of a wxApp, setting an exception if there isn't one. 
 867 // This doesn't need to aquire the GIL because it should only be called from 
 868 // an %exception before the lock is released. 
 870 bool wxPyCheckForApp() { 
 871     if (wxTheApp 
!= NULL
) 
 874         PyErr_SetString(wxPyNoAppError
, "The wx.App object must be created first!"); 
 879 //--------------------------------------------------------------------------- 
 881 void wxPyUserData_dtor(wxPyUserData
* self
) { 
 882     if (! wxPyDoingCleanup
) { 
 883         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 884         Py_DECREF(self
->m_obj
); 
 886         wxPyEndBlockThreads(blocked
); 
 891 void wxPyClientData_dtor(wxPyClientData
* self
) { 
 892     if (! wxPyDoingCleanup
) {           // Don't do it during cleanup as Python 
 893                                         // may have already garbage collected the object... 
 894         if (self
->m_incRef
) { 
 895             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 896             Py_DECREF(self
->m_obj
); 
 897             wxPyEndBlockThreads(blocked
); 
 905 // This is called when an OOR controled object is being destroyed.  Although 
 906 // the C++ object is going away there is no way to force the Python object 
 907 // (and all references to it) to die too.  This causes problems (crashes) in 
 908 // wxPython when a python shadow object attempts to call a C++ method using 
 909 // the now bogus pointer... So to try and prevent this we'll do a little black 
 910 // magic and change the class of the python instance to a class that will 
 911 // raise an exception for any attempt to call methods with it.  See 
 912 // _wxPyDeadObject in _core_ex.py for the implementation of this class. 
 913 void wxPyOORClientData_dtor(wxPyOORClientData
* self
) { 
 915     static PyObject
* deadObjectClass 
= NULL
; 
 917     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
 918     if (deadObjectClass 
== NULL
) { 
 919         deadObjectClass 
= PyDict_GetItemString(wxPython_dict
, "_wxPyDeadObject"); 
 920         // TODO:  Can not wxASSERT here because inside a wxPyBeginBlock Threads, 
 921         // will lead to a deadlock when it tries to aquire the GIL again. 
 922         //wxASSERT_MSG(deadObjectClass != NULL, wxT("Can't get _wxPyDeadObject class!")); 
 923         Py_INCREF(deadObjectClass
); 
 927     // Only if there is more than one reference to the object and we are 
 928     // holding the OOR reference: 
 929     if ( !wxPyDoingCleanup 
&& self
->m_obj
->ob_refcnt 
> 1 && self
->m_incRef
) { 
 930         // bool isInstance = wxPyInstance_Check(self->m_obj); 
 932         //wxASSERT_MSG(isInstance, wxT("m_obj not an instance!?!?!")); 
 934         // Call __del__, if there is one. 
 935         PyObject
* func 
= PyObject_GetAttrString(self
->m_obj
, "__del__"); 
 937             PyObject
* rv 
= PyObject_CallMethod(self
->m_obj
, "__del__", NULL
); 
 941         if (PyErr_Occurred()) 
 942             PyErr_Clear();      // just ignore it for now 
 945         PyObject
* dict 
= PyObject_GetAttrString(self
->m_obj
, "__dict__"); 
 947             // Clear the instance's dictionary 
 950             // put the name of the old class into the instance, and then reset the 
 951             // class to be the dead class. 
 952             PyObject
* klass 
= PyObject_GetAttrString(self
->m_obj
, "__class__"); 
 953             PyObject
* name 
=  PyObject_GetAttrString(klass
, "__name__"); 
 954             PyDict_SetItemString(dict
, "_name", name
); 
 955             PyObject_SetAttrString(self
->m_obj
, "__class__",  deadObjectClass
); 
 956             //Py_INCREF(deadObjectClass); 
 962     // m_obj is DECREF'd in the base class dtor... 
 963     wxPyEndBlockThreads(blocked
); 
 967 //--------------------------------------------------------------------------- 
 968 // Stuff used by OOR to find the right wxPython class type to return and to 
 972 // The pointer type map is used when the "pointer" type name generated by SWIG 
 973 // is not the same as the shadow class name, for example wxPyTreeCtrl 
 974 // vs. wxTreeCtrl.  It needs to be referenced in Python as well as from C++, 
 975 // so we'll just make it a Python dictionary in the wx module's namespace. 
 976 // (See __wxSetDictionary) 
 977 void wxPyPtrTypeMap_Add(const char* commonName
, const char* ptrName
) { 
 978     if (! wxPyPtrTypeMap
) 
 979         wxPyPtrTypeMap 
= PyDict_New(); 
 980     PyDict_SetItemString(wxPyPtrTypeMap
, 
 982                          PyString_FromString((char*)ptrName
)); 
 988 PyObject
*  wxPyMake_wxObject(wxObject
* source
, bool setThisOwn
, bool checkEvtHandler
) { 
 989     PyObject
* target 
= NULL
; 
 990     bool      isEvtHandler 
= false; 
 991     bool      isSizer 
= false; 
 994         // If it's derived from wxEvtHandler then there may 
 995         // already be a pointer to a Python object that we can use 
 997         if (checkEvtHandler 
&& wxIsKindOf(source
, wxEvtHandler
)) { 
 999             wxEvtHandler
* eh 
= (wxEvtHandler
*)source
; 
1000             wxPyOORClientData
* data 
= (wxPyOORClientData
*)eh
->GetClientObject(); 
1002                 target 
= data
->m_obj
; 
1008         // Also check for wxSizer 
1009         if (!target 
&& wxIsKindOf(source
, wxSizer
)) { 
1011             wxSizer
* sz 
= (wxSizer
*)source
; 
1012             wxPyOORClientData
* data 
= (wxPyOORClientData
*)sz
->GetClientObject(); 
1014                 target 
= data
->m_obj
; 
1021             // Otherwise make it the old fashioned way by making a new shadow 
1022             // object and putting this pointer in it.  Look up the class 
1023             // heirarchy until we find a class name that is located in the 
1025             const wxClassInfo
* info   
= source
->GetClassInfo(); 
1026             wxString           name   
= info
->GetClassName(); 
1027             bool               exists 
= wxPyCheckSwigType(name
); 
1028             while (info 
&& !exists
) { 
1029                 info 
= info
->GetBaseClass1(); 
1030                 name 
= info
->GetClassName(); 
1031                 exists 
= wxPyCheckSwigType(name
); 
1034                 target 
= wxPyConstructObject((void*)source
, name
, setThisOwn
); 
1035                 if (target 
&& isEvtHandler
) 
1036                     ((wxEvtHandler
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
1037                 if (target 
&& isSizer
) 
1038                     ((wxSizer
*)source
)->SetClientObject(new wxPyOORClientData(target
)); 
1040                 wxString 
msg(wxT("wxPython class not found for ")); 
1041                 msg 
+= source
->GetClassInfo()->GetClassName(); 
1042                 PyErr_SetString(PyExc_NameError
, msg
.mbc_str()); 
1046     } else {  // source was NULL so return None. 
1047         Py_INCREF(Py_None
); target 
= Py_None
; 
1053 PyObject
*  wxPyMake_wxSizer(wxSizer
* source
, bool setThisOwn
) { 
1055     return wxPyMake_wxObject(source
, setThisOwn
); 
1059 //--------------------------------------------------------------------------- 
1062 #ifdef WXP_WITH_THREAD 
1063 #if !wxPyUSE_GIL_STATE 
1066 unsigned long wxPyGetCurrentThreadId() { 
1067     return wxThread::GetCurrentId(); 
1070 static wxPyThreadState gs_shutdownTState
; 
1073 wxPyThreadState
* wxPyGetThreadState() { 
1074     if (wxPyTMutex 
== NULL
) // Python is shutting down... 
1075         return &gs_shutdownTState
; 
1077     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
1078     wxPyThreadState
* tstate 
= NULL
; 
1081     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
1082         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
1083         if (info
.tid 
== ctid
) { 
1088     wxPyTMutex
->Unlock(); 
1089     wxASSERT_MSG(tstate
, wxT("PyThreadState should not be NULL!")); 
1095 void wxPySaveThreadState(PyThreadState
* tstate
) { 
1096     if (wxPyTMutex 
== NULL
) { // Python is shutting down, assume a single thread... 
1097         gs_shutdownTState
.tstate 
= tstate
; 
1100     unsigned long ctid 
= wxPyGetCurrentThreadId(); 
1102     for(size_t i
=0; i 
< wxPyTStates
->GetCount(); i
++) { 
1103         wxPyThreadState
& info 
= wxPyTStates
->Item(i
); 
1104         if (info
.tid 
== ctid
) { 
1106             if (info
.tstate 
!= tstate
) 
1107                 wxLogMessage("*** tstate mismatch!???"); 
1109             info
.tstate 
= tstate
;    // allow for transient tstates 
1110             // Normally it will never change, but apparently COM callbacks 
1111             // (i.e. ActiveX controls) will (incorrectly IMHO) use a transient 
1112             // tstate which will then be garbage the next time we try to use 
1115             wxPyTMutex
->Unlock(); 
1119     // not found, so add it... 
1120     wxPyTStates
->Add(new wxPyThreadState(ctid
, tstate
)); 
1121     wxPyTMutex
->Unlock(); 
1129 // Calls from Python to wxWindows code are wrapped in calls to these 
1132 PyThreadState
* wxPyBeginAllowThreads() { 
1133 #ifdef WXP_WITH_THREAD 
1134     PyThreadState
* saved 
= PyEval_SaveThread();  // Py_BEGIN_ALLOW_THREADS; 
1135 #if !wxPyUSE_GIL_STATE 
1136     wxPySaveThreadState(saved
); 
1144 void wxPyEndAllowThreads(PyThreadState
* saved
) { 
1145 #ifdef WXP_WITH_THREAD 
1146     PyEval_RestoreThread(saved
);   // Py_END_ALLOW_THREADS; 
1152 // Calls from wxWindows back to Python code, or even any PyObject 
1153 // manipulations, PyDECREF's and etc. are wrapped in calls to these functions: 
1155 wxPyBlock_t 
wxPyBeginBlockThreads() { 
1156 #ifdef WXP_WITH_THREAD 
1157     if (! Py_IsInitialized()) { 
1158         return (wxPyBlock_t
)0; 
1160 #if wxPyUSE_GIL_STATE 
1161     PyGILState_STATE state 
= PyGILState_Ensure(); 
1164     PyThreadState 
*current 
= _PyThreadState_Current
; 
1166     // Only block if there wasn't already a tstate, or if the current one is 
1167     // not the one we are wanting to change to.  This should prevent deadlock 
1168     // if there are nested calls to wxPyBeginBlockThreads 
1169     wxPyBlock_t blocked 
= false; 
1170     wxPyThreadState
* tstate 
= wxPyGetThreadState(); 
1171     if (current 
!= tstate
->tstate
) { 
1172         PyEval_RestoreThread(tstate
->tstate
); 
1178     return (wxPyBlock_t
)0; 
1183 void wxPyEndBlockThreads(wxPyBlock_t blocked
) { 
1184 #ifdef WXP_WITH_THREAD 
1185     if (! Py_IsInitialized()) { 
1188 #if wxPyUSE_GIL_STATE 
1189     PyGILState_Release(blocked
); 
1191     // Only unblock if we blocked in the last call to wxPyBeginBlockThreads. 
1192     // The value of blocked passed in needs to be the same as that returned 
1193     // from wxPyBeginBlockThreads at the same nesting level. 
1195         PyEval_SaveThread(); 
1202 //--------------------------------------------------------------------------- 
1203 // wxPyInputStream and wxPyCBInputStream methods 
1206 void wxPyInputStream::close() { 
1207     /* do nothing for now */ 
1210 void wxPyInputStream::flush() { 
1211     /* do nothing for now */ 
1214 bool wxPyInputStream::eof() { 
1216         return m_wxis
->Eof(); 
1221 wxPyInputStream::~wxPyInputStream() { 
1229 PyObject
* wxPyInputStream::read(int size
) { 
1230     PyObject
* obj 
= NULL
; 
1232     const int BUFSIZE 
= 1024; 
1234     // check if we have a real wxInputStream to work with 
1236         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1237         PyErr_SetString(PyExc_IOError
, "no valid C-wxInputStream"); 
1238         wxPyEndBlockThreads(blocked
); 
1243         // read while bytes are available on the stream 
1244         while ( m_wxis
->CanRead() ) { 
1245             m_wxis
->Read(buf
.GetAppendBuf(BUFSIZE
), BUFSIZE
); 
1246             buf
.UngetAppendBuf(m_wxis
->LastRead()); 
1249     } else {  // Read only size number of characters 
1250         m_wxis
->Read(buf
.GetWriteBuf(size
), size
); 
1251         buf
.UngetWriteBuf(m_wxis
->LastRead()); 
1255     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1256     wxStreamError err 
= m_wxis
->GetLastError(); 
1257     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1258         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1261         // We use only strings for the streams, not unicode 
1262         obj 
= PyString_FromStringAndSize(buf
, buf
.GetDataLen()); 
1264     wxPyEndBlockThreads(blocked
); 
1269 PyObject
* wxPyInputStream::readline(int size
) { 
1270     PyObject
* obj 
= NULL
; 
1275     // check if we have a real wxInputStream to work with 
1277         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1278         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1279         wxPyEndBlockThreads(blocked
); 
1283     // read until \n or byte limit reached 
1284     for (i
=ch
=0; (ch 
!= '\n') && (m_wxis
->CanRead()) && ((size 
< 0) || (i 
< size
)); i
++) { 
1285         ch 
= m_wxis
->GetC(); 
1290     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1291     wxStreamError err 
= m_wxis
->GetLastError(); 
1292     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1293         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1296         // We use only strings for the streams, not unicode 
1297         obj 
= PyString_FromStringAndSize((char*)buf
.GetData(), buf
.GetDataLen()); 
1299     wxPyEndBlockThreads(blocked
); 
1304 PyObject
* wxPyInputStream::readlines(int sizehint
) { 
1307     // check if we have a real wxInputStream to work with 
1309         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1310         PyErr_SetString(PyExc_IOError
,"no valid C-wxInputStream"); 
1311         wxPyEndBlockThreads(blocked
); 
1316     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1317     pylist 
= PyList_New(0); 
1318     wxPyEndBlockThreads(blocked
); 
1321         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1323         wxPyEndBlockThreads(blocked
); 
1327     // read sizehint bytes or until EOF 
1329     for (i
=0; (m_wxis
->CanRead()) && ((sizehint 
< 0) || (i 
< sizehint
));) { 
1330         PyObject
* s 
= this->readline(); 
1332             wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1334             wxPyEndBlockThreads(blocked
); 
1337         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1338         PyList_Append(pylist
, s
); 
1339         i 
+= PyString_Size(s
); 
1340         wxPyEndBlockThreads(blocked
); 
1344     wxStreamError err 
= m_wxis
->GetLastError(); 
1345     if (err 
!= wxSTREAM_NO_ERROR 
&& err 
!= wxSTREAM_EOF
) { 
1346         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1348         PyErr_SetString(PyExc_IOError
,"IOError in wxInputStream"); 
1349         wxPyEndBlockThreads(blocked
); 
1357 void wxPyInputStream::seek(int offset
, int whence
) { 
1359         m_wxis
->SeekI(offset
, wxSeekMode(whence
)); 
1362 int wxPyInputStream::tell(){ 
1364         return m_wxis
->TellI(); 
1371 wxPyCBInputStream::wxPyCBInputStream(PyObject 
*r
, PyObject 
*s
, PyObject 
*t
, bool block
) 
1372     : wxInputStream(), m_read(r
), m_seek(s
), m_tell(t
), m_block(block
) 
1375 wxPyCBInputStream::wxPyCBInputStream(const wxPyCBInputStream
& other
) 
1377     m_read  
= other
.m_read
; 
1378     m_seek  
= other
.m_seek
; 
1379     m_tell  
= other
.m_tell
; 
1380     m_block 
= other
.m_block
; 
1387 wxPyCBInputStream::~wxPyCBInputStream() { 
1388     wxPyBlock_t blocked
; 
1389     if (m_block
) blocked 
= wxPyBeginBlockThreads(); 
1393     if (m_block
) wxPyEndBlockThreads(blocked
); 
1397 wxPyCBInputStream
* wxPyCBInputStream::create(PyObject 
*py
, bool block
) { 
1398     wxPyBlock_t blocked
; 
1399     if (block
) blocked 
= wxPyBeginBlockThreads(); 
1401     PyObject
* read 
= getMethod(py
, "read"); 
1402     PyObject
* seek 
= getMethod(py
, "seek"); 
1403     PyObject
* tell 
= getMethod(py
, "tell"); 
1406         PyErr_SetString(PyExc_TypeError
, "Not a file-like object"); 
1410         if (block
) wxPyEndBlockThreads(blocked
); 
1414     if (block
) wxPyEndBlockThreads(blocked
); 
1415     return new wxPyCBInputStream(read
, seek
, tell
, block
); 
1419 wxPyCBInputStream
* wxPyCBInputStream_create(PyObject 
*py
, bool block
) { 
1420     return wxPyCBInputStream::create(py
, block
); 
1423 wxPyCBInputStream
* wxPyCBInputStream_copy(wxPyCBInputStream
* other
) { 
1424     return new wxPyCBInputStream(*other
); 
1427 PyObject
* wxPyCBInputStream::getMethod(PyObject
* py
, char* name
) { 
1428     if (!PyObject_HasAttrString(py
, name
)) 
1430     PyObject
* o 
= PyObject_GetAttrString(py
, name
); 
1431     if (!PyMethod_Check(o
) && !PyCFunction_Check(o
)) { 
1439 wxFileOffset 
wxPyCBInputStream::GetLength() const { 
1440     wxPyCBInputStream
* self 
= (wxPyCBInputStream
*)this; // cast off const 
1441     if (m_seek 
&& m_tell
) { 
1442         wxFileOffset temp 
= self
->OnSysTell(); 
1443         wxFileOffset ret 
= self
->OnSysSeek(0, wxFromEnd
); 
1444         self
->OnSysSeek(temp
, wxFromStart
); 
1448         return wxInvalidOffset
; 
1452 size_t wxPyCBInputStream::OnSysRead(void *buffer
, size_t bufsize
) { 
1456     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1457     PyObject
* arglist 
= Py_BuildValue("(i)", bufsize
); 
1458     PyObject
* result 
= PyEval_CallObject(m_read
, arglist
); 
1462     if ((result 
!= NULL
) && PyString_Check(result
)) { 
1463         o 
= PyString_Size(result
); 
1465             m_lasterror 
= wxSTREAM_EOF
; 
1468         memcpy((char*)buffer
, PyString_AsString(result
), o
);  // strings only, not unicode... 
1473         m_lasterror 
= wxSTREAM_READ_ERROR
; 
1474     wxPyEndBlockThreads(blocked
); 
1478 size_t wxPyCBInputStream::OnSysWrite(const void *buffer
, size_t bufsize
) { 
1479     m_lasterror 
= wxSTREAM_WRITE_ERROR
; 
1484 wxFileOffset 
wxPyCBInputStream::OnSysSeek(wxFileOffset off
, wxSeekMode mode
) { 
1485     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1486     PyObject
* arglist 
= PyTuple_New(2); 
1488     if (sizeof(wxFileOffset
) > sizeof(long)) 
1489         // wxFileOffset is a 64-bit value... 
1490         PyTuple_SET_ITEM(arglist
, 0, PyLong_FromLongLong(off
)); 
1492         PyTuple_SET_ITEM(arglist
, 0, PyInt_FromLong(off
)); 
1494     PyTuple_SET_ITEM(arglist
, 1, PyInt_FromLong(mode
)); 
1497     PyObject
* result 
= PyEval_CallObject(m_seek
, arglist
); 
1500     wxPyEndBlockThreads(blocked
); 
1505 wxFileOffset 
wxPyCBInputStream::OnSysTell() const { 
1506     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1507     PyObject
* arglist 
= Py_BuildValue("()"); 
1508     PyObject
* result 
= PyEval_CallObject(m_tell
, arglist
); 
1511     if (result 
!= NULL
) { 
1512         if (PyLong_Check(result
)) 
1513             o 
= PyLong_AsLongLong(result
); 
1515             o 
= PyInt_AsLong(result
); 
1518     wxPyEndBlockThreads(blocked
); 
1522 //---------------------------------------------------------------------- 
1524 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback
, wxObject
); 
1526 wxPyCallback::wxPyCallback(PyObject
* func
) { 
1531 wxPyCallback::wxPyCallback(const wxPyCallback
& other
) { 
1532     m_func 
= other
.m_func
; 
1536 wxPyCallback::~wxPyCallback() { 
1537     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1539     wxPyEndBlockThreads(blocked
); 
1543 #define wxPy_PRECALLINIT     "_preCallInit" 
1544 #define wxPy_POSTCALLCLEANUP "_postCallCleanup" 
1546 // This function is used for all events destined for Python event handlers. 
1547 void wxPyCallback::EventThunker(wxEvent
& event
) { 
1548     wxPyCallback
*   cb 
= (wxPyCallback
*)event
.m_callbackUserData
; 
1549     PyObject
*       func 
= cb
->m_func
; 
1553     bool            checkSkip 
= false; 
1555     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1556     wxString className 
= event
.GetClassInfo()->GetClassName(); 
1558     // If the event is one of these types then pass the original 
1559     // event object instead of the one passed to us. 
1560     if ( className 
== wxT("wxPyEvent") ) { 
1561         arg 
=       ((wxPyEvent
*)&event
)->GetSelf(); 
1562         checkSkip 
= ((wxPyEvent
*)&event
)->GetCloned(); 
1564     else if ( className 
== wxT("wxPyCommandEvent") ) { 
1565         arg 
=       ((wxPyCommandEvent
*)&event
)->GetSelf(); 
1566         checkSkip 
= ((wxPyCommandEvent
*)&event
)->GetCloned(); 
1569         arg 
= wxPyConstructObject((void*)&event
, className
); 
1575         // "intern" the pre/post method names to speed up the HasAttr 
1576         static PyObject
* s_preName  
= NULL
; 
1577         static PyObject
* s_postName 
= NULL
; 
1578         if (s_preName 
== NULL
) { 
1579             s_preName  
= PyString_FromString(wxPy_PRECALLINIT
); 
1580             s_postName 
= PyString_FromString(wxPy_POSTCALLCLEANUP
); 
1583         // Check if the event object needs some preinitialization 
1584         if (PyObject_HasAttr(arg
, s_preName
)) { 
1585             result 
= PyObject_CallMethodObjArgs(arg
, s_preName
, arg
, NULL
); 
1587                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1588                 PyErr_Clear();       // Just in case... 
1594         // Call the event handler, passing the event object 
1595         tuple 
= PyTuple_New(1); 
1596         PyTuple_SET_ITEM(tuple
, 0, arg
);  // steals ref to arg 
1597         result 
= PyEval_CallObject(func
, tuple
); 
1599             Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1600             PyErr_Clear();       // Just in case... 
1605         // Check if the event object needs some post cleanup 
1606         if (PyObject_HasAttr(arg
, s_postName
)) { 
1607             result 
= PyObject_CallMethodObjArgs(arg
, s_postName
, arg
, NULL
); 
1609                 Py_DECREF(result
);   // result is ignored, but we still need to decref it 
1610                 PyErr_Clear();       // Just in case... 
1617             // if the event object was one of our special types and 
1618             // it had been cloned, then we need to extract the Skipped 
1619             // value from the original and set it in the clone. 
1620             result 
= PyObject_CallMethod(arg
, "GetSkipped", ""); 
1622                 event
.Skip(PyInt_AsLong(result
)); 
1630     wxPyEndBlockThreads(blocked
); 
1634 //---------------------------------------------------------------------- 
1636 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper
& other
) { 
1638       m_self 
= other
.m_self
; 
1639       m_class 
= other
.m_class
; 
1647 void wxPyCallbackHelper::setSelf(PyObject
* self
, PyObject
* klass
, int incref
) { 
1658 #if PYTHON_API_VERSION >= 1011 
1660 // Prior to Python 2.2 PyMethod_GetClass returned the class object 
1661 // in which the method was defined.  Starting with 2.2 it returns 
1662 // "class that asked for the method" which seems totally bogus to me 
1663 // but apprently it fixes some obscure problem waiting to happen in 
1664 // Python.  Since the API was not documented Guido and the gang felt 
1665 // safe in changing it.  Needless to say that totally screwed up the 
1666 // logic below in wxPyCallbackHelper::findCallback, hence this icky 
1667 // code to find the class where the method is actually defined... 
1670 PyObject
* PyFindClassWithAttr(PyObject 
*klass
, PyObject 
*name
) 
1674     if (PyType_Check(klass
)) {      // new style classes 
1675         // This code is borrowed/adapted from _PyType_Lookup in typeobject.c 
1676         PyTypeObject
* type 
= (PyTypeObject
*)klass
; 
1677         PyObject 
*mro
, *res
, *base
, *dict
; 
1678         /* Look in tp_dict of types in MRO */ 
1680         assert(PyTuple_Check(mro
)); 
1681         n 
= PyTuple_GET_SIZE(mro
); 
1682         for (i 
= 0; i 
< n
; i
++) { 
1683             base 
= PyTuple_GET_ITEM(mro
, i
); 
1684             if (PyClass_Check(base
)) 
1685                 dict 
= ((PyClassObject 
*)base
)->cl_dict
; 
1687                 assert(PyType_Check(base
)); 
1688                 dict 
= ((PyTypeObject 
*)base
)->tp_dict
; 
1690             assert(dict 
&& PyDict_Check(dict
)); 
1691             res 
= PyDict_GetItem(dict
, name
); 
1698     else if (PyClass_Check(klass
)) { // old style classes 
1699         // This code is borrowed/adapted from class_lookup in classobject.c 
1700         PyClassObject
* cp 
= (PyClassObject
*)klass
; 
1701         PyObject 
*value 
= PyDict_GetItem(cp
->cl_dict
, name
); 
1702         if (value 
!= NULL
) { 
1703             return (PyObject
*)cp
; 
1705         n 
= PyTuple_Size(cp
->cl_bases
); 
1706         for (i 
= 0; i 
< n
; i
++) { 
1707             PyObject
* base 
= PyTuple_GetItem(cp
->cl_bases
, i
); 
1708             PyObject 
*v 
= PyFindClassWithAttr(base
, name
); 
1720 PyObject
* PyMethod_GetDefiningClass(PyObject
* method
, const char* name
) 
1722     PyObject
* mgc 
= PyMethod_GET_CLASS(method
); 
1724 #if PYTHON_API_VERSION <= 1010    // prior to Python 2.2, the easy way 
1726 #else                             // 2.2 and after, the hard way... 
1728     PyObject
* nameo 
= PyString_FromString(name
); 
1729     PyObject
* klass 
= PyFindClassWithAttr(mgc
, nameo
); 
1737 bool wxPyCallbackHelper::findCallback(const char* name
) const { 
1738     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
1739     self
->m_lastFound 
= NULL
; 
1741     // If the object (m_self) has an attibute of the given name... 
1742     if (m_self 
&& PyObject_HasAttrString(m_self
, (char*)name
)) { 
1743         PyObject 
*method
, *klass
; 
1744         method 
= PyObject_GetAttrString(m_self
, (char*)name
); 
1746         // ...and if that attribute is a method, and if that method's class is 
1747         // not from a base class... 
1748         if (PyMethod_Check(method
) && 
1749             (klass 
= PyMethod_GetDefiningClass(method
, (char*)name
)) != NULL 
&& 
1750             ((klass 
== m_class
) || PyObject_IsSubclass(klass
, m_class
))) { 
1752             // ...then we'll save a pointer to the method so callCallback can call it. 
1753             self
->m_lastFound 
= method
; 
1759     return m_lastFound 
!= NULL
; 
1763 int wxPyCallbackHelper::callCallback(PyObject
* argTuple
) const { 
1767     result 
= callCallbackObj(argTuple
); 
1768     if (result
) {                       // Assumes an integer return type... 
1769         retval 
= PyInt_AsLong(result
); 
1771         PyErr_Clear();                  // forget about it if it's not... 
1776 // Invoke the Python callable object, returning the raw PyObject return 
1777 // value.  Caller should DECREF the return value and also manage the GIL. 
1778 PyObject
* wxPyCallbackHelper::callCallbackObj(PyObject
* argTuple
) const { 
1781     // Save a copy of the pointer in case the callback generates another 
1782     // callback.  In that case m_lastFound will have a different value when 
1783     // it gets back here... 
1784     PyObject
* method 
= m_lastFound
; 
1786     result 
= PyEval_CallObject(method
, argTuple
); 
1787     Py_DECREF(argTuple
); 
1796 void wxPyCBH_setCallbackInfo(wxPyCallbackHelper
& cbh
, PyObject
* self
, PyObject
* klass
, int incref
) { 
1797     cbh
.setSelf(self
, klass
, incref
); 
1800 bool wxPyCBH_findCallback(const wxPyCallbackHelper
& cbh
, const char* name
) { 
1801     return cbh
.findCallback(name
); 
1804 int  wxPyCBH_callCallback(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1805     return cbh
.callCallback(argTuple
); 
1808 PyObject
* wxPyCBH_callCallbackObj(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
1809     return cbh
.callCallbackObj(argTuple
); 
1813 void wxPyCBH_delete(wxPyCallbackHelper
* cbh
) { 
1814     if (cbh
->m_incRef
) { 
1815         wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1816         Py_XDECREF(cbh
->m_self
); 
1817         Py_XDECREF(cbh
->m_class
); 
1818         wxPyEndBlockThreads(blocked
); 
1822 //--------------------------------------------------------------------------- 
1823 //--------------------------------------------------------------------------- 
1824 // These event classes can be derived from in Python and passed through the event 
1825 // system without losing anything.  They do this by keeping a reference to 
1826 // themselves and some special case handling in wxPyCallback::EventThunker. 
1829 wxPyEvtSelfRef::wxPyEvtSelfRef() { 
1830     //m_self = Py_None;         // **** We don't do normal ref counting to prevent 
1831     //Py_INCREF(m_self);        //      circular loops... 
1835 wxPyEvtSelfRef::~wxPyEvtSelfRef() { 
1836     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1839     wxPyEndBlockThreads(blocked
); 
1842 void wxPyEvtSelfRef::SetSelf(PyObject
* self
, bool clone
) { 
1843     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1851     wxPyEndBlockThreads(blocked
); 
1854 PyObject
* wxPyEvtSelfRef::GetSelf() const { 
1860 IMPLEMENT_ABSTRACT_CLASS(wxPyEvent
, wxEvent
); 
1861 IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent
, wxCommandEvent
); 
1864 wxPyEvent::wxPyEvent(int winid
, wxEventType commandType
) 
1865     : wxEvent(winid
, commandType
) { 
1869 wxPyEvent::wxPyEvent(const wxPyEvent
& evt
) 
1872     SetSelf(evt
.m_self
, true); 
1876 wxPyEvent::~wxPyEvent() { 
1880 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType
, int id
) 
1881     : wxCommandEvent(commandType
, id
) { 
1885 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent
& evt
) 
1886     : wxCommandEvent(evt
) 
1888     SetSelf(evt
.m_self
, true); 
1892 wxPyCommandEvent::~wxPyCommandEvent() { 
1899 //--------------------------------------------------------------------------- 
1900 //--------------------------------------------------------------------------- 
1901 // Convert a wxList to a Python List, only works for lists of wxObjects 
1903 PyObject
* wxPy_ConvertList(wxListBase
* listbase
) { 
1904     wxList
*     list 
= (wxList
*)listbase
;  // this is probably bad... 
1908     wxNode
*     node 
= list
->GetFirst(); 
1910     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
1911     pyList 
= PyList_New(0); 
1913         wxObj 
= node
->GetData(); 
1914         pyObj 
= wxPyMake_wxObject(wxObj
,false); 
1915         PyList_Append(pyList
, pyObj
); 
1916         node 
= node
->GetNext(); 
1918     wxPyEndBlockThreads(blocked
); 
1922 //---------------------------------------------------------------------- 
1924 long wxPyGetWinHandle(wxWindow
* win
) { 
1927     return (long)win
->GetHandle(); 
1930 #if defined(__WXGTK__) || defined(__WXX11) 
1931     return (long)GetXWindow(win
); 
1935     //return (long)MAC_WXHWND(win->MacGetTopLevelWindowRef()); 
1936     return (long)win
->GetHandle(); 
1942 //---------------------------------------------------------------------- 
1943 // Some helper functions for typemaps in my_typemaps.i, so they won't be 
1944 // included in every file over and over again... 
1946 wxString
* wxString_in_helper(PyObject
* source
) { 
1947     wxString
* target 
= NULL
; 
1949     if (!PyString_Check(source
) && !PyUnicode_Check(source
)) { 
1950         PyErr_SetString(PyExc_TypeError
, "String or Unicode type required"); 
1954     PyObject
* uni 
= source
; 
1955     if (PyString_Check(source
)) { 
1956         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
1957         if (PyErr_Occurred()) return NULL
; 
1959     target 
= new wxString(); 
1960     size_t len 
= PyUnicode_GET_SIZE(uni
); 
1962         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
->GetWriteBuf(len
), len
); 
1963         target
->UngetWriteBuf(len
); 
1966     if (PyString_Check(source
)) 
1969     // Convert to a string object if it isn't already, then to wxString 
1970     PyObject
* str 
= source
; 
1971     if (PyUnicode_Check(source
)) { 
1972         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
1973         if (PyErr_Occurred()) return NULL
; 
1975     else if (!PyString_Check(source
)) { 
1976         str 
= PyObject_Str(source
); 
1977         if (PyErr_Occurred()) return NULL
; 
1979     char* tmpPtr
; int tmpSize
; 
1980     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
1981     target 
= new wxString(tmpPtr
, tmpSize
); 
1983     if (!PyString_Check(source
)) 
1985 #endif // wxUSE_UNICODE 
1991 // Similar to above except doesn't use "new" and doesn't set an exception 
1992 wxString 
Py2wxString(PyObject
* source
) 
1997     // Convert to a unicode object, if not already, then to a wxString 
1998     PyObject
* uni 
= source
; 
1999     if (!PyUnicode_Check(source
)) { 
2000         uni 
= PyUnicode_FromEncodedObject(source
, wxPyDefaultEncoding
, "strict"); 
2001         if (PyErr_Occurred()) return wxEmptyString
;  // TODO:  should we PyErr_Clear? 
2003     size_t len 
= PyUnicode_GET_SIZE(uni
); 
2005         PyUnicode_AsWideChar((PyUnicodeObject
*)uni
, target
.GetWriteBuf(len
), len
); 
2006         target
.UngetWriteBuf(); 
2009     if (!PyUnicode_Check(source
)) 
2012     // Convert to a string object if it isn't already, then to wxString 
2013     PyObject
* str 
= source
; 
2014     if (PyUnicode_Check(source
)) { 
2015         str 
= PyUnicode_AsEncodedString(source
, wxPyDefaultEncoding
, "strict"); 
2016         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
2018     else if (!PyString_Check(source
)) { 
2019         str 
= PyObject_Str(source
); 
2020         if (PyErr_Occurred()) return wxEmptyString
;    // TODO:  should we PyErr_Clear? 
2022     char* tmpPtr
; int tmpSize
; 
2023     PyString_AsStringAndSize(str
, &tmpPtr
, &tmpSize
); 
2024     target 
= wxString(tmpPtr
, tmpSize
); 
2026     if (!PyString_Check(source
)) 
2028 #endif // wxUSE_UNICODE 
2034 // Make either a Python String or Unicode object, depending on build mode 
2035 PyObject
* wx2PyString(const wxString
& src
) 
2039     str 
= PyUnicode_FromWideChar(src
.c_str(), src
.Len()); 
2041     str 
= PyString_FromStringAndSize(src
.c_str(), src
.Len()); 
2048 void wxSetDefaultPyEncoding(const char* encoding
) 
2050     strncpy(wxPyDefaultEncoding
, encoding
, DEFAULTENCODING_SIZE
); 
2053 const char* wxGetDefaultPyEncoding() 
2055     return wxPyDefaultEncoding
; 
2058 //---------------------------------------------------------------------- 
2061 byte
* byte_LIST_helper(PyObject
* source
) { 
2062     if (!PyList_Check(source
)) { 
2063         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2066     int count 
= PyList_Size(source
); 
2067     byte
* temp 
= new byte
[count
]; 
2069         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2072     for (int x
=0; x
<count
; x
++) { 
2073         PyObject
* o 
= PyList_GetItem(source
, x
); 
2074         if (! PyInt_Check(o
)) { 
2075             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2078         temp
[x
] = (byte
)PyInt_AsLong(o
); 
2084 int* int_LIST_helper(PyObject
* source
) { 
2085     if (!PyList_Check(source
)) { 
2086         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2089     int count 
= PyList_Size(source
); 
2090     int* temp 
= new int[count
]; 
2092         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2095     for (int x
=0; x
<count
; x
++) { 
2096         PyObject
* o 
= PyList_GetItem(source
, x
); 
2097         if (! PyInt_Check(o
)) { 
2098             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2101         temp
[x
] = PyInt_AsLong(o
); 
2107 long* long_LIST_helper(PyObject
* source
) { 
2108     if (!PyList_Check(source
)) { 
2109         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2112     int count 
= PyList_Size(source
); 
2113     long* temp 
= new long[count
]; 
2115         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2118     for (int x
=0; x
<count
; x
++) { 
2119         PyObject
* o 
= PyList_GetItem(source
, x
); 
2120         if (! PyInt_Check(o
)) { 
2121             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
2124         temp
[x
] = PyInt_AsLong(o
); 
2130 char** string_LIST_helper(PyObject
* source
) { 
2131     if (!PyList_Check(source
)) { 
2132         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2135     int count 
= PyList_Size(source
); 
2136     char** temp 
= new char*[count
]; 
2138         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2141     for (int x
=0; x
<count
; x
++) { 
2142         PyObject
* o 
= PyList_GetItem(source
, x
); 
2143         if (! PyString_Check(o
)) { 
2144             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2147         temp
[x
] = PyString_AsString(o
); 
2152 //-------------------------------- 
2153 // Part of patch from Tim Hochberg 
2154 static inline bool wxPointFromObjects(PyObject
* o1
, PyObject
* o2
, wxPoint
* point
) { 
2155     if (PyInt_Check(o1
) && PyInt_Check(o2
)) { 
2156         point
->x 
= PyInt_AS_LONG(o1
); 
2157         point
->y 
= PyInt_AS_LONG(o2
); 
2160     if (PyFloat_Check(o1
) && PyFloat_Check(o2
)) { 
2161         point
->x 
= (int)PyFloat_AS_DOUBLE(o1
); 
2162         point
->y 
= (int)PyFloat_AS_DOUBLE(o2
); 
2165     if (wxPySwigInstance_Check(o1
) || wxPySwigInstance_Check(o2
)) {  // TODO: Why??? 
2166         // Disallow instances because they can cause havok 
2169     if (PyNumber_Check(o1
) && PyNumber_Check(o2
)) { 
2170         // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2 
2171         point
->x 
= PyInt_AsLong(o1
); 
2172         point
->y 
= PyInt_AsLong(o2
); 
2179 wxPoint
* wxPoint_LIST_helper(PyObject
* source
, int *count
) { 
2180     // Putting all of the declarations here allows 
2181     // us to put the error handling all in one place. 
2184     PyObject 
*o
, *o1
, *o2
; 
2185     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2187     if (!PySequence_Check(source
)) { 
2191     // The length of the sequence is returned in count. 
2192     *count 
= PySequence_Length(source
); 
2197     temp 
= new wxPoint
[*count
]; 
2199         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2202     for (x
=0; x
<*count
; x
++) { 
2203         // Get an item: try fast way first. 
2205             o 
= PySequence_Fast_GET_ITEM(source
, x
); 
2208             o 
= PySequence_GetItem(source
, x
); 
2214         // Convert o to wxPoint. 
2215         if ((PyTuple_Check(o
) && PyTuple_GET_SIZE(o
) == 2) || 
2216             (PyList_Check(o
) && PyList_GET_SIZE(o
) == 2)) { 
2217             o1 
= PySequence_Fast_GET_ITEM(o
, 0); 
2218             o2 
= PySequence_Fast_GET_ITEM(o
, 1); 
2219             if (!wxPointFromObjects(o1
, o2
, &temp
[x
])) { 
2223         else if (wxPySwigInstance_Check(o
)) { 
2225             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPoint"))) { 
2230         else if (PySequence_Check(o
) && PySequence_Length(o
) == 2) { 
2231             o1 
= PySequence_GetItem(o
, 0); 
2232             o2 
= PySequence_GetItem(o
, 1); 
2233             if (!wxPointFromObjects(o1
, o2
, &temp
[x
])) { 
2257     PyErr_SetString(PyExc_TypeError
, "Expected a sequence of length-2 sequences or wxPoints."); 
2261 //------------------------------ 
2264 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) { 
2265     if (!PyList_Check(source
)) { 
2266         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2269     int count 
= PyList_Size(source
); 
2270     wxBitmap
** temp 
= new wxBitmap
*[count
]; 
2272         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2275     for (int x
=0; x
<count
; x
++) { 
2276         PyObject
* o 
= PyList_GetItem(source
, x
); 
2277         if (wxPySwigInstance_Check(o
)) { 
2279             if (! wxPyConvertSwigPtr(o
, (void **) &pt
, wxT("wxBitmap"))) { 
2280                 PyErr_SetString(PyExc_TypeError
,"Expected wxBitmap."); 
2286             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps."); 
2295 wxString
* wxString_LIST_helper(PyObject
* source
) { 
2296     if (!PyList_Check(source
)) { 
2297         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2300     int count 
= PyList_Size(source
); 
2301     wxString
* temp 
= new wxString
[count
]; 
2303         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2306     for (int x
=0; x
<count
; x
++) { 
2307         PyObject
* o 
= PyList_GetItem(source
, x
); 
2308 #if PYTHON_API_VERSION >= 1009 
2309         if (! PyString_Check(o
) && ! PyUnicode_Check(o
)) { 
2310             PyErr_SetString(PyExc_TypeError
, "Expected a list of string or unicode objects."); 
2314         if (! PyString_Check(o
)) { 
2315             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
2320         wxString
* pStr 
= wxString_in_helper(o
); 
2328 wxAcceleratorEntry
* wxAcceleratorEntry_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     wxAcceleratorEntry
* temp 
= new wxAcceleratorEntry
[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 (wxPySwigInstance_Check(o
)) { 
2342             wxAcceleratorEntry
* ae
; 
2343             if (! wxPyConvertSwigPtr(o
, (void **) &ae
, wxT("wxAcceleratorEntry"))) { 
2344                 PyErr_SetString(PyExc_TypeError
,"Expected wxAcceleratorEntry."); 
2349         else if (PyTuple_Check(o
)) { 
2350             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
2351             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
2352             PyObject
* o3 
= PyTuple_GetItem(o
, 2); 
2353             temp
[x
].Set(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2356             PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects."); 
2364 wxPen
** wxPen_LIST_helper(PyObject
* source
) { 
2365     if (!PyList_Check(source
)) { 
2366         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
2369     int count 
= PyList_Size(source
); 
2370     wxPen
** temp 
= new wxPen
*[count
]; 
2372         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
2375     for (int x
=0; x
<count
; x
++) { 
2376         PyObject
* o 
= PyList_GetItem(source
, x
); 
2377         if (wxPySwigInstance_Check(o
)) { 
2379             if (! wxPyConvertSwigPtr(o
, (void **)&pt
, wxT("wxPen"))) { 
2381                 PyErr_SetString(PyExc_TypeError
,"Expected wxPen."); 
2388             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxPens."); 
2396 bool wxPy2int_seq_helper(PyObject
* source
, int* i1
, int* i2
) { 
2397     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2400     if (!PySequence_Check(source
) || PySequence_Length(source
) != 2) 
2404         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2405         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2408         o1 
= PySequence_GetItem(source
, 0); 
2409         o2 
= PySequence_GetItem(source
, 1); 
2412     *i1 
= PyInt_AsLong(o1
); 
2413     *i2 
= PyInt_AsLong(o2
); 
2423 bool wxPy4int_seq_helper(PyObject
* source
, int* i1
, int* i2
, int* i3
, int* i4
) { 
2424     bool isFast 
= PyList_Check(source
) || PyTuple_Check(source
); 
2425     PyObject 
*o1
, *o2
, *o3
, *o4
; 
2427     if (!PySequence_Check(source
) || PySequence_Length(source
) != 4) 
2431         o1 
= PySequence_Fast_GET_ITEM(source
, 0); 
2432         o2 
= PySequence_Fast_GET_ITEM(source
, 1); 
2433         o3 
= PySequence_Fast_GET_ITEM(source
, 2); 
2434         o4 
= PySequence_Fast_GET_ITEM(source
, 3); 
2437         o1 
= PySequence_GetItem(source
, 0); 
2438         o2 
= PySequence_GetItem(source
, 1); 
2439         o3 
= PySequence_GetItem(source
, 2); 
2440         o4 
= PySequence_GetItem(source
, 3); 
2443     *i1 
= PyInt_AsLong(o1
); 
2444     *i2 
= PyInt_AsLong(o2
); 
2445     *i3 
= PyInt_AsLong(o3
); 
2446     *i4 
= PyInt_AsLong(o4
); 
2458 //---------------------------------------------------------------------- 
2460 bool wxPySimple_typecheck(PyObject
* source
, const wxChar
* classname
, int seqLen
) 
2464     if (wxPySwigInstance_Check(source
) && 
2465         wxPyConvertSwigPtr(source
, (void **)&ptr
, classname
)) 
2469     if (PySequence_Check(source
) && PySequence_Length(source
) == seqLen
) 
2475 bool wxSize_helper(PyObject
* source
, wxSize
** obj
) 
2477     if (source 
== Py_None
) { 
2478         **obj 
= wxSize(-1,-1); 
2481     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxSize")); 
2485 bool wxPoint_helper(PyObject
* source
, wxPoint
** obj
) 
2487     if (source 
== Py_None
) { 
2488         **obj 
= wxPoint(-1,-1); 
2491     return wxPyTwoIntItem_helper(source
, obj
, wxT("wxPoint")); 
2496 bool wxRealPoint_helper(PyObject
* source
, wxRealPoint
** obj
) { 
2498     if (source 
== Py_None
) { 
2499         **obj 
= wxRealPoint(-1,-1); 
2503     // If source is an object instance then it may already be the right type 
2504     if (wxPySwigInstance_Check(source
)) { 
2506         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRealPoint"))) 
2511     // otherwise a 2-tuple of floats is expected 
2512     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
2513         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2514         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2515         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2520         **obj 
= wxRealPoint(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2527     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxRealPoint object."); 
2533 bool wxRect_helper(PyObject
* source
, wxRect
** obj
) { 
2535     if (source 
== Py_None
) { 
2536         **obj 
= wxRect(-1,-1,-1,-1); 
2540     // If source is an object instance then it may already be the right type 
2541     if (wxPySwigInstance_Check(source
)) { 
2543         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxRect"))) 
2548     // otherwise a 4-tuple of integers is expected 
2549     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
2550         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2551         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2552         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2553         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
2554         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || 
2555             !PyNumber_Check(o3
) || !PyNumber_Check(o4
)) { 
2562         **obj 
= wxRect(PyInt_AsLong(o1
), PyInt_AsLong(o2
), 
2563                        PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
2572     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of integers or a wxRect object."); 
2578 bool wxColour_helper(PyObject
* source
, wxColour
** obj
) { 
2580     if (source 
== Py_None
) { 
2581         **obj 
= wxNullColour
; 
2585     // If source is an object instance then it may already be the right type 
2586     if (wxPySwigInstance_Check(source
)) { 
2588         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxColour"))) 
2593     // otherwise check for a string 
2594     else if (PyString_Check(source
) || PyUnicode_Check(source
)) { 
2595         wxString spec 
= Py2wxString(source
); 
2596         if (spec
.GetChar(0) == '#' && spec
.Length() == 7) {  // It's  #RRGGBB 
2597             long red
, green
, blue
; 
2598             red 
= green 
= blue 
= 0; 
2599             spec
.Mid(1,2).ToLong(&red
,   16); 
2600             spec
.Mid(3,2).ToLong(&green
, 16); 
2601             spec
.Mid(5,2).ToLong(&blue
,  16); 
2603             **obj 
= wxColour(red
, green
, blue
); 
2606         else {                                       // it's a colour name 
2607             **obj 
= wxColour(spec
); 
2611     // last chance: 3-tuple of integers is expected 
2612     else if (PySequence_Check(source
) && PyObject_Length(source
) == 3) { 
2613         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2614         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2615         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
2616         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
) || !PyNumber_Check(o3
)) { 
2622         **obj 
= wxColour(PyInt_AsLong(o1
), PyInt_AsLong(o2
), PyInt_AsLong(o3
)); 
2630     PyErr_SetString(PyExc_TypeError
, 
2631                     "Expected a wxColour object or a string containing a colour name or '#RRGGBB'."); 
2636 bool wxColour_typecheck(PyObject
* source
) { 
2638     if (wxPySimple_typecheck(source
, wxT("wxColour"), 3)) 
2641     if (PyString_Check(source
) || PyUnicode_Check(source
)) 
2649 bool wxPoint2D_helper(PyObject
* source
, wxPoint2D
** obj
) { 
2651     if (source 
== Py_None
) { 
2652         **obj 
= wxPoint2D(-1,-1); 
2656     // If source is an object instance then it may already be the right type 
2657     if (wxPySwigInstance_Check(source
)) { 
2659         if (! wxPyConvertSwigPtr(source
, (void **)&ptr
, wxT("wxPoint2D"))) 
2664     // otherwise a length-2 sequence of floats is expected 
2665     if (PySequence_Check(source
) && PySequence_Length(source
) == 2) { 
2666         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
2667         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
2668         // This should really check for floats, not numbers -- but that would break code. 
2669         if (!PyNumber_Check(o1
) || !PyNumber_Check(o2
)) { 
2674         **obj 
= wxPoint2D(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
2680     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxPoint2D object."); 
2685 //---------------------------------------------------------------------- 
2687 PyObject
* wxArrayString2PyList_helper(const wxArrayString
& arr
) { 
2689     PyObject
* list 
= PyList_New(0); 
2690     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2692         PyObject
* str 
= PyUnicode_FromWideChar(arr
[i
].c_str(), arr
[i
].Len()); 
2694         PyObject
* str 
= PyString_FromStringAndSize(arr
[i
].c_str(), arr
[i
].Len()); 
2696         PyList_Append(list
, str
); 
2703 PyObject
* wxArrayInt2PyList_helper(const wxArrayInt
& arr
) { 
2705     PyObject
* list 
= PyList_New(0); 
2706     for (size_t i
=0; i 
< arr
.GetCount(); i
++) { 
2707         PyObject
* number 
= PyInt_FromLong(arr
[i
]); 
2708         PyList_Append(list
, number
); 
2715 //---------------------------------------------------------------------- 
2716 // wxPyImageHandler methods 
2718 // TODO: Switch these to use wxPython's standard macros and helper classes 
2719 //       for calling callbacks. 
2721 PyObject
* wxPyImageHandler::m_DoCanRead_Name 
= NULL
; 
2722 PyObject
* wxPyImageHandler::m_GetImageCount_Name 
= NULL
; 
2723 PyObject
* wxPyImageHandler::m_LoadFile_Name 
= NULL
; 
2724 PyObject
* wxPyImageHandler::m_SaveFile_Name 
= NULL
; 
2726 PyObject
* wxPyImageHandler::py_InputStream(wxInputStream
* stream
) { 
2727     return wxPyConstructObject(new wxPyInputStream(stream
), 
2728                                wxT("wxPyInputStream"), 0); 
2731 PyObject
* wxPyImageHandler::py_Image(wxImage
* image
) { 
2732     return wxPyConstructObject(image
, wxT("wxImage"), 0); 
2735 PyObject
* wxPyImageHandler::py_OutputStream(wxOutputStream
* stream
) { 
2736     return wxPyConstructObject(stream
, wxT("wxOutputStream"), 0); 
2739 wxPyImageHandler::wxPyImageHandler(): 
2742     if (!m_DoCanRead_Name
) { 
2743         m_DoCanRead_Name 
= PyString_FromString("DoCanRead"); 
2744         m_GetImageCount_Name 
= PyString_FromString("GetImageCount"); 
2745         m_LoadFile_Name 
= PyString_FromString("LoadFile"); 
2746         m_SaveFile_Name 
= PyString_FromString("SaveFile"); 
2750 wxPyImageHandler::~wxPyImageHandler() { 
2757 void wxPyImageHandler::_SetSelf(PyObject 
*self
) { 
2758     // should check here for isinstance(PyImageHandler) ?? 
2763 bool wxPyImageHandler::DoCanRead(wxInputStream
& stream
) { 
2764     // check if our object has this method 
2765     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2766     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_DoCanRead_Name
)) { 
2767         wxPyEndBlockThreads(blocked
); 
2771     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_DoCanRead_Name
, 
2772                                                py_InputStream(&stream
), NULL
); 
2773     bool retval 
= false; 
2775         retval 
= PyInt_AsLong(res
); 
2781     wxPyEndBlockThreads(blocked
); 
2785 bool wxPyImageHandler::LoadFile( wxImage
* image
, wxInputStream
& stream
, 
2786                                  bool verbose
, int index 
) { 
2787     // check if our object has this method 
2788     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2789     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_LoadFile_Name
)) { 
2790         wxPyEndBlockThreads(blocked
); 
2793     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_LoadFile_Name
, 
2795                                                py_InputStream(&stream
), 
2796                                                PyInt_FromLong(verbose
), 
2797                                                PyInt_FromLong(index
), 
2799     bool retval 
= false; 
2801         retval 
= PyInt_AsLong(res
); 
2806     wxPyEndBlockThreads(blocked
); 
2810 bool wxPyImageHandler::SaveFile( wxImage
* image
, wxOutputStream
& stream
, 
2812     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2813     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_SaveFile_Name
)) { 
2814         wxPyEndBlockThreads(blocked
); 
2817     PyObject
* res 
= PyObject_CallMethodObjArgs(m_self
, m_SaveFile_Name
, 
2819                                                py_OutputStream(&stream
), 
2820                                                PyInt_FromLong(verbose
), 
2822     bool retval 
= false; 
2824         retval
=PyInt_AsLong(res
); 
2829     wxPyEndBlockThreads(blocked
); 
2833 int wxPyImageHandler::GetImageCount( wxInputStream
& stream 
) { 
2834     wxPyBlock_t blocked 
= wxPyBeginBlockThreads(); 
2835     if (!m_self 
|| !PyObject_HasAttr(m_self
, m_GetImageCount_Name
)) { 
2836         wxPyEndBlockThreads(blocked
); 
2839     PyObject 
*res
=PyObject_CallMethodObjArgs(m_self
, m_GetImageCount_Name
, 
2840                                              py_InputStream(&stream
), 
2844         retval
=PyInt_AsLong(res
); 
2849     wxPyEndBlockThreads(blocked
); 
2854 //---------------------------------------------------------------------- 
2855 //----------------------------------------------------------------------