Catch situations where currentframe() returns None. See SF patch #1447410, this is...
[python.git] / Modules / flmodule.c
blobaa0d04e4059b83c9a95394200b3af9f4ff8ed9c0
1 /* FL module -- interface to Mark Overmars' FORMS Library. */
3 /* This code works with FORMS version 2.2 (if you defined
4 OBSOLETE_FORMS_CALLS), and 2.3.
5 FORMS can be ftp'ed from ftp.cs.ruu.nl (131.211.80.17), directory
6 /pub/SGI/FORMS. */
8 /* A half-hearted attempt has been made to allow programs using this
9 * module to exploit parallelism (through the threads module). No provisions
10 * have been made for multiple threads to use this module at the same time,
11 * though. So, a program with a forms thread and a non-forms thread will work
12 * fine but a program with two threads using forms will probably crash (unless
13 * the program takes precaution to ensure that only one thread can be in
14 * this module at any time). This will have to be fixed some time.
15 * (A fix will probably also have to synchronize with the gl module).
18 #include "Python.h"
19 #include "forms.h"
20 #include "structmember.h"
22 /* Generic Forms Objects */
24 typedef struct {
25 PyObject_HEAD
26 FL_OBJECT *ob_generic;
27 PyMethodDef *ob_methods;
28 PyObject *ob_callback;
29 PyObject *ob_callback_arg;
30 } genericobject;
32 static PyTypeObject GenericObjecttype;
34 #define is_genericobject(g) ((g)->ob_type == &GenericObjecttype)
36 /* List of all objects (XXX this should be a hash table on address...) */
38 static PyObject *allgenerics = NULL;
39 static int nfreeslots = 0;
41 /* Add an object to the list of known objects */
43 static void
44 knowgeneric(genericobject *g)
46 int i, n;
47 /* Create the list if it doesn't already exist */
48 if (allgenerics == NULL) {
49 allgenerics = PyList_New(0);
50 if (allgenerics == NULL) {
51 PyErr_Clear();
52 return; /* Too bad, live without allgenerics... */
55 if (nfreeslots > 0) {
56 /* Search the list for reusable slots (NULL items) */
57 /* XXX This can be made faster! */
58 n = PyList_Size(allgenerics);
59 for (i = 0; i < n; i++) {
60 if (PyList_GetItem(allgenerics, i) == NULL) {
61 Py_INCREF(g);
62 PyList_SetItem(allgenerics, i, (PyObject *)g);
63 nfreeslots--;
64 return;
67 /* Strange... no free slots found... */
68 nfreeslots = 0;
70 /* No free entries, append new item to the end */
71 PyList_Append(allgenerics, (PyObject *)g);
74 /* Find an object in the list of known objects */
76 static genericobject *
77 findgeneric(FL_OBJECT *generic)
79 int i, n;
80 genericobject *g;
82 if (allgenerics == NULL)
83 return NULL; /* No objects known yet */
84 n = PyList_Size(allgenerics);
85 for (i = 0; i < n; i++) {
86 g = (genericobject *)PyList_GetItem(allgenerics, i);
87 if (g != NULL && g->ob_generic == generic)
88 return g;
90 return NULL; /* Unknown object */
93 /* Remove an object from the list of known objects */
95 static void
96 forgetgeneric(genericobject *g)
98 int i, n;
100 Py_XDECREF(g->ob_callback);
101 g->ob_callback = NULL;
102 Py_XDECREF(g->ob_callback_arg);
103 g->ob_callback_arg = NULL;
104 if (allgenerics == NULL)
105 return; /* No objects known yet */
106 n = PyList_Size(allgenerics);
107 for (i = 0; i < n; i++) {
108 if (g == (genericobject *)PyList_GetItem(allgenerics, i)) {
109 PyList_SetItem(allgenerics, i, (PyObject *)NULL);
110 nfreeslots++;
111 break;
116 /* Called when a form is about to be freed --
117 remove all the objects that we know about from it. */
119 static void
120 releaseobjects(FL_FORM *form)
122 int i, n;
123 genericobject *g;
125 if (allgenerics == NULL)
126 return; /* No objects known yet */
127 n = PyList_Size(allgenerics);
128 for (i = 0; i < n; i++) {
129 g = (genericobject *)PyList_GetItem(allgenerics, i);
130 if (g != NULL && g->ob_generic->form == form) {
131 fl_delete_object(g->ob_generic);
132 /* The object is now unreachable for
133 do_forms and check_forms, so
134 delete it from the list of known objects */
135 Py_XDECREF(g->ob_callback);
136 g->ob_callback = NULL;
137 Py_XDECREF(g->ob_callback_arg);
138 g->ob_callback_arg = NULL;
139 PyList_SetItem(allgenerics, i, (PyObject *)NULL);
140 nfreeslots++;
146 /* Methods of generic objects */
148 static PyObject *
149 generic_set_call_back(genericobject *g, PyObject *args)
151 if (args == NULL) {
152 Py_XDECREF(g->ob_callback);
153 Py_XDECREF(g->ob_callback_arg);
154 g->ob_callback = NULL;
155 g->ob_callback_arg = NULL;
157 else {
158 if (!PyTuple_Check(args) || PyTuple_Size(args) != 2) {
159 PyErr_BadArgument();
160 return NULL;
162 Py_XDECREF(g->ob_callback);
163 Py_XDECREF(g->ob_callback_arg);
164 g->ob_callback = PyTuple_GetItem(args, 0);
165 Py_INCREF(g->ob_callback);
166 g->ob_callback_arg = PyTuple_GetItem(args, 1);
167 Py_INCREF(g->ob_callback_arg);
169 Py_INCREF(Py_None);
170 return Py_None;
173 static PyObject *
174 generic_call(genericobject *g, void (*func)(FL_OBJECT *))
176 (*func)(g->ob_generic);
177 Py_INCREF(Py_None);
178 return Py_None;
181 static PyObject *
182 generic_delete_object(genericobject *g)
184 PyObject *res;
185 res = generic_call(g, fl_delete_object);
186 if (res != NULL)
187 forgetgeneric(g);
188 return res;
191 static PyObject *
192 generic_show_object(genericobject *g)
194 return generic_call(g, fl_show_object);
197 static PyObject *
198 generic_hide_object(genericobject *g)
200 return generic_call(g, fl_hide_object);
203 static PyObject *
204 generic_redraw_object(genericobject *g)
206 return generic_call(g, fl_redraw_object);
209 #ifdef OBSOLETE_FORMS_CALLS
211 /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported
212 in 2.3. Since there's no foolproof way to tell which version we're
213 using, we omit them unconditionally. */
215 static PyObject *
216 generic_freeze_object(genericobject *g)
218 return generic_call(g, fl_freeze_object);
221 static PyObject *
222 generic_unfreeze_object(genericobject *g)
224 return generic_call(g, fl_unfreeze_object);
227 #endif /* OBSOLETE_FORMS_CALLS */
229 static PyObject *
230 generic_activate_object(genericobject *g)
232 return generic_call(g, fl_activate_object);
235 static PyObject *
236 generic_deactivate_object(genericobject *g)
238 return generic_call(g, fl_deactivate_object);
241 static PyObject *
242 generic_set_object_shortcut(genericobject *g, PyObject *args)
244 char *str;
245 if (!PyArg_ParseTuple(args, "s:set_object_shortcut", &str))
246 return NULL;
247 fl_set_object_shortcut(g->ob_generic, str);
248 Py_INCREF(Py_None);
249 return Py_None;
252 static PyMethodDef generic_methods[] = {
253 {"set_call_back", (PyCFunction)generic_set_call_back, METH_OLDARGS},
254 {"delete_object", (PyCFunction)generic_delete_object, METH_NOARGS},
255 {"show_object", (PyCFunction)generic_show_object, METH_NOARGS},
256 {"hide_object", (PyCFunction)generic_hide_object, METH_NOARGS},
257 {"redraw_object", (PyCFunction)generic_redraw_object, METH_NOARGS},
258 #ifdef OBSOLETE_FORMS_CALLS
259 {"freeze_object", (PyCFunction)generic_freeze_object, METH_NOARGS},
260 {"unfreeze_object", (PyCFunction)generic_unfreeze_object, METH_NOARGS},
261 #endif
262 {"activate_object", (PyCFunction)generic_activate_object, METH_NOARGS},
263 {"deactivate_object", (PyCFunction)generic_deactivate_object, METH_NOARGS},
264 {"set_object_shortcut", (PyCFunction)generic_set_object_shortcut, METH_OLDARGS},
265 {NULL, NULL} /* sentinel */
268 static void
269 generic_dealloc(genericobject *g)
271 fl_free_object(g->ob_generic);
272 Py_XDECREF(g->ob_callback);
273 Py_XDECREF(g->ob_callback_arg);
274 PyObject_Del(g);
277 #define OFF(x) offsetof(FL_OBJECT, x)
279 static struct memberlist generic_memberlist[] = {
280 {"objclass", T_INT, OFF(objclass), RO},
281 {"type", T_INT, OFF(type), RO},
282 {"boxtype", T_INT, OFF(boxtype)},
283 {"x", T_FLOAT, OFF(x)},
284 {"y", T_FLOAT, OFF(y)},
285 {"w", T_FLOAT, OFF(w)},
286 {"h", T_FLOAT, OFF(h)},
287 {"col1", T_INT, OFF(col1)},
288 {"col2", T_INT, OFF(col2)},
289 {"align", T_INT, OFF(align)},
290 {"lcol", T_INT, OFF(lcol)},
291 {"lsize", T_FLOAT, OFF(lsize)},
292 /* "label" is treated specially! */
293 {"lstyle", T_INT, OFF(lstyle)},
294 {"pushed", T_INT, OFF(pushed), RO},
295 {"focus", T_INT, OFF(focus), RO},
296 {"belowmouse", T_INT, OFF(belowmouse),RO},
297 /* {"frozen", T_INT, OFF(frozen), RO}, */
298 {"active", T_INT, OFF(active)},
299 {"input", T_INT, OFF(input)},
300 {"visible", T_INT, OFF(visible), RO},
301 {"radio", T_INT, OFF(radio)},
302 {"automatic", T_INT, OFF(automatic)},
303 {NULL} /* Sentinel */
306 #undef OFF
308 static PyObject *
309 generic_getattr(genericobject *g, char *name)
311 PyObject *meth;
313 /* XXX Ought to special-case name "__methods__" */
314 if (g-> ob_methods) {
315 meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);
316 if (meth != NULL) return meth;
317 PyErr_Clear();
320 meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
321 if (meth != NULL)
322 return meth;
323 PyErr_Clear();
325 /* "label" is an exception, getmember only works for char pointers,
326 not for char arrays */
327 if (strcmp(name, "label") == 0)
328 return PyString_FromString(g->ob_generic->label);
330 return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
333 static int
334 generic_setattr(genericobject *g, char *name, PyObject *v)
336 int ret;
338 if (v == NULL) {
339 PyErr_SetString(PyExc_TypeError,
340 "can't delete forms object attributes");
341 return -1;
344 /* "label" is an exception: setmember doesn't set strings;
345 and FORMS wants you to call a function to set the label */
346 if (strcmp(name, "label") == 0) {
347 if (!PyString_Check(v)) {
348 PyErr_SetString(PyExc_TypeError,
349 "label attr must be string");
350 return -1;
352 fl_set_object_label(g->ob_generic, PyString_AsString(v));
353 return 0;
356 ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
358 /* Rather than calling all the various set_object_* functions,
359 we call fl_redraw_object here. This is sometimes redundant
360 but I doubt that's a big problem */
361 if (ret == 0)
362 fl_redraw_object(g->ob_generic);
364 return ret;
367 static PyObject *
368 generic_repr(genericobject *g)
370 char buf[100];
371 PyOS_snprintf(buf, sizeof(buf), "<FORMS_object at %p, objclass=%d>",
372 g, g->ob_generic->objclass);
373 return PyString_FromString(buf);
376 static PyTypeObject GenericObjecttype = {
377 PyObject_HEAD_INIT(&PyType_Type)
378 0, /*ob_size*/
379 "fl.FORMS_object", /*tp_name*/
380 sizeof(genericobject), /*tp_size*/
381 0, /*tp_itemsize*/
382 /* methods */
383 (destructor)generic_dealloc, /*tp_dealloc*/
384 0, /*tp_print*/
385 (getattrfunc)generic_getattr, /*tp_getattr*/
386 (setattrfunc)generic_setattr, /*tp_setattr*/
387 0, /*tp_compare*/
388 (reprfunc)generic_repr, /*tp_repr*/
391 static PyObject *
392 newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
394 genericobject *g;
395 g = PyObject_New(genericobject, &GenericObjecttype);
396 if (g == NULL)
397 return NULL;
398 g-> ob_generic = generic;
399 g->ob_methods = methods;
400 g->ob_callback = NULL;
401 g->ob_callback_arg = NULL;
402 knowgeneric(g);
403 return (PyObject *)g;
406 /**********************************************************************/
407 /* Some common calling sequences */
409 /* void func (object, float) */
410 static PyObject *
411 call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
413 float parameter;
415 if (!PyArg_Parse(args, "f", &parameter)) return NULL;
417 (*func) (obj, parameter);
419 Py_INCREF(Py_None);
420 return Py_None;
423 /* void func (object, float) */
424 static PyObject *
425 call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
427 float par1, par2;
429 if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
431 (*func) (obj, par1, par2);
433 Py_INCREF(Py_None);
434 return Py_None;
437 /* void func (object, int) */
438 static PyObject *
439 call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
441 int parameter;
443 if (!PyArg_Parse(args, "i", &parameter)) return NULL;
445 (*func) (obj, parameter);
447 Py_INCREF(Py_None);
448 return Py_None;
451 /* void func (object, char) */
452 static PyObject *
453 call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
455 char *a;
457 if (!PyArg_Parse(args, "s", &a)) return NULL;
459 (*func) (obj, a[0]);
461 Py_INCREF(Py_None);
462 return Py_None;
465 /* void func (object, string) */
466 static PyObject *
467 call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
469 char *a;
471 if (!PyArg_Parse(args, "s", &a)) return NULL;
473 (*func) (obj, a);
475 Py_INCREF(Py_None);
476 return Py_None;
480 /* void func (object, int, string) */
481 static PyObject *
482 call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
484 char *b;
485 int a;
487 if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
489 (*func) (obj, a, b);
491 Py_INCREF(Py_None);
492 return Py_None;
495 #ifdef UNUSED
496 /* void func (object, int, int) */
497 static PyObject *
498 call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
500 int par1, par2;
502 if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
504 (*func) (obj, par1, par2);
506 Py_INCREF(Py_None);
507 return Py_None;
509 #endif
511 /* int func (object) */
512 static PyObject *
513 call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj)
515 int retval;
517 retval = (*func) (obj);
519 return PyInt_FromLong ((long) retval);
522 /* char * func (object) */
523 static PyObject *
524 call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj)
526 char *str;
528 str = (*func) (obj);
530 if (str == NULL) {
531 Py_INCREF(Py_None);
532 return Py_None;
534 return PyString_FromString (str);
537 /* int func (object) */
538 static PyObject *
539 call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj)
541 float retval;
543 retval = (*func) (obj);
545 return PyFloat_FromDouble (retval);
548 static PyObject *
549 call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj)
551 float f1, f2;
553 (*func) (obj, &f1, &f2);
555 return Py_BuildValue("(ff)", f1, f2);
558 #ifdef UNUSED
559 static PyObject *
560 call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj)
562 float f;
564 (*func) (obj, &f);
566 return PyFloat_FromDouble (f);
568 #endif
570 /**********************************************************************/
571 /* Class : browser */
573 static PyObject *
574 set_browser_topline(genericobject *g, PyObject *args)
576 return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
579 static PyObject *
580 clear_browser(genericobject *g)
582 return generic_call (g, fl_clear_browser);
585 static PyObject *
586 add_browser_line (genericobject *g, PyObject *args)
588 return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
591 static PyObject *
592 addto_browser (genericobject *g, PyObject *args)
594 return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
597 static PyObject *
598 insert_browser_line (genericobject *g, PyObject *args)
600 return call_forms_INiINstr (fl_insert_browser_line,
601 g-> ob_generic, args);
604 static PyObject *
605 delete_browser_line (genericobject *g, PyObject *args)
607 return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
610 static PyObject *
611 replace_browser_line (genericobject *g, PyObject *args)
613 return call_forms_INiINstr (fl_replace_browser_line,
614 g-> ob_generic, args);
617 static PyObject *
618 get_browser_line(genericobject *g, PyObject *args)
620 int i;
621 char *str;
623 if (!PyArg_Parse(args, "i", &i))
624 return NULL;
626 str = fl_get_browser_line (g->ob_generic, i);
628 if (str == NULL) {
629 Py_INCREF(Py_None);
630 return Py_None;
632 return PyString_FromString (str);
635 static PyObject *
636 load_browser (genericobject *g, PyObject *args)
638 /* XXX strictly speaking this is wrong since fl_load_browser
639 XXX returns int, not void */
640 return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
643 static PyObject *
644 get_browser_maxline(genericobject *g)
646 return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
649 static PyObject *
650 select_browser_line (genericobject *g, PyObject *args)
652 return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
655 static PyObject *
656 deselect_browser_line (genericobject *g, PyObject *args)
658 return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
661 static PyObject *
662 deselect_browser (genericobject *g)
664 return generic_call (g, fl_deselect_browser);
667 static PyObject *
668 isselected_browser_line (genericobject *g, PyObject *args)
670 int i, j;
672 if (!PyArg_Parse(args, "i", &i))
673 return NULL;
675 j = fl_isselected_browser_line (g->ob_generic, i);
677 return PyInt_FromLong (j);
680 static PyObject *
681 get_browser (genericobject *g)
683 return call_forms_Ri (fl_get_browser, g-> ob_generic);
686 static PyObject *
687 set_browser_fontsize (genericobject *g, PyObject *args)
689 return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
692 static PyObject *
693 set_browser_fontstyle (genericobject *g, PyObject *args)
695 return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
698 static PyObject *
699 set_browser_specialkey (genericobject *g, PyObject *args)
701 return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
704 static PyMethodDef browser_methods[] = {
705 {"set_browser_topline", (PyCFunction)set_browser_topline,
706 METH_OLDARGS},
707 {"clear_browser", (PyCFunction)clear_browser,
708 METH_NOARGS},
709 {"add_browser_line", (PyCFunction)add_browser_line,
710 METH_OLDARGS},
711 {"addto_browser", (PyCFunction)addto_browser,
712 METH_OLDARGS},
713 {"insert_browser_line", (PyCFunction)insert_browser_line,
714 METH_OLDARGS},
715 {"delete_browser_line", (PyCFunction)delete_browser_line,
716 METH_OLDARGS},
717 {"replace_browser_line", (PyCFunction)replace_browser_line,
718 METH_OLDARGS},
719 {"get_browser_line", (PyCFunction)get_browser_line,
720 METH_OLDARGS},
721 {"load_browser", (PyCFunction)load_browser,
722 METH_OLDARGS},
723 {"get_browser_maxline", (PyCFunction)get_browser_maxline,
724 METH_NOARGS,}
725 {"select_browser_line", (PyCFunction)select_browser_line,
726 METH_OLDARGS},
727 {"deselect_browser_line", (PyCFunction)deselect_browser_line,
728 METH_OLDARGS},
729 {"deselect_browser", (PyCFunction)deselect_browser,
730 METH_NOARGS,}
731 {"isselected_browser_line", (PyCFunction)isselected_browser_line,
732 METH_OLDARGS},
733 {"get_browser", (PyCFunction)get_browser,
734 METH_NOARGS,}
735 {"set_browser_fontsize", (PyCFunction)set_browser_fontsize,
736 METH_OLDARGS},
737 {"set_browser_fontstyle", (PyCFunction)set_browser_fontstyle,
738 METH_OLDARGS},
739 {"set_browser_specialkey", (PyCFunction)set_browser_specialkey,
740 METH_OLDARGS},
741 {NULL, NULL} /* sentinel */
744 /* Class: button */
746 static PyObject *
747 set_button(genericobject *g, PyObject *args)
749 return call_forms_INi (fl_set_button, g-> ob_generic, args);
752 static PyObject *
753 get_button(genericobject *g)
755 return call_forms_Ri (fl_get_button, g-> ob_generic);
758 static PyObject *
759 get_button_numb(genericobject *g)
761 return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
764 static PyObject *
765 set_button_shortcut(genericobject *g, PyObject *args)
767 return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
770 static PyMethodDef button_methods[] = {
771 {"set_button", (PyCFunction)set_button, METH_OLDARGS},
772 {"get_button", (PyCFunction)get_button, METH_NOARGS},
773 {"get_button_numb", (PyCFunction)get_button_numb, METH_NOARGS},
774 {"set_button_shortcut", (PyCFunction)set_button_shortcut, METH_OLDARGS},
775 {NULL, NULL} /* sentinel */
778 /* Class: choice */
780 static PyObject *
781 set_choice(genericobject *g, PyObject *args)
783 return call_forms_INi (fl_set_choice, g-> ob_generic, args);
786 static PyObject *
787 get_choice(genericobject *g)
789 return call_forms_Ri (fl_get_choice, g-> ob_generic);
792 static PyObject *
793 clear_choice (genericobject *g)
795 return generic_call (g, fl_clear_choice);
798 static PyObject *
799 addto_choice (genericobject *g, PyObject *args)
801 return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
804 static PyObject *
805 replace_choice (genericobject *g, PyObject *args)
807 return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
810 static PyObject *
811 delete_choice (genericobject *g, PyObject *args)
813 return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
816 static PyObject *
817 get_choice_text (genericobject *g)
819 return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
822 static PyObject *
823 set_choice_fontsize (genericobject *g, PyObject *args)
825 return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
828 static PyObject *
829 set_choice_fontstyle (genericobject *g, PyObject *args)
831 return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
834 static PyMethodDef choice_methods[] = {
835 {"set_choice", (PyCFunction)set_choice, METH_OLDARGS},
836 {"get_choice", (PyCFunction)get_choice, METH_NOARGS},
837 {"clear_choice", (PyCFunction)clear_choice, METH_NOARGS},
838 {"addto_choice", (PyCFunction)addto_choice, METH_OLDARGS},
839 {"replace_choice", (PyCFunction)replace_choice, METH_OLDARGS},
840 {"delete_choice", (PyCFunction)delete_choice, METH_OLDARGS},
841 {"get_choice_text", (PyCFunction)get_choice_text, METH_NOARGS},
842 {"set_choice_fontsize", (PyCFunction)set_choice_fontsize, METH_OLDARGS},
843 {"set_choice_fontstyle",(PyCFunction)set_choice_fontstyle, METH_OLDARGS},
844 {NULL, NULL} /* sentinel */
847 /* Class : Clock */
849 static PyObject *
850 get_clock(genericobject *g)
852 int i0, i1, i2;
854 fl_get_clock (g->ob_generic, &i0, &i1, &i2);
856 return Py_BuildValue("(iii)", i0, i1, i2);
859 static PyMethodDef clock_methods[] = {
860 {"get_clock", (PyCFunction)get_clock, METH_NOARGS},
861 {NULL, NULL} /* sentinel */
864 /* CLass : Counters */
866 static PyObject *
867 get_counter_value(genericobject *g)
869 return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
872 static PyObject *
873 set_counter_value (genericobject *g, PyObject *args)
875 return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
878 static PyObject *
879 set_counter_precision (genericobject *g, PyObject *args)
881 return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
884 static PyObject *
885 set_counter_bounds (genericobject *g, PyObject *args)
887 return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
890 static PyObject *
891 set_counter_step (genericobject *g, PyObject *args)
893 return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
896 static PyObject *
897 set_counter_return (genericobject *g, PyObject *args)
899 return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
902 static PyMethodDef counter_methods[] = {
903 {"set_counter_value", (PyCFunction)set_counter_value,
904 METH_OLDARGS},
905 {"get_counter_value", (PyCFunction)get_counter_value,
906 METH_NOARGS},
907 {"set_counter_bounds", (PyCFunction)set_counter_bounds,
908 METH_OLDARGS},
909 {"set_counter_step", (PyCFunction)set_counter_step,
910 METH_OLDARGS},
911 {"set_counter_precision", (PyCFunction)set_counter_precision,
912 METH_OLDARGS},
913 {"set_counter_return", (PyCFunction)set_counter_return,
914 METH_OLDARGS},
915 {NULL, NULL} /* sentinel */
919 /* Class: Dials */
921 static PyObject *
922 get_dial_value(genericobject *g)
924 return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
927 static PyObject *
928 set_dial_value (genericobject *g, PyObject *args)
930 return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
933 static PyObject *
934 set_dial_bounds (genericobject *g, PyObject *args)
936 return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
939 static PyObject *
940 get_dial_bounds (genericobject *g)
942 return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
945 static PyObject *
946 set_dial_step (genericobject *g, PyObject *args)
948 return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
951 static PyMethodDef dial_methods[] = {
952 {"set_dial_value", (PyCFunction)set_dial_value, METH_OLDARGS},
953 {"get_dial_value", (PyCFunction)get_dial_value, METH_NOARGS},
954 {"set_dial_bounds", (PyCFunction)set_dial_bounds, METH_OLDARGS},
955 {"get_dial_bounds", (PyCFunction)get_dial_bounds, METH_NOARGS},
956 {"set_dial_step", (PyCFunction)set_dial_step, METH_OLDARGS},
957 {NULL, NULL} /* sentinel */
960 /* Class : Input */
962 static PyObject *
963 set_input (genericobject *g, PyObject *args)
965 return call_forms_INstr (fl_set_input, g-> ob_generic, args);
968 static PyObject *
969 get_input (genericobject *g)
971 return call_forms_Rstr (fl_get_input, g-> ob_generic);
974 static PyObject *
975 set_input_color (genericobject *g, PyObject *args)
977 return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
980 static PyObject *
981 set_input_return (genericobject *g, PyObject *args)
983 return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
986 static PyMethodDef input_methods[] = {
987 {"set_input", (PyCFunction)set_input, METH_OLDARGS},
988 {"get_input", (PyCFunction)get_input, METH_NOARGS},
989 {"set_input_color", (PyCFunction)set_input_color, METH_OLDARGS},
990 {"set_input_return", (PyCFunction)set_input_return, METH_OLDARGS},
991 {NULL, NULL} /* sentinel */
995 /* Class : Menu */
997 static PyObject *
998 set_menu (genericobject *g, PyObject *args)
1000 return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
1003 static PyObject *
1004 get_menu (genericobject *g)
1006 /* XXX strictly speaking this is wrong since fl_get_menu
1007 XXX returns long, not int */
1008 return call_forms_Ri (fl_get_menu, g-> ob_generic);
1011 static PyObject *
1012 get_menu_text (genericobject *g)
1014 return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
1017 static PyObject *
1018 addto_menu (genericobject *g, PyObject *args)
1020 return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
1023 static PyMethodDef menu_methods[] = {
1024 {"set_menu", (PyCFunction)set_menu, METH_OLDARGS},
1025 {"get_menu", (PyCFunction)get_menu, METH_NOARGS},
1026 {"get_menu_text", (PyCFunction)get_menu_text, METH_NOARGS},
1027 {"addto_menu", (PyCFunction)addto_menu, METH_OLDARGS},
1028 {NULL, NULL} /* sentinel */
1032 /* Class: Sliders */
1034 static PyObject *
1035 get_slider_value(genericobject *g)
1037 return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
1040 static PyObject *
1041 set_slider_value (genericobject *g, PyObject *args)
1043 return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
1046 static PyObject *
1047 set_slider_bounds (genericobject *g, PyObject *args)
1049 return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
1052 static PyObject *
1053 get_slider_bounds (genericobject *g)
1055 return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
1058 static PyObject *
1059 set_slider_return (genericobject *g, PyObject *args)
1061 return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
1064 static PyObject *
1065 set_slider_size (genericobject *g, PyObject *args)
1067 return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
1070 static PyObject *
1071 set_slider_precision (genericobject *g, PyObject *args)
1073 return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
1076 static PyObject *
1077 set_slider_step (genericobject *g, PyObject *args)
1079 return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
1083 static PyMethodDef slider_methods[] = {
1084 {"set_slider_value", (PyCFunction)set_slider_value, METH_OLDARGS},
1085 {"get_slider_value", (PyCFunction)get_slider_value, METH_NOARGS},
1086 {"set_slider_bounds", (PyCFunction)set_slider_bounds, METH_OLDARGS},
1087 {"get_slider_bounds", (PyCFunction)get_slider_bounds, METH_NOARGS},
1088 {"set_slider_return", (PyCFunction)set_slider_return, METH_OLDARGS},
1089 {"set_slider_size", (PyCFunction)set_slider_size, METH_OLDARGS},
1090 {"set_slider_precision",(PyCFunction)set_slider_precision, METH_OLDARGS},
1091 {"set_slider_step", (PyCFunction)set_slider_step, METH_OLDARGS},
1092 {NULL, NULL} /* sentinel */
1095 static PyObject *
1096 set_positioner_xvalue (genericobject *g, PyObject *args)
1098 return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
1101 static PyObject *
1102 set_positioner_xbounds (genericobject *g, PyObject *args)
1104 return call_forms_INfINf (fl_set_positioner_xbounds,
1105 g-> ob_generic, args);
1108 static PyObject *
1109 set_positioner_yvalue (genericobject *g, PyObject *args)
1111 return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
1114 static PyObject *
1115 set_positioner_ybounds (genericobject *g, PyObject *args)
1117 return call_forms_INfINf (fl_set_positioner_ybounds,
1118 g-> ob_generic, args);
1121 static PyObject *
1122 get_positioner_xvalue (genericobject *g)
1124 return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
1127 static PyObject *
1128 get_positioner_xbounds (genericobject *g)
1130 return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
1133 static PyObject *
1134 get_positioner_yvalue (genericobject *g)
1136 return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
1139 static PyObject *
1140 get_positioner_ybounds (genericobject *g)
1142 return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
1145 static PyMethodDef positioner_methods[] = {
1146 {"set_positioner_xvalue", (PyCFunction)set_positioner_xvalue,
1147 METH_OLDARGS},
1148 {"set_positioner_yvalue", (PyCFunction)set_positioner_yvalue,
1149 METH_OLDARGS},
1150 {"set_positioner_xbounds", (PyCFunction)set_positioner_xbounds,
1151 METH_OLDARGS},
1152 {"set_positioner_ybounds", (PyCFunction)set_positioner_ybounds,
1153 METH_OLDARGS},
1154 {"get_positioner_xvalue", (PyCFunction)get_positioner_xvalue,
1155 METH_NOARGS},
1156 {"get_positioner_yvalue", (PyCFunction)get_positioner_yvalue,
1157 METH_NOARGS},
1158 {"get_positioner_xbounds", (PyCFunction)get_positioner_xbounds,
1159 METH_NOARGS},
1160 {"get_positioner_ybounds", (PyCFunction)get_positioner_ybounds,
1161 METH_NOARGS},
1162 {NULL, NULL} /* sentinel */
1165 /* Class timer */
1167 static PyObject *
1168 set_timer (genericobject *g, PyObject *args)
1170 return call_forms_INf (fl_set_timer, g-> ob_generic, args);
1173 static PyObject *
1174 get_timer (genericobject *g)
1176 return call_forms_Rf (fl_get_timer, g-> ob_generic);
1179 static PyMethodDef timer_methods[] = {
1180 {"set_timer", (PyCFunction)set_timer, METH_OLDARGS},
1181 {"get_timer", (PyCFunction)get_timer, METH_NOARGS},
1182 {NULL, NULL} /* sentinel */
1185 /* Form objects */
1187 typedef struct {
1188 PyObject_HEAD
1189 FL_FORM *ob_form;
1190 } formobject;
1192 static PyTypeObject Formtype;
1194 #define is_formobject(v) ((v)->ob_type == &Formtype)
1196 static PyObject *
1197 form_show_form(formobject *f, PyObject *args)
1199 int place, border;
1200 char *name;
1201 if (!PyArg_Parse(args, "(iis)", &place, &border, &name))
1202 return NULL;
1203 fl_show_form(f->ob_form, place, border, name);
1204 Py_INCREF(Py_None);
1205 return Py_None;
1208 static PyObject *
1209 form_call(void (*func)(FL_FORM *), FL_FORM *f)
1211 (*func)(f);
1213 Py_INCREF(Py_None);
1214 return Py_None;
1217 static PyObject *
1218 form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
1220 int a, b;
1222 if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
1224 (*func)(f, a, b);
1226 Py_INCREF(Py_None);
1227 return Py_None;
1230 static PyObject *
1231 form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
1233 float a, b;
1235 if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
1237 (*func)(f, a, b);
1239 Py_INCREF(Py_None);
1240 return Py_None;
1243 static PyObject *
1244 form_hide_form(formobject *f)
1246 return form_call(fl_hide_form, f-> ob_form);
1249 static PyObject *
1250 form_redraw_form(formobject *f)
1252 return form_call(fl_redraw_form, f-> ob_form);
1255 static PyObject *
1256 form_set_form_position(formobject *f, PyObject *args)
1258 return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
1261 static PyObject *
1262 form_set_form_size(formobject *f, PyObject *args)
1264 return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
1267 static PyObject *
1268 form_scale_form(formobject *f, PyObject *args)
1270 return form_call_INfINf(fl_scale_form, f-> ob_form, args);
1273 static PyObject *
1274 generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
1276 int type;
1277 float x, y, w, h;
1278 char *name;
1279 FL_OBJECT *obj;
1281 if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
1282 return NULL;
1284 fl_addto_form (f-> ob_form);
1286 obj = (*func) (type, x, y, w, h, name);
1288 fl_end_form();
1290 if (obj == NULL) {
1291 PyErr_NoMemory();
1292 return NULL;
1295 return newgenericobject (obj, internal_methods);
1298 static PyObject *
1299 form_add_button(formobject *f, PyObject *args)
1301 return generic_add_object(f, args, fl_add_button, button_methods);
1304 static PyObject *
1305 form_add_lightbutton(formobject *f, PyObject *args)
1307 return generic_add_object(f, args, fl_add_lightbutton, button_methods);
1310 static PyObject *
1311 form_add_roundbutton(formobject *f, PyObject *args)
1313 return generic_add_object(f, args, fl_add_roundbutton, button_methods);
1316 static PyObject *
1317 form_add_menu (formobject *f, PyObject *args)
1319 return generic_add_object(f, args, fl_add_menu, menu_methods);
1322 static PyObject *
1323 form_add_slider(formobject *f, PyObject *args)
1325 return generic_add_object(f, args, fl_add_slider, slider_methods);
1328 static PyObject *
1329 form_add_valslider(formobject *f, PyObject *args)
1331 return generic_add_object(f, args, fl_add_valslider, slider_methods);
1334 static PyObject *
1335 form_add_dial(formobject *f, PyObject *args)
1337 return generic_add_object(f, args, fl_add_dial, dial_methods);
1340 static PyObject *
1341 form_add_counter(formobject *f, PyObject *args)
1343 return generic_add_object(f, args, fl_add_counter, counter_methods);
1346 static PyObject *
1347 form_add_clock(formobject *f, PyObject *args)
1349 return generic_add_object(f, args, fl_add_clock, clock_methods);
1352 static PyObject *
1353 form_add_box(formobject *f, PyObject *args)
1355 return generic_add_object(f, args, fl_add_box,
1356 (PyMethodDef *)NULL);
1359 static PyObject *
1360 form_add_choice(formobject *f, PyObject *args)
1362 return generic_add_object(f, args, fl_add_choice, choice_methods);
1365 static PyObject *
1366 form_add_browser(formobject *f, PyObject *args)
1368 return generic_add_object(f, args, fl_add_browser, browser_methods);
1371 static PyObject *
1372 form_add_positioner(formobject *f, PyObject *args)
1374 return generic_add_object(f, args, fl_add_positioner,
1375 positioner_methods);
1378 static PyObject *
1379 form_add_input(formobject *f, PyObject *args)
1381 return generic_add_object(f, args, fl_add_input, input_methods);
1384 static PyObject *
1385 form_add_text(formobject *f, PyObject *args)
1387 return generic_add_object(f, args, fl_add_text,
1388 (PyMethodDef *)NULL);
1391 static PyObject *
1392 form_add_timer(formobject *f, PyObject *args)
1394 return generic_add_object(f, args, fl_add_timer, timer_methods);
1397 static PyObject *
1398 form_freeze_form(formobject *f)
1400 return form_call(fl_freeze_form, f-> ob_form);
1403 static PyObject *
1404 form_unfreeze_form(formobject *f)
1406 return form_call(fl_unfreeze_form, f-> ob_form);
1409 static PyObject *
1410 form_activate_form(formobject *f)
1412 return form_call(fl_activate_form, f-> ob_form);
1415 static PyObject *
1416 form_deactivate_form(formobject *f)
1418 return form_call(fl_deactivate_form, f-> ob_form);
1421 static PyObject *
1422 form_bgn_group(formobject *f, PyObject *args)
1424 FL_OBJECT *obj;
1426 fl_addto_form(f-> ob_form);
1427 obj = fl_bgn_group();
1428 fl_end_form();
1430 if (obj == NULL) {
1431 PyErr_NoMemory();
1432 return NULL;
1435 return newgenericobject (obj, (PyMethodDef *) NULL);
1438 static PyObject *
1439 form_end_group(formobject *f, PyObject *args)
1441 fl_addto_form(f-> ob_form);
1442 fl_end_group();
1443 fl_end_form();
1444 Py_INCREF(Py_None);
1445 return Py_None;
1448 static PyObject *
1449 forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
1451 int type;
1452 float mx, my;
1453 FL_OBJECT *generic;
1454 genericobject *g;
1456 if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
1458 generic = (*func) (f-> ob_form, type, mx, my);
1460 if (generic == NULL)
1462 Py_INCREF(Py_None);
1463 return Py_None;
1466 g = findgeneric(generic);
1467 if (g == NULL) {
1468 PyErr_SetString(PyExc_RuntimeError,
1469 "forms_find_{first|last} returns unknown object");
1470 return NULL;
1472 Py_INCREF(g);
1473 return (PyObject *) g;
1476 static PyObject *
1477 form_find_first(formobject *f, PyObject *args)
1479 return forms_find_first_or_last(fl_find_first, f, args);
1482 static PyObject *
1483 form_find_last(formobject *f, PyObject *args)
1485 return forms_find_first_or_last(fl_find_last, f, args);
1488 static PyObject *
1489 form_set_object_focus(formobject *f, PyObject *args)
1491 genericobject *g;
1492 if (args == NULL || !is_genericobject(args)) {
1493 PyErr_BadArgument();
1494 return NULL;
1496 g = (genericobject *)args;
1497 fl_set_object_focus(f->ob_form, g->ob_generic);
1498 Py_INCREF(Py_None);
1499 return Py_None;
1502 static PyMethodDef form_methods[] = {
1503 /* adm */
1504 {"show_form", (PyCFunction)form_show_form, METH_OLDARGS},
1505 {"hide_form", (PyCFunction)form_hide_form, METH_NOARGS},
1506 {"redraw_form", (PyCFunction)form_redraw_form, METH_NOARGS},
1507 {"set_form_position", (PyCFunction)form_set_form_position, METH_OLDARGS},
1508 {"set_form_size", (PyCFunction)form_set_form_size, METH_OLDARGS},
1509 {"scale_form", (PyCFunction)form_scale_form, METH_OLDARGS},
1510 {"freeze_form", (PyCFunction)form_freeze_form, METH_NOARGS},
1511 {"unfreeze_form", (PyCFunction)form_unfreeze_form, METH_NOARGS},
1512 {"activate_form", (PyCFunction)form_activate_form, METH_NOARGS},
1513 {"deactivate_form", (PyCFunction)form_deactivate_form, METH_NOARGS},
1514 {"bgn_group", (PyCFunction)form_bgn_group, METH_OLDARGS},
1515 {"end_group", (PyCFunction)form_end_group, METH_OLDARGS},
1516 {"find_first", (PyCFunction)form_find_first, METH_OLDARGS},
1517 {"find_last", (PyCFunction)form_find_last, METH_OLDARGS},
1518 {"set_object_focus", (PyCFunction)form_set_object_focus, METH_OLDARGS},
1520 /* basic objects */
1521 {"add_button", (PyCFunction)form_add_button, METH_OLDARGS},
1522 /* {"add_bitmap", (method)form_add_bitmap, METH_OLDARGS}, */
1523 {"add_lightbutton", (PyCFunction)form_add_lightbutton, METH_OLDARGS},
1524 {"add_roundbutton", (PyCFunction)form_add_roundbutton, METH_OLDARGS},
1525 {"add_menu", (PyCFunction)form_add_menu, METH_OLDARGS},
1526 {"add_slider", (PyCFunction)form_add_slider, METH_OLDARGS},
1527 {"add_positioner", (PyCFunction)form_add_positioner, METH_OLDARGS},
1528 {"add_valslider", (PyCFunction)form_add_valslider, METH_OLDARGS},
1529 {"add_dial", (PyCFunction)form_add_dial, METH_OLDARGS},
1530 {"add_counter", (PyCFunction)form_add_counter, METH_OLDARGS},
1531 {"add_box", (PyCFunction)form_add_box, METH_OLDARGS},
1532 {"add_clock", (PyCFunction)form_add_clock, METH_OLDARGS},
1533 {"add_choice", (PyCFunction)form_add_choice, METH_OLDARGS},
1534 {"add_browser", (PyCFunction)form_add_browser, METH_OLDARGS},
1535 {"add_input", (PyCFunction)form_add_input, METH_OLDARGS},
1536 {"add_timer", (PyCFunction)form_add_timer, METH_OLDARGS},
1537 {"add_text", (PyCFunction)form_add_text, METH_OLDARGS},
1538 {NULL, NULL} /* sentinel */
1541 static void
1542 form_dealloc(formobject *f)
1544 releaseobjects(f->ob_form);
1545 if (f->ob_form->visible)
1546 fl_hide_form(f->ob_form);
1547 fl_free_form(f->ob_form);
1548 PyObject_Del(f);
1551 #define OFF(x) offsetof(FL_FORM, x)
1553 static struct memberlist form_memberlist[] = {
1554 {"window", T_LONG, OFF(window), RO},
1555 {"w", T_FLOAT, OFF(w)},
1556 {"h", T_FLOAT, OFF(h)},
1557 {"x", T_FLOAT, OFF(x), RO},
1558 {"y", T_FLOAT, OFF(y), RO},
1559 {"deactivated", T_INT, OFF(deactivated)},
1560 {"visible", T_INT, OFF(visible), RO},
1561 {"frozen", T_INT, OFF(frozen), RO},
1562 {"doublebuf", T_INT, OFF(doublebuf)},
1563 {NULL} /* Sentinel */
1566 #undef OFF
1568 static PyObject *
1569 form_getattr(formobject *f, char *name)
1571 PyObject *meth;
1573 meth = Py_FindMethod(form_methods, (PyObject *)f, name);
1574 if (meth != NULL)
1575 return meth;
1576 PyErr_Clear();
1577 return PyMember_Get((char *)f->ob_form, form_memberlist, name);
1580 static int
1581 form_setattr(formobject *f, char *name, PyObject *v)
1583 if (v == NULL) {
1584 PyErr_SetString(PyExc_TypeError,
1585 "can't delete form attributes");
1586 return -1;
1589 return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
1592 static PyObject *
1593 form_repr(formobject *f)
1595 char buf[100];
1596 PyOS_snprintf(buf, sizeof(buf), "<FORMS_form at %p, window=%ld>",
1597 f, f->ob_form->window);
1598 return PyString_FromString(buf);
1601 static PyTypeObject Formtype = {
1602 PyObject_HEAD_INIT(&PyType_Type)
1603 0, /*ob_size*/
1604 "fl.FORMS_form", /*tp_name*/
1605 sizeof(formobject), /*tp_size*/
1606 0, /*tp_itemsize*/
1607 /* methods */
1608 (destructor)form_dealloc, /*tp_dealloc*/
1609 0, /*tp_print*/
1610 (getattrfunc)form_getattr, /*tp_getattr*/
1611 (setattrfunc)form_setattr, /*tp_setattr*/
1612 0, /*tp_compare*/
1613 (reprfunc)form_repr, /*tp_repr*/
1616 static PyObject *
1617 newformobject(FL_FORM *form)
1619 formobject *f;
1620 f = PyObject_New(formobject, &Formtype);
1621 if (f == NULL)
1622 return NULL;
1623 f->ob_form = form;
1624 return (PyObject *)f;
1628 /* The "fl" module */
1630 static PyObject *
1631 forms_make_form(PyObject *dummy, PyObject *args)
1633 int type;
1634 float w, h;
1635 FL_FORM *form;
1636 if (!PyArg_Parse(args, "(iff)", &type, &w, &h))
1637 return NULL;
1638 form = fl_bgn_form(type, w, h);
1639 if (form == NULL) {
1640 /* XXX Actually, cannot happen! */
1641 PyErr_NoMemory();
1642 return NULL;
1644 fl_end_form();
1645 return newformobject(form);
1648 static PyObject *
1649 forms_activate_all_forms(PyObject *f, PyObject *args)
1651 fl_activate_all_forms();
1652 Py_INCREF(Py_None);
1653 return Py_None;
1656 static PyObject *
1657 forms_deactivate_all_forms(PyObject *f, PyObject *args)
1659 fl_deactivate_all_forms();
1660 Py_INCREF(Py_None);
1661 return Py_None;
1664 static PyObject *my_event_callback = NULL;
1666 static PyObject *
1667 forms_set_event_call_back(PyObject *dummy, PyObject *args)
1669 if (args == Py_None)
1670 args = NULL;
1671 my_event_callback = args;
1672 Py_XINCREF(args);
1673 Py_INCREF(Py_None);
1674 return Py_None;
1677 static PyObject *
1678 forms_do_or_check_forms(PyObject *dummy, FL_OBJECT *(*func)(void))
1680 FL_OBJECT *generic;
1681 genericobject *g;
1682 PyObject *arg, *res;
1684 for (;;) {
1685 Py_BEGIN_ALLOW_THREADS
1686 generic = (*func)();
1687 Py_END_ALLOW_THREADS
1688 if (generic == NULL) {
1689 Py_INCREF(Py_None);
1690 return Py_None;
1692 if (generic == FL_EVENT) {
1693 int dev;
1694 short val;
1695 if (my_event_callback == NULL)
1696 return PyInt_FromLong(-1L);
1697 dev = fl_qread(&val);
1698 arg = Py_BuildValue("(ih)", dev, val);
1699 if (arg == NULL)
1700 return NULL;
1701 res = PyEval_CallObject(my_event_callback, arg);
1702 Py_XDECREF(res);
1703 Py_DECREF(arg);
1704 if (res == NULL)
1705 return NULL; /* Callback raised exception */
1706 continue;
1708 g = findgeneric(generic);
1709 if (g == NULL) {
1710 /* Object not known to us (some dialogs cause this) */
1711 continue; /* Ignore it */
1713 if (g->ob_callback == NULL) {
1714 Py_INCREF(g);
1715 return ((PyObject *) g);
1717 arg = PyTuple_Pack(2, (PyObject *)g, g->ob_callback_arg);
1718 if (arg == NULL)
1719 return NULL;
1720 res = PyEval_CallObject(g->ob_callback, arg);
1721 Py_XDECREF(res);
1722 Py_DECREF(arg);
1723 if (res == NULL)
1724 return NULL; /* Callback raised exception */
1728 static PyObject *
1729 forms_do_forms(PyObject *dummy)
1731 return forms_do_or_check_forms(dummy, fl_do_forms);
1734 static PyObject *
1735 forms_check_forms(PyObject *dummy)
1737 return forms_do_or_check_forms(dummy, fl_check_forms);
1740 static PyObject *
1741 forms_do_only_forms(PyObject *dummy)
1743 return forms_do_or_check_forms(dummy, fl_do_only_forms);
1746 static PyObject *
1747 forms_check_only_forms(PyObject *dummy)
1749 return forms_do_or_check_forms(dummy, fl_check_only_forms);
1752 #ifdef UNUSED
1753 static PyObject *
1754 fl_call(void (*func)(void))
1756 (*func)();
1757 Py_INCREF(Py_None);
1758 return Py_None;
1760 #endif
1762 static PyObject *
1763 forms_set_graphics_mode(PyObject *dummy, PyObject *args)
1765 int rgbmode, doublebuf;
1767 if (!PyArg_Parse(args, "(ii)", &rgbmode, &doublebuf))
1768 return NULL;
1769 fl_set_graphics_mode(rgbmode,doublebuf);
1770 Py_INCREF(Py_None);
1771 return Py_None;
1774 static PyObject *
1775 forms_get_rgbmode(PyObject *dummy, PyObject *args)
1777 extern int fl_rgbmode;
1779 if (args != NULL) {
1780 PyErr_BadArgument();
1781 return NULL;
1783 return PyInt_FromLong((long)fl_rgbmode);
1786 static PyObject *
1787 forms_show_errors(PyObject *dummy, PyObject *args)
1789 int show;
1790 if (!PyArg_Parse(args, "i", &show))
1791 return NULL;
1792 fl_show_errors(show);
1793 Py_INCREF(Py_None);
1794 return Py_None;
1797 static PyObject *
1798 forms_set_font_name(PyObject *dummy, PyObject *args)
1800 int numb;
1801 char *name;
1802 if (!PyArg_Parse(args, "(is)", &numb, &name))
1803 return NULL;
1804 fl_set_font_name(numb, name);
1805 Py_INCREF(Py_None);
1806 return Py_None;
1810 static PyObject *
1811 forms_qdevice(PyObject *self, PyObject *args)
1813 short arg1;
1814 if (!PyArg_Parse(args, "h", &arg1))
1815 return NULL;
1816 fl_qdevice(arg1);
1817 Py_INCREF(Py_None);
1818 return Py_None;
1821 static PyObject *
1822 forms_unqdevice(PyObject *self, PyObject *args)
1824 short arg1;
1825 if (!PyArg_Parse(args, "h", &arg1))
1826 return NULL;
1827 fl_unqdevice(arg1);
1828 Py_INCREF(Py_None);
1829 return Py_None;
1832 static PyObject *
1833 forms_isqueued(PyObject *self, PyObject *args)
1835 long retval;
1836 short arg1;
1837 if (!PyArg_Parse(args, "h", &arg1))
1838 return NULL;
1839 retval = fl_isqueued(arg1);
1841 return PyInt_FromLong(retval);
1844 static PyObject *
1845 forms_qtest(PyObject *self, PyObject *args)
1847 long retval;
1848 retval = fl_qtest();
1849 return PyInt_FromLong(retval);
1853 static PyObject *
1854 forms_qread(PyObject *self, PyObject *args)
1856 int dev;
1857 short val;
1858 Py_BEGIN_ALLOW_THREADS
1859 dev = fl_qread(&val);
1860 Py_END_ALLOW_THREADS
1861 return Py_BuildValue("(ih)", dev, val);
1864 static PyObject *
1865 forms_qreset(PyObject *self)
1867 fl_qreset();
1868 Py_INCREF(Py_None);
1869 return Py_None;
1872 static PyObject *
1873 forms_qenter(PyObject *self, PyObject *args)
1875 short arg1, arg2;
1876 if (!PyArg_Parse(args, "(hh)", &arg1, &arg2))
1877 return NULL;
1878 fl_qenter(arg1, arg2);
1879 Py_INCREF(Py_None);
1880 return Py_None;
1883 static PyObject *
1884 forms_color(PyObject *self, PyObject *args)
1886 int arg;
1888 if (!PyArg_Parse(args, "i", &arg)) return NULL;
1890 fl_color((short) arg);
1892 Py_INCREF(Py_None);
1893 return Py_None;
1896 static PyObject *
1897 forms_mapcolor(PyObject *self, PyObject *args)
1899 int arg0, arg1, arg2, arg3;
1901 if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
1902 return NULL;
1904 fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
1906 Py_INCREF(Py_None);
1907 return Py_None;
1910 static PyObject *
1911 forms_getmcolor(PyObject *self, PyObject *args)
1913 int arg;
1914 short r, g, b;
1916 if (!PyArg_Parse(args, "i", &arg)) return NULL;
1918 fl_getmcolor(arg, &r, &g, &b);
1920 return Py_BuildValue("(hhh)", r, g, b);
1923 static PyObject *
1924 forms_get_mouse(PyObject *self)
1926 float x, y;
1928 fl_get_mouse(&x, &y);
1930 return Py_BuildValue("(ff)", x, y);
1933 static PyObject *
1934 forms_tie(PyObject *self, PyObject *args)
1936 short arg1, arg2, arg3;
1937 if (!PyArg_Parse(args, "(hhh)", &arg1, &arg2, &arg3))
1938 return NULL;
1939 fl_tie(arg1, arg2, arg3);
1940 Py_INCREF(Py_None);
1941 return Py_None;
1944 static PyObject *
1945 forms_show_message(PyObject *f, PyObject *args)
1947 char *a, *b, *c;
1949 if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
1951 Py_BEGIN_ALLOW_THREADS
1952 fl_show_message(a, b, c);
1953 Py_END_ALLOW_THREADS
1955 Py_INCREF(Py_None);
1956 return Py_None;
1959 static PyObject *
1960 forms_show_choice(PyObject *f, PyObject *args)
1962 char *m1, *m2, *m3, *b1, *b2, *b3;
1963 int nb;
1964 char *format;
1965 long rv;
1967 if (args == NULL || !PyTuple_Check(args)) {
1968 PyErr_BadArgument();
1969 return NULL;
1971 nb = PyTuple_Size(args) - 3;
1972 if (nb <= 0) {
1973 PyErr_SetString(PyExc_TypeError,
1974 "need at least one button label");
1975 return NULL;
1977 if (PyInt_Check(PyTuple_GetItem(args, 3))) {
1978 PyErr_SetString(PyExc_TypeError,
1979 "'number-of-buttons' argument not needed");
1980 return NULL;
1982 switch (nb) {
1983 case 1: format = "(ssss)"; break;
1984 case 2: format = "(sssss)"; break;
1985 case 3: format = "(ssssss)"; break;
1986 default:
1987 PyErr_SetString(PyExc_TypeError, "too many button labels");
1988 return NULL;
1991 if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
1992 return NULL;
1994 Py_BEGIN_ALLOW_THREADS
1995 rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
1996 Py_END_ALLOW_THREADS
1997 return PyInt_FromLong(rv);
2000 static PyObject *
2001 forms_show_question(PyObject *f, PyObject *args)
2003 int ret;
2004 char *a, *b, *c;
2006 if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
2008 Py_BEGIN_ALLOW_THREADS
2009 ret = fl_show_question(a, b, c);
2010 Py_END_ALLOW_THREADS
2012 return PyInt_FromLong((long) ret);
2015 static PyObject *
2016 forms_show_input(PyObject *f, PyObject *args)
2018 char *str;
2019 char *a, *b;
2021 if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
2023 Py_BEGIN_ALLOW_THREADS
2024 str = fl_show_input(a, b);
2025 Py_END_ALLOW_THREADS
2027 if (str == NULL) {
2028 Py_INCREF(Py_None);
2029 return Py_None;
2031 return PyString_FromString(str);
2034 static PyObject *
2035 forms_file_selector(PyObject *f, PyObject *args)
2037 char *str;
2038 char *a, *b, *c, *d;
2040 if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
2042 Py_BEGIN_ALLOW_THREADS
2043 str = fl_show_file_selector(a, b, c, d);
2044 Py_END_ALLOW_THREADS
2046 if (str == NULL) {
2047 Py_INCREF(Py_None);
2048 return Py_None;
2050 return PyString_FromString(str);
2054 static PyObject *
2055 forms_file_selector_func(PyObject *args, char *(*func)(void))
2057 char *str;
2059 str = (*func) ();
2061 if (str == NULL) {
2062 Py_INCREF(Py_None);
2063 return Py_None;
2065 return PyString_FromString(str);
2068 static PyObject *
2069 forms_get_directory(PyObject *f, PyObject *args)
2071 return forms_file_selector_func(args, fl_get_directory);
2074 static PyObject *
2075 forms_get_pattern(PyObject *f, PyObject *args)
2077 return forms_file_selector_func(args, fl_get_pattern);
2080 static PyObject *
2081 forms_get_filename(PyObject *f, PyObject *args)
2083 return forms_file_selector_func(args, fl_get_filename);
2086 static PyMethodDef forms_methods[] = {
2087 /* adm */
2088 {"make_form", forms_make_form, METH_OLDARGS},
2089 {"activate_all_forms", forms_activate_all_forms, METH_OLDARGS},
2090 {"deactivate_all_forms",forms_deactivate_all_forms, METH_OLDARGS},
2091 /* gl support wrappers */
2092 {"qdevice", forms_qdevice, METH_OLDARGS},
2093 {"unqdevice", forms_unqdevice, METH_OLDARGS},
2094 {"isqueued", forms_isqueued, METH_OLDARGS},
2095 {"qtest", forms_qtest, METH_OLDARGS},
2096 {"qread", forms_qread, METH_OLDARGS},
2097 /* {"blkqread", forms_blkqread, METH_OLDARGS}, */
2098 {"qreset", forms_qreset, METH_NOARGS},
2099 {"qenter", forms_qenter, METH_OLDARGS},
2100 {"get_mouse", forms_get_mouse, METH_NOARGS},
2101 {"tie", forms_tie, METH_OLDARGS},
2102 /* {"new_events", forms_new_events, METH_OLDARGS}, */
2103 {"color", forms_color, METH_OLDARGS},
2104 {"mapcolor", forms_mapcolor, METH_OLDARGS},
2105 {"getmcolor", forms_getmcolor, METH_OLDARGS},
2106 /* interaction */
2107 {"do_forms", forms_do_forms, METH_NOARGS},
2108 {"do_only_forms", forms_do_only_forms, METH_NOARGS},
2109 {"check_forms", forms_check_forms, METH_NOARGS},
2110 {"check_only_forms", forms_check_only_forms, METH_NOARGS},
2111 {"set_event_call_back", forms_set_event_call_back, METH_OLDARGS},
2112 /* goodies */
2113 {"show_message", forms_show_message, METH_OLDARGS},
2114 {"show_question", forms_show_question, METH_OLDARGS},
2115 {"show_choice", forms_show_choice, METH_OLDARGS},
2116 {"show_input", forms_show_input, METH_OLDARGS},
2117 {"show_file_selector", forms_file_selector, METH_OLDARGS},
2118 {"file_selector", forms_file_selector, METH_OLDARGS}, /* BW compat */
2119 {"get_directory", forms_get_directory, METH_OLDARGS},
2120 {"get_pattern", forms_get_pattern, METH_OLDARGS},
2121 {"get_filename", forms_get_filename, METH_OLDARGS},
2122 {"set_graphics_mode", forms_set_graphics_mode, METH_OLDARGS},
2123 {"get_rgbmode", forms_get_rgbmode, METH_OLDARGS},
2124 {"show_errors", forms_show_errors, METH_OLDARGS},
2125 {"set_font_name", forms_set_font_name, METH_OLDARGS},
2126 {NULL, NULL} /* sentinel */
2129 PyMODINIT_FUNC
2130 initfl(void)
2132 Py_InitModule("fl", forms_methods);
2133 if (m == NULL)
2134 return;
2135 foreground();
2136 fl_init();