define(`xSTREAMx',divnum)
divert(-1)
# @(#)Copyright (c), 1987, 1993 StatSci, Inc.  All rights reserved.
divert(xSTREAMx)
ifdef(`INITIALIZE',,`define(`INITIALIZE',`')')
ifdef(`TERMINATE',,`define(`TERMINATE',`')')
#include <signal.h>
#include <setjmp.h>
define(`am',`(F77_COM(bgrp)[($1)-1])')
jmp_buf sjbuf;
char which;
char *getenv();
static confirm();
INCLUDE(u/pipes,device)
define(`LISTEN',`if(istat!=SIG_IGN)signal(SIGINT,onintr)')
define(`DEAF',`signal(SIGINT,SIG_IGN)')

long F77_COM(reshap);

main(argc,argv)
int argc; char *argv[];
{
	long copymode, interact=1, n, n2, zero=0, type, m;
	extern float F77_COM(bgrp)[200];
	int i, first=1, (*istat)(); void onintr();
	float *x,*y,*x2,*y2,xx,yy,pos;
	char *buf,*calloc();
INITIALIZE
	F77_COM(reshap) = 0;
	istat = signal(SIGINT, SIG_IGN);	/* remember initial interrupt status */
	setjmp(sjbuf);	/* save current position */
	while(read(INPIPE,&which,1)>0){
		F77_CALL(zsizez,int=&F77_COM(reshap));
		switch(which){
			case 'C':	/* copy */
				pread(INPIPE,&copymode,sizeof(copymode));
				pread(INPIPE,&n,sizeof(n));
				i=n;
				buf=calloc(i+1,sizeof(char));
				pread(INPIPE,buf,i);
				*(buf+i) = '\0';
				F77_CALL(wcopyz,int=&copymode,char=buf,int=&n); /*set deferred mode*/
				free(buf);
				confirm(which);
				break;
			case 'E':	/* eject */
				LISTEN; F77_CALL(wejecz); if(interact)F77_CALL(zejecz); DEAF;
				confirm(which);
				break;
			case 'X':	/* end eXecution */
				LISTEN; F77_CALL(wwrapz); if(interact)F77_CALL(zwrapz); DEAF;
			case 'W':	/* wrapup (end of this function) */
				confirm(which);
				break;
			case 'L':	/* lines */
			case 'P':	/* points */
			case 'G':	/* polygon */
				pread(INPIPE,&n,sizeof(n));
				i = n;
				x = (float*) calloc(i,sizeof(float));
				y = (float*) calloc(i, sizeof(float));
				pread(INPIPE, x, i*sizeof(float));
				pread(INPIPE, y, i*sizeof(float));
				LISTEN;
				if(which=='L')      { if(interact)F77_CALL(zlinsz,real=x,real=y,int=&n); }
				else if(which=='P') { if(interact)F77_CALL(zpntsz,real=x,real=y,int=&n); }
				else                { if(interact)F77_CALL(zpolyz,real=x,real=y,int=&n); }
				DEAF;
				if(which=='L') F77_CALL(wlinsz,real=x,real=y,int=&n);
				else if(which=='P') F77_CALL(wpntsz,real=x,real=y,int=&n);
				else F77_CALL(wpolyz,real=x,real=y,int=&n);
				free(x); free(y);
				confirm(which);
				write(OUTPIPE,F77_COM(bgrp)+5,2*sizeof(float));	/* update LPP */
				break;
			case 'S':	/* segments */
				pread(INPIPE,&n,sizeof(n));
				i = n;
				x = (float*) calloc(i,sizeof(float));
				y = (float*) calloc(i, sizeof(float));
				x2 = (float*) calloc(i,sizeof(float));
				y2 = (float*) calloc(i, sizeof(float));
				pread(INPIPE, x, i*sizeof(float));
				pread(INPIPE, y, i*sizeof(float));
				pread(INPIPE, x2, i*sizeof(float));
				pread(INPIPE, y2, i*sizeof(float));
				LISTEN; if(interact)F77_CALL(zsegsz,real=x,real=y,real=x2,real=y2,int=&n); DEAF;
				F77_CALL(wsegsz,real=x,real=y,real=x2,real=y2,int=&n); /*deferred*/
				free(x); free(y); free(x2); free(y2);
				confirm(which);
				write(OUTPIPE,F77_COM(bgrp)+5,2*sizeof(float));	/* update LPP */
				break;
			case 'T':	/* text */
				pread(INPIPE,&n,sizeof(n));
				i = n;
				pread(INPIPE,&xx,sizeof(xx));
				pread(INPIPE,&yy,sizeof(yy));
				pread(INPIPE,&pos,sizeof(pos));
				buf = calloc(i,sizeof(char));
				pread(INPIPE,buf,i*sizeof(char));
				LISTEN; if(interact)F77_CALL(ztextz,real=&xx,real=&yy,char=buf,int=&n,real=&pos); DEAF;
				F77_CALL(wtextz,real=&xx,real=&yy,char=buf,int=&n,real=&pos);
				free(buf);
				confirm(which);
				write(OUTPIPE,F77_COM(bgrp)+85,2*sizeof(float));	/* update NCP */
				break;
			case 'D':	/* diff */
				pread(INPIPE,&n,sizeof(n));
				i = n;
				x = (float*) calloc(i,sizeof(float));
				pread(INPIPE,x,i*sizeof(float));
				F77_CALL(amdiff,real=x,int=&n);
				F77_CALL(wdiffz,real=x,int=&n);
				free(x);
				confirm(which);
				break;
			case 'I':	/* initialize */
			case 'M':	/* initialize with parameters */
				if(which=='M'){
					pread(INPIPE,&n,sizeof(n));
					i = n;
					x = (float*) calloc(i>0?i:1, sizeof(float));
					if(i>0) pread(INPIPE, x, i*sizeof(float));
					if(first) F77_CALL(pbegnz,real=x,int=&n);
					free(x);
					}
				else if(which=='I' && first)
					F77_CALL(pbegnz,int=&zero,int=&zero); 
				if(first) {
					first = 0;
					F77_CALL(winitz);
					interact = getenv("BATCH")==NULL;
					interact |= F77_COM(bgrp)[29]==PRINTER;
					interact |= F77_COM(bgrp)[29]==UNIXPLOT;
					interact |= F77_COM(bgrp)[29]==PIC;
					interact |= F77_COM(bgrp)[29]==POSTSCRIPT;
					interact |= F77_COM(bgrp)[29]==IMAGEN;
					}
				pwrite(OUTPIPE,F77_COM(bgrp),200*sizeof(float));
				break;
			case 'Q':	/* query */
				pread(INPIPE, &n2, sizeof(n2)); i = n2;
				x = (float*) calloc(i,sizeof(float));
				y = (float*) calloc(i,sizeof(float));
				LISTEN; if(interact)F77_CALL(zrdpnz,real=x,real=y,int=&n,int=&n2);
				else FATAL(No graphic input in background)
				DEAF;
				confirm(which);
				write(OUTPIPE, &n, sizeof(n)); i = n;
				if(i>0){
					pwrite(OUTPIPE,x,i*sizeof(float));
					pwrite(OUTPIPE,y,i*sizeof(float));
					}
				free(x); free(y);
				break;
			case 'H':	/* general purpose hook */
				pread(INPIPE, &type, sizeof(type));
				pread(INPIPE, &n, sizeof(n));
				x = (float *)calloc(n>0?n:1, sizeof(float));
				if(n > 0)
					pread(INPIPE, x, n*sizeof(float));
				pread(INPIPE, &m, sizeof(m));
				y = (float *)calloc(m>0?m:1, sizeof(float));
				LISTEN;
				if(interact)
					F77_CALL(zhookz,int=&type,real=x,int=&n,real=y,int=&m);
				DEAF;
				write(OUTPIPE, &m, sizeof(m));
				if(m > 0)
					pwrite(OUTPIPE, y, m*sizeof(float));
				free(x); free(y);
				confirm(which);
				break;
			case 'l':	/* string length */
				pread(INPIPE,&n,sizeof(n));
				i = n;
				buf = calloc(i,sizeof(char));
				pread(INPIPE,buf,i*sizeof(char));
				F77_CALL(zlengz,char=buf,real=&xx);
				free(buf);
				confirm(which);
				write(OUTPIPE,&xx,sizeof(float));
				break;
 			default: fprintf(stderr,"Bad operation to device driver: %c\n",which); 
				break;
			}
		}
TERMINATE
}

F77_SUB(zzabt)
{
	DEAF;
	which='A'; write(OUTPIPE,&which,1);
	longjmp(sjbuf,1);
}

void onintr()
{
	DEAF;
	alarm(0);	/* turn off any pending alarm calls */
	F77_CALL(zintrz);	/* special device dependent interrupt  fixer (default calls zflshz) */
	which='B'; write(OUTPIPE,&which,1);	/* signal BREAK */
	longjmp(sjbuf,1);	/* return to top of loop */
}

static confirm(c)
char c;
{
	char Reshaped = 'R';
	if(F77_COM(reshap)) {
		write(OUTPIPE,&Reshaped,1);
		pwrite(OUTPIPE,F77_COM(bgrp),200*sizeof(float));
		F77_COM(reshap) = 0;
		}
	else write(OUTPIPE,&c,1);
}

SCCS_ID(91781,`@(#)'driver.m 3.10 last edit 2/23/93 StatSci. From BASEFILE)
F77_MAIN
