1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Helper functions/classes for the wxPython extension module 
   9 // Copyright:   (c) 1998 by Total Control Software 
  10 // Licence:     wxWindows license 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 #include <stdio.h>  // get the correct definition of NULL 
  20 #include <wx/msw/private.h> 
  23 #undef LoadAccelerators 
  30 #include <gdk/gdkprivate.h> 
  31 #include <wx/gtk/win_gtk.h> 
  32 //#include <gdk/gdk.h> 
  33 //#include <gdk/gdkx.h> 
  34 //#include <gtk/gtkwindow.h> 
  36 //extern GtkWidget *wxRootWindow; 
  41 //--------------------------------------------------------------------------- 
  43 //wxHashTable*  wxPyWindows = NULL; 
  46 wxPoint     wxPyDefaultPosition
;        //wxDefaultPosition); 
  47 wxSize      wxPyDefaultSize
;            //wxDefaultSize); 
  48 wxString    
wxPyEmptyStr(""); 
  52 #ifdef __WXMSW__             // If building for win32... 
  53 //---------------------------------------------------------------------- 
  54 // This gets run when the DLL is loaded.  We just need to save a handle. 
  55 //---------------------------------------------------------------------- 
  58     HINSTANCE   hinstDLL
,    // handle to DLL module 
  59     DWORD       fdwReason
,   // reason for calling function 
  60     LPVOID      lpvReserved  
// reserved 
  63     wxSetInstance(hinstDLL
); 
  68 //---------------------------------------------------------------------- 
  69 // Class for implementing the wxp main application shell. 
  70 //---------------------------------------------------------------------- 
  72 wxPyApp 
