[comp.sources.amiga] v02i034: vt100 2.6 -w- tektronix support

ng@s.cc.purdue.edu.UUCP (10/02/87)

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# Xshar: Extended Shell Archiver.
# This is part  3 out of  3.
# This archive created: Fri Oct  2 13:14:34 1987
# By: Craig Norborg (Purdue University Computing Center)
#	Run the following text with /bin/sh to create:
#	expand.c
#	tek.c
#	vt100.c
#	window.c
cat << \SHAR_EOF > expand.c
/*************************************************************
 * vt100 terminal emulator - Wild card and Directory support
 *
 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
 *	v2.5 870214 DBW - more additions (see readme file)
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW	- new features (see README)
 *           860830 Steve Drew Added Wild card support,
 *		    features(expand.c)
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *      Much of the code from this module extracted from
 *      Matt Dillons Shell program. (Thanxs Matt.)
 *************************************************************/

#include "vt100.h"

struct DPTR {                    /* Format of directory fetch ptr */
   struct FileLock *lock;        /* lock on directory   */
   struct FileInfoBlock *fib;    /* mod'd fib for entry */
};

/*
 * Disk directory routines
 *
 *
 * diropen() returns a struct DPTR, or NULL if the given file does not
 * exist.  stat will be set to 1 if the file is a directory.  If the
 * name is "", then the current directory is openned.
 *
 * dirnext() returns 1 until there are no more entries.  The **name and
 * *stat are set.  *stat = 1 if the file is a directory.
 *
 * dirclose() closes a directory channel.
 *
 */

struct DPTR *
diropen(name, stat)
char *name;
int *stat;
{
   struct DPTR *dp;
   int namelen, endslash = 0;
   struct FileLock *MyLock;
   
   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
                                 (FindTask(NULL)))->pr_CurrentDir);
   namelen = strlen(name);
   if (namelen && name[namelen - 1] == '/') {
      name[namelen - 1] = '\0';
      endslash = 1;
   }
   *stat = 0;
   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
   if (*name == '\0') 
      dp->lock = (struct FileLock *)DupLock (MyLock);
   else
      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
   if (endslash)
      name[namelen - 1] = '/';
   if (dp->lock == NULL) {
      free (dp);
      return (NULL);
   }
   dp->fib = (struct FileInfoBlock *)
         AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
   if (!Examine (dp->lock, dp->fib)) {
      dirclose (dp);
      return (NULL);
   }
   if (dp->fib->fib_DirEntryType >= 0)
      *stat = 1;
   return (dp);
}

dirnext(dp, pname, stat)
struct DPTR *dp;
char **pname;
int *stat;
{
   if (dp == NULL)
      return (0);
   if (ExNext (dp->lock, dp->fib)) {
      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
      *pname = dp->fib->fib_FileName;
      return (1);
   }
   return (0);
}


dirclose(dp)
struct DPTR *dp;
{
   if (dp == NULL)
      return (1);
   if (dp->fib)
      FreeMem (dp->fib, (long)sizeof(*dp->fib));
   if (dp->lock)
      UnLock (dp->lock);
   free (dp);
   return (1);
}

free_expand(av)
char **av;
{
   char **base = av;

   if (av) {
      while (*av) {
         free (*av);
         ++av;
      }
      free (base);
   }
}

/*
 * EXPAND(wild_name, pac)
 *    wild_name      - char * (example: "df0:*.c")
 *    pac            - int  *  will be set to # of arguments.
 *
 */


char **
expand(base, pac)
char *base;
int *pac;
{
   char **eav = (char **)malloc (sizeof(char *));
   int  eleft, eac;

   char *ptr, *name;
   char *bname, *ename, *tail;
   int stat, scr;
   struct DPTR *dp;

   *pac = eleft = eac = 0;
   base = strcpy(malloc(strlen(base)+1), base);
   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
   if (ptr < base) {
      bname = strcpy (malloc(1), "");
   } else {
      scr = ptr[1];
      ptr[1] = '\0';
      bname = strcpy (malloc(strlen(base)+1), base);
      ptr[1] = scr;
   }
   ename = ptr + 1;
   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
   scr = *ptr;
   *ptr = '\0';
   tail = (scr) ? ptr + 1 : NULL;

   if ((dp = diropen (bname, &stat)) == NULL  ||  stat == 0) {
      free (bname);
      free (base);
      free (eav);
      req ("Could not open directory","",0);
      return (NULL);
   }
   while (dirnext (dp, &name, &stat)) {
      if (compare_ok(ename, name)) {
         if (tail) {
            int alt_ac;
            char *search, **alt_av, **scrav;
            struct FileLock *lock;

            if (!stat)      /* expect more dirs, but this not a dir */
               continue;
            lock = (struct FileLock *)CurrentDir (dp->lock);
            search = malloc(strlen(name)+strlen(tail)+2);
            strcpy (search, name);
            strcat (search, "/");
            strcat (search, tail);
            scrav = alt_av = expand (search, &alt_ac);
            CurrentDir (lock);
            if (scrav) {
               while (*scrav) {
                  if (eleft < 2) {
                     char **scrav = (char **)
			malloc(sizeof(char *) * (eac + 10));
                     movmem (eav, scrav, sizeof(char *) * (eac + 1));
                     free (eav);
                     eav = scrav;
                     eleft = 10;
                  }
                  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
                  strcpy(eav[eac], bname);
                  strcat(eav[eac], *scrav);
                  free (*scrav);
                  ++scrav;
                  --eleft, ++eac;
               }
               free (alt_av);
            }
         } else {
            if (eleft < 2) {
               char **scrav = (char **)
		    malloc(sizeof(char *) * (eac + 10));
               movmem (eav, scrav, sizeof(char *) * (eac + 1));
               free (eav);
               eav = scrav;
               eleft = 10;
            }
            eav[eac] = malloc (strlen(bname)+strlen(name)+1);
            eav[eac] = strcpy(eav[eac], bname);
            strcat(eav[eac], name);
            --eleft, ++eac;
         }
      }
   }
   dirclose (dp);
   *pac = eac;
   eav[eac] = NULL;
   free (bname);
   free (base);
   if (eac)
      return (eav);
   free (eav);
   return (NULL);
}

/*
 * Compare a wild card name with a normal name
 */

#define MAXB   8

compare_ok(wild, name)
char *wild, *name;
{
   char *w = wild;
   char *n = name;
   char *back[MAXB][2];
   int  bi = 0;

   while (*n || *w) {
      switch (*w) {
      case '*':
         if (bi == MAXB) {
            req ("Too many levels of '*'","",0);
            return (0);
         }
         back[bi][0] = w;
         back[bi][1] = n;
         ++bi;
         ++w;
         continue;
goback:
         --bi;
         while (bi >= 0 && *back[bi][1] == '\0')
            --bi;
         if (bi < 0)
            return (0);
         w = back[bi][0] + 1;
         n = ++back[bi][1];
         ++bi;
         continue;
      case '?':
         if (!*n) {
            if (bi)
               goto goback;
            return (0);
         }
         break;
      default:
         if (toupper(*n) != toupper(*w)) {
            if (bi)
               goto goback;
            return (0);
         }
         break;
      }
      if (*n)  ++n;
      if (*w)  ++w;
   }
   return (1);
}

