/*
 * $Id: tek.trm,v 1.11 1995/12/20 21:48:14 drd Exp $
 *
 */

/* GNUPLOT - tek.trm */
/*
 * Copyright (C) 1990 - 1993   
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for any purpose with or 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.
 *
 * Permission to modify the software is granted, but not the right to
 * distribute the modified code.  Modifications are to be distributed 
 * as patches to released version.
 *  
 * This software  is provided "as is" without express or implied warranty.
 * 
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *  tek40xx, bitgraph, kermit_color_tek40xx, kermit_mono_tek40xx, selanar
 *  ln03plus
 *
 * AUTHORS
 *   Colin Kelley, Thomas Williams, Russell Lang
 * 
 * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
 * 
 */

/*
 * Modified June 1995 Ian MacPhedran to support newterm format
 */
#define TEK
#define CTEK
#define VTTEK
#define KERMIT
#define SELANAR
#define BITGRAPH

#ifndef GOT_DRIVER_H
#include "driver.h"
#endif /* GOT_DRIVER_H */

#ifdef TERM_REGISTER
register_term(tek40)
#ifdef VTTEK
register_term(vttek)
#endif
#ifdef KERMIT
register_term(kc_tek40)
register_term(km_tek40)
#endif
#ifdef SELANAR
register_term(selanar)
#endif
#ifdef BITGRAPH
register_term(bitgraph)
#endif
#endif /* TERM_REGISTER */

#ifdef TERM_PROTO
TERM_PUBLIC void TEK40init __P((void));
TERM_PUBLIC void TEK40graphics __P((void));
TERM_PUBLIC void TEK40text __P((void));
TERM_PUBLIC void TEK40linetype __P((int linetype));
TERM_PUBLIC void TEK40move __P((unsigned int x, unsigned int y));
TERM_PUBLIC void TEK40vector __P((unsigned int x, unsigned int y));
TERM_PUBLIC void TEK40put_text __P((unsigned int x, unsigned int y, char str[]));
TERM_PUBLIC void TEK40reset __P((void));
TERM_PUBLIC void BG_text __P((void));
TERM_PUBLIC void BG_put_text __P((unsigned int x, unsigned int y, char str[]));
TERM_PUBLIC void KTEK40graphics __P((void));
TERM_PUBLIC void KTEK40Ctext __P((void));
TERM_PUBLIC void KTEK40Clinetype __P((int linetype));
TERM_PUBLIC void KTEK40Mlinetype __P((int linetype));
TERM_PUBLIC void KTEK40reset __P((void));
TERM_PUBLIC void SEL_init __P((void));
TERM_PUBLIC void SEL_graphics __P((void));
TERM_PUBLIC void SEL_text __P((void));
TERM_PUBLIC void SEL_reset __P((void));
TERM_PUBLIC void VTTEK40init __P((void));
TERM_PUBLIC void VTTEK40reset __P((void));
TERM_PUBLIC void VTTEK40linetype __P((int linetype));
TERM_PUBLIC void VTTEK40put_text __P((unsigned int x, unsigned int y, char str[]));
TERM_PUBLIC void CTEK_linetype __P((int linetype));
TERM_PUBLIC void CTEK_move __P((unsigned int x, unsigned int y));
TERM_PUBLIC void CTEK_vector __P((unsigned int x, unsigned int y));

#define GOT_TEK40_PROTO
#endif /* TERM_PROTO */

#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY

#ifdef TEK

#define TEK40XMAX 1024
#define TEK40YMAX 780

#define TEK40XLAST (TEK40XMAX - 1)
#define TEK40YLAST (TEK40YMAX - 1)

#define TEK40VCHAR		25
#define TEK40HCHAR		14
#define TEK40VTIC		11
#define TEK40HTIC		11	

#define HX 0x20		/* bit pattern to OR over 5-bit data */
#define HY 0x20
#define LX 0x40
#define LY 0x60

#define LOWER5 31
#define UPPER5 (31<<5)


TERM_PUBLIC void TEK40init()
{
}


TERM_PUBLIC void TEK40graphics()
{
#ifdef vms
	term_pasthru();
#endif /* vms */
	fprintf(outfile,"\033\014");
/*                   1
	1. clear screen
*/
	(void) fflush(outfile);
	sleep(1);  
	/* sleep 1 second to allow screen time to clear on real 
	   tektronix terminals */
}

TERM_PUBLIC void TEK40text()
{
	TEK40move(0,12);
	fprintf(outfile,"\037");
/*                   1
	1. into alphanumerics
*/
#ifdef vms
	term_nopasthru();
#endif /* vms */
}


