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
25 #ifdef wxUSE_GDK_IMLIB
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 //----------------------------------------------------------------------
49 HINSTANCE hinstDLL
, // handle to DLL module
50 DWORD fdwReason
, // reason for calling function
51 LPVOID lpvReserved
// reserved
54 wxhInstance
= hinstDLL
;
59 //----------------------------------------------------------------------
60 // Class for implementing the wxp main application shell.
61 //----------------------------------------------------------------------
63 wxPyApp
*wxPythonApp
= NULL
; // Global instance of application object
66 // This one isn't acutally called... See __wxStart()
67 bool wxPyApp::OnInit(void) {
71 int wxPyApp::MainLoop(void) {
72 int retval
= wxApp::MainLoop();
77 void wxPyApp::AfterMainLoop(void) {
78 // more stuff from wxEntry...
81 if (wxPythonApp
->GetTopWindow()) {
82 // Forcibly delete the window.
83 if (wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame
)) ||
84 wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog
))) {
86 wxPythonApp
->GetTopWindow()->Close(TRUE
);
87 wxPythonApp
->DeletePendingObjects();
90 delete wxPythonApp
->GetTopWindow();
91 wxPythonApp
->SetTopWindow(NULL
);
96 wxPythonApp
->DeletePendingObjects();
99 wxPythonApp
->OnExit();
104 wxApp::CommonCleanUp();
110 //---------------------------------------------------------------------
111 // a few native methods to add to the module
112 //----------------------------------------------------------------------
115 // This is where we pick up the first part of the wxEntry functionality...
116 // The rest is in __wxStart and AfterMainLoop. Thi function is called when
117 // wxpc is imported. (Before there is a wxApp object.)
120 // Bail out if there is already windows created. This means that the
121 // toolkit has already been initialized, as in embedding wxPython in
122 // a C++ wxWindows app.
123 if (wxTopLevelWindows
.Number() > 0)
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
));
140 gtk_init( &argc
, &argv
);
143 #ifdef wxUSE_GDK_IMLIB
145 gtk_widget_push_visual(gdk_imlib_get_visual());
146 gtk_widget_push_colormap(gdk_imlib_get_colormap());
156 static char* __nullArgv
[1] = { 0 };
158 // Start the user application, user App's OnInit method is a parameter here
159 PyObject
* __wxStart(PyObject
* /* self */, PyObject
* args
)
161 PyObject
* onInitFunc
= NULL
;
167 if (!PyArg_ParseTuple(args
, "O", &onInitFunc
))
170 if (wxTopLevelWindows
.Number() > 0) {
171 PyErr_SetString(PyExc_TypeError
, "Only 1 wxApp per process!");
176 // This is the next part of the wxEntry functionality...
177 wxPythonApp
->argc
= 0;
178 wxPythonApp
->argv
= __nullArgv
;
179 wxPythonApp
->OnInitGui();
182 // Call the Python App's OnInit function
183 arglist
= PyTuple_New(0);
184 result
= PyEval_CallObject(onInitFunc
, arglist
);
190 if (! PyInt_Check(result
)) {
191 PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value");
194 bResult
= PyInt_AS_LONG(result
);
196 wxPythonApp
->DeletePendingObjects();
197 wxPythonApp
->OnExit();
202 wxApp::CommonCleanUp();
204 PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting...");
209 wxTheApp
->m_initialized
= (wxTopLevelWindows
.Number() > 0);
220 PyObject
* wxPython_dict
;
221 PyObject
* __wxSetDictionary(PyObject
* /* self */, PyObject
* args
)
224 if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
))
227 if (!PyDict_Check(wxPython_dict
)) {
228 PyErr_SetString(PyExc_TypeError
, "_wxSetDictionary must have dictionary object!");
232 #define wxPlatform "__WXMOTIF__"
235 #define wxPlatform "__WXQT__"
238 #define wxPlatform "__WXGTK__"
240 #if defined(__WIN32__) || defined(__WXMSW__)
241 #define wxPlatform "__WXMSW__"
244 #define wxPlatform "__WXMAC__"
247 PyDict_SetItemString(wxPython_dict
, "wxPlatform", PyString_FromString(wxPlatform
));
254 //---------------------------------------------------------------------------
258 PyObject
* wxPyConstructObject(void* ptr
, char* className
)
260 char buff
[64]; // should always be big enough...
263 sprintf(buff
, "_%s_p", className
);
264 SWIG_MakePtr(swigptr
, ptr
, buff
);
266 sprintf(buff
, "%sPtr", className
);
267 PyObject
* classobj
= PyDict_GetItemString(wxPython_dict
, buff
);
273 PyObject
* arg
= Py_BuildValue("(s)", swigptr
);
274 PyObject
* obj
= PyInstance_New(classobj
, arg
, NULL
);
281 // This function is used for all events destined for Python event handlers.
282 void wxPyCallback::EventThunker(wxEvent
& event
) {
283 wxPyCallback
* cb
= (wxPyCallback
*)event
.m_callbackUserData
;
284 PyObject
* func
= cb
->m_func
;
289 arg
= wxPyConstructObject((void*)&event
, event
.GetClassInfo()->GetClassName());
291 tuple
= PyTuple_New(1);
292 PyTuple_SET_ITEM(tuple
, 0, arg
);
293 result
= PyEval_CallObject(func
, tuple
);
305 //---------------------------------------------------------------------------
307 wxPyMenu::wxPyMenu(const wxString
& title
, PyObject
* _func
)
308 : wxMenu(title
, (wxFunction
)(func
? MenuCallback
: NULL
)), func(0) {
316 wxPyMenu::~wxPyMenu() {
322 void wxPyMenu::MenuCallback(wxMenu
& menu
, wxCommandEvent
& evt
) {
323 PyObject
* evtobj
= wxPyConstructObject((void*)&evt
, "wxCommandEvent");
324 PyObject
* menuobj
= wxPyConstructObject((void*)&menu
, "wxMenu");
325 if (PyErr_Occurred()) {
326 // bail out if a problem
330 // Now call the callback...
331 PyObject
* func
= ((wxPyMenu
*)&menu
)->func
;
332 PyObject
* args
= Py_BuildValue("(OO)", menuobj
, evtobj
);
333 PyObject
* res
= PyEval_CallObject(func
, args
);
341 //---------------------------------------------------------------------------
343 wxPyTimer::wxPyTimer(PyObject
* callback
) {
348 wxPyTimer::~wxPyTimer() {
352 void wxPyTimer::Notify() {
354 PyObject
* args
= Py_BuildValue("()");
356 result
= PyEval_CallObject(func
, args
);
368 //----------------------------------------------------------------------
369 //----------------------------------------------------------------------
370 // Some helper functions for typemaps in my_typemaps.i, so they won't be
371 // imcluded in every file...
374 int* int_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 int* temp
= new int[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 long* long_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 long* temp
= new long[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 (! PyInt_Check(o
)) {
411 PyErr_SetString(PyExc_TypeError
, "Expected a list of integers.");
414 temp
[x
] = PyInt_AsLong(o
);
420 char** string_LIST_helper(PyObject
* source
) {
421 if (!PyList_Check(source
)) {
422 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
425 int count
= PyList_Size(source
);
426 char** temp
= new char*[count
];
428 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
431 for (int x
=0; x
<count
; x
++) {
432 PyObject
* o
= PyList_GetItem(source
, x
);
433 if (! PyString_Check(o
)) {
434 PyErr_SetString(PyExc_TypeError
, "Expected a list of strings.");
437 temp
[x
] = PyString_AsString(o
);
444 wxPoint
* wxPoint_LIST_helper(PyObject
* source
) {
445 if (!PyList_Check(source
)) {
446 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
449 int count
= PyList_Size(source
);
450 wxPoint
* temp
= new wxPoint
[count
];
452 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
455 for (int x
=0; x
<count
; x
++) {
456 PyObject
* o
= PyList_GetItem(source
, x
);
457 if (PyString_Check(o
)) {
458 char* st
= PyString_AsString(o
);
460 if (SWIG_GetPtr(st
,(void **) &pt
,"_wxPoint_p")) {
461 PyErr_SetString(PyExc_TypeError
,"Expected _wxPoint_p.");
466 else if (PyTuple_Check(o
)) {
467 PyObject
* o1
= PyTuple_GetItem(o
, 0);
468 PyObject
* o2
= PyTuple_GetItem(o
, 1);
470 temp
[x
].x
= PyInt_AsLong(o1
);
471 temp
[x
].y
= PyInt_AsLong(o2
);
474 PyErr_SetString(PyExc_TypeError
, "Expected a list of 2-tuples or wxPoints.");
482 wxBitmap
** wxBitmap_LIST_helper(PyObject
* source
) {
483 if (!PyList_Check(source
)) {
484 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
487 int count
= PyList_Size(source
);
488 wxBitmap
** temp
= new wxBitmap
*[count
];
490 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
493 for (int x
=0; x
<count
; x
++) {
494 PyObject
* o
= PyList_GetItem(source
, x
);
495 if (PyString_Check(o
)) {
496 char* st
= PyString_AsString(o
);
498 if (SWIG_GetPtr(st
,(void **) &pt
,"_wxBitmap_p")) {
499 PyErr_SetString(PyExc_TypeError
,"Expected _wxBitmap_p.");
505 PyErr_SetString(PyExc_TypeError
, "Expected a list of wxBitmaps.");
514 wxString
* wxString_LIST_helper(PyObject
* source
) {
515 if (!PyList_Check(source
)) {
516 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
519 int count
= PyList_Size(source
);
520 wxString
* temp
= new wxString
[count
];
522 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
525 for (int x
=0; x
<count
; x
++) {
526 PyObject
* o
= PyList_GetItem(source
, x
);
527 if (! PyString_Check(o
)) {
528 PyErr_SetString(PyExc_TypeError
, "Expected a list of strings.");
531 temp
[x
] = PyString_AsString(o
);
538 wxAcceleratorEntry
* wxAcceleratorEntry_LIST_helper(PyObject
* source
) {
539 if (!PyList_Check(source
)) {
540 PyErr_SetString(PyExc_TypeError
, "Expected a list object.");
543 int count
= PyList_Size(source
);
544 wxAcceleratorEntry
* temp
= new wxAcceleratorEntry
[count
];
546 PyErr_SetString(PyExc_MemoryError
, "Unable to allocate temporary array");
549 for (int x
=0; x
<count
; x
++) {
550 PyObject
* o
= PyList_GetItem(source
, x
);
551 if (PyString_Check(o
)) {
552 char* st
= PyString_AsString(o
);
553 wxAcceleratorEntry
* ae
;
554 if (SWIG_GetPtr(st
,(void **) &ae
,"_wxAcceleratorEntry_p")) {
555 PyErr_SetString(PyExc_TypeError
,"Expected _wxAcceleratorEntry_p.");
560 else if (PyTuple_Check(o
)) {
561 PyObject
* o1
= PyTuple_GetItem(o
, 0);
562 PyObject
* o2
= PyTuple_GetItem(o
, 1);
563 PyObject
* o3
= PyTuple_GetItem(o
, 2);
565 temp
[x
].m_flags
= PyInt_AsLong(o1
);
566 temp
[x
].m_keyCode
= PyInt_AsLong(o2
);
567 temp
[x
].m_command
= PyInt_AsLong(o3
);
570 PyErr_SetString(PyExc_TypeError
, "Expected a list of 3-tuples or wxAcceleratorEntry objects.");
579 //----------------------------------------------------------------------
580 // A WinMain for when wxWindows and Python are linked together in a single
581 // application, instead of as a dynamic module
584 //#if !defined(WIN_PYD) && defined(WIN32)
586 //extern "C" int Py_Main(int argc, char** argv);
588 //int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR m_lpCmdLine,
594 // // Initialize wxWindows, but don't start the main loop
595 // wxEntry(hInstance, hPrevInstance, m_lpCmdLine, nCmdShow, FALSE);
598 // PyObject *argvList = PyList_New(0);
600 // char* stderrfilename = "wxpstderr.log";
602 // char* script = NULL;
603 // int argc = wxPythonApp->argc;
604 // char** argv = wxPythonApp->argv;
606 // for (int i = 1; i < argc; i++) {
607 // if (strncmp(argv[i], "wxpstderr=", 10) == 0)
608 // stderrfilename = argv[i]+10;
610 // PyList_Append(argvList, PyString_FromString(argv[i]));
617 // PySys_SetObject("argv", argvList);
621 //// //PyRun_SimpleString("import sys; sys.stdout=open('wxpstdout.log','w')");
622 // sprintf(buf, "import sys; sys.stdout=sys.stderr=open('%s','w')", stderrfilename);
623 // PyRun_SimpleString(buf);
629 // FILE *fp = fopen(script, "r");
631 // PyRun_SimpleFile(fp, script);// This returns after wxpApp constructor
636 // sprintf(msg, "Cannot open %s", script);
637 // wxMessageBox(msg);
641 // PyRun_SimpleString("import wxpide");
649 //----------------------------------------------------------------------
651 /////////////////////////////////////////////////////////////////////////////
654 // Revision 1.10 1998/10/02 06:40:39 RD
655 // Version 0.4 of wxPython for MSW.
657 // Revision 1.9 1998/09/25 13:28:52 VZ
659 // USE_xxx constants renamed to wxUSE_xxx. This is an incompatible change, you
660 // must recompile everything after upgrading!
662 // Revision 1.8 1998/08/27 21:59:08 RD
663 // Some chicken-and-egg problems solved for wxPython on wxGTK
665 // Revision 1.7 1998/08/27 00:00:26 RD
667 // - have discovered some problems but not yet discovered solutions...
669 // Revision 1.6 1998/08/18 21:54:12 RD
671 // ifdef out some wxGTK specific code
673 // Revision 1.5 1998/08/18 19:48:17 RD
674 // more wxGTK compatibility things.
676 // It builds now but there are serious runtime problems...
678 // Revision 1.4 1998/08/16 04:31:06 RD
681 // Revision 1.3 1998/08/15 07:36:36 RD
682 // - Moved the header in the .i files out of the code that gets put into
683 // the .cpp files. It caused CVS conflicts because of the RCS ID being
684 // different each time.
686 // - A few minor fixes.
688 // Revision 1.2 1998/08/14 23:36:36 RD
689 // Beginings of wxGTK compatibility
691 // Revision 1.1 1998/08/09 08:25:51 RD