set_dir(new)
char *new;
{
   register 	char 		*s;
   int   			i;
   struct 	FileLock 	*lock;
   char 			temp[60];
   struct       FileInfoBlock   *fib;
  
   if (*new != '\000') {
      strcpy(temp, MyDir);
      s = new;
      if (*s == '/') {
         s++;
         for (i=strlen(MyDir);
              MyDir[i] != '/' && MyDir[i] != ':';
              i--);
         MyDir[i+1] = '\0';
         strcat(MyDir, s);
         }
      else if (exists(s, ':') == 0) {
         if (MyDir[strlen(MyDir)-1] != ':')
            strcat(MyDir, "/");
         strcat(MyDir, s);
         }
      else
         strcpy(MyDir, s);

      if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
         req("Directory not found:",MyDir,0);
         strcpy(MyDir, temp);
         }
      else {
	 fib = (struct FileInfoBlock *)AllocMem(
		(long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
	 if (fib) {
      	    if (Examine(lock, fib)) {
      		if (fib->fib_DirEntryType > 0) {
		    CurrentDir(lock);
		    if (MyDirLock != NULL) UnLock(MyDirLock);
		    MyDirLock = lock;
		    if (MyDir[strlen(MyDir)-1] == '/')
			MyDir[strlen(MyDir)-1] = '\000';
		    }
		else {
            	    req("Not a Directory:",MyDir,0);               
            	    strcpy(MyDir,temp);
		    }
		}
	    FreeMem(fib, (long)sizeof(struct FileInfoBlock));
	    }
	else {
	    req("Can't change directory... ","No free memory!",0);
	    strcpy(MyDir,temp);
	    }
	}
    }
}

exists(s,c)
char *s,c;
    {
    while (*s != '\000')
	if (*s++ == c) return(1);
    return(0);
    }
SHAR_EOF
cat << \SHAR_EOF > tek.c
/* This module is a minimum extenal hooks tek 4010 emulation, the
 * function InitTek() must be called before any of the others, it
 * assumes that gfx, intuition are open. Tek() returns true if it
 * uses the input stream else false. It must be called before any 
 * character parsing or you could get into trouble. CloseTek() Frees
 * up all resources used by this module */

/* I had to invent a few commands for area fill reset screen, and
 * color setting. Any one who knows the correct commands please let me
 * know  the line drawing and color index selection are standard commands.
 * I have vax software to drive the 640x400 mode, and it works really well.
 * the 1024x780 mode is not quite as clear, but works ok.
 * The author of this software can be contacted as:
 * T.Whelan
 * Dept. of Physics & Astronomy
 * University of Iowa
 * Iowa City
 * IA 52244
 * and on span at IOWA::WHELAN

 * on the "to do" list, are graphic input mode and run time selection
 * of the screen resolution. */

/******************************************************************/
/*		Now built on top of vt100 v2.6
/*		Mods added by NG	4-87
/******************************************************************/

/*  compiler directives to fetch the necessary header files */

#include "vt100.h"
#include <graphics/display.h>

/*********************** tek defaults *******************************/
int	t_scale = 0; /* 0->1024x780	1->640x400 resolution	*/
int	t_on    = 0; /* 0 = no  1 = yes  come up with tek screen on */
int	t_depth = 1; /* depth of tek screen					*/
int	t_interlace = 1; /* interlace tek screen  0=no  1=yes	*/

int TekMode = FALSE;
/* global pointers, used only in this code module */
struct Screen	   *TekScreen;
struct Window      *TekWindow;
void *TekFillRas;	/* was an int * in 1.1	*/
int Tek_screen_open = 0;	/* new variable added by NG	*/
extern void * AllocRaster();	/* was an int * in 1.1	*/
/* macros... */
#define mrp TekWindow->RPort
#define COLOR(i, j, k, l) SetRGB4(&TekScreen->ViewPort, i, j, k, l)


/* this macro puts the tek screen at the back
 * and sets things so that the user gets the
 * non-tek mode of operation, there are some problems here
 * as we do not use intuition to control window positions */
#define TekOFF() {TekMode = FALSE; \
		  ScreenToBack(TekScreen); }

#define clear() SetRast(mrp, 0L); /* set the screen to color Zero */

/* the screen size */
#define xmin 0
#define ymin 0 
#define xmax 640		/* changed from old tek version		*/
#define ymax 400

struct NewScreen TekNewScreen = { 
   xmin, ymin,
   xmax, ymax, 1,		/* 1 bit plane is now the default */
   0, 1,
   HIRES|INTERLACE,		/* now the default	*/
   CUSTOMSCREEN,
   NULL,
   NULL,
   NULL,
   NULL
   };

struct NewWindow TekNewWindow = {
   xmin, ymin,
   xmax, ymax,
   1, 0,
   RAWKEY, 	/* No IDCMP flags */
   BORDERLESS|NOCAREREFRESH|SMART_REFRESH,
   NULL,
   NULL,
   NULL,
   NULL,
   NULL,
   0, 0,
   0, 0,
   CUSTOMSCREEN
   };

/********  tek menu stuff  *******/
struct MenuItem TekItem[TekParamsMax];
struct IntuiText TekText[TekParamsMax];
struct MenuItem TekScaleItem[TekScaleMax];
struct IntuiText TekScaleText[TekScaleMax];
struct MenuItem TekDepthItem[TekDepthMax];
struct IntuiText TekDepthText[TekDepthMax];
struct MenuItem TekInterlaceItem[TekInterlaceMax];
struct IntuiText TekInterlaceText[TekInterlaceMax];
struct MenuItem TekScreenItem[TekScreenMax];
struct IntuiText TekScreenText[TekScreenMax];
struct MenuItem TekSelectItem[TekSelectMax];
struct IntuiText TekSelectText[TekSelectMax];


/* initalize the window and screen needed for this mode
 * inituition and gfx are assumed open */
/* was called InitTek in old version - now this function just opens
the tek screen so rename it 	*/

OpenTek(HisPort)			
struct MsgPort *HisPort;
{  
static struct AreaInfo ai;
static WORD buffer[250];
static struct TmpRas tr;

if(doing_init == 1)
	return(FALSE);
if(Tek_screen_open == 1)
	return(FALSE);
TekScreen = (struct Screen *)OpenScreen(&TekNewScreen);
if (TekScreen == NULL) {
	emits("Cannot open Tek screen\n");
	return TRUE;
}

TekNewWindow.Screen = TekScreen;
TekWindow = (struct Window *)OpenWindow(&TekNewWindow);
if (TekWindow == NULL){
	emits("Cannot open Tek window\n");
	return TRUE;
}

/* make HisPort the User Port for this window, so that his
 * read routines will work when my screen is active
 */
TekWindow->UserPort = HisPort;
ModifyIDCMP(TekWindow, RAWKEY|MENUPICK);

/* allow for area fill */
InitArea (&ai, buffer, 100L);
mrp->AreaInfo = &ai;
TekFillRas = AllocRaster((long)xmax, (long)ymax);
/* mrp->TmpRas = InitTmpRas(&tr, TekFillRas, RASSIZE((long)xmax, (long)ymax)); 		this worked with 1.1 */
InitTmpRas(&tr, TekFillRas, RASSIZE((long)xmax, (long)ymax)); 

reset();

TekOFF();
Tek_screen_open = 1;	/* added by NG	*/
return FALSE; /* no errors detected */
}


InitTekDev()
{
if(t_on == 1)
	OpenTek();
}

CloseTek()
{
 if(Tek_screen_open == 0)
 	return;
 TekMode = FALSE;
 FreeRaster(TekFillRas,(long)xmax,(long)ymax);
 TekWindow->UserPort = NULL; /* I will not close his port */
 CloseWindow(TekWindow);
 CloseScreen(TekScreen);
 Tek_screen_open = 0;
}


/*************************************************
* Function to do tek 4010 graphics and mode
* switching, the function returns false if it
* uses the character else the
* character can be used for something else
*************************************************/


