/*===========================================================================
  Copyright (C) 1995-2009 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*
 * HEADER : tekdrv.c       - Vers 3.6.002  - Sep 1993 -  L. Fini, F. Tribioli
 *                         - Vers 3.6.001  - Jan 1992 -  L. Fini, F. Tribioli

 *  Generalized AGL device driver for "Tektronix like" devices

 *  This driver can control any device emulating a tektronix 401x or 41xx,
 *  provided device dependent sequences are stored in a file on the AGL
 *  standard directory. Sequences are stored in the file as decimal integer
 *  values with a terminating value 0.
 *  The first line of the file must be a string equal to either tt, if the
 *  device is a terminal, or to any name to be used as output file name
 *  template (the full file name will be obtained by appending to the
 *  template a number (0,1,...).
 *  The second line must contain physical dimensions of device, the number
 *  of line styles allowed (ignored since ver. 3.3 of AGL) and an optional
 *  parameter for the number of colors allowed. When this parameter is there
 *  a line must be added to the end of the file with the escape sequence
 *  needed to change drawing color.

 *  E.g.: for the plain tektronix 4010 the caps file will be as follows:
 *
 *  tt                     # The device is a terminal
 *  18 12 0                # Screen dimensions , number of line styles (*)
 *  0                      # Initialization string
 *  29 0                   # set the graphic mode
 *  31 0                   # Reset alpha mode
 *  29 27 26 0             # Enable cursor
 *  29 27 12 31 0          # Erase screen
 *  0                      # Termination string
 
 *  For the QMS laser printer in Tektronix emulation mode:

 *  QMSPLOT                # Output to the file QMSPLOT.n
 *  26.0 19.8 0            # Paper sheet dimensions, number of line styles
 *  94 80 89 94 95 10 94   # Initialization sequence (long sequences may be
 *  73 71 84 94 95 10 94   # Subdivided into more than a single line)
 *  80 78 94 95 10 0       # End of initialization sequence
 *  22 29 0                # Set the graphic mode
 *  27 10 0                # Reset alpha mode
 *  0                      # Enable cursor (unsupported)
 *  27 12 0                # Erase screen (newpage)
 *  94 80 89 94 95 10 94   # Termination sequence
 *  73 71 69 94 95 10 94
 *  80 78 94 95 10 0       # End of termination sequence
 
 *  For the tektronix 41xx-42xx (color terminals):

 * tt                      # Output to terminal
 * 18 12 0 16              # Screen dim., # of line styles, # of colors
 * 27 37 33 48 0           # Initialization sequence
 * 29 0                    # Set graphic mode
 * 31 0                    # Reset alpha mode
 * 29 27 26 0              # Enable cursor
 * 29 27 12 31 0           # Erase screen
 * 27 37 33 49 0           # Termination sequence (reset ansi mode)
 * 27 77 76 0              # Escape sequence to change color

 * (*) the number of line styles on line 2 of device file is actually
 *     ignored since vers. 3.3 of AGL

 *  The device is selected via the string passed to init service: if the
 *  is (e.g.:) tt\0vt640\0\0, then the file /agl/vt640.cap is used
 *  This means that the device is declared as: tt:tkg.vt640 in the AGLDEV.DAT
 *  file
 */

/*
.VERSION

090630		last modif
*/

#include <aglsys.h>
#include <aglerror.h>
#include <agldcom.h>
#include <agldcaps.h>
#include <proto_agl.h>

#define TRUE  1
#define FALSE 0

/*                                                                           */
/*  The following entry points have been defined:                            */
/*                                                                           */
/*  Function    Entry point                                                  */
/*                                                                           */
/*  Initialize  AGLINTKG                                                     */
/*  Cursor en.  AGLCUTKG                                                     */
/*  Erase       AGLERTKG                                                     */
/*  Escape      AGLESTKG                                                     */
/*  Polyline    AGLPLTKG                                                     */
/*  Flush buff. AGLSETKG                                                     */
/*  Finish      AGLTETKG                                                     */
/*                                                                           */

#define TKGDEFBAKGRN	TKGWHITE		/* Default Background */
#define TKGDEFFORGRN	TKGBLACK		/* Default foreground */


static struct              /* Character buffer                               */
  {
   char *BUFPNT;
   char DRVBUF [80];
  }                       AGLDVBUF;

