cinap_lenrekadd hg and python4bb9e2215 years agoHistory
2139 lines · 49.2 KB · C
RawDownload
/* FL module -- interface to Mark Overmars' FORMS Library. */ /* This code works with FORMS version 2.2 (if you defined   OBSOLETE_FORMS_CALLS), and 2.3.   FORMS can be ftp'ed from ftp.cs.ruu.nl (131.211.80.17), directory   /pub/SGI/FORMS. */ /* A half-hearted attempt has been made to allow programs using this * module to exploit parallelism (through the threads module). No provisions * have been made for multiple threads to use this module at the same time, * though. So, a program with a forms thread and a non-forms thread will work * fine but a program with two threads using forms will probably crash (unless * the program takes precaution to ensure that only one thread can be in * this module at any time). This will have to be fixed some time. * (A fix will probably also have to synchronize with the gl module). */ #include "Python.h"#include "forms.h"#include "structmember.h" /* Generic Forms Objects */ typedef struct {	PyObject_HEAD	FL_OBJECT *ob_generic;	PyMethodDef *ob_methods;	PyObject *ob_callback;	PyObject *ob_callback_arg;} genericobject; static PyTypeObject GenericObjecttype; #define is_genericobject(g) ((g)->ob_type == &GenericObjecttype) /* List of all objects (XXX this should be a hash table on address...) */ static PyObject *allgenerics = NULL;static int nfreeslots = 0; /* Add an object to the list of known objects */ static voidknowgeneric(genericobject *g){	int i, n;	/* Create the list if it doesn't already exist */	if (allgenerics == NULL) {		allgenerics = PyList_New(0);		if (allgenerics == NULL) {			PyErr_Clear();			return; /* Too bad, live without allgenerics... */		}	}	if (nfreeslots > 0) {		/* Search the list for reusable slots (NULL items) */		/* XXX This can be made faster! */		n = PyList_Size(allgenerics);		for (i = 0; i < n; i++) {			if (PyList_GetItem(allgenerics, i) == NULL) {				Py_INCREF(g);				PyList_SetItem(allgenerics, i, (PyObject *)g);				nfreeslots--;				return;			}		}		/* Strange... no free slots found... */		nfreeslots = 0;	}	/* No free entries, append new item to the end */	PyList_Append(allgenerics, (PyObject *)g);} /* Find an object in the list of known objects */ static genericobject *findgeneric(FL_OBJECT *generic){	int i, n;	genericobject *g;		if (allgenerics == NULL)		return NULL; /* No objects known yet */	n = PyList_Size(allgenerics);	for (i = 0; i < n; i++) {		g = (genericobject *)PyList_GetItem(allgenerics, i);		if (g != NULL && g->ob_generic == generic)			return g;	}	return NULL; /* Unknown object */} /* Remove an object from the list of known objects */ static voidforgetgeneric(genericobject *g){	int i, n;		Py_XDECREF(g->ob_callback);	g->ob_callback = NULL;	Py_XDECREF(g->ob_callback_arg);	g->ob_callback_arg = NULL;	if (allgenerics == NULL)		return; /* No objects known yet */	n = PyList_Size(allgenerics);	for (i = 0; i < n; i++) {		if (g == (genericobject *)PyList_GetItem(allgenerics, i)) {			PyList_SetItem(allgenerics, i, (PyObject *)NULL);			nfreeslots++;			break;		}	}} /* Called when a form is about to be freed --   remove all the objects that we know about from it. */ static voidreleaseobjects(FL_FORM *form){	int i, n;	genericobject *g;		if (allgenerics == NULL)		return; /* No objects known yet */	n = PyList_Size(allgenerics);	for (i = 0; i < n; i++) {		g = (genericobject *)PyList_GetItem(allgenerics, i);		if (g != NULL && g->ob_generic->form == form) {			fl_delete_object(g->ob_generic);			/* The object is now unreachable for			   do_forms and check_forms, so			   delete it from the list of known objects */			Py_XDECREF(g->ob_callback);			g->ob_callback = NULL;			Py_XDECREF(g->ob_callback_arg);			g->ob_callback_arg = NULL;			PyList_SetItem(allgenerics, i, (PyObject *)NULL);			nfreeslots++;		}	}}  /* Methods of generic objects */ static PyObject *generic_set_call_back(genericobject *g, PyObject *args){	if (PyTuple_GET_SIZE(args) == 0) {		Py_XDECREF(g->ob_callback);		Py_XDECREF(g->ob_callback_arg);		g->ob_callback = NULL;		g->ob_callback_arg = NULL;	}	else {        PyObject *a, *b;        if (!PyArg_UnpackTuple(args, "set_call_back", 2, 2, &a, &b)            return NULL;		Py_XDECREF(g->ob_callback);		Py_XDECREF(g->ob_callback_arg);		g->ob_callback = a;		Py_INCREF(g->ob_callback);		g->ob_callback_arg = b;		Py_INCREF(g->ob_callback_arg);	}	Py_INCREF(Py_None);	return Py_None;} static PyObject *generic_call(genericobject *g, void (*func)(FL_OBJECT *)){	(*func)(g->ob_generic);	Py_INCREF(Py_None);	return Py_None;} static PyObject *generic_delete_object(genericobject *g){	PyObject *res;	res = generic_call(g, fl_delete_object);	if (res != NULL)		forgetgeneric(g);	return res;} static PyObject *generic_show_object(genericobject *g){	return generic_call(g, fl_show_object);} static PyObject *generic_hide_object(genericobject *g){	return generic_call(g, fl_hide_object);} static PyObject *generic_redraw_object(genericobject *g){	return generic_call(g, fl_redraw_object);} #ifdef OBSOLETE_FORMS_CALLS  /* (un)freeze_object() are obsolete in FORMS 2.2 and unsupported    in 2.3.  Since there's no foolproof way to tell which version we're    using, we omit them unconditionally. */ static PyObject *generic_freeze_object(genericobject *g){	return generic_call(g, fl_freeze_object);} static PyObject *generic_unfreeze_object(genericobject *g){	return generic_call(g, fl_unfreeze_object);} #endif /* OBSOLETE_FORMS_CALLS */ static PyObject *generic_activate_object(genericobject *g){	return generic_call(g, fl_activate_object);} static PyObject *generic_deactivate_object(genericobject *g){	return generic_call(g, fl_deactivate_object);} static PyObject *generic_set_object_shortcut(genericobject *g, PyObject *args){	char *str;	if (!PyArg_ParseTuple(args, "s:set_object_shortcut", &str))		return NULL;	fl_set_object_shortcut(g->ob_generic, str);	Py_INCREF(Py_None);	return Py_None;} static PyMethodDef generic_methods[] = {	{"set_call_back",	(PyCFunction)generic_set_call_back, METH_VARARGS},	{"delete_object",	(PyCFunction)generic_delete_object, METH_NOARGS},	{"show_object",		(PyCFunction)generic_show_object, METH_NOARGS},	{"hide_object",		(PyCFunction)generic_hide_object, METH_NOARGS},	{"redraw_object",	(PyCFunction)generic_redraw_object, METH_NOARGS},#ifdef OBSOLETE_FORMS_CALLS	{"freeze_object",	(PyCFunction)generic_freeze_object, METH_NOARGS},	{"unfreeze_object",	(PyCFunction)generic_unfreeze_object, METH_NOARGS},#endif	{"activate_object",	(PyCFunction)generic_activate_object, METH_NOARGS},	{"deactivate_object",	(PyCFunction)generic_deactivate_object, METH_NOARGS},	{"set_object_shortcut",	(PyCFunction)generic_set_object_shortcut, METH_VARARGS},	{NULL,			NULL}		/* sentinel */}; static voidgeneric_dealloc(genericobject *g){	fl_free_object(g->ob_generic);	Py_XDECREF(g->ob_callback);	Py_XDECREF(g->ob_callback_arg);	PyObject_Del(g);} #define OFF(x) offsetof(FL_OBJECT, x) static struct memberlist generic_memberlist[] = {	{"objclass",	T_INT,		OFF(objclass),	RO},	{"type",	T_INT,		OFF(type),	RO},	{"boxtype",	T_INT,		OFF(boxtype)},	{"x",		T_FLOAT,	OFF(x)},	{"y",		T_FLOAT,	OFF(y)},	{"w",		T_FLOAT,	OFF(w)},	{"h",		T_FLOAT,	OFF(h)},	{"col1",	T_INT,		OFF(col1)},	{"col2",	T_INT,		OFF(col2)},	{"align",	T_INT,		OFF(align)},	{"lcol",	T_INT,		OFF(lcol)},	{"lsize",	T_FLOAT,	OFF(lsize)},	/* "label" is treated specially! */	{"lstyle",	T_INT,		OFF(lstyle)},	{"pushed",	T_INT,		OFF(pushed),	RO},	{"focus",	T_INT,		OFF(focus),	RO},	{"belowmouse",	T_INT,		OFF(belowmouse),RO},/*	{"frozen",	T_INT,		OFF(frozen),	RO},	*/	{"active",	T_INT,		OFF(active)},	{"input",	T_INT,		OFF(input)},	{"visible",	T_INT,		OFF(visible),	RO},	{"radio",	T_INT,		OFF(radio)},	{"automatic",	T_INT,		OFF(automatic)},	{NULL}	/* Sentinel */}; #undef OFF static PyObject *generic_getattr(genericobject *g, char *name){	PyObject *meth; 	/* XXX Ought to special-case name "__methods__" */	if (g-> ob_methods) {		meth = Py_FindMethod(g->ob_methods, (PyObject *)g, name);		if (meth != NULL) return meth;		PyErr_Clear();	} 	meth = Py_FindMethod(generic_methods, (PyObject *)g, name);	if (meth != NULL)		return meth;	PyErr_Clear(); 	/* "label" is an exception, getmember only works for char pointers,	   not for char arrays */	if (strcmp(name, "label") == 0)		return PyString_FromString(g->ob_generic->label); 	return PyMember_Get((char *)g->ob_generic, generic_memberlist, name);} static intgeneric_setattr(genericobject *g, char *name, PyObject *v){	int ret; 	if (v == NULL) {		PyErr_SetString(PyExc_TypeError,				"can't delete forms object attributes");		return -1;	} 	/* "label" is an exception: setmember doesn't set strings;	   and FORMS wants you to call a function to set the label */	if (strcmp(name, "label") == 0) {		if (!PyString_Check(v)) {			PyErr_SetString(PyExc_TypeError,					"label attr must be string");			return -1;		}		fl_set_object_label(g->ob_generic, PyString_AsString(v));		return 0;	} 	ret = PyMember_Set((char *)g->ob_generic, generic_memberlist, name, v); 	/* Rather than calling all the various set_object_* functions,	   we call fl_redraw_object here.  This is sometimes redundant	   but I doubt that's a big problem */	if (ret == 0)		fl_redraw_object(g->ob_generic); 	return ret;} static PyObject *generic_repr(genericobject *g){	char buf[100];	PyOS_snprintf(buf, sizeof(buf), "<FORMS_object at %p, objclass=%d>",		      g, g->ob_generic->objclass);	return PyString_FromString(buf);} static PyTypeObject GenericObjecttype = {	PyObject_HEAD_INIT(&PyType_Type)	0,				/*ob_size*/	"fl.FORMS_object",		/*tp_name*/	sizeof(genericobject),		/*tp_size*/	0,				/*tp_itemsize*/	/* methods */	(destructor)generic_dealloc,	/*tp_dealloc*/	0,				/*tp_print*/	(getattrfunc)generic_getattr,	/*tp_getattr*/	(setattrfunc)generic_setattr,	/*tp_setattr*/	0,				/*tp_compare*/	(reprfunc)generic_repr,		/*tp_repr*/}; static PyObject *newgenericobject(FL_OBJECT *generic, PyMethodDef *methods){	genericobject *g;	g = PyObject_New(genericobject, &GenericObjecttype);	if (g == NULL)		return NULL;	g-> ob_generic = generic;	g->ob_methods = methods;	g->ob_callback = NULL;	g->ob_callback_arg = NULL;	knowgeneric(g);	return (PyObject *)g;} /**********************************************************************//* Some common calling sequences */ /* void func (object, float) */static PyObject *call_forms_INf (void (*func)(FL_OBJECT *, float), FL_OBJECT *obj, PyObject *args){	float parameter; 	if (!PyArg_Parse(args, "f", &parameter)) return NULL; 	(*func) (obj, parameter); 	Py_INCREF(Py_None);	return Py_None;} /* void func (object, float) */static PyObject *call_forms_INfINf (void (*func)(FL_OBJECT *, float, float), FL_OBJECT *obj, PyObject *args){	float par1, par2; 	if (!PyArg_Parse(args, "(ff)", &par1, &par2)) return NULL; 	(*func) (obj, par1, par2); 	Py_INCREF(Py_None);	return Py_None;} /* void func (object, int) */static PyObject *call_forms_INi (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args){	int parameter; 	if (!PyArg_Parse(args, "i", &parameter)) return NULL; 	(*func) (obj, parameter); 	Py_INCREF(Py_None);	return Py_None;} /* void func (object, char) */static PyObject *call_forms_INc (void (*func)(FL_OBJECT *, int), FL_OBJECT *obj, PyObject *args){	char *a; 	if (!PyArg_Parse(args, "s", &a)) return NULL; 	(*func) (obj, a[0]); 	Py_INCREF(Py_None);	return Py_None;} /* void func (object, string) */static PyObject *call_forms_INstr (void (*func)(FL_OBJECT *, char *), FL_OBJECT *obj, PyObject *args){	char *a; 	if (!PyArg_Parse(args, "s", &a)) return NULL; 	(*func) (obj, a); 	Py_INCREF(Py_None);	return Py_None;}  /* void func (object, int, string) */static PyObject *call_forms_INiINstr (void (*func)(FL_OBJECT *, int, char *), FL_OBJECT *obj, PyObject *args){	char *b;	int a;		if (!PyArg_Parse(args, "(is)", &a, &b)) return NULL;		(*func) (obj, a, b);		Py_INCREF(Py_None);	return Py_None;} #ifdef UNUSED/* void func (object, int, int) */static PyObject *call_forms_INiINi (void (*func)(FL_OBJECT *, int, int), FL_OBJECT *obj, PyObject *args){	int par1, par2;	

Lines 1–500 of 2139.