]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/helpers.cpp
065e70e0ba891f5528f442bd63775c67653d9413
[wxWidgets.git] / 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 #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 #include <wx/msw/winundef.h>
22 #include <wx/msw/msvcrt.h>
23 #endif
24
25 #ifdef __WXGTK__
26 #include <gtk/gtk.h>
27 #include <gdk/gdkprivate.h>
28 #include <wx/gtk/win_gtk.h>
29 #endif
30
31
32 //----------------------------------------------------------------------
33
34 #ifdef __WXGTK__
35 int WXDLLEXPORT wxEntryStart( int& argc, char** argv );
36 #else
37 int WXDLLEXPORT wxEntryStart( int argc, char** argv );
38 #endif
39 int WXDLLEXPORT wxEntryInitGui();
40 void WXDLLEXPORT wxEntryCleanup();
41
42 wxPyApp* wxPythonApp = NULL; // Global instance of application object
43
44
45 #ifdef WXP_WITH_THREAD
46 struct wxPyThreadState {
47 unsigned long tid;
48 PyThreadState* tstate;
49
50 wxPyThreadState(unsigned long _tid=0, PyThreadState* _tstate=NULL)
51 : tid(_tid), tstate(_tstate) {}
52 };
53
54 #include <wx/dynarray.h>
55 WX_DECLARE_OBJARRAY(wxPyThreadState, wxPyThreadStateArray);
56 #include <wx/arrimpl.cpp>
57 WX_DEFINE_OBJARRAY(wxPyThreadStateArray);
58
59 wxPyThreadStateArray* wxPyTStates = NULL;
60 wxMutex* wxPyTMutex = NULL;
61 #endif
62
63
64 #ifdef __WXMSW__ // If building for win32...
65 //----------------------------------------------------------------------
66 // This gets run when the DLL is loaded. We just need to save a handle.
67 //----------------------------------------------------------------------
68
69 BOOL WINAPI DllMain(
70 HINSTANCE hinstDLL, // handle to DLL module
71 DWORD fdwReason, // reason for calling function
72 LPVOID lpvReserved // reserved
73 )
74 {
75 wxSetInstance(hinstDLL);
76 return 1;
77 }
78 #endif
79
80 //----------------------------------------------------------------------
81 // Classes for implementing the wxp main application shell.
82 //----------------------------------------------------------------------
83
84
85 wxPyApp::wxPyApp() {
86 // printf("**** ctor\n");
87 }
88
89 wxPyApp::~wxPyApp() {
90 // printf("**** dtor\n");
91 }
92
93
94 // This one isn't acutally called... See __wxStart()
95 bool wxPyApp::OnInit() {
96 return FALSE;
97 }
98
99
100 int wxPyApp::MainLoop() {
101 int retval = 0;
102
103 DeletePendingObjects();
104 bool initialized = wxTopLevelWindows.GetCount() != 0;
105 #ifdef __WXGTK__
106 m_initialized = initialized;
107 #endif
108
109 if (initialized) {
110 retval = wxApp::MainLoop();
111 OnExit();
112 }
113 return retval;
114 }
115
116
117
118 //---------------------------------------------------------------------
119 //----------------------------------------------------------------------
120
121
122 // This is where we pick up the first part of the wxEntry functionality...
123 // The rest is in __wxStart and __wxCleanup. This function is called when
124 // wxcmodule is imported. (Before there is a wxApp object.)
125 void __wxPreStart()
126 {
127
128 #ifdef __WXMSW__
129 // wxCrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
130 #endif
131
132 #ifdef WXP_WITH_THREAD
133 PyEval_InitThreads();
134 wxPyTStates = new wxPyThreadStateArray;
135 wxPyTMutex = new wxMutex;
136 #endif
137
138 // Bail out if there is already windows created. This means that the
139 // toolkit has already been initialized, as in embedding wxPython in
140 // a C++ wxWindows app.
141 if (wxTopLevelWindows.Number() > 0)
142 return;
143
144
145 int argc = 0;
146 char** argv = NULL;
147 PyObject* sysargv = PySys_GetObject("argv");
148 if (sysargv != NULL) {
149 argc = PyList_Size(sysargv);
150 argv = new char*[argc+1];
151 int x;
152 for(x=0; x<argc; x++)
153 argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
154 argv[argc] = NULL;
155 }
156
157 wxEntryStart(argc, argv);
158 delete [] argv;
159 }
160
161
162
163 // Start the user application, user App's OnInit method is a parameter here
164 PyObject* __wxStart(PyObject* /* self */, PyObject* args)
165 {
166 PyObject* onInitFunc = NULL;
167 PyObject* arglist;
168 PyObject* result;
169 long bResult;
170
171 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
172 return NULL;
173
174 #if 0 // Try it out without this check, see how it does...
175 if (wxTopLevelWindows.Number() > 0) {
176 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
177 return NULL;
178 }
179 #endif
180
181 // This is the next part of the wxEntry functionality...
182 int argc = 0;
183 char** argv = NULL;
184 PyObject* sysargv = PySys_GetObject("argv");
185 if (sysargv != NULL) {
186 argc = PyList_Size(sysargv);
187 argv = new char*[argc+1];
188 int x;
189 for(x=0; x<argc; x++)
190 argv[x] = copystring(PyString_AsString(PyList_GetItem(sysargv, x)));
191 argv[argc] = NULL;
192 }
193 wxPythonApp->argc = argc;
194 wxPythonApp->argv = argv;
195
196 wxEntryInitGui();
197
198 // Call the Python App's OnInit function
199 arglist = PyTuple_New(0);
200 result = PyEval_CallObject(onInitFunc, arglist);
201 if (!result) { // an exception was raised.
202 return NULL;
203 }
204
205 if (! PyInt_Check(result)) {
206 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
207 return NULL;
208 }
209 bResult = PyInt_AS_LONG(result);
210 if (! bResult) {
211 PyErr_SetString(PyExc_SystemExit, "OnInit returned FALSE, exiting...");
212 return NULL;
213 }
214
215 #ifdef __WXGTK__
216 wxTheApp->m_initialized = (wxTopLevelWindows.GetCount() > 0);
217 #endif
218
219 Py_INCREF(Py_None);
220 return Py_None;
221 }
222
223
224 void __wxCleanup() {
225 wxEntryCleanup();
226 #ifdef WXP_WITH_THREAD
227 delete wxPyTMutex;
228 wxPyTMutex = NULL;
229 wxPyTStates->Empty();
230 delete wxPyTStates;
231 wxPyTStates = NULL;
232 #endif
233 }
234
235
236
237 static PyObject* wxPython_dict = NULL;
238 static PyObject* wxPyPtrTypeMap = NULL;
239
240 PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
241 {
242
243 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
244 return NULL;
245
246 if (!PyDict_Check(wxPython_dict)) {
247 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
248 return NULL;
249 }
250
251 if (! wxPyPtrTypeMap)
252 wxPyPtrTypeMap = PyDict_New();
253 PyDict_SetItemString(wxPython_dict, "__wxPyPtrTypeMap", wxPyPtrTypeMap);
254
255
256 #ifdef __WXMOTIF__
257 #define wxPlatform "__WXMOTIF__"
258 #endif
259 #ifdef __WXX11__
260 #define wxPlatform "__WXX11__"
261 #endif
262 #ifdef __WXGTK__
263 #define wxPlatform "__WXGTK__"
264 #endif
265 #if defined(__WIN32__) || defined(__WXMSW__)
266 #define wxPlatform "__WXMSW__"
267 #endif
268 #ifdef __WXMAC__
269 #define wxPlatform "__WXMAC__"
270 #endif
271
272 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
273
274 Py_INCREF(Py_None);
275 return Py_None;
276 }
277
278
279 //---------------------------------------------------------------------------
280 // Stuff used by OOR to find the right wxPython class type to return and to
281 // build it.
282
283
284 // The pointer type map is used when the "pointer" type name generated by SWIG
285 // is not the same as the shadow class name, for example wxPyTreeCtrl
286 // vs. wxTreeCtrl. It needs to be referenced in Python as well as from C++,
287 // so we'll just make it a Python dictionary in the wx module's namespace.
288 void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) {
289 if (! wxPyPtrTypeMap)
290 wxPyPtrTypeMap = PyDict_New();
291 PyDict_SetItemString(wxPyPtrTypeMap,
292 (char*)commonName,
293 PyString_FromString((char*)ptrName));
294 }
295
296
297
298 PyObject* wxPyClassExists(const char* className) {
299
300 if (!className)
301 return NULL;
302
303 char buff[64]; // should always be big enough...
304
305 sprintf(buff, "%sPtr", className);
306 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
307
308 return classobj; // returns NULL if not found
309 }
310
311
312 PyObject* wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) {
313 PyObject* target = NULL;
314 bool isEvtHandler = FALSE;
315
316 if (source) {
317 // If it's derived from wxEvtHandler then there may
318 // already be a pointer to a Python object that we can use
319 // in the OOR data.
320 if (checkEvtHandler && wxIsKindOf(source, wxEvtHandler)) {
321 isEvtHandler = TRUE;
322 wxEvtHandler* eh = (wxEvtHandler*)source;
323 wxPyClientData* data = (wxPyClientData*)eh->GetClientObject();
324 if (data) {
325 target = data->m_obj;
326 Py_INCREF(target);
327 }
328 }
329
330 if (! target) {
331 // Otherwise make it the old fashioned way by making a
332 // new shadow object and putting this pointer in it.
333 wxClassInfo* info = source->GetClassInfo();
334 wxChar* name = (wxChar*)info->GetClassName();
335 PyObject* klass = wxPyClassExists(name);
336 while (info && !klass) {
337 name = (wxChar*)info->GetBaseClassName1();
338 info = wxClassInfo::FindClass(name);
339 klass = wxPyClassExists(name);
340 }
341 if (info) {
342 target = wxPyConstructObject(source, name, klass, FALSE);
343 if (target && isEvtHandler)
344 ((wxEvtHandler*)source)->SetClientObject(new wxPyClientData(target));
345 } else {
346 wxString msg("wxPython class not found for ");
347 msg += source->GetClassInfo()->GetClassName();
348 PyErr_SetString(PyExc_NameError, msg.c_str());
349 target = NULL;
350 }
351 }
352 } else { // source was NULL so return None.
353 Py_INCREF(Py_None); target = Py_None;
354 }
355 return target;
356 }
357
358
359 PyObject* wxPyMake_wxSizer(wxSizer* source) {
360 PyObject* target = NULL;
361
362 if (source && wxIsKindOf(source, wxSizer)) {
363 // If it's derived from wxSizer then there may
364 // already be a pointer to a Python object that we can use
365 // in the OOR data.
366 wxSizer* sz = (wxSizer*)source;
367 wxPyClientData* data = (wxPyClientData*)sz->GetClientObject();
368 if (data) {
369 target = data->m_obj;
370 Py_INCREF(target);
371 }
372 }
373 if (! target) {
374 target = wxPyMake_wxObject(source, FALSE);
375 if (target != Py_None)
376 ((wxSizer*)source)->SetClientObject(new wxPyClientData(target));
377 }
378 return target;
379 }
380
381
382
383 //---------------------------------------------------------------------------
384
385 PyObject* wxPyConstructObject(void* ptr,
386 const char* className,
387 PyObject* klass,
388 int setThisOwn) {
389
390 PyObject* obj;
391 PyObject* arg;
392 PyObject* item;
393 char swigptr[64]; // should always be big enough...
394 char buff[64];
395
396 if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)className)) != NULL) {
397 className = PyString_AsString(item);
398 }
399 sprintf(buff, "_%s_p", className);
400 SWIG_MakePtr(swigptr, ptr, buff);
401
402 arg = Py_BuildValue("(s)", swigptr);
403 obj = PyInstance_New(klass, arg, NULL);
404 Py_DECREF(arg);
405
406 if (setThisOwn) {
407 PyObject* one = PyInt_FromLong(1);
408 PyObject_SetAttrString(obj, "thisown", one);
409 Py_DECREF(one);
410 }
411
412 return obj;
413 }
414
415
416 PyObject* wxPyConstructObject(void* ptr,
417 const char* className,
418 int setThisOwn) {
419 PyObject* obj;
420
421 if (!ptr) {
422 Py_INCREF(Py_None);
423 return Py_None;
424 }
425
426 char buff[64]; // should always be big enough...
427 sprintf(buff, "%sPtr", className);
428
429 wxASSERT_MSG(wxPython_dict, "wxPython_dict is not set yet!!");
430
431 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
432 if (! classobj) {
433 char temp[128];
434 sprintf(temp,
435 "*** Unknown class name %s, tell Robin about it please ***",
436 buff);
437 obj = PyString_FromString(temp);
438 return obj;
439 }
440
441 return wxPyConstructObject(ptr, className, classobj, setThisOwn);
442 }
443
444 //---------------------------------------------------------------------------
445
446
447 #ifdef WXP_WITH_THREAD
448 inline
449 unsigned long wxPyGetCurrentThreadId() {
450 return wxThread::GetCurrentId();
451 }
452
453 static PyThreadState* gs_shutdownTState;
454 static
455 PyThreadState* wxPyGetThreadState() {
456 if (wxPyTMutex == NULL) // Python is shutting down...
457 return gs_shutdownTState;
458
459 unsigned long ctid = wxPyGetCurrentThreadId();
460 PyThreadState* tstate = NULL;
461
462 wxPyTMutex->Lock();
463 for(size_t i=0; i < wxPyTStates->GetCount(); i++) {
464 wxPyThreadState& info = wxPyTStates->Item(i);
465 if (info.tid == ctid) {
466 tstate = info.tstate;
467 break;
468 }
469 }
470 wxPyTMutex->Unlock();
471 wxASSERT_MSG(tstate, "PyThreadState should not be NULL!");
472 return tstate;
473 }
474
475 static
476 void wxPySaveThreadState(PyThreadState* tstate) {
477 if (wxPyTMutex == NULL) { // Python is shutting down, assume a single thread...
478 gs_shutdownTState = tstate;
479 return;
480 }
481 unsigned long ctid = wxPyGetCurrentThreadId();
482 wxPyTMutex->Lock();
483 for(size_t i=0; i < wxPyTStates->GetCount(); i++) {
484 wxPyThreadState& info = wxPyTStates->Item(i);
485 if (info.tid == ctid) {
486 info.tstate = tstate;
487 wxPyTMutex->Unlock();
488 return;
489 }
490 }
491 // not found, so add it...
492 wxPyTStates->Add(new wxPyThreadState(ctid, tstate));
493 wxPyTMutex->Unlock();
494 }
495
496 #endif
497
498
499 // Calls from Python to wxWindows code are wrapped in calls to these
500 // functions:
501
502 PyThreadState* wxPyBeginAllowThreads() {
503 #ifdef WXP_WITH_THREAD
504 PyThreadState* saved = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS;
505 wxPySaveThreadState(saved);
506 return saved;
507 #else
508 return NULL;
509 #endif
510 }
511
512 void wxPyEndAllowThreads(PyThreadState* saved) {
513 #ifdef WXP_WITH_THREAD
514 PyEval_RestoreThread(saved); // Py_END_ALLOW_THREADS;
515 #endif
516 }
517
518
519
520 // Calls from wxWindows back to Python code, or even any PyObject
521 // manipulations, PyDECREF's and etc. are wrapped in calls to these functions:
522
523 void wxPyBeginBlockThreads() {
524 #ifdef WXP_WITH_THREAD
525 PyThreadState* tstate = wxPyGetThreadState();
526 PyEval_RestoreThread(tstate);
527 #endif
528 }
529
530
531 void wxPyEndBlockThreads() {
532 #ifdef WXP_WITH_THREAD
533 PyThreadState* tstate = PyEval_SaveThread();
534 // Is there any need to save it again?
535 #endif
536 }
537
538
539 //---------------------------------------------------------------------------
540 // wxPyInputStream and wxPyCBInputStream methods
541
542 #include <wx/listimpl.cpp>
543 WX_DEFINE_LIST(wxStringPtrList);
544
545
546 void wxPyInputStream::close() {
547 /* do nothing */
548 }
549
550 void wxPyInputStream::flush() {
551 /* do nothing */
552 }
553
554 bool wxPyInputStream::eof() {
555 if (m_wxis)
556 return m_wxis->Eof();
557 else
558 return TRUE;
559 }
560
561 wxPyInputStream::~wxPyInputStream() {
562 /* do nothing */
563 }
564
565 wxString* wxPyInputStream::read(int size) {
566 wxString* s = NULL;
567 const int BUFSIZE = 1024;
568
569 // check if we have a real wxInputStream to work with
570 if (!m_wxis) {
571 PyErr_SetString(PyExc_IOError, "no valid C-wxInputStream");
572 return NULL;
573 }
574
575 if (size < 0) {
576 // init buffers
577 char * buf = new char[BUFSIZE];
578 if (!buf) {
579 PyErr_NoMemory();
580 return NULL;
581 }
582
583 s = new wxString();
584 if (!s) {
585 delete buf;
586 PyErr_NoMemory();
587 return NULL;
588 }
589
590 // read until EOF
591 while (! m_wxis->Eof()) {
592 m_wxis->Read(buf, BUFSIZE);
593 s->Append(buf, m_wxis->LastRead());
594 }
595 delete buf;
596
597 // error check
598 if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
599 delete s;
600 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
601 return NULL;
602 }
603
604 } else { // Read only size number of characters
605 s = new wxString;
606 if (!s) {
607 PyErr_NoMemory();
608 return NULL;
609 }
610
611 // read size bytes
612 m_wxis->Read(s->GetWriteBuf(size+1), size);
613 s->UngetWriteBuf(m_wxis->LastRead());
614
615 // error check
616 if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
617 delete s;
618 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
619 return NULL;
620 }
621 }
622 return s;
623 }
624
625
626 wxString* wxPyInputStream::readline (int size) {
627 // check if we have a real wxInputStream to work with
628 if (!m_wxis) {
629 PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream");
630 return NULL;
631 }
632
633 // init buffer
634 int i;
635 char ch;
636 wxString* s = new wxString;
637 if (!s) {
638 PyErr_NoMemory();
639 return NULL;
640 }
641
642 // read until \n or byte limit reached
643 for (i=ch=0; (ch != '\n') && (!m_wxis->Eof()) && ((size < 0) || (i < size)); i++) {
644 *s += ch = m_wxis->GetC();
645 }
646
647 // errorcheck
648 if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
649 delete s;
650 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
651 return NULL;
652 }
653 return s;
654 }
655
656
657 wxStringPtrList* wxPyInputStream::readlines (int sizehint) {
658 // check if we have a real wxInputStream to work with
659 if (!m_wxis) {
660 PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below");
661 return NULL;
662 }
663
664 // init list
665 wxStringPtrList* l = new wxStringPtrList();
666 if (!l) {
667 PyErr_NoMemory();
668 return NULL;
669 }
670
671 // read sizehint bytes or until EOF
672 int i;
673 for (i=0; (!m_wxis->Eof()) && ((sizehint < 0) || (i < sizehint));) {
674 wxString* s = readline();
675 if (s == NULL) {
676 l->DeleteContents(TRUE);
677 l->Clear();
678 return NULL;
679 }
680 l->Append(s);
681 i = i + s->Length();
682 }
683
684 // error check
685 if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
686 l->DeleteContents(TRUE);
687 l->Clear();
688 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
689 return NULL;
690 }
691 return l;
692 }
693
694
695 void wxPyInputStream::seek(int offset, int whence) {
696 if (m_wxis)
697 m_wxis->SeekI(offset, wxSeekMode(whence));
698 }
699
700 int wxPyInputStream::tell(){
701 if (m_wxis)
702 return m_wxis->TellI();
703 else return 0;
704 }
705
706
707
708
709 wxPyCBInputStream::wxPyCBInputStream(PyObject *r, PyObject *s, PyObject *t, bool block)
710 : wxInputStream(), m_read(r), m_seek(s), m_tell(t), m_block(block)
711 {}
712
713
714 wxPyCBInputStream::~wxPyCBInputStream() {
715 if (m_block) wxPyBeginBlockThreads();
716 Py_XDECREF(m_read);
717 Py_XDECREF(m_seek);
718 Py_XDECREF(m_tell);
719 if (m_block) wxPyEndBlockThreads();
720 }
721
722
723 wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) {
724 if (block) wxPyBeginBlockThreads();
725
726 PyObject* read = getMethod(py, "read");
727 PyObject* seek = getMethod(py, "seek");
728 PyObject* tell = getMethod(py, "tell");
729
730 if (!read) {
731 PyErr_SetString(PyExc_TypeError, "Not a file-like object");
732 Py_XDECREF(read);
733 Py_XDECREF(seek);
734 Py_XDECREF(tell);
735 if (block) wxPyEndBlockThreads();
736 return NULL;
737 }
738
739 if (block) wxPyEndBlockThreads();
740 return new wxPyCBInputStream(read, seek, tell, block);
741 }
742
743 PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) {
744 if (!PyObject_HasAttrString(py, name))
745 return NULL;
746 PyObject* o = PyObject_GetAttrString(py, name);
747 if (!PyMethod_Check(o) && !PyCFunction_Check(o)) {
748 Py_DECREF(o);
749 return NULL;
750 }
751 return o;
752 }
753
754
755 size_t wxPyCBInputStream::GetSize() const {
756 wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
757 if (m_seek && m_tell) {
758 off_t temp = self->OnSysTell();
759 off_t ret = self->OnSysSeek(0, wxFromEnd);
760 self->OnSysSeek(temp, wxFromStart);
761 return ret;
762 }
763 else
764 return 0;
765 }
766
767
768 size_t wxPyCBInputStream::OnSysRead(void *buffer, size_t bufsize) {
769 if (bufsize == 0)
770 return 0;
771
772 wxPyBeginBlockThreads();
773 PyObject* arglist = Py_BuildValue("(i)", bufsize);
774 PyObject* result = PyEval_CallObject(m_read, arglist);
775 Py_DECREF(arglist);
776
777 size_t o = 0;
778 if ((result != NULL) && PyString_Check(result)) { // TODO: unicode?
779 o = PyString_Size(result);
780 if (o == 0)
781 m_lasterror = wxSTREAM_EOF;
782 if (o > bufsize)
783 o = bufsize;
784 memcpy((char*)buffer, PyString_AsString(result), o);
785 Py_DECREF(result);
786
787 }
788 else
789 m_lasterror = wxSTREAM_READ_ERROR;
790 wxPyEndBlockThreads();
791 m_lastcount = o;
792 return o;
793 }
794
795 size_t wxPyCBInputStream::OnSysWrite(const void *buffer, size_t bufsize) {
796 m_lasterror = wxSTREAM_WRITE_ERROR;
797 return 0;
798 }
799
800 off_t wxPyCBInputStream::OnSysSeek(off_t off, wxSeekMode mode) {
801 wxPyBeginBlockThreads();
802 PyObject* arglist = Py_BuildValue("(ii)", off, mode);
803 PyObject* result = PyEval_CallObject(m_seek, arglist);
804 Py_DECREF(arglist);
805 Py_XDECREF(result);
806 wxPyEndBlockThreads();
807 return OnSysTell();
808 }
809
810 off_t wxPyCBInputStream::OnSysTell() const {
811 wxPyBeginBlockThreads();
812 PyObject* arglist = Py_BuildValue("()");
813 PyObject* result = PyEval_CallObject(m_tell, arglist);
814 Py_DECREF(arglist);
815 off_t o = 0;
816 if (result != NULL) {
817 o = PyInt_AsLong(result);
818 Py_DECREF(result);
819 };
820 wxPyEndBlockThreads();
821 return o;
822 }
823
824 //----------------------------------------------------------------------
825
826 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
827
828 wxPyCallback::wxPyCallback(PyObject* func) {
829 m_func = func;
830 Py_INCREF(m_func);
831 }
832
833 wxPyCallback::wxPyCallback(const wxPyCallback& other) {
834 m_func = other.m_func;
835 Py_INCREF(m_func);
836 }
837
838 wxPyCallback::~wxPyCallback() {
839 wxPyBeginBlockThreads();
840 Py_DECREF(m_func);
841 wxPyEndBlockThreads();
842 }
843
844
845
846 // This function is used for all events destined for Python event handlers.
847 void wxPyCallback::EventThunker(wxEvent& event) {
848 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
849 PyObject* func = cb->m_func;
850 PyObject* result;
851 PyObject* arg;
852 PyObject* tuple;
853
854
855 wxPyBeginBlockThreads();
856 wxString className = event.GetClassInfo()->GetClassName();
857
858 if (className == "wxPyEvent")
859 arg = ((wxPyEvent*)&event)->GetSelf();
860 else if (className == "wxPyCommandEvent")
861 arg = ((wxPyCommandEvent*)&event)->GetSelf();
862 else
863 arg = wxPyConstructObject((void*)&event, className);
864
865 tuple = PyTuple_New(1);
866 PyTuple_SET_ITEM(tuple, 0, arg);
867 result = PyEval_CallObject(func, tuple);
868 Py_DECREF(tuple);
869 if (result) {
870 Py_DECREF(result);
871 PyErr_Clear(); // Just in case...
872 } else {
873 PyErr_Print();
874 }
875 wxPyEndBlockThreads();
876 }
877
878
879 //----------------------------------------------------------------------
880
881 wxPyCallbackHelper::wxPyCallbackHelper(const wxPyCallbackHelper& other) {
882 m_lastFound = NULL;
883 m_self = other.m_self;
884 m_class = other.m_class;
885 if (m_self) {
886 Py_INCREF(m_self);
887 Py_INCREF(m_class);
888 }
889 }
890
891
892 void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
893 m_self = self;
894 m_class = klass;
895 m_incRef = incref;
896 if (incref) {
897 Py_INCREF(m_self);
898 Py_INCREF(m_class);
899 }
900 }
901
902
903 #if PYTHON_API_VERSION >= 1011
904
905 // Prior to Python 2.2 PyMethod_GetClass returned the class object
906 // in which the method was defined. Starting with 2.2 it returns
907 // "class that asked for the method" which seems totally bogus to me
908 // but apprently if fixes some obscure problem waiting to happen in
909 // Python. Since the API was not documented Guido and the gang felt
910 // safe in changing it. Needless to say that totally screwed up the
911 // logic below in wxPyCallbackHelper::findCallback, hence this icky
912 // code to find the class where the method is actuallt defined...
913
914 static
915 PyObject* PyFindClassWithAttr(PyObject *klass, PyObject *name)
916 {
917 int i, n;
918
919 if (PyType_Check(klass)) { // new style classes
920 // This code is borrowed/adapted from _PyType_Lookup in typeobject.c
921 // (TODO: This part is not tested yet, so I'm not sure it is correct...)
922 PyTypeObject* type = (PyTypeObject*)klass;
923 PyObject *mro, *res, *base, *dict;
924 /* Look in tp_dict of types in MRO */
925 mro = type->tp_mro;
926 assert(PyTuple_Check(mro));
927 n = PyTuple_GET_SIZE(mro);
928 for (i = 0; i < n; i++) {
929 base = PyTuple_GET_ITEM(mro, i);
930 if (PyClass_Check(base))
931 dict = ((PyClassObject *)base)->cl_dict;
932 else {
933 assert(PyType_Check(base));
934 dict = ((PyTypeObject *)base)->tp_dict;
935 }
936 assert(dict && PyDict_Check(dict));
937 res = PyDict_GetItem(dict, name);
938 if (res != NULL)
939 return base;
940 }
941 return NULL;
942 }
943
944 else if (PyClass_Check(klass)) { // old style classes
945 // This code is borrowed/adapted from class_lookup in classobject.c
946 PyClassObject* cp = (PyClassObject*)klass;
947 PyObject *value = PyDict_GetItem(cp->cl_dict, name);
948 if (value != NULL) {
949 return (PyObject*)cp;
950 }
951 n = PyTuple_Size(cp->cl_bases);
952 for (i = 0; i < n; i++) {
953 PyObject* base = PyTuple_GetItem(cp->cl_bases, i);
954 PyObject *v = PyFindClassWithAttr(base, name);
955 if (v != NULL)
956 return v;
957 }
958 return NULL;
959 }
960 }
961 #endif
962
963
964 static
965 PyObject* PyMethod_GetDefiningClass(PyObject* method, const char* name)
966 {
967 PyObject* mgc = PyMethod_GET_CLASS(method);
968
969 #if PYTHON_API_VERSION <= 1010 // prior to Python 2.2, the easy way
970 return mgc;
971 #else // 2.2 and after, the hard way...
972
973 PyObject* nameo = PyString_FromString(name);
974 PyObject* klass = PyFindClassWithAttr(mgc, nameo);
975 Py_DECREF(nameo);
976 return klass;
977 #endif
978 }
979
980
981
982 bool wxPyCallbackHelper::findCallback(const char* name) const {
983 wxPyCallbackHelper* self = (wxPyCallbackHelper*)this; // cast away const
984 self->m_lastFound = NULL;
985
986 // If the object (m_self) has an attibute of the given name...
987 if (m_self && PyObject_HasAttrString(m_self, (char*)name)) {
988 PyObject *method, *klass;
989 method = PyObject_GetAttrString(m_self, (char*)name);
990
991 // ...and if that attribute is a method, and if that method's class is
992 // not from a base class...
993 if (PyMethod_Check(method) &&
994 (klass = PyMethod_GetDefiningClass(method, (char*)name)) != NULL &&
995 ((klass == m_class) || PyClass_IsSubclass(klass, m_class))) {
996
997 // ...then we'll save a pointer to the method so callCallback can call it.
998 self->m_lastFound = method;
999 }
1000 else {
1001 Py_DECREF(method);
1002 }
1003 }
1004 return m_lastFound != NULL;
1005 }
1006
1007
1008 int wxPyCallbackHelper::callCallback(PyObject* argTuple) const {
1009 PyObject* result;
1010 int retval = FALSE;
1011
1012 result = callCallbackObj(argTuple);
1013 if (result) { // Assumes an integer return type...
1014 retval = PyInt_AsLong(result);
1015 Py_DECREF(result);
1016 PyErr_Clear(); // forget about it if it's not...
1017 }
1018 return retval;
1019 }
1020
1021 // Invoke the Python callable object, returning the raw PyObject return
1022 // value. Caller should DECREF the return value and also call PyEval_SaveThread.
1023 PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) const {
1024 PyObject* result;
1025
1026 // Save a copy of the pointer in case the callback generates another
1027 // callback. In that case m_lastFound will have a different value when
1028 // it gets back here...
1029 PyObject* method = m_lastFound;
1030
1031 result = PyEval_CallObject(method, argTuple);
1032 Py_DECREF(argTuple);
1033 Py_DECREF(method);
1034 if (!result) {
1035 PyErr_Print();
1036 }
1037 return result;
1038 }
1039
1040
1041 void wxPyCBH_setCallbackInfo(wxPyCallbackHelper& cbh, PyObject* self, PyObject* klass, int incref) {
1042 cbh.setSelf(self, klass, incref);
1043 }
1044
1045 bool wxPyCBH_findCallback(const wxPyCallbackHelper& cbh, const char* name) {
1046 return cbh.findCallback(name);
1047 }
1048
1049 int wxPyCBH_callCallback(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
1050 return cbh.callCallback(argTuple);
1051 }
1052
1053 PyObject* wxPyCBH_callCallbackObj(const wxPyCallbackHelper& cbh, PyObject* argTuple) {
1054 return cbh.callCallbackObj(argTuple);
1055 }
1056
1057
1058 void wxPyCBH_delete(wxPyCallbackHelper* cbh) {
1059 if (cbh->m_incRef) {
1060 wxPyBeginBlockThreads();
1061 Py_XDECREF(cbh->m_self);
1062 Py_XDECREF(cbh->m_class);
1063 wxPyEndBlockThreads();
1064 }
1065 }
1066
1067 //---------------------------------------------------------------------------
1068 //---------------------------------------------------------------------------
1069 // These event classes can be derived from in Python and passed through the event
1070 // system without losing anything. They do this by keeping a reference to
1071 // themselves and some special case handling in wxPyCallback::EventThunker.
1072
1073
1074 wxPyEvtSelfRef::wxPyEvtSelfRef() {
1075 //m_self = Py_None; // **** We don't do normal ref counting to prevent
1076 //Py_INCREF(m_self); // circular loops...
1077 m_cloned = FALSE;
1078 }
1079
1080 wxPyEvtSelfRef::~wxPyEvtSelfRef() {
1081 wxPyBeginBlockThreads();
1082 if (m_cloned)
1083 Py_DECREF(m_self);
1084 wxPyEndBlockThreads();
1085 }
1086
1087 void wxPyEvtSelfRef::SetSelf(PyObject* self, bool clone) {
1088 wxPyBeginBlockThreads();
1089 if (m_cloned)
1090 Py_DECREF(m_self);
1091 m_self = self;
1092 if (clone) {
1093 Py_INCREF(m_self);
1094 m_cloned = TRUE;
1095 }
1096 wxPyEndBlockThreads();
1097 }
1098
1099 PyObject* wxPyEvtSelfRef::GetSelf() const {
1100 Py_INCREF(m_self);
1101 return m_self;
1102 }
1103
1104
1105 IMPLEMENT_ABSTRACT_CLASS(wxPyEvent, wxEvent);
1106 IMPLEMENT_ABSTRACT_CLASS(wxPyCommandEvent, wxCommandEvent);
1107
1108
1109 wxPyEvent::wxPyEvent(int id)
1110 : wxEvent(id) {
1111 }
1112
1113
1114 wxPyEvent::wxPyEvent(const wxPyEvent& evt)
1115 : wxEvent(evt)
1116 {
1117 SetSelf(evt.m_self, TRUE);
1118 }
1119
1120
1121 wxPyEvent::~wxPyEvent() {
1122 }
1123
1124
1125 wxPyCommandEvent::wxPyCommandEvent(wxEventType commandType, int id)
1126 : wxCommandEvent(commandType, id) {
1127 }
1128
1129
1130 wxPyCommandEvent::wxPyCommandEvent(const wxPyCommandEvent& evt)
1131 : wxCommandEvent(evt)
1132 {
1133 SetSelf(evt.m_self, TRUE);
1134 }
1135
1136
1137 wxPyCommandEvent::~wxPyCommandEvent() {
1138 }
1139
1140
1141
1142
1143 //---------------------------------------------------------------------------
1144 //---------------------------------------------------------------------------
1145
1146
1147 wxPyTimer::wxPyTimer(PyObject* callback) {
1148 func = callback;
1149 Py_INCREF(func);
1150 }
1151
1152 wxPyTimer::~wxPyTimer() {
1153 wxPyBeginBlockThreads();
1154 Py_DECREF(func);
1155 wxPyEndBlockThreads();
1156 }
1157
1158 void wxPyTimer::Notify() {
1159 if (!func || func == Py_None) {
1160 wxTimer::Notify();
1161 }
1162 else {
1163 wxPyBeginBlockThreads();
1164
1165 PyObject* result;
1166 PyObject* args = Py_BuildValue("()");
1167
1168 result = PyEval_CallObject(func, args);
1169 Py_DECREF(args);
1170 if (result) {
1171 Py_DECREF(result);
1172 PyErr_Clear();
1173 } else {
1174 PyErr_Print();
1175 }
1176
1177 wxPyEndBlockThreads();
1178 }
1179 }
1180
1181
1182
1183 //---------------------------------------------------------------------------
1184 //---------------------------------------------------------------------------
1185 // Convert a wxList to a Python List
1186
1187 PyObject* wxPy_ConvertList(wxListBase* list, const char* className) {
1188 PyObject* pyList;
1189 PyObject* pyObj;
1190 wxObject* wxObj;
1191 wxNode* node = list->First();
1192
1193 wxPyBeginBlockThreads();
1194 pyList = PyList_New(0);
1195 while (node) {
1196 wxObj = node->Data();
1197 pyObj = wxPyMake_wxObject(wxObj); //wxPyConstructObject(wxObj, className);
1198 PyList_Append(pyList, pyObj);
1199 node = node->Next();
1200 }
1201 wxPyEndBlockThreads();
1202 return pyList;
1203 }
1204
1205 //----------------------------------------------------------------------
1206
1207 long wxPyGetWinHandle(wxWindow* win) {
1208 #ifdef __WXMSW__
1209 return (long)win->GetHandle();
1210 #endif
1211
1212 // Find and return the actual X-Window.
1213 #ifdef __WXGTK__
1214 if (win->m_wxwindow) {
1215 GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window;
1216 if (bwin) {
1217 return (long)bwin->xwindow;
1218 }
1219 }
1220 #endif
1221 return 0;
1222 }
1223
1224 //----------------------------------------------------------------------
1225 // Some helper functions for typemaps in my_typemaps.i, so they won't be
1226 // included in every file...
1227
1228
1229 byte* byte_LIST_helper(PyObject* source) {
1230 if (!PyList_Check(source)) {
1231 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1232 return NULL;
1233 }
1234 int count = PyList_Size(source);
1235 byte* temp = new byte[count];
1236 if (! temp) {
1237 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1238 return NULL;
1239 }
1240 for (int x=0; x<count; x++) {
1241 PyObject* o = PyList_GetItem(source, x);
1242 if (! PyInt_Check(o)) {
1243 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
1244 return NULL;
1245 }
1246 temp[x] = (byte)PyInt_AsLong(o);
1247 }
1248 return temp;
1249 }
1250
1251
1252 int* int_LIST_helper(PyObject* source) {
1253 if (!PyList_Check(source)) {
1254 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1255 return NULL;
1256 }
1257 int count = PyList_Size(source);
1258 int* temp = new int[count];
1259 if (! temp) {
1260 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1261 return NULL;
1262 }
1263 for (int x=0; x<count; x++) {
1264 PyObject* o = PyList_GetItem(source, x);
1265 if (! PyInt_Check(o)) {
1266 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
1267 return NULL;
1268 }
1269 temp[x] = PyInt_AsLong(o);
1270 }
1271 return temp;
1272 }
1273
1274
1275 long* long_LIST_helper(PyObject* source) {
1276 if (!PyList_Check(source)) {
1277 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1278 return NULL;
1279 }
1280 int count = PyList_Size(source);
1281 long* temp = new long[count];
1282 if (! temp) {
1283 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1284 return NULL;
1285 }
1286 for (int x=0; x<count; x++) {
1287 PyObject* o = PyList_GetItem(source, x);
1288 if (! PyInt_Check(o)) {
1289 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
1290 return NULL;
1291 }
1292 temp[x] = PyInt_AsLong(o);
1293 }
1294 return temp;
1295 }
1296
1297
1298 char** string_LIST_helper(PyObject* source) {
1299 if (!PyList_Check(source)) {
1300 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1301 return NULL;
1302 }
1303 int count = PyList_Size(source);
1304 char** temp = new char*[count];
1305 if (! temp) {
1306 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1307 return NULL;
1308 }
1309 for (int x=0; x<count; x++) {
1310 PyObject* o = PyList_GetItem(source, x);
1311 if (! PyString_Check(o)) {
1312 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
1313 return NULL;
1314 }
1315 temp[x] = PyString_AsString(o);
1316 }
1317 return temp;
1318 }
1319
1320 //--------------------------------
1321 // Part of patch from Tim Hochberg
1322 static inline bool wxPointFromObjects(PyObject* o1, PyObject* o2, wxPoint* point) {
1323 if (PyInt_Check(o1) && PyInt_Check(o2)) {
1324 point->x = PyInt_AS_LONG(o1);
1325 point->y = PyInt_AS_LONG(o2);
1326 return true;
1327 }
1328 if (PyFloat_Check(o1) && PyFloat_Check(o2)) {
1329 point->x = (int)PyFloat_AS_DOUBLE(o1);
1330 point->y = (int)PyFloat_AS_DOUBLE(o2);
1331 return true;
1332 }
1333 if (PyInstance_Check(o1) || PyInstance_Check(o2)) {
1334 // Disallow instances because they can cause havok
1335 return false;
1336 }
1337 if (PyNumber_Check(o1) && PyNumber_Check(o2)) {
1338 // I believe this excludes instances, so this should be safe without INCREFFing o1 and o2
1339 point->x = PyInt_AsLong(o1);
1340 point->y = PyInt_AsLong(o2);
1341 return true;
1342 }
1343 return false;
1344 }
1345
1346
1347 wxPoint* wxPoint_LIST_helper(PyObject* source, int *count) {
1348 // Putting all of the declarations here allows
1349 // us to put the error handling all in one place.
1350 int x;
1351 wxPoint* temp;
1352 PyObject *o, *o1, *o2;
1353 bool isFast = PyList_Check(source) || PyTuple_Check(source);
1354
1355 if (!PySequence_Check(source)) {
1356 goto error0;
1357 }
1358
1359 // The length of the sequence is returned in count.
1360 *count = PySequence_Length(source);
1361 if (*count < 0) {
1362 goto error0;
1363 }
1364
1365 temp = new wxPoint[*count];
1366 if (!temp) {
1367 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1368 return NULL;
1369 }
1370 for (x=0; x<*count; x++) {
1371 // Get an item: try fast way first.
1372 if (isFast) {
1373 o = PySequence_Fast_GET_ITEM(source, x);
1374 }
1375 else {
1376 o = PySequence_GetItem(source, x);
1377 if (o == NULL) {
1378 goto error1;
1379 }
1380 }
1381
1382 // Convert o to wxPoint.
1383 if ((PyTuple_Check(o) && PyTuple_GET_SIZE(o) == 2) ||
1384 (PyList_Check(o) && PyList_GET_SIZE(o) == 2)) {
1385 o1 = PySequence_Fast_GET_ITEM(o, 0);
1386 o2 = PySequence_Fast_GET_ITEM(o, 1);
1387 if (!wxPointFromObjects(o1, o2, &temp[x])) {
1388 goto error2;
1389 }
1390 }
1391 else if (PyInstance_Check(o)) {
1392 wxPoint* pt;
1393 if (SWIG_GetPtrObj(o, (void **)&pt, "_wxPoint_p")) {
1394 goto error2;
1395 }
1396 temp[x] = *pt;
1397 }
1398 else if (PySequence_Check(o) && PySequence_Length(o) == 2) {
1399 o1 = PySequence_GetItem(o, 0);
1400 o2 = PySequence_GetItem(o, 1);
1401 if (!wxPointFromObjects(o1, o2, &temp[x])) {
1402 goto error3;
1403 }
1404 Py_DECREF(o1);
1405 Py_DECREF(o2);
1406 }
1407 else {
1408 goto error2;
1409 }
1410 // Clean up.
1411 if (!isFast)
1412 Py_DECREF(o);
1413 }
1414 return temp;
1415
1416 error3:
1417 Py_DECREF(o1);
1418 Py_DECREF(o2);
1419 error2:
1420 if (!isFast)
1421 Py_DECREF(o);
1422 error1:
1423 delete temp;
1424 error0:
1425 PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoints.");
1426 return NULL;
1427 }
1428 // end of patch
1429 //------------------------------
1430
1431
1432 wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
1433 if (!PyList_Check(source)) {
1434 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1435 return NULL;
1436 }
1437 int count = PyList_Size(source);
1438 wxBitmap** temp = new wxBitmap*[count];
1439 if (! temp) {
1440 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1441 return NULL;
1442 }
1443 for (int x=0; x<count; x++) {
1444 PyObject* o = PyList_GetItem(source, x);
1445 if (PyInstance_Check(o)) {
1446 wxBitmap* pt;
1447 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxBitmap_p")) {
1448 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
1449 return NULL;
1450 }
1451 temp[x] = pt;
1452 }
1453 else {
1454 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
1455 return NULL;
1456 }
1457 }
1458 return temp;
1459 }
1460
1461
1462
1463 wxString* wxString_LIST_helper(PyObject* source) {
1464 if (!PyList_Check(source)) {
1465 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1466 return NULL;
1467 }
1468 int count = PyList_Size(source);
1469 wxString* temp = new wxString[count];
1470 if (! temp) {
1471 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1472 return NULL;
1473 }
1474 for (int x=0; x<count; x++) {
1475 PyObject* o = PyList_GetItem(source, x);
1476 #if PYTHON_API_VERSION >= 1009
1477 if (! PyString_Check(o) && ! PyUnicode_Check(o)) {
1478 PyErr_SetString(PyExc_TypeError, "Expected a list of string or unicode objects.");
1479 return NULL;
1480 }
1481
1482 char* buff;
1483 int length;
1484 if (PyString_AsStringAndSize(o, &buff, &length) == -1)
1485 return NULL;
1486 temp[x] = wxString(buff, length);
1487 #else
1488 if (! PyString_Check(o)) {
1489 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
1490 return NULL;
1491 }
1492 temp[x] = PyString_AsString(o);
1493 #endif
1494 }
1495 return temp;
1496 }
1497
1498
1499 wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
1500 if (!PyList_Check(source)) {
1501 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1502 return NULL;
1503 }
1504 int count = PyList_Size(source);
1505 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
1506 if (! temp) {
1507 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1508 return NULL;
1509 }
1510 for (int x=0; x<count; x++) {
1511 PyObject* o = PyList_GetItem(source, x);
1512 if (PyInstance_Check(o)) {
1513 wxAcceleratorEntry* ae;
1514 if (SWIG_GetPtrObj(o, (void **) &ae,"_wxAcceleratorEntry_p")) {
1515 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
1516 return NULL;
1517 }
1518 temp[x] = *ae;
1519 }
1520 else if (PyTuple_Check(o)) {
1521 PyObject* o1 = PyTuple_GetItem(o, 0);
1522 PyObject* o2 = PyTuple_GetItem(o, 1);
1523 PyObject* o3 = PyTuple_GetItem(o, 2);
1524 temp[x].Set(PyInt_AsLong(o1), PyInt_AsLong(o2), PyInt_AsLong(o3));
1525 }
1526 else {
1527 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
1528 return NULL;
1529 }
1530 }
1531 return temp;
1532 }
1533
1534
1535 wxPen** wxPen_LIST_helper(PyObject* source) {
1536 if (!PyList_Check(source)) {
1537 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
1538 return NULL;
1539 }
1540 int count = PyList_Size(source);
1541 wxPen** temp = new wxPen*[count];
1542 if (!temp) {
1543 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
1544 return NULL;
1545 }
1546 for (int x=0; x<count; x++) {
1547 PyObject* o = PyList_GetItem(source, x);
1548 if (PyInstance_Check(o)) {
1549 wxPen* pt;
1550 if (SWIG_GetPtrObj(o, (void **) &pt,"_wxPen_p")) {
1551 delete temp;
1552 PyErr_SetString(PyExc_TypeError,"Expected _wxPen_p.");
1553 return NULL;
1554 }
1555 temp[x] = pt;
1556 }
1557 else {
1558 delete temp;
1559 PyErr_SetString(PyExc_TypeError, "Expected a list of wxPens.");
1560 return NULL;
1561 }
1562 }
1563 return temp;
1564 }
1565
1566
1567 bool _2int_seq_helper(PyObject* source, int* i1, int* i2) {
1568 bool isFast = PyList_Check(source) || PyTuple_Check(source);
1569 PyObject *o1, *o2;
1570
1571 if (!PySequence_Check(source) || PySequence_Length(source) != 2)
1572 return FALSE;
1573
1574 if (isFast) {
1575 o1 = PySequence_Fast_GET_ITEM(source, 0);
1576 o2 = PySequence_Fast_GET_ITEM(source, 1);
1577 }
1578 else {
1579 o1 = PySequence_GetItem(source, 0);
1580 o2 = PySequence_GetItem(source, 1);
1581 }
1582
1583 *i1 = PyInt_AsLong(o1);
1584 *i2 = PyInt_AsLong(o2);
1585
1586 if (! isFast) {
1587 Py_DECREF(o1);
1588 Py_DECREF(o2);
1589 }
1590 return TRUE;
1591 }
1592
1593
1594 bool _4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4) {
1595 bool isFast = PyList_Check(source) || PyTuple_Check(source);
1596 PyObject *o1, *o2, *o3, *o4;
1597
1598 if (!PySequence_Check(source) || PySequence_Length(source) != 4)
1599 return FALSE;
1600
1601 if (isFast) {
1602 o1 = PySequence_Fast_GET_ITEM(source, 0);
1603 o2 = PySequence_Fast_GET_ITEM(source, 1);
1604 o3 = PySequence_Fast_GET_ITEM(source, 2);
1605 o4 = PySequence_Fast_GET_ITEM(source, 3);
1606 }
1607 else {
1608 o1 = PySequence_GetItem(source, 0);
1609 o2 = PySequence_GetItem(source, 1);
1610 o3 = PySequence_GetItem(source, 2);
1611 o4 = PySequence_GetItem(source, 3);
1612 }
1613
1614 *i1 = PyInt_AsLong(o1);
1615 *i2 = PyInt_AsLong(o2);
1616 *i3 = PyInt_AsLong(o3);
1617 *i4 = PyInt_AsLong(o4);
1618
1619 if (! isFast) {
1620 Py_DECREF(o1);
1621 Py_DECREF(o2);
1622 Py_DECREF(o3);
1623 Py_DECREF(o4);
1624 }
1625 return TRUE;
1626 }
1627
1628
1629 //----------------------------------------------------------------------
1630
1631 bool wxSize_helper(PyObject* source, wxSize** obj) {
1632
1633 // If source is an object instance then it may already be the right type
1634 if (PyInstance_Check(source)) {
1635 wxSize* ptr;
1636 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxSize_p"))
1637 goto error;
1638 *obj = ptr;
1639 return TRUE;
1640 }
1641 // otherwise a 2-tuple of integers is expected
1642 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
1643 PyObject* o1 = PySequence_GetItem(source, 0);
1644 PyObject* o2 = PySequence_GetItem(source, 1);
1645 **obj = wxSize(PyInt_AsLong(o1), PyInt_AsLong(o2));
1646 return TRUE;
1647 }
1648
1649 error:
1650 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxSize object.");
1651 return FALSE;
1652 }
1653
1654 bool wxPoint_helper(PyObject* source, wxPoint** obj) {
1655
1656 // If source is an object instance then it may already be the right type
1657 if (PyInstance_Check(source)) {
1658 wxPoint* ptr;
1659 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint_p"))
1660 goto error;
1661 *obj = ptr;
1662 return TRUE;
1663 }
1664 // otherwise a length-2 sequence of integers is expected
1665 if (PySequence_Check(source) && PySequence_Length(source) == 2) {
1666 PyObject* o1 = PySequence_GetItem(source, 0);
1667 PyObject* o2 = PySequence_GetItem(source, 1);
1668 // This should really check for integers, not numbers -- but that would break code.
1669 if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) {
1670 Py_DECREF(o1);
1671 Py_DECREF(o2);
1672 goto error;
1673 }
1674 **obj = wxPoint(PyInt_AsLong(o1), PyInt_AsLong(o2));
1675 Py_DECREF(o1);
1676 Py_DECREF(o2);
1677 return TRUE;
1678 }
1679 error:
1680 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of integers or a wxPoint object.");
1681 return FALSE;
1682 }
1683
1684
1685
1686 bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj) {
1687
1688 // If source is an object instance then it may already be the right type
1689 if (PyInstance_Check(source)) {
1690 wxRealPoint* ptr;
1691 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRealPoint_p"))
1692 goto error;
1693 *obj = ptr;
1694 return TRUE;
1695 }
1696 // otherwise a 2-tuple of floats is expected
1697 else if (PySequence_Check(source) && PyObject_Length(source) == 2) {
1698 PyObject* o1 = PySequence_GetItem(source, 0);
1699 PyObject* o2 = PySequence_GetItem(source, 1);
1700 **obj = wxRealPoint(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2));
1701 return TRUE;
1702 }
1703
1704 error:
1705 PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxRealPoint object.");
1706 return FALSE;
1707 }
1708
1709
1710
1711
1712 bool wxRect_helper(PyObject* source, wxRect** obj) {
1713
1714 // If source is an object instance then it may already be the right type
1715 if (PyInstance_Check(source)) {
1716 wxRect* ptr;
1717 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxRect_p"))
1718 goto error;
1719 *obj = ptr;
1720 return TRUE;
1721 }
1722 // otherwise a 4-tuple of integers is expected
1723 else if (PySequence_Check(source) && PyObject_Length(source) == 4) {
1724 PyObject* o1 = PySequence_GetItem(source, 0);
1725 PyObject* o2 = PySequence_GetItem(source, 1);
1726 PyObject* o3 = PySequence_GetItem(source, 2);
1727 PyObject* o4 = PySequence_GetItem(source, 3);
1728 **obj = wxRect(PyInt_AsLong(o1), PyInt_AsLong(o2),
1729 PyInt_AsLong(o3), PyInt_AsLong(o4));
1730 return TRUE;
1731 }
1732
1733 error:
1734 PyErr_SetString(PyExc_TypeError, "Expected a 4-tuple of integers or a wxRect object.");
1735 return FALSE;
1736 }
1737
1738
1739
1740 bool wxColour_helper(PyObject* source, wxColour** obj) {
1741
1742 // If source is an object instance then it may already be the right type
1743 if (PyInstance_Check(source)) {
1744 wxColour* ptr;
1745 if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxColour_p"))
1746 goto error;
1747 *obj = ptr;
1748 return TRUE;
1749 }
1750 // otherwise a string is expected
1751 else if (PyString_Check(source)) {
1752 wxString spec = PyString_AS_STRING(source);
1753 if (spec[0U] == '#' && spec.Length() == 7) { // It's #RRGGBB
1754 char* junk;
1755 int red = strtol(spec.Mid(1,2), &junk, 16);
1756 int green = strtol(spec.Mid(3,2), &junk, 16);
1757 int blue = strtol(spec.Mid(5,2), &junk, 16);
1758 **obj = wxColour(red, green, blue);
1759 return TRUE;
1760 }
1761 else { // it's a colour name
1762 **obj = wxColour(spec);
1763 return TRUE;
1764 }
1765 }
1766
1767 error:
1768 PyErr_SetString(PyExc_TypeError, "Expected a wxColour object or a string containing a colour name or '#RRGGBB'.");
1769 return FALSE;
1770 }
1771
1772
1773 //----------------------------------------------------------------------
1774
1775 PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) {
1776
1777 PyObject* list = PyList_New(0);
1778 for (size_t i=0; i < arr.GetCount(); i++) {
1779 PyObject* str = PyString_FromString(arr[i].c_str());
1780 PyList_Append(list, str);
1781 Py_DECREF(str);
1782 }
1783 return list;
1784 }
1785
1786
1787 PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) {
1788
1789 PyObject* list = PyList_New(0);
1790 for (size_t i=0; i < arr.GetCount(); i++) {
1791 PyObject* number = PyInt_FromLong(arr[i]);
1792 PyList_Append(list, number);
1793 Py_DECREF(number);
1794 }
1795 return list;
1796 }
1797
1798
1799 //----------------------------------------------------------------------
1800 //----------------------------------------------------------------------
1801
1802
1803
1804