TERM_PUBLIC void TEK40linetype(linetype)
int linetype;
{
}

TERM_PUBLIC void TEK40move(x,y)
unsigned int x,y;
{
	(void) putc('\035', outfile);	/* into graphics */
	TEK40vector(x,y);
}


TERM_PUBLIC void TEK40vector(x,y)
unsigned int x,y;
{
	(void) putc((HY | (y & UPPER5)>>5), outfile);
	(void) putc((LY | (y & LOWER5)), outfile);
	(void) putc((HX | (x & UPPER5)>>5), outfile);
	(void) putc((LX | (x & LOWER5)), outfile);
}


TERM_PUBLIC void TEK40put_text(x,y,str)
unsigned int x,y;
char str[];
{
	TEK40move(x,y-11);
	fprintf(outfile,"\037%s\n",str);
}


TERM_PUBLIC void TEK40reset()
{
}

#endif /* TEK */



/* thanks to dukecdu!evs (Ed Simpson) for the BBN BitGraph driver */

#ifdef BITGRAPH

#define BG_XMAX			 	768 /* width of plot area */
#define BG_YMAX			 	768 /* height of plot area */
#define BG_SCREEN_HEIGHT	1024 /* full screen height */

#define BG_XLAST	 (BG_XMAX - 1)
#define BG_YLAST	 (BG_YMAX - 1)

#define BG_VCHAR	16
#define BG_HCHAR	 9
#define BG_VTIC		 8
#define BG_HTIC		 8	


#define BG_init TEK40init

#define BG_graphics TEK40graphics


#define BG_linetype TEK40linetype

#define BG_move TEK40move

#define BG_vector TEK40vector


TERM_PUBLIC void BG_text()
{
	BG_move(0, BG_SCREEN_HEIGHT - 2 * BG_VCHAR);
	fprintf(outfile,"\037");
/*                   1
	1. into alphanumerics
*/
}


TERM_PUBLIC void BG_put_text(x,y,str)
unsigned int x,y;
char str[];
{
	BG_move(x,y-11);
	fprintf(outfile,"\037%s\n",str);
}


#define BG_reset TEK40reset

#endif /* BITGRAPH */


/* Color and Monochrome specials for the MS-DOS Kermit Tektronix Emulator
   by Russell Lang,  eln272v@monu1.cc.monash.oz  */

#ifdef KERMIT

#define KTEK40HCHAR		13

TERM_PUBLIC void KTEK40graphics()
{
#ifdef vms
        term_mode_tek();
	term_pasthru();
#endif /* vms */
	fprintf(outfile,"\033\014");
/*                   1
	1. clear screen
*/
	/* kermit tektronix emulation doesn't need to wait */
}

TERM_PUBLIC void KTEK40Ctext()
{
	TEK40text();
	KTEK40Clinetype(0);  /* change to green */
#ifdef vms
	term_nopasthru();
#endif /* vms */
}

/* special color linetypes for MS-DOS Kermit v2.31 tektronix emulator */
/*	0 = normal, 1 = bright 
	foreground color (30-37) = 30 + colors
		where colors are   1=red, 2=green, 4=blue */
static char *kermit_color[15]= {"\033[0;37m","\033[1;30m",
		"\033[0;32m","\033[0;36m","\033[0;31m","\033[0;35m",
		"\033[1;34m","\033[1;33m","\033[1;31m","\033[1;37m",
		"\033[1;35m","\033[1;32m","\033[1;36m","\033[0;34m",
		"\033[0;33m"};

TERM_PUBLIC void KTEK40Clinetype(linetype)
int linetype;
{
	if (linetype >= 13)
		linetype %= 13;
	fprintf(outfile,"%s",kermit_color[linetype+2]);
}


/* linetypes for MS-DOS Kermit v2.30 tektronix emulator */
/* `=solid, a=fine dots, b=short dashes, c=dash dot, 
   d=long dash dot, e=dash dot dot */
static char *kerm_linetype = "`a`abcde" ;

TERM_PUBLIC void KTEK40Mlinetype(linetype)
int linetype;
{
	if (linetype >= 6)
		linetype %= 6;
	fprintf(outfile,"\033%c",kerm_linetype[linetype+2]);
}

TERM_PUBLIC void KTEK40reset()
{
	fprintf(outfile,"\030\n");  /* turn off Tek emulation */
#ifdef vms
	term_mode_native();
#endif /* vms */
}

