Fix periodic focus bug
[wmaker-crm.git] / WINGs / python / WINGs.i
blob2c739350e5bd417c08008a4286039586e76f7fb0
1 %module wings
2 %{
3 #include "WINGs/WINGsP.h"
4 %}
6 %include typemaps.i
8 // This tells SWIG to treat char ** as a special case
9 %typemap(python, in) char ** {
10 /* Check if is a list */
11 if (PyList_Check($input)) {
12 int size = PyList_Size($input);
13 int i = 0;
14 $1 = (char **) wmalloc((size+1)*sizeof(char *));
15 for (i = 0; i < size; i++) {
16 PyObject *o = PyList_GetItem($input, i);
17 if (PyString_Check(o))
18 $1[i] = PyString_AsString(PyList_GetItem($input, i));
19 else {
20 PyErr_SetString(PyExc_TypeError, "list must contain strings");
21 wfree($1);
22 return NULL;
25 $1[i] = 0;
26 } else {
27 PyErr_SetString(PyExc_TypeError, "not a list");
28 return NULL;
31 // This cleans up the char ** array we malloc-ed before the function call
32 %typemap(python, freearg) char ** {
33 wfree($1);
35 // This allows a C function to return a char ** as a Python list
36 %typemap(python, out) char ** {
37 int len,i;
38 len = 0;
39 while ($1[len]) len++;
40 $result = PyList_New(len);
41 for (i = 0; i < len; i++) {
42 PyList_SetItem($result, i, PyString_FromString($1[i]));
46 // Now for some callbacks
47 %typemap(python, in) PyObject *pyacArgs {
48 if (PyTuple_Check($input)) {
49 if (PyTuple_Size($input) != 3) {
50 PyErr_SetString(PyExc_ValueError,
51 "wrong number of parameters in tuple. should be 3.");
52 return NULL;
53 } else {
54 PyObject *func = PyTuple_GetItem($input, 1);
55 if (func!=Py_None && !PyCallable_Check(func)) {
56 PyErr_SetString(PyExc_TypeError,
57 "'action' needs to be a callable object!");
58 return NULL;
61 } else {
62 PyErr_SetString(PyExc_TypeError, "2nd argument not a tuple!");
63 return NULL;
65 $1 = $input;
68 %typemap(python, in) PyObject *pycArgs {
69 if (PyTuple_Check($input)) {
70 if (PyTuple_Size($input) != 2) {
71 PyErr_SetString(PyExc_ValueError,
72 "wrong number of parameters in tuple. should be 2.");
73 return NULL;
74 } else {
75 PyObject *func = PyTuple_GetItem($input, 0);
76 if (func!=Py_None && !PyCallable_Check(func)) {
77 PyErr_SetString(PyExc_TypeError,
78 "'action' needs to be a callable object!");
79 return NULL;
82 } else {
83 PyErr_SetString(PyExc_TypeError, "2nd argument not a tuple!");
84 return NULL;
86 $1 = $input;
89 // Type mapping for grabbing a FILE * from Python
90 %typemap(python, in) FILE * {
91 if (!PyFile_Check($input)) {
92 PyErr_SetString(PyExc_TypeError, "Need a file!");
93 return NULL;
95 $1 = PyFile_AsFile($input);
98 /* These are for free-ing the return of functions that need to be freed
99 * before returning control to python. */
100 %typemap(python, ret) char* WMGetTextFieldText { wfree($1); };
103 %include exception.i
105 %exception pyWMScreenMainLoop {
106 $function
107 if (PyErr_Occurred())
108 return NULL;
111 %exception pyWMRunModalLoop {
112 $function
113 if (PyErr_Occurred())
114 return NULL;
118 static int mainLoopDone = 0;
122 %inline %{
123 WMScreen *pyWMOpenScreen(const char *display, int simpleapp)
125 Display *dpy = XOpenDisplay(display);
127 if (!dpy) {
128 wwarning("WINGs: could not open display %s", XDisplayName(display));
129 return NULL;
132 if (simpleapp) {
133 return WMCreateSimpleApplicationScreen(dpy);
134 } else {
135 return WMCreateScreen(dpy, DefaultScreen(dpy));
139 void pyWMScreenMainLoop(WMScreen *scr)
141 XEvent event;
143 while (!PyErr_Occurred() && !mainLoopDone) {
144 WMNextEvent(((W_Screen*)scr)->display, &event);
145 WMHandleEvent(&event);
149 void pyWMBreakScreenMainLoop(WMScreen *scr)
151 mainLoopDone = 1;
154 void pyWMRunModalLoop(WMScreen *scr, WMView *view)
156 int oldModalLoop = scr->modalLoop;
157 WMView *oldModalView = scr->modalView;
159 scr->modalView = view;
161 scr->modalLoop = 1;
162 while (!PyErr_Occurred() && scr->modalLoop) {
163 XEvent event;
165 WMNextEvent(scr->display, &event);
166 WMHandleEvent(&event);
169 scr->modalView = oldModalView;
170 scr->modalLoop = oldModalLoop;
175 //%rename WMScreenMainLoop _WMScreenMainLoop;
176 //%rename(_WMScreenMainLoop) WMScreenMainLoop;
177 //%rename WMRunModalLoop _WMRunModalLoop;
181 /* These functions match the prototypes of the normal C callback
182 * functions. However, we use the clientdata pointer for holding a
183 * reference to a Python tuple containing (object, funct, clientData).
185 static void PythonWMActionCallback(WMWidget *widget, void *cdata)
187 PyObject *pyobj, *func, *pydata, *arglist, *tuple, *result;
189 tuple = (PyObject*) cdata;
190 pyobj = PyTuple_GetItem(tuple, 0);
191 func = PyTuple_GetItem(tuple, 1);
192 if (func && func!=Py_None) {
193 pydata = PyTuple_GetItem(tuple, 2);
194 arglist = Py_BuildValue("(OO)", pyobj, pydata);
195 result = PyEval_CallObject(func, arglist);
196 Py_DECREF(arglist);
197 Py_XDECREF(result);
201 static void PythonWMCallback(void *data)
203 PyObject *func, *pydata, *arglist, *tuple, *result;
205 tuple = (PyObject*) data;
206 func = PyTuple_GetItem(tuple, 0);
207 if (func && func!=Py_None) {
208 pydata = PyTuple_GetItem(tuple, 1);
209 arglist = Py_BuildValue("(O)", pydata);
210 result = PyEval_CallObject(func, arglist);
211 Py_DECREF(arglist);
212 Py_XDECREF(result);
216 static void
217 pyTextFieldDidBeginEditing(WMTextFieldDelegate *self, WMNotification *notif)
219 PyObject *pyobj, *delegate, *func, *pydata, *arglist, *tuple, *result;
220 int action;
222 tuple = (PyObject*) self->data;
223 pyobj = PyTuple_GetItem(tuple, 0);
224 delegate = PyTuple_GetItem(tuple, 1);
225 if (delegate != Py_None) {
226 // should we call PyObject_HasAttrString()?? rather not and let
227 // python raise an exception because the object doesn't has the
228 // attribute
229 func = PyObject_GetAttrString(delegate, "didBeginEditing");
230 if (func!=NULL && func!=Py_None) {
231 pydata = PyObject_GetAttrString(delegate, "data");
232 if (!pydata) {
233 Py_INCREF(Py_None);
234 pydata = Py_None;
236 action = (int)WMGetNotificationClientData(notif);
237 arglist = Py_BuildValue("(OOi)", pyobj, pydata, action);
238 result = PyEval_CallObject(func, arglist);
239 Py_DECREF(pydata);
240 Py_DECREF(arglist);
241 Py_XDECREF(result);
243 Py_XDECREF(func);
247 static void
248 pyTextFieldDidChange(WMTextFieldDelegate *self, WMNotification *notif)
250 PyObject *pyobj, *delegate, *func, *pydata, *arglist, *tuple, *result;
251 int action;
253 tuple = (PyObject*) self->data;
254 pyobj = PyTuple_GetItem(tuple, 0);
255 delegate = PyTuple_GetItem(tuple, 1);
256 if (delegate != Py_None) {
257 func = PyObject_GetAttrString(delegate, "didChange");
258 if (func!=NULL && func!=Py_None) {
259 pydata = PyObject_GetAttrString(delegate, "data");
260 if (!pydata) {
261 Py_INCREF(Py_None);
262 pydata = Py_None;
264 action = (int)WMGetNotificationClientData(notif);
265 arglist = Py_BuildValue("(OOi)", pyobj, pydata, action);
266 result = PyEval_CallObject(func, arglist);
267 Py_DECREF(pydata);
268 Py_DECREF(arglist);
269 Py_XDECREF(result);
271 Py_XDECREF(func);
275 static void
276 pyTextFieldDidEndEditing(WMTextFieldDelegate *self, WMNotification *notif)
278 PyObject *pyobj, *delegate, *func, *pydata, *arglist, *tuple, *result;
279 int action;
281 tuple = (PyObject*) self->data;
282 pyobj = PyTuple_GetItem(tuple, 0);
283 delegate = PyTuple_GetItem(tuple, 1);
284 if (delegate != Py_None) {
285 func = PyObject_GetAttrString(delegate, "didEndEditing");
286 if (func!=NULL && func!=Py_None) {
287 pydata = PyObject_GetAttrString(delegate, "data");
288 if (!pydata) {
289 Py_INCREF(Py_None);
290 pydata = Py_None;
292 action = (int)WMGetNotificationClientData(notif);
293 arglist = Py_BuildValue("(OOi)", pyobj, pydata, action);
294 result = PyEval_CallObject(func, arglist);
295 Py_DECREF(pydata);
296 Py_DECREF(arglist);
297 Py_XDECREF(result);
299 Py_XDECREF(func);
303 static Bool
304 pyTextFieldShouldBeginEditing(WMTextFieldDelegate *self, WMTextField *tPtr)
306 PyObject *pyobj, *delegate, *func, *pydata, *arglist, *tuple, *result;
307 Bool retval = False;
309 tuple = (PyObject*) self->data;
310 pyobj = PyTuple_GetItem(tuple, 0);
311 delegate = PyTuple_GetItem(tuple, 1);
312 if (delegate != Py_None) {
313 func = PyObject_GetAttrString(delegate, "shouldBeginEditing");
314 if (func!=NULL && func!=Py_None) {
315 pydata = PyObject_GetAttrString(delegate, "data");
316 if (!pydata) {
317 Py_INCREF(Py_None);
318 pydata = Py_None;
320 arglist = Py_BuildValue("(OO)", pyobj, pydata);
321 result = PyEval_CallObject(func, arglist);
322 if (result!=Py_None && PyInt_AsLong(result)!=0) {
323 retval = True;
325 Py_DECREF(pydata);
326 Py_DECREF(arglist);
327 Py_XDECREF(result);
329 Py_XDECREF(func);
332 return retval;
335 static Bool
336 pyTextFieldShouldEndEditing(WMTextFieldDelegate *self, WMTextField *tPtr)
338 PyObject *pyobj, *delegate, *func, *pydata, *arglist, *tuple, *result;
339 Bool retval = False;
341 tuple = (PyObject*) self->data;
342 pyobj = PyTuple_GetItem(tuple, 0);
343 delegate = PyTuple_GetItem(tuple, 1);
344 if (delegate != Py_None) {
345 func = PyObject_GetAttrString(delegate, "shouldEndEditing");
346 if (func!=NULL && func!=Py_None) {
347 pydata = PyObject_GetAttrString(delegate, "data");
348 if (!pydata) {
349 Py_INCREF(Py_None);
350 pydata = Py_None;
352 arglist = Py_BuildValue("(OO)", pyobj, pydata);
353 result = PyEval_CallObject(func, arglist);
354 if (result!=Py_None && PyInt_AsLong(result)!=0) {
355 retval = True;
357 Py_DECREF(pydata);
358 Py_DECREF(arglist);
359 Py_XDECREF(result);
361 Py_XDECREF(func);
364 return retval;
368 %inline %{
369 void pyWMSetWindowCloseAction(WMWindow *win, PyObject *pyacArgs) {
370 WMSetWindowCloseAction(win, PythonWMActionCallback, (void*)pyacArgs);
371 Py_INCREF(pyacArgs);
374 void pyWMSetButtonAction(WMButton *bPtr, PyObject *pyacArgs) {
375 WMSetButtonAction(bPtr, PythonWMActionCallback, (void*)pyacArgs);
376 Py_INCREF(pyacArgs);
379 void pyWMSetScrollerAction(WMScroller *sPtr, PyObject *pyacArgs) {
380 WMSetScrollerAction(sPtr, PythonWMActionCallback, (void*)pyacArgs);
381 Py_INCREF(pyacArgs);
384 void pyWMSetListAction(WMList *lPtr, PyObject *pyacArgs) {
385 WMSetListAction(lPtr, PythonWMActionCallback, (void*)pyacArgs);
386 Py_INCREF(pyacArgs);
389 void pyWMSetListDoubleAction(WMList *lPtr, PyObject *pyacArgs) {
390 WMSetListDoubleAction(lPtr, PythonWMActionCallback, (void*)pyacArgs);
391 Py_INCREF(pyacArgs);
394 void pyWMSetBrowserAction(WMBrowser *bPtr, PyObject *pyacArgs) {
395 WMSetBrowserAction(bPtr, PythonWMActionCallback, (void*)pyacArgs);
396 Py_INCREF(pyacArgs);
399 void pyWMSetBrowserDoubleAction(WMBrowser *bPtr, PyObject *pyacArgs) {
400 WMSetBrowserDoubleAction(bPtr, PythonWMActionCallback, (void*)pyacArgs);
401 Py_INCREF(pyacArgs);
404 void pyWMSetMenuItemAction(WMMenuItem *miPtr, PyObject *pyacArgs) {
405 WMSetMenuItemAction(miPtr, PythonWMActionCallback, (void*)pyacArgs);
406 Py_INCREF(pyacArgs);
409 void pyWMSetPopUpButtonAction(WMPopUpButton *pPtr, PyObject *pyacArgs) {
410 WMSetPopUpButtonAction(pPtr, PythonWMActionCallback, (void*)pyacArgs);
411 Py_INCREF(pyacArgs);
414 void pyWMSetSliderAction(WMSlider *sPtr, PyObject *pyacArgs) {
415 WMSetSliderAction(sPtr, PythonWMActionCallback, (void*)pyacArgs);
416 Py_INCREF(pyacArgs);
419 void pyWMSetRulerMoveAction(WMRuler *rPtr, PyObject *pyacArgs) {
420 WMSetRulerMoveAction(rPtr, PythonWMActionCallback, (void*)pyacArgs);
421 Py_INCREF(pyacArgs);
424 void pyWMSetRulerReleaseAction(WMRuler *rPtr, PyObject *pyacArgs) {
425 WMSetRulerReleaseAction(rPtr, PythonWMActionCallback, (void*)pyacArgs);
426 Py_INCREF(pyacArgs);
429 void pyWMSetColorPanelAction(WMColorPanel *panel, PyObject *pyacArgs) {
430 WMSetColorPanelAction(panel, (WMAction2*)PythonWMActionCallback, (void*)pyacArgs);
431 Py_INCREF(pyacArgs);
434 void* pyWMAddTimerHandler(int miliseconds, PyObject *pycArgs) {
435 Py_INCREF(pycArgs);
436 return (void*)WMAddTimerHandler(miliseconds, PythonWMCallback,
437 (void*)pycArgs);
440 void* pyWMAddPersistentTimerHandler(int miliseconds, PyObject *pycArgs) {
441 Py_INCREF(pycArgs);
442 return (void*)WMAddPersistentTimerHandler(miliseconds, PythonWMCallback,
443 (void*)pycArgs);
446 /* this doesn't work. we pass (func, data) as cdata at creation time, but
447 * only data at destruction, so it won't find it unless we change
448 * WMDeleteTimerWithClientData() to extract data from the tuple, and this
449 * requires access to the internals of WINGs
450 void pyWMDeleteTimerWithClientData(PyObject *pycData) {
451 WMDeleteTimerWithClientData((void*)pycData);
454 void pyWMDeleteTimerHandler(void *handlerID) {
455 WMDeleteTimerHandler((WMHandlerID)handlerID);
458 void* pyWMAddIdleHandler(PyObject *pycArgs) {
459 Py_INCREF(pycArgs);
460 return (void*)WMAddIdleHandler(PythonWMCallback, (void*)pycArgs);
463 void pyWMDeleteIdleHandler(void *handlerID) {
464 WMDeleteIdleHandler((WMHandlerID)handlerID);
470 %exception pyWMSetTextFieldDelegate {
471 $function
472 if (PyErr_Occurred()) {
473 return NULL;
477 %inline %{
478 void pyWMSetTextFieldDelegate(WMTextField *tPtr, PyObject *txtArgs) {
479 WMTextFieldDelegate *td;
481 if (!txtArgs || !PyTuple_Check(txtArgs) || PyTuple_Size(txtArgs)!=2) {
482 PyErr_SetString(PyExc_TypeError, "invalid setting of WMTextField "
483 "delegate. Should be '(self, delegate)'");
484 return;
486 // how do I check if txtArgs[1] is an instance of WMTextFieldDelegate?
487 td = WMGetTextFieldDelegate(tPtr);
488 if (!td) {
489 td = (WMTextFieldDelegate*)wmalloc(sizeof(WMTextFieldDelegate));
490 td->didBeginEditing = pyTextFieldDidBeginEditing;
491 td->didChange = pyTextFieldDidChange;
492 td->didEndEditing = pyTextFieldDidEndEditing;
493 td->shouldBeginEditing = pyTextFieldShouldBeginEditing;
494 td->shouldEndEditing = pyTextFieldShouldEndEditing;
495 } else {
496 Py_XDECREF((PyObject*)td->data);
498 Py_INCREF(txtArgs);
499 td->data = txtArgs;
500 WMSetTextFieldDelegate(tPtr, td);
505 %inline %{
506 PyObject* pyWMGetTextFieldDelegate(WMTextField *tPtr) {
507 WMTextFieldDelegate *td;
508 PyObject *result, *tuple;
510 td = WMGetTextFieldDelegate(tPtr);
511 if (!td) {
512 Py_INCREF(Py_None);
513 return Py_None;
516 tuple = (PyObject*)td->data;
517 if (!tuple || !PyTuple_Check(tuple) || PyTuple_Size(tuple)!=2) {
518 PyErr_SetString(PyExc_TypeError, "invalid TextField delegate");
519 return NULL;
522 result = PyTuple_GetItem(tuple, 1);
523 if (!result)
524 result = Py_None;
526 Py_INCREF(result);
528 return result;
533 /* ignore structures we will not use */
534 %ignore ConnectionDelegate;
536 /* ignore functions we don't need */
537 // should we ignore vararg functions, or just convert them to functions with
538 // a fixed number of parameters?
539 %varargs(char*) wmessage;
540 //%ignore wmessage;
541 %ignore wwarning;
542 %ignore wfatal;
543 %ignore wsyserror;
544 %ignore wsyserrorwithcode;
545 %ignore WMCreatePLArray;
546 %ignore WMCreatePLDictionary;
548 %apply int *INPUT { int *argc };
550 #define Bool int
552 %include "WINGs/WUtil.h"
554 /* ignore structures we will not use */
556 /* ignore functions we don't need */
558 %include "WINGs/WINGs.h"
562 void
563 WHandleEvents()
565 /* Check any expired timers */
566 W_CheckTimerHandlers();
568 /* Do idle and timer stuff while there are no input events */
569 /* Do not wait for input here. just peek to se if input is available */
570 while (!W_HandleInputEvents(False, -1) && W_CheckIdleHandlers()) {
571 /* dispatch timer events */
572 W_CheckTimerHandlers();
575 W_HandleInputEvents(True, -1);
577 /* Check any expired timers */
578 W_CheckTimerHandlers();
583 /* rewrite functions originally defined as macros */
584 %inline %{
585 #undef WMDuplicateArray
586 WMArray* WMDuplicateArray(WMArray* array) {
587 return WMCreateArrayWithArray(array);
590 #undef WMPushInArray
591 void WMPushInArray(WMArray *array, void *item) {
592 WMAddToArray(array, item);
595 #undef WMSetInArray
596 void* WMSetInArray(WMArray *array, int index, void *item) {
597 return WMReplaceInArray(array, index, item);
600 #undef WMRemoveFromArray
601 int WMRemoveFromArray(WMArray *array, void *item) {
602 return WMRemoveFromArrayMatching(array, NULL, item);
605 #undef WMGetFirstInArray
606 int WMGetFirstInArray(WMArray *array, void *item) {
607 return WMFindInArray(array, NULL, item);
610 #undef WMCreateBag
611 WMBag* WMCreateBag(int size) {
612 return WMCreateTreeBag();
615 #undef WMCreateBagWithDestructor
616 WMBag* WMCreateBagWithDestructor(int size, WMFreeDataProc *destructor) {
617 return WMCreateTreeBagWithDestructor(destructor);
620 #undef WMSetInBag
621 void* WMSetInBag(WMBag *bag, int index, void *item) {
622 return WMReplaceInBag(bag, index, item);
625 #undef WMAddItemToTree
626 WMTreeNode* WMAddItemToTree(WMTreeNode *parent, void *item) {
627 return WMInsertItemInTree(parent, -1, item);
630 #undef WMAddNodeToTree
631 WMTreeNode* WMAddNodeToTree(WMTreeNode *parent, WMTreeNode *aNode) {
632 return WMInsertNodeInTree(parent, -1, aNode);
635 #undef WMGetFirstInTree
636 /* Returns first tree node that has data == cdata */
637 WMTreeNode* WMGetFirstInTree(WMTreeNode *aTree, void *cdata) {
638 return WMFindInTree(aTree, NULL, cdata);
641 #undef WMFlushConnection
642 int WMFlushConnection(WMConnection *cPtr) {
643 return WMSendConnectionData(cPtr, NULL);
646 #undef WMGetConnectionQueuedData
647 WMArray* WMGetConnectionQueuedData(WMConnection *cPtr) {
648 return WMGetConnectionUnsentData(cPtr);
651 #undef WMWidgetClass
652 W_Class WMWidgetClass(WMWidget *widget) {
653 return (((W_WidgetType*)(widget))->widgetClass);
656 #undef WMWidgetView
657 WMView* WMWidgetView(WMWidget *widget) {
658 return (((W_WidgetType*)(widget))->view);
661 #undef WMCreateCommandButton
662 WMButton* WMCreateCommandButton(WMWidget *parent) {
663 return WMCreateCustomButton(parent, WBBSpringLoadedMask|WBBPushInMask
664 |WBBPushLightMask|WBBPushChangeMask);
667 #undef WMCreateRadioButton
668 WMButton* WMCreateRadioButton(WMWidget *parent) {
669 return WMCreateButton(parent, WBTRadio);
672 #undef WMCreateSwitchButton
673 WMButton* WMCreateSwitchButton(WMWidget *parent) {
674 return WMCreateButton(parent, WBTSwitch);
677 #undef WMAddListItem
678 WMListItem* WMAddListItem(WMList *lPtr, char *text)
680 return WMInsertListItem(lPtr, -1, text);
683 #undef WMCreateText
684 WMText* WMCreateText(WMWidget *parent) {
685 return WMCreateTextForDocumentType(parent, NULL, NULL);
688 #undef WMRefreshText
689 void WMRefreshText(WMText *tPtr) {
690 return WMThawText(tPtr);
693 #undef WMClearText
694 void WMClearText(WMText *tPtr) {
695 return WMAppendTextStream(tPtr, NULL);