mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	Setup.in: clarified Tk comments somewhat. structmodule.c: use memcpy() instead of double precision assignment.
		
			
				
	
	
		
			777 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			777 lines
		
	
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**********************************************************
 | 
						|
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
 | 
						|
The Netherlands.
 | 
						|
 | 
						|
                        All Rights Reserved
 | 
						|
 | 
						|
Permission to use, copy, modify, and distribute this software and its 
 | 
						|
documentation for any purpose and without fee is hereby granted, 
 | 
						|
provided that the above copyright notice appear in all copies and that
 | 
						|
both that copyright notice and this permission notice appear in 
 | 
						|
supporting documentation, and that the names of Stichting Mathematisch
 | 
						|
Centrum or CWI not be used in advertising or publicity pertaining to
 | 
						|
distribution of the software without specific, written prior permission.
 | 
						|
 | 
						|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
 | 
						|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
						|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
 | 
						|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
						|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
						|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 | 
						|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 | 
						|
******************************************************************/
 | 
						|
 | 
						|
/* AL module -- interface to Mark Callow's Audio Library (AL). */
 | 
						|
 | 
						|
#include <audio.h>
 | 
						|
 | 
						|
/* Check which version audio library we have: */
 | 
						|
#ifdef AL_ERROR_NUMBER
 | 
						|
#define AL_405
 | 
						|
/* XXXX 4.0.5 libaudio also allows us to provide better error
 | 
						|
** handling (with ALseterrorhandler). We should implement that
 | 
						|
** sometime.
 | 
						|
*/
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#include "allobjects.h"
 | 
						|
#include "import.h"
 | 
						|
#include "modsupport.h"
 | 
						|
#include "structmember.h"
 | 
						|
#include "ceval.h"
 | 
						|
 | 
						|
 | 
						|
/* Config objects */
 | 
						|
 | 
						|
typedef struct {
 | 
						|
	OB_HEAD
 | 
						|
	ALconfig ob_config;
 | 
						|
} configobject;
 | 
						|
 | 
						|
staticforward typeobject Configtype;
 | 
						|
 | 
						|
#define is_configobject(v) ((v)->ob_type == &Configtype)
 | 
						|
 | 
						|
/* Forward */
 | 
						|
static int getconfigarg PROTO((object *, ALconfig *));
 | 
						|
static int getstrstrconfigarg PROTO((object *, char **, char **, ALconfig *));
 | 
						|
 | 
						|
static object *
 | 
						|