#define USEFULBUF 70    

#define BUFGRD  (AGLDVBUF.DRVBUF+USEFULBUF)      /*  Buffer limit for tests  */

#define CVTX(c) ((int)((c)*TKGFACTX+0.5));
#define CVTY(c) ((int)((c)*TKGFACTY+0.5));
#define INVCVTX(c) ((c)*TKGINPX);
#define INVCVTY(c) ((c)*TKGINPY);

/******************* Tektronix 4010 Characteristics **************************/

#define VERSCODE 36			/* Declare driver version            */


#define TKGXPIXEL   1024
#define TKGYPIXEL   780
#define TKGCLR01    1
#define TKGCLR02    2
#define TKGCLR03    3
#define TKGNWIDTH   0

#define TKGBLACK    0
#define TKGRED      1
#define TKGGREEN    2
#define TKGBLUE     4
#define TKGYELLOW   6
#define TKGMAGENTA  3
#define TKGCYAN     7
#define TKGWHITE    15

#define CHARMULT  1.50

#define TKGFACTX   1023.0           /* Normalized to device coordinate      */
#define TKGFACTY   779.0            /*                conversion factors    */

#define TKGINPX   0.0009775171      /* Device to normalized coordinate      */
#define TKGINPY   0.001283697       /*                conversion factors    */

#define MOVE   29
#define DRAW   0

/*****************************************************************************/
/*                           global status variables                         */

/*  The driver allows NDEVS different tektronix like devices to be accessed  */
/*  at the same time                                                         */

#define NDEVS 2              /* Number of tek-alike devices concurr. open    */
#define CMDBUFLNG 100        /* Space for commands for each device           */

static int isterm[NDEVS];
static int tkflags[NDEVS];
static FILE *channel[NDEVS] = { NULL, NULL };
static FILE *inchann[NDEVS];
static int color[NDEVS] = { TKGCLR01, TKGCLR01 };
static char *init[NDEVS];
static char *graph[NDEVS]; 
static char *alpha[NDEVS];
static char *tenable[NDEVS];
static char *erase[NDEVS];
static char *term[NDEVS];
static int ncolors[NDEVS];
static char *changecolor[NDEVS];
static char cmdbuf[NDEVS][CMDBUFLNG];

static int untouched[NDEVS];

static FILE *chn;                         /* current file pointer            */

static float xleng,yleng;

/*****************************************************************************/
/*                           generic static variables                        */

static int sendflg;                 /* Buffer not empty flag                 */
static char check[4];               /* Tektronix command character buffer    */
static char iplt[4];

/*************************************************************************   */
static char *fgetnxt(buf,curlng,filpt)  /* get the next line from caps file  */
                                        /* and puts data into the command    */
                                        /* buffer, followed by 0             */
                                        /* Returns pointer to first free     */
                                        /* byte of buffer                    */
 char *buf;                             /* Pointer to first byte of buffer   */
 int  *curlng;                          /* Remaining buffer length           */
 FILE *filpt;                           /* caps file pointer                 */
 {
  int aux;
  char line[132];
  char *pt;

  if(buf==NULL) return buf;

  if(*curlng==0) return NULL;

  pt=AG_GETS(line,132,filpt);
  if(pt==NULL) return NULL;

  do
   {
    int n;
    n=sscanf(pt,"%d",&aux);
    if(n==EOF) 
     {
      pt=AG_GETS(line,132,filpt);
      if(pt==NULL) return NULL;
     }
    else
     {
      *buf = aux;
      (*curlng)--;
      if(aux==0) break;
      buf++;
      while(*pt) if(isspace(*pt)) break; else pt++;  /* scan to next blank */
      while(*pt) if(!isspace(*pt))break; else pt++;  /* scan to next non blnk */
     }
   }
  while(*curlng>0);

  buf++;
  return (buf);
 }