*wxPythonApp 
= NULL
;            // Global instance of application object 
  76 //    printf("**** ctor\n"); 
  80 //    printf("**** dtor\n"); 
  84 // This one isn't acutally called...  See __wxStart() 
  85 bool wxPyApp::OnInit(void) { 
  89 int  wxPyApp::MainLoop(void) { 
  92     DeletePendingObjects(); 
  94     m_initialized 
= wxTopLevelWindows
.GetCount() != 0; 
  98         retval 
= wxApp::MainLoop(); 
  99         wxPythonApp
->OnExit(); 
 105 //--------------------------------------------------------------------- 
 106 //---------------------------------------------------------------------- 
 109 #include "wx/msw/msvcrt.h" 
 113 int  WXDLLEXPORT 
wxEntryStart( int argc
, char** argv 
); 
 114 int  WXDLLEXPORT 
wxEntryInitGui(); 
 115 void WXDLLEXPORT 
wxEntryCleanup(); 
 118 #ifdef WXP_WITH_THREAD 
 119 PyThreadState
*  wxPyEventThreadState 
= NULL
; 
 121 static char* __nullArgv
[1] = { 0 }; 
 124 // This is where we pick up the first part of the wxEntry functionality... 
 125 // The rest is in __wxStart and  __wxCleanup.  This function is called when 
 126 // wxcmodule is imported.  (Before there is a wxApp object.) 
 131 //    wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); 
 134 #ifdef WXP_WITH_THREAD 
 135     PyEval_InitThreads(); 
 136     wxPyEventThreadState 
= PyThreadState_Get(); 
 139     // Bail out if there is already windows created.  This means that the 
 140     // toolkit has already been initialized, as in embedding wxPython in 
 141     // a C++ wxWindows app. 
 142     if (wxTopLevelWindows
.Number() > 0) 
 146     PyObject
* sysargv 
= PySys_GetObject("argv"); 
 147     int argc 
= PyList_Size(sysargv
); 
 148     char** argv 
= new char*[argc
+1]; 
 150     for(x
=0; x
<argc
; x
++) 
 151         argv
[x
] = PyString_AsString(PyList_GetItem(sysargv
, x
)); 
 154     wxEntryStart(argc
, argv
); 
 160 // Start the user application, user App's OnInit method is a parameter here 
 161 PyObject
* __wxStart(PyObject
* /* self */, PyObject
* args
) 
 163     PyObject
*   onInitFunc 
= NULL
; 
 168     if (!PyArg_ParseTuple(args
, "O", &onInitFunc
)) 
 171 #if 0  // Try it out without this check, soo how it does... 
 172     if (wxTopLevelWindows
.Number() > 0) { 
 173         PyErr_SetString(PyExc_TypeError
, "Only 1 wxApp per process!"); 
 178     // This is the next part of the wxEntry functionality... 
 179     PyObject
* sysargv 
= PySys_GetObject("argv"); 
 180     int argc 
= PyList_Size(sysargv
); 
 181     char** argv 
= new char*[argc
+1]; 
 183     for(x
=0; x
<argc
; x
++) 
 184         argv
[x
] = copystring(PyString_AsString(PyList_GetItem(sysargv
, x
))); 
 187     wxPythonApp
->argc 
= argc
; 
 188     wxPythonApp
->argv 
= argv
; 
 192     // Call the Python App's OnInit function 
 193     arglist 
= PyTuple_New(0); 
 194     result 
= PyEval_CallObject(onInitFunc
, arglist
); 
 195     if (!result
) {      // an exception was raised. 
 199     if (! PyInt_Check(result
)) { 
 200         PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value"); 
 203     bResult 
= PyInt_AS_LONG(result
); 
 205         PyErr_SetString(PyExc_SystemExit
, "OnInit returned FALSE, exiting..."); 
 210     wxTheApp
->m_initialized 
= (wxTopLevelWindows
.GetCount() > 0); 
 223 PyObject
* wxPython_dict
; 
 224 PyObject
* __wxSetDictionary(PyObject
* /* self */, PyObject
* args
) 
 227     if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
)) 
 230     if (!PyDict_Check(wxPython_dict
)) { 
 231         PyErr_SetString(PyExc_TypeError
, "_wxSetDictionary must have dictionary object!"); 
 235 #define wxPlatform "__WXMOTIF__" 
 238 #define wxPlatform "__WXQT__" 
 241 #define wxPlatform "__WXGTK__" 
 243 #if defined(__WIN32__) || defined(__WXMSW__) 
 244 #define wxPlatform "__WXMSW__" 
 247 #define wxPlatform "__WXMAC__" 
 250     PyDict_SetItemString(wxPython_dict
, "wxPlatform", PyString_FromString(wxPlatform
)); 
 257 //--------------------------------------------------------------------------- 
 259 PyObject
* wxPyConstructObject(void* ptr
, 
 260                               const char* className
, 
 270     char    buff
[64];               // should always be big enough... 
 273     sprintf(buff
, "_%s_p", className
); 
 274     SWIG_MakePtr(swigptr
, ptr
, buff
); 
 276     sprintf(buff
, "%sPtr", className
); 
 277     PyObject
* classobj 
= PyDict_GetItemString(wxPython_dict
, buff
); 
 279         //Py_INCREF(Py_None); 
 283                 "*** Unknown class name %s, tell Robin about it please ***", 
 285         obj 
= PyString_FromString(temp
); 
 289     arg 
= Py_BuildValue("(s)", swigptr
); 
 290     obj 
= PyInstance_New(classobj
, arg
, NULL
); 
 294         PyObject
* one 
= PyInt_FromLong(1); 
 295         PyObject_SetAttrString(obj
, "thisown", one
); 
 302 //--------------------------------------------------------------------------- 
 304 static PyThreadState
* myPyThreadState_Get() { 
 305     PyThreadState
* current
; 
 306     current 
= PyThreadState_Swap(NULL
); 
 307     PyThreadState_Swap(current
); 
 312 bool wxPyRestoreThread() { 
 313     // NOTE: The Python API docs state that if a thread already has the 
 314     // interpreter lock and calls PyEval_RestoreThread again a deadlock 
 315     // occurs, so I put in this code as a guard condition since there are 
 316     // many possibilites for nested events and callbacks in wxPython.  If 
 317     // The current thread is our thread, then we can assume that we 
 318     // already have the lock.  (I hope!) 
 320 #ifdef WXP_WITH_THREAD 
 321     if (wxPyEventThreadState 
!= myPyThreadState_Get()) { 
 322         PyEval_RestoreThread(wxPyEventThreadState
); 
 331 void wxPySaveThread(bool doSave
) { 
 332 #ifdef WXP_WITH_THREAD 
 334         wxPyEventThreadState 
= PyEval_SaveThread(); 
 339 //--------------------------------------------------------------------------- 
 342 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback
, wxObject
); 
 344 wxPyCallback::wxPyCallback(PyObject
* func
) { 
 349 wxPyCallback::wxPyCallback(const wxPyCallback
& other
) { 
 350     m_func 
= other
.m_func
; 
 354 wxPyCallback::~wxPyCallback() { 
 355     bool doSave 
= wxPyRestoreThread(); 
 357     wxPySaveThread(doSave
); 
 362 // This function is used for all events destined for Python event handlers. 
 363 void wxPyCallback::EventThunker(wxEvent
& event
) { 
 364     wxPyCallback
*   cb 
= (wxPyCallback
*)event
.m_callbackUserData
; 
 365     PyObject
*       func 
= cb
->m_func
; 
 371     bool doSave 
= wxPyRestoreThread(); 
 372     wxString className 
= event
.GetClassInfo()->GetClassName(); 
 374     if (className 
== "wxPyEvent") 
 375         arg 
= ((wxPyEvent
*)&event
)->GetSelf(); 
 376     else if (className 
== "wxPyCommandEvent") 
 377         arg 
= ((wxPyCommandEvent
*)&event
)->GetSelf(); 
 379         arg 
= wxPyConstructObject((void*)&event
, className
); 
 381     tuple 
= PyTuple_New(1); 
 382     PyTuple_SET_ITEM(tuple
, 0, arg
); 
 383     result 
= PyEval_CallObject(func
, tuple
); 
 391     wxPySaveThread(doSave
); 
 395 //---------------------------------------------------------------------- 
 397 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper
& other
) { 
 399       m_self 
= other
.m_self
; 
 400       m_class 
= other
.m_class
; 
 408 void wxPyCallbackHelper::setSelf(PyObject
* self
, PyObject
* klass
, int incref
) { 
 419 // If the object (m_self) has an attibute of the given name, and if that 
 420 // attribute is a method, and if that method's class is not from a base class, 
 421 // then we'll save a pointer to the method so callCallback can call it. 
 422 bool wxPyCallbackHelper::findCallback(const char* name
) const { 
 423     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
 424     self
->m_lastFound 
= NULL
; 
 425     if (m_self 
&& PyObject_HasAttrString(m_self
, (char*)name
)) { 
 427         method 
= PyObject_GetAttrString(m_self
, (char*)name
); 
 429         if (PyMethod_Check(method
) && 
 430             ((PyMethod_GET_CLASS(method
) == m_class
) || 
 431              PyClass_IsSubclass(PyMethod_GET_CLASS(method
), m_class
))) { 
 433             self
->m_lastFound 
= method
; 
 439     return m_lastFound 
!= NULL
; 
 443 int wxPyCallbackHelper::callCallback(PyObject
* argTuple
) const { 
 447     result 
= callCallbackObj(argTuple
); 
 448     if (result
) {                       // Assumes an integer return type... 
 449         retval 
= PyInt_AsLong(result
); 
 451         PyErr_Clear();                  // forget about it if it's not... 
 456 // Invoke the Python callable object, returning the raw PyObject return 
 457 // value.  Caller should DECREF the return value and also call PyEval_SaveThread. 
 458 PyObject
* wxPyCallbackHelper::callCallbackObj(PyObject
* argTuple
) const { 
 459     wxPyCallbackHelper
* self 
= (wxPyCallbackHelper
*)this; // cast away const 
 462     // Save a copy of the pointer in case the callback generates another 
 463     // callback.  In that case m_lastFound will have a different value when 
 464     // it gets back here... 
 465     PyObject
* method 
= m_lastFound
; 
 467     result 
= PyEval_CallObject(method
, argTuple
); 
 477 void wxPyCBH_setSelf(wxPyCallbackHelper
& cbh
, PyObject
* self
, PyObject
* klass
, int incref
) { 
 478     cbh
.setSelf(self
, klass
, incref
); 
 481 bool wxPyCBH_findCallback(const wxPyCallbackHelper
& cbh
, const char* name
) { 
 482     return cbh
.findCallback(name
); 
 485 int  wxPyCBH_callCallback(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
 486     return cbh
.callCallback(argTuple
); 
 489 PyObject
* wxPyCBH_callCallbackObj(const wxPyCallbackHelper
& cbh
, PyObject
* argTuple
) { 
 490     return cbh
.callCallbackObj(argTuple
); 
 494 void wxPyCBH_delete(wxPyCallbackHelper
* cbh
) { 
 495     bool doSave 
= wxPyRestoreThread(); 
 497         Py_XDECREF(cbh
->m_self
); 
 498         Py_XDECREF(cbh
->m_class
); 
 500     wxPySaveThread(doSave
); 
 503 //--------------------------------------------------------------------------- 
 504 //--------------------------------------------------------------------------- 
 505 // These classes can be derived from in Python and passed through the event 
 506 // system without losing anything.  They do this by keeping a reference to 
 507 // themselves and some special case handling in wxPyCallback::EventThunker. 
 510 wxPyEvtSelfRef::wxPyEvtSelfRef() { 
 511     //m_self = Py_None;         // **** We don't do normal ref counting to prevent 
 512     //Py_INCREF(m_self);        //      circular loops... 
 516 wxPyEvtSelfRef::~wxPyEvtSelfRef() { 
 517     bool doSave 
= wxPyRestoreThread(); 
 520     wxPySaveThread(doSave
); 
 523 void wxPyEvtSelfRef::SetSelf(PyObject
* self
, bool clone
) { 
 524     bool doSave 
= wxPyRestoreThread(); 
 532     wxPySaveThread(doSave
); 
 535 PyObject
* wxPyEvtSelfRef::GetSelf() const { 
 541 wxPyEvent::wxPyEvent(int id
) 
 545 wxPyEvent::~wxPyEvent() { 
 548 // This one is so the event object can be Cloned... 
 549 void wxPyEvent::CopyObject(wxObject
& dest
) const { 
 550     wxEvent::CopyObject(dest
); 
 551     ((wxPyEvent
*)&dest
)->SetSelf(m_self
, TRUE
); 
 555 IMPLEMENT_DYNAMIC_CLASS(wxPyEvent
, wxEvent
); 
 558 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType
, int id
) 
 559     : wxCommandEvent(commandType
, id
) { 
 562 wxPyCommandEvent::~wxPyCommandEvent() { 
 565 void wxPyCommandEvent::CopyObject(wxObject
& dest
) const { 
 566     wxCommandEvent::CopyObject(dest
); 
 567     ((wxPyCommandEvent
*)&dest
)->SetSelf(m_self
, TRUE
); 
 571 IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent
, wxCommandEvent
); 
 575 //--------------------------------------------------------------------------- 
 576 //--------------------------------------------------------------------------- 
 579 wxPyTimer::wxPyTimer(PyObject
* callback
) { 
 584 wxPyTimer::~wxPyTimer() { 
 585     bool doSave 
= wxPyRestoreThread(); 
 587     wxPySaveThread(doSave
); 
 590 void wxPyTimer::Notify() { 
 591     if (!func 
|| func 
== Py_None
) { 
 595         bool doSave 
= wxPyRestoreThread(); 
 598         PyObject
*   args 
= Py_BuildValue("()"); 
 600         result 
= PyEval_CallObject(func
, args
); 
 609         wxPySaveThread(doSave
); 
 615 //--------------------------------------------------------------------------- 
 616 //--------------------------------------------------------------------------- 
 617 // Convert a wxList to a Python List 
 619 PyObject
* wxPy_ConvertList(wxListBase
* list
, const char* className
) { 
 623     wxNode
*     node 
= list
->First(); 
 625     bool doSave 
= wxPyRestoreThread(); 
 626     pyList 
= PyList_New(0); 
 628         wxObj 
= node
->Data(); 
 629         pyObj 
= wxPyConstructObject(wxObj
, className
); 
 630         PyList_Append(pyList
, pyObj
); 
 633     wxPySaveThread(doSave
); 
 637 //---------------------------------------------------------------------- 
 639 long wxPyGetWinHandle(wxWindow
* win
) { 
 641     return (long)win
->GetHandle(); 
 644     // Find and return the actual X-Window. 
 646     if (win
->m_wxwindow
) { 
 647         GdkWindowPrivate
* bwin 
= (GdkWindowPrivate
*)GTK_PIZZA(win
->m_wxwindow
)->bin_window
; 
 649             return (long)bwin
->xwindow
; 
 656 //---------------------------------------------------------------------- 
 657 // Some helper functions for typemaps in my_typemaps.i, so they won't be 
 658 // included in every file... 
 661 byte
* byte_LIST_helper(PyObject
* source
) { 
 662     if (!PyList_Check(source
)) { 
 663         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 666     int count 
= PyList_Size(source
); 
 667     byte
* temp 
= new byte
[count
]; 
 669         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 672     for (int x
=0; x
<count
; x
++) { 
 673         PyObject
* o 
= PyList_GetItem(source
, x
); 
 674         if (! PyInt_Check(o
)) { 
 675             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
 678         temp
[x
] = (byte
)PyInt_AsLong(o
); 
 684 int* int_LIST_helper(PyObject
* source
) { 
 685     if (!PyList_Check(source
)) { 
 686         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 689     int count 
= PyList_Size(source
); 
 690     int* temp 
= new int[count
]; 
 692         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 695     for (int x
=0; x
<count
; x
++) { 
 696         PyObject
* o 
= PyList_GetItem(source
, x
); 
 697         if (! PyInt_Check(o
)) { 
 698             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
 701         temp
[x
] = PyInt_AsLong(o
); 
 707 long* long_LIST_helper(PyObject
* source
) { 
 708     if (!PyList_Check(source
)) { 
 709         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 712     int count 
= PyList_Size(source
); 
 713     long* temp 
= new long[count
]; 
 715         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 718     for (int x
=0; x
<count
; x
++) { 
 719         PyObject
* o 
= PyList_GetItem(source
, x
); 
 720         if (! PyInt_Check(o
)) { 
 721             PyErr_SetString(PyExc_TypeError
, "Expected a list of integers."); 
 724         temp
[x
] = PyInt_AsLong(o
); 
 730 char** string_LIST_helper(PyObject
* source
) { 
 731     if (!PyList_Check(source
)) { 
 732         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 735     int count 
= PyList_Size(source
); 
 736     char** temp 
= new char*[count
]; 
 738         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 741     for (int x
=0; x
<count
; x
++) { 
 742         PyObject
* o 
= PyList_GetItem(source
, x
); 
 743         if (! PyString_Check(o
)) { 
 744             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
 747         temp
[x
] = PyString_AsString(o
); 
 754 wxPoint
* wxPoint_LIST_helper(PyObject
* source
) { 
 755     if (!PyList_Check(source
)) { 
 756         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 759     int count 
= PyList_Size(source
); 
 760     wxPoint
* temp 
= new wxPoint
[count
]; 
 762         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 765     for (int x
=0; x
<count
; x
++) { 
 766         PyObject
* o 
= PyList_GetItem(source
, x
); 
 767         if (PyTuple_Check(o
)) { 
 768             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
 769             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
 771             temp
[x
].x 
= PyInt_AsLong(o1
); 
 772             temp
[x
].y 
= PyInt_AsLong(o2
); 
 774         else if (PyInstance_Check(o
)) { 
 776             if (SWIG_GetPtrObj(o
,(void **) &pt
,"_wxPoint_p")) { 
 777                 PyErr_SetString(PyExc_TypeError
,"Expected _wxPoint_p."); 
 783             PyErr_SetString(PyExc_TypeError
, "Expected a list of 2-tuples or wxPoints."); 
 791 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) { 
 792     if (!PyList_Check(source
)) { 
 793         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 796     int count 
= PyList_Size(source
); 
 797     wxBitmap
** temp 
= new wxBitmap
*[count
]; 
 799         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 802     for (int x
=0; x
<count
; x
++) { 
 803         PyObject
* o 
= PyList_GetItem(source
, x
); 
 804         if (PyInstance_Check(o
)) { 
 806             if (SWIG_GetPtrObj(o
, (void **) &pt
,"_wxBitmap_p")) { 
 807                 PyErr_SetString(PyExc_TypeError
,"Expected _wxBitmap_p."); 
 813             PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps."); 
 822 wxString
* wxString_LIST_helper(PyObject
* source
) { 
 823     if (!PyList_Check(source
)) { 
 824         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 827     int count 
= PyList_Size(source
); 
 828     wxString
* temp 
= new wxString
[count
]; 
 830         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 833     for (int x
=0; x
<count
; x
++) { 
 834         PyObject
* o 
= PyList_GetItem(source
, x
); 
 835         if (! PyString_Check(o
)) { 
 836             PyErr_SetString(PyExc_TypeError
, "Expected a list of strings."); 
 839         temp
[x
] = PyString_AsString(o
); 
 845 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) { 
 846     if (!PyList_Check(source
)) { 
 847         PyErr_SetString(PyExc_TypeError
, "Expected a list object."); 
 850     int count                
= PyList_Size(source
); 
 851     wxAcceleratorEntry
* temp 
= new wxAcceleratorEntry
[count
]; 
 853         PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array"); 
 856     for (int x
=0; x
<count
; x
++) { 
 857         PyObject
* o 
= PyList_GetItem(source
, x
); 
 858         if (PyInstance_Check(o
)) { 
 859             wxAcceleratorEntry
* ae
; 
 860             if (SWIG_GetPtrObj(o
, (void **) &ae
,"_wxAcceleratorEntry_p")) { 
 861                 PyErr_SetString(PyExc_TypeError
,"Expected _wxAcceleratorEntry_p."); 
 866         else if (PyTuple_Check(o
)) { 
 867             PyObject
* o1 
= PyTuple_GetItem(o
, 0); 
 868             PyObject
* o2 
= PyTuple_GetItem(o
, 1); 
 869             PyObject
* o3 
= PyTuple_GetItem(o
, 2); 
 871             temp
[x
].m_flags   
= PyInt_AsLong(o1
); 
 872             temp
[x
].m_keyCode 
= PyInt_AsLong(o2
); 
 873             temp
[x
].m_command 
= PyInt_AsLong(o3
); 
 876             PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects."); 
 885 //---------------------------------------------------------------------- 
 887 bool wxSize_helper(PyObject
* source
, wxSize
** obj
) { 
 889     // If source is an object instance then it may already be the right type 
 890     if (PyInstance_Check(source
)) { 
 892         if (SWIG_GetPtrObj(source
, (void **)&ptr
, "_wxSize_p")) 
 897     // otherwise a 2-tuple of integers is expected 
 898     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
 899         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
 900         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
 901         **obj 
= wxSize(PyInt_AsLong(o1
), PyInt_AsLong(o2
)); 
 906     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of integers or a wxSize object."); 
 910 bool wxPoint_helper(PyObject
* source
, wxPoint
** obj
) { 
 912     // If source is an object instance then it may already be the right type 
 913     if (PyInstance_Check(source
)) { 
 915         if (SWIG_GetPtrObj(source
, (void **)&ptr
, "_wxPoint_p")) 
 920     // otherwise a 2-tuple of integers is expected 
 921     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
 922         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
 923         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
 924         **obj 
= wxPoint(PyInt_AsLong(o1
), PyInt_AsLong(o2
)); 
 929     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of integers or a wxPoint object."); 
 935 bool wxRealPoint_helper(PyObject
* source
, wxRealPoint
** obj
) { 
 937     // If source is an object instance then it may already be the right type 
 938     if (PyInstance_Check(source
)) { 
 940         if (SWIG_GetPtrObj(source
, (void **)&ptr
, "_wxRealPoint_p")) 
 945     // otherwise a 2-tuple of floats is expected 
 946     else if (PySequence_Check(source
) && PyObject_Length(source
) == 2) { 
 947         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
 948         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
 949         **obj 
= wxRealPoint(PyFloat_AsDouble(o1
), PyFloat_AsDouble(o2
)); 
 954     PyErr_SetString(PyExc_TypeError
, "Expected a 2-tuple of floats or a wxRealPoint object."); 
 961 bool wxRect_helper(PyObject
* source
, wxRect
** obj
) { 
 963     // If source is an object instance then it may already be the right type 
 964     if (PyInstance_Check(source
)) { 
 966         if (SWIG_GetPtrObj(source
, (void **)&ptr
, "_wxRect_p")) 
 971     // otherwise a 4-tuple of integers is expected 
 972     else if (PySequence_Check(source
) && PyObject_Length(source
) == 4) { 
 973         PyObject
* o1 
= PySequence_GetItem(source
, 0); 
 974         PyObject
* o2 
= PySequence_GetItem(source
, 1); 
 975         PyObject
* o3 
= PySequence_GetItem(source
, 2); 
 976         PyObject
* o4 
= PySequence_GetItem(source
, 3); 
 977         **obj 
= wxRect(PyInt_AsLong(o1
), PyInt_AsLong(o2
), 
 978                      PyInt_AsLong(o3
), PyInt_AsLong(o4
)); 
 983     PyErr_SetString(PyExc_TypeError
, "Expected a 4-tuple of integers or a wxRect object."); 
 989 bool wxColour_helper(PyObject
* source
, wxColour
** obj
) { 
 991     // If source is an object instance then it may already be the right type 
 992     if (PyInstance_Check(source
)) { 
 994         if (SWIG_GetPtrObj(source
, (void **)&ptr
, "_wxColour_p")) 
 999     // otherwise a string is expected 
1000     else if (PyString_Check(source
)) { 
1001         wxString spec 
= PyString_AS_STRING(source
); 
1002         if (spec
[0] == '#' && spec
.Length() == 7) {  // It's  #RRGGBB 
1004             int red   
= strtol(spec
.Mid(1,2), &junk
, 16); 
1005             int green 
= strtol(spec
.Mid(3,2), &junk
, 16); 
1006             int blue  
= strtol(spec
.Mid(5,2), &junk
, 16); 
1007             **obj 
= wxColour(red
, green
, blue
); 
1010         else {                                       // it's a colour name 
1011             **obj 
= wxColour(spec
); 
1017     PyErr_SetString(PyExc_TypeError
, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'."); 
1022 //---------------------------------------------------------------------- 
1023 //---------------------------------------------------------------------- 
1024 //----------------------------------------------------------------------