/* 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 /*********************** 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; nUserPort); } } } 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); } } }