#endif /* KERMIT */


/* thanks to sask!macphed (Geoff Coleman and Ian Macphedran) for the
   Selanar driver */

#ifdef SELANAR

TERM_PUBLIC void SEL_init()
{
	fprintf(outfile,"\033\062");
/*					1
	1. set to ansi mode
*/
}


TERM_PUBLIC void SEL_graphics()
{
	fprintf(outfile,"\033[H\033[J\033\061\033\014");
/*                   1           2       3
	1. clear ANSI screen
	2. set to TEK mode
	3. clear screen
*/
}


TERM_PUBLIC void SEL_text()
{
	TEK40move(0,12);
	fprintf(outfile,"\033\062");
/*                   1
	1. into ANSI mode
*/
}

TERM_PUBLIC void SEL_reset()
{
	fprintf(outfile,"\033\061\033\012\033\062\033[H\033[J");
/*                   1        2       3      4
1       set tek mode
2       clear screen
3       set ansi mode
4       clear screen
*/
}
#endif /* SELANAR */

#ifdef VTTEK

TERM_PUBLIC void VTTEK40init()
{
        fprintf(outfile,"\033[?38h");
        fflush(outfile);
        sleep(1);
        /* sleep 1 second to allow screen time to clear on some terminals */
#ifdef vms
        term_mode_tek();
#endif /* vms */
}

TERM_PUBLIC void VTTEK40reset()
{
        fprintf(outfile,"\033[?38l");
        fflush(outfile);
        sleep(1);
        /* sleep 1 second to allow screen time to clear on some terminals */
#ifdef vms
        term_mode_native();
#endif /* vms */
}

/* linetypes for VT-type terminals in tektronix emulator mode */
/* `=solid, a=fine dots, b=short dashes, c=dash dot,
   d=long dash dot, h=bold solid, i=bold fine dots, j=bold short dashes,
   k=bold dash dot, l=bold long dash dot */
static char *vt_linetype = "`a`abcdhijkl" ;
static int last_vt_linetype = 0;
TERM_PUBLIC void VTTEK40linetype(linetype)
int linetype;
{
        if (linetype >= 10)
                linetype %= 10;
        fprintf(outfile,"\033%c",vt_linetype[linetype+2]);
        last_vt_linetype = linetype;
}

TERM_PUBLIC void VTTEK40put_text(x,y,str)
unsigned int x,y;
char str[];
{
        int linetype;
        linetype = last_vt_linetype;
        VTTEK40linetype(0);
        TEK40put_text(x,y,str);
        VTTEK40linetype(linetype);
}

#endif /* VTTEK */

#ifdef LN03P

TERM_PUBLIC void LN03Pinit()
{
	fprintf(outfile,"\033[?38h");
}

TERM_PUBLIC void LN03Preset()
{
	fprintf(outfile,"\033[?38l");
}
#endif /* LN03P */



/* tek40xx (monochrome) with linetype support by Jay I. Choe */
#ifdef CTEK

/* these are common and maybe defined before */
#ifndef ABS
#define ABS(A) (((A)>=0)? (A):-(A))
#endif

/* these are common and maybe defined before */ 
/* e.g. in AMIGA intuition.h */
#ifndef SIGN
#define SIGN(A) (((A) >= 0)? 1:-1)
#endif

static void CT_solid_vector __P((int x, int y));
static void CT_draw_vpoint __P((int x, int y, int last));
static void CT_pattern_vector __P((int x1, int y1));

/* CT_lines are line types defined as bit pattern */
static unsigned long CT_lines[]=
{  0xffffffff,  /* solid line */
   0x000fffff,  /* long dash */
   0x00ff00ff,  /* short dash */
   0x00f00fff,  /* dash-dot */
   0x00f07fff,  /* long dash - dot */
   0x07070707,
   0x07ff07ff,
   0x070707ff};

/* current line pattern */
static unsigned long *CT_pattern = &CT_lines[0];

/* we need to keep track of tek cursor location */
static int CT_last_linetype=0, CT_last_x,CT_last_y;

TERM_PUBLIC void CTEK_linetype(linetype)
int linetype;
{
  if(linetype<0) linetype=0;
  linetype %= (sizeof(CT_lines)/sizeof(unsigned long));
  CT_pattern= &CT_lines[linetype];
  CT_last_linetype=linetype;
}

TERM_PUBLIC void CTEK_move(x, y)
unsigned int x;
unsigned int y;
{
  TEK40move(x,y);
  CT_last_x=x;
  CT_last_y=y;
}

