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