Exemple #1
0
int main (int argc, char **argv)
{
	int nTic1,nTic2,width,height;
	float smin,smax,bclip,wclip,x1beg,x1end,x2beg,x2end;
	char *edgecolor="cyan",*tricolor="yellow",*cmap="gray",
		*label1="",*label2="",*title="",
		*labelFont="",*titleFont="",
		*axesColor="",*gridColor="",*titleColor="",
		*style="seismic",*grid1="none",*grid2="none";
	Model *model;
	XrmValue from,to;
	ExposeCD exposeCD;
	Widget toplevel,axes;
	Display *dpy;
	Window win;
	Arg args[100];
	int nargs;
	float bhue=0,whue=240,sat=1,bright=1;

	/* initialize getpar */
	initargs(argc,argv);
        requestdoc(0);

	
	/* read model */
	model = readModel(stdin);
	
	/* determine minimum and maximum s(x,y) */
	minmax(model,&smin,&smax);
	
	/* get optional parameters */
	getparstring("edgecolor",&edgecolor);
	getparstring("tricolor",&tricolor);
	bclip = smin; getparfloat("bclip",&bclip);
	wclip = smax; getparfloat("wclip",&wclip);
        getparstring("cmap",&cmap);   

	/* initialize toolkit intrinsics and set toplevel parameters */
	toplevel = XtInitialize(argv[0],"Sxplot",NULL,0,&argc,argv);
	nargs = 0;
	if (getparint("width",&width))
		{XtSetArg(args[nargs],XtNwidth,width); nargs++;}
	if (getparint("height",&height))
		{XtSetArg(args[nargs],XtNheight,height); nargs++;}
	XtSetValues(toplevel,args,nargs);

	/* create axes and set axes parameters */
	axes = XtCreateManagedWidget("axes",xtcwpAxesWidgetClass,
		toplevel,NULL,0);


	nargs = 0;
	if (getparstring("grid1",&grid1)) {
		from.addr = (char *)grid1;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesGrid,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgrid1,*((int*)to.addr));
		nargs++;
	}
	if (getparstring("grid2",&grid2)) {
		from.addr = (char *)grid2;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesGrid,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgrid2,*((int*)to.addr));
		nargs++;
	}
	if (getparint("nTic1",&nTic1))
		{XtSetArg(args[nargs],XtNnTic1,nTic1); nargs++;}
	if (getparint("nTic2",&nTic2))
		{XtSetArg(args[nargs],XtNnTic2,nTic2); nargs++;}
	if (getparstring("label1",&label1))
		{XtSetArg(args[nargs],XtNlabel1,label1); nargs++;}
	if (getparstring("label2",&label2))
		{XtSetArg(args[nargs],XtNlabel2,label2); nargs++;}
	if (getparstring("title",&title))
		{XtSetArg(args[nargs],XtNtitle,title); nargs++;}
	if (getparstring("style",&style)) {
		from.size = (unsigned int) strlen(style);  from.addr = (char *)style;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesStyle,&to);
		if (to.addr) XtSetArg(args[nargs],XtNstyle,*((int*)to.addr));
		nargs++;
	}
	if (getparstring("axesColor",&axesColor)) {
		from.addr = (char *)axesColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNaxesColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("gridColor",&gridColor)) {
		from.addr = (char *)gridColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgridColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("titleColor",&titleColor)) {
		from.addr = (char *)titleColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNtitleColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("labelFont",&labelFont)) {
		from.addr = (char *)labelFont;
		XtConvertAndStore(axes,XtRString,&from,XtRFont,&to);
		if (to.addr) XtSetArg(args[nargs],XtNlabelFont,
			*((Font*)to.addr));
		nargs++;
	}
	if (getparstring("titleFont",&titleFont)) {
		from.addr = (char *)titleFont;
		XtConvertAndStore(axes,XtRString,&from,XtRFont,&to);
		if (to.addr) XtSetArg(args[nargs],XtNtitleFont,
			*((Font*)to.addr));
		nargs++;
	}
	XtSetValues(axes,args,nargs);
	x1beg = model->xmin; getparfloat("x1beg",&x1beg);
	x1end = model->xmax; getparfloat("x1end",&x1end);
	x2beg = model->ymin; getparfloat("x2beg",&x2beg);
	x2end = model->ymax; getparfloat("x2end",&x2end);
	XtcwpSetAxesValues(axes,x1beg,x1end,x2beg,x2end);

	/* add callbacks to axes widget */
	XtAddCallback(axes,XtNresizeCallback,(XtCallbackProc) resizeCB,NULL);
	exposeCD.model = model;
	exposeCD.edgecolor = edgecolor;
	exposeCD.tricolor = tricolor;
	exposeCD.bclip = bclip;
	exposeCD.wclip = wclip;
	XtAddCallback(axes,XtNexposeCallback,(XtCallbackProc) exposeCB,&exposeCD);
	XtAddCallback(axes,XtNinputCallback,(XtCallbackProc) inputCB,NULL);

	/* realize widgets */
	XtRealizeWidget(toplevel);

	/* if necessary, create private colormap */
	dpy = XtDisplay(toplevel);
	win = XtWindow(toplevel);

	if (STREQ(cmap,"gray")) {
	  XSetWindowColormap(dpy,win,XtcwpCreateGrayColormap(dpy,win));
	} else if (STREQ(cmap,"hue")) {
	  XSetWindowColormap(dpy,win,XtcwpCreateHueColormap(dpy,win,
														bhue,whue,sat,bright)); /* see Note below */
	}
	
	/* go */
	XtMainLoop();

	return EXIT_SUCCESS;
}
Exemple #2
0
void inputCB (Widget w, 
	ClientData *cd,
	XtcwpAxesCallbackStruct *ca)