static int setdev(AGLDVCOM)  /* Set up device info at open. Return dev idx   */
 struct bufcom *AGLDVCOM;
 {
  char *pt;
  char *cmdbufpt;
  int bufspace;
  int i,npar,dummy;
  FILE *filpt;
  char aux[PHNAMLNG];

  for(i=0; i<NDEVS; i++)                   /* search device slot             */
   {
    if ( channel[i] == NULL ) break;
   }

  if(i>=NDEVS)
   {                                       /* No free slot for the device    */
    ERRCODE=DEVOPNSEV;
    return(-1);
   }

  pt=CHARBUF+strlen(CHARBUF)+1;            /* Skip to device type            */

  filpt=AG_STDO(pt,".cap",0);              /* Open caps file                 */
  if(filpt==NULL) { ERRCODE=CAPOPNSEV; return (-1); }

  {
   char line[132];
   char *pt;

   pt=AG_GETS(line,132,filpt);

   sscanf(pt,"%s",aux);                    /* Get device type                */

   AG_DMSG("1st line:",aux);

   if(strncmp(aux,"tt",2)==0)
    {                                     /*  The device is a terminal       */
     tkflags[i]=INTERACTIVE|ERASEIT;
     strcpy(aux,CHARBUF);                 /* get device name from call buff. */
     AG_DMSG("Out to:",aux);
     channel[i]=AGL_fopen(aux);             /* Open the device                 */

     if(channel[i] == stdout)             /* Fix for OS which don't allow    */
      inchann[i] = stdin;                 /* to read from stdout             */
     else
      inchann[i] = channel[i];

     isterm[i] = TRUE;                     /* Signal it is a terminal         */
     *CHARBUF='\0';
    }
   else
    {                                 /* The device is spooled                */
     tkflags[i]=SEPALPHA;
 
     AG_NEWN(aux);

     if(*aux == '\0')
      {
       ERRCODE=DEVOPNSEV;
       return(-1);
      }

     strcpy(CHARBUF,aux);                    /* pass back file name           */
     AG_DMSG("Out to:",aux);
     channel[i]=fopen(aux,B_CREATE);        /* Open the file                  */
     isterm[i] = FALSE;                     /* Signal it is a file            */
     untouched[i]=TRUE;
    }

   if(channel[i]==NULL) { ERRCODE = DEVOPNSEV; return(-1); }

   pt=AG_GETS(line,132,filpt);
                              /* Read screen dimensions, line style (not used)*/
                              /* and number of colors (optional)              */
   npar=sscanf(pt, "%f %f %d %d", &xleng, &yleng, &dummy, &ncolors[i]);
  }

  bufspace = CMDBUFLNG;
  cmdbufpt = cmdbuf[i];
  init[i] = cmdbufpt;
  cmdbufpt=fgetnxt(init[i],&bufspace,filpt);
  graph[i]=cmdbufpt;
  cmdbufpt=fgetnxt(graph[i],&bufspace,filpt);
  alpha[i]=cmdbufpt;
  cmdbufpt=fgetnxt(alpha[i],&bufspace,filpt);
  tenable[i]=cmdbufpt;
  cmdbufpt=fgetnxt(tenable[i],&bufspace,filpt);
  erase[i]=cmdbufpt;
  cmdbufpt=fgetnxt(erase[i],&bufspace,filpt);
  term[i]=cmdbufpt;
  cmdbufpt=fgetnxt(term[i],&bufspace,filpt);
  if(npar==4)			/* color parameter is present in .cap file   */
   {
    ncolors[i]--;
    if(ncolors[i]<1) ncolors[i]=1;	/* check for correct values          */
    changecolor[i]=cmdbufpt;
    cmdbufpt=fgetnxt(changecolor[i],&bufspace,filpt);
   }
  else
   ncolors[i]=1;                /* B/W terminal (no color parameter present) */

  fclose(filpt);

  if(cmdbufpt==NULL)
   {
    ERRCODE=CAPRDSEV;
    return(-1);
   }
  else
   return(i);
 }



/*************************************************************************   */
/*                          SEND Buffer Entry points                         */
/*                                                                           */

