Blob Blame History Raw
/* Hello, Emacs, this is -*-C-*-
 * $Id: tek.trm,v 1.26 2015/03/24 23:30:06 sfeam Exp $
 *
 */

/* GNUPLOT - tek.trm */

/*[
 * Copyright 1990 - 1993, 1998, 2004
 *
 * 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 complete modified source code.  Modifications are to
 * be distributed as patches to the released version.  Permission to
 * distribute binaries produced by compiling modified sources is granted,
 * provided you
 *   1. distribute the corresponding source modifications from the
 *    released version in the form of a patch file along with the binaries,
 *   2. add special version identification to distinguish your version
 *    in addition to the base release version number,
 *   3. provide your name and address as the primary contact for the
 *    support of your modified version, and
 *   4. retain our contact information in regard to use of the base
 *    software.
 * Permission to distribute the released version of the source code along
 * with corresponding source modifications in the form of a patch file is
 * granted with same provisions 2 through 4 for binary distributions.
 *
 * This software is provided "as is" without express or implied warranty
 * to the extent permitted by applicable law.
]*/

/*
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *  tek40xx, bitgraph, kermit_color_tek40xx, kermit_mono_tek40xx, selanar
 *  sixel, ln03plus, xterm
 *
 * AUTHORS
 *   Colin Kelley, Thomas Williams, Russell Lang
 *
 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
 *
 */

/*
 * Modified June 1995 Ian MacPhedran to support newterm format
 */

/*
 * Modified November 2013 Erik Olofsen to support DEC's Sixel graphics,
 * natively, which is more practical than using the PBM driver and piping
 * through e.g. `ppmtosixel`.
 * Gnuplot should be configured with `--with-bitmap-terminals`.
 * The code was inserted here as XTerm now supports Tek and Sixel codes;
 * for this driver to work, the Xterm terminal type should be selected as
 * VT340, and `sixelScrolling` is best selected. The driver was tested from
 * XTerm version 2.9.7, and mlterm version 3.3.2.
 * Under VMS, the DECW$TERMINAL may be used (set to dark text and light
 * background).
 * The `set terminal` options are identical to that of the PBM driver,
 * but `grayscale` not available (albeit via rgb specifications).
 * Filled polygons are supported; the code was inspired by public domain
 * code by Darel Rex Finley.
 * Line widths greater than one are plotted using filled squares, with
 * solid line types only.
 * RGB color specifications are supported and override the defaults,
 * which are according to the XTerm source:

     * VT340:
     *      mono    color
     *   0: 0%      0%              (bg for light on dark mode)
     *   1: 14%     blue
     *   2: 29%     red
     *   3: 43%     green
     *   4: 57%     magenta
     *   5: 71%     cyan
     *   6: 86%     yellow
     *   7: 100%    50%             (fg for light on dark mode)
     *   8: 0%      25%
     *   9: 14%     gray-blue
     *  10: 29%     gray-red
     *  11: 43%     gray-green
     *  12: 57%     gray-magenta
     *  13: 71%     gray-cyan
     *  14: 86%     gray-yellow
     *  15: 100%    75%

 * To get the default device colors as given above (with offset 1), use:

   unset for [i=1:16] linetype i
   set for [i=1:16] linetype i linecolor i

   or for black dashed lines:

   set for [i=1:16] linetype i dashtype i linecolor "black"
*/

#define TEK
#define CTEK
#define VTTEK
#define XTERM
#ifndef NO_BITMAP_SUPPORT
#define SIXEL
#endif

/* Version 4.3: still available, but no longer built by default */
#if 0
#define KERMIT
#define SELANAR
#define BITGRAPH
#endif

#include "driver.h"

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

