/**********************************************************
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.

******************************************************************/

/* SV module -- interface to the Indigo video board */

#include <sys/time.h>
#include <svideo.h>
#include "allobjects.h"
#include "import.h"
#include "modsupport.h"
#include "compile.h"
#include "ceval.h"
#include "yuv.h"		/* for YUV conversion functions */

typedef struct {
	OB_HEAD
	SV_nodeP ob_svideo;
	svCaptureInfo ob_info;
} svobject;

typedef struct {
	OB_HEAD
	void *ob_capture;
	int ob_mustunlock;
	svCaptureInfo ob_info;
	svobject *ob_svideo;
} captureobject;

static object *SvError;		/* exception sv.error */

static object *newcaptureobject PROTO((svobject *, void *, int));

/* Set a SV-specific error from svideo_errno and return NULL */
static object *
sv_error()
{
	err_setstr(SvError, svStrerror(svideo_errno));
	return NULL;
}

static object *
svc_conversion(self, args, function, factor)
	captureobject *self;
	object *args;
	void (*function)();
	float factor;
{
	object *output;
	int invert;

	if (!getargs(args, "i", &invert))
		return NULL;

	output = newsizedstringobject(NULL, (int) (self->ob_info.width * self->ob_info.height * factor));
	if (output == NULL)
		return NULL;

	(*function)((boolean) invert, self->ob_capture, getstringvalue(output),
		    self->ob_info.width, self->ob_info.height);

	return output;
}

/*
 * 3 functions to convert from Starter Video YUV 4:1:1 format to
 * Compression Library 4:2:2 Duplicate Chroma format.
 */
static object *
svc_YUVtoYUV422DC(self, args)
	captureobject *self;
	object *args;
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, yuv_sv411_to_cl422dc, 2.0);
}

static object *
svc_YUVtoYUV422DC_quarter(self, args)
	captureobject *self;
	object *args;
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, yuv_sv411_to_cl422dc_quartersize, 0.5);
}

static object *
svc_YUVtoYUV422DC_sixteenth(self, args)
	captureobject *self;
	object *args;
{
	if (self->ob_info.format != SV_YUV411_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, yuv_sv411_to_cl422dc_sixteenthsize, 0.125);
}

static object *
svc_YUVtoRGB(self, args)
	captureobject *self;
	object *args;
{
	switch (self->ob_info.format) {
	case SV_YUV411_FRAMES:
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		err_setstr(SvError, "data had bad format");
		return NULL;
	}
	return svc_conversion(self, args, svYUVtoRGB, (float) sizeof(long));
}

static object *
svc_RGB8toRGB32(self, args)
	captureobject *self;
	object *args;
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svRGB8toRGB32, (float) sizeof(long));
}

static object *
svc_InterleaveFields(self, args)
	captureobject *self;
	object *args;
{
	if (self->ob_info.format != SV_RGB8_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}
	return svc_conversion(self, args, svInterleaveFields, 1.0);
}

static object *
svc_GetFields(self, args)
	captureobject *self;
	object *args;
{
	object *f1, *f2, *ret;
	int fieldsize;

	if (self->ob_info.format != SV_RGB8_FRAMES) {
		err_setstr(SvError, "data has bad format");
		return NULL;
	}

	fieldsize = self->ob_info.width * self->ob_info.height / 2;
	f1 = newsizedstringobject((char *) self->ob_capture, fieldsize);
	f2 = newsizedstringobject((char *) self->ob_capture + fieldsize, fieldsize);
	ret = mkvalue("(OO)", f1, f2);
	XDECREF(f1);
	XDECREF(f2);
	return ret;
}
	
static object *
svc_UnlockCaptureData(self, args)
	captureobject *self;
	object *args;
{
	if (!getnoarg(args))
		return NULL;

	if (!self->ob_mustunlock) {
		err_setstr(SvError, "buffer should not be unlocked");
		return NULL;
	}

	if (svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture))
		return sv_error();

	self->ob_mustunlock = 0;

	INCREF(None);
	return None;
}

#ifdef USE_GL
#include <gl.h>

static object *
svc_lrectwrite(self, args)
	captureobject *self;
	object *args;
{
	Screencoord x1, x2, y1, y2;

	if (!getargs(args, "(hhhh)", &x1, &x2, &y1, &y2))
		return NULL;