static void CT_solid_vector(x, y)
int x;
int y;
{
  TEK40vector(x,y);
  CT_last_x=x;
  CT_last_y=y;
}

/*
   simulate pixel draw using tek vector draw.
   delays actual line drawing until maximum line segment is determined
   (or first/last point is defined)
*/
static int CT_penon=0; /* is Pen on? */

static void CT_draw_vpoint(x, y,last)
int x;
int y;
int last;
{
  static int xx0, yy0,xx1,yy1;

  if((*CT_pattern) & 1) {
    if(CT_penon) { /* This point is a continuation of current line */
      xx1=x;
      yy1=y;
    }
    else { /* beginning of new line */
      xx0=xx1=x;
      yy0=yy1=y;
      CT_penon=1;
    }
    *CT_pattern = ((*CT_pattern)>>1) | 0x80000000; /* rotate the pattern */
    if(last) { /* draw the line anyway if this is the last point */
      TEK40move(xx0,yy0);
      TEK40vector(xx1,yy1);
      CT_penon=0;
    }
  }
  else { /* do not draw this pixel */
    if(CT_penon) { /* last line segment ended at the previous pixel. */
                   /* draw the line */
      TEK40move(xx0,yy0);
      TEK40vector(xx1,yy1);
      CT_penon=0;
    }
    *CT_pattern = (*CT_pattern)>>1; /* rotate the current pattern */
  }
}

/*
   draw vector line with pattern
*/

static void CT_pattern_vector(x1, y1)
int x1;
int y1;
{
  int op; /* order parameter */
  int x0 = CT_last_x;
  int y0 = CT_last_y;
  int dx = x1-x0;
  int dy = y1-y0;
  int ax = ABS(dx) << 1;
  int ay = ABS(dy) << 1;
  int sx = SIGN(dx);
  int sy = SIGN(dy);

  if(ax >= ay) {
    for(op = ay - (ax >> 1); x0 != x1; x0 += sx, op += ay) {
      CT_draw_vpoint(x0,y0,0);
      if(op >0 || (op==0 && sx==1)) {
	op -= ax;
	y0 += sy;
      }
    }
  }
  else {  /* ax < ay */
    for(op = ax - (ay >> 1); y0 != y1 ; y0 += sy, op += ax) {
      CT_draw_vpoint(x0,y0,0);
      if(op >0 || (op==0 && sy==1)) {
	op -= ay;
	x0 += sx;
      }
    }
  }
  CT_draw_vpoint(x0,y0,1); /* last point */
  CT_last_x=x1;
  CT_last_y=y1;
}

TERM_PUBLIC void CTEK_vector(x, y)
unsigned int x;
unsigned int y;
{
  if(CT_last_linetype<=0)
    CT_solid_vector(x,y);
  else
    CT_pattern_vector(x,y);
}

#endif /* CTEK */
#endif /* TERM_BODY */

#ifdef TERM_TABLE

TERM_TABLE_START(tek40_driver)
#ifndef CTEK
   "tek40xx", "Tektronix 4010 and others; most TEK emulators",
           TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR, 
           TEK40VTIC, TEK40HTIC, options_null, TEK40init, TEK40reset, 
           TEK40text, null_scale, TEK40graphics, TEK40move, TEK40vector, 
           TEK40linetype, TEK40put_text, null_text_angle, 
           null_justify_text, line_and_point, do_arrow, set_font_null
#else
   "tek40xx","Tektronix 4010 and others; most TEK emulators",
        TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR,
        TEK40VTIC, TEK40HTIC, options_null, TEK40init, TEK40reset,
        TEK40text, null_scale, TEK40graphics, CTEK_move, CTEK_vector, 
        CTEK_linetype, TEK40put_text, null_text_angle, 
        null_justify_text, line_and_point, do_arrow, set_font_null
#endif
TERM_TABLE_END(tek40_driver)
#undef LAST_TERM
#define LAST_TERM tek40_driver

#ifdef VTTEK
TERM_TABLE_START(vttek_driver)
   "vttek", "VT-like tek40xx terminal emulator",
       TEK40XMAX,TEK40YMAX,TEK40VCHAR, TEK40HCHAR,
       TEK40VTIC, TEK40HTIC, options_null, VTTEK40init, VTTEK40reset,
       TEK40text, null_scale, TEK40graphics, TEK40move, TEK40vector,
       VTTEK40linetype, VTTEK40put_text, null_text_angle,
       null_justify_text, line_and_point, do_arrow, set_font_null