int Tek(c)
char c;
{
#define dx 8
#define dy 10

static int x = xmin, xl;
static int y = ymin + dy, yl;
static int last, escmode = FALSE, boxmode = FALSE;
static int loy, hix, hiy;

/* static enum {alpha, line, move, point} mode;	*/
/* manx 3.2 did not have enum data types	*/

#define alpha	1
#define line	2
#define	move	3
#define point	4
static int	mode;

static colormode = NULL, index, red, green;
#define COLORSET  1024
static int tk4100 = NULL;
static int ic = 1;
static int lastc = 1;

if (TekMode) goto top;
if (c == 29) {
    TekMode = TRUE;
    if(Tek_screen_open == 0)
        return TRUE;
    ScreenToFront(TekScreen);
    mode = move;
    }
return TekMode; /* i.e. if c== 29 we used it and can leave */
top:
/* first handle case if graph is sent without having the tek screen
 * turned on; just eat the graphics commands until the graph is
 * finished - then turn back to text mode
 * also make this selanar compatible
 */
	if(Tek_screen_open == 0) {  
		if((c == 24) || ((lastc == 27) && (c == 50)))
			TekMode = FALSE;	 /* turn tek mode off	*/
		lastc = c;
		return TRUE;
	}
/*
if(mode == alpha) {
	emit(c);
	emit(13);
	emit(10);
}
*/

if (escmode)
	{
	if (colormode != (int)NULL) {
	   c = c - 48;
	   colormode++;
	   if (colormode == 2)
	      index = c;
	   else if (colormode == 3)
	      red = c;
	   else if (colormode == 4)
	      green = c;
	   else if (colormode == 5) {
	   	COLOR((long)index, (long)red, (long)green, (long)c);
	   	colormode = NULL;
	   	escmode = FALSE;
		}
	   return TekMode;
	}
	switch (c)
	{
	case '2':    /* Selanar Compatable graphics terminator */
          TekOFF();
          boxmode = FALSE;
	break;
/* I do not know what the tek 4100 area fill commands are so I made-up
   my own, this will not harm the line drawing mode. */
	case 'A':
	   boxmode = TRUE;
	break;
	case 'B':
	  boxmode = FALSE;
	break;
	case 'Q':
	  colormode = 1;
	return TekMode;
/* another one of my own commands */
	case 'R':   /* reset to default then clear screen */
	    reset();
	    ic = 1;
	case 12:     /* clear page */
             x = xmin;
             y = ymin + dy;
	    mode = alpha;
	    tk4100 = NULL;
	    clear();
	break;
	case 'M':  /* looks like a 4100 command */
	     tk4100 = 'M';
	break;
	}
	escmode = FALSE;
	}
else if (tk4100 != (int)NULL)
	{
	if (tk4100 == COLORSET)
	   ic = c - 48;
	   SetAPen(mrp, (long)ic);
	  
	if (tk4100 == 'M' && c == 'L')  
	   tk4100 = COLORSET;
	else
	    tk4100 = NULL;
	}
else if (c >= 32)
	if (mode == alpha)
	  {
	  if(xl > xmax-dx) xl = xmax-dx;
	  if(xl < xmin) xl = xmin;
	  if(yl < ymin+dy) yl = ymin+dy;
	  if(yl > ymax) yl = ymax;

	  SetAPen(mrp, 1L);
	  Move(mrp,(long)xl,(long)yl);
	  Text(mrp,&c,1L);
	  SetAPen(mrp, (long)ic);
	  xl += dx;
	  if (xl > xmax) xl = xmax;		
	  }
	else
	  {
		/* a note here about 4014 graphics, If your graphics software
		   drives a Tek 4014 then this will work perfecly well, you
		   just will not be able to use the 4096 pixel resolution
		   that that big storage tube device offers */
	  register int tag, data, x, y;
	  tag = c/32;
	  data = c - tag*32;
	  switch (tag)
	  {
	  case 1:
	    if (last == 3)
	        hix = data*32;
	    else
	        hiy = data*32;
	  break;
	  case 2:
	     x = hix + data;   /* low x always sent so don't save it */
	     y = hiy + loy;
	     if (t_scale == 0)
	       {
	       x = (((float)x)*xmax)/1024;
	       y = (((float)y)*ymax)/780;
	       }
	       x = x/(2-t_interlace);
	       y = (ymax-1) -  (y/(2-t_interlace));
		if(x > xmax) x = xmax;
		if(x < xmin) x = xmin;
		if(y > ymax) y = ymax;
		if(y < ymin) y = ymin;
	     switch (mode)
	     {
	     case move:
	     	mode = line;
	     	Move(mrp, (long)x, (long)y);
	     break;
	     case line:
	        if (boxmode)
		  RectFill(mrp, (long)min((int)xl,(int)x), 
			(long)min((int)yl,(int)y), (long)max((int)xl,(int)x),
			(long)max((int)yl,(int)y));
	        else
	     	  Draw(mrp, (long)x, (long)y);
	     break;
	     case point:
	        WritePixel(mrp, (long)x, (long)y);
	      break;
	      }
	  xl = x;
	  yl = y;
	  break;
	  case 3:
	     loy = data;
	  break;
	  }
	  last = tag; 
	  }
else    switch(c)
	{
	case 7:     /* bell */
	     DisplayBeep(NULL);
	break;
	case 8:   /* backspace */
           x -= dx;
           if (x < xmin) x = xmin;
        break;
	case 9:  /* cursor right */
	   x += dx;
	   if (x > xmax) x = xmax;
	break;
	case 10: /* NL */
	     y += dy;
	     if (y > ymax) y = ymax;
	break;
	case 11: /* cursor up */
	     y -= dy;
	     if (y < ymin+dy) y = ymin+dy;
	break;
	case 13:  /* CR */
             x = xmin;
	break;
	case 24:  /* CAN */
	    TekOFF();
	    boxmode = FALSE;
	break;
	case 27:  /* ESC */
	     escmode = TRUE;
	break;
	case 28:  /* FS (point-plot) */
	     mode = point;
	break;
	case 29:  /* GS vector */
	     mode = move;
	break;
	case 31: /* alpha mode */
	     mode = alpha;
	break;
	default:
	break;
      } /* end of switch */
      return TRUE;
}
reset()
{
/* mess up the colors */
COLOR(0L, 0L, 0L, 0L);
COLOR(1L, 15L, 15L, 15L);
COLOR(2L, 15L, 0L, 0L);
COLOR(3L, 0L, 15L, 0L);
COLOR(4L, 0L, 0L, 15L);
COLOR(5L, 0L, 15L, 15L);
COLOR(6L, 15L, 0L, 15L);
COLOR(7L, 15L, 15L, 0L);
COLOR(8L, 15L, 8L, 0L);
COLOR(9L, 8L, 15L, 0L);
COLOR(10L,0L, 15L, 8L);
COLOR(11L,0L, 8L, 15L);
COLOR(12L,8L, 0L, 15L);
COLOR(13L,15L, 0L, 8L);
COLOR(14L,5L, 5L, 5L);
COLOR(15L,10L, 10L, 10L);

clear();
SetAPen(mrp, 1L); 
}

max(a,b)
int a,b;
{
if(a >= b) return(a);
return(b);
}

min(a,b)
int a,b;
{
if(a <= b) return(a);
return(b);
}

/*****************************************************************/
/*	Intialize the structure arrays needed for
/*		the Tek menu items
/*****************************************************************/
char keycommands[] = " TVEQ";
char otherkeys[] = "NY";