void AGLSETKG (AGLDVCOM)                      /* send buffer routine         */
 struct bufcom *AGLDVCOM;
 {
  int nbytes;
  int curchn;

  curchn=CHANNEL;
  chn = channel[curchn];

  if (sendflg)
   {
    char *pt = alpha[curchn];

    while ( *pt ) *AGLDVBUF.BUFPNT++ = *pt++;     /* set epilog command   */

    nbytes=AGLDVBUF.BUFPNT-AGLDVBUF.DRVBUF;       /* Compute buffer leng.    */
    AGLDVBUF.BUFPNT = AGLDVBUF.DRVBUF;            /* Reset buffer pointer    */

    if(isterm[curchn])                               /* Send the buffer      */
     {
      AGL_fwrite(AGLDVBUF.BUFPNT,1,nbytes,chn);
      AGL_fflush(chn);
     }
    else
      fwrite(AGLDVBUF.BUFPNT,1,nbytes,chn);

    pt = graph[curchn];
    while(*pt) *AGLDVBUF.BUFPNT++ = *pt++;         /* Preset prolog command   */

    if ( check[0] != 0 )                          /* Preset for a dummy      */
     {                                            /* move to the last        */
      *AGLDVBUF.BUFPNT++ = MOVE;                  /* point, if not the       */
      *AGLDVBUF.BUFPNT++ = iplt[0];              /* first buffer            */
      *AGLDVBUF.BUFPNT++ = iplt[1];
      *AGLDVBUF.BUFPNT++ = iplt[2];
      *AGLDVBUF.BUFPNT++ = iplt[3];
     }
   }
  sendflg = FALSE;
  ERRCODE=AGLNOERR;
 }


/*************************************************************************   */
/*                          Generic move/draw routine                        */
/*                                                                           */

static void movtra (curchn,xx,yy,code,AGLDVCOM)
int curchn;
float xx,yy;
int code;
struct bufcom *AGLDVCOM;
{
static int ix0=(-1), iy0;    /* Previous point memory to avoid retracing */
int ix1,iy1;

if(color[curchn]==TKGDEFBAKGRN) return;      /* emulate null color drawing  */

ix1 = CVTX(xx);
iy1 = CVTY(yy);

if((ix1==ix0)&&(iy1==iy0))     			/* Test if same point   */
	return;

if ( AGLDVBUF.BUFPNT > BUFGRD )
	AGLSETKG(AGLDVCOM);

if ( code==MOVE ) 
	*AGLDVBUF.BUFPNT++ = code;		/* put raise "pen" code      */
else
	untouched[curchn]=FALSE;

						/* Compute plot characters   */
						/*       to get to ix, iy    */
						/* Order is:                 */
						/*       HIY, LOY, HIX, LOX  */
ix0=ix1; iy0=iy1;

iplt[0] = ((iy0>>5) & 037) | 040;
iplt[1] =  (iy0 & 037) | 0140;
iplt[2] = ((ix0>>5) & 037) | 040;
iplt[3] =  (ix0 & 037) | 0100;

						/* Optimize output           */
						/*        string length      */

if(check[0]!=iplt[0]) {				/* Include HIY               */
	check[0] = iplt[0];
	*AGLDVBUF.BUFPNT++ = iplt[0];
}

if((check[1]!=iplt[1])||(check[2]!=iplt[2])) {	/* Include LOY          */
	check[1] = iplt[1];
	*AGLDVBUF.BUFPNT++ = iplt[1];
}

if(check[2]!=iplt[2]) {				/* Include HIX               */
	check[2] = iplt[2];
	*AGLDVBUF.BUFPNT++ = iplt[2];
}
check[3] = iplt[3]; 				/* Include LOX               */
*AGLDVBUF.BUFPNT++ = iplt[3];

if(code==MOVE) 					/* "forget" point if MOVE    */
	ix0= -1;

sendflg = TRUE;				/* Set buffer not empty flag    */
}


/*****************************************************************************/
/*                          CURSOR READ Entry points                         */