	lrectwrite(x1, x2, y1, y2, (unsigned long *) self->ob_capture);

	INCREF(None);
	return None;
}
#endif

static object *
svc_writefile(self, args)
	captureobject *self;
	object *args;
{
	object *file;
	int size;

	if (!getargs(args, "O", &file))
		return NULL;

	if (!is_fileobject(file)) {
		err_setstr(SvError, "not a file object");
		return NULL;
	}

	size = self->ob_info.width * self->ob_info.height;

	if (fwrite(self->ob_capture, sizeof(long), size, getfilefile(file)) != size) {
		err_setstr(SvError, "writing failed");
		return NULL;
	}

	INCREF(None);
	return None;
}

static object *
svc_FindVisibleRegion(self, args)
	captureobject *self;
	object *args;
{
	void *visible;
	int width;

	if (!getnoarg(args))
		return NULL;

	if (svFindVisibleRegion(self->ob_svideo->ob_svideo, self->ob_capture, &visible, self->ob_info.width))
		return sv_error();

	if (visible == NULL) {
		err_setstr(SvError, "data in wrong format");
		return NULL;
	}

	return newcaptureobject(self->ob_svideo, visible, 0);
}

static struct methodlist capture_methods[] = {
	{"YUVtoRGB",		(method)svc_YUVtoRGB},
	{"RGB8toRGB32",		(method)svc_RGB8toRGB32},
	{"InterleaveFields",	(method)svc_InterleaveFields},
	{"UnlockCaptureData",	(method)svc_UnlockCaptureData},
	{"FindVisibleRegion",	(method)svc_FindVisibleRegion},
	{"GetFields",		(method)svc_GetFields},
	{"YUVtoYUV422DC",	(method)svc_YUVtoYUV422DC},
	{"YUVtoYUV422DC_quarter",(method)svc_YUVtoYUV422DC_quarter},
	{"YUVtoYUV422DC_sixteenth",(method)svc_YUVtoYUV422DC_sixteenth},
#ifdef USE_GL
	{"lrectwrite",		(method)svc_lrectwrite},
#endif
	{"writefile",		(method)svc_writefile},
	{NULL,			NULL} 		/* sentinel */
};

static void
capture_dealloc(self)
	captureobject *self;
{
	if (self->ob_capture != NULL) {
		if (self->ob_mustunlock)
			(void) svUnlockCaptureData(self->ob_svideo->ob_svideo, self->ob_capture);
		self->ob_capture = NULL;
		DECREF(self->ob_svideo);
		self->ob_svideo = NULL;
	}
	DEL(self);
}

static object *
capture_getattr(self, name)
	svobject *self;
	char *name;
{
	return findmethod(capture_methods, (object *)self, name);
}