#ifdef TERM_PROTO
TERM_PUBLIC void TEK40init __PROTO((void));
TERM_PUBLIC void TEK40graphics __PROTO((void));
TERM_PUBLIC void TEK40text __PROTO((void));
TERM_PUBLIC void TEK40move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void TEK40vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void TEK40put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
TERM_PUBLIC void TEK40reset __PROTO((void));
#ifdef BITGRAPH
TERM_PUBLIC void BG_text __PROTO((void));
TERM_PUBLIC void BG_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
#endif
#if defined(SELANAR) || defined(BITGRAPH)
TERM_PUBLIC void TEK40linetype __PROTO((int linetype));
#endif
#ifdef KERMIT
TERM_PUBLIC void KTEK40graphics __PROTO((void));
TERM_PUBLIC void KTEK40Ctext __PROTO((void));
TERM_PUBLIC void KTEK40Clinetype __PROTO((int linetype));
TERM_PUBLIC void KTEK40Mlinetype __PROTO((int linetype));
TERM_PUBLIC void KTEK40reset __PROTO((void));
#endif
#ifdef SELANAR
TERM_PUBLIC void SEL_init __PROTO((void));
TERM_PUBLIC void SEL_graphics __PROTO((void));
TERM_PUBLIC void SEL_text __PROTO((void));
TERM_PUBLIC void SEL_reset __PROTO((void));
#endif
#ifdef SIXEL
TERM_PUBLIC void SIXEL_options __PROTO((void));
TERM_PUBLIC void SIXEL_init __PROTO((void));
TERM_PUBLIC void SIXEL_reset __PROTO((void));
TERM_PUBLIC void SIXEL_text __PROTO((void));
TERM_PUBLIC void SIXEL_setfont __PROTO((void));
TERM_PUBLIC void SIXEL_graphics __PROTO((void));
TERM_PUBLIC void SIXEL_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void SIXEL_vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void SIXEL_linetype __PROTO((int linetype));
TERM_PUBLIC void SIXEL_dashtype __PROTO((int type, t_dashtype *custom_dash_type));
TERM_PUBLIC void SIXEL_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
TERM_PUBLIC int SIXEL_text_angle __PROTO((int));
TERM_PUBLIC void SIXEL_fillbox __PROTO((int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height));
TERM_PUBLIC void SIXEL_linewidth __PROTO((double linewidth));
TERM_PUBLIC int SIXEL_make_palette (t_sm_palette *);
TERM_PUBLIC void SIXEL_set_color __PROTO((t_colorspec *colorspec));
TERM_PUBLIC void SIXEL_filled_polygon __PROTO((int points, gpiPoint *corners));
#endif
TERM_PUBLIC void VTTEK40init __PROTO((void));
TERM_PUBLIC void VTTEK40reset __PROTO((void));
TERM_PUBLIC void VTTEK40linetype __PROTO((int linetype));
TERM_PUBLIC void VTTEK40put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
TERM_PUBLIC void XTERM_graphics __PROTO((void));
TERM_PUBLIC void XTERM_resume __PROTO((void));
TERM_PUBLIC void XTERM_text __PROTO((void));
TERM_PUBLIC int  XTERM_set_font __PROTO((const char * fontname));
TERM_PUBLIC void CTEK_linetype __PROTO((int linetype));
TERM_PUBLIC void CTEK_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void CTEK_vector __PROTO((unsigned int x, unsigned int y));

#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 */
    fputs("\033\014", gpoutfile);
/*                   1
	1. clear screen
*/
    (void) fflush(gpoutfile);
    sleep(1);
    /* sleep 1 second to allow screen time to clear on real
       tektronix terminals */
}

TERM_PUBLIC void
TEK40text()
{
#ifdef VMS
    (void) fflush(gpoutfile);	/* finish the graphics */
#endif
    TEK40move(0, 12);
    fputs("\037", gpoutfile);
/*                   1
	1. into alphanumerics
*/
#ifdef VMS
    term_nopasthru();
#endif /* VMS */
}


#if defined(SELANAR) || defined(BITGRAPH)
TERM_PUBLIC void
TEK40linetype(int linetype)
{
    (void) linetype;
}
#endif

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


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


