1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Helper functions/classes for the wxPython extenaion module
9 // Copyright: (c) 1998 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
13 #ifndef __wxp_helpers__
14 #define __wxp_helpers__
19 //----------------------------------------------------------------------
21 // if we want to handle threads and Python threads are available...
22 #if defined(WXP_USE_THREAD) && defined(WITH_THREAD)
24 #define WXP_WITH_THREAD
25 #define wxPy_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
26 #define wxPy_END_ALLOW_THREADS Py_END_ALLOW_THREADS
28 #else // no Python threads...
29 #undef WXP_WITH_THREAD
30 #define wxPy_BEGIN_ALLOW_THREADS
31 #define wxPy_END_ALLOW_THREADS
35 //---------------------------------------------------------------------------
37 #if defined(__WXMSW__)
38 # define HELPEREXPORT __declspec(dllexport)
43 //----------------------------------------------------------------------
45 class wxPyApp
: public wxApp
52 //# void AfterMainLoop(void);
55 extern wxPyApp
*wxPythonApp
;
57 //----------------------------------------------------------------------
60 PyObject
* __wxStart(PyObject
*, PyObject
* args
);
62 extern PyObject
* wxPython_dict
;
63 PyObject
* __wxSetDictionary(PyObject
*, PyObject
* args
);
65 void wxPyEventThunker(wxObject
*, wxEvent
& event
);
67 HELPEREXPORT PyObject
* wxPyConstructObject(void* ptr
, char* className
);
68 HELPEREXPORT
bool wxPyRestoreThread();
69 HELPEREXPORT
void wxPySaveThread(bool doSave
);
71 //----------------------------------------------------------------------
75 extern "C" void SWIG_MakePtr(char *, void *, char *);
76 extern "C" char *SWIG_GetPtr(char *, void **, char *);
77 extern "C" char *SWIG_GetPtrObj(PyObject
*obj
, void **ptr
, char *type
);
82 # pragma warning(disable:4800)
85 typedef unsigned char byte
;
88 // Non-const versions to keep SWIG happy.
89 extern wxPoint wxPyDefaultPosition
;
90 extern wxSize wxPyDefaultSize
;
91 extern wxString wxPyEmptyStr
;
93 //----------------------------------------------------------------------
95 class wxPyCallback
: public wxObject
{
97 wxPyCallback(PyObject
* func
);
100 void EventThunker(wxEvent
& event
);
105 //---------------------------------------------------------------------------
107 // class wxPyMenu : public wxMenu {
109 // wxPyMenu(const wxString& title = "", PyObject* func=NULL);
113 // static void MenuCallback(wxMenu& menu, wxCommandEvent& evt);
118 //---------------------------------------------------------------------------
120 class wxPyTimer
: public wxTimer
{
122 wxPyTimer(PyObject
* callback
);
131 //---------------------------------------------------------------------------
133 class wxPyEvent
: public wxCommandEvent
{
134 DECLARE_DYNAMIC_CLASS(wxPyEvent
)
136 wxPyEvent(wxEventType commandType
= wxEVT_NULL
, PyObject
* userData
= Py_None
);
139 void SetUserData(PyObject
* userData
);
140 PyObject
* GetUserData();
143 PyObject
* m_userData
;
150 //---------------------------------------------------------------------------
151 // This class holds an instance of a Python Shadow Class object and assists
152 // with looking up and invoking Python callback methods from C++ virtual
153 // method redirections. For all classes which have virtuals which should be
154 // overridable in wxPython, a new subclass is created that contains a
155 // wxPyCallbackHelper.
157 // **** This class should be combined with wxPyCallback defined above.
159 //---------------------------------------------------------------------------
161 class HELPEREXPORT wxPyCallbackHelper
{
163 wxPyCallbackHelper();
164 ~wxPyCallbackHelper();
166 void setSelf(PyObject
* self
);
168 bool findCallback(const wxString
& name
);
169 int callCallback(PyObject
* argTuple
);
170 PyObject
* callCallbackObj(PyObject
* argTuple
);
174 PyObject
* m_lastFound
;
179 //---------------------------------------------------------------------------
180 // These macros are used to implement the virtual methods that should
181 // redirect to a Python method if one exists. The names designate the
182 // return type, if any as well as any parameter types.
183 //---------------------------------------------------------------------------
186 void _setSelf(PyObject* self) { \
187 m_myInst.setSelf(self); \
189 private: wxPyCallbackHelper m_myInst;
191 //---------------------------------------------------------------------------
193 #define DEC_PYCALLBACK__(CBNAME) \
195 void base_##CBNAME();
198 #define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME) \
199 void CLASS::CBNAME() { \
200 bool doSave = wxPyRestoreThread(); \
201 if (m_myInst.findCallback(#CBNAME)) \
202 m_myInst.callCallback(Py_BuildValue("()")); \
205 wxPySaveThread(doSave); \
207 void CLASS::base_##CBNAME() { \
211 //---------------------------------------------------------------------------
213 #define DEC_PYCALLBACK_BOOL_INTINT(CBNAME) \
214 bool CBNAME(int a, int b); \
215 bool base_##CBNAME(int a, int b);
218 #define IMP_PYCALLBACK_BOOL_INTINT(CLASS, PCLASS, CBNAME) \
219 bool CLASS::CBNAME(int a, int b) { \
221 bool doSave = wxPyRestoreThread(); \
222 if (m_myInst.findCallback(#CBNAME)) \
223 rval = m_myInst.callCallback(Py_BuildValue("(ii)",a,b)); \
225 rval = PCLASS::CBNAME(a,b); \
226 wxPySaveThread(doSave); \
229 bool CLASS::base_##CBNAME(int a, int b) { \
230 return PCLASS::CBNAME(a,b); \
233 //---------------------------------------------------------------------------
235 #define DEC_PYCALLBACK_BOOL_INT(CBNAME) \
236 bool CBNAME(int a); \
237 bool base_##CBNAME(int a);
240 #define IMP_PYCALLBACK_BOOL_INT(CLASS, PCLASS, CBNAME) \
241 bool CLASS::CBNAME(int a) { \
243 bool doSave = wxPyRestoreThread(); \
244 if (m_myInst.findCallback(#CBNAME)) \
245 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
247 rval = PCLASS::CBNAME(a); \
248 wxPySaveThread(doSave); \
251 bool CLASS::base_##CBNAME(int a) { \
252 return PCLASS::CBNAME(a); \
255 //---------------------------------------------------------------------------
257 #define DEC_PYCALLBACK_BOOL_INT_pure(CBNAME) \
261 #define IMP_PYCALLBACK_BOOL_INT_pure(CLASS, PCLASS, CBNAME) \
262 bool CLASS::CBNAME(int a) { \
264 bool doSave = wxPyRestoreThread(); \
265 if (m_myInst.findCallback(#CBNAME)) \
266 rval = m_myInst.callCallback(Py_BuildValue("(i)",a)); \
268 wxPySaveThread(doSave); \
273 //---------------------------------------------------------------------------
275 #define DEC_PYCALLBACK__DC(CBNAME) \
276 void CBNAME(wxDC& a); \
277 void base_##CBNAME(wxDC& a);
280 #define IMP_PYCALLBACK__DC(CLASS, PCLASS, CBNAME) \
281 void CLASS::CBNAME(wxDC& a) { \
282 bool doSave = wxPyRestoreThread(); \
283 if (m_myInst.findCallback(#CBNAME)) \
284 m_myInst.callCallback(Py_BuildValue("(O)", \
285 wxPyConstructObject(&a, "wxDC"))); \
288 wxPySaveThread(doSave); \
290 void CLASS::base_##CBNAME(wxDC& a) { \
296 //---------------------------------------------------------------------------
298 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
299 void CBNAME(wxDC& a, bool b); \
300 void base_##CBNAME(wxDC& a, bool b);
303 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
304 void CLASS::CBNAME(wxDC& a, bool b) { \
305 bool doSave = wxPyRestoreThread(); \
306 if (m_myInst.findCallback(#CBNAME)) \
307 m_myInst.callCallback(Py_BuildValue("(Oi)", \
308 wxPyConstructObject(&a, "wxDC"), (int)b)); \
310 PCLASS::CBNAME(a, b); \
311 wxPySaveThread(doSave); \
313 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
314 PCLASS::CBNAME(a, b); \
317 //---------------------------------------------------------------------------
319 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
320 void CBNAME(wxDC& a, bool b); \
321 void base_##CBNAME(wxDC& a, bool b);
324 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
325 void CLASS::CBNAME(wxDC& a, bool b) { \
326 bool doSave = wxPyRestoreThread(); \
327 if (m_myInst.findCallback(#CBNAME)) \
328 m_myInst.callCallback(Py_BuildValue("(Oi)", \
329 wxPyConstructObject(&a, "wxDC"), (int)b)); \
331 PCLASS::CBNAME(a, b); \
332 wxPySaveThread(doSave); \
334 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
335 PCLASS::CBNAME(a, b); \
338 //---------------------------------------------------------------------------
340 #define DEC_PYCALLBACK__2DBL(CBNAME) \
341 void CBNAME(double a, double b); \
342 void base_##CBNAME(double a, double b);
345 #define IMP_PYCALLBACK__2DBL(CLASS, PCLASS, CBNAME) \
346 void CLASS::CBNAME(double a, double b) { \
347 bool doSave = wxPyRestoreThread(); \
348 if (m_myInst.findCallback(#CBNAME)) \
349 m_myInst.callCallback(Py_BuildValue("(dd)",a,b)); \
351 PCLASS::CBNAME(a, b); \
352 wxPySaveThread(doSave); \
354 void CLASS::base_##CBNAME(double a, double b) { \
355 PCLASS::CBNAME(a, b); \
358 //---------------------------------------------------------------------------
360 #define DEC_PYCALLBACK__2DBL2INT(CBNAME) \
361 void CBNAME(double a, double b, int c, int d); \
362 void base_##CBNAME(double a, double b, int c, int d);
365 #define IMP_PYCALLBACK__2DBL2INT(CLASS, PCLASS, CBNAME) \
366 void CLASS::CBNAME(double a, double b, int c, int d) { \
367 bool doSave = wxPyRestoreThread(); \
368 if (m_myInst.findCallback(#CBNAME)) \
369 m_myInst.callCallback(Py_BuildValue("(ddii)", \
372 PCLASS::CBNAME(a, b, c, d); \
373 wxPySaveThread(doSave); \
375 void CLASS::base_##CBNAME(double a, double b, int c, int d) { \
376 PCLASS::CBNAME(a, b, c, d); \
379 //---------------------------------------------------------------------------
381 #define DEC_PYCALLBACK__DC4DBLBOOL(CBNAME) \
382 void CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
383 void base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
386 #define IMP_PYCALLBACK__DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
387 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
388 bool doSave = wxPyRestoreThread(); \
389 if (m_myInst.findCallback(#CBNAME)) \
390 m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
391 wxPyConstructObject(&a, "wxDC"), \
392 b, c, d, e, (int)f)); \
394 PCLASS::CBNAME(a, b, c, d, e, f); \
395 wxPySaveThread(doSave); \
397 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
398 PCLASS::CBNAME(a, b, c, d, e, f); \
401 //---------------------------------------------------------------------------
403 #define DEC_PYCALLBACK_BOOL_DC4DBLBOOL(CBNAME) \
404 bool CBNAME(wxDC& a, double b, double c, double d, double e, bool f); \
405 bool base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f);
408 #define IMP_PYCALLBACK_BOOL_DC4DBLBOOL(CLASS, PCLASS, CBNAME) \
409 bool CLASS::CBNAME(wxDC& a, double b, double c, double d, double e, bool f) { \
410 bool doSave = wxPyRestoreThread(); \
411 if (m_myInst.findCallback(#CBNAME)) \
412 return m_myInst.callCallback(Py_BuildValue("(Oddddi)", \
413 wxPyConstructObject(&a, "wxDC"), \
414 b, c, d, e, (int)f)); \
416 return PCLASS::CBNAME(a, b, c, d, e, f); \
417 wxPySaveThread(doSave); \
419 bool CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e, bool f) {\
420 return PCLASS::CBNAME(a, b, c, d, e, f); \
423 //---------------------------------------------------------------------------
425 #define DEC_PYCALLBACK__BOOL2DBL2INT(CBNAME) \
426 void CBNAME(bool a, double b, double c, int d, int e); \
427 void base_##CBNAME(bool a, double b, double c, int d, int e);
430 #define IMP_PYCALLBACK__BOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
431 void CLASS::CBNAME(bool a, double b, double c, int d, int e) { \
432 bool doSave = wxPyRestoreThread(); \
433 if (m_myInst.findCallback(#CBNAME)) \
434 m_myInst.callCallback(Py_BuildValue("(idii)", \
437 PCLASS::CBNAME(a, b, c, d, e); \
438 wxPySaveThread(doSave); \
440 void CLASS::base_##CBNAME(bool a, double b, double c, int d, int e) { \
441 PCLASS::CBNAME(a, b, c, d, e); \
444 //---------------------------------------------------------------------------
446 #define DEC_PYCALLBACK__DC4DBL(CBNAME) \
447 void CBNAME(wxDC& a, double b, double c, double d, double e); \
448 void base_##CBNAME(wxDC& a, double b, double c, double d, double e);
451 #define IMP_PYCALLBACK__DC4DBL(CLASS, PCLASS, CBNAME) \
452 void CLASS::CBNAME(wxDC& a, double b, double c, double d, double e) { \
453 bool doSave = wxPyRestoreThread(); \
454 if (m_myInst.findCallback(#CBNAME)) \
455 m_myInst.callCallback(Py_BuildValue("(Odddd)", \
456 wxPyConstructObject(&a, "wxDC"), \
459 PCLASS::CBNAME(a, b, c, d, e); \
460 wxPySaveThread(doSave); \
462 void CLASS::base_##CBNAME(wxDC& a, double b, double c, double d, double e) {\
463 PCLASS::CBNAME(a, b, c, d, e); \
466 //---------------------------------------------------------------------------
468 #define DEC_PYCALLBACK__DCBOOL(CBNAME) \
469 void CBNAME(wxDC& a, bool b); \
470 void base_##CBNAME(wxDC& a, bool b);
473 #define IMP_PYCALLBACK__DCBOOL(CLASS, PCLASS, CBNAME) \
474 void CLASS::CBNAME(wxDC& a, bool b) { \
475 bool doSave = wxPyRestoreThread(); \
476 if (m_myInst.findCallback(#CBNAME)) \
477 m_myInst.callCallback(Py_BuildValue("(Oi)", \
478 wxPyConstructObject(&a, "wxDC"), \
481 PCLASS::CBNAME(a, b); \
482 wxPySaveThread(doSave); \
484 void CLASS::base_##CBNAME(wxDC& a, bool b) { \
485 PCLASS::CBNAME(a, b); \
488 //---------------------------------------------------------------------------
490 #define DEC_PYCALLBACK__WXCPBOOL2DBL2INT(CBNAME) \
491 void CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f); \
492 void base_##CBNAME(wxControlPoint* a, bool b, double c, double d, int e, int f);
495 #define IMP_PYCALLBACK__WXCPBOOL2DBL2INT(CLASS, PCLASS, CBNAME) \
496 void CLASS::CBNAME(wxControlPoint* a, bool b, double c, double d, \
498 bool doSave = wxPyRestoreThread(); \
499 if (m_myInst.findCallback(#CBNAME)) \
500 m_myInst.callCallback(Py_BuildValue("(Oiddii)", \
501 wxPyConstructObject(a, "wxControlPoint"), \
502 (int)b, c, d, e, f)); \
504 PCLASS::CBNAME(a, b, c, d, e, f); \
505 wxPySaveThread(doSave); \
507 void CLASS::base_##CBNAME(wxControlPoint* a, bool b, double c, double d, \
509 PCLASS::CBNAME(a, b, c, d, e, f); \
512 //---------------------------------------------------------------------------
514 #define DEC_PYCALLBACK__WXCP2DBL2INT(CBNAME) \
515 void CBNAME(wxControlPoint* a, double b, double c, int d, int e); \
516 void base_##CBNAME(wxControlPoint* a, double b, double c, int d, int e);
519 #define IMP_PYCALLBACK__WXCP2DBL2INT(CLASS, PCLASS, CBNAME) \
520 void CLASS::CBNAME(wxControlPoint* a, double b, double c, int d, int e) { \
521 bool doSave = wxPyRestoreThread(); \
522 if (m_myInst.findCallback(#CBNAME)) \
523 m_myInst.callCallback(Py_BuildValue("(Oddii)", \
524 wxPyConstructObject(a, "wxControlPoint"), \
527 PCLASS::CBNAME(a, b, c, d, e); \
528 wxPySaveThread(doSave); \
530 void CLASS::base_##CBNAME(wxControlPoint* a, double b, double c, \
532 PCLASS::CBNAME(a, b, c, d, e); \
535 //---------------------------------------------------------------------------
537 #define DEC_PYCALLBACK__2DBLINT(CBNAME) \
538 void CBNAME(double a, double b, int c); \
539 void base_##CBNAME(double a, double b, int c);
542 #define IMP_PYCALLBACK__2DBLINT(CLASS, PCLASS, CBNAME) \
543 void CLASS::CBNAME(double a, double b, int c) { \
544 bool doSave = wxPyRestoreThread(); \
545 if (m_myInst.findCallback(#CBNAME)) \
546 m_myInst.callCallback(Py_BuildValue("(ddi)", a,b,c)); \
548 PCLASS::CBNAME(a, b, c); \
549 wxPySaveThread(doSave); \
551 void CLASS::base_##CBNAME(double a, double b, int c) { \
552 PCLASS::CBNAME(a, b, c); \
555 //---------------------------------------------------------------------------
557 #define DEC_PYCALLBACK__BOOL2DBLINT(CBNAME) \
558 void CBNAME(bool a, double b, double c, int d); \
559 void base_##CBNAME(bool a, double b, double c, int d);
562 #define IMP_PYCALLBACK__BOOL2DBLINT(CLASS, PCLASS, CBNAME) \
563 void CLASS::CBNAME(bool a, double b, double c, int d) { \
564 bool doSave = wxPyRestoreThread(); \
565 if (m_myInst.findCallback(#CBNAME)) \
566 m_myInst.callCallback(Py_BuildValue("(iddi)", (int)a,b,c,d)); \
568 PCLASS::CBNAME(a, b, c, d); \
569 wxPySaveThread(doSave); \
571 void CLASS::base_##CBNAME(bool a, double b, double c, int d) { \
572 PCLASS::CBNAME(a, b, c, d); \
575 //---------------------------------------------------------------------------
576 //---------------------------------------------------------------------------
577 //---------------------------------------------------------------------------
578 //---------------------------------------------------------------------------