home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / flmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  48.5 KB  |  2,135 lines

  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. staticforward 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
  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 *
  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
  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
  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 *
  149. generic_set_call_back(genericobject *g, PyObject *args)
  150. {
  151.     if (args == NULL) {
  152.         Py_XDECREF(g->ob_callback);
  153.         Py_XDECREF(g->ob_callback_arg);
  154.         g->ob_callback = NULL;
  155.         g->ob_callback_arg = NULL;
  156.     }
  157.     else {
  158.         if (!PyTuple_Check(args) || PyTuple_Size(args) != 2) {
  159.             PyErr_BadArgument();
  160.             return NULL;
  161.         }
  162.         Py_XDECREF(g->ob_callback);
  163.         Py_XDECREF(g->ob_callback_arg);
  164.         g->ob_callback = PyTuple_GetItem(args, 0);
  165.         Py_INCREF(g->ob_callback);
  166.         g->ob_callback_arg = PyTuple_GetItem(args, 1);
  167.         Py_INCREF(g->ob_callback_arg);
  168.     }
  169.     Py_INCREF(Py_None);
  170.     return Py_None;
  171. }
  172.  
  173. static PyObject *
  174. generic_call(genericobject *g, PyObject *args, void (*func)(FL_OBJECT *))
  175. {
  176.     if (!PyArg_NoArgs(args))
  177.         return NULL;
  178.     (*func)(g->ob_generic);
  179.     Py_INCREF(Py_None);
  180.     return Py_None;
  181. }
  182.  
  183. static PyObject *
  184. generic_delete_object(genericobject *g, PyObject *args)
  185. {
  186.     PyObject *res;
  187.     res = generic_call(g, args, fl_delete_object);
  188.     if (res != NULL)
  189.         forgetgeneric(g);
  190.     return res;
  191. }
  192.  
  193. static PyObject *
  194. generic_show_object(genericobject *g, PyObject *args)
  195. {
  196.     return generic_call(g, args, fl_show_object);
  197. }
  198.  
  199. static PyObject *
  200. generic_hide_object(genericobject *g, PyObject *args)
  201. {
  202.     return generic_call(g, args, fl_hide_object);
  203. }
  204.  
  205. static PyObject *
  206. generic_redraw_object(genericobject *g, PyObject *args)
  207. {
  208.     return generic_call(g, args, fl_redraw_object);
  209. }
  210.  
  211. #ifdef OBSOLETE_FORMS_CALLS
  212.  
  213.  /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported
  214.     in 2.3.  Since there's no foolproof way to tell which version we're
  215.     using, we omit them unconditionally. */
  216.  
  217. static PyObject *
  218. generic_freeze_object(genericobject *g, PyObject *args)
  219. {
  220.     return generic_call(g, args, fl_freeze_object);
  221. }
  222.  
  223. static PyObject *
  224. generic_unfreeze_object(genericobject *g, PyObject *args)
  225. {
  226.     return generic_call(g, args, fl_unfreeze_object);
  227. }
  228.  
  229. #endif /* OBSOLETE_FORMS_CALLS */
  230.  
  231. static PyObject *
  232. generic_activate_object(genericobject *g, PyObject *args)
  233. {
  234.     return generic_call(g, args, fl_activate_object);
  235. }
  236.  
  237. static PyObject *
  238. generic_deactivate_object(genericobject *g, PyObject *args)
  239. {
  240.     return generic_call(g, args, fl_deactivate_object);
  241. }
  242.  
  243. static PyObject *
  244. generic_set_object_shortcut(genericobject *g, PyObject *args)
  245. {
  246.     char *str;
  247.     if (!PyArg_Parse(args, "s", &str))
  248.         return NULL;
  249.     fl_set_object_shortcut(g->ob_generic, str);
  250.     Py_INCREF(Py_None);
  251.     return Py_None;
  252. }
  253.  
  254. static PyMethodDef generic_methods[] = {
  255.     {"set_call_back",    (PyCFunction)generic_set_call_back},
  256.     {"delete_object",    (PyCFunction)generic_delete_object},
  257.     {"show_object",        (PyCFunction)generic_show_object},
  258.     {"hide_object",        (PyCFunction)generic_hide_object},
  259.     {"redraw_object",    (PyCFunction)generic_redraw_object},
  260. #ifdef OBSOLETE_FORMS_CALLS
  261.     {"freeze_object",    (PyCFunction)generic_freeze_object},
  262.     {"unfreeze_object",    (PyCFunction)generic_unfreeze_object},
  263. #endif
  264.     {"activate_object",    (PyCFunction)generic_activate_object},
  265.     {"deactivate_object",    (PyCFunction)generic_deactivate_object},
  266.     {"set_object_shortcut",    (PyCFunction)generic_set_object_shortcut},
  267.     {NULL,            NULL}        /* sentinel */
  268. };
  269.  
  270. static void
  271. generic_dealloc(genericobject *g)
  272. {
  273.     fl_free_object(g->ob_generic);
  274.     Py_XDECREF(g->ob_callback);
  275.     Py_XDECREF(g->ob_callback_arg);
  276.     PyObject_Del(g);
  277. }
  278.  
  279. #define OFF(x) offsetof(FL_OBJECT, x)
  280.  
  281. static struct memberlist generic_memberlist[] = {
  282.     {"objclass",    T_INT,        OFF(objclass),    RO},
  283.     {"type",    T_INT,        OFF(type),    RO},
  284.     {"boxtype",    T_INT,        OFF(boxtype)},
  285.     {"x",        T_FLOAT,    OFF(x)},
  286.     {"y",        T_FLOAT,    OFF(y)},
  287.     {"w",        T_FLOAT,    OFF(w)},
  288.     {"h",        T_FLOAT,    OFF(h)},
  289.     {"col1",    T_INT,        OFF(col1)},
  290.     {"col2",    T_INT,        OFF(col2)},
  291.     {"align",    T_INT,        OFF(align)},
  292.     {"lcol",    T_INT,        OFF(lcol)},
  293.     {"lsize",    T_FLOAT,    OFF(lsize)},
  294.     /* "label" is treated specially! */
  295.     {"lstyle",    T_INT,        OFF(lstyle)},
  296.     {"pushed",    T_INT,        OFF(pushed),    RO},
  297.     {"focus",    T_INT,        OFF(focus),    RO},
  298.     {"belowmouse",    T_INT,        OFF(belowmouse),RO},
  299. /*    {"frozen",    T_INT,        OFF(frozen),    RO},    */
  300.     {"active",    T_INT,        OFF(active)},
  301.     {"input",    T_INT,        OFF(input)},
  302.     {"visible",    T_INT,        OFF(visible),    RO},
  303.     {"radio",    T_INT,        OFF(radio)},
  304.     {"automatic",    T_INT,        OFF(automatic)},
  305.     {NULL}    /* Sentinel */
  306. };
  307.  
  308. #undef OFF
  309.  
  310. static PyObject *
  311. generic_getattr(genericobject *g, char *name)
  312. {
  313.     PyObject *meth;
  314.  
  315.     /* XXX Ought to special-case name "__methods__" */
  316.     if (g-> ob_methods) {
  317.         meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);
  318.         if (meth != NULL) return meth;
  319.         PyErr_Clear();
  320.     }
  321.  
  322.     meth = Py_FindMethod(generic_methods, (PyObject *)g, name);
  323.     if (meth != NULL)
  324.         return meth;
  325.     PyErr_Clear();
  326.  
  327.     /* "label" is an exception, getmember only works for char pointers,
  328.        not for char arrays */
  329.     if (strcmp(name, "label") == 0)
  330.         return PyString_FromString(g->ob_generic->label);
  331.  
  332.     return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);
  333. }
  334.  
  335. static int
  336. generic_setattr(genericobject *g, char *name, PyObject *v)
  337. {
  338.     int ret;
  339.  
  340.     if (v == NULL) {
  341.         PyErr_SetString(PyExc_TypeError,
  342.                 "can't delete forms object attributes");
  343.         return -1;
  344.     }
  345.  
  346.     /* "label" is an exception: setmember doesn't set strings;
  347.        and FORMS wants you to call a function to set the label */
  348.     if (strcmp(name, "label") == 0) {
  349.         if (!PyString_Check(v)) {
  350.             PyErr_SetString(PyExc_TypeError,
  351.                     "label attr must be string");
  352.             return -1;
  353.         }
  354.         fl_set_object_label(g->ob_generic, PyString_AsString(v));
  355.         return 0;
  356.     }
  357.  
  358.     ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v);
  359.  
  360.     /* Rather than calling all the various set_object_* functions,
  361.        we call fl_redraw_object here.  This is sometimes redundant
  362.        but I doubt that's a big problem */
  363.     if (ret == 0)
  364.         fl_redraw_object(g->ob_generic);
  365.  
  366.     return ret;
  367. }
  368.  
  369. static PyObject *
  370. generic_repr(genericobject *g)
  371. {
  372.     char buf[100];
  373.     sprintf(buf, "<FORMS_object at %p, objclass=%d>",
  374.         g, g->ob_generic->objclass);
  375.     return PyString_FromString(buf);
  376. }
  377.  
  378. static PyTypeObject GenericObjecttype = {
  379.     PyObject_HEAD_INIT(&PyType_Type)
  380.     0,                /*ob_size*/
  381.     "FORMS_object",            /*tp_name*/
  382.     sizeof(genericobject),        /*tp_size*/
  383.     0,                /*tp_itemsize*/
  384.     /* methods */
  385.     (destructor)generic_dealloc,    /*tp_dealloc*/
  386.     0,                /*tp_print*/
  387.     (getattrfunc)generic_getattr,    /*tp_getattr*/
  388.     (setattrfunc)generic_setattr,    /*tp_setattr*/
  389.     0,                /*tp_compare*/
  390.     (reprfunc)generic_repr,        /*tp_repr*/
  391. };
  392.  
  393. static PyObject *
  394. newgenericobject(FL_OBJECT *generic, PyMethodDef *methods)
  395. {
  396.     genericobject *g;
  397.     g = PyObject_New(genericobject, &GenericObjecttype);
  398.     if (g == NULL)
  399.         return NULL;
  400.     g-> ob_generic = generic;
  401.     g->ob_methods = methods;
  402.     g->ob_callback = NULL;
  403.     g->ob_callback_arg = NULL;
  404.     knowgeneric(g);
  405.     return (PyObject *)g;
  406. }
  407.  
  408. /**********************************************************************/
  409. /* Some common calling sequences */
  410.  
  411. /* void func (object, float) */
  412. static PyObject *
  413. call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args)
  414. {
  415.     float parameter;
  416.  
  417.     if (!PyArg_Parse(args, "f", ¶meter)) return NULL;
  418.  
  419.     (*func) (obj, parameter);
  420.  
  421.     Py_INCREF(Py_None);
  422.     return Py_None;
  423. }
  424.  
  425. /* void func (object, float) */
  426. static PyObject *
  427. call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args)
  428. {
  429.     float par1, par2;
  430.  
  431.     if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL;
  432.  
  433.     (*func) (obj, par1, par2);
  434.  
  435.     Py_INCREF(Py_None);
  436.     return Py_None;
  437. }
  438.  
  439. /* void func (object, int) */
  440. static PyObject *
  441. call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
  442. {
  443.     int parameter;
  444.  
  445.     if (!PyArg_Parse(args, "i", ¶meter)) return NULL;
  446.  
  447.     (*func) (obj, parameter);
  448.  
  449.     Py_INCREF(Py_None);
  450.     return Py_None;
  451. }
  452.  
  453. /* void func (object, char) */
  454. static PyObject *
  455. call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args)
  456. {
  457.     char *a;
  458.  
  459.     if (!PyArg_Parse(args, "s", &a)) return NULL;
  460.  
  461.     (*func) (obj, a[0]);
  462.  
  463.     Py_INCREF(Py_None);
  464.     return Py_None;
  465. }
  466.  
  467. /* void func (object, string) */
  468. static PyObject *
  469. call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args)
  470. {
  471.     char *a;
  472.  
  473.     if (!PyArg_Parse(args, "s", &a)) return NULL;
  474.  
  475.     (*func) (obj, a);
  476.  
  477.     Py_INCREF(Py_None);
  478.     return Py_None;
  479. }
  480.  
  481.  
  482. /* void func (object, int, string) */
  483. static PyObject *
  484. call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args)
  485. {
  486.     char *b;
  487.     int a;
  488.     
  489.     if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;
  490.     
  491.     (*func) (obj, a, b);
  492.     
  493.     Py_INCREF(Py_None);
  494.     return Py_None;
  495. }
  496.  
  497. #ifdef UNUSED
  498. /* void func (object, int, int) */
  499. static PyObject *
  500. call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args)
  501. {
  502.     int par1, par2;
  503.     
  504.     if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
  505.     
  506.     (*func) (obj, par1, par2);
  507.     
  508.     Py_INCREF(Py_None);
  509.     return Py_None;
  510. }
  511. #endif
  512.  
  513. /* int func (object) */
  514. static PyObject *
  515. call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj, PyObject *args)
  516. {
  517.     int retval;
  518.     
  519.     if (!PyArg_NoArgs(args)) return NULL;
  520.     
  521.     retval = (*func) (obj);
  522.     
  523.     return PyInt_FromLong ((long) retval);
  524. }
  525.  
  526. /* char * func (object) */
  527. static PyObject *
  528. call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj, PyObject *args)
  529. {
  530.     char *str;
  531.     
  532.     if (!PyArg_NoArgs(args)) return NULL;
  533.     
  534.     str = (*func) (obj);
  535.     
  536.     if (str == NULL) {
  537.         Py_INCREF(Py_None);
  538.         return Py_None;
  539.     }
  540.     return PyString_FromString (str);
  541. }
  542.  
  543. /* int func (object) */
  544. static PyObject *
  545. call_forms_Rf (float (*func)(FL_OBJECT *), FL_OBJECT *obj, PyObject *args)
  546. {
  547.     float retval;
  548.     
  549.     if (!PyArg_NoArgs(args)) return NULL;
  550.     
  551.     retval = (*func) (obj);
  552.     
  553.     return PyFloat_FromDouble (retval);
  554. }
  555.  
  556. static PyObject *
  557. call_forms_OUTfOUTf (void (*func)(FL_OBJECT *, float *, float *), FL_OBJECT *obj, PyObject *args)
  558. {
  559.     float f1, f2;
  560.     
  561.     if (!PyArg_NoArgs(args)) return NULL;
  562.     
  563.     (*func) (obj, &f1, &f2);
  564.  
  565.     return Py_BuildValue("(ff)", f1, f2);
  566. }
  567.  
  568. #ifdef UNUSED
  569. static PyObject *
  570. call_forms_OUTf (void (*func)(FL_OBJECT *, float *), FL_OBJECT *obj, PyObject *args)
  571. {
  572.     float f;
  573.  
  574.     if (!PyArg_NoArgs(args)) return NULL;
  575.  
  576.     (*func) (obj, &f);
  577.  
  578.     return PyFloat_FromDouble (f);
  579. }
  580. #endif
  581.  
  582. /**********************************************************************/
  583. /* Class : browser */
  584.  
  585. static PyObject *
  586. set_browser_topline(genericobject *g, PyObject *args)
  587. {
  588.     return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
  589. }
  590.  
  591. static PyObject *
  592. clear_browser(genericobject *g, PyObject *args)
  593. {
  594.     return generic_call (g, args, fl_clear_browser);
  595. }
  596.  
  597. static PyObject *
  598. add_browser_line (genericobject *g, PyObject *args)
  599. {
  600.     return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
  601. }
  602.  
  603. static PyObject *
  604. addto_browser (genericobject *g, PyObject *args)
  605. {
  606.     return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
  607. }
  608.  
  609. static PyObject *
  610. insert_browser_line (genericobject *g, PyObject *args)
  611. {
  612.     return call_forms_INiINstr (fl_insert_browser_line,
  613.                     g-> ob_generic, args);
  614. }
  615.  
  616. static PyObject *
  617. delete_browser_line (genericobject *g, PyObject *args)
  618. {
  619.     return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
  620. }
  621.  
  622. static PyObject *
  623. replace_browser_line (genericobject *g, PyObject *args)
  624. {
  625.     return call_forms_INiINstr (fl_replace_browser_line,
  626.                     g-> ob_generic, args);
  627. }
  628.  
  629. static PyObject *
  630. get_browser_line(genericobject *g, PyObject *args)
  631. {
  632.     int i;
  633.     char *str;
  634.  
  635.     if (!PyArg_Parse(args, "i", &i))
  636.         return NULL;
  637.  
  638.     str = fl_get_browser_line (g->ob_generic, i);
  639.  
  640.     if (str == NULL) {
  641.         Py_INCREF(Py_None);
  642.         return Py_None;
  643.     }
  644.     return PyString_FromString (str);
  645. }
  646.  
  647. static PyObject *
  648. load_browser (genericobject *g, PyObject *args)
  649. {
  650.     /* XXX strictly speaking this is wrong since fl_load_browser
  651.        XXX returns int, not void */
  652.     return call_forms_INstr (fl_load_browser, g-> ob_generic, args);
  653. }
  654.  
  655. static PyObject *
  656. get_browser_maxline(genericobject *g, PyObject *args)
  657. {
  658.     return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic, args);
  659. }
  660.  
  661. static PyObject *
  662. select_browser_line (genericobject *g, PyObject *args)
  663. {
  664.     return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
  665. }
  666.  
  667. static PyObject *
  668. deselect_browser_line (genericobject *g, PyObject *args)
  669. {
  670.     return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
  671. }
  672.  
  673. static PyObject *
  674. deselect_browser (genericobject *g, PyObject *args)
  675. {
  676.     return generic_call (g, args, fl_deselect_browser);
  677. }
  678.  
  679. static PyObject *
  680. isselected_browser_line (genericobject *g, PyObject *args)
  681. {
  682.     int i, j;
  683.     
  684.     if (!PyArg_Parse(args, "i", &i))
  685.         return NULL;
  686.     
  687.     j = fl_isselected_browser_line (g->ob_generic, i);
  688.     
  689.     return PyInt_FromLong (j);
  690. }
  691.  
  692. static PyObject *
  693. get_browser (genericobject *g, PyObject *args)
  694. {
  695.     return call_forms_Ri (fl_get_browser, g-> ob_generic, args);
  696. }
  697.  
  698. static PyObject *
  699. set_browser_fontsize (genericobject *g, PyObject *args)
  700. {
  701.     return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
  702. }
  703.  
  704. static PyObject *
  705. set_browser_fontstyle (genericobject *g, PyObject *args)
  706. {
  707.     return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
  708. }
  709.  
  710. static PyObject *
  711. set_browser_specialkey (genericobject *g, PyObject *args)
  712. {
  713.     return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
  714. }
  715.  
  716. static PyMethodDef browser_methods[] = {
  717.     {"set_browser_topline",        (PyCFunction)set_browser_topline},
  718.     {"clear_browser",        (PyCFunction)clear_browser},
  719.     {"add_browser_line",        (PyCFunction)add_browser_line},
  720.     {"addto_browser",        (PyCFunction)addto_browser},
  721.     {"insert_browser_line",        (PyCFunction)insert_browser_line},
  722.     {"delete_browser_line",        (PyCFunction)delete_browser_line},
  723.     {"replace_browser_line",    (PyCFunction)replace_browser_line},
  724.     {"get_browser_line",        (PyCFunction)get_browser_line},
  725.     {"load_browser",        (PyCFunction)load_browser},
  726.     {"get_browser_maxline",        (PyCFunction)get_browser_maxline},
  727.     {"select_browser_line",        (PyCFunction)select_browser_line},
  728.     {"deselect_browser_line",    (PyCFunction)deselect_browser_line},
  729.     {"deselect_browser",        (PyCFunction)deselect_browser},
  730.     {"isselected_browser_line",    (PyCFunction)isselected_browser_line},
  731.     {"get_browser",            (PyCFunction)get_browser},
  732.     {"set_browser_fontsize",    (PyCFunction)set_browser_fontsize},
  733.     {"set_browser_fontstyle",    (PyCFunction)set_browser_fontstyle},
  734.     {"set_browser_specialkey",    (PyCFunction)set_browser_specialkey},
  735.     {NULL,                NULL}        /* sentinel */
  736. };
  737.  
  738. /* Class: button */
  739.  
  740. static PyObject *
  741. set_button(genericobject *g, PyObject *args)
  742. {
  743.     return call_forms_INi (fl_set_button, g-> ob_generic, args);
  744. }
  745.  
  746. static PyObject *
  747. get_button(genericobject *g, PyObject *args)
  748. {
  749.     return call_forms_Ri (fl_get_button, g-> ob_generic, args);
  750. }
  751.  
  752. static PyObject *
  753. get_button_numb(genericobject *g, PyObject *args)
  754. {
  755.     return call_forms_Ri (fl_get_button_numb, g-> ob_generic, args);
  756. }
  757.  
  758. static PyObject *
  759. set_button_shortcut(genericobject *g, PyObject *args)
  760. {
  761.     return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
  762. }
  763.  
  764. static PyMethodDef button_methods[] = {
  765.     {"set_button",        (PyCFunction)set_button},
  766.     {"get_button",        (PyCFunction)get_button},
  767.     {"get_button_numb",    (PyCFunction)get_button_numb},
  768.     {"set_button_shortcut",    (PyCFunction)set_button_shortcut},
  769.     {NULL,            NULL}        /* sentinel */
  770. };
  771.  
  772. /* Class: choice */
  773.  
  774. static PyObject *
  775. set_choice(genericobject *g, PyObject *args)
  776. {
  777.     return call_forms_INi (fl_set_choice, g-> ob_generic, args);
  778. }
  779.  
  780. static PyObject *
  781. get_choice(genericobject *g, PyObject *args)
  782. {
  783.     return call_forms_Ri (fl_get_choice, g-> ob_generic, args);
  784. }
  785.  
  786. static PyObject *
  787. clear_choice (genericobject *g, PyObject *args)
  788. {
  789.     return generic_call (g, args, fl_clear_choice);
  790. }
  791.  
  792. static PyObject *
  793. addto_choice (genericobject *g, PyObject *args)
  794. {
  795.     return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
  796. }
  797.  
  798. static PyObject *
  799. replace_choice (genericobject *g, PyObject *args)
  800. {
  801.     return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
  802. }
  803.  
  804. static PyObject *
  805. delete_choice (genericobject *g, PyObject *args)
  806. {
  807.     return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
  808. }
  809.  
  810. static PyObject *
  811. get_choice_text (genericobject *g, PyObject *args)
  812. {
  813.     return call_forms_Rstr (fl_get_choice_text, g-> ob_generic, args);
  814. }
  815.  
  816. static PyObject *
  817. set_choice_fontsize (genericobject *g, PyObject *args)
  818. {
  819.     return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
  820. }
  821.  
  822. static PyObject *
  823. set_choice_fontstyle (genericobject *g, PyObject *args)
  824. {
  825.     return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
  826. }
  827.  
  828. static PyMethodDef choice_methods[] = {
  829.     {"set_choice",        (PyCFunction)set_choice},
  830.     {"get_choice",        (PyCFunction)get_choice},
  831.     {"clear_choice",    (PyCFunction)clear_choice},
  832.     {"addto_choice",    (PyCFunction)addto_choice},
  833.     {"replace_choice",    (PyCFunction)replace_choice},
  834.     {"delete_choice",    (PyCFunction)delete_choice},
  835.     {"get_choice_text",    (PyCFunction)get_choice_text},
  836.     {"set_choice_fontsize", (PyCFunction)set_choice_fontsize},
  837.     {"set_choice_fontstyle",(PyCFunction)set_choice_fontstyle},
  838.     {NULL,            NULL}        /* sentinel */
  839. };
  840.  
  841. /* Class : Clock */
  842.  
  843. static PyObject *
  844. get_clock(genericobject *g, PyObject *args)
  845. {
  846.     int i0, i1, i2;
  847.  
  848.     if (!PyArg_NoArgs(args))
  849.         return NULL;
  850.  
  851.     fl_get_clock (g->ob_generic, &i0, &i1, &i2);
  852.  
  853.     return Py_BuildValue("(iii)", i0, i1, i2);
  854. }
  855.  
  856. static PyMethodDef clock_methods[] = {
  857.     {"get_clock",        (PyCFunction)get_clock},
  858.     {NULL,            NULL}        /* sentinel */
  859. };
  860.  
  861. /* CLass : Counters */
  862.  
  863. static PyObject *
  864. get_counter_value(genericobject *g, PyObject *args)
  865. {
  866.     return call_forms_Rf (fl_get_counter_value, g-> ob_generic, args);
  867. }
  868.  
  869. static PyObject *
  870. set_counter_value (genericobject *g, PyObject *args)
  871. {
  872.     return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
  873. }
  874.  
  875. static PyObject *
  876. set_counter_precision (genericobject *g, PyObject *args)
  877. {
  878.     return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
  879. }
  880.  
  881. static PyObject *
  882. set_counter_bounds (genericobject *g, PyObject *args)
  883. {
  884.     return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
  885. }
  886.  
  887. static PyObject *
  888. set_counter_step (genericobject *g, PyObject *args)
  889. {
  890.     return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
  891. }
  892.  
  893. static PyObject *
  894. set_counter_return (genericobject *g, PyObject *args)
  895. {
  896.     return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
  897. }
  898.  
  899. static PyMethodDef counter_methods[] = {
  900.     {"set_counter_value",        (PyCFunction)set_counter_value},
  901.     {"get_counter_value",        (PyCFunction)get_counter_value},
  902.     {"set_counter_bounds",        (PyCFunction)set_counter_bounds},
  903.     {"set_counter_step",        (PyCFunction)set_counter_step},
  904.     {"set_counter_precision",    (PyCFunction)set_counter_precision},
  905.     {"set_counter_return",        (PyCFunction)set_counter_return},
  906.     {NULL,                NULL}        /* sentinel */
  907. };
  908.  
  909.  
  910. /* Class: Dials */
  911.  
  912. static PyObject *
  913. get_dial_value(genericobject *g, PyObject *args)
  914. {
  915.     return call_forms_Rf (fl_get_dial_value, g-> ob_generic, args);
  916. }
  917.  
  918. static PyObject *
  919. set_dial_value (genericobject *g, PyObject *args)
  920. {
  921.     return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
  922. }
  923.  
  924. static PyObject *
  925. set_dial_bounds (genericobject *g, PyObject *args)
  926. {
  927.     return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
  928. }
  929.  
  930. static PyObject *
  931. get_dial_bounds (genericobject *g, PyObject *args)
  932. {
  933.     return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic, args);
  934. }
  935.  
  936. static PyObject *
  937. set_dial_step (genericobject *g, PyObject *args)
  938. {
  939.     return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
  940. }
  941.  
  942. static PyMethodDef dial_methods[] = {
  943.     {"set_dial_value",    (PyCFunction)set_dial_value},
  944.     {"get_dial_value",    (PyCFunction)get_dial_value},
  945.     {"set_dial_bounds",    (PyCFunction)set_dial_bounds},
  946.     {"get_dial_bounds",    (PyCFunction)get_dial_bounds},
  947.     {"set_dial_step",    (PyCFunction)set_dial_step},
  948.     {NULL,            NULL}        /* sentinel */
  949. };
  950.  
  951. /* Class : Input */
  952.  
  953. static PyObject *
  954. set_input (genericobject *g, PyObject *args)
  955. {
  956.     return call_forms_INstr (fl_set_input, g-> ob_generic, args);
  957. }
  958.  
  959. static PyObject *
  960. get_input (genericobject *g, PyObject *args)
  961. {
  962.     return call_forms_Rstr (fl_get_input, g-> ob_generic, args);
  963. }
  964.  
  965. static PyObject *
  966. set_input_color (genericobject *g, PyObject *args)
  967. {
  968.     return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
  969. }
  970.  
  971. static PyObject *
  972. set_input_return (genericobject *g, PyObject *args)
  973. {
  974.     return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
  975. }
  976.  
  977. static PyMethodDef input_methods[] = {
  978.     {"set_input",        (PyCFunction)set_input},
  979.     {"get_input",        (PyCFunction)get_input},
  980.     {"set_input_color",    (PyCFunction)set_input_color},
  981.     {"set_input_return",    (PyCFunction)set_input_return},
  982.     {NULL,            NULL}        /* sentinel */
  983. };
  984.  
  985.  
  986. /* Class : Menu */
  987.  
  988. static PyObject *
  989. set_menu (genericobject *g, PyObject *args)
  990. {
  991.     return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
  992. }
  993.  
  994. static PyObject *
  995. get_menu (genericobject *g, PyObject *args)
  996. {
  997.     /* XXX strictly speaking this is wrong since fl_get_menu
  998.        XXX returns long, not int */
  999.     return call_forms_Ri (fl_get_menu, g-> ob_generic, args);
  1000. }
  1001.  
  1002. static PyObject *
  1003. get_menu_text (genericobject *g, PyObject *args)
  1004. {
  1005.     return call_forms_Rstr (fl_get_menu_text, g-> ob_generic, args);
  1006. }
  1007.  
  1008. static PyObject *
  1009. addto_menu (genericobject *g, PyObject *args)
  1010. {
  1011.     return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
  1012. }
  1013.  
  1014. static PyMethodDef menu_methods[] = {
  1015.     {"set_menu",        (PyCFunction)set_menu},
  1016.     {"get_menu",        (PyCFunction)get_menu},
  1017.     {"get_menu_text",    (PyCFunction)get_menu_text},
  1018.     {"addto_menu",        (PyCFunction)addto_menu},
  1019.     {NULL,            NULL}        /* sentinel */
  1020. };
  1021.  
  1022.  
  1023. /* Class: Sliders */
  1024.  
  1025. static PyObject *
  1026. get_slider_value(genericobject *g, PyObject *args)
  1027. {
  1028.     return call_forms_Rf (fl_get_slider_value, g-> ob_generic, args);
  1029. }
  1030.  
  1031. static PyObject *
  1032. set_slider_value (genericobject *g, PyObject *args)
  1033. {
  1034.     return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
  1035. }
  1036.  
  1037. static PyObject *
  1038. set_slider_bounds (genericobject *g, PyObject *args)
  1039. {
  1040.     return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
  1041. }
  1042.  
  1043. static PyObject *
  1044. get_slider_bounds (genericobject *g, PyObject *args)
  1045. {
  1046.     return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic, args);
  1047. }
  1048.  
  1049. static PyObject *
  1050. set_slider_return (genericobject *g, PyObject *args)
  1051. {
  1052.     return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
  1053. }
  1054.  
  1055. static PyObject *
  1056. set_slider_size (genericobject *g, PyObject *args)
  1057. {
  1058.     return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
  1059. }
  1060.  
  1061. static PyObject *
  1062. set_slider_precision (genericobject *g, PyObject *args)
  1063. {
  1064.     return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
  1065. }
  1066.  
  1067. static PyObject *
  1068. set_slider_step (genericobject *g, PyObject *args)
  1069. {
  1070.     return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
  1071. }
  1072.  
  1073.  
  1074. static PyMethodDef slider_methods[] = {
  1075.     {"set_slider_value",    (PyCFunction)set_slider_value},
  1076.     {"get_slider_value",    (PyCFunction)get_slider_value},
  1077.     {"set_slider_bounds",    (PyCFunction)set_slider_bounds},
  1078.     {"get_slider_bounds",    (PyCFunction)get_slider_bounds},
  1079.     {"set_slider_return",    (PyCFunction)set_slider_return},
  1080.     {"set_slider_size",    (PyCFunction)set_slider_size},
  1081.     {"set_slider_precision",(PyCFunction)set_slider_precision},
  1082.     {"set_slider_step",    (PyCFunction)set_slider_step},
  1083.     {NULL,            NULL}        /* sentinel */
  1084. };
  1085.  
  1086. static PyObject *
  1087. set_positioner_xvalue (genericobject *g, PyObject *args)
  1088. {
  1089.     return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
  1090. }
  1091.  
  1092. static PyObject *
  1093. set_positioner_xbounds (genericobject *g, PyObject *args)
  1094. {
  1095.     return call_forms_INfINf (fl_set_positioner_xbounds,
  1096.                   g-> ob_generic, args);
  1097. }
  1098.  
  1099. static PyObject *
  1100. set_positioner_yvalue (genericobject *g, PyObject *args)
  1101. {
  1102.     return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
  1103. }
  1104.  
  1105. static PyObject *
  1106. set_positioner_ybounds (genericobject *g, PyObject *args)
  1107. {
  1108.     return call_forms_INfINf (fl_set_positioner_ybounds,
  1109.                   g-> ob_generic, args);
  1110. }
  1111.  
  1112. static PyObject *
  1113. get_positioner_xvalue (genericobject *g, PyObject *args)
  1114. {
  1115.     return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic, args);
  1116. }
  1117.  
  1118. static PyObject *
  1119. get_positioner_xbounds (genericobject *g, PyObject *args)
  1120. {
  1121.     return call_forms_OUTfOUTf (fl_get_positioner_xbounds,
  1122.                     g-> ob_generic, args);
  1123. }
  1124.  
  1125. static PyObject *
  1126. get_positioner_yvalue (genericobject *g, PyObject *args)
  1127. {
  1128.     return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic, args);
  1129. }
  1130.  
  1131. static PyObject *
  1132. get_positioner_ybounds (genericobject *g, PyObject *args)
  1133. {
  1134.     return call_forms_OUTfOUTf (fl_get_positioner_ybounds,
  1135.                     g-> ob_generic, args);
  1136. }
  1137.  
  1138. static PyMethodDef positioner_methods[] = {
  1139.     {"set_positioner_xvalue",    (PyCFunction)set_positioner_xvalue},
  1140.     {"set_positioner_yvalue",    (PyCFunction)set_positioner_yvalue},
  1141.     {"set_positioner_xbounds",    (PyCFunction)set_positioner_xbounds},
  1142.     {"set_positioner_ybounds",    (PyCFunction)set_positioner_ybounds},
  1143.     {"get_positioner_xvalue",    (PyCFunction)get_positioner_xvalue},
  1144.     {"get_positioner_yvalue",    (PyCFunction)get_positioner_yvalue},
  1145.     {"get_positioner_xbounds",    (PyCFunction)get_positioner_xbounds},
  1146.     {"get_positioner_ybounds",    (PyCFunction)get_positioner_ybounds},
  1147.     {NULL,            NULL}        /* sentinel */
  1148. };
  1149.  
  1150. /* Class timer */
  1151.  
  1152. static PyObject *
  1153. set_timer (genericobject *g, PyObject *args)
  1154. {
  1155.     return call_forms_INf (fl_set_timer, g-> ob_generic, args);
  1156. }
  1157.  
  1158. static PyObject *
  1159. get_timer (genericobject *g, PyObject *args)
  1160. {
  1161.     return call_forms_Rf (fl_get_timer, g-> ob_generic, args);
  1162. }
  1163.  
  1164. static PyMethodDef timer_methods[] = {
  1165.     {"set_timer",        (PyCFunction)set_timer},
  1166.     {"get_timer",        (PyCFunction)get_timer},
  1167.     {NULL,            NULL}        /* sentinel */
  1168. };
  1169.  
  1170. /* Form objects */
  1171.  
  1172. typedef struct {
  1173.     PyObject_HEAD
  1174.     FL_FORM *ob_form;
  1175. } formobject;
  1176.  
  1177. staticforward PyTypeObject Formtype;
  1178.  
  1179. #define is_formobject(v) ((v)->ob_type == &Formtype)
  1180.  
  1181. static PyObject *
  1182. form_show_form(formobject *f, PyObject *args)
  1183. {
  1184.     int place, border;
  1185.     char *name;
  1186.     if (!PyArg_Parse(args, "(iis)", &place, &border, &name))
  1187.         return NULL;
  1188.     fl_show_form(f->ob_form, place, border, name);
  1189.     Py_INCREF(Py_None);
  1190.     return Py_None;
  1191. }
  1192.  
  1193. static PyObject *
  1194. form_call(void (*func)(FL_FORM *), FL_FORM *f, PyObject *args)
  1195. {
  1196.     if (!PyArg_NoArgs(args)) return NULL;
  1197.  
  1198.     (*func)(f);
  1199.  
  1200.     Py_INCREF(Py_None);
  1201.     return Py_None;
  1202. }
  1203.  
  1204. static PyObject *
  1205. form_call_INiINi(void (*func)(FL_FORM *, int, int), FL_FORM *f, PyObject *args)
  1206. {
  1207.     int a, b;
  1208.  
  1209.     if (!PyArg_Parse(args, "(ii)", &a, &b)) return NULL;
  1210.  
  1211.     (*func)(f, a, b);
  1212.  
  1213.     Py_INCREF(Py_None);
  1214.     return Py_None;
  1215. }
  1216.  
  1217. static PyObject *
  1218. form_call_INfINf(void (*func)(FL_FORM *, float, float), FL_FORM *f, PyObject *args)
  1219. {
  1220.     float a, b;
  1221.  
  1222.     if (!PyArg_Parse(args, "(ff)", &a, &b)) return NULL;
  1223.  
  1224.     (*func)(f, a, b);
  1225.  
  1226.     Py_INCREF(Py_None);
  1227.     return Py_None;
  1228. }
  1229.  
  1230. static PyObject *
  1231. form_hide_form(formobject *f, PyObject *args)
  1232. {
  1233.     return form_call(fl_hide_form, f-> ob_form, args);
  1234. }
  1235.  
  1236. static PyObject *
  1237. form_redraw_form(formobject *f, PyObject *args)
  1238. {
  1239.     return form_call(fl_redraw_form, f-> ob_form, args);
  1240. }
  1241.  
  1242. static PyObject *
  1243. form_set_form_position(formobject *f, PyObject *args)
  1244. {
  1245.     return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
  1246. }
  1247.  
  1248. static PyObject *
  1249. form_set_form_size(formobject *f, PyObject *args)
  1250. {
  1251.     return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
  1252. }
  1253.  
  1254. static PyObject *
  1255. form_scale_form(formobject *f, PyObject *args)
  1256. {
  1257.     return form_call_INfINf(fl_scale_form, f-> ob_form, args);
  1258. }
  1259.  
  1260. static PyObject *
  1261. generic_add_object(formobject *f, PyObject *args, FL_OBJECT *(*func)(int, float, float, float, float, char*), PyMethodDef *internal_methods)
  1262. {
  1263.     int type;
  1264.     float x, y, w, h;
  1265.     char *name;
  1266.     FL_OBJECT *obj;
  1267.  
  1268.     if (!PyArg_Parse(args,"(iffffs)", &type,&x,&y,&w,&h,&name))
  1269.         return NULL;
  1270.  
  1271.     fl_addto_form (f-> ob_form);
  1272.  
  1273.     obj = (*func) (type, x, y, w, h, name);
  1274.  
  1275.     fl_end_form();
  1276.  
  1277.     if (obj == NULL) {
  1278.         PyErr_NoMemory();
  1279.         return NULL;
  1280.     }
  1281.  
  1282.     return newgenericobject (obj, internal_methods);
  1283. }
  1284.  
  1285. static PyObject *
  1286. form_add_button(formobject *f, PyObject *args)
  1287. {
  1288.     return generic_add_object(f, args, fl_add_button, button_methods);
  1289. }
  1290.  
  1291. static PyObject *
  1292. form_add_lightbutton(formobject *f, PyObject *args)
  1293. {
  1294.     return generic_add_object(f, args, fl_add_lightbutton, button_methods);
  1295. }
  1296.  
  1297. static PyObject *
  1298. form_add_roundbutton(formobject *f, PyObject *args)
  1299. {
  1300.     return generic_add_object(f, args, fl_add_roundbutton, button_methods);
  1301. }
  1302.  
  1303. static PyObject *
  1304. form_add_menu (formobject *f, PyObject *args)
  1305. {
  1306.     return generic_add_object(f, args, fl_add_menu, menu_methods);
  1307. }
  1308.  
  1309. static PyObject *
  1310. form_add_slider(formobject *f, PyObject *args)
  1311. {
  1312.     return generic_add_object(f, args, fl_add_slider, slider_methods);
  1313. }
  1314.  
  1315. static PyObject *
  1316. form_add_valslider(formobject *f, PyObject *args)
  1317. {
  1318.     return generic_add_object(f, args, fl_add_valslider, slider_methods);
  1319. }
  1320.  
  1321. static PyObject *
  1322. form_add_dial(formobject *f, PyObject *args)
  1323. {
  1324.     return generic_add_object(f, args, fl_add_dial, dial_methods);
  1325. }
  1326.  
  1327. static PyObject *
  1328. form_add_counter(formobject *f, PyObject *args)
  1329. {
  1330.     return generic_add_object(f, args, fl_add_counter, counter_methods);
  1331. }
  1332.  
  1333. static PyObject *
  1334. form_add_clock(formobject *f, PyObject *args)
  1335. {
  1336.     return generic_add_object(f, args, fl_add_clock, clock_methods);
  1337. }
  1338.  
  1339. static PyObject *
  1340. form_add_box(formobject *f, PyObject *args)
  1341. {
  1342.     return generic_add_object(f, args, fl_add_box,
  1343.                   (PyMethodDef *)NULL);
  1344. }
  1345.  
  1346. static PyObject *
  1347. form_add_choice(formobject *f, PyObject *args)
  1348. {
  1349.     return generic_add_object(f, args, fl_add_choice, choice_methods);
  1350. }
  1351.  
  1352. static PyObject *
  1353. form_add_browser(formobject *f, PyObject *args)
  1354. {
  1355.     return generic_add_object(f, args, fl_add_browser, browser_methods);
  1356. }
  1357.  
  1358. static PyObject *
  1359. form_add_positioner(formobject *f, PyObject *args)
  1360. {
  1361.     return generic_add_object(f, args, fl_add_positioner,
  1362.                   positioner_methods);
  1363. }
  1364.  
  1365. static PyObject *
  1366. form_add_input(formobject *f, PyObject *args)
  1367. {
  1368.     return generic_add_object(f, args, fl_add_input, input_methods);
  1369. }
  1370.  
  1371. static PyObject *
  1372. form_add_text(formobject *f, PyObject *args)
  1373. {
  1374.     return generic_add_object(f, args, fl_add_text,
  1375.                   (PyMethodDef *)NULL);
  1376. }
  1377.  
  1378. static PyObject *
  1379. form_add_timer(formobject *f, PyObject *args)
  1380. {
  1381.     return generic_add_object(f, args, fl_add_timer, timer_methods);
  1382. }
  1383.  
  1384. static PyObject *
  1385. form_freeze_form(formobject *f, PyObject *args)
  1386. {
  1387.     return form_call(fl_freeze_form, f-> ob_form, args);
  1388. }
  1389.  
  1390. static PyObject *
  1391. form_unfreeze_form(formobject *f, PyObject *args)
  1392. {
  1393.     return form_call(fl_unfreeze_form, f-> ob_form, args);
  1394. }
  1395.  
  1396. static PyObject *
  1397. form_activate_form(formobject *f, PyObject *args)
  1398. {
  1399.     return form_call(fl_activate_form, f-> ob_form, args);
  1400. }
  1401.  
  1402. static PyObject *
  1403. form_deactivate_form(formobject *f, PyObject *args)
  1404. {
  1405.     return form_call(fl_deactivate_form, f-> ob_form, args);
  1406. }
  1407.  
  1408. static PyObject *
  1409. form_bgn_group(formobject *f, PyObject *args)
  1410. {
  1411.     FL_OBJECT *obj;
  1412.  
  1413.     fl_addto_form(f-> ob_form);
  1414.     obj = fl_bgn_group();
  1415.     fl_end_form();
  1416.  
  1417.     if (obj == NULL) {
  1418.         PyErr_NoMemory();
  1419.         return NULL;
  1420.     }
  1421.  
  1422.     return newgenericobject (obj, (PyMethodDef *) NULL);
  1423. }
  1424.  
  1425. static PyObject *
  1426. form_end_group(formobject *f, PyObject *args)
  1427. {
  1428.     fl_addto_form(f-> ob_form);
  1429.     fl_end_group();
  1430.     fl_end_form();
  1431.     Py_INCREF(Py_None);
  1432.     return Py_None;
  1433. }
  1434.  
  1435. static PyObject *
  1436. forms_find_first_or_last(FL_OBJECT *(*func)(FL_FORM *, int, float, float), formobject *f, PyObject *args)
  1437. {
  1438.     int type;
  1439.     float mx, my;
  1440.     FL_OBJECT *generic;
  1441.     genericobject *g;
  1442.     
  1443.     if (!PyArg_Parse(args, "(iff)", &type, &mx, &my)) return NULL;
  1444.  
  1445.     generic = (*func) (f-> ob_form, type, mx, my);
  1446.  
  1447.     if (generic == NULL)
  1448.     {
  1449.         Py_INCREF(Py_None);
  1450.         return Py_None;
  1451.     }
  1452.  
  1453.     g = findgeneric(generic);
  1454.     if (g == NULL) {
  1455.         PyErr_SetString(PyExc_RuntimeError,
  1456.                "forms_find_{first|last} returns unknown object");
  1457.         return NULL;
  1458.     }
  1459.     Py_INCREF(g);
  1460.     return (PyObject *) g;
  1461. }
  1462.  
  1463. static PyObject *
  1464. form_find_first(formobject *f, PyObject *args)
  1465. {
  1466.     return forms_find_first_or_last(fl_find_first, f, args);
  1467. }
  1468.  
  1469. static PyObject *
  1470. form_find_last(formobject *f, PyObject *args)
  1471. {
  1472.     return forms_find_first_or_last(fl_find_last, f, args);
  1473. }
  1474.  
  1475. static PyObject *
  1476. form_set_object_focus(formobject *f, PyObject *args)
  1477. {
  1478.     genericobject *g;
  1479.     if (args == NULL || !is_genericobject(args)) {
  1480.         PyErr_BadArgument();
  1481.         return NULL;
  1482.     }
  1483.     g = (genericobject *)args;
  1484.     fl_set_object_focus(f->ob_form, g->ob_generic);
  1485.     Py_INCREF(Py_None);
  1486.     return Py_None;
  1487. }
  1488.  
  1489. static PyMethodDef form_methods[] = {
  1490. /* adm */
  1491.     {"show_form",        (PyCFunction)form_show_form},
  1492.     {"hide_form",        (PyCFunction)form_hide_form},
  1493.     {"redraw_form",        (PyCFunction)form_redraw_form},
  1494.     {"set_form_position",    (PyCFunction)form_set_form_position},
  1495.     {"set_form_size",    (PyCFunction)form_set_form_size},
  1496.     {"scale_form",        (PyCFunction)form_scale_form},
  1497.     {"freeze_form",        (PyCFunction)form_freeze_form},
  1498.     {"unfreeze_form",    (PyCFunction)form_unfreeze_form},
  1499.     {"activate_form",    (PyCFunction)form_activate_form},
  1500.     {"deactivate_form",    (PyCFunction)form_deactivate_form},
  1501.     {"bgn_group",        (PyCFunction)form_bgn_group},
  1502.     {"end_group",        (PyCFunction)form_end_group},
  1503.     {"find_first",        (PyCFunction)form_find_first},
  1504.     {"find_last",        (PyCFunction)form_find_last},
  1505.     {"set_object_focus",    (PyCFunction)form_set_object_focus},
  1506.  
  1507. /* basic objects */
  1508.     {"add_button",        (PyCFunction)form_add_button},
  1509. /*    {"add_bitmap",        (method)form_add_bitmap}, */
  1510.     {"add_lightbutton",    (PyCFunction)form_add_lightbutton},
  1511.     {"add_roundbutton",    (PyCFunction)form_add_roundbutton},
  1512.     {"add_menu",        (PyCFunction)form_add_menu},
  1513.     {"add_slider",        (PyCFunction)form_add_slider},
  1514.     {"add_positioner",    (PyCFunction)form_add_positioner},
  1515.     {"add_valslider",    (PyCFunction)form_add_valslider},
  1516.     {"add_dial",        (PyCFunction)form_add_dial},
  1517.     {"add_counter",        (PyCFunction)form_add_counter},
  1518.     {"add_box",        (PyCFunction)form_add_box},
  1519.     {"add_clock",        (PyCFunction)form_add_clock},
  1520.     {"add_choice",        (PyCFunction)form_add_choice},
  1521.     {"add_browser",        (PyCFunction)form_add_browser},
  1522.     {"add_input",        (PyCFunction)form_add_input},
  1523.     {"add_timer",        (PyCFunction)form_add_timer},
  1524.     {"add_text",        (PyCFunction)form_add_text},
  1525.     {NULL,            NULL}        /* sentinel */
  1526. };
  1527.  
  1528. static void
  1529. form_dealloc(formobject *f)
  1530. {
  1531.     releaseobjects(f->ob_form);
  1532.     if (f->ob_form->visible)
  1533.         fl_hide_form(f->ob_form);
  1534.     fl_free_form(f->ob_form);
  1535.     PyObject_Del(f);
  1536. }
  1537.  
  1538. #define OFF(x) offsetof(FL_FORM, x)
  1539.  
  1540. static struct memberlist form_memberlist[] = {
  1541.     {"window",    T_LONG,        OFF(window),    RO},
  1542.     {"w",        T_FLOAT,    OFF(w)},
  1543.     {"h",        T_FLOAT,    OFF(h)},
  1544.     {"x",        T_FLOAT,    OFF(x),        RO},
  1545.     {"y",        T_FLOAT,    OFF(y),        RO},
  1546.     {"deactivated",    T_INT,        OFF(deactivated)},
  1547.     {"visible",    T_INT,        OFF(visible),    RO},
  1548.     {"frozen",    T_INT,        OFF(frozen),    RO},
  1549.     {"doublebuf",    T_INT,        OFF(doublebuf)},
  1550.     {NULL}    /* Sentinel */
  1551. };
  1552.  
  1553. #undef OFF
  1554.  
  1555. static PyObject *
  1556. form_getattr(formobject *f, char *name)
  1557. {
  1558.     PyObject *meth;
  1559.  
  1560.     meth = Py_FindMethod(form_methods, (PyObject *)f, name);
  1561.     if (meth != NULL)
  1562.         return meth;
  1563.     PyErr_Clear();
  1564.     return PyMember_Get((char *)f->ob_form, form_memberlist, name);
  1565. }
  1566.  
  1567. static int
  1568. form_setattr(formobject *f, char *name, PyObject *v)
  1569. {
  1570.     if (v == NULL) {
  1571.         PyErr_SetString(PyExc_TypeError,
  1572.                 "can't delete form attributes");
  1573.         return -1;
  1574.     }
  1575.  
  1576.     return PyMember_Set((char *)f->ob_form, form_memberlist, name, v);
  1577. }
  1578.  
  1579. static PyObject *
  1580. form_repr(formobject *f)
  1581. {
  1582.     char buf[100];
  1583.     sprintf(buf, "<FORMS_form at %p, window=%ld>",
  1584.         f, f->ob_form->window);
  1585.     return PyString_FromString(buf);
  1586. }
  1587.  
  1588. static PyTypeObject Formtype = {
  1589.     PyObject_HEAD_INIT(&PyType_Type)
  1590.     0,                /*ob_size*/
  1591.     "FORMS_form",            /*tp_name*/
  1592.     sizeof(formobject),        /*tp_size*/
  1593.     0,                /*tp_itemsize*/
  1594.     /* methods */
  1595.     (destructor)form_dealloc,    /*tp_dealloc*/
  1596.     0,                /*tp_print*/
  1597.     (getattrfunc)form_getattr,    /*tp_getattr*/
  1598.     (setattrfunc)form_setattr,    /*tp_setattr*/
  1599.     0,                /*tp_compare*/
  1600.     (reprfunc)form_repr,        /*tp_repr*/
  1601. };
  1602.  
  1603. static PyObject *
  1604. newformobject(FL_FORM *form)
  1605. {
  1606.     formobject *f;
  1607.     f = PyObject_New(formobject, &Formtype);
  1608.     if (f == NULL)
  1609.         return NULL;
  1610.     f->ob_form = form;
  1611.     return (PyObject *)f;
  1612. }
  1613.  
  1614.  
  1615. /* The "fl" module */
  1616.  
  1617. static PyObject *
  1618. forms_make_form(PyObject *dummy, PyObject *args)
  1619. {
  1620.     int type;
  1621.     float w, h;
  1622.     FL_FORM *form;
  1623.     if (!PyArg_Parse(args, "(iff)", &type, &w, &h))
  1624.         return NULL;
  1625.     form = fl_bgn_form(type, w, h);
  1626.     if (form == NULL) {
  1627.         /* XXX Actually, cannot happen! */
  1628.         PyErr_NoMemory();
  1629.         return NULL;
  1630.     }
  1631.     fl_end_form();
  1632.     return newformobject(form);
  1633. }
  1634.  
  1635. static PyObject *
  1636. forms_activate_all_forms(PyObject *f, PyObject *args)
  1637. {
  1638.     fl_activate_all_forms();
  1639.     Py_INCREF(Py_None);
  1640.     return Py_None;
  1641. }
  1642.  
  1643. static PyObject *
  1644. forms_deactivate_all_forms(PyObject *f, PyObject *args)
  1645. {
  1646.     fl_deactivate_all_forms();
  1647.     Py_INCREF(Py_None);
  1648.     return Py_None;
  1649. }
  1650.  
  1651. static PyObject *my_event_callback = NULL;
  1652.  
  1653. static PyObject *
  1654. forms_set_event_call_back(PyObject *dummy, PyObject *args)
  1655. {
  1656.     if (args == Py_None)
  1657.         args = NULL;
  1658.     my_event_callback = args;
  1659.     Py_XINCREF(args);
  1660.     Py_INCREF(Py_None);
  1661.     return Py_None;
  1662. }
  1663.  
  1664. static PyObject *
  1665. forms_do_or_check_forms(PyObject *dummy, PyObject *args, FL_OBJECT *(*func)(void))
  1666. {
  1667.     FL_OBJECT *generic;
  1668.     genericobject *g;
  1669.     PyObject *arg, *res;
  1670.     
  1671.     if (!PyArg_NoArgs(args))
  1672.         return NULL;
  1673.  
  1674.     for (;;) {
  1675.         Py_BEGIN_ALLOW_THREADS
  1676.         generic = (*func)();
  1677.         Py_END_ALLOW_THREADS
  1678.         if (generic == NULL) {
  1679.             Py_INCREF(Py_None);
  1680.             return Py_None;
  1681.         }
  1682.         if (generic == FL_EVENT) {
  1683.             int dev;
  1684.             short val;
  1685.             if (my_event_callback == NULL)
  1686.                 return PyInt_FromLong(-1L);
  1687.             dev = fl_qread(&val);
  1688.             arg = Py_BuildValue("(ih)", dev, val);
  1689.             if (arg == NULL)
  1690.                 return NULL;
  1691.             res = PyEval_CallObject(my_event_callback, arg);
  1692.             Py_XDECREF(res);
  1693.             Py_DECREF(arg);
  1694.             if (res == NULL)
  1695.                 return NULL; /* Callback raised exception */
  1696.             continue;
  1697.         }
  1698.         g = findgeneric(generic);
  1699.         if (g == NULL) {
  1700.             /* Object not known to us (some dialogs cause this) */
  1701.             continue; /* Ignore it */
  1702.         }
  1703.         if (g->ob_callback == NULL) {
  1704.             Py_INCREF(g);
  1705.             return ((PyObject *) g);
  1706.         }
  1707.         arg = Py_BuildValue("(OO)", (PyObject *)g, g->ob_callback_arg);
  1708.         if (arg == NULL)
  1709.             return NULL;
  1710.         res = PyEval_CallObject(g->ob_callback, arg);
  1711.         Py_XDECREF(res);
  1712.         Py_DECREF(arg);
  1713.         if (res == NULL)
  1714.             return NULL; /* Callback raised exception */
  1715.     }
  1716. }
  1717.  
  1718. static PyObject *
  1719. forms_do_forms(PyObject *dummy, PyObject *args)
  1720. {
  1721.     return forms_do_or_check_forms(dummy, args, fl_do_forms);
  1722. }
  1723.  
  1724. static PyObject *
  1725. forms_check_forms(PyObject *dummy, PyObject *args)
  1726. {
  1727.     return forms_do_or_check_forms(dummy, args, fl_check_forms);
  1728. }
  1729.  
  1730. static PyObject *
  1731. forms_do_only_forms(PyObject *dummy, PyObject *args)
  1732. {
  1733.     return forms_do_or_check_forms(dummy, args, fl_do_only_forms);
  1734. }
  1735.  
  1736. static PyObject *
  1737. forms_check_only_forms(PyObject *dummy, PyObject *args)
  1738. {
  1739.     return forms_do_or_check_forms(dummy, args, fl_check_only_forms);
  1740. }
  1741.  
  1742. #ifdef UNUSED
  1743. static PyObject *
  1744. fl_call(void (*func)(void), PyObject *args)
  1745. {
  1746.     if (!PyArg_NoArgs(args))
  1747.         return NULL;
  1748.     (*func)();
  1749.     Py_INCREF(Py_None);
  1750.     return Py_None;
  1751. }
  1752. #endif
  1753.  
  1754. static PyObject *
  1755. forms_set_graphics_mode(PyObject *dummy, PyObject *args)
  1756. {
  1757.     int rgbmode, doublebuf;
  1758.  
  1759.     if (!PyArg_Parse(args, "(ii)", &rgbmode, &doublebuf))
  1760.         return NULL;
  1761.     fl_set_graphics_mode(rgbmode,doublebuf);
  1762.     Py_INCREF(Py_None);
  1763.     return Py_None;
  1764. }
  1765.  
  1766. static PyObject *
  1767. forms_get_rgbmode(PyObject *dummy, PyObject *args)
  1768. {
  1769.     extern int fl_rgbmode;
  1770.  
  1771.     if (args != NULL) {
  1772.         PyErr_BadArgument();
  1773.         return NULL;
  1774.     }
  1775.     return PyInt_FromLong((long)fl_rgbmode);
  1776. }
  1777.  
  1778. static PyObject *
  1779. forms_show_errors(PyObject *dummy, PyObject *args)
  1780. {
  1781.     int show;
  1782.     if (!PyArg_Parse(args, "i", &show))
  1783.         return NULL;
  1784.     fl_show_errors(show);
  1785.     Py_INCREF(Py_None);
  1786.     return Py_None;
  1787. }
  1788.  
  1789. static PyObject *
  1790. forms_set_font_name(PyObject *dummy, PyObject *args)
  1791. {
  1792.     int numb;
  1793.     char *name;
  1794.     if (!PyArg_Parse(args, "(is)", &numb, &name))
  1795.         return NULL;
  1796.     fl_set_font_name(numb, name);
  1797.     Py_INCREF(Py_None);
  1798.     return Py_None;
  1799. }
  1800.  
  1801.  
  1802. static PyObject *
  1803. forms_qdevice(PyObject *self, PyObject *args)
  1804. {
  1805.     short arg1;
  1806.     if (!PyArg_Parse(args, "h", &arg1))
  1807.         return NULL;
  1808.     fl_qdevice(arg1);
  1809.     Py_INCREF(Py_None);
  1810.     return Py_None;
  1811. }
  1812.  
  1813. static PyObject *
  1814. forms_unqdevice(PyObject *self, PyObject *args)
  1815. {
  1816.     short arg1;
  1817.     if (!PyArg_Parse(args, "h", &arg1))
  1818.         return NULL;
  1819.     fl_unqdevice(arg1);
  1820.     Py_INCREF(Py_None);
  1821.     return Py_None;
  1822. }
  1823.  
  1824. static PyObject *
  1825. forms_isqueued(PyObject *self, PyObject *args)
  1826. {
  1827.     long retval;
  1828.     short arg1;
  1829.     if (!PyArg_Parse(args, "h", &arg1))
  1830.         return NULL;
  1831.     retval = fl_isqueued(arg1);
  1832.  
  1833.     return PyInt_FromLong(retval);
  1834. }
  1835.  
  1836. static PyObject *
  1837. forms_qtest(PyObject *self, PyObject *args)
  1838. {
  1839.     long retval;
  1840.     retval = fl_qtest();
  1841.     return PyInt_FromLong(retval);
  1842. }
  1843.  
  1844.  
  1845. static PyObject *
  1846. forms_qread(PyObject *self, PyObject *args)
  1847. {
  1848.     int dev;
  1849.     short val;
  1850.     Py_BEGIN_ALLOW_THREADS
  1851.     dev = fl_qread(&val);
  1852.     Py_END_ALLOW_THREADS
  1853.     return Py_BuildValue("(ih)", dev, val);
  1854. }
  1855.  
  1856. static PyObject *
  1857. forms_qreset(PyObject *self, PyObject *args)
  1858. {
  1859.     if (!PyArg_NoArgs(args)) return NULL;
  1860.  
  1861.     fl_qreset();
  1862.     Py_INCREF(Py_None);
  1863.     return Py_None;
  1864. }
  1865.  
  1866. static PyObject *
  1867. forms_qenter(PyObject *self, PyObject *args)
  1868. {
  1869.     short arg1, arg2;
  1870.     if (!PyArg_Parse(args, "(hh)", &arg1, &arg2))
  1871.         return NULL;
  1872.     fl_qenter(arg1, arg2);
  1873.     Py_INCREF(Py_None);
  1874.     return Py_None;
  1875. }
  1876.  
  1877. static PyObject *
  1878. forms_color(PyObject *self, PyObject *args)
  1879. {
  1880.     int arg;
  1881.  
  1882.     if (!PyArg_Parse(args, "i", &arg)) return NULL;
  1883.  
  1884.     fl_color((short) arg);
  1885.  
  1886.     Py_INCREF(Py_None);
  1887.     return Py_None;
  1888. }
  1889.  
  1890. static PyObject *
  1891. forms_mapcolor(PyObject *self, PyObject *args)
  1892. {
  1893.     int arg0, arg1, arg2, arg3;
  1894.  
  1895.     if (!PyArg_Parse(args, "(iiii)", &arg0, &arg1, &arg2, &arg3))
  1896.         return NULL;
  1897.  
  1898.     fl_mapcolor(arg0, (short) arg1, (short) arg2, (short) arg3);
  1899.  
  1900.     Py_INCREF(Py_None);
  1901.     return Py_None;
  1902. }
  1903.  
  1904. static PyObject *
  1905. forms_getmcolor(PyObject *self, PyObject *args)
  1906. {
  1907.     int arg;
  1908.     short r, g, b;
  1909.  
  1910.     if (!PyArg_Parse(args, "i", &arg)) return NULL;
  1911.  
  1912.     fl_getmcolor(arg, &r, &g, &b);
  1913.  
  1914.     return Py_BuildValue("(hhh)", r, g, b);
  1915. }
  1916.  
  1917. static PyObject *
  1918. forms_get_mouse(PyObject *self, PyObject *args)
  1919. {
  1920.     float x, y;
  1921.  
  1922.     if (!PyArg_NoArgs(args)) return NULL;
  1923.     
  1924.     fl_get_mouse(&x, &y);
  1925.  
  1926.     return Py_BuildValue("(ff)", x, y);
  1927. }
  1928.  
  1929. static PyObject *
  1930. forms_tie(PyObject *self, PyObject *args)
  1931. {
  1932.     short arg1, arg2, arg3;
  1933.     if (!PyArg_Parse(args, "(hhh)", &arg1, &arg2, &arg3))
  1934.         return NULL;
  1935.     fl_tie(arg1, arg2, arg3);
  1936.     Py_INCREF(Py_None);
  1937.     return Py_None;
  1938. }
  1939.  
  1940. static PyObject *
  1941. forms_show_message(PyObject *f, PyObject *args)
  1942. {
  1943.     char *a, *b, *c;
  1944.  
  1945.     if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
  1946.  
  1947.     Py_BEGIN_ALLOW_THREADS
  1948.     fl_show_message(a, b, c);
  1949.     Py_END_ALLOW_THREADS
  1950.  
  1951.     Py_INCREF(Py_None);
  1952.     return Py_None;
  1953. }
  1954.  
  1955. static PyObject *
  1956. forms_show_choice(PyObject *f, PyObject *args)
  1957. {
  1958.     char *m1, *m2, *m3, *b1, *b2, *b3;
  1959.     int nb;
  1960.     char *format;
  1961.     long rv;
  1962.  
  1963.     if (args == NULL || !PyTuple_Check(args)) {
  1964.         PyErr_BadArgument();
  1965.         return NULL;
  1966.     }
  1967.     nb = PyTuple_Size(args) - 3;
  1968.     if (nb <= 0) {
  1969.         PyErr_SetString(PyExc_TypeError,
  1970.                 "need at least one button label");
  1971.         return NULL;
  1972.     }
  1973.     if (PyInt_Check(PyTuple_GetItem(args, 3))) {
  1974.         PyErr_SetString(PyExc_TypeError,
  1975.                "'number-of-buttons' argument not needed");
  1976.         return NULL;
  1977.     }
  1978.     switch (nb) {
  1979.     case 1: format = "(ssss)"; break;
  1980.     case 2: format = "(sssss)"; break;
  1981.     case 3: format = "(ssssss)"; break;
  1982.     default:
  1983.         PyErr_SetString(PyExc_TypeError, "too many button labels");
  1984.         return NULL;
  1985.     }
  1986.  
  1987.     if (!PyArg_Parse(args, format, &m1, &m2, &m3, &b1, &b2, &b3))
  1988.         return NULL;
  1989.  
  1990.     Py_BEGIN_ALLOW_THREADS
  1991.     rv = fl_show_choice(m1, m2, m3, nb, b1, b2, b3);
  1992.     Py_END_ALLOW_THREADS
  1993.     return PyInt_FromLong(rv);
  1994. }
  1995.  
  1996. static PyObject *
  1997. forms_show_question(PyObject *f, PyObject *args)
  1998. {
  1999.     int ret;
  2000.     char *a, *b, *c;
  2001.  
  2002.     if (!PyArg_Parse(args, "(sss)", &a, &b, &c)) return NULL;
  2003.  
  2004.     Py_BEGIN_ALLOW_THREADS
  2005.     ret = fl_show_question(a, b, c);
  2006.     Py_END_ALLOW_THREADS
  2007.  
  2008.     return PyInt_FromLong((long) ret);
  2009. }
  2010.  
  2011. static PyObject *
  2012. forms_show_input(PyObject *f, PyObject *args)
  2013. {
  2014.     char *str;
  2015.     char *a, *b;
  2016.  
  2017.     if (!PyArg_Parse(args, "(ss)", &a, &b)) return NULL;
  2018.  
  2019.     Py_BEGIN_ALLOW_THREADS
  2020.     str = fl_show_input(a, b);
  2021.     Py_END_ALLOW_THREADS
  2022.  
  2023.     if (str == NULL) {
  2024.         Py_INCREF(Py_None);
  2025.         return Py_None;
  2026.     }
  2027.     return PyString_FromString(str);
  2028. }
  2029.  
  2030. static PyObject *
  2031. forms_file_selector(PyObject *f, PyObject *args)
  2032. {
  2033.     char *str;
  2034.     char *a, *b, *c, *d;
  2035.  
  2036.     if (!PyArg_Parse(args, "(ssss)", &a, &b, &c, &d)) return NULL;
  2037.  
  2038.     Py_BEGIN_ALLOW_THREADS
  2039.     str = fl_show_file_selector(a, b, c, d);
  2040.     Py_END_ALLOW_THREADS
  2041.  
  2042.     if (str == NULL) {
  2043.         Py_INCREF(Py_None);
  2044.         return Py_None;
  2045.     }
  2046.     return PyString_FromString(str);
  2047. }
  2048.  
  2049.  
  2050. static PyObject *
  2051. forms_file_selector_func(PyObject *args, char *(*func)(void))
  2052. {
  2053.     char *str;
  2054.  
  2055.     str = (*func) ();
  2056.  
  2057.     if (str == NULL) {
  2058.         Py_INCREF(Py_None);
  2059.         return Py_None;
  2060.     }
  2061.     return PyString_FromString(str);
  2062. }
  2063.  
  2064. static PyObject *
  2065. forms_get_directory(PyObject *f, PyObject *args)
  2066. {
  2067.     return forms_file_selector_func(args, fl_get_directory);
  2068. }
  2069.  
  2070. static PyObject *
  2071. forms_get_pattern(PyObject *f, PyObject *args)
  2072. {
  2073.     return forms_file_selector_func(args, fl_get_pattern);
  2074. }
  2075.  
  2076. static PyObject *
  2077. forms_get_filename(PyObject *f, PyObject *args)
  2078. {
  2079.     return forms_file_selector_func(args, fl_get_filename);
  2080. }
  2081.  
  2082. static PyMethodDef forms_methods[] = {
  2083. /* adm */
  2084.     {"make_form",        forms_make_form},
  2085.     {"activate_all_forms",    forms_activate_all_forms},
  2086.     {"deactivate_all_forms",forms_deactivate_all_forms},
  2087. /* gl support wrappers */
  2088.     {"qdevice",        forms_qdevice},
  2089.     {"unqdevice",        forms_unqdevice},
  2090.     {"isqueued",        forms_isqueued},
  2091.     {"qtest",        forms_qtest},
  2092.     {"qread",        forms_qread},
  2093. /*    {"blkqread",        forms_blkqread}, */
  2094.     {"qreset",        forms_qreset},
  2095.     {"qenter",        forms_qenter},
  2096.     {"get_mouse",        forms_get_mouse},
  2097.     {"tie",            forms_tie},
  2098. /*    {"new_events",        forms_new_events}, */
  2099.     {"color",        forms_color},
  2100.     {"mapcolor",        forms_mapcolor},
  2101.     {"getmcolor",        forms_getmcolor},
  2102. /* interaction */
  2103.     {"do_forms",        forms_do_forms},
  2104.     {"do_only_forms",    forms_do_only_forms},
  2105.     {"check_forms",        forms_check_forms},
  2106.     {"check_only_forms",    forms_check_only_forms},
  2107.     {"set_event_call_back",    forms_set_event_call_back},
  2108. /* goodies */
  2109.     {"show_message",    forms_show_message},
  2110.     {"show_question",    forms_show_question},
  2111.     {"show_choice",        forms_show_choice},
  2112.     {"show_input",        forms_show_input},
  2113.     {"show_file_selector",    forms_file_selector},
  2114.     {"file_selector",    forms_file_selector}, /* BW compat */
  2115.     {"get_directory",    forms_get_directory},
  2116.     {"get_pattern",        forms_get_pattern},
  2117.     {"get_filename",    forms_get_filename},
  2118.     {"set_graphics_mode",    forms_set_graphics_mode},
  2119.     {"get_rgbmode",        forms_get_rgbmode},
  2120.     {"show_errors",        forms_show_errors},
  2121.     {"set_font_name",    forms_set_font_name},
  2122.     {NULL,            NULL}        /* sentinel */
  2123. };
  2124.  
  2125. DL_EXPORT(void)
  2126. initfl(void)
  2127. {
  2128.     Py_InitModule("fl", forms_methods);
  2129.     foreground();
  2130.     fl_init();
  2131. }
  2132.  
  2133.  
  2134.  
  2135.