void
InitTekItems()	
{
	int n;

	for(n=0; n<TekParamsMax; n++) {
		TekItem[n].NextItem = &TekItem[n+1];
		TekItem[n].LeftEdge = 0;
		TekItem[n].TopEdge = 10 * n;
		TekItem[n].Width = 100;
		TekItem[n].Height = 10;
		TekItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
		TekItem[n].MutualExclude = 0;
		TekItem[n].ItemFill = (APTR)&TekText[n];
		TekItem[n].SelectFill = NULL;
		TekItem[n].Command = 0;

		TekText[n].FrontPen = 0;
		TekText[n].BackPen = 1;
		TekText[n].DrawMode = JAM2;
		TekText[n].LeftEdge = 0;
		TekText[n].TopEdge = 1;
		TekText[n].ITextFont = NULL;
		TekText[n].NextText = NULL;
	}
	TekItem[TekParamsMax - 1].NextItem = NULL;

	TekText[0].IText = (UBYTE *)"Scale";
	TekText[1].IText = (UBYTE *)"Screen Depth";
	TekText[2].IText = (UBYTE *)"Interlace";
	TekItem[0].SubItem = TekScaleItem;
	TekItem[1].SubItem = TekDepthItem;
	TekItem[2].SubItem = TekInterlaceItem;

	for(n=0; n<TekScaleMax; n++) {
		TekScaleItem[n].NextItem = &TekScaleItem[n+1];
		TekScaleItem[n].LeftEdge = 60;
		TekScaleItem[n].TopEdge = 10 * n;
		TekScaleItem[n].Width = 100;
		TekScaleItem[n].Height = 10;
		TekScaleItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
		TekScaleItem[n].MutualExclude = (~(1 << n));
		TekScaleItem[n].ItemFill = (APTR)&TekScaleText[n];
		TekScaleItem[n].SelectFill = NULL;
		TekScaleItem[n].Command = 0;

		TekScaleText[n].FrontPen = 0;
		TekScaleText[n].BackPen = 1;
		TekScaleText[n].DrawMode = JAM2;
		TekScaleText[n].LeftEdge = 0;
		TekScaleText[n].TopEdge = 1;
		TekScaleText[n].ITextFont = NULL;
		TekScaleText[n].NextText = NULL;
	}
	TekScaleItem[TekScaleMax - 1].NextItem = NULL;

	switch(t_scale) {
		case 0:
			TekScaleItem[0].Flags |= CHECKED;
			break;
		case 1:
			TekScaleItem[1].Flags |= CHECKED;
			break;
	}

	TekScaleText[0].IText = (UBYTE *)"   1028x780";
	TekScaleText[1].IText = (UBYTE *)"   640x400";

	for(n=0; n<TekDepthMax; n++) {
		TekDepthItem[n].NextItem = &TekDepthItem[n+1];
		TekDepthItem[n].LeftEdge = 60;
		TekDepthItem[n].TopEdge = 10 * n;
		TekDepthItem[n].Width = 60;
		TekDepthItem[n].Height = 10;
		TekDepthItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
		TekDepthItem[n].MutualExclude = (~(1 << n));
		TekDepthItem[n].ItemFill = (APTR)&TekDepthText[n];
		TekDepthItem[n].SelectFill = NULL;
		TekDepthItem[n].Command = 0;

		TekDepthText[n].FrontPen = 0;
		TekDepthText[n].BackPen = 1;
		TekDepthText[n].DrawMode = JAM2;
		TekDepthText[n].LeftEdge = 0;
		TekDepthText[n].TopEdge = 1;
		TekDepthText[n].ITextFont = NULL;
		TekDepthText[n].NextText = NULL;
	}
	TekDepthItem[TekDepthMax - 1].NextItem = NULL;

	TekDepthText[0].IText = (UBYTE *)"    1";
	TekDepthText[1].IText = (UBYTE *)"    2";
	TekDepthText[2].IText = (UBYTE *)"    3";
	TekDepthText[3].IText = (UBYTE *)"    4";

	switch(t_depth) {
		case 1:
			TekDepthItem[0].Flags |= CHECKED;
			break;
		case 2:
			TekDepthItem[1].Flags |= CHECKED;
			break;
		case 3:
			TekDepthItem[2].Flags |= CHECKED;
			break;
		case 4:
			TekDepthItem[3].Flags |= CHECKED;
			break;
	}

	for(n=0; n<TekInterlaceMax; n++) {
		TekInterlaceItem[n].NextItem = &TekInterlaceItem[n+1];
		TekInterlaceItem[n].LeftEdge = 60;
		TekInterlaceItem[n].TopEdge = 10 * n;
		TekInterlaceItem[n].Width = 60;
		TekInterlaceItem[n].Height = 10;
		TekInterlaceItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
		TekInterlaceItem[n].MutualExclude = (~(1 << n));
		TekInterlaceItem[n].ItemFill = (APTR)&TekInterlaceText[n];
		TekInterlaceItem[n].SelectFill = NULL;
		TekInterlaceItem[n].Command = 0;

		TekInterlaceText[n].FrontPen = 0;
		TekInterlaceText[n].BackPen = 1;
		TekInterlaceText[n].DrawMode = JAM2;
		TekInterlaceText[n].LeftEdge = 0;
		TekInterlaceText[n].TopEdge = 1;
		TekInterlaceText[n].ITextFont = NULL;
		TekInterlaceText[n].NextText = NULL;
	}
	TekInterlaceItem[TekInterlaceMax - 1].NextItem = NULL;

	TekInterlaceText[0].IText = (UBYTE *)"   Off";
	TekInterlaceText[1].IText = (UBYTE *)"   On";

	switch(t_interlace) {
		case 0:
			TekInterlaceItem[0].Flags |= CHECKED;
			break;
		case 1:
			TekInterlaceItem[1].Flags |= CHECKED;
			break;
	}


	for(n=0; n<TekScreenMax; n++) {
		TekScreenItem[n].NextItem = &TekScreenItem[n+1];
		TekScreenItem[n].LeftEdge = 0;
		TekScreenItem[n].TopEdge = 10 * n;
		TekScreenItem[n].Width = 140;
		TekScreenItem[n].Height = 10;
		TekScreenItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
		TekScreenItem[n].MutualExclude = 0;
		TekScreenItem[n].ItemFill = (APTR)&TekScreenText[n];
		TekScreenItem[n].SelectFill = NULL;
		if(n != 0) {
			TekScreenItem[n].Command = keycommands[n];
			TekScreenItem[n].Flags |= COMMSEQ;
			}
		else
			TekScreenItem[n].Command = 0;

		TekScreenText[n].FrontPen = 0;
		TekScreenText[n].BackPen = 1;
		TekScreenText[n].DrawMode = JAM2;
		TekScreenText[n].LeftEdge = 0;
		TekScreenText[n].TopEdge = 1;
		TekScreenText[n].ITextFont = NULL;
		TekScreenText[n].NextText = NULL;
	}
	TekScreenItem[TekScreenMax - 1].NextItem = NULL;

	TekScreenText[0].IText = (UBYTE *)"  TekScreen";
	TekScreenText[1].IText = (UBYTE *)"  Tek Front";
	TekScreenText[2].IText = (UBYTE *)"  VT  Front";
	TekScreenText[3].IText = (UBYTE *)"  Erase";
	TekScreenText[4].IText = (UBYTE *)"  Quit";

	TekScreenItem[0].SubItem = TekSelectItem;

	for(n=0; n<TekSelectMax; n++) {
		TekSelectItem[n].NextItem = &TekSelectItem[n+1];
		TekSelectItem[n].LeftEdge = 60;
		TekSelectItem[n].TopEdge = 10 * n;
		TekSelectItem[n].Width = 100;
		TekSelectItem[n].Height = 10;
		TekSelectItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT
		| COMMSEQ;
		TekSelectItem[n].MutualExclude = (~(1 << n));
		TekSelectItem[n].ItemFill = (APTR)&TekSelectText[n];
		TekSelectItem[n].SelectFill = NULL;
		TekSelectItem[n].Command = otherkeys[n];

		TekSelectText[n].FrontPen = 0;
		TekSelectText[n].BackPen = 1;
		TekSelectText[n].DrawMode = JAM2;
		TekSelectText[n].LeftEdge = 0;
		TekSelectText[n].TopEdge = 1;
		TekSelectText[n].ITextFont = NULL;
		TekSelectText[n].NextText = NULL;
	}
	TekSelectItem[TekSelectMax - 1].NextItem = NULL;

/*	switch(t_on) {
		case 0:
			TekSelectItem[0].Flags |= CHECKED;
			break;
		case 1:
			TekSelectItem[1].Flags |= CHECKED;
			break;
	} 
*/

	TekSelectItem[t_on].Flags |= CHECKED;

	TekSelectText[0].IText = (UBYTE *)"    Off";
	TekSelectText[1].IText = (UBYTE *)"    On";
}

/****************************************************************/
/*	The following function inits the Menu structure array with 
/*		the tek menu items			                    
/****************************************************************/
void 
InitTekMenu()
{
menu[4].NextMenu = &menu[5];
menu[4].LeftEdge = 300;
menu[4].TopEdge = 0;
menu[4].Width = 85;
menu[4].Height = 10;
menu[4].Flags = MENUENABLED;
menu[4].MenuName = "Tek params";        /* text for menu-bar display */
menu[4].FirstItem = &TekItem[0]; /* pointer to first item in list */

menu[5].NextMenu = NULL;
menu[5].LeftEdge = 390;
menu[5].TopEdge = 0;
menu[5].Width = 60;
menu[5].Height = 10;
menu[5].Flags = MENUENABLED;
menu[5].MenuName = "Screen";   /* text for menu-bar display */
menu[5].FirstItem = &TekScreenItem[0];  /* pointer to first item in list */

}

void
t_cmd_scale(n)
char *n;
{
	t_scale = atoi(n);
}

void
t_cmd_depth(n)
char *n;
{
	if(t_depth != atoi(n)) {
		t_depth = atoi(n);
		if(Tek_screen_open == 1) {
			CloseTek();
			TekNewScreen.Depth = t_depth;
			OpenTek(mywindow->UserPort);
		}
	}
}

void
t_cmd_on(n)
char *n;
{
	if(t_on != atoi(n)) {
		t_on = atoi(n);
		if(t_on == 0)
			CloseTek();
		else
			OpenTek(mywindow->UserPort);
	}
}

void 
t_cmd_interlace(n)
char *n;
{
	if(t_interlace != atoi(n)) {
		t_interlace = atoi(n);
		if(Tek_screen_open == 1) {
			CloseTek();
			if(t_interlace == 0) 
				TekNewScreen.ViewModes |= ~INTERLACE;
			else 
				TekNewScreen.ViewModes |= INTERLACE;
			OpenTek(mywindow->UserPort);
		}
	}
}

void
t_cmd_null(n)
char *n;
{ }

struct COMMAND {
    void (*func)();
    char *cname;
    };

/********************** command tables *******************************/
static struct COMMAND Tekcmds[] = {	/* initialization commands */
    t_cmd_scale,     "ts",		/* set tek scale 	*/
    t_cmd_on,        "to",		/* set tek screen on or off	*/
    t_cmd_interlace, "ti",		/* set tek interlace on or off	*/
    t_cmd_depth,     "td",		/* set tek screen depth 	    */
    t_cmd_null,      NULL		/* end of list		*/
    };

exe_t_cmd(p,l)
char *p;
int l;
    {
    int i,l2;

    /* search in the tek command list */
	for (i=0; Tekcmds[i].func != cmd_null; ++i) {
	    l2 = strlen(Tekcmds[i].cname);
	    if (l >= l2 && strncmp(p, Tekcmds[i].cname, l2) == 0) {
		(*Tekcmds[i].func)(next_wrd(p+l, &l));
		return(TRUE);
		}
	    }

    }
