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 //----------------------------------------------------------------------
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...
80 if (wxPythonApp
->GetTopWindow()) {
81 // Forcibly delete the window.
82 if (wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame
)) ||
83 wxPythonApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog
))) {
85 wxPythonApp
->GetTopWindow()->Close(TRUE
);
86 wxPythonApp
->DeletePendingObjects();
89 delete wxPythonApp
->GetTopWindow();
90 wxPythonApp
->SetTopWindow(NULL
);
95 wxPythonApp
->DeletePendingObjects();
98 wxPythonApp
->OnExit();
103 wxApp::CommonCleanUp();
109 //---------------------------------------------------------------------
110 // a few native methods to add to the module
111 //----------------------------------------------------------------------
114 // This is where we pick up the first part of the wxEntry functionality...
115 // The rest is in __wxStart and AfterMainLoop. Thi function is called when
116 // wxpc is imported. (Before there is a wxApp object.)
119 // Bail out if there is already windows created. This means that the
120 // toolkit has already been initialized, as in embedding wxPython in
121 // a C++ wxWindows app.
122 if (wxTopLevelWindows
.Number() > 0)
126 wxApp::Initialize((WXHINSTANCE
)wxhInstance
);
129 wxClassInfo::InitializeClasses();
131 PyObject
* sysargv
= PySys_GetObject("argv");
132 int argc
= PyList_Size(sysargv
);
133 char** argv
= new char*[argc
+1];
135 for(x
=0; x
<argc
; x
++)
136 argv
[x
] = PyString_AsString(PyList_GetItem(sysargv
, x
));
139 gtk_init( &argc
, &argv
);
142 #ifdef wxUSE_GDK_IMLIB
144 gtk_widget_push_visual(gdk_imlib_get_visual());
145 gtk_widget_push_colormap(gdk_imlib_get_colormap());
155 static char* __nullArgv
[1] = { 0 };
157 // Start the user application, user App's OnInit method is a parameter here
158 PyObject
* __wxStart(PyObject
* /* self */, PyObject
* args
)
160 PyObject
* onInitFunc
= NULL
;
166 if (!PyArg_ParseTuple(args
, "O", &onInitFunc
))
169 if (wxTopLevelWindows
.Number() > 0) {
170 PyErr_SetString(PyExc_TypeError
, "Only 1 wxApp per process!");
175 // This is the next part of the wxEntry functionality...
176 wxPythonApp
->argc
= 0;
177 wxPythonApp
->argv
= __nullArgv
;
178 wxPythonApp
->OnInitGui();
181 // Call the Python App's OnInit function
182 arglist
= PyTuple_New(0);
183 result
= PyEval_CallObject(onInitFunc
, arglist
);
189 if (! PyInt_Check(result
)) {
190 PyErr_SetString(PyExc_TypeError
, "OnInit should return a boolean value");
193 bResult
= PyInt_AS_LONG(result
);
195 wxPythonApp
->DeletePendingObjects();
196 wxPythonApp
->OnExit();
201 wxApp::CommonCleanUp();
203 PyErr_SetString(PyExc_SystemExit
, "OnInit returned false, exiting...");
208 wxTheApp
->m_initialized
= (wxTopLevelWindows
.Number() > 0);
219 PyObject
* wxPython_dict
;
220 PyObject
* __wxSetDictionary(PyObject
* /* self */, PyObject
* args
)
223 if (!PyArg_ParseTuple(args
, "O", &wxPython_dict
))
226 if (!PyDict_Check(wxPython_dict
)) {
227 PyErr_SetString(PyExc_TypeError
, "_wxSetDictionary must have dictionary object!");
231 #define wxPlatform "__WXMOTIF__"
234 #define wxPlatform "__WXQT__"
237 #define wxPlatform "__WXGTK__"
239 #if defined(__WIN32__) || defined(__WXMSW__)
240 #define wxPlatform "__WXMSW__"
243 #define wxPlatform "__WXMAC__"
246 PyDict_SetItemString(wxPython_dict
, "wxPlatform", PyString_FromString(wxPlatform
));
253 //---------------------------------------------------------------------------
257 PyObject
* wxPyConstructObject(void* ptr
, char* className
)
259 char buff
[64]; // should be big enough...
262 sprintf(buff
, "_%s_p", className
);
263 SWIG_MakePtr(swigptr
, ptr
, buff
);
265 sprintf(buff
, "%sPtr", className
);
266 PyObject
* classobj
= PyDict_GetItemString(wxPython_dict
, buff
);
272 PyObject
* arg
= Py_BuildValue("(s)", swigptr
);
273 PyObject
* obj
= PyInstance_New(classobj
, arg
, NULL
);
280 // This function is used for all events destined for Python event handlers.
281 void wxPyCallback::EventThunker(wxEvent
& event
) {
282 wxPyCallback
* cb
= (wxPyCallback
*)event
.m_callbackUserData
;
283 PyObject
* func
= cb
->m_func
;
288 arg
= wxPyConstructObject((void*)&event
, event
.GetClassInfo()->GetClassName());
290 tuple
= PyTuple_New(1);
291 PyTuple_SET_ITEM(tuple
, 0, arg
);
292 result
= PyEval_CallObject(func
, tuple
);
304 //---------------------------------------------------------------------------
306 wxPyMenu::wxPyMenu(const wxString
& title
, PyObject
* _func
)
307 : wxMenu(title
, (wxFunction
)(func
? MenuCallback
: NULL
)), func(0) {
315 wxPyMenu::~wxPyMenu() {
321 void wxPyMenu::MenuCallback(wxMenu
& menu
, wxCommandEvent
& evt
) {
322 PyObject
* evtobj
= wxPyConstructObject((void*)&evt
, "wxCommandEvent");
323 PyObject
* menuobj
= wxPyConstructObject((void*)&menu
, "wxMenu");
324 if (PyErr_Occurred()) {
325 // bail out if a problem
329 // Now call the callback...
330 PyObject
* func
= ((wxPyMenu
*)&menu
)->func
;
331 PyObject
* args
= Py_BuildValue("(OO)", menuobj
, evtobj
);
332 PyObject
* res
= PyEval_CallObject(func
, args
);
340 //---------------------------------------------------------------------------
342 wxPyTimer::wxPyTimer(PyObject
* callback
) {
347 wxPyTimer::~wxPyTimer() {
351 void wxPyTimer::Notify() {
353 PyObject
* args
= Py_BuildValue("()");
355 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.9 1998/09/25 13:28:52 VZ
655 // USE_xxx constants renamed to wxUSE_xxx. This is an incompatible change, you
656 // must recompile everything after upgrading!
658 // Revision 1.8 1998/08/27 21:59:08 RD
659 // Some chicken-and-egg problems solved for wxPython on wxGTK
661 // Revision 1.7 1998/08/27 00:00:26 RD
663 // - have discovered some problems but not yet discovered solutions...
665 // Revision 1.6 1998/08/18 21:54:12 RD
667 // ifdef out some wxGTK specific code
669 // Revision 1.5 1998/08/18 19:48:17 RD
670 // more wxGTK compatibility things.
672 // It builds now but there are serious runtime problems...
674 // Revision 1.4 1998/08/16 04:31:06 RD
677 // Revision 1.3 1998/08/15 07:36:36 RD
678 // - Moved the header in the .i files out of the code that gets put into
679 // the .cpp files. It caused CVS conflicts because of the RCS ID being
680 // different each time.
682 // - A few minor fixes.
684 // Revision 1.2 1998/08/14 23:36:36 RD
685 // Beginings of wxGTK compatibility
687 // Revision 1.1 1998/08/09 08:25:51 RD