typeobject Capturetype = {
	OB_HEAD_INIT(&Typetype)
	0,				/*ob_size*/
	"capture",			/*tp_name*/
	sizeof(captureobject),		/*tp_size*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)capture_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)capture_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
};

static object *
newcaptureobject(self, ptr, mustunlock)
	svobject *self;
	void *ptr;
	int mustunlock;
{
	captureobject *p;

	p = NEWOBJ(captureobject, &Capturetype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = self;
	INCREF(self);
	p->ob_capture = ptr;
	p->ob_mustunlock = mustunlock;
	p->ob_info = self->ob_info;
	return (object *) p;
}

static object *
sv_GetCaptureData(self, args)
	svobject *self;
	object *args;
{
	void *ptr;
	long fieldID;
	object *res, *c;

	if (!getnoarg(args))
		return NULL;

	if (svGetCaptureData(self->ob_svideo, &ptr, &fieldID))
		return sv_error();

	if (ptr == NULL) {
		err_setstr(SvError, "no data available");
		return NULL;
	}

	c = newcaptureobject(self, ptr, 1);
	if (c == NULL)
		return NULL;
	res = mkvalue("(Oi)", c, fieldID);
	DECREF(c);
	return res;
}

static object *
sv_BindGLWindow(self, args)
	svobject *self;
	object *args;
{
	long wid;
	int mode;

	if (!getargs(args, "(ii)", &wid, &mode))
		return NULL;

	if (svBindGLWindow(self->ob_svideo, wid, mode))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_EndContinuousCapture(self, args)
	svobject *self;
	object *args;
{

	if (!getnoarg(args))
		return NULL;

	if (svEndContinuousCapture(self->ob_svideo))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_IsVideoDisplayed(self, args)
	svobject *self;
	object *args;
{
	int v;

	if (!getnoarg(args))
		return NULL;

	v = svIsVideoDisplayed(self->ob_svideo);
	if (v == -1)
		return sv_error();

	return newintobject((long) v);
}

static object *
sv_OutputOffset(self, args)
	svobject *self;
	object *args;
{
	int x_offset;
	int y_offset;

	if (!getargs(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svOutputOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_PutFrame(self, args)
	svobject *self;
	object *args;
{
	char *buffer;

	if (!getargs(args, "s", &buffer))
		return NULL;

	if (svPutFrame(self->ob_svideo, buffer))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_QuerySize(self, args)
	svobject *self;
	object *args;
{
	int w;
	int h;
	int rw;
	int rh;

	if (!getargs(args, "(ii)", &w, &h))
		return NULL;

	if (svQuerySize(self->ob_svideo, w, h, &rw, &rh))
		return sv_error();

	return mkvalue("(ii)", (long) rw, (long) rh);
}

static object *
sv_SetSize(self, args)
	svobject *self;
	object *args;
{
	int w;
	int h;

	if (!getargs(args, "(ii)", &w, &h))
		return NULL;

	if (svSetSize(self->ob_svideo, w, h))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_SetStdDefaults(self, args)
	svobject *self;
	object *args;
{

	if (!getnoarg(args))
		return NULL;

	if (svSetStdDefaults(self->ob_svideo))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_UseExclusive(self, args)
	svobject *self;
	object *args;
{
	boolean onoff;
	int mode;

	if (!getargs(args, "(ii)", &onoff, &mode))
		return NULL;

	if (svUseExclusive(self->ob_svideo, onoff, mode))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_WindowOffset(self, args)
	svobject *self;
	object *args;
{
	int x_offset;
	int y_offset;

	if (!getargs(args, "(ii)", &x_offset, &y_offset))
		return NULL;

	if (svWindowOffset(self->ob_svideo, x_offset, y_offset))
		return sv_error();

	INCREF(None);
	return None;
}

static object *
sv_CaptureBurst(self, args)
	svobject *self;
	object *args;
{
	int bytes, i;
	svCaptureInfo info;
	void *bitvector = NULL;
	object *videodata, *bitvecobj, *res;
	static object *evenitem, *odditem;

	if (!getargs(args, "(iiiii)", &info.format, &info.width, &info.height,
		     &info.size, &info.samplingrate))
		return NULL;

	switch (info.format) {
	case SV_RGB8_FRAMES:
		bitvector = malloc(SV_BITVEC_SIZE(info.size));
		break;
	case SV_YUV411_FRAMES_AND_BLANKING_BUFFER:
		break;
	default:
		err_setstr(SvError, "illegal format specified");
		return NULL;
	}

	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes)) {
		if (bitvector)
			free(bitvector);
		return sv_error();
	}

	videodata = newsizedstringobject(NULL, bytes);
	if (videodata == NULL) {
		if (bitvector)
			free(bitvector);
		return NULL;
	}

	/* XXX -- need to do something about the bitvector */
	if (svCaptureBurst(self->ob_svideo, &info, getstringvalue(videodata),
			   bitvector)) {
		if (bitvector)
			free(bitvector);
		DECREF(videodata);
		return sv_error();
	}

	if (bitvector) {
		if (evenitem == NULL) {
			evenitem = newintobject(0);
			if (evenitem == NULL) {
				free(bitvector);
				DECREF(videodata);
				return NULL;
			}
		}
		if (odditem == NULL) {
			odditem = newintobject(1);
			if (odditem == NULL) {
				free(bitvector);
				DECREF(videodata);
				return NULL;
			}
		}
		bitvecobj = newtupleobject(2 * info.size);
		if (bitvecobj == NULL) {
			free(bitvecobj);
			DECREF(videodata);
			return NULL;
		}
		for (i = 0; i < 2 * info.size; i++) {
			if (SV_GET_FIELD(bitvector, i) == SV_EVEN_FIELD) {
				INCREF(evenitem);
				settupleitem(bitvecobj, i, evenitem);
			} else {
				INCREF(odditem);
				settupleitem(bitvecobj, i, odditem);
			}
		}
		free(bitvector);
	} else {
		bitvecobj = None;
		INCREF(None);
	}

	res = mkvalue("((iiiii)OO)", info.format, info.width, info.height,
		       info.size, info.samplingrate, videodata, bitvecobj);
	DECREF(videodata);
	DECREF(bitvecobj);
	return res;
}