SHAR_EOF
cat << \SHAR_EOF > vt100.c
/********************************************************************
 *  vt100 terminal emulator with xmodem transfer capability
 *
 *	v2.65		NG  - added tek4014 emulation
 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
 *	v2.5 870214 DBW - more additions (see readme file)
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860901 ACS - Added Parity and Word Length and support code
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *  use <esc> to abort xmodem or kermit transfers
 *
 *  written by Michael Mounier
 *  new version by Dave Wecker
 *******************************************************************/

/*  all includes defines and globals */
#include "vt100.h"

/**************************************************************/
/* here are all the global definitions that appear in vt100.h */
/**************************************************************/

char    bufr[BufSize];
int     fd, timeout = FALSE, ttime;
int	multi = FALSE, server;
long    bytes_xferred;
char	MyDir[60];
struct	FileLock *MyDirLock = NULL;
struct	FileLock *StartLock = NULL;
struct	IntuitionBase *IntuitionBase;
struct	GfxBase *GfxBase;

struct	TextAttr myattr = {
    (STRPTR) "topaz.font",
    8,
    0,
    0};
struct	TextFont *myfont = NULL;
struct NewScreen NewScreen = {
   0L,0L,640L,200L,1L,       /* left, top, width, height, depth */
   0,1,HIRES,    /* DetailPen, BlockPen, ViewModes */
   CUSTOMSCREEN,&myattr,   /* Type, Font */
   (UBYTE *)"VT100", /* Title */
   NULL,NULL };         /* Gadgets, Bitmap */
struct NewWindow NewWindow = {
   0,0L,640L,200L,     /* left, top, width, height */
   0,1,              /* detailpen, blockpen */
   MENUPICK|CLOSEWINDOW|RAWKEY|REQCLEAR|REQSET|ACTIVEWINDOW|INACTIVEWINDOW,
   SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
   NULL,NULL,        /* FirstGadget, CheckMark */
   (UBYTE *)NULL,
   NULL,             /* set screen after open screen */
   NULL,             /* bitmap */
   640L, 200L, 640L, 200L,/* minw, minh, maxw, maxh */
   CUSTOMSCREEN      /* Type */
   };
struct IntuiText MyTitle = {
    0,1,JAM2,26,0,	/* front pen, back pen, mode, left, top */
    &myattr,		/* font */
    (UBYTE *)VERSION,	/* title */
    NULL};		/* next text */
struct Screen *myscreen = NULL;      /* ptr to applications screen */
struct Window *mywindow = NULL;     /* ptr to applications window */
struct ViewPort *myviewport;
struct RastPort *myrastport;
struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
struct Preferences  *Prefs;	    /* preferences from GetPrefs() */

/**** String requester support ******/

char	InpBuf[80],UndoBuf[80],Prompt[80];
struct IntuiText donetxt = {
    1,0,JAM2,0,0,	/* front pen, back pen, mode, left, top */
    &myattr,		/* font */
    (UBYTE *)"DONE",	/* question to ask */
    NULL};		/* next text */
struct Gadget mydonegad = {
    NULL,290,2,40,10,/* next,left,top,width,height */
    GADGHCOMP|REQGADGET,/* flags */
    RELVERIFY|ENDGADGET,/* activation */
    BOOLGADGET,		/* gadget type */
    NULL,NULL,&donetxt,	/* gad render, sel render, gad text */
    0L,NULL,2,NULL};	/* mutual exclude, special, ID, user data */
struct	StringInfo mystrinfo = {
    (UBYTE *)InpBuf,
    (UBYTE *)UndoBuf,
    0,80,0,0,0,0,	/* initial, max, disp, undo, #chrs, dsp chrs */
    0,0,NULL,0L,NULL};	/* left,top,layer,longint,keymap */
struct Gadget mystrgad = {
    &mydonegad,10,12,320,10,	/* next,left,top,width,height */
    GADGHCOMP|REQGADGET,/* flags */
    ENDGADGET,STRGADGET,/* activation, type */
    NULL,NULL,NULL,	/* gad render, sel render, gad text */
    0L,			/* mutual exclude */
    (APTR)&mystrinfo,	/* special info */
    1,NULL};		/* gadget ID, user data */
struct IntuiText mystrtxt = {
    0,1,JAM2,10,2,	/* front pen, back pen, mode, left, top */
    &myattr,		/* font */
    (UBYTE *)Prompt,	/* question to ask */
    NULL};		/* next text */
struct Requester myrequest = {
    NULL,200,40,340,22,	/* older requester, left, top, width, height */
    0,0,&mystrgad,	/* relleft reltop, gadgets */
    NULL,		/* border */
    &mystrtxt,		/* text */
    NULL,1,NULL,	/* flags, back fill pen, layer */
    {0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0},	/* pad1 */
    NULL,NULL,		/* image bit map, rquest window */
    {0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0} /* pad2 */
    };
int numreqs = 0;	/* number of outstanding requestors */

/***** menu structures *****/
struct MenuItem FileItem[FILEMAX];
struct IntuiText FileText[FILEMAX];
struct MenuItem CommItem[COMMAX];
struct IntuiText CommText[COMMAX];
struct MenuItem RSItem[RSMAX];
struct IntuiText RSText[RSMAX];
struct MenuItem ParItem[PARMAX];
struct IntuiText ParText[PARMAX];
struct MenuItem XFItem[XFMAX];
struct IntuiText XFText[XFMAX];
struct MenuItem ScriptItem[SCRIPTMAX];
struct IntuiText ScriptText[SCRIPTMAX];
struct MenuItem UtilItem[UTILMAX];
struct IntuiText UtilText[UTILMAX];
struct Menu menu[MAXMENU];
struct IOExtSer *Read_Request;
char *rs_in;
struct IOExtSer *Write_Request;
char rs_out[2];
struct timerequest Timer;
struct MsgPort *Timer_Port = NULL;
struct timerequest Script_Timer;
struct MsgPort *Script_Timer_Port = NULL;
struct IOAudio Audio_Request;
struct MsgPort *Audio_Port = NULL;
UBYTE  *BeepWave;
UBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
int x,y,curmode;
int MINX	= 0;
int MAXX	= 632;
int MINY	= 14;
int MAXY	= 198;
int top		= 14;
int bot		= 198;
int savx	= 0;
int savy	= 14;
int savmode	= 0;
int nlmode	= 0;
int alt		= 0;
int savalt	= 0;
int a[2]	= { 0, 0 };
int sa[2]	= { 0, 0 };
int  inesc	= -1;
int  inctrl	= -1;
int  private	= 0;
int  badseq	= 0;
int  maxcol	= 79;

/*************************** defaults *******************************/
int	p_baud	     = 2400;	    /* baud rate */
int	p_screen     = 1;	    /* 0 = WORKBENCH,	    1 = CUSTOM */
int	p_wbcolors   = 1;	    /* 0 = Custom, 1 = Workbench colors */
int	p_interlace  = 1;	    /* 0 = no interlace,    1 = interlace */
int	p_depth	     = 1;	    /* number of bit planes (1 or 2) */
int	p_foreground = 0x950;	    /* default foreground RGB color */
int	p_background = 0x000;	    /* default background RGB color */
int	p_bold	     = 0x900;	    /* default BOLD       RGB color */
int	p_cursor     = 0x009;	    /* default Cursor	  RGB color */
int	p_lines	     = 48;	    /* number of lines on the screen */
int	p_mode	     = 1;	    /* 0 = image, 1 = CRLF (for kermit) */
int	p_buffer     = 512;	    /* read buffer size (>= 512 bytes) */
int     p_parity     = 0;	    /* 0=none,1=mark,2=space,3=even,4=odd */
long	p_break	     = 750000;	    /* break time (in micro seconds) */
int	p_volume     = 64;	    /* beep volume (0 = DisplayBeep) */
int	p_wrap	     = 0;	    /* 0 = truncate, 1 = wrap long lines */
int	p_keyapp     = 0;	    /* 0 = numeric, 1 = application keypad */
int	p_curapp     = 0;	    /* 0 = cursor, 1 = application cursor */
int	p_echo	     = 0;	    /* 0 = full duplex, 1 = half duplex */
int	p_bs_del     = 0;	    /* 0 = normal, 1 = swap bs and delete */
int	p_convert    = 1;	    /* 1 = convert filenames to lower case */
char	p_keyscript  = 0x7E;	    /* function key script introducer = ~ */
char	*p_f[10]     = {	    /* function key defaults */
    "\033OP","\033OQ","\033OR","\033OS",
    "f5","f6","f7","f8","f9","f10" };

