1 /* FL module -- interface to Mark Overmars' FORMS Library. */
2 
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. */
7 
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).
16  */
17 
18 #include "Python.h"
19 #include "forms.h"
20 #include "structmember.h"
21 
22 /* Generic Forms Objects */
23 
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;
31 
32 static PyTypeObject GenericObjecttype;
33 
34 #define is_genericobject(g) ((g)->ob_type == &GenericObjecttype)
35 
36 /* List of all objects (XXX this should be a hash table on address...) */
37 
38 static PyObject *allgenerics = NULL;
39 static int nfreeslots = 0;
40 
41 /* Add an object to the list of known objects */
42 
43 static void
knowgeneric(genericobject * g)44 knowgeneric(genericobject *g)
45 {
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... */
53         }
54     }
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;
65             }
66         }
67         /* Strange... no free slots found... */
68         nfreeslots = 0;
69     }
70     /* No free entries, append new item to the end */
71     PyList_Append(allgenerics, (PyObject *)g);
72 }
73 
74 /* Find an object in the list of known objects */
75 
76 static genericobject *
findgeneric(FL_OBJECT * generic)77 findgeneric(FL_OBJECT *generic)
78 {
79     int i, n;
80     genericobject *g;
81 
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;
89     }
90     return NULL; /* Unknown object */
91 }
92 
93 /* Remove an object from the list of known objects */
94 
95 static void
forgetgeneric(genericobject * g)96 forgetgeneric(genericobject *g)
97 {
98     int i, n;
99 
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;
112         }
113     }
114 }
115 
116 /* Called when a form is about to be freed --
117    remove all the objects that we know about from it. */
118 
119 static void
releaseobjects(FL_FORM * form)120 releaseobjects(FL_FORM *form)
121 {
122     int i, n;
123     genericobject *g;
124 
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++;
141         }
142     }
143 }
144 
145 
146 /* Methods of generic objects */
147 
148 static PyObject *
generic_set_call_back(genericobject * g,PyObject * args)149 generic_set_call_back(genericobject *g, PyObject *args)
150 {
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;
156     }
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);
167     }
168     Py_INCREF(Py_None);
169     return Py_None;
170 }
171 
172 static PyObject *
generic_call(genericobject * g,void (* func)(FL_OBJECT *))173 generic_call(genericobject *g, void (*func)(FL_OBJECT *))
174 {
175     (*func)(g->ob_generic);
176     Py_INCREF(Py_None);
177     return Py_None;
178 }
179 
180 static PyObject *
generic_delete_object(genericobject * g)181 generic_delete_object(genericobject *g)
182 {
183     PyObject *res;
184     res = generic_call(g, fl_delete_object);
185     if (res != NULL)
186         forgetgeneric(g);
187     return res;
188 }
189 
190 static PyObject *
generic_show_object(genericobject * g)191 generic_show_object(genericobject *g)
192 {
193     return generic_call(g, fl_show_object);
194 }
195 
196 static PyObject *
generic_hide_object(genericobject * g)197 generic_hide_object(genericobject *g)
198 {
199     return generic_call(g, fl_hide_object);
200 }
201 
202 static PyObject *
generic_redraw_object(genericobject * g)203 generic_redraw_object(genericobject *g)
204 {
205     return generic_call(g, fl_redraw_object);
206 }
207 
208 #ifdef OBSOLETE_FORMS_CALLS
209 
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. */
213 
214 static PyObject *
generic_freeze_object(genericobject * g)215 generic_freeze_object(genericobject *g)
216 {
217     return generic_call(g, fl_freeze_object);
218 }
219 
220 static PyObject *
generic_unfreeze_object(genericobject * g)221 generic_unfreeze_object(genericobject *g)
222 {
223     return generic_call(g, fl_unfreeze_object);
224 }
225 
226 #endif /* OBSOLETE_FORMS_CALLS */
227 
228 static PyObject *
generic_activate_object(genericobject * g)229 generic_activate_object(genericobject *g)
230 {
231     return generic_call(g, fl_activate_object);
232 }
233 
234 static PyObject *
generic_deactivate_object(genericobject * g)235 generic_deactivate_object(genericobject *g)
236 {
237     return generic_call(g, fl_deactivate_object);
238 }
239 
240 static PyObject *
generic_set_object_shortcut(genericobject * g,PyObject * args)241 generic_set_object_shortcut(genericobject *g, PyObject *args)
242 {
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;
249 }
250 
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 */
265 };
266 
267 static void
generic_dealloc(genericobject * g)268 generic_dealloc(genericobject *g)
269 {
270     fl_free_object(g->ob_generic);
271     Py_XDECREF(g->ob_callback);
272     Py_XDECREF(g->ob_callback_arg);
273     PyObject_Del(g);
274 }
275 
276 #define OFF(x) offsetof(FL_OBJECT, x)
277 
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 */
303 };
304 
305 #undef OFF
306 
307 static PyObject *
generic_getattr(genericobject * g,char * name)308 generic_getattr(genericobject *g, char *name)
309 {
310     PyObject *meth;
311 
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();
317     }
318 
319     meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
320     if (meth != NULL)
321         return meth;
322     PyErr_Clear();
323 
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);
328 
329     return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
330 }
331 
332 static int
generic_setattr(genericobject * g,char * name,PyObject * v)333 generic_setattr(genericobject *g, char *name, PyObject *v)
334 {
335     int ret;
336 
337     if (v == NULL) {
338         PyErr_SetString(PyExc_TypeError,
339                         "can't delete forms object attributes");
340         return -1;
341     }
342 
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;
350         }
351         fl_set_object_label(g->ob_generic, PyString_AsString(v));
352         return 0;
353     }
354 
355     ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
356 
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);
362 
363     return ret;
364 }
365 
366 static PyObject *
generic_repr(genericobject * g)367 generic_repr(genericobject *g)
368 {
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);
373 }
374 
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*/
388 };
389 
390 static PyObject *
newgenericobject(FL_OBJECT * generic,PyMethodDef * methods)391 newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
392 {
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;
403 }
404 
405 /**********************************************************************/
406 /* Some common calling sequences */
407 
408 /* void func (object, float) */
409 static PyObject *
call_forms_INf(void (* func)(FL_OBJECT *,float),FL_OBJECT * obj,PyObject * args)410 call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
411 {
412     float parameter;
413 
414     if (!PyArg_Parse(args, "f", &parameter)) return NULL;
415 
416     (*func) (obj, parameter);
417 
418     Py_INCREF(Py_None);
419     return Py_None;
420 }
421 
422 /* void func (object, float) */
423 static PyObject *
call_forms_INfINf(void (* func)(FL_OBJECT *,float,float),FL_OBJECT * obj,PyObject * args)424 call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
425 {
426     float par1, par2;
427 
428     if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
429 
430     (*func) (obj, par1, par2);
431 
432     Py_INCREF(Py_None);
433     return Py_None;
434 }
435 
436 /* void func (object, int) */
437 static PyObject *
call_forms_INi(void (* func)(FL_OBJECT *,int),FL_OBJECT * obj,PyObject * args)438 call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
439 {
440     int parameter;
441 
442     if (!PyArg_Parse(args, "i", &parameter)) return NULL;
443 
444     (*func) (obj, parameter);
445 
446     Py_INCREF(Py_None);
447     return Py_None;
448 }
449 
450 /* void func (object, char) */
451 static PyObject *
call_forms_INc(void (* func)(FL_OBJECT *,int),FL_OBJECT * obj,PyObject * args)452 call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
453 {
454     char *a;
455 
456     if (!PyArg_Parse(args, "s", &a)) return NULL;
457 
458     (*func) (obj, a[0]);
459 
460     Py_INCREF(Py_None);
461     return Py_None;
462 }
463 
464 /* void func (object, string) */
465 static PyObject *
call_forms_INstr(void (* func)(FL_OBJECT *,char *),FL_OBJECT * obj,PyObject * args)466 call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
467 {
468     char *a;
469 
470     if (!PyArg_Parse(args, "s", &a)) return NULL;
471 
472     (*func) (obj, a);
473 
474     Py_INCREF(Py_None);
475     return Py_None;
476 }
477 
478 
479 /* void func (object, int, string) */
480 static PyObject *
call_forms_INiINstr(void (* func)(FL_OBJECT *,int,char *),FL_OBJECT * obj,PyObject * args)481 call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
482 {
483     char *b;
484     int a;
485 
486     if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
487 
488     (*func) (obj, a, b);
489 
490     Py_INCREF(Py_None);
491     return Py_None;
492 }
493 
494 #ifdef UNUSED
495 /* void func (object, int, int) */
496 static PyObject *
call_forms_INiINi(void (* func)(FL_OBJECT *,int,int),FL_OBJECT * obj,PyObject * args)497 call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
498 {
499     int par1, par2;
500 
501     if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
502 
503     (*func) (obj, par1, par2);
504 
505     Py_INCREF(Py_None);
506     return Py_None;
507 }
508 #endif
509 
510 /* int func (object) */
511 static PyObject *
call_forms_Ri(int (* func)(FL_OBJECT *),FL_OBJECT * obj)512 call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj)
513 {
514     int retval;
515 
516     retval = (*func) (obj);
517 
518     return PyInt_FromLong ((long) retval);
519 }
520 
521 /* char * func (object) */
522 static PyObject *
call_forms_Rstr(char * (* func)(FL_OBJECT *),FL_OBJECT * obj)523 call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj)
524 {
525     char *str;
526 
527     str = (*func) (obj);
528 
529     if (str == NULL) {
530         Py_INCREF(Py_None);
531         return Py_None;
532     }
533     return PyString_FromString (str);
534 }
535 
536 /* int func (object) */
537 static PyObject *
call_forms_Rf(float (* func)(FL_OBJECT *),FL_OBJECT * obj)538 call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj)
539 {
540     float retval;
541 
542     retval = (*func) (obj);
543 
544     return PyFloat_FromDouble (retval);
545 }
546 
547 static PyObject *
call_forms_OUTfOUTf(void (* func)(FL_OBJECT *,float *,float *),FL_OBJECT * obj)548 call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj)
549 {
550     float f1, f2;
551 
552     (*func) (obj, &f1, &f2);
553 
554     return Py_BuildValue("(ff)", f1, f2);
555 }
556 
557 #ifdef UNUSED
558 static PyObject *
call_forms_OUTf(void (* func)(FL_OBJECT *,float *),FL_OBJECT * obj)559 call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj)
560 {
561     float f;
562 
563     (*func) (obj, &f);
564 
565     return PyFloat_FromDouble (f);
566 }
567 #endif
568 
569 /**********************************************************************/
570 /* Class : browser */
571 
572 static PyObject *
set_browser_topline(genericobject * g,PyObject * args)573 set_browser_topline(genericobject *g, PyObject *args)
574 {
575     return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
576 }
577 
578 static PyObject *
clear_browser(genericobject * g)579 clear_browser(genericobject *g)
580 {
581     return generic_call (g, fl_clear_browser);
582 }
583 
584 static PyObject *
add_browser_line(genericobject * g,PyObject * args)585 add_browser_line (genericobject *g, PyObject *args)
586 {
587     return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
588 }
589 
590 static PyObject *
addto_browser(genericobject * g,PyObject * args)591 addto_browser (genericobject *g, PyObject *args)
592 {
593     return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
594 }
595 
596 static PyObject *
insert_browser_line(genericobject * g,PyObject * args)597 insert_browser_line (genericobject *g, PyObject *args)
598 {
599     return call_forms_INiINstr (fl_insert_browser_line,
600                                 g-> ob_generic, args);
601 }
602 
603 static PyObject *
delete_browser_line(genericobject * g,PyObject * args)604 delete_browser_line (genericobject *g, PyObject *args)
605 {
606     return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
607 }
608 
609 static PyObject *
replace_browser_line(genericobject * g,PyObject * args)610 replace_browser_line (genericobject *g, PyObject *args)
611 {
612     return call_forms_INiINstr (fl_replace_browser_line,
613                                 g-> ob_generic, args);
614 }
615 
616 static PyObject *
get_browser_line(genericobject * g,PyObject * args)617 get_browser_line(genericobject *g, PyObject *args)
618 {
619     int i;
620     char *str;
621 
622     if (!PyArg_Parse(args, "i", &i))
623         return NULL;
624 
625     str = fl_get_browser_line (g->ob_generic, i);
626 
627     if (str == NULL) {
628         Py_INCREF(Py_None);
629         return Py_None;
630     }
631     return PyString_FromString (str);
632 }
633 
634 static PyObject *
load_browser(genericobject * g,PyObject * args)635 load_browser (genericobject *g, PyObject *args)
636 {
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);
640 }
641 
642 static PyObject *
get_browser_maxline(genericobject * g)643 get_browser_maxline(genericobject *g)
644 {
645     return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
646 }
647 
648 static PyObject *
select_browser_line(genericobject * g,PyObject * args)649 select_browser_line (genericobject *g, PyObject *args)
650 {
651     return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
652 }
653 
654 static PyObject *
deselect_browser_line(genericobject * g,PyObject * args)655 deselect_browser_line (genericobject *g, PyObject *args)
656 {
657     return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
658 }
659 
660 static PyObject *
deselect_browser(genericobject * g)661 deselect_browser (genericobject *g)
662 {
663     return generic_call (g, fl_deselect_browser);
664 }
665 
666 static PyObject *
isselected_browser_line(genericobject * g,PyObject * args)667 isselected_browser_line (genericobject *g, PyObject *args)
668 {
669     int i, j;
670 
671     if (!PyArg_Parse(args, "i", &i))
672         return NULL;
673 
674     j = fl_isselected_browser_line (g->ob_generic, i);
675 
676     return PyInt_FromLong (j);
677 }
678 
679 static PyObject *
get_browser(genericobject * g)680 get_browser (genericobject *g)
681 {
682     return call_forms_Ri (fl_get_browser, g-> ob_generic);
683 }
684 
685 static PyObject *
set_browser_fontsize(genericobject * g,PyObject * args)686 set_browser_fontsize (genericobject *g, PyObject *args)
687 {
688     return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
689 }
690 
691 static PyObject *
set_browser_fontstyle(genericobject * g,PyObject * args)692 set_browser_fontstyle (genericobject *g, PyObject *args)
693 {
694     return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
695 }
696 
697 static PyObject *
set_browser_specialkey(genericobject * g,PyObject * args)698 set_browser_specialkey (genericobject *g, PyObject *args)
699 {
700     return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
701 }
702 
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 */
741 };
742 
743 /* Class: button */
744 
745 static PyObject *
set_button(genericobject * g,PyObject * args)746 set_button(genericobject *g, PyObject *args)
747 {
748     return call_forms_INi (fl_set_button, g-> ob_generic, args);
749 }
750 
751 static PyObject *
get_button(genericobject * g)752 get_button(genericobject *g)
753 {
754     return call_forms_Ri (fl_get_button, g-> ob_generic);
755 }
756 
757 static PyObject *
get_button_numb(genericobject * g)758 get_button_numb(genericobject *g)
759 {
760     return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
761 }
762 
763 static PyObject *
set_button_shortcut(genericobject * g,PyObject * args)764 set_button_shortcut(genericobject *g, PyObject *args)
765 {
766     return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
767 }
768 
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 */
775 };
776 
777 /* Class: choice */
778 
779 static PyObject *
set_choice(genericobject * g,PyObject * args)780 set_choice(genericobject *g, PyObject *args)
781 {
782     return call_forms_INi (fl_set_choice, g-> ob_generic, args);
783 }
784 
785 static PyObject *
get_choice(genericobject * g)786 get_choice(genericobject *g)
787 {
788     return call_forms_Ri (fl_get_choice, g-> ob_generic);
789 }
790 
791 static PyObject *
clear_choice(genericobject * g)792 clear_choice (genericobject *g)
793 {
794     return generic_call (g, fl_clear_choice);
795 }
796 
797 static PyObject *
addto_choice(genericobject * g,PyObject * args)798 addto_choice (genericobject *g, PyObject *args)
799 {
800     return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
801 }
802 
803 static PyObject *
replace_choice(genericobject * g,PyObject * args)804 replace_choice (genericobject *g, PyObject *args)
805 {
806     return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
807 }
808 
809 static PyObject *
delete_choice(genericobject * g,PyObject * args)810 delete_choice (genericobject *g, PyObject *args)
811 {
812     return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
813 }
814 
815 static PyObject *
get_choice_text(genericobject * g)816 get_choice_text (genericobject *g)
817 {
818     return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
819 }
820 
821 static PyObject *
set_choice_fontsize(genericobject * g,PyObject * args)822 set_choice_fontsize (genericobject *g, PyObject *args)
823 {
824     return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
825 }
826 
827 static PyObject *
set_choice_fontstyle(genericobject * g,PyObject * args)828 set_choice_fontstyle (genericobject *g, PyObject *args)
829 {
830     return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
831 }
832 
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 */
844 };
845 
846 /* Class : Clock */
847 
848 static PyObject *
get_clock(genericobject * g)849 get_clock(genericobject *g)
850 {
851     int i0, i1, i2;
852 
853     fl_get_clock (g->ob_generic, &i0, &i1, &i2);
854 
855     return Py_BuildValue("(iii)", i0, i1, i2);
856 }
857 
858 static PyMethodDef clock_methods[] = {
859     {"get_clock",               (PyCFunction)get_clock, METH_NOARGS},
860     {NULL,                      NULL}           /* sentinel */
861 };
862 
863 /* CLass : Counters */
864 
865 static PyObject *
get_counter_value(genericobject * g)866 get_counter_value(genericobject *g)
867 {
868     return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
869 }
870 
871 static PyObject *
set_counter_value(genericobject * g,PyObject * args)872 set_counter_value (genericobject *g, PyObject *args)
873 {
874     return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
875 }
876 
877 static PyObject *
set_counter_precision(genericobject * g,PyObject * args)878 set_counter_precision (genericobject *g, PyObject *args)
879 {
880     return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
881 }
882 
883 static PyObject *
set_counter_bounds(genericobject * g,PyObject * args)884 set_counter_bounds (genericobject *g, PyObject *args)
885 {
886     return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
887 }
888 
889 static PyObject *
set_counter_step(genericobject * g,PyObject * args)890 set_counter_step (genericobject *g, PyObject *args)
891 {
892     return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
893 }
894 
895 static PyObject *
set_counter_return(genericobject * g,PyObject * args)896 set_counter_return (genericobject *g, PyObject *args)
897 {
898     return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
899 }
900 
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 */
915 };
916 
917 
918 /* Class: Dials */
919 
920 static PyObject *
get_dial_value(genericobject * g)921 get_dial_value(genericobject *g)
922 {
923     return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
924 }
925 
926 static PyObject *
set_dial_value(genericobject * g,PyObject * args)927 set_dial_value (genericobject *g, PyObject *args)
928 {
929     return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
930 }
931 
932 static PyObject *
set_dial_bounds(genericobject * g,PyObject * args)933 set_dial_bounds (genericobject *g, PyObject *args)
934 {
935     return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
936 }
937 
938 static PyObject *
get_dial_bounds(genericobject * g)939 get_dial_bounds (genericobject *g)
940 {
941     return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
942 }
943 
944 static PyObject *
set_dial_step(genericobject * g,PyObject * args)945 set_dial_step (genericobject *g, PyObject *args)
946 {
947     return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
948 }
949 
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 */
957 };
958 
959 /* Class : Input */
960 
961 static PyObject *
set_input(genericobject * g,PyObject * args)962 set_input (genericobject *g, PyObject *args)
963 {
964     return call_forms_INstr (fl_set_input, g-> ob_generic, args);
965 }
966 
967 static PyObject *
get_input(genericobject * g)968 get_input (genericobject *g)
969 {
970     return call_forms_Rstr (fl_get_input, g-> ob_generic);
971 }
972 
973 static PyObject *
set_input_color(genericobject * g,PyObject * args)974 set_input_color (genericobject *g, PyObject *args)
975 {
976     return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
977 }
978 
979 static PyObject *
set_input_return(genericobject * g,PyObject * args)980 set_input_return (genericobject *g, PyObject *args)
981 {
982     return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
983 }
984 
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 */
991 };
992 
993 
994 /* Class : Menu */
995 
996 static PyObject *
set_menu(genericobject * g,PyObject * args)997 set_menu (genericobject *g, PyObject *args)
998 {
999     return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
1000 }
1001 
1002 static PyObject *
get_menu(genericobject * g)1003 get_menu (genericobject *g)
1004 {
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);
1008 }
1009 
1010 static PyObject *
get_menu_text(genericobject * g)1011 get_menu_text (genericobject *g)
1012 {
1013     return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
1014 }
1015 
1016 static PyObject *
addto_menu(genericobject * g,PyObject * args)1017 addto_menu (genericobject *g, PyObject *args)
1018 {
1019     return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
1020 }
1021 
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 */
1028 };
1029 
1030 
1031 /* Class: Sliders */
1032 
1033 static PyObject *
get_slider_value(genericobject * g)1034 get_slider_value(genericobject *g)
1035 {
1036     return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
1037 }
1038 
1039 static PyObject *
set_slider_value(genericobject * g,PyObject * args)1040 set_slider_value (genericobject *g, PyObject *args)
1041 {
1042     return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
1043 }
1044 
1045 static PyObject *
set_slider_bounds(genericobject * g,PyObject * args)1046 set_slider_bounds (genericobject *g, PyObject *args)
1047 {
1048     return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
1049 }
1050 
1051 static PyObject *
get_slider_bounds(genericobject * g)1052 get_slider_bounds (genericobject *g)
1053 {
1054     return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
1055 }
1056 
1057 static PyObject *
set_slider_return(genericobject * g,PyObject * args)1058 set_slider_return (genericobject *g, PyObject *args)
1059 {
1060     return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
1061 }
1062 
1063 static PyObject *
set_slider_size(genericobject * g,PyObject * args)1064 set_slider_size (genericobject *g, PyObject *args)
1065 {
1066     return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
1067 }
1068 
1069 static PyObject *
set_slider_precision(genericobject * g,PyObject * args)1070 set_slider_precision (genericobject *g, PyObject *args)
1071 {
1072     return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
1073 }
1074 
1075 static PyObject *
set_slider_step(genericobject * g,PyObject * args)1076 set_slider_step (genericobject *g, PyObject *args)
1077 {
1078     return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
1079 }
1080 
1081 
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 */
1092 };
1093 
1094 static PyObject *
set_positioner_xvalue(genericobject * g,PyObject * args)1095 set_positioner_xvalue (genericobject *g, PyObject *args)
1096 {
1097     return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
1098 }
1099 
1100 static PyObject *
set_positioner_xbounds(genericobject * g,PyObject * args)1101 set_positioner_xbounds (genericobject *g, PyObject *args)
1102 {
1103     return call_forms_INfINf (fl_set_positioner_xbounds,
1104                               g-> ob_generic, args);
1105 }
1106 
1107 static PyObject *
set_positioner_yvalue(genericobject * g,PyObject * args)1108 set_positioner_yvalue (genericobject *g, PyObject *args)
1109 {
1110     return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
1111 }
1112 
1113 static PyObject *
set_positioner_ybounds(genericobject * g,PyObject * args)1114 set_positioner_ybounds (genericobject *g, PyObject *args)
1115 {
1116     return call_forms_INfINf (fl_set_positioner_ybounds,
1117                               g-> ob_generic, args);
1118 }
1119 
1120 static PyObject *
get_positioner_xvalue(genericobject * g)1121 get_positioner_xvalue (genericobject *g)
1122 {
1123     return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
1124 }
1125 
1126 static PyObject *
get_positioner_xbounds(genericobject * g)1127 get_positioner_xbounds (genericobject *g)
1128 {
1129     return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
1130 }
1131 
1132 static PyObject *
get_positioner_yvalue(genericobject * g)1133 get_positioner_yvalue (genericobject *g)
1134 {
1135     return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
1136 }
1137 
1138 static PyObject *
get_positioner_ybounds(genericobject * g)1139 get_positioner_ybounds (genericobject *g)
1140 {
1141     return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
1142 }
1143 
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 */
1162 };
1163 
1164 /* Class timer */
1165 
1166 static PyObject *
set_timer(genericobject * g,PyObject * args)1167 set_timer (genericobject *g, PyObject *args)
1168 {
1169     return call_forms_INf (fl_set_timer, g-> ob_generic, args);
1170 }
1171 
1172 static PyObject *
get_timer(genericobject * g)1173 get_timer (genericobject *g)
1174 {
1175     return call_forms_Rf (fl_get_timer, g-> ob_generic);
1176 }
1177 
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 */
1182 };
1183 
1184 /* Form objects */
1185 
1186 typedef struct {
1187     PyObject_HEAD
1188     FL_FORM *ob_form;
1189 } formobject;
1190 
1191 static PyTypeObject Formtype;
1192 
1193 #define is_formobject(v) ((v)->ob_type == &Formtype)
1194 
1195 static PyObject *
form_show_form(formobject * f,PyObject * args)1196 form_show_form(formobject *f, PyObject *args)
1197 {
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;
1205 }
1206 
1207 static PyObject *
form_call(void (* func)(FL_FORM *),FL_FORM * f)1208 form_call(void (*func)(FL_FORM *), FL_FORM *f)
1209 {
1210     (*func)(f);
1211 
1212     Py_INCREF(Py_None);
1213     return Py_None;
1214 }
1215 
1216 static PyObject *
form_call_INiINi(void (* func)(FL_FORM *,int,int),FL_FORM * f,PyObject * args)1217 form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
1218 {
1219     int a, b;
1220 
1221     if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
1222 
1223     (*func)(f, a, b);
1224 
1225     Py_INCREF(Py_None);
1226     return Py_None;
1227 }
1228 
1229 static PyObject *
form_call_INfINf(void (* func)(FL_FORM *,float,float),FL_FORM * f,PyObject * args)1230 form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
1231 {
1232     float a, b;
1233 
1234     if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
1235 
1236     (*func)(f, a, b);
1237 
1238     Py_INCREF(Py_None);
1239     return Py_None;
1240 }
1241 
1242 static PyObject *
form_hide_form(formobject * f)1243 form_hide_form(formobject *f)
1244 {
1245     return form_call(fl_hide_form, f-> ob_form);
1246 }
1247 
1248 static PyObject *
form_redraw_form(formobject * f)1249 form_redraw_form(formobject *f)
1250 {
1251     return form_call(fl_redraw_form, f-> ob_form);
1252 }
1253 
1254 static PyObject *
form_set_form_position(formobject * f,PyObject * args)1255 form_set_form_position(formobject *f, PyObject *args)
1256 {
1257     return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
1258 }
1259 
1260 static PyObject *
form_set_form_size(formobject * f,PyObject * args)1261 form_set_form_size(formobject *f, PyObject *args)
1262 {
1263     return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
1264 }
1265 
1266 static PyObject *
form_scale_form(formobject * f,PyObject * args)1267 form_scale_form(formobject *f, PyObject *args)
1268 {
1269     return form_call_INfINf(fl_scale_form, f-> ob_form, args);
1270 }
1271 
1272 static PyObject *
generic_add_object(formobject * f,PyObject * args,FL_OBJECT * (* func)(int,float,float,float,float,char *),PyMethodDef * internal_methods)1273 generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
1274 {
1275     int type;
1276     float x, y, w, h;
1277     char *name;
1278     FL_OBJECT *obj;
1279 
1280     if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
1281         return NULL;
1282 
1283     fl_addto_form (f-> ob_form);
1284 
1285     obj = (*func) (type, x, y, w, h, name);
1286 
1287     fl_end_form();
1288 
1289     if (obj == NULL) {
1290         PyErr_NoMemory();
1291         return NULL;
1292     }
1293 
1294     return newgenericobject (obj, internal_methods);
1295 }
1296 
1297 static PyObject *
form_add_button(formobject * f,PyObject * args)1298 form_add_button(formobject *f, PyObject *args)
1299 {
1300     return generic_add_object(f, args, fl_add_button, button_methods);
1301 }
1302 
1303 static PyObject *
form_add_lightbutton(formobject * f,PyObject * args)1304 form_add_lightbutton(formobject *f, PyObject *args)
1305 {
1306     return generic_add_object(f, args, fl_add_lightbutton, button_methods);
1307 }
1308 
1309 static PyObject *
form_add_roundbutton(formobject * f,PyObject * args)1310 form_add_roundbutton(formobject *f, PyObject *args)
1311 {
1312     return generic_add_object(f, args, fl_add_roundbutton, button_methods);
1313 }
1314 
1315 static PyObject *
form_add_menu(formobject * f,PyObject * args)1316 form_add_menu (formobject *f, PyObject *args)
1317 {
1318     return generic_add_object(f, args, fl_add_menu, menu_methods);
1319 }
1320 
1321 static PyObject *
form_add_slider(formobject * f,PyObject * args)1322 form_add_slider(formobject *f, PyObject *args)
1323 {
1324     return generic_add_object(f, args, fl_add_slider, slider_methods);
1325 }
1326 
1327 static PyObject *
form_add_valslider(formobject * f,PyObject * args)1328 form_add_valslider(formobject *f, PyObject *args)
1329 {
1330     return generic_add_object(f, args, fl_add_valslider, slider_methods);
1331 }
1332 
1333 static PyObject *
form_add_dial(formobject * f,PyObject * args)1334 form_add_dial(formobject *f, PyObject *args)
1335 {
1336     return generic_add_object(f, args, fl_add_dial, dial_methods);
1337 }
1338 
1339 static PyObject *
form_add_counter(formobject * f,PyObject * args)1340 form_add_counter(formobject *f, PyObject *args)
1341 {
1342     return generic_add_object(f, args, fl_add_counter, counter_methods);
1343 }
1344 
1345 static PyObject *
form_add_clock(formobject * f,PyObject * args)1346 form_add_clock(formobject *f, PyObject *args)
1347 {
1348     return generic_add_object(f, args, fl_add_clock, clock_methods);
1349 }
1350 
1351 static PyObject *
form_add_box(formobject * f,PyObject * args)1352 form_add_box(formobject *f, PyObject *args)
1353 {
1354     return generic_add_object(f, args, fl_add_box,
1355                               (PyMethodDef *)NULL);
1356 }
1357 
1358 static PyObject *
form_add_choice(formobject * f,PyObject * args)1359 form_add_choice(formobject *f, PyObject *args)
1360 {
1361     return generic_add_object(f, args, fl_add_choice, choice_methods);
1362 }
1363 
1364 static PyObject *
form_add_browser(formobject * f,PyObject * args)1365 form_add_browser(formobject *f, PyObject *args)
1366 {
1367     return generic_add_object(f, args, fl_add_browser, browser_methods);
1368 }
1369 
1370 static PyObject *
form_add_positioner(formobject * f,PyObject * args)1371 form_add_positioner(formobject *f, PyObject *args)
1372 {
1373     return generic_add_object(f, args, fl_add_positioner,
1374                               positioner_methods);
1375 }
1376 
1377 static PyObject *
form_add_input(formobject * f,PyObject * args)1378 form_add_input(formobject *f, PyObject *args)
1379 {
1380     return generic_add_object(f, args, fl_add_input, input_methods);
1381 }
1382 
1383 static PyObject *
form_add_text(formobject * f,PyObject * args)1384 form_add_text(formobject *f, PyObject *args)
1385 {
1386     return generic_add_object(f, args, fl_add_text,
1387                               (PyMethodDef *)NULL);
1388 }
1389 
1390 static PyObject *
form_add_timer(formobject * f,PyObject * args)1391 form_add_timer(formobject *f, PyObject *args)
1392 {
1393     return generic_add_object(f, args, fl_add_timer, timer_methods);
1394 }
1395 
1396 static PyObject *
form_freeze_form(formobject * f)1397 form_freeze_form(formobject *f)
1398 {
1399     return form_call(fl_freeze_form, f-> ob_form);
1400 }
1401 
1402 static PyObject *
form_unfreeze_form(formobject * f)1403 form_unfreeze_form(formobject *f)
1404 {
1405     return form_call(fl_unfreeze_form, f-> ob_form);
1406 }
1407 
1408 static PyObject *
form_activate_form(formobject * f)1409 form_activate_form(formobject *f)
1410 {
1411     return form_call(fl_activate_form, f-> ob_form);
1412 }
1413 
1414 static PyObject *
form_deactivate_form(formobject * f)1415 form_deactivate_form(formobject *f)
1416 {
1417     return form_call(fl_deactivate_form, f-> ob_form);
1418 }
1419 
1420 static PyObject *
form_bgn_group(formobject * f,PyObject * args)1421 form_bgn_group(formobject *f, PyObject *args)
1422 {
1423     FL_OBJECT *obj;
1424 
1425     fl_addto_form(f-> ob_form);
1426     obj = fl_bgn_group();
1427     fl_end_form();
1428 
1429     if (obj == NULL) {
1430         PyErr_NoMemory();
1431         return NULL;
1432     }
1433 
1434     return newgenericobject (obj, (PyMethodDef *) NULL);
1435 }
1436 
1437 static PyObject *
form_end_group(formobject * f,PyObject * args)1438 form_end_group(formobject *f, PyObject *args)
1439 {
1440     fl_addto_form(f-> ob_form);
1441     fl_end_group();
1442     fl_end_form();
1443     Py_INCREF(Py_None);
1444     return Py_None;
1445 }
1446 
1447 static PyObject *
forms_find_first_or_last(FL_OBJECT * (* func)(FL_FORM *,int,float,float),formobject * f,PyObject * args)1448 forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
1449 {
1450     int type;
1451     float mx, my;
1452     FL_OBJECT *generic;
1453     genericobject *g;
1454 
1455     if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
1456 
1457     generic = (*func) (f-> ob_form, type, mx, my);
1458 
1459     if (generic == NULL)
1460     {
1461         Py_INCREF(Py_None);
1462         return Py_None;
1463     }
1464 
1465     g = findgeneric(generic);
1466     if (g == NULL) {
1467         PyErr_SetString(PyExc_RuntimeError,
1468                    "forms_find_{first|last} returns unknown object");
1469         return NULL;
1470     }
1471     Py_INCREF(g);
1472     return (PyObject *) g;
1473 }
1474 
1475 static PyObject *
form_find_first(formobject * f,PyObject * args)1476 form_find_first(formobject *f, PyObject *args)
1477 {
1478     return forms_find_first_or_last(fl_find_first, f, args);
1479 }
1480 
1481 static PyObject *
form_find_last(formobject * f,PyObject * args)1482 form_find_last(formobject *f, PyObject *args)
1483 {
1484     return forms_find_first_or_last(fl_find_last, f, args);
1485 }
1486 
1487 static PyObject *
form_set_object_focus(formobject * f,PyObject * args)1488 form_set_object_focus(formobject *f, PyObject *args)
1489 {
1490     genericobject *g;
1491     if (args == NULL || !is_genericobject(args)) {
1492         PyErr_BadArgument();
1493         return NULL;
1494     }
1495     g = (genericobject *)args;
1496     fl_set_object_focus(f->ob_form, g->ob_generic);
1497     Py_INCREF(Py_None);
1498     return Py_None;
1499 }
1500 
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},
1518 
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 */
1538 };
1539 
1540 static void
form_dealloc(formobject * f)1541 form_dealloc(formobject *f)
1542 {
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);
1548 }
1549 
1550 #define OFF(x) offsetof(FL_FORM, x)
1551 
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 */
1563 };
1564 
1565 #undef OFF
1566 
1567 static PyObject *
form_getattr(formobject * f,char * name)1568 form_getattr(formobject *f, char *name)
1569 {
1570     PyObject *meth;
1571 
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);
1577 }
1578 
1579 static int
form_setattr(formobject * f,char * name,PyObject * v)1580 form_setattr(formobject *f, char *name, PyObject *v)
1581 {
1582     if (v == NULL) {
1583         PyErr_SetString(PyExc_TypeError,
1584                         "can't delete form attributes");
1585         return -1;
1586     }
1587 
1588     return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
1589 }
1590 
1591 static PyObject *
form_repr(formobject * f)1592 form_repr(formobject *f)
1593 {
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);
1598 }
1599 
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*/
1613 };
1614 
1615 static PyObject *
newformobject(FL_FORM * form)1616 newformobject(FL_FORM *form)
1617 {
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;
1624 }
1625 
1626 
1627 /* The "fl" module */
1628 
1629 static PyObject *
forms_make_form(PyObject * dummy,PyObject * args)1630 forms_make_form(PyObject *dummy, PyObject *args)
1631 {
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;
1642     }
1643     fl_end_form();
1644     return newformobject(form);
1645 }
1646 
1647 static PyObject *
forms_activate_all_forms(PyObject * f,PyObject * args)1648 forms_activate_all_forms(PyObject *f, PyObject *args)
1649 {
1650     fl_activate_all_forms();
1651     Py_INCREF(Py_None);
1652     return Py_None;
1653 }
1654 
1655 static PyObject *
forms_deactivate_all_forms(PyObject * f,PyObject * args)1656 forms_deactivate_all_forms(PyObject *f, PyObject *args)
1657 {
1658     fl_deactivate_all_forms();
1659     Py_INCREF(Py_None);
1660     return Py_None;
1661 }
1662 
1663 static PyObject *my_event_callback = NULL;
1664 
1665 static PyObject *
forms_set_event_call_back(PyObject * dummy,PyObject * args)1666 forms_set_event_call_back(PyObject *dummy, PyObject *args)
1667 {
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;
1674 }
1675 
1676 static PyObject *
forms_do_or_check_forms(PyObject * dummy,FL_OBJECT * (* func)(void))1677 forms_do_or_check_forms(PyObject *dummy, FL_OBJECT *(*func)(void))
1678 {
1679     FL_OBJECT *generic;
1680     genericobject *g;
1681     PyObject *arg, *res;
1682 
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;
1690         }
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;
1706         }
1707         g = findgeneric(generic);
1708         if (g == NULL) {
1709             /* Object not known to us (some dialogs cause this) */
1710             continue; /* Ignore it */
1711         }
1712         if (g->ob_callback == NULL) {
1713             Py_INCREF(g);
1714             return ((PyObject *) g);
1715         }
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 */
1724     }
1725 }
1726 
1727 static PyObject *
forms_do_forms(PyObject * dummy)1728 forms_do_forms(PyObject *dummy)
1729 {
1730     return forms_do_or_check_forms(dummy, fl_do_forms);
1731 }
1732 
1733 static PyObject *
forms_check_forms(PyObject * dummy)1734 forms_check_forms(PyObject *dummy)
1735 {
1736     return forms_do_or_check_forms(dummy, fl_check_forms);
1737 }
1738 
1739 static PyObject *
forms_do_only_forms(PyObject * dummy)1740 forms_do_only_forms(PyObject *dummy)
1741 {
1742     return forms_do_or_check_forms(dummy, fl_do_only_forms);
1743 }
1744 
1745 static PyObject *
forms_check_only_forms(PyObject * dummy)1746 forms_check_only_forms(PyObject *dummy)
1747 {
1748     return forms_do_or_check_forms(dummy, fl_check_only_forms);
1749 }
1750 
1751 #ifdef UNUSED
1752 static PyObject *
fl_call(void (* func)(void))1753 fl_call(void (*func)(void))
1754 {
1755     (*func)();
1756     Py_INCREF(Py_None);
1757     return Py_None;
1758 }
1759 #endif
1760 
1761 static PyObject *
forms_set_graphics_mode(PyObject * dummy,PyObject * args)1762 forms_set_graphics_mode(PyObject *dummy, PyObject *args)
1763 {
1764     int rgbmode, doublebuf;
1765 
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;
1771 }
1772 
1773 static PyObject *
forms_get_rgbmode(PyObject * dummy,PyObject * args)1774 forms_get_rgbmode(PyObject *dummy, PyObject *args)
1775 {
1776     extern int fl_rgbmode;
1777 
1778     if (args != NULL) {
1779         PyErr_BadArgument();
1780         return NULL;
1781     }
1782     return PyInt_FromLong((long)fl_rgbmode);
1783 }
1784 
1785 static PyObject *
forms_show_errors(PyObject * dummy,PyObject * args)1786 forms_show_errors(PyObject *dummy, PyObject *args)
1787 {
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;
1794 }
1795 
1796 static PyObject *
forms_set_font_name(PyObject * dummy,PyObject * args)1797 forms_set_font_name(PyObject *dummy, PyObject *args)
1798 {
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;
1806 }
1807 
1808 
1809 static PyObject *
forms_qdevice(PyObject * self,PyObject * args)1810 forms_qdevice(PyObject *self, PyObject *args)
1811 {
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;
1818 }
1819 
1820 static PyObject *
forms_unqdevice(PyObject * self,PyObject * args)1821 forms_unqdevice(PyObject *self, PyObject *args)
1822 {
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;
1829 }
1830 
1831 static PyObject *
forms_isqueued(PyObject * self,PyObject * args)1832 forms_isqueued(PyObject *self, PyObject *args)
1833 {
1834     long retval;
1835     short arg1;
1836     if (!PyArg_Parse(args, "h", &arg1))
1837         return NULL;
1838     retval = fl_isqueued(arg1);
1839 
1840     return PyInt_FromLong(retval);
1841 }
1842 
1843 static PyObject *
forms_qtest(PyObject * self,PyObject * args)1844 forms_qtest(PyObject *self, PyObject *args)
1845 {
1846     long retval;
1847     retval = fl_qtest();
1848     return PyInt_FromLong(retval);
1849 }
1850 
1851 
1852 static PyObject *
forms_qread(PyObject * self,PyObject * args)1853 forms_qread(PyObject *self, PyObject *args)
1854 {
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);
1861 }
1862 
1863 static PyObject *
forms_qreset(PyObject * self)1864 forms_qreset(PyObject *self)
1865 {
1866     fl_qreset();
1867     Py_INCREF(Py_None);
1868     return Py_None;
1869 }
1870 
1871 static PyObject *
forms_qenter(PyObject * self,PyObject * args)1872 forms_qenter(PyObject *self, PyObject *args)
1873 {
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;
1880 }
1881 
1882 static PyObject *
forms_color(PyObject * self,PyObject * args)1883 forms_color(PyObject *self, PyObject *args)
1884 {
1885     int arg;
1886 
1887     if (!PyArg_Parse(args, "i", &arg)) return NULL;
1888 
1889     fl_color((short) arg);
1890 
1891     Py_INCREF(Py_None);
1892     return Py_None;
1893 }
1894 
1895 static PyObject *
forms_mapcolor(PyObject * self,PyObject * args)1896 forms_mapcolor(PyObject *self, PyObject *args)
1897 {
1898     int arg0, arg1, arg2, arg3;
1899 
1900     if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
1901         return NULL;
1902 
1903     fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
1904 
1905     Py_INCREF(Py_None);
1906     return Py_None;
1907 }
1908 
1909 static PyObject *
forms_getmcolor(PyObject * self,PyObject * args)1910 forms_getmcolor(PyObject *self, PyObject *args)
1911 {
1912     int arg;
1913     short r, g, b;
1914 
1915     if (!PyArg_Parse(args, "i", &arg)) return NULL;
1916 
1917     fl_getmcolor(arg, &r, &g, &b);
1918 
1919     return Py_BuildValue("(hhh)", r, g, b);
1920 }
1921 
1922 static PyObject *
forms_get_mouse(PyObject * self)1923 forms_get_mouse(PyObject *self)
1924 {
1925     float x, y;
1926 
1927     fl_get_mouse(&x, &y);
1928 
1929     return Py_BuildValue("(ff)", x, y);
1930 }
1931 
1932 static PyObject *
forms_tie(PyObject * self,PyObject * args)1933 forms_tie(PyObject *self, PyObject *args)
1934 {
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;
1941 }
1942 
1943 static PyObject *
forms_show_message(PyObject * f,PyObject * args)1944 forms_show_message(PyObject *f, PyObject *args)
1945 {
1946     char *a, *b, *c;
1947 
1948     if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
1949 
1950     Py_BEGIN_ALLOW_THREADS
1951     fl_show_message(a, b, c);
1952     Py_END_ALLOW_THREADS
1953 
1954     Py_INCREF(Py_None);
1955     return Py_None;
1956 }
1957 
1958 static PyObject *
forms_show_choice(PyObject * f,PyObject * args)1959 forms_show_choice(PyObject *f, PyObject *args)
1960 {
1961     char *m1, *m2, *m3, *b1, *b2, *b3;
1962     int nb;
1963     char *format;
1964     long rv;
1965 
1966     if (args == NULL || !PyTuple_Check(args)) {
1967         PyErr_BadArgument();
1968         return NULL;
1969     }
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;
1975     }
1976     if (PyInt_Check(PyTuple_GetItem(args, 3))) {
1977         PyErr_SetString(PyExc_TypeError,
1978                    "'number-of-buttons' argument not needed");
1979         return NULL;
1980     }
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;
1988     }
1989 
1990     if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
1991         return NULL;
1992 
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);
1997 }
1998 
1999 static PyObject *
forms_show_question(PyObject * f,PyObject * args)2000 forms_show_question(PyObject *f, PyObject *args)
2001 {
2002     int ret;
2003     char *a, *b, *c;
2004 
2005     if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
2006 
2007     Py_BEGIN_ALLOW_THREADS
2008     ret = fl_show_question(a, b, c);
2009     Py_END_ALLOW_THREADS
2010 
2011     return PyInt_FromLong((long) ret);
2012 }
2013 
2014 static PyObject *
forms_show_input(PyObject * f,PyObject * args)2015 forms_show_input(PyObject *f, PyObject *args)
2016 {
2017     char *str;
2018     char *a, *b;
2019 
2020     if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
2021 
2022     Py_BEGIN_ALLOW_THREADS
2023     str = fl_show_input(a, b);
2024     Py_END_ALLOW_THREADS
2025 
2026     if (str == NULL) {
2027         Py_INCREF(Py_None);
2028         return Py_None;
2029     }
2030     return PyString_FromString(str);
2031 }
2032 
2033 static PyObject *
forms_file_selector(PyObject * f,PyObject * args)2034 forms_file_selector(PyObject *f, PyObject *args)
2035 {
2036     char *str;
2037     char *a, *b, *c, *d;
2038 
2039     if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
2040 
2041     Py_BEGIN_ALLOW_THREADS
2042     str = fl_show_file_selector(a, b, c, d);
2043     Py_END_ALLOW_THREADS
2044 
2045     if (str == NULL) {
2046         Py_INCREF(Py_None);
2047         return Py_None;
2048     }
2049     return PyString_FromString(str);
2050 }
2051 
2052 
2053 static PyObject *
forms_file_selector_func(PyObject * args,char * (* func)(void))2054 forms_file_selector_func(PyObject *args, char *(*func)(void))
2055 {
2056     char *str;
2057 
2058     str = (*func) ();
2059 
2060     if (str == NULL) {
2061         Py_INCREF(Py_None);
2062         return Py_None;
2063     }
2064     return PyString_FromString(str);
2065 }
2066 
2067 static PyObject *
forms_get_directory(PyObject * f,PyObject * args)2068 forms_get_directory(PyObject *f, PyObject *args)
2069 {
2070     return forms_file_selector_func(args, fl_get_directory);
2071 }
2072 
2073 static PyObject *
forms_get_pattern(PyObject * f,PyObject * args)2074 forms_get_pattern(PyObject *f, PyObject *args)
2075 {
2076     return forms_file_selector_func(args, fl_get_pattern);
2077 }
2078 
2079 static PyObject *
forms_get_filename(PyObject * f,PyObject * args)2080 forms_get_filename(PyObject *f, PyObject *args)
2081 {
2082     return forms_file_selector_func(args, fl_get_filename);
2083 }
2084 
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 */
2126 };
2127 
2128 PyMODINIT_FUNC
initfl(void)2129 initfl(void)
2130 {
2131 
2132     if (PyErr_WarnPy3k("the fl module has been removed in "
2133                        "Python 3.0", 2) < 0)
2134     return;
2135 
2136     Py_InitModule("fl", forms_methods);
2137     if (m == NULL)
2138         return;
2139     foreground();
2140     fl_init();
2141 }
2142 
2143 
2144 
2145