⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flmodule.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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;

staticforward 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 void
knowgeneric(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 void
forgetgeneric(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 void
releaseobjects(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 (args == NULL) {
		Py_XDECREF(g->ob_callback);
		Py_XDECREF(g->ob_callback_arg);
		g->ob_callback = NULL;
		g->ob_callback_arg = NULL;
	}
	else {
		if (!PyTuple_Check(args) || PyTuple_Size(args) != 2) {
			PyErr_BadArgument();
			return NULL;
		}
		Py_XDECREF(g->ob_callback);
		Py_XDECREF(g->ob_callback_arg);
		g->ob_callback = PyTuple_GetItem(args, 0);
		Py_INCREF(g->ob_callback);
		g->ob_callback_arg = PyTuple_GetItem(args, 1);
		Py_INCREF(g->ob_callback_arg);
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
generic_call(genericobject *g, PyObject *args, void (*func)(FL_OBJECT *))
{
	if (!PyArg_NoArgs(args))
		return NULL;
	(*func)(g->ob_generic);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
generic_delete_object(genericobject *g, PyObject *args)
{
	PyObject *res;
	res = generic_call(g, args, fl_delete_object);
	if (res != NULL)
		forgetgeneric(g);
	return res;
}

static PyObject *
generic_show_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, fl_show_object);
}

static PyObject *
generic_hide_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, fl_hide_object);
}

static PyObject *
generic_redraw_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, 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, PyObject *args)
{
	return generic_call(g, args, fl_freeze_object);
}

static PyObject *
generic_unfreeze_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, fl_unfreeze_object);
}

#endif /* OBSOLETE_FORMS_CALLS */

static PyObject *
generic_activate_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, fl_activate_object);
}

static PyObject *
generic_deactivate_object(genericobject *g, PyObject *args)
{
	return generic_call(g, args, fl_deactivate_object);
}

static PyObject *
generic_set_object_shortcut(genericobject *g, PyObject *args)
{
	char *str;
	if (!PyArg_Parse(args, "s", &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},
	{"delete_object",	(PyCFunction)generic_delete_object},
	{"show_object",		(PyCFunction)generic_show_object},
	{"hide_object",		(PyCFunction)generic_hide_object},
	{"redraw_object",	(PyCFunction)generic_redraw_object},
#ifdef OBSOLETE_FORMS_CALLS
	{"freeze_object",	(PyCFunction)generic_freeze_object},
	{"unfreeze_object",	(PyCFunction)generic_unfreeze_object},
#endif
	{"activate_object",	(PyCFunction)generic_activate_object},
	{"deactivate_object",	(PyCFunction)generic_deactivate_object},
	{"set_object_shortcut",	(PyCFunction)generic_set_object_shortcut},
	{NULL,			NULL}		/* sentinel */
};

static void
generic_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 int
generic_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;
	
	if (!PyArg_Parse(args, "(ii)", &par1, &par2)) return NULL;
	
	(*func) (obj, par1, par2);
	
	Py_INCREF(Py_None);
	return Py_None;
}
#endif

/* int func (object) */
static PyObject *
call_forms_Ri (int (*func)(FL_OBJECT *), FL_OBJECT *obj, PyObject *args)
{
	int retval;
	
	if (!PyArg_NoArgs(args)) return NULL;
	
	retval = (*func) (obj);
	
	return PyInt_FromLong ((long) retval);
}

/* char * func (object) */
static PyObject *
call_forms_Rstr (char * (*func)(FL_OBJECT *), FL_OBJECT *obj, PyObject *args)
{
	char *str;
	
	if (!PyArg_NoArgs(args)) return NULL;
	
	str = (*func) (obj);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -