]> git.saurik.com Git - wxWidgets.git/blame_incremental - wxPython/src/helpers.cpp
Added support more support for DB2
[wxWidgets.git] / wxPython / src / helpers.cpp
... / ...
CommitLineData
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#include <stdio.h> // get the correct definition of NULL
14
15#undef DEBUG
16#include <Python.h>
17#include "helpers.h"
18
19#ifdef __WXMSW__
20#include <wx/msw/private.h>
21#undef FindWindow
22#undef GetCharWidth
23#undef LoadAccelerators
24#undef GetClassInfo
25#undef GetClassName
26#endif
27
28#ifdef __WXGTK__
29#include <gtk/gtk.h>
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>
35
36//extern GtkWidget *wxRootWindow;
37
38#endif
39
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
48BOOL 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
63wxPyApp *wxPythonApp = NULL; // Global instance of application object
64
65
66wxPyApp::wxPyApp() {
67// printf("**** ctor\n");
68}
69
70wxPyApp::~wxPyApp() {
71// printf("**** dtor\n");
72}
73
74
75// This one isn't acutally called... See __wxStart()
76bool wxPyApp::OnInit(void) {
77 return FALSE;
78}
79
80int wxPyApp::MainLoop(void) {
81 int retval = 0;
82
83 DeletePendingObjects();
84#ifdef __WXGTK__
85 m_initialized = wxTopLevelWindows.GetCount() != 0;
86#endif
87
88 if (Initialized()) {
89 retval = wxApp::MainLoop();
90 wxPythonApp->OnExit();
91 }
92 return retval;
93}
94
95
96//---------------------------------------------------------------------
97//----------------------------------------------------------------------
98
99#ifdef __WXMSW__
100#include "wx/msw/msvcrt.h"
101#endif
102
103
104int WXDLLEXPORT wxEntryStart( int argc, char** argv );
105int WXDLLEXPORT wxEntryInitGui();
106void WXDLLEXPORT wxEntryCleanup();
107
108
109#ifdef WXP_WITH_THREAD
110PyThreadState* wxPyEventThreadState = NULL;
111#endif
112
113
114// This is where we pick up the first part of the wxEntry functionality...
115// The rest is in __wxStart and __wxCleanup. This function is called when
116// wxcmodule is imported. (Before there is a wxApp object.)
117void __wxPreStart()
118{
119
120#ifdef __WXMSW__
121// wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
122#endif
123
124#ifdef WXP_WITH_THREAD
125#if 0 // OLD THREAD STUFF
126 PyEval_InitThreads();
127 wxPyEventThreadState = PyThreadState_Get();
128#else
129 PyEval_InitThreads();
130 wxPyEventThreadState = PyThreadState_New(PyThreadState_Get()->interp);
131#endif
132#endif
133
134 // Bail out if there is already windows created. This means that the
135 // toolkit has already been initialized, as in embedding wxPython in
136 // a C++ wxWindows app.
137 if (wxTopLevelWindows.Number() > 0)
138 return;
139
140
141 PyObject* sysargv = PySys_GetObject("argv");
142 int argc = PyList_Size(sysargv);
143 char** argv = new char*[argc+1];
144 int x;
145 for(x=0; x<argc; x++)
146 argv[x] = PyString_AsString(PyList_GetItem(sysargv, x));
147 argv[argc] = NULL;
148
149 wxEntryStart(argc, argv);
150 delete [] argv;
151}
152
153
154
155// Start the user application, user App's OnInit method is a parameter here
156PyObject* __wxStart(PyObject* /* self */, PyObject* args)
157{
158 PyObject* onInitFunc = NULL;
159 PyObject* arglist;
160 PyObject* result;
161 long bResult;
162
163 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
164 return NULL;
165
166#if 0 // Try it out without this check, see how it does...
167 if (wxTopLevelWindows.Number() > 0) {
168 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
169 return NULL;
170 }
171#endif
172
173 // This is the next part of the wxEntry functionality...
174 PyObject* sysargv = PySys_GetObject("argv");
175 int argc = PyList_Size(sysargv);
176 char** argv = new char*[argc+1];
177 int x;
178 for(x=0; x<argc; x++)
179 argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
180 argv[argc] = NULL;
181
182 wxPythonApp->argc = argc;
183 wxPythonApp->argv = argv;
184
185 wxEntryInitGui();
186
187 // Call the Python App's OnInit function
188 arglist = PyTuple_New(0);
189 result = PyEval_CallObject(onInitFunc, arglist);
190 if (!result) { // an exception was raised.
191 return NULL;
192 }
193
194 if (! PyInt_Check(result)) {
195 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
196 return NULL;
197 }
198 bResult = PyInt_AS_LONG(result);
199 if (! bResult) {
200 PyErr_SetString(PyExc_SystemExit, "OnInit returned FALSE, exiting...");
201 return NULL;
202 }
203
204#ifdef __WXGTK__
205 wxTheApp->m_initialized = (wxTopLevelWindows.GetCount() > 0);
206#endif
207
208 Py_INCREF(Py_None);
209 return Py_None;
210}
211
212void __wxCleanup() {
213 wxEntryCleanup();
214}
215
216
217
218PyObject* wxPython_dict;
219PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
220{
221
222 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
223 return NULL;
224
225 if (!PyDict_Check(wxPython_dict)) {
226 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
227 return NULL;
228 }
229#ifdef __WXMOTIF__
230#define wxPlatform "__WXMOTIF__"
231#endif
232#ifdef __WXQT__
233#define wxPlatform "__WXQT__"
234#endif
235#ifdef __WXGTK__
236#define wxPlatform "__WXGTK__"
237#endif
238#if defined(__WIN32__) || defined(__WXMSW__)
239#define wxPlatform "__WXMSW__"
240#endif
241#ifdef __WXMAC__
242#define wxPlatform "__WXMAC__"
243#endif
244
245 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
246
247 Py_INCREF(Py_None);
248 return Py_None;
249}
250
251
252//---------------------------------------------------------------------------
253
254PyObject* wxPyConstructObject(void* ptr,
255 const char* className,
256 int setThisOwn) {
257 PyObject* obj;
258 PyObject* arg;
259
260 if (!ptr) {
261 Py_INCREF(Py_None);
262 return Py_None;
263 }
264
265 char buff[64]; // should always be big enough...
266 char swigptr[64];
267
268 sprintf(buff, "_%s_p", className);
269 SWIG_MakePtr(swigptr, ptr, buff);
270
271 sprintf(buff, "%sPtr", className);
272 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
273 if (! classobj) {
274 //Py_INCREF(Py_None);
275 //return Py_None;
276 char temp[128];
277 sprintf(temp,
278 "*** Unknown class name %s, tell Robin about it please ***",
279 buff);
280 obj = PyString_FromString(temp);
281 return obj;
282 }
283
284 arg = Py_BuildValue("(s)", swigptr);
285 obj = PyInstance_New(classobj, arg, NULL);
286 Py_DECREF(arg);
287
288 if (setThisOwn) {
289 PyObject* one = PyInt_FromLong(1);
290 PyObject_SetAttrString(obj, "thisown", one);
291 Py_DECREF(one);
292 }
293
294 return obj;
295}
296
297//---------------------------------------------------------------------------
298
299static PyThreadState* myPyThreadState_Get() {
300 PyThreadState* current;
301 current = PyThreadState_Swap(NULL);
302 PyThreadState_Swap(current);
303 return current;
304}
305
306
307bool wxPyRestoreThread() {
308 // NOTE: The Python API docs state that if a thread already has the
309 // interpreter lock and calls PyEval_RestoreThread again a deadlock
310 // occurs, so I put in this code as a guard condition since there are
311 // many possibilites for nested events and callbacks in wxPython. If
312 // The current thread is our thread, then we can assume that we
313 // already have the lock. (I hope!)
314 //
315#ifdef WXP_WITH_THREAD
316#if 0 // OLD THREAD STUFF
317 if (wxPyEventThreadState != myPyThreadState_Get()) {
318 PyEval_RestoreThread(wxPyEventThreadState);
319 return TRUE;
320 }
321 else
322#else
323 if (wxPyEventThreadState != myPyThreadState_Get()) {
324 PyEval_AcquireThread(wxPyEventThreadState);
325 return TRUE;
326 }
327 else
328#endif
329#endif
330 return FALSE;
331}
332
333
334void wxPySaveThread(bool doSave) {
335#ifdef WXP_WITH_THREAD
336#if 0 // OLD THREAD STUFF
337 if (doSave) {
338 wxPyEventThreadState = PyEval_SaveThread();
339 }
340#else
341 if (doSave) {
342 PyEval_ReleaseThread(wxPyEventThreadState);
343 }
344#endif
345#endif
346}
347
348//---------------------------------------------------------------------------
349
350
351IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
352
353wxPyCallback::wxPyCallback(PyObject* func) {
354 m_func = func;
355 Py_INCREF(m_func);
356}
357
358wxPyCallback::wxPyCallback(const wxPyCallback& other) {
359 m_func = other.m_func;
360 Py_INCREF(m_func);
361}
362
363wxPyCallback::~wxPyCallback() {
364 bool doSave = wxPyRestoreThread();
365 Py_DECREF(m_func);
366 wxPySaveThread(doSave);
367}
368
369
370
371// This function is used for all events destined for Python event handlers.
372void wxPyCallback::EventThunker(wxEvent& event) {
373 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
374 PyObject* func = cb->m_func;
375 PyObject* result;
376 PyObject* arg;
377 PyObject* tuple;
378
379
380 bool doSave = wxPyRestoreThread();
381 wxString className = event.GetClassInfo()->GetClassName();
382
383 if (className == "wxPyEvent")
384 arg = ((wxPyEvent*)&event)->GetSelf();
385 else if (className == "wxPyCommandEvent")
386 arg = ((wxPyCommandEvent*)&event)->GetSelf();
387 else
388 arg = wxPyConstructObject((void*)&event, className);
389
390 tuple = PyTuple_New(1);
391 PyTuple_SET_ITEM(tuple, 0, arg);
392 result = PyEval_CallObject(func, tuple);
393 Py_DECREF(tuple);
394 if (result) {
395 Py_DECREF(result);
396 PyErr_Clear();
397 } else {
398 PyErr_Print();
399 }
400 wxPySaveThread(doSave);
401}
402
403
404//----------------------------------------------------------------------
405
406wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
407 m_lastFound = NULL;
408 m_self = other.m_self;
409 m_class = other.m_class;
410 if (m_self) {
411 Py_INCREF(m_self);
412 Py_INCREF(m_class);
413 }
414}
415
416
417void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
418 m_self = self;
419 m_class = klass;
420 m_incRef = incref;
421 if (incref) {
422 Py_INCREF(m_self);
423 Py_INCREF(m_class);
424 }
425}
426
427
428// If the object (m_self) has an attibute of the given name, and if that
429// attribute is a method, and if that method's class is not from a base class,
430// then we'll save a pointer to the method so callCallback can call it.
431bool wxPyCallbackHelper::findCallback(const char* name) const {
432 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
433 self->m_lastFound = NULL;
434 if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
435 PyObject* method;
436 method = PyObject_GetAttrString(m_self, (char*)name);
437
438 if (PyMethod_Check(method) &&
439 ((PyMethod_GET_CLASS(method) == m_class) ||
440 PyClass_IsSubclass(PyMethod_GET_CLASS(method), m_class))) {
441
442 self->m_lastFound = method;
443 }
444 else {
445 Py_DECREF(method);
446 }
447 }
448 return m_lastFound != NULL;
449}
450
451
452int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
453 PyObject* result;
454 int retval = FALSE;
455
456 result = callCallbackObj(argTuple);
457 if (result) { // Assumes an integer return type...
458 retval = PyInt_AsLong(result);
459 Py_DECREF(result);
460 PyErr_Clear(); // forget about it if it's not...
461 }
462 return retval;
463}
464
465// Invoke the Python callable object, returning the raw PyObject return
466// value. Caller should DECREF the return value and also call PyEval_SaveThread.
467PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
468 PyObject* result;
469
470 // Save a copy of the pointer in case the callback generates another
471 // callback. In that case m_lastFound will have a different value when
472 // it gets back here...
473 PyObject* method = m_lastFound;
474
475 result = PyEval_CallObject(method, argTuple);
476 Py_DECREF(argTuple);
477 Py_DECREF(method);
478 if (!result) {
479 PyErr_Print();
480 }
481 return result;
482}
483
484
485void wxPyCBH_setSelf(wxPyCallbackHelper& cbh, PyObject* self, PyObject* klass, int incref) {
486 cbh.setSelf(self, klass, incref);
487}
488
489bool wxPyCBH_findCallback(const wxPyCallbackHelper& cbh, const char* name) {
490 return cbh.findCallback(name);
491}
492
493int wxPyCBH_callCallback(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
494 return cbh.callCallback(argTuple);
495}
496
497PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
498 return cbh.callCallbackObj(argTuple);
499}
500
501
502void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
503 bool doSave = wxPyRestoreThread();
504 if (cbh->m_incRef) {
505 Py_XDECREF(cbh->m_self);
506 Py_XDECREF(cbh->m_class);
507 }
508 wxPySaveThread(doSave);
509}
510
511//---------------------------------------------------------------------------
512//---------------------------------------------------------------------------
513// These classes can be derived from in Python and passed through the event
514// system without losing anything. They do this by keeping a reference to
515// themselves and some special case handling in wxPyCallback::EventThunker.
516
517
518wxPyEvtSelfRef::wxPyEvtSelfRef() {
519 //m_self = Py_None; // **** We don't do normal ref counting to prevent
520 //Py_INCREF(m_self); // circular loops...
521 m_cloned = FALSE;
522}
523
524wxPyEvtSelfRef::~wxPyEvtSelfRef() {
525 bool doSave = wxPyRestoreThread();
526 if (m_cloned)
527 Py_DECREF(m_self);
528 wxPySaveThread(doSave);
529}
530
531void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
532 bool doSave = wxPyRestoreThread();
533 if (m_cloned)
534 Py_DECREF(m_self);
535 m_self = self;
536 if (clone) {
537 Py_INCREF(m_self);
538 m_cloned = TRUE;
539 }
540 wxPySaveThread(doSave);
541}
542
543PyObject* wxPyEvtSelfRef::GetSelf() const {
544 Py_INCREF(m_self);
545 return m_self;
546}
547
548
549wxPyEvent::wxPyEvent(int id)
550 : wxEvent(id) {
551}
552
553wxPyEvent::~wxPyEvent() {
554}
555
556// This one is so the event object can be Cloned...
557void wxPyEvent::CopyObject(wxObject& dest) const {
558 wxEvent::CopyObject(dest);
559 ((wxPyEvent*)&dest)->SetSelf(m_self, TRUE);
560}
561
562
563IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxEvent);
564
565
566wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
567 : wxCommandEvent(commandType, id) {
568}
569
570wxPyCommandEvent::~wxPyCommandEvent() {
571}
572
573void wxPyCommandEvent::CopyObject(wxObject& dest) const {
574 wxCommandEvent::CopyObject(dest);
575 ((wxPyCommandEvent*)&dest)->SetSelf(m_self, TRUE);
576}
577
578
579IMPLEMENT_DYNAMIC_CLASS(wxPyCommandEvent, wxCommandEvent);
580
581
582
583//---------------------------------------------------------------------------
584//---------------------------------------------------------------------------
585
586
587wxPyTimer::wxPyTimer(PyObject* callback) {
588 func = callback;
589 Py_INCREF(func);
590}
591
592wxPyTimer::~wxPyTimer() {
593 bool doSave = wxPyRestoreThread();
594 Py_DECREF(func);
595 wxPySaveThread(doSave);
596}
597
598void wxPyTimer::Notify() {
599 if (!func || func == Py_None) {
600 wxTimer::Notify();
601 }
602 else {
603 bool doSave = wxPyRestoreThread();
604
605 PyObject* result;
606 PyObject* args = Py_BuildValue("()");
607
608 result = PyEval_CallObject(func, args);
609 Py_DECREF(args);
610 if (result) {
611 Py_DECREF(result);
612 PyErr_Clear();
613 } else {
614 PyErr_Print();
615 }
616
617 wxPySaveThread(doSave);
618 }
619}
620
621
622
623//---------------------------------------------------------------------------
624//---------------------------------------------------------------------------
625// Convert a wxList to a Python List
626
627PyObject* wxPy_ConvertList(wxListBase* list, const char* className) {
628 PyObject* pyList;
629 PyObject* pyObj;
630 wxObject* wxObj;
631 wxNode* node = list->First();
632
633 bool doSave = wxPyRestoreThread();
634 pyList = PyList_New(0);
635 while (node) {
636 wxObj = node->Data();
637 pyObj = wxPyConstructObject(wxObj, className);
638 PyList_Append(pyList, pyObj);
639 node = node->Next();
640 }
641 wxPySaveThread(doSave);
642 return pyList;
643}
644
645//----------------------------------------------------------------------
646
647long wxPyGetWinHandle(wxWindow* win) {
648#ifdef __WXMSW__
649 return (long)win->GetHandle();
650#endif
651
652 // Find and return the actual X-Window.
653#ifdef __WXGTK__
654 if (win->m_wxwindow) {
655 GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window;
656 if (bwin) {
657 return (long)bwin->xwindow;
658 }
659 }
660#endif
661 return 0;
662}
663
664//----------------------------------------------------------------------
665// Some helper functions for typemaps in my_typemaps.i, so they won't be
666// included in every file...
667
668
669byte* byte_LIST_helper(PyObject* source) {
670 if (!PyList_Check(source)) {
671 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
672 return NULL;
673 }
674 int count = PyList_Size(source);
675 byte* temp = new byte[count];
676 if (! temp) {
677 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
678 return NULL;
679 }
680 for (int x=0; x<count; x++) {
681 PyObject* o = PyList_GetItem(source, x);
682 if (! PyInt_Check(o)) {
683 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
684 return NULL;
685 }
686 temp[x] = (byte)PyInt_AsLong(o);
687 }
688 return temp;
689}
690
691
692int* int_LIST_helper(PyObject* source) {
693 if (!PyList_Check(source)) {
694 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
695 return NULL;
696 }
697 int count = PyList_Size(source);
698 int* temp = new int[count];
699 if (! temp) {
700 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
701 return NULL;
702 }
703 for (int x=0; x<count; x++) {
704 PyObject* o = PyList_GetItem(source, x);
705 if (! PyInt_Check(o)) {
706 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
707 return NULL;
708 }
709 temp[x] = PyInt_AsLong(o);
710 }
711 return temp;
712}
713
714
715long* long_LIST_helper(PyObject* source) {
716 if (!PyList_Check(source)) {
717 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
718 return NULL;
719 }
720 int count = PyList_Size(source);
721 long* temp = new long[count];
722 if (! temp) {
723 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
724 return NULL;
725 }
726 for (int x=0; x<count; x++) {
727 PyObject* o = PyList_GetItem(source, x);
728 if (! PyInt_Check(o)) {
729 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
730 return NULL;
731 }
732 temp[x] = PyInt_AsLong(o);
733 }
734 return temp;
735}
736
737
738char** string_LIST_helper(PyObject* source) {
739 if (!PyList_Check(source)) {
740 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
741 return NULL;
742 }
743 int count = PyList_Size(source);
744 char** temp = new char*[count];
745 if (! temp) {
746 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
747 return NULL;
748 }
749 for (int x=0; x<count; x++) {
750 PyObject* o = PyList_GetItem(source, x);
751 if (! PyString_Check(o)) {
752 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
753 return NULL;
754 }
755 temp[x] = PyString_AsString(o);
756 }
757 return temp;
758}
759
760//--------------------------------
761// Part of patch from Tim Hochberg
762static inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point) {
763 if (PyInt_Check(o1) && PyInt_Check(o2)) {
764 point->x = PyInt_AS_LONG(o1);
765 point->y = PyInt_AS_LONG(o2);
766 return true;
767 }
768 if (PyFloat_Check(o1) && PyFloat_Check(o2)) {
769 point->x = (int)PyFloat_AS_DOUBLE(o1);
770 point->y = (int)PyFloat_AS_DOUBLE(o2);
771 return true;
772 }
773 if (PyInstance_Check(o1) || PyInstance_Check(o2)) {
774 // Disallow instances because they can cause havok
775 return false;
776 }
777 if (PyNumber_Check(o1) && PyNumber_Check(o2)) {
778 // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2
779 point->x = PyInt_AsLong(o1);
780 point->y = PyInt_AsLong(o2);
781 return true;
782 }
783 return false;
784}
785
786
787#if PYTHON_API_VERSION < 1009
788#define PySequence_Fast_GET_ITEM(o, i)\
789 (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))
790#endif
791
792wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) {
793 // Putting all of the declarations here allows
794 // us to put the error handling all in one place.
795 int x;
796 wxPoint* temp;
797 PyObject *o, *o1, *o2;
798 int isFast = PyList_Check(source) || PyTuple_Check(source);
799
800 // The length of the sequence is returned in count.
801 if (!PySequence_Check(source)) {
802 goto error0;
803 }
804 *count = PySequence_Length(source);
805 if (*count < 0) {
806 goto error0;
807 }
808
809 temp = new wxPoint[*count];
810 if (!temp) {
811 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
812 return NULL;
813 }
814 for (x=0; x<*count; x++) {
815 // Get an item: try fast way first.
816 if (isFast) {
817 o = PySequence_Fast_GET_ITEM(source, x);
818 }
819 else {
820 o = PySequence_GetItem(source, x);
821 if (o == NULL) {
822 goto error1;
823 }
824 }
825
826 // Convert o to wxPoint.
827 if ((PyTuple_Check(o) && PyTuple_GET_SIZE(o) == 2) ||
828 (PyList_Check(o) && PyList_GET_SIZE(o) == 2)) {
829 o1 = PySequence_Fast_GET_ITEM(o, 0);
830 o2 = PySequence_Fast_GET_ITEM(o, 1);
831 if (!wxPointFromObjects(o1, o2, &temp[x])) {
832 goto error2;
833 }
834 }
835 else if (PyInstance_Check(o)) {
836 wxPoint* pt;
837 if (SWIG_GetPtrObj(o, (void **)&pt, "_wxPoint_p")) {
838 goto error2;
839 }
840 temp[x] = *pt;
841 }
842 else if (PySequence_Check(o) && PySequence_Length(o) == 2) {
843 o1 = PySequence_GetItem(o, 0);
844 o2 = PySequence_GetItem(o, 1);
845 if (!wxPointFromObjects(o1, o2, &temp[x])) {
846 goto error3;
847 }
848 Py_DECREF(o1);
849 Py_DECREF(o2);
850 }
851 else {
852 goto error2;
853 }
854 // Clean up.
855 if (!isFast)
856 Py_DECREF(o);
857 }
858 return temp;
859
860error3:
861 Py_DECREF(o1);
862 Py_DECREF(o2);
863error2:
864 if (!isFast)
865 Py_DECREF(o);
866error1:
867 delete temp;
868error0:
869 PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoints.");
870 return NULL;
871}
872// end of patch
873//------------------------------
874
875
876wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
877 if (!PyList_Check(source)) {
878 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
879 return NULL;
880 }
881 int count = PyList_Size(source);
882 wxBitmap** temp = new wxBitmap*[count];
883 if (! temp) {
884 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
885 return NULL;
886 }
887 for (int x=0; x<count; x++) {
888 PyObject* o = PyList_GetItem(source, x);
889 if (PyInstance_Check(o)) {
890 wxBitmap* pt;
891 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
892 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
893 return NULL;
894 }
895 temp[x] = pt;
896 }
897 else {
898 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
899 return NULL;
900 }
901 }
902 return temp;
903}
904
905
906
907wxString* wxString_LIST_helper(PyObject* source) {
908 if (!PyList_Check(source)) {
909 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
910 return NULL;
911 }
912 int count = PyList_Size(source);
913 wxString* temp = new wxString[count];
914 if (! temp) {
915 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
916 return NULL;
917 }
918 for (int x=0; x<count; x++) {
919 PyObject* o = PyList_GetItem(source, x);
920 if (! PyString_Check(o)) {
921 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
922 return NULL;
923 }
924 temp[x] = PyString_AsString(o);
925 }
926 return temp;
927}
928
929
930wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
931 if (!PyList_Check(source)) {
932 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
933 return NULL;
934 }
935 int count = PyList_Size(source);
936 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
937 if (! temp) {
938 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
939 return NULL;
940 }
941 for (int x=0; x<count; x++) {
942 PyObject* o = PyList_GetItem(source, x);
943 if (PyInstance_Check(o)) {
944 wxAcceleratorEntry* ae;
945 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
946 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
947 return NULL;
948 }
949 temp[x] = *ae;
950 }
951 else if (PyTuple_Check(o)) {
952 PyObject* o1 = PyTuple_GetItem(o, 0);
953 PyObject* o2 = PyTuple_GetItem(o, 1);
954 PyObject* o3 = PyTuple_GetItem(o, 2);
955
956 temp[x].m_flags = PyInt_AsLong(o1);
957 temp[x].m_keyCode = PyInt_AsLong(o2);
958 temp[x].m_command = PyInt_AsLong(o3);
959 }
960 else {
961 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
962 return NULL;
963 }
964 }
965 return temp;
966}
967
968
969
970//----------------------------------------------------------------------
971
972bool wxSize_helper(PyObject* source, wxSize** obj) {
973
974 // If source is an object instance then it may already be the right type
975 if (PyInstance_Check(source)) {
976 wxSize* ptr;
977 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
978 goto error;
979 *obj = ptr;
980 return TRUE;
981 }
982 // otherwise a 2-tuple of integers is expected
983 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
984 PyObject* o1 = PySequence_GetItem(source, 0);
985 PyObject* o2 = PySequence_GetItem(source, 1);
986 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
987 return TRUE;
988 }
989
990 error:
991 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
992 return FALSE;
993}
994
995bool wxPoint_helper(PyObject* source, wxPoint** obj) {
996
997 // If source is an object instance then it may already be the right type
998 if (PyInstance_Check(source)) {
999 wxPoint* ptr;
1000 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
1001 goto error;
1002 *obj = ptr;
1003 return TRUE;
1004 }
1005 // otherwise a length-2 sequence of integers is expected
1006 if (PySequence_Check(source) && PySequence_Length(source) == 2) {
1007 PyObject* o1 = PySequence_GetItem(source, 0);
1008 PyObject* o2 = PySequence_GetItem(source, 1);
1009 // This should really check for integers, not numbers -- but that would break code.
1010 if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) {
1011 Py_DECREF(o1);
1012 Py_DECREF(o2);
1013 goto error;
1014 }
1015 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
1016 Py_DECREF(o1);
1017 Py_DECREF(o2);
1018 return TRUE;
1019 }
1020 error:
1021 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
1022 return FALSE;
1023}
1024
1025
1026
1027bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
1028
1029 // If source is an object instance then it may already be the right type
1030 if (PyInstance_Check(source)) {
1031 wxRealPoint* ptr;
1032 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
1033 goto error;
1034 *obj = ptr;
1035 return TRUE;
1036 }
1037 // otherwise a 2-tuple of floats is expected
1038 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
1039 PyObject* o1 = PySequence_GetItem(source, 0);
1040 PyObject* o2 = PySequence_GetItem(source, 1);
1041 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
1042 return TRUE;
1043 }
1044
1045 error:
1046 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
1047 return FALSE;
1048}
1049
1050
1051
1052
1053bool wxRect_helper(PyObject* source, wxRect** obj) {
1054
1055 // If source is an object instance then it may already be the right type
1056 if (PyInstance_Check(source)) {
1057 wxRect* ptr;
1058 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
1059 goto error;
1060 *obj = ptr;
1061 return TRUE;
1062 }
1063 // otherwise a 4-tuple of integers is expected
1064 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
1065 PyObject* o1 = PySequence_GetItem(source, 0);
1066 PyObject* o2 = PySequence_GetItem(source, 1);
1067 PyObject* o3 = PySequence_GetItem(source, 2);
1068 PyObject* o4 = PySequence_GetItem(source, 3);
1069 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
1070 PyInt_AsLong(o3), PyInt_AsLong(o4));
1071 return TRUE;
1072 }
1073
1074 error:
1075 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
1076 return FALSE;
1077}
1078
1079
1080
1081bool wxColour_helper(PyObject* source, wxColour** obj) {
1082
1083 // If source is an object instance then it may already be the right type
1084 if (PyInstance_Check(source)) {
1085 wxColour* ptr;
1086 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxColour_p"))
1087 goto error;
1088 *obj = ptr;
1089 return TRUE;
1090 }
1091 // otherwise a string is expected
1092 else if (PyString_Check(source)) {
1093 wxString spec = PyString_AS_STRING(source);
1094 if (spec[0U] == '#' && spec.Length() == 7) { // It's #RRGGBB
1095 char* junk;
1096 int red = strtol(spec.Mid(1,2), &junk, 16);
1097 int green = strtol(spec.Mid(3,2), &junk, 16);
1098 int blue = strtol(spec.Mid(5,2), &junk, 16);
1099 **obj = wxColour(red, green, blue);
1100 return TRUE;
1101 }
1102 else { // it's a colour name
1103 **obj = wxColour(spec);
1104 return TRUE;
1105 }
1106 }
1107
1108 error:
1109 PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
1110 return FALSE;
1111}
1112
1113
1114//----------------------------------------------------------------------
1115//----------------------------------------------------------------------
1116//----------------------------------------------------------------------
1117
1118
1119
1120