TERM_TABLE_END(vttek_driver)
#undef LAST_TERM
#define LAST_TERM vttek_driver
#endif

#ifdef KERMIT
TERM_TABLE_START(kc_tek40_driver)
   "kc_tek40xx", "MS-DOS Kermit Tek4010 terminal emulator - color",
           TEK40XMAX,TEK40YMAX,TEK40VCHAR, KTEK40HCHAR, 
           TEK40VTIC, TEK40HTIC, options_null, TEK40init, KTEK40reset, 
           KTEK40Ctext, null_scale, KTEK40graphics, TEK40move, TEK40vector, 
           KTEK40Clinetype, TEK40put_text, null_text_angle, 
           null_justify_text, do_point, do_arrow, set_font_null
TERM_TABLE_END(kc_tek40_driver)

TERM_TABLE_START(km_tek40_driver)
   "km_tek40xx", "MS-DOS Kermit Tek4010 terminal emulator - monochrome",
           TEK40XMAX,TEK40YMAX,TEK40VCHAR, KTEK40HCHAR, 
           TEK40VTIC, TEK40HTIC, options_null, TEK40init, KTEK40reset, 
           TEK40text, null_scale, KTEK40graphics, TEK40move, TEK40vector, 
           KTEK40Mlinetype, TEK40put_text, null_text_angle, 
           null_justify_text, line_and_point, do_arrow, set_font_null
TERM_TABLE_END(km_tek40_driver)
#undef LAST_TERM
#define LAST_TERM km_tek40_driver
#endif

#ifdef SELANAR
TERM_TABLE_START(selanar_driver)
   "selanar", "Selanar",
           TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR, 
           TEK40VTIC, TEK40HTIC, options_null, SEL_init, SEL_reset, 
           SEL_text, null_scale, SEL_graphics, TEK40move, TEK40vector, 
           TEK40linetype, TEK40put_text, null_text_angle, 
           null_justify_text, line_and_point, do_arrow, set_font_null
TERM_TABLE_END(selanar_driver)
#undef LAST_TERM
#define LAST_TERM selanar_driver
#endif

#ifdef BITGRAPH
TERM_TABLE_START(bitgraph_driver)
   "bitgraph", "BBN Bitgraph Terminal",
           BG_XMAX,BG_YMAX,BG_VCHAR, BG_HCHAR, 
           BG_VTIC, BG_HTIC, options_null, BG_init, BG_reset, 
           BG_text, null_scale, BG_graphics, BG_move, BG_vector,
           BG_linetype, BG_put_text, null_text_angle, 
           null_justify_text, line_and_point, do_arrow, set_font_null
TERM_TABLE_END(bitgraph_driver)
#undef LAST_TERM
#define LAST_TERM bitgraph_drive
#endif

#endif /* TERM_TABLE */

#endif /* TERM_PROTO_ONLY */

/*
 * NAME: tek40xx
 *
 * OPTIONS: none
 *
 * SUPPORTS: Tektronix 4010 and others; most TEK emulators
 *
 * Further Info: none 
 *
 */

#ifdef VTTEK
/*
 * NAME: vttek
 *
 * OPTIONS: none
 *
 * SUPPORTS: VT-like tek40xx terminal emulator
 *
 * Further Info: none 
 *
 */
#endif /* VTTEK */

#ifdef KERMIT
/*
 * NAME: kc_tek40xx
 *
 * OPTIONS: none
 *
 * SUPPORTS: MS-DOS Kermit Tek4010 terminal emulator
 *
 * Further Info: colour version. There is also a terminal (km_tek40xx)
 *		 that supports monochrome graphics.
 *
 */
/*
 * NAME: km_tek40xx
 *
 * OPTIONS: none
 *
 * SUPPORTS: MS-DOS Kermit Tek4010 terminal emulator
 *
 * Further Info: monochrome version. There is also a terminal (kc_tek40xx)
 *		 that supports colour graphics.
 *
 */
#endif /* KERMIT */

#ifdef SELANAR
/*
 * NAME: selanar
 *
 * OPTIONS: none
 *
 * SUPPORTS: selanar
 *
 * Further Info: none
 *
 */
#endif /* SELANAR */

#ifdef BITGRAPH
/*
 * NAME: bitgraph
 *
 * OPTIONS: none
 *
 * SUPPORTS: BBN Bitgraph Terminal
 *
 * Further Info: none
 *
 */
#endif /* BITGRAPH */