void AGLCUTKG (AGLDVCOM)               /* Enable cursor and read position    */
 struct bufcom *AGLDVCOM;
 {
  int nread,flag,exprd;
  int curchn;
  char cbuf[5];
  void AGL_setraw();
  void AGL_reset();

  curchn = CHANNEL;

  if( !(isterm[curchn]) )
   {
    ERRCODE=UNSFEATINF;
    return;
   }

  chn = channel[curchn];

  flag = (IBUFFR(1)>=0);                  /* Get cursor enable flag        */

  if(isterm[curchn])
   {
    AGL_setraw(inchann[curchn]);            /* Defined in <sys>dep.c file   */
   }

  if (flag) 
   {
    int len,cnt;
    char *pt=cbuf;

    len = strlen(tenable[curchn]);
    AGL_fwrite(tenable[curchn],1,len,chn);                 /* Enable cursor  */ 
    AGL_fflush(chn);
    exprd=5;                        /* Number of chars sent when keypressed */
    for(nread=0;nread<exprd;pt++,nread++)
     {
      cnt=AGL_fread(pt,sizeof(char),1,inchann[curchn]);  /* Read data      */
      if(cnt != 1) break;
      *(pt) &= 0x7f;                            /* Clean parity etc.        */
     }
    len = strlen(alpha[curchn]);
    AGL_fwrite(alpha[curchn],1,len,chn);          /* Restore alpha mode      */
    AGL_fflush(chn);
   }
  else
   {
    exprd=1;
    nread=AGL_fread(cbuf,sizeof(char),1,inchann[curchn]);  /* Read data      */
    *(cbuf) &= 0x7f;                            /* Clean parity etc.        */
   }

  if(isterm[curchn])
   {
    AGL_reset(inchann[curchn]);              /* Defined in <sys>dep.c file   */
   }

  if ( nread != exprd ) { ERRCODE = DEVIOSEV; return; }

  if(flag)
   {  
    int ixx,iyy;
    ixx = ((cbuf[1]&037)<<5)|(cbuf[2]&037);
    iyy = ((cbuf[3]&037)<<5)|(cbuf[4]&037);
 
    RBUFFR(0) = INVCVTX(ixx);
    RBUFFR(1) = INVCVTY(iyy);
    IBUFFR(2) = 0;                 /* Return pixel value is not supported  */
   }
  
  IBUFFR(1) = cbuf[0];
  ERRCODE = AGLNOERR;
 }


/*****************************************************************************/
/*                          ERASE SCREEN Entry points                        */
/*                                                                           */

void AGLERTKG (AGLDVCOM) 
 struct bufcom *AGLDVCOM;
 {
  int len;
  int curchn;

  curchn = CHANNEL;
  chn = channel[curchn];

  len=strlen(erase[curchn]);

  if(isterm[curchn])                                 /* Send erase  command  */
   {
    AGL_fwrite(erase[curchn],1,len,chn);                 /* Enable cursor  */ 
    AGL_fflush(chn);
   }
  else
   fwrite(erase[curchn],1,len,chn);

  ERRCODE = AGLNOERR;
 }



/*************************************************************************   */
/*                          DEVICE INIT Entry points                         */
/*                                                                           */

