]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/src/helpers.cpp
added font encoding support
[wxWidgets.git] / utils / wxPython / src / helpers.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: helpers.cpp
3 // Purpose: Helper functions/classes for the wxPython extension module
4 //
5 // Author: Robin Dunn
6 //
7 // Created: 7/1/97
8 // RCS-ID: $Id$
9 // Copyright: (c) 1998 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13
14 #ifdef __WXGTK__
15 #include <gtk/gtk.h>
16 #endif
17
18 #undef DEBUG
19 #include <Python.h>
20 #include "helpers.h"
21 #ifdef __WXMSW__
22 #include <wx/msw/private.h>
23 #undef FindWindow
24 #undef GetCharWidth
25 #undef LoadAccelerators
26 #undef GetClassInfo
27 #undef GetClassName
28 #endif
29 #include <wx/module.h>
30
31
32 //---------------------------------------------------------------------------
33
34 //wxHashTable* wxPyWindows = NULL;
35
36
37 wxPoint wxPyDefaultPosition; //wxDefaultPosition);
38 wxSize wxPyDefaultSize; //wxDefaultSize);
39 wxString wxPyEmptyStr("");
40
41
42
43 #ifdef __WXMSW__ // If building for win32...
44 //----------------------------------------------------------------------
45 // This gets run when the DLL is loaded. We just need to save a handle.
46 //----------------------------------------------------------------------
47
48 BOOL WINAPI DllMain(
49 HINSTANCE hinstDLL, // handle to DLL module
50 DWORD fdwReason, // reason for calling function
51 LPVOID lpvReserved // reserved
52 )
53 {
54 wxSetInstance(hinstDLL);
55 return 1;
56 }
57 #endif
58
59 //----------------------------------------------------------------------
60 // Class for implementing the wxp main application shell.
61 //----------------------------------------------------------------------
62
63 wxPyApp *wxPythonApp = NULL; // Global instance of application object
64
65
66 wxPyApp::wxPyApp() {
67 // printf("**** ctor\n");
68 }
69
70 wxPyApp::~wxPyApp() {
71 // printf("**** dtor\n");
72 }
73
74
75 // This one isn't acutally called... See __wxStart()
76 bool wxPyApp::OnInit(void) {
77 return false;
78 }
79
80 int wxPyApp::MainLoop(void) {
81 int retval = wxApp::MainLoop();
82 //# AfterMainLoop();
83 wxPythonApp->OnExit(); //#
84 return retval;
85 }
86
87
88 //# void wxPyApp::AfterMainLoop(void) {
89 // // more stuff from wxEntry...
90
91 // if (wxPythonApp->GetTopWindow()) {
92 // // Forcibly delete the window.
93 // if (wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
94 // wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog))) {
95
96 // wxPythonApp->GetTopWindow()->Close(TRUE);
97 // wxPythonApp->DeletePendingObjects();
98 // }
99 // else {
100 // delete wxPythonApp->GetTopWindow();
101 // wxPythonApp->SetTopWindow(NULL);
102 // }
103 // }
104 // #ifdef __WXGTK__
105 // wxPythonApp->DeletePendingObjects();
106 // #endif
107
108 // wxPythonApp->OnExit();
109 // wxApp::CleanUp();
110 // // delete wxPythonApp;
111 // }
112
113
114 //---------------------------------------------------------------------
115 // a few native methods to add to the module
116 //----------------------------------------------------------------------
117
118
119 // This is where we pick up the first part of the wxEntry functionality...
120 // The rest is in __wxStart and AfterMainLoop. This function is called when
121 // wxcmodule is imported. (Before there is a wxApp object.)
122 void __wxPreStart()
123 {
124 // Bail out if there is already windows created. This means that the
125 // toolkit has already been initialized, as in embedding wxPython in
126 // a C++ wxWindows app.
127 if (wxTopLevelWindows.Number() > 0)
128 return;
129
130 #ifdef __WXMSW__
131 wxApp::Initialize();
132 #endif
133
134 #ifdef __WXGTK__
135 PyObject* sysargv = PySys_GetObject("argv");
136 int argc = PyList_Size(sysargv);
137 char** argv = new char*[argc+1];
138 int x;
139 for(x=0; x<argc; x++)
140 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
141 argv[argc] = NULL;
142
143 gtk_set_locale();
144 #if wxUSE_WCHAR_T
145 if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
146 #else
147 if (!wxOKlibc()) wxConvCurrent = (wxMBConv*) NULL;
148 #endif
149 gtk_init( &argc, &argv );
150 wxSetDetectableAutoRepeat( TRUE );
151 delete [] argv;
152
153 wxApp::Initialize(); // may return FALSE. Should we check?
154 #endif
155
156 }
157
158
159 #ifdef WXP_WITH_THREAD
160 PyThreadState* wxPyEventThreadState = NULL;
161 #endif
162 static char* __nullArgv[1] = { 0 };
163
164
165
166 // Start the user application, user App's OnInit method is a parameter here
167 PyObject* __wxStart(PyObject* /* self */, PyObject* args)
168 {
169 PyObject* onInitFunc = NULL;
170 PyObject* arglist;
171 PyObject* result;
172 long bResult;
173
174 #ifdef WXP_WITH_THREAD
175 wxPyEventThreadState = PyThreadState_Get();
176 #endif
177
178 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
179 return NULL;
180
181 if (wxTopLevelWindows.Number() > 0) {
182 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
183 return NULL;
184 }
185
186
187 // This is the next part of the wxEntry functionality...
188 wxPythonApp->argc = 0;
189 wxPythonApp->argv = NULL;
190 wxPythonApp->OnInitGui();
191
192
193 // Call the Python App's OnInit function
194 arglist = PyTuple_New(0);
195 result = PyEval_CallObject(onInitFunc, arglist);
196 if (!result) { // an exception was raised.
197 return NULL;
198 }
199
200 if (! PyInt_Check(result)) {
201 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
202 return NULL;
203 }
204 bResult = PyInt_AS_LONG(result);
205 if (! bResult) {
206 PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
207 return NULL;
208 }
209
210 #ifdef __WXGTK__
211 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
212 #endif
213
214 Py_INCREF(Py_None);
215 return Py_None;
216 }
217
218
219
220
221
222 PyObject* wxPython_dict;
223 PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
224 {
225
226 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
227 return NULL;
228
229 if (!PyDict_Check(wxPython_dict)) {
230 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
231 return NULL;
232 }
233 #ifdef __WXMOTIF__
234 #define wxPlatform "__WXMOTIF__"
235 #endif
236 #ifdef __WXQT__
237 #define wxPlatform "__WXQT__"
238 #endif
239 #ifdef __WXGTK__
240 #define wxPlatform "__WXGTK__"
241 #endif
242 #if defined(__WIN32__) || defined(__WXMSW__)
243 #define wxPlatform "__WXMSW__"
244 #endif
245 #ifdef __WXMAC__
246 #define wxPlatform "__WXMAC__"
247 #endif
248
249 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
250
251 Py_INCREF(Py_None);
252 return Py_None;
253 }
254
255
256 //---------------------------------------------------------------------------
257
258 PyObject* wxPyConstructObject(void* ptr, char* className) {
259 char buff[64]; // should always be big enough...
260 char swigptr[64];
261
262 sprintf(buff, "_%s_p", className);
263 SWIG_MakePtr(swigptr, ptr, buff);
264
265 sprintf(buff, "%sPtr", className);
266 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
267 if (! classobj) {
268 Py_INCREF(Py_None);
269 return Py_None;
270 }
271
272 PyObject* arg = Py_BuildValue("(s)", swigptr);
273 PyObject* obj = PyInstance_New(classobj, arg, NULL);
274 Py_DECREF(arg);
275
276 return obj;
277 }
278
279 //---------------------------------------------------------------------------
280
281 //static bool _wxPyInEvent = false;
282 static unsigned int _wxPyNestCount = 0;
283
284 HELPEREXPORT bool wxPyRestoreThread() {
285 // #ifdef WXP_WITH_THREAD
286 // //if (wxPyEventThreadState != PyThreadState_Get()) {
287 // if (! _wxPyInEvent) {
288 // PyEval_RestoreThread(wxPyEventThreadState);
289 // _wxPyInEvent = true;
290 // return TRUE;
291 // } else
292 // #endif
293 // return FALSE;
294
295 // NOTE: The Python API docs state that if a thread already has the
296 // interpreter lock and calls PyEval_RestoreThread again a deadlock
297 // occurs, so I put in the above code as a guard condition since there are
298 // many possibilites for nested events and callbacks in wxPython.
299 //
300 // Unfortunately, it seems like somebody was lying (or I'm not
301 // understanding...) because each of the nested calls to this function
302 // MUST call PyEval_RestoreThread or Python pukes with a thread error (at
303 // least on Win32.)
304 //
305 // until I know better, this is how I am doing it instead:
306 #ifdef WXP_WITH_THREAD
307 PyEval_RestoreThread(wxPyEventThreadState);
308 _wxPyNestCount += 1;
309 if (_wxPyNestCount == 1)
310 return TRUE;
311 else
312 #endif
313 return FALSE;
314 }
315
316
317 HELPEREXPORT void wxPySaveThread(bool doSave) {
318 #ifdef WXP_WITH_THREAD
319 if (doSave) {
320 PyEval_SaveThread();
321 //_wxPyInEvent = false;
322 }
323 _wxPyNestCount -= 1;
324 #endif
325 }
326
327 //---------------------------------------------------------------------------
328
329
330 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
331
332 wxPyCallback::wxPyCallback(PyObject* func) {
333 m_func = func;
334 Py_INCREF(m_func);
335 }
336
337 wxPyCallback::wxPyCallback(const wxPyCallback& other) {
338 m_func = other.m_func;
339 Py_INCREF(m_func);
340 }
341
342 wxPyCallback::~wxPyCallback() {
343 bool doSave = wxPyRestoreThread();
344 Py_DECREF(m_func);
345 wxPySaveThread(doSave);
346 }
347
348
349
350
351 // This function is used for all events destined for Python event handlers.
352 void wxPyCallback::EventThunker(wxEvent& event) {
353 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
354 PyObject* func = cb->m_func;
355 PyObject* result;
356 PyObject* arg;
357 PyObject* tuple;
358
359
360 bool doSave = wxPyRestoreThread();
361 arg = wxPyConstructObject((void*)&event, event.GetClassInfo()->GetClassName());
362
363 tuple = PyTuple_New(1);
364 PyTuple_SET_ITEM(tuple, 0, arg);
365 result = PyEval_CallObject(func, tuple);
366 Py_DECREF(tuple);
367 if (result) {
368 Py_DECREF(result);
369 PyErr_Clear();
370 } else {
371 PyErr_Print();
372 }
373 wxPySaveThread(doSave);
374 }
375
376
377 //----------------------------------------------------------------------
378
379 wxPyCallbackHelper::wxPyCallbackHelper() {
380 m_self = NULL;
381 m_lastFound = NULL;
382 }
383
384
385 wxPyCallbackHelper::~wxPyCallbackHelper() {
386 bool doSave = wxPyRestoreThread();
387 Py_XDECREF(m_self);
388 wxPySaveThread(doSave);
389 }
390
391 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
392 m_lastFound = NULL;
393 m_self = other.m_self;
394 if (m_self)
395 Py_INCREF(m_self);
396 }
397
398
399 void wxPyCallbackHelper::setSelf(PyObject* self, int incref) {
400 m_self = self;
401 if (incref)
402 Py_INCREF(m_self);
403 }
404
405
406 bool wxPyCallbackHelper::findCallback(const wxString& name) {
407 m_lastFound = NULL;
408 if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
409 m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
410
411 return m_lastFound != NULL;
412 }
413
414
415 int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
416 PyObject* result;
417 int retval = FALSE;
418
419 result = callCallbackObj(argTuple);
420 if (result) { // Assumes an integer return type...
421 retval = PyInt_AsLong(result);
422 Py_DECREF(result);
423 PyErr_Clear(); // forget about it if it's not...
424 }
425 return retval;
426 }
427
428 // Invoke the Python callable object, returning the raw PyObject return
429 // value. Caller should DECREF the return value and also call PyEval_SaveThread.
430 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
431 PyObject* result;
432
433 result = PyEval_CallObject(m_lastFound, argTuple);
434 Py_DECREF(argTuple);
435 if (!result) {
436 PyErr_Print();
437 }
438 return result;
439 }
440
441
442
443 //---------------------------------------------------------------------------
444 //---------------------------------------------------------------------------
445
446
447 wxPyTimer::wxPyTimer(PyObject* callback) {
448 func = callback;
449 Py_INCREF(func);
450 }
451
452 wxPyTimer::~wxPyTimer() {
453 bool doSave = wxPyRestoreThread();
454 Py_DECREF(func);
455 wxPySaveThread(doSave);
456 }
457
458 void wxPyTimer::Notify() {
459 bool doSave = wxPyRestoreThread();
460
461 PyObject* result;
462 PyObject* args = Py_BuildValue("()");
463
464 result = PyEval_CallObject(func, args);
465 Py_DECREF(args);
466 if (result) {
467 Py_DECREF(result);
468 PyErr_Clear();
469 } else {
470 PyErr_Print();
471 }
472 wxPySaveThread(doSave);
473 }
474
475
476
477 //---------------------------------------------------------------------------
478 //---------------------------------------------------------------------------
479 // Convert a wxList to a Python List
480
481 PyObject* wxPy_ConvertList(wxListBase* list, char* className) {
482 PyObject* pyList;
483 PyObject* pyObj;
484 wxObject* wxObj;
485 wxNode* node = list->First();
486
487 bool doSave = wxPyRestoreThread();
488 pyList = PyList_New(0);
489 while (node) {
490 wxObj = node->Data();
491 pyObj = wxPyConstructObject(wxObj, className);
492 PyList_Append(pyList, pyObj);
493 node = node->Next();
494 }
495 wxPySaveThread(doSave);
496 return pyList;
497 }
498
499 //----------------------------------------------------------------------
500 // Some helper functions for typemaps in my_typemaps.i, so they won't be
501 // included in every file...
502
503
504 byte* byte_LIST_helper(PyObject* source) {
505 if (!PyList_Check(source)) {
506 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
507 return NULL;
508 }
509 int count = PyList_Size(source);
510 byte* temp = new byte[count];
511 if (! temp) {
512 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
513 return NULL;
514 }
515 for (int x=0; x<count; x++) {
516 PyObject* o = PyList_GetItem(source, x);
517 if (! PyInt_Check(o)) {
518 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
519 return NULL;
520 }
521 temp[x] = (byte)PyInt_AsLong(o);
522 }
523 return temp;
524 }
525
526
527 int* int_LIST_helper(PyObject* source) {
528 if (!PyList_Check(source)) {
529 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
530 return NULL;
531 }
532 int count = PyList_Size(source);
533 int* temp = new int[count];
534 if (! temp) {
535 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
536 return NULL;
537 }
538 for (int x=0; x<count; x++) {
539 PyObject* o = PyList_GetItem(source, x);
540 if (! PyInt_Check(o)) {
541 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
542 return NULL;
543 }
544 temp[x] = PyInt_AsLong(o);
545 }
546 return temp;
547 }
548
549
550 long* long_LIST_helper(PyObject* source) {
551 if (!PyList_Check(source)) {
552 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
553 return NULL;
554 }
555 int count = PyList_Size(source);
556 long* temp = new long[count];
557 if (! temp) {
558 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
559 return NULL;
560 }
561 for (int x=0; x<count; x++) {
562 PyObject* o = PyList_GetItem(source, x);
563 if (! PyInt_Check(o)) {
564 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
565 return NULL;
566 }
567 temp[x] = PyInt_AsLong(o);
568 }
569 return temp;
570 }
571
572
573 char** string_LIST_helper(PyObject* source) {
574 if (!PyList_Check(source)) {
575 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
576 return NULL;
577 }
578 int count = PyList_Size(source);
579 char** temp = new char*[count];
580 if (! temp) {
581 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
582 return NULL;
583 }
584 for (int x=0; x<count; x++) {
585 PyObject* o = PyList_GetItem(source, x);
586 if (! PyString_Check(o)) {
587 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
588 return NULL;
589 }
590 temp[x] = PyString_AsString(o);
591 }
592 return temp;
593 }
594
595
596
597 wxPoint* wxPoint_LIST_helper(PyObject* source) {
598 if (!PyList_Check(source)) {
599 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
600 return NULL;
601 }
602 int count = PyList_Size(source);
603 wxPoint* temp = new wxPoint[count];
604 if (! temp) {
605 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
606 return NULL;
607 }
608 for (int x=0; x<count; x++) {
609 PyObject* o = PyList_GetItem(source, x);
610 if (PyTuple_Check(o)) {
611 PyObject* o1 = PyTuple_GetItem(o, 0);
612 PyObject* o2 = PyTuple_GetItem(o, 1);
613
614 temp[x].x = PyInt_AsLong(o1);
615 temp[x].y = PyInt_AsLong(o2);
616 }
617 else if (PyInstance_Check(o)) {
618 wxPoint* pt;
619 if (SWIG_GetPtrObj(o,(void **) &pt,"_wxPoint_p")) {
620 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
621 return NULL;
622 }
623 temp[x] = *pt;
624 }
625 else {
626 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
627 return NULL;
628 }
629 }
630 return temp;
631 }
632
633
634 wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
635 if (!PyList_Check(source)) {
636 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
637 return NULL;
638 }
639 int count = PyList_Size(source);
640 wxBitmap** temp = new wxBitmap*[count];
641 if (! temp) {
642 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
643 return NULL;
644 }
645 for (int x=0; x<count; x++) {
646 PyObject* o = PyList_GetItem(source, x);
647 if (PyInstance_Check(o)) {
648 wxBitmap* pt;
649 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
650 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
651 return NULL;
652 }
653 temp[x] = pt;
654 }
655 else {
656 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
657 return NULL;
658 }
659 }
660 return temp;
661 }
662
663
664
665 wxString* wxString_LIST_helper(PyObject* source) {
666 if (!PyList_Check(source)) {
667 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
668 return NULL;
669 }
670 int count = PyList_Size(source);
671 wxString* temp = new wxString[count];
672 if (! temp) {
673 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
674 return NULL;
675 }
676 for (int x=0; x<count; x++) {
677 PyObject* o = PyList_GetItem(source, x);
678 if (! PyString_Check(o)) {
679 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
680 return NULL;
681 }
682 temp[x] = PyString_AsString(o);
683 }
684 return temp;
685 }
686
687
688 wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
689 if (!PyList_Check(source)) {
690 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
691 return NULL;
692 }
693 int count = PyList_Size(source);
694 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
695 if (! temp) {
696 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
697 return NULL;
698 }
699 for (int x=0; x<count; x++) {
700 PyObject* o = PyList_GetItem(source, x);
701 if (PyInstance_Check(o)) {
702 wxAcceleratorEntry* ae;
703 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
704 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
705 return NULL;
706 }
707 temp[x] = *ae;
708 }
709 else if (PyTuple_Check(o)) {
710 PyObject* o1 = PyTuple_GetItem(o, 0);
711 PyObject* o2 = PyTuple_GetItem(o, 1);
712 PyObject* o3 = PyTuple_GetItem(o, 2);
713
714 temp[x].m_flags = PyInt_AsLong(o1);
715 temp[x].m_keyCode = PyInt_AsLong(o2);
716 temp[x].m_command = PyInt_AsLong(o3);
717 }
718 else {
719 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
720 return NULL;
721 }
722 }
723 return temp;
724 }
725
726
727
728 //----------------------------------------------------------------------
729
730 bool wxSize_helper(PyObject* source, wxSize** obj) {
731
732 // If source is an object instance then it may already be the right type
733 if (PyInstance_Check(source)) {
734 wxSize* ptr;
735 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
736 goto error;
737 *obj = ptr;
738 return TRUE;
739 }
740 // otherwise a 2-tuple of integers is expected
741 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
742 PyObject* o1 = PySequence_GetItem(source, 0);
743 PyObject* o2 = PySequence_GetItem(source, 1);
744 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
745 return TRUE;
746 }
747
748 error:
749 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
750 return FALSE;
751 }
752
753 bool wxPoint_helper(PyObject* source, wxPoint** obj) {
754
755 // If source is an object instance then it may already be the right type
756 if (PyInstance_Check(source)) {
757 wxPoint* ptr;
758 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
759 goto error;
760 *obj = ptr;
761 return TRUE;
762 }
763 // otherwise a 2-tuple of integers is expected
764 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
765 PyObject* o1 = PySequence_GetItem(source, 0);
766 PyObject* o2 = PySequence_GetItem(source, 1);
767 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
768 return TRUE;
769 }
770
771 error:
772 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
773 return FALSE;
774 }
775
776
777
778 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
779
780 // If source is an object instance then it may already be the right type
781 if (PyInstance_Check(source)) {
782 wxRealPoint* ptr;
783 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
784 goto error;
785 *obj = ptr;
786 return TRUE;
787 }
788 // otherwise a 2-tuple of floats is expected
789 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
790 PyObject* o1 = PySequence_GetItem(source, 0);
791 PyObject* o2 = PySequence_GetItem(source, 1);
792 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
793 return TRUE;
794 }
795
796 error:
797 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
798 return FALSE;
799 }
800
801
802
803
804 bool wxRect_helper(PyObject* source, wxRect** obj) {
805
806 // If source is an object instance then it may already be the right type
807 if (PyInstance_Check(source)) {
808 wxRect* ptr;
809 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
810 goto error;
811 *obj = ptr;
812 return TRUE;
813 }
814 // otherwise a 4-tuple of integers is expected
815 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
816 PyObject* o1 = PySequence_GetItem(source, 0);
817 PyObject* o2 = PySequence_GetItem(source, 1);
818 PyObject* o3 = PySequence_GetItem(source, 2);
819 PyObject* o4 = PySequence_GetItem(source, 3);
820 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
821 PyInt_AsLong(o3), PyInt_AsLong(o4));
822 return TRUE;
823 }
824
825 error:
826 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
827 return FALSE;
828 }
829
830
831
832 //----------------------------------------------------------------------
833 //----------------------------------------------------------------------
834 //----------------------------------------------------------------------
835
836
837