/*****************************************************************************
Input event callback - currently handles rubber zoom box and pause on
button 3 only.  Updates dimensions and start indices of bbytes, based
on user-dragged zoom box, and sets both bbytes and image to NULL, so
that expose callback will make new bbytes and image.
*****************************************************************************/
{
	int nxa=cd->nxa,nya=cd->nya,
		nxb=cd->nxb,nyb=cd->nyb,ixb=cd->ixb,iyb=cd->iyb;
	unsigned char *bbytes=cd->bbytes;
	float x1bega=cd->x1bega,x1enda=cd->x1enda,
		x2bega=cd->x2bega,x2enda=cd->x2enda;
	int x=ca->x,y=ca->y,width=ca->width,height=ca->height;
	float x1beg=ca->x1beg,x1end=ca->x1end,x2beg=ca->x2beg,x2end=ca->x2end;
	int style=ca->style;
	XEvent *event=ca->event;
	int xb,yb,wb,hb;
	int nxbn,nybn,ixbn,iybn;
	float x1begn,x1endn,x2begn,x2endn;
	static int stopflag=0;

	/* check for button 2 */
	if (event->type==ButtonRelease && event->xbutton.button==Button2) {
		cd->forward = !cd->forward;
		return;
	}

	/* check for button 3 */
	if (event->type==ButtonRelease && event->xbutton.button==Button3) {
		stopflag = !stopflag;
		if (stopflag) {
			XtRemoveWorkProc(cd->wpid);
		} else {
			cd->wpid = XtAppAddWorkProc(cd->ac,
					(XtWorkProc) readFrame,cd);
		}
		return;
	}

	/* track pointer and get rubber box */
	XtcwpRubberBox(XtDisplay(w),XtWindow(w),*event,&xb,&yb,&wb,&hb);

	/* if zoom box has tiny width or height */
	if (wb<3 || hb<3) {
	
		/* restore number of samples inside box */
		nxbn = nxa;
		nybn = nya;
		
		/* restore indices of first samples inside box */
		ixbn = 0;
		iybn = 0;
		
		/* restore axes limits */
		x1begn = x1bega;
		x1endn = x1enda;
		x2begn = x2bega;
		x2endn = x2enda;
	
	/* else if valid zoom box */
	} else {
	
		/* clip zoom box to lie within axes rectangle */
		if (xb<x) {
			wb -= x-xb;
			xb = x;
		}
		if (yb<y) {
			hb -= y-yb;
			yb = y;
		}
		if (xb+wb>x+width) wb = x-xb+width;
		if (yb+hb>y+height) hb = y-yb+height;
		
		/* determine number of samples inside box (at least 2 by 2) */
		nxbn = 1+NINT((float)wb/width*(nxb-1));
		if (nxbn<2) nxbn = 2;
		nybn = 1+NINT((float)hb/height*(nyb-1));
		if (nybn<2) nybn = 2;
		
		/* determine indices of first samples inside box */
		ixbn = ixb+NINT((float)(xb-x)/width*(nxb-1));
		if (ixbn+nxbn>ixb+nxb) ixbn = ixb+nxb-nxbn;
		iybn = iyb+NINT((float)(yb-y)/height*(nyb-1));
		if (iybn+nybn>iyb+nyb) iybn = iyb+nyb-nybn;
		
		/* determine axes limits */
		if (style==XtcwpNORMAL) {
			x1begn = x1beg+(ixbn-ixb)*(x1end-x1beg)/(nxb-1);
			x1endn = x1beg+(ixbn+nxbn-ixb-1)*(x1end-x1beg)/(nxb-1);
			x2begn = x2end+(iybn+nybn-iyb-1)*(x2beg-x2end)/(nyb-1);
			x2endn = x2end+(iybn-iyb)*(x2beg-x2end)/(nyb-1);
		} else {
			x1endn = x1beg+(iybn+nybn-iyb-1)*(x1end-x1beg)/(nyb-1);
			x1begn = x1beg+(iybn-iyb)*(x1end-x1beg)/(nyb-1);
			x2begn = x2beg+(ixbn-ixb)*(x2end-x2beg)/(nxb-1);
			x2endn = x2beg+(ixbn+nxbn-ixb-1)*(x2end-x2beg)/(nxb-1);
		}
	}
	
	/* set axes limits */
	XtcwpSetAxesValues(w,x1begn,x1endn,x2begn,x2endn);
	
	/* set client data */
	cd->nxb = nxbn;
	cd->nyb = nybn;
	cd->ixb = ixbn;
	cd->iyb = iybn;

	/* if bytes inside box exist, destroy and set pointer to NULL */
	if (bbytes!=NULL) free1(bbytes);
	cd->bbytes = NULL;
	
	/* if image exists, destroy and set pointer to NULL */
	if (cd->image!=NULL) {
		XDestroyImage(cd->image);
		cd->image = NULL;
	}
	
	/* clear window and force an expose event */
	XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,True);
}
Exemple #3
0
void inputCB (Widget w, 
	char * clientdata,
	XtcwpAxesCallbackStruct *ca)
{
	int x=ca->x,y=ca->y,width=ca->width,height=ca->height;
	float x1beg=ca->x1beg,x1end=ca->x1end,x2beg=ca->x2beg,x2end=ca->x2end;
	int style=ca->style;
	XEvent *event=ca->event;
	int xb,yb,wb,hb;
	float x1begn,x1endn,x2begn,x2endn;
	static int firstinput=1;
	static float x1begs,x1ends,x2begs,x2ends;

	/* if first input, save initial axes limits */
	if (firstinput) {
		x1begs = x1beg; 
		x1ends = x1end; 
		x2begs = x2beg;
		x2ends = x2end;
		firstinput = 0;
		clientdata += 0; /* dummy */
	}

	if (event->type==ButtonPress && event->xbutton.button==Button3)
	  { 
		/* JG: requires extra fields in Axes.c's defaultTranslations[] to make this work. Harmless if not */
		exit(0);
	  }
	/* track pointer and get rubber box */
	XtcwpRubberBox(XtDisplay(w),XtWindow(w),*event,&xb,&yb,&wb,&hb);

	/* if new box has zero width or height */
	if (wb==0 || hb==0) {

		/* restore initial limits */
		XtcwpSetAxesValues(w,x1begs,x1ends,x2begs,x2ends);
	
	/* else if non-zero zoom box */
	} else {
	
		/* clip box */
		if (xb<x) {
			wb -= x-xb;
			xb = x;
		}
		if (yb<y) {
			hb -= y-yb;
			yb = y;
		}
		if (xb+wb>x+width) wb = x-xb+width;
		if (yb+hb>y+height) hb = y-yb+height;
	
		/* determine axes limits */
		if (style==XtcwpNORMAL) {
			x1begn = x1beg+(xb-x)*(x1end-x1beg)/width;
			x1endn = x1beg+(xb+wb-x)*(x1end-x1beg)/width;
			x2begn = x2end+(yb+hb-y)*(x2beg-x2end)/height;
			x2endn = x2end+(yb-y)*(x2beg-x2end)/height;
		} else {
			x1endn = x1beg+(yb+hb-y)*(x1end-x1beg)/height;
			x1begn = x1beg+(yb-y)*(x1end-x1beg)/height;
			x2begn = x2beg+(xb-x)*(x2end-x2beg)/width;
			x2endn = x2beg+(xb+wb-x)*(x2end-x2beg)/width;
		}
	
		/* set axes limits */
		XtcwpSetAxesValues(w,x1begn,x1endn,x2begn,x2endn);
	}
	
	/* force an expose event */
	XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,True);
}
Exemple #4
0
int
main (int argc, char **argv)
{
	int n1,n2,nz,iz,verbose,looping,nTic1,nTic2,width,height,interp;
	float d1,f1,d2,f2,*z,
		clip,bclip,wclip,white,wfrac,
		perc,bperc,wperc,*temp,
		bhue,whue,sat,bright,
		x1beg,x2beg,x1end,x2end,
		x1min,x1max,x2min,x2max,
		fframe,dframe;
	char *label1="",*label2="",*format="",*windowtitle="",
		*labelFont="",*titleFont="",
		*axesColor="",*gridColor="",*titleColor="",
		*style="normal",*grid1="none",*grid2="none",
		*cmap;
	ClientData cd;
	XrmValue from,to;
	Widget toplevel,axes;
	XtAppContext ac;
	Display *dpy;
	Window win;
	Arg args[98];
	int nargs;
	int scr;
	unsigned int depth;

	/* initialize getpar */
	initargs(argc,argv);
	requestdoc(1);

	/* get parameters describing colormaps */
	cmap = "gray";  getparstring("cmap",&cmap);
	if (STREQ("saturation",cmap)) cmap = "sat";
	bhue = 0;  getparfloat("bhue",&bhue);  bhue /= 360.0;
	whue = 240;  getparfloat("whue",&whue); whue /= 360.0;
	sat = 1.0; getparfloat("sat",&sat);
	if (sat<0.0 || sat>1.0) err("sat must be in range [0,1]!\n");
	bright = 1.0; getparfloat("bright",&bright);
	if (bright<0.0 || bright>1.0) err("bright must be in range [0,1]!\n");

	/* get parameters describing 1st dimension sampling */
	if (!getparint("n1",&n1))
		err("Must specify number of samples in 1st dimension!\n");
	if (!getparfloat("d1",&d1)) d1 = 1.0;
	if (!getparfloat("f1",&f1)) f1 = 0.0;
	x1min = (d1>0.0)?f1:f1+(n1-1)*d1;
	x1max = (d1<0.0)?f1:f1+(n1-1)*d1;
	if (!getparfloat("x1beg",&x1beg)) x1beg = x1min;
	if (!getparfloat("x1end",&x1end)) x1end = x1max;

	/* get parameters describing 2nd dimension sampling */
	if (!getparint("n2",&n2))
		err("Must specify number of samples in 2nd dimension!\n");
	if (!getparfloat("d2",&d2)) d2 = 1.0;
	if (!getparfloat("f2",&f2)) f2 = 0.0;
	x2min = (d2>0.0)?f2:f2+(n2-1)*d2;
	x2max = (d2<0.0)?f2:f2+(n2-1)*d2;
	if (!getparfloat("x2beg",&x2beg)) x2beg = x2min;
	if (!getparfloat("x2end",&x2end)) x2end = x2max;

	/* read first frame of float data */
	nz = n1*n2;
	z = ealloc1float(nz);
	if (fread(z,sizeof(float),nz,stdin)!=nz)
		err("error reading input file");

	/* if necessary, determine clips from percentiles */
	if (getparfloat("clip",&clip)) {
		bclip = clip;
		wclip = -clip;
	}
	if ((!getparfloat("bclip",&bclip) || !getparfloat("wclip",&wclip)) &&
		!getparfloat("clip",&clip)) {
		perc = 100.0;  getparfloat("perc",&perc);
		temp = ealloc1float(nz);
		for (iz=0; iz<nz; iz++)
			temp[iz] = z[iz];
		if (!getparfloat("bclip",&bclip)) {
			bperc = perc;	getparfloat("bperc",&bperc);
			iz = (nz*bperc/100.0);
			if (iz<0) iz = 0;
			if (iz>nz-1) iz = nz-1;
			qkfind(iz,nz,temp);
			bclip = temp[iz];
		}
		if (!getparfloat("wclip",&wclip)) {
			wperc = 100.0-perc;  getparfloat("wperc",&wperc);
			iz = (nz*wperc/100.0);
			if (iz<0) iz = 0;
			if (iz>nz-1) iz = nz-1;
			qkfind(iz,nz,temp);
			wclip = temp[iz];
		}
		free1float(temp);
	}
	if (!getparfloat("white",&white)) white = (bclip+wclip)/2.0;
	if (!getparint("verbose",&verbose)) verbose = 1;
	if (!getparint("sleep",&cd.sleep)) cd.sleep=0 ;
	if (!getparint("loop",&looping)) looping = 0;
	if (verbose) {
		if(STREQ(cmap,"sat") || STREQ(cmap,"customsat")) {
			warn("bclip=%g wclip=%g white=%g",bclip,wclip,white);
		} else {
			warn("bclip=%g wclip=%g",bclip,wclip);
		}
	}
	wfrac = (bclip!=wclip) ? (bclip-white)/(bclip-wclip) : 1.0;

	/* initialize toolkit and set toplevel parameters */
 	toplevel = XtAppInitialize(&ac,"XMovie_XAPP_DEF",NULL,0,&argc,argv,NULL,NULL,0);
	dpy = XtDisplay(toplevel);
	nargs = 0;
	if (getparstring("windowtitle",&windowtitle))
		{XtSetArg(args[nargs],XtNtitle,windowtitle); nargs++;}
	if (getparstring("windowtitle",&windowtitle))
		{XtSetArg(args[nargs],XtNiconName,windowtitle); nargs++;}
	if (getparint("width",&width))
		{XtSetArg(args[nargs],XtNwidth,width); nargs++;}
	if (getparint("height",&height))
		{XtSetArg(args[nargs],XtNheight,height); nargs++;}
	XtSetArg(args[nargs],XtNinput,TRUE);nargs++; 
	XtSetValues(toplevel,args,nargs);

	/* if necessary, make private colormap */
	win = XRootWindowOfScreen(XtScreen(toplevel));
	nargs = 0;

	scr=DefaultScreen(dpy);
	depth=(unsigned int)DefaultDepth(dpy,scr);

	if (depth<=8) {
	  if (STREQ(cmap,"gray")) {
	    Colormap cm=XtcwpCreateGrayColormap(dpy,win);
	    XtSetArg(args[nargs],XtNcolormap,cm); nargs++;
	  } else if (STREQ(cmap,"hue")) {
	    Colormap cm=XtcwpCreateHueColormap(dpy,win,
					       bhue,whue,sat,bright);
	    XtSetArg(args[nargs],XtNcolormap,cm); nargs++;
	  } else if (STREQ(cmap,"sat")) {
	    Colormap cm=XtcwpCreateSatColormap(dpy,win,
					       bhue,whue,wfrac,bright);

	    XtSetArg(args[nargs],XtNcolormap,cm); nargs++;
	  }
	  XtSetValues(toplevel,args,nargs);
	}

	/* create axes and set axes parameters */
	axes = XtCreateManagedWidget("axes",xtcwpAxesWidgetClass, 
		toplevel,NULL,0);
		
	nargs = 0;

	if (getparstring("grid1",&grid1)) {
		from.addr = (char *)grid1;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesGrid,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgrid1,*((int*)to.addr));
		nargs++;
	}
	if (getparstring("grid2",&grid2)) {
		from.addr = (char *)grid2;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesGrid,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgrid2,*((int*)to.addr));
		nargs++;
	}

	if (getparint("nTic1",&nTic1))
		{XtSetArg(args[nargs],XtNnTic1,nTic1); nargs++;}
	if (getparint("nTic2",&nTic2))
		{XtSetArg(args[nargs],XtNnTic2,nTic2); nargs++;}
	if (getparstring("label1",&label1))
		{XtSetArg(args[nargs],XtNlabel1,label1); nargs++;}
	if (getparstring("label2",&label2))
		{XtSetArg(args[nargs],XtNlabel2,label2); nargs++;}
	if (getparstring("title",&format))
		{XtSetArg(args[nargs],XtNtitle,format); nargs++;}
	if (getparstring("style",&style)) {
		from.size = (unsigned int) strlen(style);  from.addr = (char *)style;
		XtConvertAndStore(axes,XtRString,&from,XtcwpRAxesStyle,&to);
		if (to.addr) XtSetArg(args[nargs],XtNstyle,*((int*)to.addr));
		nargs++;
	}
	if (getparstring("axesColor",&axesColor)) {
		from.addr = (char *)axesColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNaxesColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("gridColor",&gridColor)) {
		from.addr = (char *)gridColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNgridColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("titleColor",&titleColor)) {
		from.addr = (char *)titleColor;
		XtConvertAndStore(axes,XtRString,&from,XtRPixel,&to);
		if (to.addr) XtSetArg(args[nargs],XtNtitleColor,
			*((unsigned long*)to.addr));
		nargs++;
	}
	if (getparstring("labelFont",&labelFont)) {
		from.addr = (char *)labelFont;
		XtConvertAndStore(axes,XtRString,&from,XtRFont,&to);
		if (to.addr) XtSetArg(args[nargs],XtNlabelFont,
			*((Font*)to.addr));
		nargs++;
	}
	if (getparstring("titleFont",&titleFont)) {
		from.addr = (char *)titleFont;
		XtConvertAndStore(axes,XtRString,&from,XtRFont,&to);
		if (to.addr) XtSetArg(args[nargs],XtNtitleFont,
			*((Font*)to.addr));
		nargs++;
	}
	XtSetValues(axes,args,nargs);
	x1beg = x1min; getparfloat("x1beg",&x1beg);
	x1end = x1max; getparfloat("x1end",&x1end);
	x2beg = x2min; getparfloat("x2beg",&x2beg);
	x2end = x2max; getparfloat("x2end",&x2end);
	adjustAxesValues(n1,d1,f1,n2,d2,f2,&x1beg,&x1end,&x2beg,&x2end);
	XtcwpSetAxesValues(axes,x1beg,x1end,x2beg,x2end);

	/* frame sampling */
	if (!getparfloat("fframe",&fframe)) fframe = 1.0;
	if (!getparfloat("dframe",&dframe)) dframe = 1.0;

	/* interpolation */
	if (!getparint("interp",&interp)) interp = 1;

	/* initial display mode: cont or step */
	if (!getparint("idm", &displayMode)) displayMode = DM_CONT;

	checkpars();

	/* initialize client data */
	cd.n1 = n1;  cd.d1 = d1;  cd.f1 = f1;
	cd.n2 = n2;  cd.d2 = d2;  cd.f2 = f2;
	cd.floats = z;
	cd.fmin = bclip;
	cd.fmax = wclip;
	cd.bmin = (unsigned char) (XtcwpGetFirstPixel(dpy));
	cd.bmax = (unsigned char) (XtcwpGetLastPixel(dpy));
	if(cd.bmax==0)cd.bmax=255;
	warn("bmin=%d bmax=%d",cd.bmin,cd.bmax);
	cd.x1bega = x1beg;
	cd.x1enda = x1end;
	cd.x2bega = x2beg;
	cd.x2enda = x2end;
	cd.abytes = NULL;
	cd.bbytes = NULL;
	cd.image = NULL;
	cd.exposed = 0;
	cd.noframes = 1;
	cd.axes = axes;
	cd.looping = looping;
	cd.frame = NULL;
	cd.format = format;
	cd.iframe = 0;
	cd.fframe = fframe;
	cd.dframe = dframe;
	cd.interp = interp;
	cd.forward = 1;
	cd.ac = ac;

	/* adjust axes title if formatted */
	if (strchr(cd.format,'%') && !strstr(cd.format,"%%")) {
		sprintf(cd.title,cd.format,cd.fframe+cd.iframe*cd.dframe);
		XtVaSetValues(cd.axes,XtNtitle,cd.title,NULL);
	}

	/* add work procedure */
	cd.wpid = XtAppAddWorkProc(ac,(XtWorkProc) readFrame,&cd);

	/* add callbacks to axes widget */
	XtAddCallback(axes,XtNresizeCallback,(XtCallbackProc) resizeCB,&cd);
	XtAddCallback(axes,XtNexposeCallback,(XtCallbackProc) exposeCB,&cd);
	XtAddCallback(axes,XtNinputCallback,(XtCallbackProc) inputCB,&cd);

	/* add Button2 translation for reversing the movie */
	XtOverrideTranslations(axes,
		XtParseTranslationTable("<Btn2Up>: input()"));

	/* add Button3 translation for pausing the movie */
	XtOverrideTranslations(axes,
		XtParseTranslationTable("<Btn3Up>: input()"));

	/* set up keypress */
	XtAddEventHandler(axes, KeyPress, FALSE,
			  (XtEventHandler) key_pressed, &cd);

	/* realize everything */
	XtRealizeWidget(toplevel);

	/* go */
	XtAppMainLoop(ac);

	return EXIT_SUCCESS;
}