void AGLINTKG (AGLDVCOM)             /*  Tektronix 4010 specific init       */
struct bufcom *AGLDVCOM;
{
register int i=1;
register char *ckpt = check;
int curchn;
ERRCODE=AGLNOERR;
switch((int)IBUFFR(0)) {
	case 0:				/* device hardware initialization */
		curchn=setdev(AGLDVCOM);

		if ( curchn != (-1) ) {
			int len;
			char *pt;  

			CHANNEL=curchn;
			len=strlen(init[curchn]);

			if(isterm[curchn])		/* Send init string  */
				AGL_fwrite(init[curchn],1,len,channel[curchn]);
			else
				fwrite(init[curchn],1,len,channel[curchn]);


			AGLDVBUF.BUFPNT = AGLDVBUF.DRVBUF;

			pt = graph[curchn];

			while(*pt) 		/* Preset prolog command   */
				*AGLDVBUF.BUFPNT++ = *pt++;

			while (i++<=4) 		/* Set status buffer      */
				*ckpt++=0;

			sendflg = FALSE;	/* Signal buffer empty    */
		}
		break;
  
	case 1:				/* Pass back device characteristics  */
		curchn = CHANNEL;
		*(CHARBUF) = '\0';

		RBUFFR(0) = xleng;
		RBUFFR(1) = yleng;

		IBUFFR(1) = tkflags[curchn];
		IBUFFR(2) = ncolors[curchn];
		IBUFFR(3) = TKGXPIXEL;
		IBUFFR(4) = TKGYPIXEL;
		IBUFFR(5) = VERSCODE;
		IBUFFR(6) = TKGNWIDTH;

		if(ncolors[curchn] > 1) {
			IBUFFR(7) = TKGDEFBAKGRN;
			IBUFFR(8) = TKGDEFFORGRN;
			IBUFFR(9) = TKGBLACK;
			IBUFFR(10) = TKGRED;
			IBUFFR(11) = TKGGREEN;
			IBUFFR(12) = TKGBLUE;
			IBUFFR(13) = TKGYELLOW;
			IBUFFR(14) = TKGMAGENTA;
			IBUFFR(15) = TKGCYAN;
			IBUFFR(16) = TKGWHITE;
		} else {
			IBUFFR(7) = 0;	/* Default Background */
			IBUFFR(8) = 1;	/* Default foreground */
			IBUFFR(9) = 0;
			IBUFFR(10) = 1;
			IBUFFR(11) = 1;
			IBUFFR(12) = 1;
			IBUFFR(13) = 1;
			IBUFFR(14) = 1;
			IBUFFR(15) = 1;
			IBUFFR(16) = 1;
		}

		RBUFFR(2) = CHARMULT;
		RBUFFR(3) = 0.0;
		RBUFFR(4) = 0.0;
		RBUFFR(5) = 0.0;
		RBUFFR(6) = xleng;
		RBUFFR(7) = yleng;
		RBUFFR(8) = 0.0;
		RBUFFR(9) = 0.0;
		break;

	case 2:                         /* Set color                          */
		curchn=CHANNEL;
		color[curchn]=IBUFFR(1);

		if(ncolors[curchn]>1) {	/* More than 1 color allowed          */
			char *pt;

                                    /* Force color number between limits  */
			if(color[curchn]>ncolors[curchn]) 
				color[curchn]=ncolors[curchn];
			if(color[curchn]<0) 
				color[curchn]=0;

			pt=changecolor[curchn];

			while(*pt) {		/* Put escape seq. to change  */
						/* color in output buffer     */
				if ( AGLDVBUF.BUFPNT > BUFGRD )
					AGLSETKG(AGLDVCOM);
				*AGLDVBUF.BUFPNT++ = *pt++;
			}
			if ( AGLDVBUF.BUFPNT > BUFGRD ) /* Put color number  */
				AGLSETKG(AGLDVCOM);
			*AGLDVBUF.BUFPNT++ = (char) color[curchn]+'0';
		}
		break;

	case  3:			/* set line style and line width     */
		ERRCODE=AGLNOERR;	/* Not used since AGL 3.3            */
		break;

	case 6: {			/* Coordinate roundoff       */
			int ixx,iyy;
			ixx = CVTX(RBUFFR(0));
			iyy = CVTY(RBUFFR(1));
			RBUFFR(0)=INVCVTX(ixx);
			RBUFFR(1)=INVCVTY(iyy);
		}
		break;
        
	default:
		break;             
}
}


/*************************************************************************   */
/*                          ESCAPE function                                  */

void AGLESTKG (AGLDVCOM)
   struct bufcom *AGLDVCOM;
   {
    ERRCODE=UNSFEATINF;
   }



/*************************************************************************   */
/*                          TERMINATE Entry points                           */
/*                                                                           */

void AGLTETKG (AGLDVCOM)
struct bufcom *AGLDVCOM;
{
int curchn;
int len,istat;
extern void AG_DMSG();


curchn=CHANNEL;
chn=channel[curchn];

len=strlen(term[curchn]);
istat = 0;

ERRCODE=AGLNOERR;

if(isterm[curchn]) {				/* Send term string       */
	AGL_fwrite(term[curchn],1,len,chn);
	AGL_fflush(chn);
	if(chn!=stdout) {			/* Don't close std files  */
		istat = AGL_fclose(chn);
		AG_DMSG("Close","out device");
	}
} else {
	fwrite(term[curchn],1,len,chn);
	istat=fclose(chn);
	AG_DMSG("Close","out file");
	IBUFFR(0)=untouched[curchn];
}

if(istat==(-1)) 
	ERRCODE=DEVIOSEV;

channel[curchn] = NULL;
CHANNEL = (-1);
}



/*****************************************************************************/
/*                          DRAW Entry points                                */
/*                                                                           */
/*                                                                           */

void AGLPLTKG (AGLDVCOM)                        /*  Tektronix 4010          */
struct bufcom *AGLDVCOM;
{
int n;
float *vectx, *vecty;
int curchn;

ERRCODE=AGLNOERR;

n=NPOINTS;

if(n<2)
	return;

curchn=CHANNEL;
vectx=VECTX;
vecty=VECTY;

movtra (curchn,(*vectx++),(*vecty++),MOVE,AGLDVCOM);

while(n-->1) 
	movtra (curchn,(*vectx++),(*vecty++),DRAW,AGLDVCOM);
}

