Improve implementation with better underlying data structure
[python.git] / Modules / flmodule.c
blob20e74e93065d06d8713e8365485608fb39b0c8e1
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 (PyTuple_GET_SIZE(args) == 0) {
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 PyObject *a, *b;
159 if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)
160 return NULL;
161 Py_XDECREF(g->ob_callback);
162 Py_XDECREF(g->ob_callback_arg);
163 g->ob_callback = a;
164 Py_INCREF(g->ob_callback);
165 g->ob_callback_arg = b;
166 Py_INCREF(g->ob_callback_arg);
168 Py_INCREF(Py_None);
169 return Py_None;
172 static PyObject *
173 generic_call(genericobject *g, void (*func)(FL_OBJECT *))
175 (*func)(g->ob_generic);
176 Py_INCREF(Py_None);
177 return Py_None;
180 static PyObject *
181 generic_delete_object(genericobject *g)
183 PyObject *res;
184 res = generic_call(g, fl_delete_object);
185 if (res != NULL)
186 forgetgeneric(g);
187 return res;
190 static PyObject *
191 generic_show_object(genericobject *g)
193 return generic_call(g, fl_show_object);
196 static PyObject *
197 generic_hide_object(genericobject *g)
199 return generic_call(g, fl_hide_object);
202 static PyObject *
203 generic_redraw_object(genericobject *g)
205 return generic_call(g, fl_redraw_object);
208 #ifdef OBSOLETE_FORMS_CALLS
210 /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported
211 in 2.3. Since there's no foolproof way to tell which version we're
212 using, we omit them unconditionally. */
214 static PyObject *
215 generic_freeze_object(genericobject *g)
217 return generic_call(g, fl_freeze_object);
220 static PyObject *
221 generic_unfreeze_object(genericobject *g)
223 return generic_call(g, fl_unfreeze_object);
226 #endif /* OBSOLETE_FORMS_CALLS */
228 static PyObject *
229 generic_activate_object(genericobject *g)
231 return generic_call(g, fl_activate_object);
234 static PyObject *
235 generic_deactivate_object(genericobject *g)
237 return generic_call(g, fl_deactivate_object);
240 static PyObject *
241 generic_set_object_shortcut(genericobject *g, PyObject *args)
243 char *str;
244 if (!PyArg_ParseTuple(args, "s:set_object_shortcut", &str))
245 return NULL;
246 fl_set_object_shortcut(g->ob_generic, str);
247 Py_INCREF(Py_None);
248 return Py_None;
251 static PyMethodDef generic_methods[] = {
252 {"set_call_back", (PyCFunction)generic_set_call_back, METH_VARARGS},
253 {"delete_object", (PyCFunction)generic_delete_object, METH_NOARGS},
254 {"show_object", (PyCFunction)generic_show_object, METH_NOARGS},
255 {"hide_object", (PyCFunction)generic_hide_object, METH_NOARGS},
256 {"redraw_object", (PyCFunction)generic_redraw_object, METH_NOARGS},
257 #ifdef OBSOLETE_FORMS_CALLS
258 {"freeze_object", (PyCFunction)generic_freeze_object, METH_NOARGS},
259 {"unfreeze_object", (PyCFunction)generic_unfreeze_object, METH_NOARGS},
260 #endif
261 {"activate_object", (PyCFunction)generic_activate_object, METH_NOARGS},
262 {"deactivate_object", (PyCFunction)generic_deactivate_object, METH_NOARGS},
263 {"set_object_shortcut", (PyCFunction)generic_set_object_shortcut, METH_VARARGS},
264 {NULL, NULL} /* sentinel */
267 static void
268 generic_dealloc(genericobject *g)
270 fl_free_object(g->ob_generic);
271 Py_XDECREF(g->ob_callback);
272 Py_XDECREF(g->ob_callback_arg);
273 PyObject_Del(g);
276 #define OFF(x) offsetof(FL_OBJECT, x)
278 static struct memberlist generic_memberlist[] = {
279 {"objclass", T_INT, OFF(objclass), RO},
280 {"type", T_INT, OFF(type), RO},
281 {"boxtype", T_INT, OFF(boxtype)},
282 {"x", T_FLOAT, OFF(x)},
283 {"y", T_FLOAT, OFF(y)},
284 {"w", T_FLOAT, OFF(w)},
285 {"h", T_FLOAT, OFF(h)},
286 {"col1", T_INT, OFF(col1)},
287 {"col2", T_INT, OFF(col2)},
288 {"align", T_INT, OFF(align)},
289 {"lcol", T_INT, OFF(lcol)},
290 {"lsize", T_FLOAT, OFF(lsize)},
291 /* "label" is treated specially! */
292 {"lstyle", T_INT, OFF(lstyle)},
293 {"pushed", T_INT, OFF(pushed), RO},
294 {"focus", T_INT, OFF(focus), RO},
295 {"belowmouse", T_INT, OFF(belowmouse),RO},
296 /* {"frozen", T_INT, OFF(frozen), RO}, */
297 {"active", T_INT, OFF(active)},
298 {"input", T_INT, OFF(input)},
299 {"visible", T_INT, OFF(visible), RO},
300 {"radio", T_INT, OFF(radio)},
301 {"automatic", T_INT, OFF(automatic)},
302 {NULL} /* Sentinel */
305 #undef OFF
307 static PyObject *
308 generic_getattr(genericobject *g, char *name)
310 PyObject *meth;
312 /* XXX Ought to special-case name "__methods__" */
313 if (g-> ob_methods) {
314 meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);
315 if (meth != NULL) return meth;
316 PyErr_Clear();
319 meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
320 if (meth != NULL)
321 return meth;
322 PyErr_Clear();
324 /* "label" is an exception, getmember only works for char pointers,
325 not for char arrays */
326 if (strcmp(name, "label") == 0)
327 return PyString_FromString(g->ob_generic->label);
329 return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
332 static int
333 generic_setattr(genericobject *g, char *name, PyObject *v)
335 int ret;
337 if (v == NULL) {
338 PyErr_SetString(PyExc_TypeError,
339 "can't delete forms object attributes");
340 return -1;
343 /* "label" is an exception: setmember doesn't set strings;
344 and FORMS wants you to call a function to set the label */
345 if (strcmp(name, "label") == 0) {
346 if (!PyString_Check(v)) {
347 PyErr_SetString(PyExc_TypeError,
348 "label attr must be string");
349 return -1;
351 fl_set_object_label(g->ob_generic, PyString_AsString(v));
352 return 0;
355 ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
357 /* Rather than calling all the various set_object_* functions,
358 we call fl_redraw_object here. This is sometimes redundant
359 but I doubt that's a big problem */
360 if (ret == 0)
361 fl_redraw_object(g->ob_generic);
363 return ret;
366 static PyObject *
367 generic_repr(genericobject *g)
369 char buf[100];
370 PyOS_snprintf(buf, sizeof(buf), "<FORMS_object at %p, objclass=%d>",
371 g, g->ob_generic->objclass);
372 return PyString_FromString(buf);
375 static PyTypeObject GenericObjecttype = {
376 PyObject_HEAD_INIT(&PyType_Type)
377 0, /*ob_size*/
378 "fl.FORMS_object", /*tp_name*/
379 sizeof(genericobject), /*tp_size*/
380 0, /*tp_itemsize*/
381 /* methods */
382 (destructor)generic_dealloc, /*tp_dealloc*/
383 0, /*tp_print*/
384 (getattrfunc)generic_getattr, /*tp_getattr*/
385 (setattrfunc)generic_setattr, /*tp_setattr*/
386 0, /*tp_compare*/
387 (reprfunc)generic_repr, /*tp_repr*/
390 static PyObject *
391 newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
393 genericobject *g;
394 g = PyObject_New(genericobject, &GenericObjecttype);
395 if (g == NULL)
396 return NULL;
397 g-> ob_generic = generic;
398 g->ob_methods = methods;
399 g->ob_callback = NULL;
400 g->ob_callback_arg = NULL;
401 knowgeneric(g);
402 return (PyObject *)g;
405 /**********************************************************************/
406 /* Some common calling sequences */
408 /* void func (object, float) */
409 static PyObject *
410 call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
412 float parameter;
414 if (!PyArg_Parse(args, "f", &parameter)) return NULL;
416 (*func) (obj, parameter);
418 Py_INCREF(Py_None);
419 return Py_None;
422 /* void func (object, float) */
423 static PyObject *
424 call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
426 float par1, par2;
428 if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
430 (*func) (obj, par1, par2);
432 Py_INCREF(Py_None);
433 return Py_None;
436 /* void func (object, int) */
437 static PyObject *
438 call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
440 int parameter;
442 if (!PyArg_Parse(args, "i", &parameter)) return NULL;
444 (*func) (obj, parameter);
446 Py_INCREF(Py_None);
447 return Py_None;
450 /* void func (object, char) */
451 static PyObject *
452 call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
454 char *a;
456 if (!PyArg_Parse(args, "s", &a)) return NULL;
458 (*func) (obj, a[0]);
460 Py_INCREF(Py_None);
461 return Py_None;
464 /* void func (object, string) */
465 static PyObject *
466 call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
468 char *a;
470 if (!PyArg_Parse(args, "s", &a)) return NULL;
472 (*func) (obj, a);
474 Py_INCREF(Py_None);
475 return Py_None;
479 /* void func (object, int, string) */
480 static PyObject *
481 call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
483 char *b;
484 int a;
486 if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
488 (*func) (obj, a, b);
490 Py_INCREF(Py_None);
491 return Py_None;
494 #ifdef UNUSED
495 /* void func (object, int, int) */
496 static PyObject *
497 call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
499 int par1, par2;
501 if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
503 (*func) (obj, par1, par2);
505 Py_INCREF(Py_None);
506 return Py_None;
508 #endif
510 /* int func (object) */
511 static PyObject *
512 call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj)
514 int retval;
516 retval = (*func) (obj);
518 return PyInt_FromLong ((long) retval);
521 /* char * func (object) */
522 static PyObject *
523 call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj)
525 char *str;
527 str = (*func) (obj);
529 if (str == NULL) {
530 Py_INCREF(Py_None);
531 return Py_None;
533 return PyString_FromString (str);
536 /* int func (object) */
537 static PyObject *
538 call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj)
540 float retval;
542 retval = (*func) (obj);
544 return PyFloat_FromDouble (retval);
547 static PyObject *
548 call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj)
550 float f1, f2;
552 (*func) (obj, &f1, &f2);
554 return Py_BuildValue("(ff)", f1, f2);
557 #ifdef UNUSED
558 static PyObject *
559 call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj)
561 float f;
563 (*func) (obj, &f);
565 return PyFloat_FromDouble (f);
567 #endif
569 /**********************************************************************/
570 /* Class : browser */
572 static PyObject *
573 set_browser_topline(genericobject *g, PyObject *args)
575 return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
578 static PyObject *
579 clear_browser(genericobject *g)
581 return generic_call (g, fl_clear_browser);
584 static PyObject *
585 add_browser_line (genericobject *g, PyObject *args)
587 return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
590 static PyObject *
591 addto_browser (genericobject *g, PyObject *args)
593 return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
596 static PyObject *
597 insert_browser_line (genericobject *g, PyObject *args)
599 return call_forms_INiINstr (fl_insert_browser_line,
600 g-> ob_generic, args);
603 static PyObject *
604 delete_browser_line (genericobject *g, PyObject *args)
606 return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
609 static PyObject *
610 replace_browser_line (genericobject *g, PyObject *args)
612 return call_forms_INiINstr (fl_replace_browser_line,
613 g-> ob_generic, args);
616 static PyObject *
617 get_browser_line(genericobject *g, PyObject *args)
619 int i;
620 char *str;
622 if (!PyArg_Parse(args, "i", &i))
623 return NULL;
625 str = fl_get_browser_line (g->ob_generic, i);
627 if (str == NULL) {
628 Py_INCREF(Py_None);
629 return Py_None;
631 return PyString_FromString (str);
634 static PyObject *
635 load_browser (genericobject *g, PyObject *args)
637 /* XXX strictly speaking this is wrong since fl_load_browser
638 XXX returns int, not void */
639 return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
642 static PyObject *
643 get_browser_maxline(genericobject *g)
645 return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
648 static PyObject *
649 select_browser_line (genericobject *g, PyObject *args)
651 return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
654 static PyObject *
655 deselect_browser_line (genericobject *g, PyObject *args)
657 return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
660 static PyObject *
661 deselect_browser (genericobject *g)
663 return generic_call (g, fl_deselect_browser);
666 static PyObject *
667 isselected_browser_line (genericobject *g, PyObject *args)
669 int i, j;
671 if (!PyArg_Parse(args, "i", &i))
672 return NULL;
674 j = fl_isselected_browser_line (g->ob_generic, i);
676 return PyInt_FromLong (j);
679 static PyObject *
680 get_browser (genericobject *g)
682 return call_forms_Ri (fl_get_browser, g-> ob_generic);
685 static PyObject *
686 set_browser_fontsize (genericobject *g, PyObject *args)
688 return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
691 static PyObject *
692 set_browser_fontstyle (genericobject *g, PyObject *args)
694 return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
697 static PyObject *
698 set_browser_specialkey (genericobject *g, PyObject *args)
700 return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
703 static PyMethodDef browser_methods[] = {
704 {"set_browser_topline", (PyCFunction)set_browser_topline,
705 METH_OLDARGS},
706 {"clear_browser", (PyCFunction)clear_browser,
707 METH_NOARGS},
708 {"add_browser_line", (PyCFunction)add_browser_line,
709 METH_OLDARGS},
710 {"addto_browser", (PyCFunction)addto_browser,
711 METH_OLDARGS},
712 {"insert_browser_line", (PyCFunction)insert_browser_line,
713 METH_OLDARGS},
714 {"delete_browser_line", (PyCFunction)delete_browser_line,
715 METH_OLDARGS},
716 {"replace_browser_line", (PyCFunction)replace_browser_line,
717 METH_OLDARGS},
718 {"get_browser_line", (PyCFunction)get_browser_line,
719 METH_OLDARGS},
720 {"load_browser", (PyCFunction)load_browser,
721 METH_OLDARGS},
722 {"get_browser_maxline", (PyCFunction)get_browser_maxline,
723 METH_NOARGS,}
724 {"select_browser_line", (PyCFunction)select_browser_line,
725 METH_OLDARGS},
726 {"deselect_browser_line", (PyCFunction)deselect_browser_line,
727 METH_OLDARGS},
728 {"deselect_browser", (PyCFunction)deselect_browser,
729 METH_NOARGS,}
730 {"isselected_browser_line", (PyCFunction)isselected_browser_line,
731 METH_OLDARGS},
732 {"get_browser", (PyCFunction)get_browser,
733 METH_NOARGS,}
734 {"set_browser_fontsize", (PyCFunction)set_browser_fontsize,
735 METH_OLDARGS},
736 {"set_browser_fontstyle", (PyCFunction)set_browser_fontstyle,
737 METH_OLDARGS},
738 {"set_browser_specialkey", (PyCFunction)set_browser_specialkey,
739 METH_OLDARGS},
740 {NULL, NULL} /* sentinel */
743 /* Class: button */
745 static PyObject *
746 set_button(genericobject *g, PyObject *args)
748 return call_forms_INi (fl_set_button, g-> ob_generic, args);
751 static PyObject *
752 get_button(genericobject *g)
754 return call_forms_Ri (fl_get_button, g-> ob_generic);
757 static PyObject *
758 get_button_numb(genericobject *g)
760 return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
763 static PyObject *
764 set_button_shortcut(genericobject *g, PyObject *args)
766 return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
769 static PyMethodDef button_methods[] = {
770 {"set_button", (PyCFunction)set_button, METH_OLDARGS},
771 {"get_button", (PyCFunction)get_button, METH_NOARGS},
772 {"get_button_numb", (PyCFunction)get_button_numb, METH_NOARGS},
773 {"set_button_shortcut", (PyCFunction)set_button_shortcut, METH_OLDARGS},
774 {NULL, NULL} /* sentinel */
777 /* Class: choice */
779 static PyObject *
780 set_choice(genericobject *g, PyObject *args)
782 return call_forms_INi (fl_set_choice, g-> ob_generic, args);
785 static PyObject *
786 get_choice(genericobject *g)
788 return call_forms_Ri (fl_get_choice, g-> ob_generic);
791 static PyObject *
792 clear_choice (genericobject *g)
794 return generic_call (g, fl_clear_choice);
797 static PyObject *
798 addto_choice (genericobject *g, PyObject *args)
800 return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
803 static PyObject *
804 replace_choice (genericobject *g, PyObject *args)
806 return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
809 static PyObject *
810 delete_choice (genericobject *g, PyObject *args)
812 return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
815 static PyObject *
816 get_choice_text (genericobject *g)
818 return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
821 static PyObject *
822 set_choice_fontsize (genericobject *g, PyObject *args)
824 return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
827 static PyObject *
828 set_choice_fontstyle (genericobject *g, PyObject *args)
830 return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
833 static PyMethodDef choice_methods[] = {
834 {"set_choice", (PyCFunction)set_choice, METH_OLDARGS},
835 {"get_choice", (PyCFunction)get_choice, METH_NOARGS},
836 {"clear_choice", (PyCFunction)clear_choice, METH_NOARGS},
837 {"addto_choice", (PyCFunction)addto_choice, METH_OLDARGS},
838 {"replace_choice", (PyCFunction)replace_choice, METH_OLDARGS},
839 {"delete_choice", (PyCFunction)delete_choice, METH_OLDARGS},
840 {"get_choice_text", (PyCFunction)get_choice_text, METH_NOARGS},
841 {"set_choice_fontsize", (PyCFunction)set_choice_fontsize, METH_OLDARGS},
842 {"set_choice_fontstyle",(PyCFunction)set_choice_fontstyle, METH_OLDARGS},
843 {NULL, NULL} /* sentinel */
846 /* Class : Clock */
848 static PyObject *
849 get_clock(genericobject *g)
851 int i0, i1, i2;
853 fl_get_clock (g->ob_generic, &i0, &i1, &i2);
855 return Py_BuildValue("(iii)", i0, i1, i2);
858 static PyMethodDef clock_methods[] = {
859 {"get_clock", (PyCFunction)get_clock, METH_NOARGS},
860 {NULL, NULL} /* sentinel */
863 /* CLass : Counters */
865 static PyObject *
866 get_counter_value(genericobject *g)
868 return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
871 static PyObject *
872 set_counter_value (genericobject *g, PyObject *args)
874 return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
877 static PyObject *
878 set_counter_precision (genericobject *g, PyObject *args)
880 return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
883 static PyObject *
884 set_counter_bounds (genericobject *g, PyObject *args)
886 return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
889 static PyObject *
890 set_counter_step (genericobject *g, PyObject *args)
892 return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
895 static PyObject *
896 set_counter_return (genericobject *g, PyObject *args)
898 return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
901 static PyMethodDef counter_methods[] = {
902 {"set_counter_value", (PyCFunction)set_counter_value,
903 METH_OLDARGS},
904 {"get_counter_value", (PyCFunction)get_counter_value,
905 METH_NOARGS},
906 {"set_counter_bounds", (PyCFunction)set_counter_bounds,
907 METH_OLDARGS},
908 {"set_counter_step", (PyCFunction)set_counter_step,
909 METH_OLDARGS},
910 {"set_counter_precision", (PyCFunction)set_counter_precision,
911 METH_OLDARGS},
912 {"set_counter_return", (PyCFunction)set_counter_return,
913 METH_OLDARGS},
914 {NULL, NULL} /* sentinel */
918 /* Class: Dials */
920 static PyObject *
921 get_dial_value(genericobject *g)
923 return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
926 static PyObject *
927 set_dial_value (genericobject *g, PyObject *args)
929 return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
932 static PyObject *
933 set_dial_bounds (genericobject *g, PyObject *args)
935 return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
938 static PyObject *
939 get_dial_bounds (genericobject *g)
941 return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
944 static PyObject *
945 set_dial_step (genericobject *g, PyObject *args)
947 return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
950 static PyMethodDef dial_methods[] = {
951 {"set_dial_value", (PyCFunction)set_dial_value, METH_OLDARGS},
952 {"get_dial_value", (PyCFunction)get_dial_value, METH_NOARGS},
953 {"set_dial_bounds", (PyCFunction)set_dial_bounds, METH_OLDARGS},
954 {"get_dial_bounds", (PyCFunction)get_dial_bounds, METH_NOARGS},
955 {"set_dial_step", (PyCFunction)set_dial_step, METH_OLDARGS},
956 {NULL, NULL} /* sentinel */
959 /* Class : Input */
961 static PyObject *
962 set_input (genericobject *g, PyObject *args)
964 return call_forms_INstr (fl_set_input, g-> ob_generic, args);
967 static PyObject *
968 get_input (genericobject *g)
970 return call_forms_Rstr (fl_get_input, g-> ob_generic);
973 static PyObject *
974 set_input_color (genericobject *g, PyObject *args)
976 return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
979 static PyObject *
980 set_input_return (genericobject *g, PyObject *args)
982 return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
985 static PyMethodDef input_methods[] = {
986 {"set_input", (PyCFunction)set_input, METH_OLDARGS},
987 {"get_input", (PyCFunction)get_input, METH_NOARGS},
988 {"set_input_color", (PyCFunction)set_input_color, METH_OLDARGS},
989 {"set_input_return", (PyCFunction)set_input_return, METH_OLDARGS},
990 {NULL, NULL} /* sentinel */
994 /* Class : Menu */
996 static PyObject *
997 set_menu (genericobject *g, PyObject *args)
999 return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
1002 static PyObject *
1003 get_menu (genericobject *g)
1005 /* XXX strictly speaking this is wrong since fl_get_menu
1006 XXX returns long, not int */
1007 return call_forms_Ri (fl_get_menu, g-> ob_generic);
1010 static PyObject *
1011 get_menu_text (genericobject *g)
1013 return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
1016 static PyObject *
1017 addto_menu (genericobject *g, PyObject *args)
1019 return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
1022 static PyMethodDef menu_methods[] = {
1023 {"set_menu", (PyCFunction)set_menu, METH_OLDARGS},
1024 {"get_menu", (PyCFunction)get_menu, METH_NOARGS},
1025 {"get_menu_text", (PyCFunction)get_menu_text, METH_NOARGS},
1026 {"addto_menu", (PyCFunction)addto_menu, METH_OLDARGS},
1027 {NULL, NULL} /* sentinel */
1031 /* Class: Sliders */
1033 static PyObject *
1034 get_slider_value(genericobject *g)
1036 return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
1039 static PyObject *
1040 set_slider_value (genericobject *g, PyObject *args)
1042 return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
1045 static PyObject *
1046 set_slider_bounds (genericobject *g, PyObject *args)
1048 return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
1051 static PyObject *
1052 get_slider_bounds (genericobject *g)
1054 return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
1057 static PyObject *
1058 set_slider_return (genericobject *g, PyObject *args)
1060 return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
1063 static PyObject *
1064 set_slider_size (genericobject *g, PyObject *args)
1066 return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
1069 static PyObject *
1070 set_slider_precision (genericobject *g, PyObject *args)
1072 return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
1075 static PyObject *
1076 set_slider_step (genericobject *g, PyObject *args)
1078 return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
1082 static PyMethodDef slider_methods[] = {
1083 {"set_slider_value", (PyCFunction)set_slider_value, METH_OLDARGS},
1084 {"get_slider_value", (PyCFunction)get_slider_value, METH_NOARGS},
1085 {"set_slider_bounds", (PyCFunction)set_slider_bounds, METH_OLDARGS},
1086 {"get_slider_bounds", (PyCFunction)get_slider_bounds, METH_NOARGS},
1087 {"set_slider_return", (PyCFunction)set_slider_return, METH_OLDARGS},
1088 {"set_slider_size", (PyCFunction)set_slider_size, METH_OLDARGS},
1089 {"set_slider_precision",(PyCFunction)set_slider_precision, METH_OLDARGS},
1090 {"set_slider_step", (PyCFunction)set_slider_step, METH_OLDARGS},
1091 {NULL, NULL} /* sentinel */
1094 static PyObject *
1095 set_positioner_xvalue (genericobject *g, PyObject *args)
1097 return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
1100 static PyObject *
1101 set_positioner_xbounds (genericobject *g, PyObject *args)
1103 return call_forms_INfINf (fl_set_positioner_xbounds,
1104 g-> ob_generic, args);
1107 static PyObject *
1108 set_positioner_yvalue (genericobject *g, PyObject *args)
1110 return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
1113 static PyObject *
1114 set_positioner_ybounds (genericobject *g, PyObject *args)
1116 return call_forms_INfINf (fl_set_positioner_ybounds,
1117 g-> ob_generic, args);
1120 static PyObject *
1121 get_positioner_xvalue (genericobject *g)
1123 return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
1126 static PyObject *
1127 get_positioner_xbounds (genericobject *g)
1129 return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
1132 static PyObject *
1133 get_positioner_yvalue (genericobject *g)
1135 return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
1138 static PyObject *
1139 get_positioner_ybounds (genericobject *g)
1141 return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
1144 static PyMethodDef positioner_methods[] = {
1145 {"set_positioner_xvalue", (PyCFunction)set_positioner_xvalue,
1146 METH_OLDARGS},
1147 {"set_positioner_yvalue", (PyCFunction)set_positioner_yvalue,
1148 METH_OLDARGS},
1149 {"set_positioner_xbounds", (PyCFunction)set_positioner_xbounds,
1150 METH_OLDARGS},
1151 {"set_positioner_ybounds", (PyCFunction)set_positioner_ybounds,
1152 METH_OLDARGS},
1153 {"get_positioner_xvalue", (PyCFunction)get_positioner_xvalue,
1154 METH_NOARGS},
1155 {"get_positioner_yvalue", (PyCFunction)get_positioner_yvalue,
1156 METH_NOARGS},
1157 {"get_positioner_xbounds", (PyCFunction)get_positioner_xbounds,
1158 METH_NOARGS},
1159 {"get_positioner_ybounds", (PyCFunction)get_positioner_ybounds,
1160 METH_NOARGS},
1161 {NULL, NULL} /* sentinel */
1164 /* Class timer */
1166 static PyObject *
1167 set_timer (genericobject *g, PyObject *args)
1169 return call_forms_INf (fl_set_timer, g-> ob_generic, args);
1172 static PyObject *
1173 get_timer (genericobject *g)
1175 return call_forms_Rf (fl_get_timer, g-> ob_generic);
1178 static PyMethodDef timer_methods[] = {
1179 {"set_timer", (PyCFunction)set_timer, METH_OLDARGS},
1180 {"get_timer", (PyCFunction)get_timer, METH_NOARGS},
1181 {NULL, NULL} /* sentinel */
1184 /* Form objects */
1186 typedef struct {
1187 PyObject_HEAD
1188 FL_FORM *ob_form;
1189 } formobject;
1191 static PyTypeObject Formtype;
1193 #define is_formobject(v) ((v)->ob_type == &Formtype)
1195 static PyObject *
1196 form_show_form(formobject *f, PyObject *args)
1198 int place, border;
1199 char *name;
1200 if (!PyArg_Parse(args, "(iis)", &place, &border, &name))
1201 return NULL;
1202 fl_show_form(f->ob_form, place, border, name);
1203 Py_INCREF(Py_None);
1204 return Py_None;
1207 static PyObject *
1208 form_call(void (*func)(FL_FORM *), FL_FORM *f)
1210 (*func)(f);
1212 Py_INCREF(Py_None);
1213 return Py_None;
1216 static PyObject *
1217 form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
1219 int a, b;
1221 if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
1223 (*func)(f, a, b);
1225 Py_INCREF(Py_None);
1226 return Py_None;
1229 static PyObject *
1230 form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
1232 float a, b;
1234 if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
1236 (*func)(f, a, b);
1238 Py_INCREF(Py_None);
1239 return Py_None;
1242 static PyObject *
1243 form_hide_form(formobject *f)
1245 return form_call(fl_hide_form, f-> ob_form);
1248 static PyObject *
1249 form_redraw_form(formobject *f)
1251 return form_call(fl_redraw_form, f-> ob_form);
1254 static PyObject *
1255 form_set_form_position(formobject *f, PyObject *args)
1257 return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
1260 static PyObject *
1261 form_set_form_size(formobject *f, PyObject *args)
1263 return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
1266 static PyObject *
1267 form_scale_form(formobject *f, PyObject *args)
1269 return form_call_INfINf(fl_scale_form, f-> ob_form, args);
1272 static PyObject *
1273 generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
1275 int type;
1276 float x, y, w, h;
1277 char *name;
1278 FL_OBJECT *obj;
1280 if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
1281 return NULL;
1283 fl_addto_form (f-> ob_form);
1285 obj = (*func) (type, x, y, w, h, name);
1287 fl_end_form();
1289 if (obj == NULL) {
1290 PyErr_NoMemory();
1291 return NULL;
1294 return newgenericobject (obj, internal_methods);
1297 static PyObject *
1298 form_add_button(formobject *f, PyObject *args)
1300 return generic_add_object(f, args, fl_add_button, button_methods);
1303 static PyObject *
1304 form_add_lightbutton(formobject *f, PyObject *args)
1306 return generic_add_object(f, args, fl_add_lightbutton, button_methods);
1309 static PyObject *
1310 form_add_roundbutton(formobject *f, PyObject *args)
1312 return generic_add_object(f, args, fl_add_roundbutton, button_methods);
1315 static PyObject *
1316 form_add_menu (formobject *f, PyObject *args)
1318 return generic_add_object(f, args, fl_add_menu, menu_methods);
1321 static PyObject *
1322 form_add_slider(formobject *f, PyObject *args)
1324 return generic_add_object(f, args, fl_add_slider, slider_methods);
1327 static PyObject *
1328 form_add_valslider(formobject *f, PyObject *args)
1330 return generic_add_object(f, args, fl_add_valslider, slider_methods);
1333 static PyObject *
1334 form_add_dial(formobject *f, PyObject *args)
1336 return generic_add_object(f, args, fl_add_dial, dial_methods);
1339 static PyObject *
1340 form_add_counter(formobject *f, PyObject *args)
1342 return generic_add_object(f, args, fl_add_counter, counter_methods);
1345 static PyObject *
1346 form_add_clock(formobject *f, PyObject *args)
1348 return generic_add_object(f, args, fl_add_clock, clock_methods);
1351 static PyObject *
1352 form_add_box(formobject *f, PyObject *args)
1354 return generic_add_object(f, args, fl_add_box,
1355 (PyMethodDef *)NULL);
1358 static PyObject *
1359 form_add_choice(formobject *f, PyObject *args)
1361 return generic_add_object(f, args, fl_add_choice, choice_methods);
1364 static PyObject *
1365 form_add_browser(formobject *f, PyObject *args)
1367 return generic_add_object(f, args, fl_add_browser, browser_methods);
1370 static PyObject *
1371 form_add_positioner(formobject *f, PyObject *args)
1373 return generic_add_object(f, args, fl_add_positioner,
1374 positioner_methods);
1377 static PyObject *
1378 form_add_input(formobject *f, PyObject *args)
1380 return generic_add_object(f, args, fl_add_input, input_methods);
1383 static PyObject *
1384 form_add_text(formobject *f, PyObject *args)
1386 return generic_add_object(f, args, fl_add_text,
1387 (PyMethodDef *)NULL);
1390 static PyObject *
1391 form_add_timer(formobject *f, PyObject *args)
1393 return generic_add_object(f, args, fl_add_timer, timer_methods);
1396 static PyObject *
1397 form_freeze_form(formobject *f)
1399 return form_call(fl_freeze_form, f-> ob_form);
1402 static PyObject *
1403 form_unfreeze_form(formobject *f)
1405 return form_call(fl_unfreeze_form, f-> ob_form);
1408 static PyObject *
1409 form_activate_form(formobject *f)
1411 return form_call(fl_activate_form, f-> ob_form);
1414 static PyObject *
1415 form_deactivate_form(formobject *f)
1417 return form_call(fl_deactivate_form, f-> ob_form);
1420 static PyObject *
1421 form_bgn_group(formobject *f, PyObject *args)
1423 FL_OBJECT *obj;
1425 fl_addto_form(f-> ob_form);
1426 obj = fl_bgn_group();
1427 fl_end_form();
1429 if (obj == NULL) {
1430 PyErr_NoMemory();
1431 return NULL;
1434 return newgenericobject (obj, (PyMethodDef *) NULL);
1437 static PyObject *
1438 form_end_group(formobject *f, PyObject *args)
1440 fl_addto_form(f-> ob_form);
1441 fl_end_group();
1442 fl_end_form();
1443 Py_INCREF(Py_None);
1444 return Py_None;
1447 static PyObject *
1448 forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
1450 int type;
1451 float mx, my;
1452 FL_OBJECT *generic;
1453 genericobject *g;
1455 if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
1457 generic = (*func) (f-> ob_form, type, mx, my);
1459 if (generic == NULL)
1461 Py_INCREF(Py_None);
1462 return Py_None;
1465 g = findgeneric(generic);
1466 if (g == NULL) {
1467 PyErr_SetString(PyExc_RuntimeError,
1468 "forms_find_{first|last} returns unknown object");
1469 return NULL;
1471 Py_INCREF(g);
1472 return (PyObject *) g;
1475 static PyObject *
1476 form_find_first(formobject *f, PyObject *args)
1478 return forms_find_first_or_last(fl_find_first, f, args);
1481 static PyObject *
1482 form_find_last(formobject *f, PyObject *args)
1484 return forms_find_first_or_last(fl_find_last, f, args);
1487 static PyObject *
1488 form_set_object_focus(formobject *f, PyObject *args)
1490 genericobject *g;
1491 if (args == NULL || !is_genericobject(args)) {
1492 PyErr_BadArgument();
1493 return NULL;
1495 g = (genericobject *)args;
1496 fl_set_object_focus(f->ob_form, g->ob_generic);
1497 Py_INCREF(Py_None);
1498 return Py_None;
1501 static PyMethodDef form_methods[] = {
1502 /* adm */
1503 {"show_form", (PyCFunction)form_show_form, METH_OLDARGS},
1504 {"hide_form", (PyCFunction)form_hide_form, METH_NOARGS},
1505 {"redraw_form", (PyCFunction)form_redraw_form, METH_NOARGS},
1506 {"set_form_position", (PyCFunction)form_set_form_position, METH_OLDARGS},
1507 {"set_form_size", (PyCFunction)form_set_form_size, METH_OLDARGS},
1508 {"scale_form", (PyCFunction)form_scale_form, METH_OLDARGS},
1509 {"freeze_form", (PyCFunction)form_freeze_form, METH_NOARGS},
1510 {"unfreeze_form", (PyCFunction)form_unfreeze_form, METH_NOARGS},
1511 {"activate_form", (PyCFunction)form_activate_form, METH_NOARGS},
1512 {"deactivate_form", (PyCFunction)form_deactivate_form, METH_NOARGS},
1513 {"bgn_group", (PyCFunction)form_bgn_group, METH_OLDARGS},
1514 {"end_group", (PyCFunction)form_end_group, METH_OLDARGS},
1515 {"find_first", (PyCFunction)form_find_first, METH_OLDARGS},
1516 {"find_last", (PyCFunction)form_find_last, METH_OLDARGS},
1517 {"set_object_focus", (PyCFunction)form_set_object_focus, METH_OLDARGS},
1519 /* basic objects */
1520 {"add_button", (PyCFunction)form_add_button, METH_OLDARGS},
1521 /* {"add_bitmap", (method)form_add_bitmap, METH_OLDARGS}, */
1522 {"add_lightbutton", (PyCFunction)form_add_lightbutton, METH_OLDARGS},
1523 {"add_roundbutton", (PyCFunction)form_add_roundbutton, METH_OLDARGS},
1524 {"add_menu", (PyCFunction)form_add_menu, METH_OLDARGS},
1525 {"add_slider", (PyCFunction)form_add_slider, METH_OLDARGS},
1526 {"add_positioner", (PyCFunction)form_add_positioner, METH_OLDARGS},
1527 {"add_valslider", (PyCFunction)form_add_valslider, METH_OLDARGS},
1528 {"add_dial", (PyCFunction)form_add_dial, METH_OLDARGS},
1529 {"add_counter", (PyCFunction)form_add_counter, METH_OLDARGS},
1530 {"add_box", (PyCFunction)form_add_box, METH_OLDARGS},
1531 {"add_clock", (PyCFunction)form_add_clock, METH_OLDARGS},
1532 {"add_choice", (PyCFunction)form_add_choice, METH_OLDARGS},
1533 {"add_browser", (PyCFunction)form_add_browser, METH_OLDARGS},
1534 {"add_input", (PyCFunction)form_add_input, METH_OLDARGS},
1535 {"add_timer", (PyCFunction)form_add_timer, METH_OLDARGS},
1536 {"add_text", (PyCFunction)form_add_text, METH_OLDARGS},
1537 {NULL, NULL} /* sentinel */
1540 static void
1541 form_dealloc(formobject *f)
1543 releaseobjects(f->ob_form);
1544 if (f->ob_form->visible)
1545 fl_hide_form(f->ob_form);
1546 fl_free_form(f->ob_form);
1547 PyObject_Del(f);
1550 #define OFF(x) offsetof(FL_FORM, x)
1552 static struct memberlist form_memberlist[] = {
1553 {"window", T_LONG, OFF(window), RO},
1554 {"w", T_FLOAT, OFF(w)},
1555 {"h", T_FLOAT, OFF(h)},
1556 {"x", T_FLOAT, OFF(x), RO},
1557 {"y", T_FLOAT, OFF(y), RO},
1558 {"deactivated", T_INT, OFF(deactivated)},
1559 {"visible", T_INT, OFF(visible), RO},
1560 {"frozen", T_INT, OFF(frozen), RO},
1561 {"doublebuf", T_INT, OFF(doublebuf)},
1562 {NULL} /* Sentinel */
1565 #undef OFF
1567 static PyObject *
1568 form_getattr(formobject *f, char *name)
1570 PyObject *meth;
1572 meth = Py_FindMethod(form_methods, (PyObject *)f, name);
1573 if (meth != NULL)
1574 return meth;
1575 PyErr_Clear();
1576 return PyMember_Get((char *)f->ob_form, form_memberlist, name);
1579 static int
1580 form_setattr(formobject *f, char *name, PyObject *v)
1582 if (v == NULL) {
1583 PyErr_SetString(PyExc_TypeError,
1584 "can't delete form attributes");
1585 return -1;
1588 return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
1591 static PyObject *
1592 form_repr(formobject *f)
1594 char buf[100];
1595 PyOS_snprintf(buf, sizeof(buf), "<FORMS_form at %p, window=%ld>",
1596 f, f->ob_form->window);
1597 return PyString_FromString(buf);
1600 static PyTypeObject Formtype = {
1601 PyObject_HEAD_INIT(&PyType_Type)
1602 0, /*ob_size*/
1603 "fl.FORMS_form", /*tp_name*/
1604 sizeof(formobject), /*tp_size*/
1605 0, /*tp_itemsize*/
1606 /* methods */
1607 (destructor)form_dealloc, /*tp_dealloc*/
1608 0, /*tp_print*/
1609 (getattrfunc)form_getattr, /*tp_getattr*/
1610 (setattrfunc)form_setattr, /*tp_setattr*/
1611 0, /*tp_compare*/
1612 (reprfunc)form_repr, /*tp_repr*/
1615 static PyObject *
1616 newformobject(FL_FORM *form)
1618 formobject *f;
1619 f = PyObject_New(formobject, &Formtype);
1620 if (f == NULL)
1621 return NULL;
1622 f->ob_form = form;
1623 return (PyObject *)f;
1627 /* The "fl" module */
1629 static PyObject *
1630 forms_make_form(PyObject *dummy, PyObject *args)
1632 int type;
1633 float w, h;
1634 FL_FORM *form;
1635 if (!PyArg_Parse(args, "(iff)", &type, &w, &h))
1636 return NULL;
1637 form = fl_bgn_form(type, w, h);
1638 if (form == NULL) {
1639 /* XXX Actually, cannot happen! */
1640 PyErr_NoMemory();
1641 return NULL;
1643 fl_end_form();
1644 return newformobject(form);
1647 static PyObject *
1648 forms_activate_all_forms(PyObject *f, PyObject *args)
1650 fl_activate_all_forms();
1651 Py_INCREF(Py_None);
1652 return Py_None;
1655 static PyObject *
1656 forms_deactivate_all_forms(PyObject *f, PyObject *args)
1658 fl_deactivate_all_forms();
1659 Py_INCREF(Py_None);
1660 return Py_None;
1663 static PyObject *my_event_callback = NULL;
1665 static PyObject *
1666 forms_set_event_call_back(PyObject *dummy, PyObject *args)
1668 if (args == Py_None)
1669 args = NULL;
1670 my_event_callback = args;
1671 Py_XINCREF(args);
1672 Py_INCREF(Py_None);
1673 return Py_None;
1676 static PyObject *
1677 forms_do_or_check_forms(PyObject *dummy, FL_OBJECT *(*func)(void))
1679 FL_OBJECT *generic;
1680 genericobject *g;
1681 PyObject *arg, *res;
1683 for (;;) {
1684 Py_BEGIN_ALLOW_THREADS
1685 generic = (*func)();
1686 Py_END_ALLOW_THREADS
1687 if (generic == NULL) {
1688 Py_INCREF(Py_None);
1689 return Py_None;
1691 if (generic == FL_EVENT) {
1692 int dev;
1693 short val;
1694 if (my_event_callback == NULL)
1695 return PyInt_FromLong(-1L);
1696 dev = fl_qread(&val);
1697 arg = Py_BuildValue("(ih)", dev, val);
1698 if (arg == NULL)
1699 return NULL;
1700 res = PyEval_CallObject(my_event_callback, arg);
1701 Py_XDECREF(res);
1702 Py_DECREF(arg);
1703 if (res == NULL)
1704 return NULL; /* Callback raised exception */
1705 continue;
1707 g = findgeneric(generic);
1708 if (g == NULL) {
1709 /* Object not known to us (some dialogs cause this) */
1710 continue; /* Ignore it */
1712 if (g->ob_callback == NULL) {
1713 Py_INCREF(g);
1714 return ((PyObject *) g);
1716 arg = PyTuple_Pack(2, (PyObject *)g, g->ob_callback_arg);
1717 if (arg == NULL)
1718 return NULL;
1719 res = PyEval_CallObject(g->ob_callback, arg);
1720 Py_XDECREF(res);
1721 Py_DECREF(arg);
1722 if (res == NULL)
1723 return NULL; /* Callback raised exception */
1727 static PyObject *
1728 forms_do_forms(PyObject *dummy)
1730 return forms_do_or_check_forms(dummy, fl_do_forms);
1733 static PyObject *
1734 forms_check_forms(PyObject *dummy)
1736 return forms_do_or_check_forms(dummy, fl_check_forms);
1739 static PyObject *
1740 forms_do_only_forms(PyObject *dummy)
1742 return forms_do_or_check_forms(dummy, fl_do_only_forms);
1745 static PyObject *
1746 forms_check_only_forms(PyObject *dummy)
1748 return forms_do_or_check_forms(dummy, fl_check_only_forms);
1751 #ifdef UNUSED
1752 static PyObject *
1753 fl_call(void (*func)(void))
1755 (*func)();
1756 Py_INCREF(Py_None);
1757 return Py_None;
1759 #endif
1761 static PyObject *
1762 forms_set_graphics_mode(PyObject *dummy, PyObject *args)
1764 int rgbmode, doublebuf;
1766 if (!PyArg_Parse(args, "(ii)", &rgbmode, &doublebuf))
1767 return NULL;
1768 fl_set_graphics_mode(rgbmode,doublebuf);
1769 Py_INCREF(Py_None);
1770 return Py_None;
1773 static PyObject *
1774 forms_get_rgbmode(PyObject *dummy, PyObject *args)
1776 extern int fl_rgbmode;
1778 if (args != NULL) {
1779 PyErr_BadArgument();
1780 return NULL;
1782 return PyInt_FromLong((long)fl_rgbmode);
1785 static PyObject *
1786 forms_show_errors(PyObject *dummy, PyObject *args)
1788 int show;
1789 if (!PyArg_Parse(args, "i", &show))
1790 return NULL;
1791 fl_show_errors(show);
1792 Py_INCREF(Py_None);
1793 return Py_None;
1796 static PyObject *
1797 forms_set_font_name(PyObject *dummy, PyObject *args)
1799 int numb;
1800 char *name;
1801 if (!PyArg_Parse(args, "(is)", &numb, &name))
1802 return NULL;
1803 fl_set_font_name(numb, name);
1804 Py_INCREF(Py_None);
1805 return Py_None;
1809 static PyObject *
1810 forms_qdevice(PyObject *self, PyObject *args)
1812 short arg1;
1813 if (!PyArg_Parse(args, "h", &arg1))
1814 return NULL;
1815 fl_qdevice(arg1);
1816 Py_INCREF(Py_None);
1817 return Py_None;
1820 static PyObject *
1821 forms_unqdevice(PyObject *self, PyObject *args)
1823 short arg1;
1824 if (!PyArg_Parse(args, "h", &arg1))
1825 return NULL;
1826 fl_unqdevice(arg1);
1827 Py_INCREF(Py_None);
1828 return Py_None;
1831 static PyObject *
1832 forms_isqueued(PyObject *self, PyObject *args)
1834 long retval;
1835 short arg1;
1836 if (!PyArg_Parse(args, "h", &arg1))
1837 return NULL;
1838 retval = fl_isqueued(arg1);
1840 return PyInt_FromLong(retval);
1843 static PyObject *
1844 forms_qtest(PyObject *self, PyObject *args)
1846 long retval;
1847 retval = fl_qtest();
1848 return PyInt_FromLong(retval);
1852 static PyObject *
1853 forms_qread(PyObject *self, PyObject *args)
1855 int dev;
1856 short val;
1857 Py_BEGIN_ALLOW_THREADS
1858 dev = fl_qread(&val);
1859 Py_END_ALLOW_THREADS
1860 return Py_BuildValue("(ih)", dev, val);
1863 static PyObject *
1864 forms_qreset(PyObject *self)
1866 fl_qreset();
1867 Py_INCREF(Py_None);
1868 return Py_None;
1871 static PyObject *
1872 forms_qenter(PyObject *self, PyObject *args)
1874 short arg1, arg2;
1875 if (!PyArg_Parse(args, "(hh)", &arg1, &arg2))
1876 return NULL;
1877 fl_qenter(arg1, arg2);
1878 Py_INCREF(Py_None);
1879 return Py_None;
1882 static PyObject *
1883 forms_color(PyObject *self, PyObject *args)
1885 int arg;
1887 if (!PyArg_Parse(args, "i", &arg)) return NULL;
1889 fl_color((short) arg);
1891 Py_INCREF(Py_None);
1892 return Py_None;
1895 static PyObject *
1896 forms_mapcolor(PyObject *self, PyObject *args)
1898 int arg0, arg1, arg2, arg3;
1900 if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
1901 return NULL;
1903 fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
1905 Py_INCREF(Py_None);
1906 return Py_None;
1909 static PyObject *
1910 forms_getmcolor(PyObject *self, PyObject *args)
1912 int arg;
1913 short r, g, b;
1915 if (!PyArg_Parse(args, "i", &arg)) return NULL;
1917 fl_getmcolor(arg, &r, &g, &b);
1919 return Py_BuildValue("(hhh)", r, g, b);
1922 static PyObject *
1923 forms_get_mouse(PyObject *self)
1925 float x, y;
1927 fl_get_mouse(&x, &y);
1929 return Py_BuildValue("(ff)", x, y);
1932 static PyObject *
1933 forms_tie(PyObject *self, PyObject *args)
1935 short arg1, arg2, arg3;
1936 if (!PyArg_Parse(args, "(hhh)", &arg1, &arg2, &arg3))
1937 return NULL;
1938 fl_tie(arg1, arg2, arg3);
1939 Py_INCREF(Py_None);
1940 return Py_None;
1943 static PyObject *
1944 forms_show_message(PyObject *f, PyObject *args)
1946 char *a, *b, *c;
1948 if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
1950 Py_BEGIN_ALLOW_THREADS
1951 fl_show_message(a, b, c);
1952 Py_END_ALLOW_THREADS
1954 Py_INCREF(Py_None);
1955 return Py_None;
1958 static PyObject *
1959 forms_show_choice(PyObject *f, PyObject *args)
1961 char *m1, *m2, *m3, *b1, *b2, *b3;
1962 int nb;
1963 char *format;
1964 long rv;
1966 if (args == NULL || !PyTuple_Check(args)) {
1967 PyErr_BadArgument();
1968 return NULL;
1970 nb = PyTuple_Size(args) - 3;
1971 if (nb <= 0) {
1972 PyErr_SetString(PyExc_TypeError,
1973 "need at least one button label");
1974 return NULL;
1976 if (PyInt_Check(PyTuple_GetItem(args, 3))) {
1977 PyErr_SetString(PyExc_TypeError,
1978 "'number-of-buttons' argument not needed");
1979 return NULL;
1981 switch (nb) {
1982 case 1: format = "(ssss)"; break;
1983 case 2: format = "(sssss)"; break;
1984 case 3: format = "(ssssss)"; break;
1985 default:
1986 PyErr_SetString(PyExc_TypeError, "too many button labels");
1987 return NULL;
1990 if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
1991 return NULL;
1993 Py_BEGIN_ALLOW_THREADS
1994 rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
1995 Py_END_ALLOW_THREADS
1996 return PyInt_FromLong(rv);
1999 static PyObject *
2000 forms_show_question(PyObject *f, PyObject *args)
2002 int ret;
2003 char *a, *b, *c;
2005 if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
2007 Py_BEGIN_ALLOW_THREADS
2008 ret = fl_show_question(a, b, c);
2009 Py_END_ALLOW_THREADS
2011 return PyInt_FromLong((long) ret);
2014 static PyObject *
2015 forms_show_input(PyObject *f, PyObject *args)
2017 char *str;
2018 char *a, *b;
2020 if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
2022 Py_BEGIN_ALLOW_THREADS
2023 str = fl_show_input(a, b);
2024 Py_END_ALLOW_THREADS
2026 if (str == NULL) {
2027 Py_INCREF(Py_None);
2028 return Py_None;
2030 return PyString_FromString(str);
2033 static PyObject *
2034 forms_file_selector(PyObject *f, PyObject *args)
2036 char *str;
2037 char *a, *b, *c, *d;
2039 if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
2041 Py_BEGIN_ALLOW_THREADS
2042 str = fl_show_file_selector(a, b, c, d);
2043 Py_END_ALLOW_THREADS
2045 if (str == NULL) {
2046 Py_INCREF(Py_None);
2047 return Py_None;
2049 return PyString_FromString(str);
2053 static PyObject *
2054 forms_file_selector_func(PyObject *args, char *(*func)(void))
2056 char *str;
2058 str = (*func) ();
2060 if (str == NULL) {
2061 Py_INCREF(Py_None);
2062 return Py_None;
2064 return PyString_FromString(str);
2067 static PyObject *
2068 forms_get_directory(PyObject *f, PyObject *args)
2070 return forms_file_selector_func(args, fl_get_directory);
2073 static PyObject *
2074 forms_get_pattern(PyObject *f, PyObject *args)
2076 return forms_file_selector_func(args, fl_get_pattern);
2079 static PyObject *
2080 forms_get_filename(PyObject *f, PyObject *args)
2082 return forms_file_selector_func(args, fl_get_filename);
2085 static PyMethodDef forms_methods[] = {
2086 /* adm */
2087 {"make_form", forms_make_form, METH_OLDARGS},
2088 {"activate_all_forms", forms_activate_all_forms, METH_OLDARGS},
2089 {"deactivate_all_forms",forms_deactivate_all_forms, METH_OLDARGS},
2090 /* gl support wrappers */
2091 {"qdevice", forms_qdevice, METH_OLDARGS},
2092 {"unqdevice", forms_unqdevice, METH_OLDARGS},
2093 {"isqueued", forms_isqueued, METH_OLDARGS},
2094 {"qtest", forms_qtest, METH_OLDARGS},
2095 {"qread", forms_qread, METH_OLDARGS},
2096 /* {"blkqread", forms_blkqread, METH_OLDARGS}, */
2097 {"qreset", forms_qreset, METH_NOARGS},
2098 {"qenter", forms_qenter, METH_OLDARGS},
2099 {"get_mouse", forms_get_mouse, METH_NOARGS},
2100 {"tie", forms_tie, METH_OLDARGS},
2101 /* {"new_events", forms_new_events, METH_OLDARGS}, */
2102 {"color", forms_color, METH_OLDARGS},
2103 {"mapcolor", forms_mapcolor, METH_OLDARGS},
2104 {"getmcolor", forms_getmcolor, METH_OLDARGS},
2105 /* interaction */
2106 {"do_forms", forms_do_forms, METH_NOARGS},
2107 {"do_only_forms", forms_do_only_forms, METH_NOARGS},
2108 {"check_forms", forms_check_forms, METH_NOARGS},
2109 {"check_only_forms", forms_check_only_forms, METH_NOARGS},
2110 {"set_event_call_back", forms_set_event_call_back, METH_OLDARGS},
2111 /* goodies */
2112 {"show_message", forms_show_message, METH_OLDARGS},
2113 {"show_question", forms_show_question, METH_OLDARGS},
2114 {"show_choice", forms_show_choice, METH_OLDARGS},
2115 {"show_input", forms_show_input, METH_OLDARGS},
2116 {"show_file_selector", forms_file_selector, METH_OLDARGS},
2117 {"file_selector", forms_file_selector, METH_OLDARGS}, /* BW compat */
2118 {"get_directory", forms_get_directory, METH_OLDARGS},
2119 {"get_pattern", forms_get_pattern, METH_OLDARGS},
2120 {"get_filename", forms_get_filename, METH_OLDARGS},
2121 {"set_graphics_mode", forms_set_graphics_mode, METH_OLDARGS},
2122 {"get_rgbmode", forms_get_rgbmode, METH_OLDARGS},
2123 {"show_errors", forms_show_errors, METH_OLDARGS},
2124 {"set_font_name", forms_set_font_name, METH_OLDARGS},
2125 {NULL, NULL} /* sentinel */
2128 PyMODINIT_FUNC
2129 initfl(void)
2132 if (PyErr_WarnPy3k("the fl module has been removed in "
2133 "Python 3.0", 2) < 0)
2134 return;
2136 Py_InitModule("fl", forms_methods);
2137 if (m == NULL)
2138 return;
2139 foreground();
2140 fl_init();