static object *
sv_CaptureOneFrame(self, args)
	svobject *self;
	object *args;
{
	svCaptureInfo info;
	int format, width, height;
	int bytes;
	object *videodata, *res;
	
	if (!getargs(args, "(iii)", &format, &width, &height))
		return NULL;
	info.format = format;
	info.width = width;
	info.height = height;
	info.size = 0;
	info.samplingrate = 0;
	if (svQueryCaptureBufferSize(self->ob_svideo, &info, &bytes))
		return sv_error();
	videodata = newsizedstringobject(NULL, bytes);
	if (videodata == NULL)
		return NULL;
	if (svCaptureOneFrame(self->ob_svideo, format, &width, &height,
			      getstringvalue(videodata))) {
		DECREF(videodata);
		return sv_error();
	}

	res = mkvalue("(iiO)", width, height, videodata);
	DECREF(videodata);
	return res;
}

static object *
sv_InitContinuousCapture(self, args)
	svobject *self;
	object *args;
{
	svCaptureInfo info;

	if (!getargs(args, "(iiiii)", &info.format, &info.width, &info.height,
		     &info.size, &info.samplingrate))
		return NULL;

	if (svInitContinuousCapture(self->ob_svideo, &info))
		return sv_error();

	self->ob_info = info;

	return mkvalue("(iiiii)", info.format, info.width, info.height,
		       info.size, info.samplingrate);
}

static object *
sv_LoadMap(self, args)
	svobject *self;
	object *args;
{
	object *rgb, *v, *cell;
	rgb_tuple *mapp;
	int maptype;
	int i, j;		/* indices */

	if (!getargs(args, "(iO)", &maptype, &rgb))
		return NULL;
	if (!is_listobject(rgb) || getlistsize(rgb) != 256) {
		err_badarg();
		return NULL;
	}
	mapp = NEW(rgb_tuple, 256);
	if (mapp == NULL)
		return err_nomem();
	for (i = 0; i < 256; i++) {
		v = getlistitem(rgb, i);
		if (!is_tupleobject(v) || gettuplesize(v) != 3) {
			DEL(mapp);
			err_badarg();
			return NULL;
		}
		for (j = 0; j < 3; j++) {
			cell = gettupleitem(v, j);
			if (!is_intobject(cell)) {
				DEL(mapp);
				err_badarg();
				return NULL;
			}
			switch (j) {
			case 0: mapp[i].red = getintvalue(cell); break;
			case 1: mapp[i].blue = getintvalue(cell); break;
			case 2: mapp[i].green = getintvalue(cell); break;
			}
		}
	}

	if (svLoadMap(self->ob_svideo, maptype, mapp)) {
		DEL(mapp);
		return sv_error();
	}

	DEL(mapp);

	INCREF(None);
	return None;
}
		
static object *
sv_CloseVideo(self, args)
	svobject *self;
	object *args;
{
	if (!getnoarg(args))
		return NULL;

	if (svCloseVideo(self->ob_svideo))
		return sv_error();
	self->ob_svideo = NULL;

	INCREF(None);
	return None;
}

static object *
doParams(self, args, func, modified)
	svobject *self;
	object *args;
	int (*func)(SV_nodeP, long *, int);
	int modified;
{
	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);
	}

	if ((*func)(self->ob_svideo, PVbuffer, length)) {
		DEL(PVbuffer);
		return sv_error();
	}

	if (modified) {
		for (i = 0; i < length; i++)
			setlistitem(list, i, newintobject(PVbuffer[i]));
	}

	DEL(PVbuffer);

	INCREF(None);
	return None;
}

static object *
sv_GetParam(self, args)
	object *self, *args;
{
	return doParams(self, args, svGetParam, 1);
}

static object *
sv_GetParamRange(self, args)
	object *self, *args;
{
	return doParams(self, args, svGetParamRange, 1);
}

static object *
sv_SetParam(self, args)
	object *self, *args;
{
	return doParams(self, args, svSetParam, 0);
}

