1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Helper functions/classes for the wxPython extension module
9 // Copyright: (c) 1998 by Total Control Software
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
17 #undef LoadAccelerators
26 #include "gdk_imlib/gdk_imlib.h"
30 //---------------------------------------------------------------------------
32 //wxHashTable* wxPyWindows = NULL;
35 wxPoint wxPyDefaultPosition
; //wxDefaultPosition);
36 wxSize wxPyDefaultSize
; //wxDefaultSize);
37 wxString
wxPyEmptyStr("");
41 #ifdef __WXMSW__ // If building for win32...
42 extern HINSTANCE wxhInstance
;
44 //----------------------------------------------------------------------
45 // This gets run when the DLL is loaded. We just need to save a handle.
46 //----------------------------------------------------------------------
48 HINSTANCE hinstDLL
, // handle to DLL module
49 DWORD fdwReason
, // reason for calling function
50 LPVOID lpvReserved
// reserved
53 wxhInstance
= hinstDLL
;
58 //----------------------------------------------------------------------
59 // Class for implementing the wxp main application shell.
60 //----------------------------------------------------------------------
62 wxPyApp
*wxPythonApp
= NULL
; // Global instance of application object
65 // This one isn't acutally called... See __wxStart()
66 bool wxPyApp::OnInit(void) {
70 int wxPyApp::MainLoop(void) {
71 int retval
= wxApp::MainLoop();
76 void wxPyApp::AfterMainLoop(void) {
77 // more stuff from wxEntry...
78 if (wxPythonApp
->GetTopWindow()) {
79 // Forcibly delete the window.
80 if (wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame
)) ||
81 wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog
))) {
83 wxPythonApp
->GetTopWindow()->Close(TRUE
);
84 wxPythonApp
->DeletePendingObjects();
87 delete wxPythonApp
->GetTopWindow();
88 wxPythonApp
->SetTopWindow(NULL
);
92 wxPythonApp
->OnExit();
97 wxApp::CommonCleanUp();
103 //---------------------------------------------------------------------
104 // a few native methods to add to the module
105 //----------------------------------------------------------------------
109 // Start the user application, user App's OnInit method is a parameter here
110 PyObject
* __wxStart(PyObject
* /* self */, PyObject
* args
)
112 PyObject
* onInitFunc
= NULL
;
117 if (!PyArg_ParseTuple(args
, "O", &onInitFunc
))
120 // This is where we pick up one part of the wxEntry functionality...
121 // the rest is in AfterMainLoop.
123 wxApp::Initialize((WXHINSTANCE
)wxhInstance
);
125 wxPythonApp
->argc
= 0;
126 wxPythonApp
->argv
= NULL
;
127 wxPythonApp
->OnInitGui();
130 wxClassInfo::InitializeClasses();
132 PyObject
* sysargv
= PySys_GetObject("argv");
133 int argc
= PyList_Size(sysargv
);
134 char** argv
= new char*[argc
+1];
136 for(x
=0; x
<argc
; x
++)
137 argv
[x
] = PyString_AsString(PyList_GetItem(sysargv
, x
));
141 wxPythonApp
->argc
= argc
;
142 wxPythonApp
->argv
= argv
;
144 gtk_init( &wxPythonApp
->argc
, &wxPythonApp
->argv
);
148 gtk_widget_push_visual(gdk_imlib_get_visual());
149 gtk_widget_push_colormap(gdk_imlib_get_colormap());
153 wxTheApp
->OnInitGui();
158 // Call the Python App's OnInit function
159 arglist
= PyTuple_New(0);
160 result
= PyEval_CallObject(onInitFunc
, arglist
);
166 if (! PyInt_Check(result
)) {
167 PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value");
170 bResult
= PyInt_AS_LONG(result
);
172 wxPythonApp
->DeletePendingObjects();
173 wxPythonApp
->OnExit();
178 wxApp::CommonCleanUp();
180 PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting...");
185 wxTheApp
->m_initialized
= (wxTopLevelWindows
.Number() > 0);
196 PyObject
* wxPython_dict
;
197 PyObject
* __wxSetDictionary(PyObject
* /* self */, PyObject
* args
)
200 if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
))
203 if (!PyDict_Check(wxPython_dict
)) {
204 PyErr_SetString(PyExc_TypeError
, "_wxSetDictionary must have dictionary object!");
208 #define wxPlatform "__WXMOTIF__"
211 #define wxPlatform "__WXQT__"
214 #define wxPlatform "__WXGTK__"
216 #if defined(__WIN32__) || defined(__WXMSW__)
217 #define wxPlatform "__WXMSW__"
220 #define wxPlatform "__WXMAC__"
223 PyDict_SetItemString(wxPython_dict
, "wxPlatform", PyString_FromString(wxPlatform
));
230 //---------------------------------------------------------------------------
234 PyObject
* wxPyConstructObject(void* ptr
, char* className
)
236 char buff
[64]; // should be big enough...
239 sprintf(buff
, "_%s_p", className
);
240 SWIG_MakePtr(swigptr
, ptr
, buff
);
242 sprintf(buff
, "%sPtr", className
);
243 PyObject
* classobj
= PyDict_GetItemString(wxPython_dict
, buff
);
249 PyObject
* arg
= Py_BuildValue("(s)", swigptr
);
250 PyObject
* obj
= PyInstance_New(classobj
, arg
, NULL
);
257 // This function is used for all events destined for Python event handlers.
258 void wxPyCallback::EventThunker(wxEvent
& event
) {
259 wxPyCallback
* cb
= (wxPyCallback
*)event
.m_callbackUserData
;
260 PyObject
* func
= cb
->m_func
;
265 arg
= wxPyConstructObject((void*)&event
, event
.GetClassInfo()->GetClassName());
267 tuple
= PyTuple_New(1);
268 PyTuple_SET_ITEM(tuple
, 0, arg
);
269 result
= PyEval_CallObject(func
, tuple
);
281 //---------------------------------------------------------------------------
283 wxPyMenu::wxPyMenu(const wxString
& title
, PyObject
* _func
)
284 : wxMenu(title
, (wxFunction
)(func
? MenuCallback
: NULL
)), func(0) {
292 wxPyMenu::~wxPyMenu() {
298 void wxPyMenu::MenuCallback(wxMenu
& menu
, wxCommandEvent
& evt
) {
299 PyObject
* evtobj
= wxPyConstructObject((void*)&evt
, "wxCommandEvent");
300 PyObject
* menuobj
= wxPyConstructObject((void*)&menu
, "wxMenu");
301 if (PyErr_Occurred()) {
302 // bail out if a problem
306 // Now call the callback...
307 PyObject
* func
= ((wxPyMenu
*)&menu
)->func
;
308 PyObject
* args
= Py_BuildValue("(OO)", menuobj
, evtobj
);
309 PyObject
* res
= PyEval_CallObject(func
, args
);
317 //---------------------------------------------------------------------------
319 wxPyTimer::wxPyTimer(PyObject
* callback
) {
324 wxPyTimer::~wxPyTimer() {
328 void wxPyTimer::Notify() {
330 PyObject
* args
= Py_BuildValue("()");
332 result
= PyEval_CallObject(func
, args
);
345 //----------------------------------------------------------------------
346 //----------------------------------------------------------------------
347 // Some helper functions for typemaps in my_typemaps.i, so they won't be
348 // imcluded in every file...
351 int* int_LIST_helper(PyObject
* source
) {
352 if (!PyList_Check(source
)) {
353 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
356 int count
= PyList_Size(source
);
357 int* temp
= new int[count
];
359 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
362 for (int x
=0; x
<count
; x
++) {
363 PyObject
* o
= PyList_GetItem(source
, x
);
364 if (! PyInt_Check(o
)) {
365 PyErr_SetString(PyExc_TypeError
, "Expected a list of integers.");
368 temp
[x
] = PyInt_AsLong(o
);
374 long* long_LIST_helper(PyObject
* source
) {
375 if (!PyList_Check(source
)) {
376 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
379 int count
= PyList_Size(source
);
380 long* temp
= new long[count
];
382 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
385 for (int x
=0; x
<count
; x
++) {
386 PyObject
* o
= PyList_GetItem(source
, x
);
387 if (! PyInt_Check(o
)) {
388 PyErr_SetString(PyExc_TypeError
, "Expected a list of integers.");
391 temp
[x
] = PyInt_AsLong(o
);
397 char** string_LIST_helper(PyObject
* source
) {
398 if (!PyList_Check(source
)) {
399 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
402 int count
= PyList_Size(source
);
403 char** temp
= new char*[count
];
405 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
408 for (int x
=0; x
<count
; x
++) {
409 PyObject
* o
= PyList_GetItem(source
, x
);
410 if (! PyString_Check(o
)) {
411 PyErr_SetString(PyExc_TypeError
, "Expected a list of strings.");
414 temp
[x
] = PyString_AsString(o
);
421 wxPoint
* wxPoint_LIST_helper(PyObject
* source
) {
422 if (!PyList_Check(source
)) {
423 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
426 int count
= PyList_Size(source
);
427 wxPoint
* temp
= new wxPoint
[count
];
429 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
432 for (int x
=0; x
<count
; x
++) {
433 PyObject
* o
= PyList_GetItem(source
, x
);
434 if (PyString_Check(o
)) {
435 char* st
= PyString_AsString(o
);
437 if (SWIG_GetPtr(st
,(void **) &pt
,"_wxPoint_p")) {
438 PyErr_SetString(PyExc_TypeError
,"Expected _wxPoint_p.");
443 else if (PyTuple_Check(o
)) {
444 PyObject
* o1
= PyTuple_GetItem(o
, 0);
445 PyObject
* o2
= PyTuple_GetItem(o
, 1);
447 temp
[x
].x
= PyInt_AsLong(o1
);
448 temp
[x
].y
= PyInt_AsLong(o2
);
451 PyErr_SetString(PyExc_TypeError
, "Expected a list of 2-tuples or wxPoints.");
459 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) {
460 if (!PyList_Check(source
)) {
461 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
464 int count
= PyList_Size(source
);
465 wxBitmap
** temp
= new wxBitmap
*[count
];
467 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
470 for (int x
=0; x
<count
; x
++) {
471 PyObject
* o
= PyList_GetItem(source
, x
);
472 if (PyString_Check(o
)) {
473 char* st
= PyString_AsString(o
);
475 if (SWIG_GetPtr(st
,(void **) &pt
,"_wxBitmap_p")) {
476 PyErr_SetString(PyExc_TypeError
,"Expected _wxBitmap_p.");
482 PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps.");
491 wxString
* wxString_LIST_helper(PyObject
* source
) {
492 if (!PyList_Check(source
)) {
493 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
496 int count
= PyList_Size(source
);
497 wxString
* temp
= new wxString
[count
];
499 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
502 for (int x
=0; x
<count
; x
++) {
503 PyObject
* o
= PyList_GetItem(source
, x
);
504 if (! PyString_Check(o
)) {
505 PyErr_SetString(PyExc_TypeError
, "Expected a list of strings.");
508 temp
[x
] = PyString_AsString(o
);
515 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) {
516 if (!PyList_Check(source
)) {
517 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
520 int count
= PyList_Size(source
);
521 wxAcceleratorEntry
* temp
= new wxAcceleratorEntry
[count
];
523 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
526 for (int x
=0; x
<count
; x
++) {
527 PyObject
* o
= PyList_GetItem(source
, x
);
528 if (PyString_Check(o
)) {
529 char* st
= PyString_AsString(o
);
530 wxAcceleratorEntry
* ae
;
531 if (SWIG_GetPtr(st
,(void **) &ae
,"_wxAcceleratorEntry_p")) {
532 PyErr_SetString(PyExc_TypeError
,"Expected _wxAcceleratorEntry_p.");
537 else if (PyTuple_Check(o
)) {
538 PyObject
* o1
= PyTuple_GetItem(o
, 0);
539 PyObject
* o2
= PyTuple_GetItem(o
, 1);
540 PyObject
* o3
= PyTuple_GetItem(o
, 2);
542 temp
[x
].m_flags
= PyInt_AsLong(o1
);
543 temp
[x
].m_keyCode
= PyInt_AsLong(o2
);
544 temp
[x
].m_command
= PyInt_AsLong(o3
);
547 PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
556 //----------------------------------------------------------------------
557 // A WinMain for when wxWindows and Python are linked together in a single
558 // application, instead of as a dynamic module
561 //#if !defined(WIN_PYD) && defined(WIN32)
563 //extern "C" int Py_Main(int argc, char** argv);
565 //int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR m_lpCmdLine,
571 // // Initialize wxWindows, but don't start the main loop
572 // wxEntry(hInstance, hPrevInstance, m_lpCmdLine, nCmdShow, FALSE);
575 // PyObject *argvList = PyList_New(0);
577 // char* stderrfilename = "wxpstderr.log";
579 // char* script = NULL;
580 // int argc = wxPythonApp->argc;
581 // char** argv = wxPythonApp->argv;
583 // for (int i = 1; i < argc; i++) {
584 // if (strncmp(argv[i], "wxpstderr=", 10) == 0)
585 // stderrfilename = argv[i]+10;
587 // PyList_Append(argvList, PyString_FromString(argv[i]));
594 // PySys_SetObject("argv", argvList);
598 //// //PyRun_SimpleString("import sys; sys.stdout=open('wxpstdout.log','w')");
599 // sprintf(buf, "import sys; sys.stdout=sys.stderr=open('%s','w')", stderrfilename);
600 // PyRun_SimpleString(buf);
606 // FILE *fp = fopen(script, "r");
608 // PyRun_SimpleFile(fp, script);// This returns after wxpApp constructor
613 // sprintf(msg, "Cannot open %s", script);
614 // wxMessageBox(msg);
618 // PyRun_SimpleString("import wxpide");
626 //----------------------------------------------------------------------
628 /////////////////////////////////////////////////////////////////////////////
631 // Revision 1.7 1998/08/27 00:00:26 RD
633 // - have discovered some problems but not yet discovered solutions...
635 // Revision 1.6 1998/08/18 21:54:12 RD
637 // ifdef out some wxGTK specific code
639 // Revision 1.5 1998/08/18 19:48:17 RD
640 // more wxGTK compatibility things.
642 // It builds now but there are serious runtime problems...
644 // Revision 1.4 1998/08/16 04:31:06 RD
647 // Revision 1.3 1998/08/15 07:36:36 RD
648 // - Moved the header in the .i files out of the code that gets put into
649 // the .cpp files. It caused CVS conflicts because of the RCS ID being
650 // different each time.
652 // - A few minor fixes.
654 // Revision 1.2 1998/08/14 23:36:36 RD
655 // Beginings of wxGTK compatibility
657 // Revision 1.1 1998/08/09 08:25:51 RD