setConfig (self, args, func)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
	void (*func)(ALconfig, long);
 | 
						|
{
 | 
						|
	long par;
 | 
						|
 | 
						|
	if (!getlongarg (args, &par)) return NULL;
 | 
						|
 | 
						|
	(*func) (self-> ob_config, par);
 | 
						|
 | 
						|
	INCREF (None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
getConfig (self, args, func)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
	long (*func)(ALconfig);
 | 
						|
{	
 | 
						|
	long par;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
	
 | 
						|
	par = (*func) (self-> ob_config);
 | 
						|
 | 
						|
	return newintobject (par);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setqueuesize (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (setConfig (self, args, ALsetqueuesize));
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getqueuesize (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (getConfig (self, args, ALgetqueuesize));
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setwidth (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (setConfig (self, args, ALsetwidth));
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getwidth (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (getConfig (self, args, ALgetwidth));	
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getchannels (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (getConfig (self, args, ALgetchannels));	
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setchannels (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (setConfig (self, args, ALsetchannels));
 | 
						|
}
 | 
						|
 | 
						|
#ifdef AL_405
 | 
						|
 | 
						|
static object *
 | 
						|
al_getsampfmt (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (getConfig (self, args, ALgetsampfmt));	
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setsampfmt (self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	return (setConfig (self, args, ALsetsampfmt));
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getfloatmax(self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	double arg;
 | 
						|
 | 
						|
	if ( !getnoarg(args) )
 | 
						|
	  return 0;
 | 
						|
	arg = ALgetfloatmax(self->ob_config);
 | 
						|
	return newfloatobject(arg);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setfloatmax(self, args)
 | 
						|
	configobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	double arg;
 | 
						|
 | 
						|
	if ( !getargs(args, "d", &arg) )
 | 
						|
	  return 0;
 | 
						|
	ALsetfloatmax(self->ob_config, arg);
 | 
						|
	INCREF(None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
#endif /* AL_405 */
 | 
						|
	
 | 
						|
static struct methodlist config_methods[] = {
 | 
						|
	{"getqueuesize",	(method)al_getqueuesize},
 | 
						|
	{"setqueuesize",	(method)al_setqueuesize},
 | 
						|
	{"getwidth",		(method)al_getwidth},
 | 
						|
	{"setwidth",		(method)al_setwidth},
 | 
						|
	{"getchannels",		(method)al_getchannels},
 | 
						|
	{"setchannels",		(method)al_setchannels},
 | 
						|
#ifdef AL_405
 | 
						|
	{"getsampfmt",		(method)al_getsampfmt},
 | 
						|
	{"setsampfmt",		(method)al_setsampfmt},
 | 
						|
	{"getfloatmax",		(method)al_getfloatmax},
 | 
						|
	{"setfloatmax",		(method)al_setfloatmax},
 | 
						|
#endif /* AL_405 */
 | 
						|
	{NULL,			NULL}		/* sentinel */
 | 
						|
};
 | 
						|
 | 
						|
static void
 | 
						|
config_dealloc(self)
 | 
						|
	configobject *self;
 | 
						|
{
 | 
						|
	ALfreeconfig(self->ob_config);
 | 
						|
	DEL(self);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
config_getattr(self, name)
 | 
						|
	configobject *self;
 | 
						|
	char *name;
 | 
						|
{
 | 
						|
	return findmethod(config_methods, (object *)self, name);
 | 
						|
}
 | 
						|
 | 
						|
static typeobject Configtype = {
 | 
						|
	OB_HEAD_INIT(&Typetype)
 | 
						|
	0,			/*ob_size*/
 | 
						|
	"config",		/*tp_name*/
 | 
						|
	sizeof(configobject),	/*tp_size*/
 | 
						|
	0,			/*tp_itemsize*/
 | 
						|
	/* methods */
 | 
						|
	(destructor)config_dealloc, /*tp_dealloc*/
 | 
						|
	0,			/*tp_print*/
 | 
						|
	(getattrfunc)config_getattr, /*tp_getattr*/
 | 
						|
	0,			/*tp_setattr*/
 | 
						|
	0,			/*tp_compare*/
 | 
						|
	0,			/*tp_repr*/
 | 
						|
};
 | 
						|
 | 
						|
static object *
 | 
						|
newconfigobject(config)
 | 
						|
	ALconfig config;
 | 
						|
{
 | 
						|
	configobject *p;
 | 
						|
	
 | 
						|
	p = NEWOBJ(configobject, &Configtype);
 | 
						|
	if (p == NULL)
 | 
						|
		return NULL;
 | 
						|
	p->ob_config = config;
 | 
						|
	return (object *)p;
 | 
						|
}
 | 
						|
 | 
						|
/* Port objects */
 | 
						|
 | 
						|
typedef struct {
 | 
						|
	OB_HEAD
 | 
						|
	ALport ob_port;
 | 
						|
} portobject;
 | 
						|
 | 
						|
staticforward typeobject Porttype;
 | 
						|
 | 
						|
#define is_portobject(v) ((v)->ob_type == &Porttype)
 | 
						|
 | 
						|
static object *
 | 
						|
al_closeport (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
 | 
						|
	if (self->ob_port != NULL) {
 | 
						|
		ALcloseport (self-> ob_port);
 | 
						|
		self->ob_port = NULL;
 | 
						|
		/* XXX Using a closed port may dump core! */
 | 
						|
	}
 | 
						|
 | 
						|
	INCREF (None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getfd (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	int fd;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
 | 
						|
	fd = ALgetfd (self-> ob_port);
 | 
						|
 | 
						|
	return newintobject (fd);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getfilled (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
	
 | 
						|
	count = ALgetfilled (self-> ob_port);
 | 
						|
 | 
						|
	return newintobject (count);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getfillable (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
	
 | 
						|
	count = ALgetfillable (self-> ob_port);
 | 
						|
 | 
						|
	return newintobject (count);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_readsamps (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
	object *v;
 | 
						|
	ALconfig c;
 | 
						|
	int width;
 | 
						|
 | 
						|
	if (!getlongarg (args, &count)) return NULL;
 | 
						|
 | 
						|
	if (count <= 0)
 | 
						|
	{
 | 
						|
		err_setstr (RuntimeError, "al.readsamps : arg <= 0");
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	c = ALgetconfig(self->ob_port);
 | 
						|
#ifdef AL_405
 | 
						|
	width = ALgetsampfmt(c);
 | 
						|
	if ( width == AL_SAMPFMT_FLOAT )
 | 
						|
	  width = sizeof(float);
 | 
						|
	else if ( width == AL_SAMPFMT_DOUBLE )
 | 
						|
	  width = sizeof(double);
 | 
						|
	else
 | 
						|
	  width = ALgetwidth(c);
 | 
						|
#else
 | 
						|
	width = ALgetwidth(c);
 | 
						|
#endif /* AL_405 */
 | 
						|
	ALfreeconfig(c);
 | 
						|
	v = newsizedstringobject ((char *)NULL, width * count);
 | 
						|
	if (v == NULL) return NULL;
 | 
						|
 | 
						|
	BGN_SAVE
 | 
						|
	ALreadsamps (self-> ob_port, (void *) getstringvalue(v), count);
 | 
						|
	END_SAVE
 | 
						|
 | 
						|
	return (v);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_writesamps (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
	char *buf;
 | 
						|
	int size, width;
 | 
						|
	ALconfig c;
 | 
						|
 | 
						|
	if (!getargs (args, "s#", &buf, &size)) return NULL;
 | 
						|
 | 
						|
	c = ALgetconfig(self->ob_port);
 | 
						|
#ifdef AL_405
 | 
						|
	width = ALgetsampfmt(c);
 | 
						|
	if ( width == AL_SAMPFMT_FLOAT )
 | 
						|
	  width = sizeof(float);
 | 
						|
	else if ( width == AL_SAMPFMT_DOUBLE )
 | 
						|
	  width = sizeof(double);
 | 
						|
	else
 | 
						|
	  width = ALgetwidth(c);
 | 
						|
#else
 | 
						|
	width = ALgetwidth(c);
 | 
						|
#endif /* AL_405 */
 | 
						|
	ALfreeconfig(c);
 | 
						|
	BGN_SAVE
 | 
						|
	ALwritesamps (self-> ob_port, (void *) buf, (long) size / width);
 | 
						|
	END_SAVE
 | 
						|
 | 
						|
	INCREF (None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getfillpoint (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
	
 | 
						|
	count = ALgetfillpoint (self-> ob_port);
 | 
						|
 | 
						|
	return newintobject (count);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setfillpoint (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	long count;
 | 
						|
 | 
						|
	if (!getlongarg (args, &count)) return NULL;
 | 
						|
	
 | 
						|
	ALsetfillpoint (self-> ob_port, count);
 | 
						|
 | 
						|
	INCREF (None);
 | 
						|
	return (None);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setconfig (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	ALconfig config;
 | 
						|
 | 
						|
	if (!getconfigarg (args, &config)) return NULL;
 | 
						|
	
 | 
						|
	ALsetconfig (self-> ob_port, config);
 | 
						|
 | 
						|
	INCREF (None);
 | 
						|
	return (None);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getconfig (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	ALconfig config;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
	
 | 
						|
	config = ALgetconfig (self-> ob_port);
 | 
						|
 | 
						|
	return newconfigobject (config);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef AL_405
 | 
						|
static object *
 | 
						|
al_getstatus (self, args)
 | 
						|
	portobject *self;
 | 
						|
	object *args;
 | 
						|
{
 | 
						|
	object *list, *v;
 | 
						|
	long *PVbuffer;
 | 
						|
	long length;
 | 
						|
	int i;
 | 
						|
	
 | 
						|
	if (!getargs(args, "O", &list))
 | 
						|
		return NULL;
 | 
						|
	if (!is_listobject(list)) {
 | 
						|
		err_badarg();
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	length = getlistsize(list);
 | 
						|
	PVbuffer = NEW(long, length);
 | 
						|
	if (PVbuffer == NULL)
 | 
						|
		return err_nomem();
 | 
						|
	for (i = 0; i < length; i++) {
 | 
						|
		v = getlistitem(list, i);
 | 
						|
		if (!is_intobject(v)) {
 | 
						|
			DEL(PVbuffer);
 | 
						|
			err_badarg();
 | 
						|
			return NULL;
 | 
						|
		}
 | 
						|
		PVbuffer[i] = getintvalue(v);
 | 
						|
	}
 | 
						|
 | 
						|
	ALgetstatus(self->ob_port, PVbuffer, length);
 | 
						|
 | 
						|
	for (i = 0; i < length; i++)
 | 
						|
	  setlistitem(list, i, newintobject(PVbuffer[i]));
 | 
						|
 | 
						|
	DEL(PVbuffer);
 | 
						|
 | 
						|
	INCREF(None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
#endif /* AL_405 */
 | 
						|
 | 
						|
static struct methodlist port_methods[] = {
 | 
						|
	{"closeport",		(method)al_closeport},
 | 
						|
	{"getfd",		(method)al_getfd},
 | 
						|
        {"fileno",		(method)al_getfd},
 | 
						|
	{"getfilled",		(method)al_getfilled},
 | 
						|
	{"getfillable",		(method)al_getfillable},
 | 
						|
	{"readsamps",		(method)al_readsamps},
 | 
						|
	{"writesamps",		(method)al_writesamps},
 | 
						|
	{"setfillpoint",	(method)al_setfillpoint},
 | 
						|
	{"getfillpoint",	(method)al_getfillpoint},
 | 
						|
	{"setconfig",		(method)al_setconfig},
 | 
						|
	{"getconfig",		(method)al_getconfig},
 | 
						|
#ifdef AL_405
 | 
						|
	{"getstatus",		(method)al_getstatus},
 | 
						|
#endif /* AL_405 */	    
 | 
						|
	{NULL,			NULL}		/* sentinel */
 | 
						|
};
 | 
						|
 | 
						|
static void
 | 
						|
port_dealloc(p)
 | 
						|
	portobject *p;
 | 
						|
{
 | 
						|
	if (p->ob_port != NULL)
 | 
						|
		ALcloseport(p->ob_port);
 | 
						|
	DEL(p);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
port_getattr(p, name)
 | 
						|
	portobject *p;
 | 
						|
	char *name;
 | 
						|
{
 | 
						|
	return findmethod(port_methods, (object *)p, name);
 | 
						|
}
 | 
						|
 | 
						|
static typeobject Porttype = {
 | 
						|
	OB_HEAD_INIT(&Typetype)
 | 
						|
	0,			/*ob_size*/
 | 
						|
	"port",			/*tp_name*/
 | 
						|
	sizeof(portobject),	/*tp_size*/
 | 
						|
	0,			/*tp_itemsize*/
 | 
						|
	/* methods */
 | 
						|
	(destructor)port_dealloc, /*tp_dealloc*/
 | 
						|
	0,			/*tp_print*/
 | 
						|
	(getattrfunc)port_getattr, /*tp_getattr*/
 | 
						|
	0,			/*tp_setattr*/
 | 
						|
	0,			/*tp_compare*/
 | 
						|
	0,			/*tp_repr*/
 | 
						|
};
 | 
						|
 | 
						|
static object *
 | 
						|
newportobject(port)
 | 
						|
	ALport port;
 | 
						|
{
 | 
						|
	portobject *p;
 | 
						|
	
 | 
						|
	p = NEWOBJ(portobject, &Porttype);
 | 
						|
	if (p == NULL)
 | 
						|
		return NULL;
 | 
						|
	p->ob_port = port;
 | 
						|
	return (object *)p;
 | 
						|
}
 | 
						|
 | 
						|
/* the module al */
 | 
						|
 | 
						|
static object *
 | 
						|
al_openport (self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	char *name, *dir;
 | 
						|
	ALport port;
 | 
						|
	ALconfig config = NULL;
 | 
						|
	int size;
 | 
						|
 | 
						|
	if (args == NULL || !is_tupleobject(args)) {
 | 
						|
		err_badarg ();
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	size = gettuplesize(args);
 | 
						|
	if (size == 2) {
 | 
						|
		if (!getargs (args, "(ss)", &name, &dir))
 | 
						|
			return NULL;
 | 
						|
	}
 | 
						|
	else if (size == 3) {
 | 
						|
		if (!getstrstrconfigarg (args, &name, &dir, &config))
 | 
						|
			return NULL;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		err_badarg ();
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	port = ALopenport(name, dir, config);
 | 
						|
 | 
						|
	if (port == NULL) {
 | 
						|
		err_errno(RuntimeError);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return newportobject (port);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_newconfig (self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	ALconfig config;
 | 
						|
 | 
						|
	if (!getnoarg (args)) return NULL;
 | 
						|
 | 
						|
	config = ALnewconfig ();
 | 
						|
	if (config == NULL) {
 | 
						|
		err_errno(RuntimeError);
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return newconfigobject (config);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_queryparams(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	long device;
 | 
						|
	long length;
 | 
						|
	long *PVbuffer;
 | 
						|
	long PVdummy[2];
 | 
						|
	object *v;
 | 
						|
	object *w;
 | 
						|
 | 
						|
	if (!getlongarg (args, &device))
 | 
						|
		return NULL;
 | 
						|
	length = ALqueryparams(device, PVdummy, 2L);
 | 
						|
	PVbuffer = NEW(long, length);
 | 
						|
	if (PVbuffer == NULL)
 | 
						|
		return err_nomem();
 | 
						|
	(void) ALqueryparams(device, PVbuffer, length);
 | 
						|
	v = newlistobject((int)length);
 | 
						|
	if (v != NULL) {
 | 
						|
		int i;
 | 
						|
		for (i = 0; i < length; i++)
 | 
						|
			setlistitem(v, i, newintobject(PVbuffer[i]));
 | 
						|
	}
 | 
						|
	DEL(PVbuffer);
 | 
						|
	return v;
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
doParams(args, func, modified)
 | 
						|
	object *args;
 | 
						|
	void (*func)(long, long *, long);
 | 
						|
	int modified;
 | 
						|
{
 | 
						|
	long device;
 | 
						|
	object *list, *v;
 | 
						|
	long *PVbuffer;
 | 
						|
	long length;
 | 
						|
	int i;
 | 
						|
	
 | 
						|
	if (!getargs(args, "(lO)", &device, &list))
 | 
						|
		return NULL;
 | 
						|
	if (!is_listobject(list)) {
 | 
						|
		err_badarg();
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	length = getlistsize(list);
 | 
						|
	PVbuffer = NEW(long, length);
 | 
						|
	if (PVbuffer == NULL)
 | 
						|
		return err_nomem();
 | 
						|
	for (i = 0; i < length; i++) {
 | 
						|
		v = getlistitem(list, i);
 | 
						|
		if (!is_intobject(v)) {
 | 
						|
			DEL(PVbuffer);
 | 
						|
			err_badarg();
 | 
						|
			return NULL;
 | 
						|
		}
 | 
						|
		PVbuffer[i] = getintvalue(v);
 | 
						|
	}
 | 
						|
 | 
						|
	(*func)(device, PVbuffer, length);
 | 
						|
 | 
						|
	if (modified) {
 | 
						|
		for (i = 0; i < length; i++)
 | 
						|
			setlistitem(list, i, newintobject(PVbuffer[i]));
 | 
						|
	}
 | 
						|
 | 
						|
	DEL(PVbuffer);
 | 
						|
 | 
						|
	INCREF(None);
 | 
						|
	return None;
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getparams(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	return doParams(args, ALgetparams, 1);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_setparams(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	return doParams(args, ALsetparams, 0);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getname(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	long device, descriptor;
 | 
						|
	char *name;
 | 
						|
	if (!getargs(args, "(ll)", &device, &descriptor))
 | 
						|
		return NULL;
 | 
						|
	name = ALgetname(device, descriptor);
 | 
						|
	if (name == NULL) {
 | 
						|
		err_setstr(ValueError, "al.getname: bad descriptor");
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
	return newstringobject(name);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getdefault(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	long device, descriptor, value;
 | 
						|
	if (!getargs(args, "(ll)", &device, &descriptor))
 | 
						|
		return NULL;
 | 
						|
	value = ALgetdefault(device, descriptor);
 | 
						|
	return newlongobject(value);
 | 
						|
}
 | 
						|
 | 
						|
static object *
 | 
						|
al_getminmax(self, args)
 | 
						|
	object *self, *args;
 | 
						|
{
 | 
						|
	long device, descriptor, min, max;
 | 
						|
	if (!getargs(args, "(ll)", &device, &descriptor))
 | 
						|
		return NULL;
 | 
						|
	min = -1;
 | 
						|
	max = -1;
 | 
						|
	ALgetminmax(device, descriptor, &min, &max);
 | 
						|
	return mkvalue("ll", min, max);
 | 
						|
}
 | 
						|
 | 
						|
static struct methodlist al_methods[] = {
 | 
						|
	{"openport",		(method)al_openport},
 | 
						|
	{"newconfig",		(method)al_newconfig},
 | 
						|
	{"queryparams",		(method)al_queryparams},
 | 
						|
	{"getparams",		(method)al_getparams},
 | 
						|
	{"setparams",		(method)al_setparams},
 | 
						|
	{"getname",		(method)al_getname},
 | 
						|
	{"getdefault",		(method)al_getdefault},
 | 
						|
	{"getminmax",		(method)al_getminmax},
 | 
						|
	{NULL,			NULL}		/* sentinel */
 | 
						|
};
 | 
						|
 | 
						|
void
 | 
						|
inital()
 | 
						|
{
 | 
						|
	initmodule("al", al_methods);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
getconfigarg(o, conf)
 | 
						|
	object *o;
 | 
						|
	ALconfig *conf;
 | 
						|
{
 | 
						|
	if (o == NULL || !is_configobject(o))
 | 
						|
		return err_badarg ();
 | 
						|
	
 | 
						|
	*conf = ((configobject *) o) -> ob_config;
 | 
						|
	
 | 
						|
	return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
getstrstrconfigarg(v, a, b, c)
 | 
						|
	object *v;
 | 
						|
	char **a;
 | 
						|
	char **b;
 | 
						|
	ALconfig *c;
 | 
						|
{
 | 
						|
	object *o;
 | 
						|
	return getargs(v, "(ssO)", a, b, &o) && getconfigarg(o, c);
 | 
						|
}
 |