]> git.saurik.com Git - wxWidgets.git/blame - utils/wxPython/src/helpers.cpp
updated version number for DLL name
[wxWidgets.git] / utils / wxPython / src / helpers.cpp
CommitLineData
7bf85405
RD
1/////////////////////////////////////////////////////////////////////////////
2// Name: helpers.cpp
03e9bead 3// Purpose: Helper functions/classes for the wxPython extension module
7bf85405
RD
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
21f4bf45 13
08127323 14#ifdef __WXGTK__
efc5f224 15#include <gtk/gtk.h>
08127323
RD
16#endif
17
7bf85405
RD
18#undef DEBUG
19#include <Python.h>
20#include "helpers.h"
af309447
RD
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
dd9a3de8 29#include <wx/module.h>
7bf85405 30
cf694132 31
7bf85405
RD
32//---------------------------------------------------------------------------
33
34//wxHashTable* wxPyWindows = NULL;
35
36
37wxPoint wxPyDefaultPosition; //wxDefaultPosition);
38wxSize wxPyDefaultSize; //wxDefaultSize);
39wxString wxPyEmptyStr("");
40
41
42
21f4bf45 43#ifdef __WXMSW__ // If building for win32...
21f4bf45
RD
44//----------------------------------------------------------------------
45// This gets run when the DLL is loaded. We just need to save a handle.
46//----------------------------------------------------------------------
9c039d08 47
21f4bf45
RD
48BOOL WINAPI DllMain(
49 HINSTANCE hinstDLL, // handle to DLL module
50 DWORD fdwReason, // reason for calling function
51 LPVOID lpvReserved // reserved
52 )
53{
af309447 54 wxSetInstance(hinstDLL);
21f4bf45
RD
55 return 1;
56}
57#endif
58
7bf85405
RD
59//----------------------------------------------------------------------
60// Class for implementing the wxp main application shell.
61//----------------------------------------------------------------------
62
63wxPyApp *wxPythonApp = NULL; // Global instance of application object
64
65
cf694132
RD
66wxPyApp::wxPyApp() {
67// printf("**** ctor\n");
68}
69
70wxPyApp::~wxPyApp() {
71// printf("**** dtor\n");
72}
73
74
7bf85405
RD
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 = wxApp::MainLoop();
8bf5d46e
RD
82//# AfterMainLoop();
83 wxPythonApp->OnExit(); //#
7bf85405
RD
84 return retval;
85}
86
af309447 87
8bf5d46e
RD
88//# void wxPyApp::AfterMainLoop(void) {
89// // more stuff from wxEntry...
0d6f9504 90
8bf5d46e
RD
91// if (wxPythonApp->GetTopWindow()) {
92// // Forcibly delete the window.
93// if (wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
94// wxPythonApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog))) {
7bf85405 95
8bf5d46e
RD
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
7bf85405 107
8bf5d46e
RD
108// wxPythonApp->OnExit();
109// wxApp::CleanUp();
110// // delete wxPythonApp;
111// }
7bf85405
RD
112
113
fb5e0af0 114//---------------------------------------------------------------------
7bf85405
RD
115// a few native methods to add to the module
116//----------------------------------------------------------------------
117
118
0d6f9504 119// This is where we pick up the first part of the wxEntry functionality...
4464bbee 120// The rest is in __wxStart and AfterMainLoop. This function is called when
8bf5d46e 121// wxcmodule is imported. (Before there is a wxApp object.)
0d6f9504 122void __wxPreStart()
7bf85405 123{
0d6f9504
RD
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;
7bf85405 129
7bf85405 130#ifdef __WXMSW__
9c039d08 131 wxApp::Initialize();
7bf85405 132#endif
21f4bf45 133
08127323 134#ifdef __WXGTK__
fb5e0af0
RD
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
08127323 143 gtk_set_locale();
8bf5d46e 144 if (!wxOKlibc()) wxConvCurrent = &wxConvLocal;
0d6f9504 145 gtk_init( &argc, &argv );
8bf5d46e 146 wxSetDetectableAutoRepeat( TRUE );
0d6f9504 147 delete [] argv;
7bf85405 148
08127323 149 wxApp::Initialize(); // may return FALSE. Should we check?
7bf85405
RD
150#endif
151
0d6f9504
RD
152}
153
154
cf694132 155#ifdef WXP_WITH_THREAD
bb0054cd
RD
156PyThreadState* wxPyEventThreadState = NULL;
157bool wxPyInEvent = false;
cf694132 158#endif
0d6f9504
RD
159static char* __nullArgv[1] = { 0 };
160
8bf5d46e
RD
161
162
0d6f9504
RD
163// Start the user application, user App's OnInit method is a parameter here
164PyObject* __wxStart(PyObject* /* self */, PyObject* args)
165{
166 PyObject* onInitFunc = NULL;
167 PyObject* arglist;
168 PyObject* result;
169 long bResult;
170
cf694132 171#ifdef WXP_WITH_THREAD
bb0054cd 172 wxPyEventThreadState = PyThreadState_Get();
cf694132 173#endif
0d6f9504
RD
174
175 if (!PyArg_ParseTuple(args, "O", &onInitFunc))
176 return NULL;
177
178 if (wxTopLevelWindows.Number() > 0) {
179 PyErr_SetString(PyExc_TypeError, "Only 1 wxApp per process!");
180 return NULL;
181 }
182
183
184 // This is the next part of the wxEntry functionality...
185 wxPythonApp->argc = 0;
cf694132 186 wxPythonApp->argv = NULL;
0d6f9504
RD
187 wxPythonApp->OnInitGui();
188
7bf85405
RD
189
190 // Call the Python App's OnInit function
191 arglist = PyTuple_New(0);
192 result = PyEval_CallObject(onInitFunc, arglist);
8bf5d46e
RD
193 if (!result) { // an exception was raised.
194 return NULL;
7bf85405
RD
195 }
196
197 if (! PyInt_Check(result)) {
198 PyErr_SetString(PyExc_TypeError, "OnInit should return a boolean value");
199 return NULL;
200 }
201 bResult = PyInt_AS_LONG(result);
202 if (! bResult) {
7bf85405
RD
203 PyErr_SetString(PyExc_SystemExit, "OnInit returned false, exiting...");
204 return NULL;
205 }
206
13dfc243 207#ifdef __WXGTK__
fb5e0af0 208 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
13dfc243 209#endif
fb5e0af0 210
7bf85405
RD
211 Py_INCREF(Py_None);
212 return Py_None;
213}
214
215
7bf85405
RD
216
217
218
219PyObject* wxPython_dict;
220PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
221{
222
223 if (!PyArg_ParseTuple(args, "O", &wxPython_dict))
224 return NULL;
225
226 if (!PyDict_Check(wxPython_dict)) {
227 PyErr_SetString(PyExc_TypeError, "_wxSetDictionary must have dictionary object!");
228 return NULL;
229 }
230#ifdef __WXMOTIF__
21f4bf45
RD
231#define wxPlatform "__WXMOTIF__"
232#endif
233#ifdef __WXQT__
234#define wxPlatform "__WXQT__"
7bf85405
RD
235#endif
236#ifdef __WXGTK__
21f4bf45 237#define wxPlatform "__WXGTK__"
7bf85405
RD
238#endif
239#if defined(__WIN32__) || defined(__WXMSW__)
fb5e0af0 240#define wxPlatform "__WXMSW__"
7bf85405
RD
241#endif
242#ifdef __WXMAC__
21f4bf45 243#define wxPlatform "__WXMAC__"
7bf85405
RD
244#endif
245
246 PyDict_SetItemString(wxPython_dict, "wxPlatform", PyString_FromString(wxPlatform));
247
248 Py_INCREF(Py_None);
249 return Py_None;
250}
251
252
253//---------------------------------------------------------------------------
254
7bf85405
RD
255PyObject* wxPyConstructObject(void* ptr, char* className)
256{
9c039d08 257 char buff[64]; // should always be big enough...
7bf85405
RD
258 char swigptr[64];
259
260 sprintf(buff, "_%s_p", className);
261 SWIG_MakePtr(swigptr, ptr, buff);
262
263 sprintf(buff, "%sPtr", className);
264 PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff);
265 if (! classobj) {
266 Py_INCREF(Py_None);
267 return Py_None;
268 }
269
270 PyObject* arg = Py_BuildValue("(s)", swigptr);
271 PyObject* obj = PyInstance_New(classobj, arg, NULL);
272 Py_DECREF(arg);
273
274 return obj;
275}
276
277
cf694132
RD
278
279wxPyCallback::wxPyCallback(PyObject* func) {
280 m_func = func;
281 Py_INCREF(m_func);
282}
283
284wxPyCallback::~wxPyCallback() {
285#ifdef WXP_WITH_THREAD
bb0054cd
RD
286 //if (! wxPyInEvent)
287 PyEval_RestoreThread(wxPyEventThreadState);
cf694132
RD
288#endif
289
290 Py_DECREF(m_func);
291
292#ifdef WXP_WITH_THREAD
bb0054cd
RD
293 //if (! wxPyInEvent)
294 PyEval_SaveThread();
cf694132
RD
295#endif
296}
297
298
299
300
7bf85405
RD
301// This function is used for all events destined for Python event handlers.
302void wxPyCallback::EventThunker(wxEvent& event) {
303 wxPyCallback* cb = (wxPyCallback*)event.m_callbackUserData;
304 PyObject* func = cb->m_func;
305 PyObject* result;
306 PyObject* arg;
307 PyObject* tuple;
308
cf694132
RD
309
310#ifdef WXP_WITH_THREAD
bb0054cd
RD
311 PyEval_RestoreThread(wxPyEventThreadState);
312 wxPyInEvent = true;
cf694132 313#endif
7bf85405
RD
314 arg = wxPyConstructObject((void*)&event, event.GetClassInfo()->GetClassName());
315
316 tuple = PyTuple_New(1);
317 PyTuple_SET_ITEM(tuple, 0, arg);
318 result = PyEval_CallObject(func, tuple);
7bf85405
RD
319 Py_DECREF(tuple);
320 if (result) {
321 Py_DECREF(result);
322 PyErr_Clear();
323 } else {
324 PyErr_Print();
325 }
cf694132
RD
326#ifdef WXP_WITH_THREAD
327 PyEval_SaveThread();
bb0054cd 328 wxPyInEvent = false;
cf694132 329#endif
7bf85405
RD
330}
331
332
333//---------------------------------------------------------------------------
334
8bf5d46e
RD
335// wxPyMenu::wxPyMenu(const wxString& title, PyObject* _func)
336// : wxMenu(title, (wxFunction)(func ? MenuCallback : NULL)), func(0) {
337
338// if (_func) {
339// func = _func;
340// Py_INCREF(func);
341// }
342// }
343
344// wxPyMenu::~wxPyMenu() {
345// #ifdef WXP_WITH_THREAD
346// //if (! wxPyInEvent)
347// PyEval_RestoreThread(wxPyEventThreadState);
348// #endif
349
350// if (func)
351// Py_DECREF(func);
352
353// #ifdef WXP_WITH_THREAD
354// //if (! wxPyInEvent)
355// PyEval_SaveThread();
356// #endif
357// }
358
359
360// void wxPyMenu::MenuCallback(wxMenu& menu, wxCommandEvent& evt) {
361// PyObject* evtobj;
362// PyObject* menuobj;
363// PyObject* func;
364// PyObject* args;
365// PyObject* res;
366
367// #ifdef WXP_WITH_THREAD
368// PyEval_RestoreThread(wxPyEventThreadState);
369// wxPyInEvent = true;
370// #endif
371// evtobj = wxPyConstructObject((void*)&evt, "wxCommandEvent");
372// menuobj = wxPyConstructObject((void*)&menu, "wxMenu");
373// if (PyErr_Occurred()) {
374// // bail out if a problem
375// PyErr_Print();
376// goto done;
377// }
378// // Now call the callback...
379// func = ((wxPyMenu*)&menu)->func;
380// args = PyTuple_New(2);
381// PyTuple_SET_ITEM(args, 0, menuobj);
382// PyTuple_SET_ITEM(args, 1, evtobj);
383// res = PyEval_CallObject(func, args);
384// Py_DECREF(args);
385// Py_XDECREF(res); /* In case res is a NULL pointer */
386// done:
387// #ifdef WXP_WITH_THREAD
388// PyEval_SaveThread();
389// wxPyInEvent = false;
390// #endif
391// return;
392// }
714e6a9e 393
7bf85405
RD
394
395//---------------------------------------------------------------------------
396
397wxPyTimer::wxPyTimer(PyObject* callback) {
398 func = callback;
399 Py_INCREF(func);
400}
401
402wxPyTimer::~wxPyTimer() {
bb0054cd
RD
403#ifdef WXP_WITH_THREAD
404 //if (! wxPyInEvent)
405 PyEval_RestoreThread(wxPyEventThreadState);
406#endif
407
7bf85405 408 Py_DECREF(func);
bb0054cd
RD
409
410#ifdef WXP_WITH_THREAD
411 //if (! wxPyInEvent)
412 PyEval_SaveThread();
413#endif
7bf85405
RD
414}
415
416void wxPyTimer::Notify() {
cf694132 417#ifdef WXP_WITH_THREAD
bb0054cd
RD
418 PyEval_RestoreThread(wxPyEventThreadState);
419 wxPyInEvent = true;
cf694132 420#endif
7bf85405
RD
421 PyObject* result;
422 PyObject* args = Py_BuildValue("()");
423
424 result = PyEval_CallObject(func, args);
425 Py_DECREF(args);
426 if (result) {
427 Py_DECREF(result);
428 PyErr_Clear();
429 } else {
430 PyErr_Print();
431 }
cf694132
RD
432#ifdef WXP_WITH_THREAD
433 PyEval_SaveThread();
bb0054cd 434 wxPyInEvent = false;
cf694132 435#endif
7bf85405
RD
436}
437
438
cf694132
RD
439//----------------------------------------------------------------------
440
441IMPLEMENT_DYNAMIC_CLASS(wxPyEvent, wxCommandEvent)
442
443wxPyEvent::wxPyEvent(wxEventType commandType, PyObject* userData)
444 : wxCommandEvent(commandType), m_userData(Py_None)
445{
446 m_userData = userData;
447 if (m_userData != Py_None) {
448 Py_INCREF(m_userData);
449 }
450}
451
452
453wxPyEvent::~wxPyEvent() {
bb0054cd
RD
454#ifdef WXP_WITH_THREAD
455 //if (! wxPyInEvent)
456 PyEval_RestoreThread(wxPyEventThreadState);
457#endif
cf694132
RD
458 if (m_userData != Py_None) {
459 Py_DECREF(m_userData);
460 m_userData = Py_None;
461 }
bb0054cd
RD
462#ifdef WXP_WITH_THREAD
463 //if (! wxPyInEvent)
464 PyEval_SaveThread();
465#endif
cf694132
RD
466}
467
468
469void wxPyEvent::SetUserData(PyObject* userData) {
470 if (m_userData != Py_None) {
471 Py_DECREF(m_userData);
472 m_userData = Py_None;
473 }
474 m_userData = userData;
475 if (m_userData != Py_None) {
476 Py_INCREF(m_userData);
477 }
478}
479
480
481PyObject* wxPyEvent::GetUserData() {
482 return m_userData;
483}
7bf85405 484
7bf85405
RD
485//----------------------------------------------------------------------
486//----------------------------------------------------------------------
487// Some helper functions for typemaps in my_typemaps.i, so they won't be
488// imcluded in every file...
489
490
b639c3c5
RD
491byte* byte_LIST_helper(PyObject* source) {
492 if (!PyList_Check(source)) {
493 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
494 return NULL;
495 }
496 int count = PyList_Size(source);
497 byte* temp = new byte[count];
498 if (! temp) {
499 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
500 return NULL;
501 }
502 for (int x=0; x<count; x++) {
503 PyObject* o = PyList_GetItem(source, x);
504 if (! PyInt_Check(o)) {
505 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
506 return NULL;
507 }
508 temp[x] = (byte)PyInt_AsLong(o);
509 }
510 return temp;
511}
512
513
7bf85405
RD
514int* int_LIST_helper(PyObject* source) {
515 if (!PyList_Check(source)) {
516 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
517 return NULL;
518 }
519 int count = PyList_Size(source);
520 int* temp = new int[count];
521 if (! temp) {
522 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
523 return NULL;
524 }
525 for (int x=0; x<count; x++) {
526 PyObject* o = PyList_GetItem(source, x);
527 if (! PyInt_Check(o)) {
528 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
529 return NULL;
530 }
531 temp[x] = PyInt_AsLong(o);
532 }
533 return temp;
534}
535
536
537long* long_LIST_helper(PyObject* source) {
538 if (!PyList_Check(source)) {
539 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
540 return NULL;
541 }
542 int count = PyList_Size(source);
543 long* temp = new long[count];
544 if (! temp) {
545 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
546 return NULL;
547 }
548 for (int x=0; x<count; x++) {
549 PyObject* o = PyList_GetItem(source, x);
550 if (! PyInt_Check(o)) {
551 PyErr_SetString(PyExc_TypeError, "Expected a list of integers.");
552 return NULL;
553 }
554 temp[x] = PyInt_AsLong(o);
555 }
556 return temp;
557}
558
559
560char** string_LIST_helper(PyObject* source) {
561 if (!PyList_Check(source)) {
562 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
563 return NULL;
564 }
565 int count = PyList_Size(source);
566 char** temp = new char*[count];
567 if (! temp) {
568 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
569 return NULL;
570 }
571 for (int x=0; x<count; x++) {
572 PyObject* o = PyList_GetItem(source, x);
573 if (! PyString_Check(o)) {
574 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
575 return NULL;
576 }
577 temp[x] = PyString_AsString(o);
578 }
579 return temp;
580}
581
582
583
584wxPoint* wxPoint_LIST_helper(PyObject* source) {
585 if (!PyList_Check(source)) {
586 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
587 return NULL;
588 }
589 int count = PyList_Size(source);
590 wxPoint* temp = new wxPoint[count];
591 if (! temp) {
592 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
593 return NULL;
594 }
595 for (int x=0; x<count; x++) {
596 PyObject* o = PyList_GetItem(source, x);
597 if (PyString_Check(o)) {
598 char* st = PyString_AsString(o);
599 wxPoint* pt;
600 if (SWIG_GetPtr(st,(void **) &pt,"_wxPoint_p")) {
601 PyErr_SetString(PyExc_TypeError,"Expected _wxPoint_p.");
602 return NULL;
603 }
604 temp[x] = *pt;
605 }
606 else if (PyTuple_Check(o)) {
607 PyObject* o1 = PyTuple_GetItem(o, 0);
608 PyObject* o2 = PyTuple_GetItem(o, 1);
609
610 temp[x].x = PyInt_AsLong(o1);
611 temp[x].y = PyInt_AsLong(o2);
612 }
613 else {
614 PyErr_SetString(PyExc_TypeError, "Expected a list of 2-tuples or wxPoints.");
615 return NULL;
616 }
617 }
618 return temp;
619}
620
621
622wxBitmap** wxBitmap_LIST_helper(PyObject* source) {
623 if (!PyList_Check(source)) {
624 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
625 return NULL;
626 }
627 int count = PyList_Size(source);
628 wxBitmap** temp = new wxBitmap*[count];
629 if (! temp) {
630 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
631 return NULL;
632 }
633 for (int x=0; x<count; x++) {
634 PyObject* o = PyList_GetItem(source, x);
635 if (PyString_Check(o)) {
636 char* st = PyString_AsString(o);
637 wxBitmap* pt;
638 if (SWIG_GetPtr(st,(void **) &pt,"_wxBitmap_p")) {
639 PyErr_SetString(PyExc_TypeError,"Expected _wxBitmap_p.");
640 return NULL;
641 }
642 temp[x] = pt;
643 }
644 else {
645 PyErr_SetString(PyExc_TypeError, "Expected a list of wxBitmaps.");
646 return NULL;
647 }
648 }
649 return temp;
650}
651
652
653
654wxString* wxString_LIST_helper(PyObject* source) {
655 if (!PyList_Check(source)) {
656 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
657 return NULL;
658 }
659 int count = PyList_Size(source);
660 wxString* temp = new wxString[count];
661 if (! temp) {
662 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
663 return NULL;
664 }
665 for (int x=0; x<count; x++) {
666 PyObject* o = PyList_GetItem(source, x);
667 if (! PyString_Check(o)) {
668 PyErr_SetString(PyExc_TypeError, "Expected a list of strings.");
669 return NULL;
670 }
671 temp[x] = PyString_AsString(o);
672 }
673 return temp;
674}
675
676
677wxAcceleratorEntry* wxAcceleratorEntry_LIST_helper(PyObject* source) {
678 if (!PyList_Check(source)) {
679 PyErr_SetString(PyExc_TypeError, "Expected a list object.");
680 return NULL;
681 }
682 int count = PyList_Size(source);
683 wxAcceleratorEntry* temp = new wxAcceleratorEntry[count];
684 if (! temp) {
685 PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
686 return NULL;
687 }
688 for (int x=0; x<count; x++) {
689 PyObject* o = PyList_GetItem(source, x);
690 if (PyString_Check(o)) {
691 char* st = PyString_AsString(o);
692 wxAcceleratorEntry* ae;
693 if (SWIG_GetPtr(st,(void **) &ae,"_wxAcceleratorEntry_p")) {
694 PyErr_SetString(PyExc_TypeError,"Expected _wxAcceleratorEntry_p.");
695 return NULL;
696 }
697 temp[x] = *ae;
698 }
699 else if (PyTuple_Check(o)) {
700 PyObject* o1 = PyTuple_GetItem(o, 0);
701 PyObject* o2 = PyTuple_GetItem(o, 1);
702 PyObject* o3 = PyTuple_GetItem(o, 2);
703
704 temp[x].m_flags = PyInt_AsLong(o1);
705 temp[x].m_keyCode = PyInt_AsLong(o2);
706 temp[x].m_command = PyInt_AsLong(o3);
707 }
708 else {
709 PyErr_SetString(PyExc_TypeError, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
710 return NULL;
711 }
712 }
713 return temp;
714}
715
bb0054cd
RD
716
717
718//----------------------------------------------------------------------
719//----------------------------------------------------------------------
720
721wxPyCallbackHelper::wxPyCallbackHelper() {
722 m_self = NULL;
723 m_lastFound = NULL;
724}
725
726
727wxPyCallbackHelper::~wxPyCallbackHelper() {
728#ifdef WXP_WITH_THREAD
729 PyEval_RestoreThread(wxPyEventThreadState);
730#endif
731
732 Py_XDECREF(m_self);
733
734#ifdef WXP_WITH_THREAD
735 PyEval_SaveThread();
736#endif
737}
738
739void wxPyCallbackHelper::setSelf(PyObject* self) {
740 m_self = self;
741 Py_INCREF(m_self);
742}
743
744
745
746bool wxPyCallbackHelper::findCallback(const wxString& name) {
747 m_lastFound = NULL;
748 if (m_self && PyObject_HasAttrString(m_self, (char*)name.c_str()))
749 m_lastFound = PyObject_GetAttrString(m_self, (char*)name.c_str());
750
751 return m_lastFound != NULL;
752}
753
754
755int wxPyCallbackHelper::callCallback(PyObject* argTuple) {
756 PyObject* result;
757 int retval = FALSE;
758
759 result = callCallbackObj(argTuple);
760 if (result) { // Assumes an integer return type...
761 retval = PyInt_AsLong(result);
762 Py_DECREF(result);
763 PyErr_Clear(); // forget about it if it's not...
764 }
765#ifdef WXP_WITH_THREAD
766 PyEval_SaveThread();
767#endif
768 return retval;
769}
770
771// Invoke the Python callable object, returning the raw PyObject return
772// value. Caller should DECREF the return value and also call PyEval_SaveThread.
773PyObject* wxPyCallbackHelper::callCallbackObj(PyObject* argTuple) {
774#ifdef WXP_WITH_THREAD
775 PyEval_RestoreThread(wxPyEventThreadState);
776#endif
777 PyObject* result;
778
779 result = PyEval_CallObject(m_lastFound, argTuple);
780 Py_DECREF(argTuple);
781 if (!result) {
782 PyErr_Print();
783 }
784 return result;
785}
786
787
788
789
790//----------------------------------------------------------------------
791//----------------------------------------------------------------------
7bf85405 792//----------------------------------------------------------------------
7bf85405 793
7bf85405 794
7bf85405 795