TERM_PUBLIC void
TEK40put_text(unsigned int x, unsigned int y, const char str[])
{
    TEK40move(x, y - 11);
    fprintf(gpoutfile, "\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
#define BG_reset TEK40reset


TERM_PUBLIC void
BG_text()
{
#ifdef VMS
    (void) fflush(gpoutfile);	/* finish the graphics */
#endif
    BG_move(0, BG_SCREEN_HEIGHT - 2 * BG_VCHAR);
    fputs("\037", gpoutfile);
/*                   1
	1. into alphanumerics
*/
}


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


#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 */
    fputs("\033\014", gpoutfile);
/*                   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 const 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(int linetype)
{
    if (linetype < -2)
	linetype = LT_BLACK;
    if (linetype >= 13)
	linetype %= 13;
    fprintf(gpoutfile, "%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 const char *kerm_linetype = "`a`abcde";

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

TERM_PUBLIC void
KTEK40reset()
{
    fputs("\030\n", gpoutfile);	/* 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()
{
    fputs("\033\062", gpoutfile);
/*					1
	1. set to ansi mode
*/
}


TERM_PUBLIC void
SEL_graphics()
{
    fputs("\033[H\033[J\033\061\033\014", gpoutfile);
/*                   1           2       3
	1. clear ANSI screen
	2. set to TEK mode
	3. clear screen
*/
#ifdef VMS
    term_pasthru();
#endif /* VMS */
}


TERM_PUBLIC void
SEL_text()
{
#ifdef VMS
    (void) fflush(gpoutfile);	/* finish the graphics */
#endif
    TEK40move(0, 12);
    fputs("\033\062", gpoutfile);
/*                   1
	1. into ANSI mode
*/
#ifdef VMS
    term_nopasthru();
#endif /* VMS */
}

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

#endif /* SELANAR */

#ifdef SIXEL

#include "bitmap.h"

#define SIXEL_XMAX  (640)
#define SIXEL_YMAX  (480)
#define SIXEL_VCHAR (FNT5X9_VCHAR)
#define SIXEL_HCHAR (FNT5X9_HCHAR)
#define SIXEL_VTIC  (FNT5X9_HBITS)
#define SIXEL_HTIC  (FNT5X9_HBITS)

#define SIXEL_COL_UNDEFINED 0
#define SIXEL_COL_DEFINED 1
#define SIXEL_COL_USED 2

static int SIXEL_mode;
static int SIXEL_font;
static int SIXEL_lt;
static int SIXEL_dt;
static int SIXEL_fp, SIXEL_np;
static double SIXEL_lw;
static unsigned int SIXEL_xp, SIXEL_yp;

struct SIXEL_colorspec {
    int state;		/* see definitions above */
    int rgbval;
};

/* the palette may be used for pre-defined, user-defined, and Gnuplot palette colors.
   set SIXEL_NCOL to 16 and the number of planes in SIXEL_init() to 5 for VT340 and
   similar Sixel devices, or higher for more recent implementations */

#define SIXEL_NCOL (16)
static struct SIXEL_colorspec SIXEL_palette[SIXEL_NCOL];

static int SIXEL_findslot(int rgbval)
{
    int i, iopt;
    int d1, d2, dist, dopt;

/* try to find a slot with a matching rgb value */

    for (i=0; i<SIXEL_NCOL; i++) {
      if (SIXEL_palette[i].rgbval == rgbval) {
          SIXEL_palette[i].state = SIXEL_COL_USED;
	  return i;
      }
    }

/* if not found, try to find an undefined slot */

    for (i=0; i<SIXEL_NCOL; i++) {
      if (SIXEL_palette[i].state == SIXEL_COL_UNDEFINED) {
        SIXEL_palette[i].state = SIXEL_COL_USED;
	SIXEL_palette[i].rgbval = rgbval;
	return i;
      }
    }

/* if not found, try to find an unused slot */

    dopt = 0x30000; /* max is 3 times 256 squared */

    for (i=0; i<SIXEL_NCOL; i++) {
      if (SIXEL_palette[i].state != SIXEL_COL_USED) {
        SIXEL_palette[i].state = SIXEL_COL_USED;
	SIXEL_palette[i].rgbval = rgbval;
	return i;
      }
      d1 = (SIXEL_palette[i].rgbval & 0xff0000) >> 16;
      d2 = (rgbval & 0xff0000) >> 16;
      dist = (d1-d2)*(d1-d2);
      d1 = (SIXEL_palette[i].rgbval & 0x00ff00) >> 8;
      d2 = (rgbval & 0x00ff00) >> 8;
      dist += (d1-d2)*(d1-d2);
      d1 = (SIXEL_palette[i].rgbval & 0x0000ff) >> 16;
      d2 = (rgbval & 0x0000ff);
      dist += (d1-d2)*(d1-d2);
      if (dist < dopt) { dopt=dist; iopt=i; }
    }

/* nothing available, use closest slot w.r.t. color */

    return iopt;
}

enum SIXEL_id {
    SIXEL_SMALL, SIXEL_MEDIUM, SIXEL_LARGE,
    SIXEL_MONOCHROME, SIXEL_COLOR, SIXEL_SIZE,
    SIXEL_OTHER
};

static struct gen_table SIXEL_opts[] =
{
    { "s$mall", SIXEL_SMALL },
    { "me$dium", SIXEL_MEDIUM },
    { "l$arge", SIXEL_LARGE },
    { "mo$nochrome", SIXEL_MONOCHROME },
    { "c$olor", SIXEL_COLOR },
    { "c$olour", SIXEL_COLOR },
    { "size", SIXEL_SIZE },
    { NULL, SIXEL_OTHER }
};

TERM_PUBLIC void
SIXEL_options()
{
    int xpixels = SIXEL_XMAX;
    int ypixels = SIXEL_YMAX;
    struct value a;
    SIXEL_font = 1;
    SIXEL_mode = 1;

    term_options[0] = NUL;

    while (!END_OF_COMMAND) {
	switch(lookup_table(&SIXEL_opts[0],c_token)) {
	case SIXEL_SMALL:
	    SIXEL_font = 1;
	    c_token++;
	    break;
	case SIXEL_MEDIUM:
	    SIXEL_font = 2;
	    c_token++;
	    break;
	case SIXEL_LARGE:
	    SIXEL_font = 3;
	    c_token++;
	    break;
	case SIXEL_MONOCHROME:
	    SIXEL_mode = 0;
	    term->flags |= TERM_MONOCHROME;
	    c_token++;
	    break;
	case SIXEL_COLOR:
	    SIXEL_mode = 1;
	    term->flags &= ~TERM_MONOCHROME;
	    c_token++;
	    break;
	case SIXEL_SIZE:
	    c_token++;
	    if (END_OF_COMMAND) {
		term->xmax = SIXEL_XMAX;
		term->ymax = SIXEL_YMAX;
	    } else {
		xpixels = real(const_express(&a));
		if (equals(c_token, ",")) {
		    c_token++;
		    ypixels = real(const_express(&a));
		    ypixels = (ypixels/6)*6; /* multiple of six */
		}
	    }
	    if (xpixels > 0)
		term->xmax = xpixels;
	    if (ypixels > 0)
		term->ymax = ypixels;
	    break;
	case SIXEL_OTHER:
	default:
	    /* reset to default, since term is already set */
	    SIXEL_font = 1;
	    SIXEL_mode = 1;
	    int_error(c_token, "expecting: {small, medium, large}, {monochrome, color}, and {size x,y}");
	    break;
	}
    }

    term->v_tic = (term->xmax < term->ymax) ? term->xmax/100 : term->ymax/100;
    if (term->v_tic < 1)
        term->v_tic = 1;
    term->h_tic = term->v_tic;

    /* setup options string */

    switch (SIXEL_font) {
    case 1:
	strcat(term_options, "small");
	break;
    case 2:
	strcat(term_options, "medium");
	break;
    case 3:
	strcat(term_options, "large");
	break;
    }

    switch (SIXEL_mode) {
    case 0:
	strcat(term_options, " monochrome");
	break;
    case 1:
	strcat(term_options, " color");
	break;
    }

    sprintf(term_options + strlen(term_options), " size %d,%d",
	term->xmax, term->ymax);
}


TERM_PUBLIC void
SIXEL_init()
{
    unsigned int xpixels = term->xmax;
    unsigned int ypixels = term->ymax;

    /* Why 5 planes for VT340?  16 predefined colors only require 4. */
    /* A usable palette would require 7 or 8 (128 or 256 colors). */
    /* A pixel is empty, or has any of the standard 16 colors, so there
       are 17 possibilities, and 5 planes are needed... */

    b_makebitmap(xpixels, ypixels, 5);

    SIXEL_setfont();
}


TERM_PUBLIC void
SIXEL_reset()
{
    b_freebitmap();
}


TERM_PUBLIC void
SIXEL_text()
{
    int i, j, k, l, ic, n, pr, no;
    char c, pc;

/* initialization to Sixel mode and pixel aspect ratio,
   but do not change the background */

    fprintf(gpoutfile,"\033Pq\"1;1\n");

/* output the actually used rgb colors */

    for (k=0; k<SIXEL_NCOL; k++)
      if (SIXEL_palette[k].state == SIXEL_COL_USED) 
        fprintf(gpoutfile,"#%d;2;%d;%d;%d\n",k,
	  (int) (((SIXEL_palette[k].rgbval & 0xff0000) >> 16) * 100./255.),
          (int) (((SIXEL_palette[k].rgbval & 0x00ff00) >> 8) * 100./255.),
          (int) (((SIXEL_palette[k].rgbval & 0x0000ff) * 100./255.)) );

    for (j=b_ysize-6; j>=0; j-=6) {
      for (k=1; k<=SIXEL_NCOL; k++) {
	no = 0; /* for finite line records (VMS) */
	pr = 0;
        pc = '\0';
        n = 0;
        for (i=0; i<b_xsize; i++) {
	  ic = (b_getpixel(i,j)==k ? 32 : 0) +
               (b_getpixel(i,j+1)==k ? 16 : 0) +
               (b_getpixel(i,j+2)==k ? 8 : 0) +
               (b_getpixel(i,j+3)==k ? 4 : 0) +
               (b_getpixel(i,j+4)==k ? 2 : 0) +
               (b_getpixel(i,j+5)==k ? 1 : 0);
          c = (char) (ic+63);
	  if (c==pc && i!=b_xsize-1) {
	    n++;
	  } else {
	    if (n>0 && pr==0) {
              pr++;
              if (n<b_xsize-1 || pc!='?' || k==1) { /* do not output empty lines */
	        no += fprintf(gpoutfile,"#%d",k-1);
	        pr++;
	      }
            }
            if (pr==2) {
	      if (i==b_xsize-1 && c==pc) n++;
	      if (n>3) {
	        no += fprintf(gpoutfile,"!%d%c",n,pc);
	      } else {
	        for (l=1; l<=n; l++) fputc(pc,gpoutfile);
	        no += n;
	      }
	      if (i==b_xsize-1 && c!=pc) {
	        fputc(c,gpoutfile);
	        no++;
	      }
	      if (no>70 && i<b_xsize-1) {
	        fprintf(gpoutfile,"\n");
	        no = 0;
	      }
            }
	    n = 1;
	  }
	  pc = c;
	}
	if (k==SIXEL_NCOL) {
	  fputs("-\n",gpoutfile);
	} else if (pr==2) {
	  fputs("$\n",gpoutfile);
	}
      }
    }

/* get out of Sixel mode */

#ifndef VMS
    fputs("\033\\\n",gpoutfile);
#else
    fputs("\033\\\n\n",gpoutfile);
#endif
    (void) fflush(gpoutfile);	/* finish the graphics */
}


TERM_PUBLIC void
SIXEL_setfont()
{
    switch (SIXEL_font) {
    case 1:
	b_charsize(FNT5X9);
	term->v_char = FNT5X9_VCHAR;
	term->h_char = FNT5X9_HCHAR;
	break;
    case 2:
	b_charsize(FNT9X17);
	term->v_char = FNT9X17_VCHAR;
	term->h_char = FNT9X17_HCHAR;
	break;
    case 3:
	b_charsize(FNT13X25);
	term->v_char = FNT13X25_VCHAR;
	term->h_char = FNT13X25_HCHAR;
	break;
    }
}


TERM_PUBLIC void
SIXEL_graphics()
{
    int i;

    b_boxfill(FS_EMPTY,0,0,b_xsize,b_ysize);
    for (i=0; i<SIXEL_NCOL; i++) { 
	struct linestyle_def *this;
	SIXEL_palette[i].state = SIXEL_COL_UNDEFINED;
	SIXEL_palette[i].rgbval = 0;
	for (this = first_perm_linestyle; this != NULL; this = this->next) {
	    if (i == this->tag-1) {
		/* Load color into SIXEL_palette[i] */
		if (this->lp_properties.pm3d_color.type == TC_RGB) {
		    int rgbval = this->lp_properties.pm3d_color.lt;
		    SIXEL_palette[i].state = SIXEL_COL_DEFINED;
		    SIXEL_palette[i].rgbval = rgbval;
		}
		break;
	    }
	}
    }
}


TERM_PUBLIC void
SIXEL_move(unsigned int x, unsigned int y)
{
    SIXEL_xp = x;
    SIXEL_yp = y;
    b_move(x,y);
}


TERM_PUBLIC void
SIXEL_vector(unsigned int x, unsigned int y)
{
    unsigned int x1, y1, x2, y2;
    int runcount;
    int dx, dy;
    int xinc, yinc;
    unsigned int xplot, yplot;
    unsigned int i, wh, wh2;

    if (SIXEL_lw <= 1.) {
      b_vector(x,y);
      return;
    }

    wh = (int) (SIXEL_lw + 0.5);
    wh2 = wh/2;

    x1 = SIXEL_xp;
    y1 = SIXEL_yp;
    x2 = x;
    y2 = y;

/* algorithm from bitmap.c */

    runcount = 0;
    dx = abs((int) (x1) - (int) (x2));
    if (x2 > x1)
	xinc = 1;
    else if (x2 == x1)
	xinc = 0;
    else
	xinc = -1;
    dy = abs((int) (y1) - (int) (y2));
    if (y2 > y1)
	yinc = 1;
    else if (y2 == y1)
	yinc = 0;
    else
	yinc = -1;
    xplot = x1;
    yplot = y1;
    if (dx > dy) {
	/* iterate x */
	while (xplot != x2) {
	    xplot += xinc;
	    runcount += dy;
	    if (runcount >= (dx - runcount)) {
		yplot += yinc;
		runcount -= dx;
	    }
            for (i=1; i<=wh; i++) {
              b_move(xplot-wh2, yplot-wh2+i);
	      b_vector(xplot-wh2+wh, yplot-wh2+i);
            }
	}
    } else {
	/* iterate y */
	while (yplot != y2) {
	    yplot += yinc;
	    runcount += dx;
	    if (runcount >= (dy - runcount)) {
		xplot += xinc;
		runcount -= dy;
	    }
            for (i=1; i<=wh; i++) {
              b_move(xplot-wh2, yplot-wh2+i);
	      b_vector(xplot-wh2+wh, yplot-wh2+i);
            }
	}
    }

    SIXEL_xp = x;
    SIXEL_yp = y;
}


TERM_PUBLIC void
SIXEL_linetype(int linetype)
{
    int i;

    if (SIXEL_mode==0) {
      b_setlinetype(linetype);
    } else {
      if (linetype < 0) {
        if (linetype==LT_AXIS) b_setlinetype(1);
        i = SIXEL_findslot(0); /* find slot with black color */
        b_setvalue(1+i);
      } else if (linetype > 0) {
        i = linetype % SIXEL_NCOL;
        b_setvalue(1+i);
      } else {
        b_setlinetype(0);
      }
    }

    SIXEL_lt = linetype;
}


TERM_PUBLIC void
SIXEL_dashtype(int type, t_dashtype *custom_dash_type)
{
    if (type >= 0)
      SIXEL_dt = type;
    else if (type == DASHTYPE_AXIS)
      SIXEL_dt = 1;
    else
      SIXEL_dt = 0; /* solid, also for custom dash types */

    b_setlinetype(SIXEL_dt);
}


TERM_PUBLIC void
SIXEL_put_text(unsigned int x, unsigned int y, const char str[])
{
    b_put_text(x,y,str);
}


TERM_PUBLIC int
SIXEL_text_angle(int ang)
{
    b_text_angle(ang);
    return TRUE;
}


TERM_PUBLIC void
SIXEL_fillbox(int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height)
{
    if (SIXEL_lt == LT_BACKGROUND)
	return;
    if (style == FS_DEFAULT)
	style = FS_OPAQUE;

    b_boxfill(style,x1,y1,width,height);
}


TERM_PUBLIC void
SIXEL_linewidth(double linewidth)
{
    SIXEL_lw = linewidth;
}


/* the palette defines all colors from the first undefined one;
   this slot region will be contiguous */

TERM_PUBLIC int SIXEL_make_palette (t_sm_palette *palette)
{
    int i, c;

    if (palette == NULL) {

	/* If we already have a palette, overwrite it */
	if (SIXEL_fp > 0) {
	    for (i=SIXEL_fp; i<SIXEL_NCOL; i++)
		SIXEL_palette[i].state = SIXEL_COL_UNDEFINED;
	    // return SIXEL_np;
	}

	SIXEL_np = SIXEL_NCOL;
	for (SIXEL_fp=0; SIXEL_fp<SIXEL_NCOL; SIXEL_fp++) {
	    if (SIXEL_palette[SIXEL_fp].state != SIXEL_COL_UNDEFINED)
		SIXEL_np--;
	    else
		break;
	}
	return SIXEL_np;
    }

    for (i = 0; i < sm_palette.colors; i++) {
	 SIXEL_palette[SIXEL_fp+i].state = SIXEL_COL_DEFINED;
	 SIXEL_palette[SIXEL_fp+i].rgbval = 0;
         c = (int) (palette->color[i].r*256);
         if (c>255) c = 255;
	 SIXEL_palette[SIXEL_fp+i].rgbval |= c << 16;
         c = (int) (palette->color[i].g*256);
         if (c>255) c = 255;
	 SIXEL_palette[SIXEL_fp+i].rgbval |= c << 8;
         c = (int) (palette->color[i].b*256);
         if (c>255) c = 255;
	 SIXEL_palette[SIXEL_fp+i].rgbval |= c;
    }

    return 0;
}


/*
 * This doesn't really set a color.  Instead it tries to match the color of
 * a previously defined linetype. If no match is found but there is space in
 * the palette for a new color, we add this one to the palette.
 * If no more space is available - too bad.
 */

TERM_PUBLIC void
SIXEL_set_color(t_colorspec *colorspec)
{
    int i;

    switch (colorspec->type) {
    default:
	return;
    case TC_LT:
	SIXEL_linetype(colorspec->lt);
	return;
    case TC_RGB:
	i = SIXEL_findslot(colorspec->lt);
        b_setvalue(1+i);
	return;
    case TC_FRAC:
        i = SIXEL_fp + (int)(colorspec->value*SIXEL_np);
        SIXEL_palette[i].state = SIXEL_COL_USED;
        b_setvalue(1+i);
	return;
    }
}

TERM_PUBLIC void
SIXEL_filled_polygon(int points, gpiPoint *corners)
{
    int nodes, *nodex, py, i, j, swap;

    if (SIXEL_lt==LT_BACKGROUND) return; /* opaque polygon! */

    b_setlinetype(0);

    nodex = (int *) malloc(sizeof(int)*points);

    for (py=0; py<b_ysize; py++) {

      nodes = 0;
      j = points-1;
      for (i=0; i<points; i++) {
        if ((corners[i].y<py && corners[j].y>=py) ||
            (corners[j].y<py && corners[i].y>=py)) {
          nodex[nodes++] = (int) ((corners[i].x + (double)(py - corners[i].y) /
                                                  (double)(corners[j].y - corners[i].y) *
                                                  (corners[j].x - corners[i].x)) + 0.5);
        }
        j = i;
      }

      i = 0;
      while (i < nodes-1) {
        if (nodex[i] > nodex[i+1]) {
          swap=nodex[i]; nodex[i]=nodex[i+1]; nodex[i+1]=swap;
          if (i) i--;
        } else {
          i++;
        }
      }

      for (i=0; i<nodes; i+=2) {
        b_move(nodex[i],py);
	b_vector(nodex[i+1],py);
      }
    }

    free(nodex);
}

#endif /* SIXEL */

#ifdef VTTEK

TERM_PUBLIC void
VTTEK40init()
{
    fputs("\033[?38h", gpoutfile);
    fflush(gpoutfile);
    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()
{
    fputs("\033[?38l", gpoutfile);
    fflush(gpoutfile);
    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 const char *vt_linetype = "`a`abcdhijkl";
static int last_vt_linetype = 0;

TERM_PUBLIC void
VTTEK40linetype(int linetype)
{
    if (linetype < -2)
	linetype = LT_BLACK;
    if (linetype >= 10)
	linetype %= 10;
    fprintf(gpoutfile, "\033%c", vt_linetype[linetype + 2]);
    last_vt_linetype = linetype;
}

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

#endif /* VTTEK */

#ifdef XTERM

#define XT_TEK_ESC "\033"
#define XT_TEK_GFX XT_TEK_ESC "[?38h"
#define XT_TEK_ANSI XT_TEK_ESC "\003"
#define XT_TEK_CLR XT_TEK_ESC "\014"
#define XT_TEK_ALPHA "\037"

static const char *xt_tek_fontsize = "89:;";

TERM_PUBLIC void
XTERM_graphics()
{
    XTERM_resume();
    fputs(XT_TEK_CLR, gpoutfile);
}


TERM_PUBLIC void
XTERM_resume()
{
    fputs(XT_TEK_GFX, gpoutfile);
}


TERM_PUBLIC void
XTERM_text()
{
    fputs(XT_TEK_ALPHA XT_TEK_ANSI, gpoutfile);
}


TERM_PUBLIC int
XTERM_set_font(const char *fontname)
{
    char size = 0;
    if (fontname) {
      size_t lp = strlen(fontname);
      if (lp>0) size = fontname[lp-1]-'1';
    }
    fprintf(gpoutfile, XT_TEK_ESC "%c",
            xt_tek_fontsize[size>0&&size<4?size:0]);

    return(TRUE);
}

#endif /* XTERM */

#ifdef LN03P

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

TERM_PUBLIC void
LN03Preset()
{
    fputs("\033[?38l", gpoutfile);
}

#endif /* LN03P */



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

/*#define ABS(A) (((A)>=0)? (A):-(A))*/
#define SIGN(A) (((A) >= 0)? 1:-1)

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

/* CT_lines are line types defined as bit pattern */
static unsigned long CT_lines[] =
{~(unsigned long)0,			/* 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(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(unsigned int x, unsigned int y)
{
    TEK40move(x, y);
    CT_last_x = x;
    CT_last_y = y;
}

static void
CT_solid_vector(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(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) | ((unsigned long)1 << 31);	/* 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(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(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

#ifdef CTEK
TERM_TABLE_START(tek40_driver)
    "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
TERM_TABLE_END(tek40_driver)
#endif /* CTEK */

#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 /* VTTEK */

#ifdef XTERM
TERM_TABLE_START(xterm_driver)
    "xterm", "Xterm Tektronix 4014 Mode",
    TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR,
    TEK40VTIC, TEK40HTIC, options_null, TEK40init, TEK40reset,
    XTERM_text, null_scale, XTERM_graphics, TEK40move, TEK40vector,
    VTTEK40linetype, VTTEK40put_text, null_text_angle,
    null_justify_text, line_and_point, do_arrow, XTERM_set_font, 0,
    TERM_CAN_MULTIPLOT|TERM_NO_OUTPUTFILE, XTERM_text, XTERM_resume
TERM_TABLE_END(xterm_driver)

#undef LAST_TERM
#define LAST_TERM xterm_driver

#endif /* XTERM */

#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)

#undef LAST_TERM
#define LAST_TERM 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 /* KERMIT */

#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 /* SELANAR */

#ifdef SIXEL
TERM_TABLE_START(sixel_driver)
    "sixel", "Sixel Graphics",
    SIXEL_XMAX, SIXEL_YMAX, SIXEL_VCHAR, SIXEL_HCHAR,
    SIXEL_VTIC, SIXEL_HTIC, SIXEL_options, SIXEL_init, SIXEL_reset,
    SIXEL_text, null_scale, SIXEL_graphics, SIXEL_move, SIXEL_vector,
    SIXEL_linetype, SIXEL_put_text, SIXEL_text_angle,
    null_justify_text, line_and_point, do_arrow, set_font_null,
    0, 0, 0, 0, SIXEL_fillbox, SIXEL_linewidth
#ifdef USE_MOUSE
    , NULL, NULL, NULL, NULL, NULL
#endif
    , SIXEL_make_palette, NULL, SIXEL_set_color
    , SIXEL_filled_polygon
    , NULL /* image */
    , NULL, NULL, NULL
    , NULL
    , NULL
    , 0.
    , NULL
#ifdef EAM_BOXED_TEXT
    , NULL
#endif 
    , NULL
    , SIXEL_dashtype
TERM_TABLE_END(sixel_driver)

#undef LAST_TERM
#define LAST_TERM sixel_driver

#endif /* SIXEL */

#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_driver

#endif /* BITGRAPH */

#endif /* TERM_TABLE */

#endif /* TERM_PROTO_ONLY */

#ifdef TERM_HELP
START_HELP(tek40)
"1 tek40",
"?commands set terminal tek40xx",
"?set terminal tek40xx",
"?set term tek40xx",
"?terminal tek40xx",
"?term tek40xx",
"?tek40",
"?commands set terminal vttek",
"?set terminal vttek",
"?set term vttek",
"?terminal vttek",
"?term vttek",
"?vttek",
"?commands set terminal xterm",
"?set terminal xterm",
"?set term xterm",
"?terminal xterm",
"?term xterm",
"?xterm",
#ifdef KERMIT
"?commands set terminal kc-tek40xx",
"?set terminal kc-tek40xx",
"?set term kc-tek40xx",
"?terminal kc-tek40xx",
"?term kc-tek40xx",
"?kc-tek40xx",
"?commands set terminal km-tek40xx",
"?set terminal km-tek40xx",
"?set term km-tek40xx",
"?terminal km-tek40xx",
"?term km-tek40xx",
"?km-tek40xx",
#endif
#ifdef SELANAR
"?commands set terminal selanar",
"?set terminal selanar",
"?set term selanar",
"?terminal selanar",
"?term selanar",
"?selanar",
#endif
#ifdef SIXEL
"?commands set terminal sixel",
"?set terminal sixel",
"?set term sixel",
"?terminal sixel",
"?term sixel",
"?sixel",
" Syntax:",
"    set terminal sixel {<fontsize>} {color|mono} {size <x>,<y>}",
"",
" The `sixel` output format was originally used by DEC terminals and printers.",
" For use with xterm emulation, xterm must be compiled/configured with",
" \"--enable-sixel-graphics\" and started with \"-ti 340\" on the command line.",
" Menu option \"sixelScrolling\" should be selected. xterm/vt340 emulation",
" limits plots to 16 simultaneous colors, but other emulators may permit more.",
#endif
#ifdef BITGRAPH
"?commands set terminal bitgraph",
"?set terminal bitgraph",
"?set term bitgraph",
"?terminal bitgraph",
"?term bitgraph",
"?bitgraph",
#endif
" This family of terminal drivers supports a variety of VT-like terminals.",
" `tek40xx` supports Tektronix 4010 and others as well as most TEK emulators.",
" `vttek` supports VT-like tek40xx terminal emulators.",
" The following are present only if selected when gnuplot is built:",
" `kc-tek40xx` supports MS-DOS Kermit Tek4010 terminal emulators in color;",
" `km-tek40xx` supports them in monochrome. `selanar` supports Selanar graphics.",
" `bitgraph` supports BBN Bitgraph terminals.",
" None have any options."
END_HELP(tek40)
#endif /* TERM_HELP */