char	*p_F[10]     = {	    /* shifted function key defaults */
    "F1","F2","F3","F4","F5",
    "F6","F7","F8","F9","F10"};

/* for script file */
int script_on;
int script_wait;
int doing_init = 0;

/******************************************************/
/*                   Main Program                     */
/*                                                    */
/*      This is the main body of the program.         */
/******************************************************/

char lookahead[80];
FILE *tranr = NULL;
FILE *trans = NULL;
int capture,send;
char name[80];
struct MsgPort *mySerPort;
int KeepGoing;	/* moved here to be global for tek emulation */

main(argc,argv)
int	argc;
char	**argv;
    {
    ULONG class;
    unsigned int code, qual;
    int i,la,dola,actual;
    char c,*ptr;

    ptr = InitDefaults(argc,argv);
    InitDevs();
    InitFileItems();
    InitCommItems();
    InitScriptItems();
    InitUtilItems();
	InitTekItems();		/* added for tek emulation 	*/
    InitMenu();
	InitTekMenu();		/* added for tek emulation 	*/
    SetMenuStrip(mywindow,&menu[0]);
    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
	InitTekDev();	/* added for tek emulation 	*/

    MyDir[0]  =	    '\000';
    StartLock =	(struct FileLock *)((ULONG)((struct Process *)
		    (FindTask(NULL)))->pr_CurrentDir);
    MyDirLock = (struct FileLock *)DupLock(StartLock);
    KeepGoing =	    TRUE;
    capture   =	    FALSE;
    send      =	    FALSE;
    maxcol    =	    MAXX / 8;
    la	      =	    0;
    x	      =	    MINX ; 
    y	      =	    MINY; 
    curmode   =	    FS_NORMAL;
    script_on =     FALSE;
    script_wait=    TRUE;
    SetAPen(mywindow->RPort,1L);
    cursorflip();
    cursorflip();    
    emit(12);
    mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
    SendIO(Read_Request);

    /* see if we had a startup script */
    if (ptr != NULL) script_start(ptr);

    while( KeepGoing )
	    {
	    /* wait for window message or serial port message */
	    cursorflip();
	    if (script_wait)	/* if script ready dont wait here */
		Wait(
		 (1L << mySerPort->mp_SigBit) |
		 (1L << mywindow->UserPort->mp_SigBit) |
		 (1L << Script_Timer_Port->mp_SigBit));
	    cursorflip();
	    
	    /* do ascii file send */
	    if (send)
		{
		if ((c=getc(trans)) != EOF) {
		    if (c == '\n') c = '\r';
		    sendchar(c);
		    }
		else {
		    fclose(trans);
		    req("File Sent","",0);
		    send=FALSE;
		    }
		}

	    /* see if there are any characters from the host */
	    if (CheckIO(Read_Request)) {
		WaitIO(Read_Request);
		c = rs_in[0] & 0x7F;
		doremote(c);
		if (script_on) chk_script(c);
	        if (capture && c != 10) {
	      	    if (c == 13) c = 10;
		    putc(c , tranr);
		    }
		Read_Request->IOSer.io_Command = SDCMD_QUERY;
		DoIO(Read_Request);
		Read_Request->IOSer.io_Command = CMD_READ;
		actual = (int)Read_Request->IOSer.io_Actual;
		if (actual > 0) {
		    if (inesc   <  0 &&
			inctrl  <  0 &&
			a[alt]  == 0 &&
			capture == FALSE) dola = 1;
		    else dola = 0;
		    Read_Request->IOSer.io_Length =
			Read_Request->IOSer.io_Actual;
		    DoIO(Read_Request);
		    Read_Request->IOSer.io_Length = 1;

		    for (i = 0; i < actual; i++) {
			c=rs_in[i] & 0x7f;
			if (script_on) chk_script(c);

			if (dola == 1) {
			    if (c >= ' ' && c <= '~' && la < 80)
				lookahead[la++] = c;
			    else {
				if (la > 0) {
				    emitbatch(la,lookahead);
				    la = 0;
				    }
				doremote(c);
				dola = 0;
				}
			    }
			else {
			    doremote(c);
			    if (inesc   <  0 &&
				inctrl  <  0 &&
				a[alt]  == 0 &&
				capture == FALSE) dola = 1;
			    if (capture && c != 10) {
				if (c == 13) c = 10;
				putc(c , tranr);
				}
			    }
			}

		    /* dump anything left in the lookahead buffer */
		    if (la > 0) {
			emitbatch(la,lookahead);
			la = 0;
			}
		    }
		SendIO(Read_Request);
		}

	    while((NewMessage = 
		    (struct IntuiMessage *)GetMsg(mywindow->UserPort))
			!= FALSE) {
		class = NewMessage->Class;
		code = NewMessage->Code;
		qual = NewMessage->Qualifier;
		ReplyMsg( NewMessage );
		switch( class )
		    {
		    case REQCLEAR:
		    numreqs = 0;
		    break;

		    case CLOSEWINDOW:
		    KeepGoing = FALSE;
		    break;

		    case RAWKEY:
		    c = toasc(code,qual,0);
		    if (p_echo) doremote(c);
		    break;

		    case NEWSIZE:
		    emit(12);
		    break;

		    case MENUPICK:
		    handle_menupick(class,code);
		    break;				    

		    default:
		    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
		    break;
		    }   /* end of switch (class) */
		}   /* end of while ( newmessage )*/

            if (!script_wait || 
                 (CheckIO(&Script_Timer) && 
		    script_wait == WAIT_TIMER))
		do_script_cmd(NEXTCOMMAND);
	    }  /* end while ( keepgoing ) */
		
    /*   It must be time to quit, so we have to clean
    *   up and exit.
    */

    cleanup("",0);

    } /* end of main */

/* cleanup code */

cleanup(reason, fault)
char *reason;
int fault;
    {
    switch(fault) {
	case 0:		/* quitting close everything */
	ClearMenuStrip( mywindow ); 
	CloseDevice(&Audio_Request);
	if (MyDirLock != NULL) UnLock(MyDirLock);

	case 8:		/* error opening audio */
	DeletePort(Audio_Port);
	FreeMem(BeepWave,BEEPSIZE);
	CloseDevice(&Timer);

	case 7:		/* error opening timer */
	DeletePort(Timer_Port);  
	CloseDevice(&Script_Timer);
	DeletePort(Script_Timer_Port);

	case 6:		/* error opening write device */
	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
	FreeMem(Write_Request,(long)sizeof(*Write_Request));
	CloseDevice(Read_Request);

	case 5:		/* error opening read device */
	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
	FreeMem(Read_Request,(long)sizeof(*Read_Request));

	case 4:		/* error opening window */
	if (myfont   != NULL) CloseFont( myfont );
	if (mywindow != NULL) CloseWindow( mywindow );
	if (p_screen != 0) CloseScreen( myscreen );

	case 3:		/* error opening screen */
	case 2:		/* error opening graphics library */
	case 1:		/* error opening intuition */
	default:
	if (*reason) puts (reason);
	}
	CloseTek();		/* added for tek emulation	*/
    exit(fault);
    } 

do_capture(file)
char *file;
    {
    if (capture == TRUE)
        {
        capture=FALSE;
        fclose(tranr);
        req("End File Capture","",0);
        }
    else
        {
        if (file == NULL) {
	    name[0] = '\000';
            req("Ascii Capture:",name,1);
	    } 
	else strcpy(name, file);
        if ((tranr=fopen(name,"w")) == 0) {
	    capture=FALSE;
	    req("Error Opening File","",0);
	    return(FALSE);
	    }
	capture=TRUE;
        }
    }

do_send(file)
char *file;
    {
    if (send == TRUE)
	{ 
        send=FALSE;
        fclose(trans);
        req("File Send Cancelled","",0);
        }
    else
        {
        if (file == NULL) {
	    name[0] = '\000';
            req("Ascii Send:",name,1);
            }
	else strcpy(name, file);
        if ((trans=fopen(name,"r")) == 0) {
   	    send=FALSE;
	    req("Error Opening File","",0);
	    return(FALSE);
	    }
	send=TRUE;
	}
    }

void setparams()
    {
    Read_Request->IOSer.io_Command = 
	Write_Request->IOSer.io_Command = 
	    SDCMD_SETPARAMS;
    DoIO(Read_Request); DoIO(Write_Request);
    Read_Request->IOSer.io_Command = CMD_READ;
    SendIO(Read_Request);
    Write_Request->IOSer.io_Command = CMD_WRITE;
    }

void hangup ()
    {
    AbortIO(Read_Request);
    CloseDevice (Read_Request);
    Timer.tr_time.tv_secs=0L;
    Timer.tr_time.tv_micro=750000L;
    DoIO((char *) &Timer.tr_node);
    OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
    setparams();
    }

