PageRenderTime 284ms CodeModel.GetById 31ms app.highlight 196ms RepoModel.GetById 35ms app.codeStats 2ms

/Modules/flmodule.c

http://unladen-swallow.googlecode.com/
C | 2144 lines | 1704 code | 355 blank | 85 comment | 145 complexity | 63b14a910e2d994c812c11e9293f0ee7 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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
  24typedef 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
  32static 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
  38static PyObject *allgenerics = NULL;
  39static int nfreeslots = 0;
  40
  41/* Add an object to the list of known objects */
  42
  43static void
  44knowgeneric(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
  76static genericobject *
  77findgeneric(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
  95static void
  96forgetgeneric(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
 119static void
 120releaseobjects(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
 148static PyObject *
 149generic_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
 172static PyObject *
 173generic_call(genericobject *g, void (*func)(FL_OBJECT *))
 174{
 175	(*func)(g->ob_generic);
 176	Py_INCREF(Py_None);
 177	return Py_None;
 178}
 179
 180static PyObject *
 181generic_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
 190static PyObject *
 191generic_show_object(genericobject *g)
 192{
 193	return generic_call(g, fl_show_object);
 194}
 195
 196static PyObject *
 197generic_hide_object(genericobject *g)
 198{
 199	return generic_call(g, fl_hide_object);
 200}
 201
 202static PyObject *
 203generic_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 
 214static PyObject *
 215generic_freeze_object(genericobject *g)
 216{
 217	return generic_call(g, fl_freeze_object);
 218}
 219
 220static PyObject *
 221generic_unfreeze_object(genericobject *g)
 222{
 223	return generic_call(g, fl_unfreeze_object);
 224}
 225
 226#endif /* OBSOLETE_FORMS_CALLS */
 227
 228static PyObject *
 229generic_activate_object(genericobject *g)
 230{
 231	return generic_call(g, fl_activate_object);
 232}
 233
 234static PyObject *
 235generic_deactivate_object(genericobject *g)
 236{
 237	return generic_call(g, fl_deactivate_object);
 238}
 239
 240static PyObject *
 241generic_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
 251static 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
 267static void
 268generic_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
 278static 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
 307static PyObject *
 308generic_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
 332static int
 333generic_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
 366static PyObject *
 367generic_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
 375static 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
 390static PyObject *
 391newgenericobject(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) */
 409static PyObject *
 410call_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) */
 423static PyObject *
 424call_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) */
 437static PyObject *
 438call_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) */
 451static PyObject *
 452call_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) */
 465static PyObject *
 466call_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) */
 480static PyObject *
 481call_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) */
 496static PyObject *
 497call_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) */
 511static PyObject *
 512call_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) */
 522static PyObject *
 523call_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) */
 537static PyObject *
 538call_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
 547static PyObject *
 548call_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
 558static PyObject *
 559call_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
 572static PyObject *
 573set_browser_topline(genericobject *g, PyObject *args)
 574{
 575	return call_forms_INi (fl_set_browser_topline, g-> ob_generic, args);
 576}
 577
 578static PyObject *
 579clear_browser(genericobject *g)
 580{
 581	return generic_call (g, fl_clear_browser);
 582}
 583
 584static PyObject *
 585add_browser_line (genericobject *g, PyObject *args)
 586{
 587	return call_forms_INstr (fl_add_browser_line, g-> ob_generic, args);
 588}
 589
 590static PyObject *
 591addto_browser (genericobject *g, PyObject *args)
 592{
 593	return call_forms_INstr (fl_addto_browser, g-> ob_generic, args);
 594}
 595
 596static PyObject *
 597insert_browser_line (genericobject *g, PyObject *args)
 598{
 599	return call_forms_INiINstr (fl_insert_browser_line,
 600				    g-> ob_generic, args);
 601}
 602
 603static PyObject *
 604delete_browser_line (genericobject *g, PyObject *args)
 605{
 606	return call_forms_INi (fl_delete_browser_line, g-> ob_generic, args);
 607}
 608
 609static PyObject *
 610replace_browser_line (genericobject *g, PyObject *args)
 611{
 612	return call_forms_INiINstr (fl_replace_browser_line,
 613				    g-> ob_generic, args);
 614}
 615
 616static PyObject *
 617get_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
 634static PyObject *
 635load_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
 642static PyObject *
 643get_browser_maxline(genericobject *g)
 644{
 645	return call_forms_Ri (fl_get_browser_maxline, g-> ob_generic);
 646}
 647
 648static PyObject *
 649select_browser_line (genericobject *g, PyObject *args)
 650{
 651	return call_forms_INi (fl_select_browser_line, g-> ob_generic, args);
 652}
 653
 654static PyObject *
 655deselect_browser_line (genericobject *g, PyObject *args)
 656{
 657	return call_forms_INi (fl_deselect_browser_line, g-> ob_generic, args);
 658}
 659
 660static PyObject *
 661deselect_browser (genericobject *g)
 662{
 663	return generic_call (g, fl_deselect_browser);
 664}
 665
 666static PyObject *
 667isselected_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
 679static PyObject *
 680get_browser (genericobject *g)
 681{
 682	return call_forms_Ri (fl_get_browser, g-> ob_generic);
 683}
 684
 685static PyObject *
 686set_browser_fontsize (genericobject *g, PyObject *args)
 687{
 688	return call_forms_INf (fl_set_browser_fontsize, g-> ob_generic, args);
 689}
 690
 691static PyObject *
 692set_browser_fontstyle (genericobject *g, PyObject *args)
 693{
 694	return call_forms_INi (fl_set_browser_fontstyle, g-> ob_generic, args);
 695}
 696
 697static PyObject *
 698set_browser_specialkey (genericobject *g, PyObject *args)
 699{
 700	return call_forms_INc(fl_set_browser_specialkey, g-> ob_generic, args);
 701}
 702
 703static 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
 745static PyObject *
 746set_button(genericobject *g, PyObject *args)
 747{
 748	return call_forms_INi (fl_set_button, g-> ob_generic, args);
 749}
 750
 751static PyObject *
 752get_button(genericobject *g)
 753{
 754	return call_forms_Ri (fl_get_button, g-> ob_generic);
 755}
 756
 757static PyObject *
 758get_button_numb(genericobject *g)
 759{
 760	return call_forms_Ri (fl_get_button_numb, g-> ob_generic);
 761}
 762
 763static PyObject *
 764set_button_shortcut(genericobject *g, PyObject *args)
 765{
 766	return call_forms_INstr (fl_set_button_shortcut, g-> ob_generic, args);
 767}
 768
 769static 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
 779static PyObject *
 780set_choice(genericobject *g, PyObject *args)
 781{
 782	return call_forms_INi (fl_set_choice, g-> ob_generic, args);
 783}
 784
 785static PyObject *
 786get_choice(genericobject *g)
 787{
 788	return call_forms_Ri (fl_get_choice, g-> ob_generic);
 789}
 790
 791static PyObject *
 792clear_choice (genericobject *g)
 793{
 794	return generic_call (g, fl_clear_choice);
 795}
 796
 797static PyObject *
 798addto_choice (genericobject *g, PyObject *args)
 799{
 800	return call_forms_INstr (fl_addto_choice, g-> ob_generic, args);
 801}
 802
 803static PyObject *
 804replace_choice (genericobject *g, PyObject *args)
 805{
 806	return call_forms_INiINstr (fl_replace_choice, g-> ob_generic, args);
 807}
 808
 809static PyObject *
 810delete_choice (genericobject *g, PyObject *args)
 811{
 812	return call_forms_INi (fl_delete_choice, g-> ob_generic, args);
 813}
 814
 815static PyObject *
 816get_choice_text (genericobject *g)
 817{
 818	return call_forms_Rstr (fl_get_choice_text, g-> ob_generic);
 819}
 820
 821static PyObject *
 822set_choice_fontsize (genericobject *g, PyObject *args)
 823{
 824	return call_forms_INf (fl_set_choice_fontsize, g-> ob_generic, args);
 825}
 826
 827static PyObject *
 828set_choice_fontstyle (genericobject *g, PyObject *args)
 829{
 830	return call_forms_INi (fl_set_choice_fontstyle, g-> ob_generic, args);
 831}
 832
 833static 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
 848static PyObject *
 849get_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
 858static PyMethodDef clock_methods[] = {
 859	{"get_clock",		(PyCFunction)get_clock, METH_NOARGS},
 860	{NULL,			NULL}		/* sentinel */
 861};
 862
 863/* CLass : Counters */
 864
 865static PyObject *
 866get_counter_value(genericobject *g)
 867{
 868	return call_forms_Rf (fl_get_counter_value, g-> ob_generic);
 869}
 870
 871static PyObject *
 872set_counter_value (genericobject *g, PyObject *args)
 873{
 874	return call_forms_INf (fl_set_counter_value, g-> ob_generic, args);
 875}
 876
 877static PyObject *
 878set_counter_precision (genericobject *g, PyObject *args)
 879{
 880	return call_forms_INi (fl_set_counter_precision, g-> ob_generic, args);
 881}
 882
 883static PyObject *
 884set_counter_bounds (genericobject *g, PyObject *args)
 885{
 886	return call_forms_INfINf (fl_set_counter_bounds, g-> ob_generic, args);
 887}
 888
 889static PyObject *
 890set_counter_step (genericobject *g, PyObject *args)
 891{
 892	return call_forms_INfINf (fl_set_counter_step, g-> ob_generic, args);
 893}
 894
 895static PyObject *
 896set_counter_return (genericobject *g, PyObject *args)
 897{
 898	return call_forms_INi (fl_set_counter_return, g-> ob_generic, args);
 899}
 900
 901static 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
 920static PyObject *
 921get_dial_value(genericobject *g)
 922{
 923	return call_forms_Rf (fl_get_dial_value, g-> ob_generic);
 924}
 925
 926static PyObject *
 927set_dial_value (genericobject *g, PyObject *args)
 928{
 929	return call_forms_INf (fl_set_dial_value, g-> ob_generic, args);
 930}
 931
 932static PyObject *
 933set_dial_bounds (genericobject *g, PyObject *args)
 934{
 935	return call_forms_INfINf (fl_set_dial_bounds, g-> ob_generic, args);
 936}
 937
 938static PyObject *
 939get_dial_bounds (genericobject *g)
 940{
 941	return call_forms_OUTfOUTf (fl_get_dial_bounds, g-> ob_generic);
 942}
 943
 944static PyObject *
 945set_dial_step (genericobject *g, PyObject *args)
 946{
 947	return call_forms_INf (fl_set_dial_step, g-> ob_generic, args);
 948}
 949
 950static 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
 961static PyObject *
 962set_input (genericobject *g, PyObject *args)
 963{
 964	return call_forms_INstr (fl_set_input, g-> ob_generic, args);
 965}
 966
 967static PyObject *
 968get_input (genericobject *g)
 969{
 970	return call_forms_Rstr (fl_get_input, g-> ob_generic);
 971}
 972
 973static PyObject *
 974set_input_color (genericobject *g, PyObject *args)
 975{
 976	return call_forms_INfINf (fl_set_input_color, g-> ob_generic, args);
 977}
 978
 979static PyObject *
 980set_input_return (genericobject *g, PyObject *args)
 981{
 982	return call_forms_INi (fl_set_input_return, g-> ob_generic, args);
 983}
 984
 985static 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
 996static PyObject *
 997set_menu (genericobject *g, PyObject *args)
 998{
 999	return call_forms_INstr (fl_set_menu, g-> ob_generic, args);
1000}
1001
1002static PyObject *
1003get_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
1010static PyObject *
1011get_menu_text (genericobject *g)
1012{
1013	return call_forms_Rstr (fl_get_menu_text, g-> ob_generic);
1014}
1015
1016static PyObject *
1017addto_menu (genericobject *g, PyObject *args)
1018{
1019	return call_forms_INstr (fl_addto_menu, g-> ob_generic, args);
1020}
1021
1022static 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
1033static PyObject *
1034get_slider_value(genericobject *g)
1035{
1036	return call_forms_Rf (fl_get_slider_value, g-> ob_generic);
1037}
1038
1039static PyObject *
1040set_slider_value (genericobject *g, PyObject *args)
1041{
1042	return call_forms_INf (fl_set_slider_value, g-> ob_generic, args);
1043}
1044
1045static PyObject *
1046set_slider_bounds (genericobject *g, PyObject *args)
1047{
1048	return call_forms_INfINf (fl_set_slider_bounds, g-> ob_generic, args);
1049}
1050
1051static PyObject *
1052get_slider_bounds (genericobject *g)
1053{
1054	return call_forms_OUTfOUTf(fl_get_slider_bounds, g-> ob_generic);
1055}
1056
1057static PyObject *
1058set_slider_return (genericobject *g, PyObject *args)
1059{
1060	return call_forms_INf (fl_set_slider_return, g-> ob_generic, args);
1061}
1062
1063static PyObject *
1064set_slider_size (genericobject *g, PyObject *args)
1065{
1066	return call_forms_INf (fl_set_slider_size, g-> ob_generic, args);
1067}
1068
1069static PyObject *
1070set_slider_precision (genericobject *g, PyObject *args)
1071{
1072	return call_forms_INi (fl_set_slider_precision, g-> ob_generic, args);
1073}
1074
1075static PyObject *
1076set_slider_step (genericobject *g, PyObject *args)
1077{
1078	return call_forms_INf (fl_set_slider_step, g-> ob_generic, args);
1079}
1080
1081
1082static 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
1094static PyObject *
1095set_positioner_xvalue (genericobject *g, PyObject *args)
1096{
1097	return call_forms_INf (fl_set_positioner_xvalue, g-> ob_generic, args);
1098}
1099
1100static PyObject *
1101set_positioner_xbounds (genericobject *g, PyObject *args)
1102{
1103	return call_forms_INfINf (fl_set_positioner_xbounds,
1104				  g-> ob_generic, args);
1105}
1106
1107static PyObject *
1108set_positioner_yvalue (genericobject *g, PyObject *args)
1109{
1110	return call_forms_INf (fl_set_positioner_yvalue, g-> ob_generic, args);
1111}
1112
1113static PyObject *
1114set_positioner_ybounds (genericobject *g, PyObject *args)
1115{
1116	return call_forms_INfINf (fl_set_positioner_ybounds,
1117				  g-> ob_generic, args);
1118}
1119
1120static PyObject *
1121get_positioner_xvalue (genericobject *g)
1122{
1123	return call_forms_Rf (fl_get_positioner_xvalue, g-> ob_generic);
1124}
1125
1126static PyObject *
1127get_positioner_xbounds (genericobject *g)
1128{
1129	return call_forms_OUTfOUTf (fl_get_positioner_xbounds, g-> ob_generic);
1130}
1131
1132static PyObject *
1133get_positioner_yvalue (genericobject *g)
1134{
1135	return call_forms_Rf (fl_get_positioner_yvalue, g-> ob_generic);
1136}
1137
1138static PyObject *
1139get_positioner_ybounds (genericobject *g)
1140{
1141	return call_forms_OUTfOUTf (fl_get_positioner_ybounds, g-> ob_generic);
1142}
1143
1144static 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
1166static PyObject *
1167set_timer (genericobject *g, PyObject *args)
1168{
1169	return call_forms_INf (fl_set_timer, g-> ob_generic, args);
1170}
1171
1172static PyObject *
1173get_timer (genericobject *g)
1174{
1175	return call_forms_Rf (fl_get_timer, g-> ob_generic);
1176}
1177
1178static 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
1186typedef struct {
1187	PyObject_HEAD
1188	FL_FORM *ob_form;
1189} formobject;
1190
1191static PyTypeObject Formtype;
1192
1193#define is_formobject(v) ((v)->ob_type == &Formtype)
1194
1195static PyObject *
1196form_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
1207static PyObject *
1208form_call(void (*func)(FL_FORM *), FL_FORM *f)
1209{
1210	(*func)(f);
1211
1212	Py_INCREF(Py_None);
1213	return Py_None;
1214}
1215
1216static PyObject *
1217form_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
1229static PyObject *
1230form_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
1242static PyObject *
1243form_hide_form(formobject *f)
1244{
1245	return form_call(fl_hide_form, f-> ob_form);
1246}
1247
1248static PyObject *
1249form_redraw_form(formobject *f)
1250{
1251	return form_call(fl_redraw_form, f-> ob_form);
1252}
1253
1254static PyObject *
1255form_set_form_position(formobject *f, PyObject *args)
1256{
1257	return form_call_INiINi(fl_set_form_position, f-> ob_form, args);
1258}
1259
1260static PyObject *
1261form_set_form_size(formobject *f, PyObject *args)
1262{
1263	return form_call_INiINi(fl_set_form_size, f-> ob_form, args);
1264}
1265
1266static PyObject *
1267form_scale_form(formobject *f, PyObject *args)
1268{
1269	return form_call_INfINf(fl_scale_form, f-> ob_form, args);
1270}
1271
1272static PyObject *
1273generic_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
1297static PyObject *
1298form_add_button(formobject *f, PyObject *args)
1299{
1300	return generic_add_object(f, args, fl_add_button, button_methods);
1301}
1302
1303static PyObject *
1304form_add_lightbutton(formobject *f, PyObject *args)
1305{
1306	return generic_add_object(f, args, fl_add_lightbutton, button_methods);
1307}
1308
1309static PyObject *
1310form_add_roundbutton(formobject *f, PyObject *args)
1311{
1312	return generic_add_object(f, args, fl_add_roundbutton, button_methods);
1313}
1314
1315static PyObject *
1316form_add_menu (formobject *f, PyObject *args)
1317{
1318	return generic_add_object(f, args, fl_add_menu, menu_methods);
1319}
1320
1321static PyObject *
1322form_add_slider(formobject *f, PyObject *args)
1323{
1324	return generic_add_object(f, args, fl_add_slider, slider_methods);
1325}
1326
1327static PyObject *
1328form_add_valslider(formobject *f, PyObject *args)
1329{
1330	return generic_add_object(f, args, fl_add_valslider, slider_methods);
1331}
1332
1333static PyObject *
1334form_add_dial(formobject *f, PyObject *args)
1335{
1336	return generic_add_object(f, args, fl_add_dial, dial_methods);
1337}
1338
1339static PyObject *
1340form_add_counter(formobject *f, PyObject *args)
1341{
1342	return generic_add_object(f, args, fl_add_counter, counter_methods);
1343}
1344
1345static PyObject *
1346form_add_clock(formobject *f, PyObject *args)
1347{
1348	return generic_add_object(f, args, fl_add_clock, clock_methods);
1349}
1350
1351static PyObject *
1352form_add_box(formobject *f, PyObject *args)
1353{
1354	return generic_add_object(f, args, fl_add_box,
1355				  (PyMethodDef *)NULL);
1356}
1357
1358static PyObject *
1359form_add_choice(formobject *f, PyObject *args)
1360{
1361	return generic_add_object(f, args, fl_add_choice, choice_methods);
1362}
1363
1364static PyObject *
1365form_add_browser(formobject *f, PyObject *args)
1366{
1367	return generic_add_object(f, args, fl_add_browser, browser_methods);
1368}
1369
1370static PyObject *
1371form_add_positioner(formobject *f, PyObject *args)
1372{
1373	return generic_add_object(f, args, fl_add_positioner,
1374				  positioner_methods);
1375}
1376
1377static PyObject *
1378form_add_input(formobject *f, PyObject *args)
1379{
1380	return generic_add_object(f, args, fl_add_input, input_methods);
1381}
1382
1383static PyObject *
1384form_add_text(formobject *f, PyObject *args)
1385{
1386	return generic_add_object(f, args, fl_add_text,
1387				  (PyMethodDef *)NULL);
1388}
1389
1390static PyObject *
1391form_add_timer(formobject *f, PyObject *args)
1392{
1393	return generic_add_object(f, args, fl_add_timer, timer_methods);
1394}
1395
1396static PyObject *
1397form_freeze_form(formobject *f)
1398{
1399	return form_call(fl_freeze_form, f-> ob_form);
1400}
1401
1402static PyObject *
1403form_unfreeze_form(formobject *f)
1404{
1405	return form_call(fl_unfreeze_form, f-> ob_form);
1406}
1407
1408static PyObject *
1409form_activate_form(formobject *f)
1410{
1411	return form_call(fl_activate_form, f-> ob_form);
1412}
1413
1414static PyObject *
1415form_deactivate_form(formobject *f)
1416{
1417	return form_call(fl_deactivate_form, f-> ob_form);
1418}
1419
1420static PyObject *
1421form_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
1437static PyObject *
1438form_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
1447static PyObject *
1448forms_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
1475static PyObject *
1476form_find_first(formobject *f, PyObject *args)
1477{
1478	return forms_find_first_or_last(fl_find_first, f, args);
1479}
1480
1481static PyObject *
1482form_find_last(formobject *f, PyObject *args)
1483{
1484	return forms_find_first_or_last(fl_find_last, f, args);
1485}
1486
1487static PyObject *
1488form_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
1501static 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
1540static void
1541form_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
1552static 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
1567static PyObject *
1568form_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
1579static int
1580form_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
1591static PyObject *
1592form_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
1600static 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
1615static PyObject *
1616newformobject(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
1629static PyObject *
1630forms_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
1647static PyObject *
1648forms_activate_all_forms(PyObject *f, PyObject *args)
1649{
1650	fl_activate_all_forms();
1651	Py_INCREF(Py_None);
1652	return Py_None;
1653}
1654
1655static PyObject *
1656forms_deactivate_all_forms(PyObject *f, PyObject *args)
1657{
1658	fl_deactivate_all_forms();
1659	Py_INCREF(Py_None);
1660	return Py_None;
1661}
1662
1663static PyObject *my_event_callback = NULL;
1664
1665static PyObject *
1666forms_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
1676static PyObject *
1677forms_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
1727static PyObject *
1728forms_do_forms(PyObject *dummy)
1729{
1730	return forms_do_or_check_forms(dummy, fl_do_forms);
1731}
1732
1733static PyObject *
1734forms_check_forms(PyObject *dummy)
1735{
1736	return forms_do_or_check_forms(dummy, fl_check_forms);
1737}
1738
1739static PyObject *
1740forms_do_only_forms(PyObject *dummy)
1741{
1742	return forms_do_or_check_forms(dummy, fl_do_only_forms);
1743}
1744
1745static PyObject *
1746forms_check_only_forms(PyObject *dummy)
1747{
1748	return forms_do_or_check_forms(dummy, fl_check_only_forms);
1749}
1750
1751#ifdef UNUSED
1752static PyObject *
1753fl_call(void (*func)(void))
1754{
1755	(*func)();
1756	Py_INCREF(Py_None);
1757	return Py_None;
1758}
1759#endif
1760
1761static PyObject *
1762forms_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
1773static PyObject *
1774forms_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
1785static PyObject *
1786forms_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
1796static PyObject *
1797forms_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
1809static PyObject *
1810forms_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
1820static PyObject *
1821forms_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
1831static PyObject *
1832forms_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
1843static PyObject *
1844forms_qtest(PyObject *self, PyObject *args)
1845{
1846	long retval;
1847	retval = fl_qtest();
1848	return PyInt_FromLong(retval);
1849}
1850
1851
1852static PyObject *
1853forms_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
1863static PyObject *
1864forms_qreset(PyObject *self)
1865{
1866	fl_qreset();
1867	Py_INCREF(Py_None);
1868	return Py_None;
1869}
1870
1871static PyObject *
1872forms_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
1882static PyObject *
1883forms_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
1895static PyObject *
1896forms_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
1909static PyObject *
1910forms_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
1922static PyObject *
1923forms_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
1932static PyObject *
1933forms_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
1943static PyObject *
1944forms_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
1958static PyObject *
1959forms_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
1999static PyObject *
2000forms_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
2014static PyObject *
2015forms_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
2033static PyObject *
2034forms_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
2053static PyObject *
2054forms_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
2067static PyObject *
2068forms_get_directory(PyObject *f, PyObject *args)
2069{
2070	return forms_file_selector_func(args, fl_get_directory);
2071}
2072
2073static PyObject *
2074forms_get_pattern(PyObject *f, PyObject *args)
2075{
2076	return forms_file_selector_func(args, fl_get_pattern);
2077}
2078
2079static PyObject *
2080forms_get_filename(PyObject *f, PyObject *args)
2081{
2082	return forms_file_selector_func(args, fl_get_filename);
2083}
2084
2085static 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_gra

Large files files are truncated, but you can click here to view the full file