static struct methodlist svideo_methods[] = {
	{"BindGLWindow",	(method)sv_BindGLWindow},
	{"EndContinuousCapture",(method)sv_EndContinuousCapture},
	{"IsVideoDisplayed",	(method)sv_IsVideoDisplayed},
	{"OutputOffset",	(method)sv_OutputOffset},
	{"PutFrame",		(method)sv_PutFrame},
	{"QuerySize",		(method)sv_QuerySize},
	{"SetSize",		(method)sv_SetSize},
	{"SetStdDefaults",	(method)sv_SetStdDefaults},
	{"UseExclusive",	(method)sv_UseExclusive},
	{"WindowOffset",	(method)sv_WindowOffset},
	{"InitContinuousCapture",(method)sv_InitContinuousCapture},
	{"CaptureBurst",	(method)sv_CaptureBurst},
	{"CaptureOneFrame",	(method)sv_CaptureOneFrame},
	{"GetCaptureData",	(method)sv_GetCaptureData},
	{"CloseVideo",		(method)sv_CloseVideo},
	{"LoadMap",		(method)sv_LoadMap},
	{"GetParam",		(method)sv_GetParam},
	{"GetParamRange",	(method)sv_GetParamRange},
	{"SetParam",		(method)sv_SetParam},
	{NULL,			NULL} 		/* sentinel */
};

static object *
sv_conversion(self, args, function, inputfactor, factor)
	object *self, *args;
	void (*function)();
	int inputfactor;
	float factor;
{
	int invert, width, height, inputlength;
	char *input;
	object *output;

	if (!getargs(args, "(is#ii)", &invert, &input, &inputlength, &width, &height))
		return NULL;

	if (width * height * inputfactor > inputlength) {
		err_setstr(SvError, "input buffer not long enough");
		return NULL;
	}

	output = newsizedstringobject(NULL, (int) (width * height * factor));
	if (output == NULL)
		return NULL;

	(*function)(invert, input, getstringvalue(output), width, height);

	return output;
}

static object *
sv_InterleaveFields(self, args)
	object *self, *args;
{
	return sv_conversion(self, args, svInterleaveFields, 1, 1.0);
}

static object *
sv_RGB8toRGB32(self, args)
	object *self, *args;
{
	return sv_conversion(self, args, svRGB8toRGB32, 1, (float) sizeof(long));
}

static object *
sv_YUVtoRGB(self, args)
	object *self, *args;
{
	return sv_conversion(self, args, svYUVtoRGB, 2, (float) sizeof(long));
}

static void
svideo_dealloc(self)
	svobject *self;
{
	if (self->ob_svideo != NULL)
		(void) svCloseVideo(self->ob_svideo);
	DEL(self);
}

static object *
svideo_getattr(self, name)
	svobject *self;
	char *name;
{
	return findmethod(svideo_methods, (object *)self, name);
}

typeobject Svtype = {
	OB_HEAD_INIT(&Typetype)
	0,			/*ob_size*/
	"sv",			/*tp_name*/
	sizeof(svobject),	/*tp_size*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)svideo_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)svideo_getattr, /*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
};

static object *
newsvobject(svp)
	SV_nodeP svp;
{
	svobject *p;

	p = NEWOBJ(svobject, &Svtype);
	if (p == NULL)
		return NULL;
	p->ob_svideo = svp;
	p->ob_info.format = 0;
	p->ob_info.size = 0;
	p->ob_info.width = 0;
	p->ob_info.height = 0;
	p->ob_info.samplingrate = 0;
	return (object *) p;
}

static object *
sv_OpenVideo(self, args)
	object *self, *args;
{
	SV_nodeP svp;

	if (!getnoarg(args))
		return NULL;

	svp = svOpenVideo();
	if (svp == NULL)
		return sv_error();

	return newsvobject(svp);
}

static struct methodlist sv_methods[] = {
	{"InterleaveFields",	(method)sv_InterleaveFields},
	{"RGB8toRGB32",		(method)sv_RGB8toRGB32},
	{"YUVtoRGB",		(method)sv_YUVtoRGB},
	{"OpenVideo",		(method)sv_OpenVideo},
	{NULL,			NULL}	/* Sentinel */
};

void
initsv()
{
	object *m, *d;

	m = initmodule("sv", sv_methods);
	d = getmoduledict(m);

	SvError = newstringobject("sv.error");
	if (SvError == NULL || dictinsert(d, "error", SvError) != 0)
		fatal("can't define sv.error");
}