void redocomm() {
    ClearMenuStrip( mywindow );         /* Remove old menu */
    InitCommItems();                    /* Re-do comm menu   */
    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
    }

void setserbaud(baud, redomenu)
int baud;
LONG redomenu;
    {
    AbortIO(Read_Request);
    Write_Request->io_Baud = Read_Request->io_Baud = baud;
    setparams();
    p_baud = baud;
    if (redomenu) redocomm();
    }

void redoutil() {
    ClearMenuStrip(mywindow);
    InitUtilItems();
    SetMenuStrip(mywindow,&menu[0]);
    }

void 
handle_menupick(class, code)
ULONG class;
unsigned int code;
    {
    unsigned int menunum, itemnum, subnum;

    if (code == MENUNULL) return;

    menunum = MENUNUM( code );
    itemnum = ITEMNUM( code );
    subnum  = SUBNUM( code );
    switch( menunum ) {
	case 0:
	switch( itemnum ) {
	    case 0:
	    do_capture(NULL);
	    break;

	    case 1:
	    do_send(NULL);
	    break;

	    case 2:
	    if (p_parity > 0) {
		req("Parity setting prevents this","",0);
		break;
		}
	    name[0] = '\000';
	    req("Xmodem Receive:",name,1);
	    multi_xfer(name,XMODEM_Read_File,0);
	    break;

	    case 3:
	    if (p_parity > 0) {
		req("Parity setting prevents this","",0);
		break;
		}
	    name[0] = '\000';
	    req("Xmodem Send:",name,1);
	    multi_xfer(name,XMODEM_Send_File,1);
	    break;

	    case 4:
	    server = TRUE;
	    name[0] = '\000';
	    req("Kermit GET remote file(s):",name,1);
	    multi_xfer(name,dokreceive,0);
            break;

	    case 5:
	    multi_xfer("",dokreceive,0);
	    break;

	    case 6:
	    server = TRUE;
	    name[0] = '\000';
	    req("Kermit Send local name:",name,1);
	    multi_xfer(name,doksend,1);
	    break;

	    case 7:
	    saybye();
	    break;
	    }
	break;

	case 1:
	switch( itemnum ) {
	    case 0:
	    switch( subnum ) {
		case 0:
		setserbaud(300, FALSE);
		break;

		case 1:
		setserbaud(1200, FALSE);
		break;

		case 2:
		setserbaud(2400, FALSE);
		break;

		case 3:
		setserbaud(4800, FALSE);
		break;

		case 4:
		setserbaud(9600, FALSE);
		break;
		}
	    break;	    

	    case 1:
	    /* Set  Parity */
	    p_parity = subnum;
	    break;

	    case 2:
	    /* set transfer mode */
	    if (subnum < 2) p_mode = subnum;
	    else {
		if (p_convert)	p_convert = 0;
		else		p_convert = 1;
		redocomm();
		}
	    break;
	    }
	break;

	case 2:
	if (!itemnum && !script_on) {
	    name[0] = '\000';
	    req("Script file name:",name,1);
	    script_start(name);
	    }
	if (itemnum && script_on) exit_script();
	break;

	case 3:
	switch( itemnum ) {
	    case 0:
	    sendbreak();
	    break;

	    case 1:
	    hangup();
	    break;

	    case 2:
	    strcpy(name,MyDir);
	    req("Directory:",name,1);
	    set_dir(name);
	    break;

	    case 3:
	    top = MINY; bot = MAXY; savx = MINX; savy = MINY;
	    curmode = FS_NORMAL; inesc = -1;
	    a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
	    redoutil();
	    emit(12);
	    break;

	    case 4:
	    if (p_echo) p_echo = 0;
	    else	p_echo = 1;
	    redoutil();
	    break;

	    case 5:
	    if (p_wrap) p_wrap = 0;
	    else        p_wrap = 1;
	    redoutil();
	    break;

	    case 6:
	    if (p_keyapp) p_keyapp = 0;
	    else          p_keyapp = 1;
	    redoutil();
	    break;

	    case 7:
	    if (p_curapp) p_curapp = 0;
	    else          p_curapp = 1;
	    redoutil();
	    break;	    

	    case 8:
	    swap_bs_del();
	    redoutil();
	    break;
	    }
	case 4:			/* new menu items added for tek emulation 	*/
	switch(itemnum) {
		case 0:				/* choose tek scale		*/
			switch (subnum) {
				case 0:
					t_scale = 0;	/* choose 1020x780 resolution	*/
					break;
				case 1:
					t_scale = 1;	/* choose 640x400	*/
					break;
			}
		break;
		case 1:				/* choose screen depth	*/
			switch (subnum) {
				case 0:
					t_cmd_depth("1");
					break;
				case 1:
					t_cmd_depth("2");
					break;
				case 2:
					t_cmd_depth("3");
					break;
				case 3:
					t_cmd_depth("4");
					break;
			}
		break;
		case 2:				/*	choose interlace 	*/
			switch (subnum) {
				case 0:
					t_cmd_interlace("0");
					break;
				case 1:
					t_cmd_interlace("1");
					break;
			}
		break;
	}
	break;

	case 5:
		switch (itemnum) {
			case 0:			/* tek screen on/off	*/
				switch(subnum) {

/*	emits("select screen on/off\n");
	printf("select screen on/off\n");	*/

					case 0:			/* tek screen off  */
					t_cmd_on("0");
					break;
					case 1:			/* tek screen on   */
					t_cmd_on("1");
					break;
				}
				break;
			case 1:
				doremote(29);
				doremote(31);	/* force tek screen to front	*/
			break;
			case 2:
				doremote(24);	/* force vt screen to front */
			break;
			case 3:		/* clear both screens	*/
/*				doremote(24);	*/
				if(Tek_screen_open == 1) {
					doremote(29);
					doremote(27);	
					doremote(12);
					doremote(24);
				}
/*				doremote(27);
				doremote('c');	*/
				inesc = -1;
				emit(12);
			break;
			case 4:					/* quit	*/
				KeepGoing = FALSE;
			break;
		}
	break;
	} /* end of switch ( menunum ) */
    }

SHAR_EOF
cat << \SHAR_EOF > window.c
/****************************************************
 * vt100 emulator - window/keyboard support
 *
 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
 *	v2.5 870214 DBW - more additions (see readme file)
 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
 *	v2.3 861101 DBW - minor bug fixes
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#include "vt100.h"

/* keyboard definitions for toasc() */
static char keys[75] = {
    '`','1','2','3','4','5','6','7','8','9','0','-' ,
    '=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
    'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
    'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
    'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
    '\t',13,13,27,127,0,0,0,'-' } ;

/***************************************************
 *  function to swap the use of backspace and delete
 ***************************************************/

void swap_bs_del()
    {
    if (p_bs_del)   p_bs_del = 0;
    else	    p_bs_del = 1;

    keys[0x41] =    p_bs_del ? 127 : 8;
    keys[0x46] =    p_bs_del ? 8 : 127;
    }

/*************************************************
 *  function to get file name (via a requestor)
 *************************************************/
void req(prmpt,name,getinp)
char *prmpt,*name;
int  getinp;
    {
    ULONG class;
    unsigned int code, qual;
    struct IntuiMessage *Msg;

    /* Make sure the prompt gets updated */
    if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
	EndRequest(&myrequest,mywindow);
	numreqs = 0;
	}

    /* copy in a prompt and a default */
    strcpy(Prompt,prmpt);
    strcpy(InpBuf,name);

    /* If there is a requester... reuse it */
    if (numreqs == 1) RefreshGadgets(&mystrgad,mywindow,&myrequest);

    /* otherwise create it */
    else {
	if (Request(&myrequest,mywindow) == 0) {
	    emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
	    emits(Prompt); emit('\n');
	    emits(InpBuf); emit('\n');
	    return;
	    }
	else numreqs = 1;
	}

    /* if we don't want input, we're done */
    if (getinp == 0 || numreqs == 0) return;

    /* throw away any extra messages */
    Wait(1L << mywindow->UserPort->mp_SigBit);
    while (Msg = (struct IntuiMessage *)GetMsg(mywindow->UserPort))
	ReplyMsg(Msg);

    /* here is where we pre-select the gadget   */
    if (!ActivateGadget(&mystrgad,mywindow,&myrequest)) {

	/* wait for his/her hands to get off the keyboard (Amiga-key) */
	Delay(20L);
	while (Msg = (struct IntuiMessage *)GetMsg(mywindow->UserPort))
	    ReplyMsg(Msg);

	/* try once more before giving up... */
	ActivateGadget(&mystrgad,mywindow,&myrequest);
	}

    /* wait for input to show up */
    while (1) {
	if ((NewMessage = (struct IntuiMessage *)
		GetMsg(mywindow->UserPort)) == FALSE) {
	    Wait(1L<<mywindow->UserPort->mp_SigBit);
	    continue;
	    }
	class = NewMessage->Class;
	code  = NewMessage->Code;
	qual  = NewMessage->Qualifier;
	ReplyMsg(NewMessage);

	/* the requestor got terminated... yea!! */
	if (class == REQCLEAR) break;

	/* maybe this is a menu item to handle */
	if (class == MENUPICK) handle_menupick(class,code);
	}

    /* all done, so return the result */
    numreqs = 0;
    strcpy(name,InpBuf);
    }

/*************************************************
*  function to print a string
*************************************************/
void emits(string)
char string[];
    {
    int i;
    char c;

    i=0;
    while (string[i] != 0)
	{
	c=string[i];
	if (c == 10) emit(13);
	emit(c);
	i += 1;
	}
    }

/*************************************************
*  function to output ascii chars to window
*************************************************/
void emit(c)
char c;
    {
    static char wrap_flag = 0;	/* are we at column 80? */

    c &= 0x7F;
    switch( c )
	{
	case '\t':
	x += 64 - ((x-MINX) % 64);
	break;

	case 10:  /* lf */
	y += 8;
	break;

	case 13:  /* cr */
	x = MINX;
	break;

	case 8:   /* backspace */
	x -= 8;
	if (x < MINX) x = MINX;
	break;

	case 12:     /* page */
	x = MINX;
	y = MINY;
	SetAPen(mywindow->RPort,0L);
	RectFill(mywindow->RPort,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	SetAPen(mywindow->RPort,1L);
	break;

	case 7:     /* bell */
	if (p_volume == 0) DisplayBeep(NULL);
	else {
	    BeginIO(&Audio_Request);
	    WaitIO(&Audio_Request);
	    }
	break;

	default:
	if (c < ' ' || c > '~') break;
	if (p_wrap && wrap_flag && x >= MAXX) {
	    x = MINX;
	    y += 8;
	    if (y > MAXY) {
		y = MAXY;
		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
		}
	    }
	Move(mywindow->RPort,(long)x,(long)y);

	if (curmode&FSF_BOLD) {
	    if (p_depth > 1) {
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
		}
	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

	if (curmode&FSF_REVERSE) {
	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	    Text(mywindow->RPort,&c,1L);
	    SetDrMd(mywindow->RPort,(long)JAM2);
	    }
	else Text(mywindow->RPort,&c,1L);

	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
	x += 8;
	} /* end of switch */

    if (y > MAXY) {
	y = MAXY;
	x = MINX;
	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
	}
    if (x > MAXX) {
	wrap_flag = 1;
	x = MAXX;
	}
    else wrap_flag = 0;
    }

/*************************************************
*  function to output ascii chars to window (batched)
*************************************************/
void emitbatch(la,lookahead)
int la;
char *lookahead;
    {
    int i;	

    Move(mywindow->RPort,(long)x,(long)y);
    i = x / 8;
    if (i+la >= maxcol) {
	if (p_wrap == 0) la = maxcol - i;
	else {
	    lookahead[la] = 0;
	    emits(lookahead);
	    return;
	    }
	}
    if (curmode&FSF_BOLD) {
	if (p_depth > 1) {
	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	}
    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

    if (curmode&FSF_REVERSE) {
	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	Text(mywindow->RPort,lookahead,(long)la);
	SetDrMd(mywindow->RPort,(long)JAM2);
	}
    else Text(mywindow->RPort,lookahead,(long)la);
    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
    x += (8 * la);
    }

/******************************
* Manipulate cursor
******************************/
void cursorflip()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

/************************************************
*  function to take raw key data and convert it 
*  into ascii chars
**************************************************/
int toasc(code,qual,local)
unsigned int code,qual;
int local;
    {
    unsigned int ctrl,shift,capsl,amiga,alt;
    char c = 0, keypad = 0;
    char *ptr;

    ctrl    = qual & IEQUALIFIER_CONTROL;
    capsl   = qual & IEQUALIFIER_CAPSLOCK;
    amiga   = qual & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND);
    shift   = qual & (IEQUALIFIER_LSHIFT   | IEQUALIFIER_RSHIFT);
    alt	    = qual & (IEQUALIFIER_LALT     | IEQUALIFIER_RALT);

    switch ( code )
	{
	case 98:
	case 226:
	case 99:
	case 227:
	case 96:
	case 97:
	case 224:
	case 225:
	case 100:
	case 101:
	case 228:
        case 229:
	case 102:
	case 103:
	case 230:
	case 231:   c = 0; break; /* ctrl, shift, capsl, amiga, or alt */

	case 0x50: 
	case 0x51: 
	case 0x52: 
	case 0x53: 
	case 0x54: 
	case 0x55: 
	case 0x56: 
	case 0x57: 
	case 0x58: 
	case 0x59:  c = 0;
		    if (shift)	ptr = p_F[code - 0x50];
		    else	ptr = p_f[code - 0x50];
		    if (!script_on && *ptr == p_keyscript)
			    script_start(++ptr);
		    else    sendstring(ptr);
		    break;
	case 0x0f: c = (p_keyapp) ? 'p' : '0'; keypad = TRUE; break;
	case 0x1d: c = (p_keyapp) ? 'q' : '1'; keypad = TRUE; break;
	case 0x1e: c = (p_keyapp) ? 'r' : '2'; keypad = TRUE; break;
	case 0x1f: c = (p_keyapp) ? 's' : '3'; keypad = TRUE; break;
	case 0x2d: c = (p_keyapp) ? 't' : '4'; keypad = TRUE; break;
	case 0x2e: c = (p_keyapp) ? 'u' : '5'; keypad = TRUE; break;
	case 0x2f: c = (p_keyapp) ? 'v' : '6'; keypad = TRUE; break;
	case 0x3d: c = (p_keyapp) ? 'w' : '7'; keypad = TRUE; break;
	case 0x3e: c = (p_keyapp) ? 'x' : '8'; keypad = TRUE; break;
	case 0x3f: c = (p_keyapp) ? 'y' : '9'; keypad = TRUE; break;
	case 0x43: c = (p_keyapp) ? 'M' : 13 ; keypad = TRUE; break;
	case 0x4a: c = (p_keyapp) ? 'l' : '-'; keypad = TRUE; break;
	case 0x5f: sendstring("\033Om") ;break;
	case 0x3c: c = (p_keyapp) ? 'n' : '.'; keypad = TRUE; break;
	case 0x4c:
	case 0x4d: 
	case 0x4e: 
	case 0x4f: sendchar(27);            /* cursor keys */
		   if (p_curapp) sendchar('O');
		   else sendchar('[');
		   sendchar(code - 11);
		   break;

	default:
	if (code < 75) c = keys[code];
	else c = 0;
	}

    if (keypad) {
        if (p_keyapp) sendstring("\033O");
        sendchar(c);
        return(0);
	}
        
    /* add modifiers to the keys */

    if (c != 0) {
	if (shift) {
	    if ((c <= 'z') && (c >= 'a')) c -= 32;
	    else
	    switch( c ) {
		case '[':  c = '{'; break;
		case ']':  c = '}'; break;
		case '\\': c = '|'; break;
		case '\'': c = '"'; break;
		case ';':  c = ':'; break;
		case '/':  c = '?'; break;
		case '.':  c = '>'; break;
		case ',':  c = '<'; break;
		case '`':  c = '~'; break;
		case '=':  c = '+'; break;
		case '-':  c = '_'; break;
		case '1':  c = '!'; break;
		case '2':  c = '@'; break;
		case '3':  c = '#'; break;
		case '4':  c = '$'; break;
		case '5':  c = '%'; break;
		case '6':  c = '^'; break;
		case '7':  c = '&'; break;
		case '8':  c = '*'; break;
		case '9':  c = '('; break;
		case '0':  c = ')'; break;
		default:            break;
		}
	    }
	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
	}
    if (ctrl) {
	if (c > '`' && c <= 127) c -= 96;
	else if (c > '@' && c <= '_') c -= 64;
	else if (c == '6') c = 30;
	else if (c == '-' || c == '?') c = 31;
	}
    if (ctrl && (c == '@' || c == '2' || c == ' ')) {
	if (!local) sendchar(alt?128:0);
	c = 0;
	}
    else if (c != 0 && (!local)) sendchar(alt?c+128:c);
    return((int)c);
    }

SHAR_EOF