/* * The functions in this file * negotiate with the operating system * for characters, and write characters in * a barely buffered fashion on the display. * All operating systems. */ #include #include #include #include "ed.h" #if ST #define BORDER 0 #define CURSOR 1 #define DESK 2 #define LETTER 3 #define BLACK 0 #define WHITE 0x777 #define COBALT 0x007 #define TEAL 0x055 #define GREEN 0x070 #define GREY 0x555 #define RED 0x700 #define MAGENTA 0x707 #define YELLOW 0x770 /* the first four are the saved values */ int bordcol; /* #0 */ int curscol; /* #1 */ int deskcol; /* #2 */ int letcol; /* #3 */ /* these are the internal values */ int bcolor; /* #0 */ int ccolor; /* #1 */ int dcolor; /* #2 */ int lcolor; /* #3 */ char *colornames[4] = {"Magenta","Magenta","Magenta","Magenta"}; #endif #if VMS #include #include #include #include #include #define NIBUF 128 /* Input buffer size */ #define NOBUF 1024 /* MM says bug buffers win! */ #define EFN 0 /* Event flag */ char obuf[NOBUF]; /* Output buffer */ int nobuf; /* # of bytes in above */ char ibuf[NIBUF]; /* Input buffer */ int nibuf; /* # of bytes in above */ int ibufi; /* Read index */ int oldmode[2]; /* Old TTY mode bits */ int newmode[2]; /* New TTY mode bits */ short iochan; /* TTY I/O channel */ #endif #if MSDOS #include #endif #if V7 #include /* for stty/gtty functions */ struct sgttyb ostate; /* saved tty state */ struct sgttyb nstate; /* values for editor mode */ #endif /* * This function is called once * to set up the terminal device streams. * On VMS, it translates SYS$INPUT until it * finds the terminal, then assigns a channel to it * and sets it raw. On CPM it is a no-op. On the ST * it is called to update the screen color and every * time we return from spawn or the term mode. */ ttopen() { #if VMS struct dsc$descriptor idsc; struct dsc$descriptor odsc; char oname[40]; int iosb[2]; int status; odsc.dsc$a_pointer = "SYS$INPUT"; odsc.dsc$w_length = strlen(odsc.dsc$a_pointer); odsc.dsc$b_dtype = DSC$K_DTYPE_T; odsc.dsc$b_class = DSC$K_CLASS_S; idsc.dsc$b_dtype = DSC$K_DTYPE_T; idsc.dsc$b_class = DSC$K_CLASS_S; do { idsc.dsc$a_pointer = odsc.dsc$a_pointer; idsc.dsc$w_length = odsc.dsc$w_length; odsc.dsc$a_pointer = &oname[0]; odsc.dsc$w_length = sizeof(oname); status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc); if (status!=SS$_NORMAL && status!=SS$_NOTRAN) exit(status); if (oname[0] == 0x1B) { odsc.dsc$a_pointer += 4; odsc.dsc$w_length -= 4; } } while (status == SS$_NORMAL); status = SYS$ASSIGN(&odsc, &iochan, 0, 0); if (status != SS$_NORMAL) exit(status); status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0, oldmode, sizeof(oldmode), 0, 0, 0, 0); if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status); newmode[0] = oldmode[0]; newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO; status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, newmode, sizeof(newmode), 0, 0, 0, 0); if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status); #endif #if ST static char first = TRUE; char colornm[80]; register int i; char temp[40]; if (first) { i = 0; Crawio(0x1b); /* clear and home */ Crawio('E'); bcolor = WHITE; /* border */ strcpy(colorname[i++],"White"); if(!alias(temp,"border")) insalias("border","white"); ccolor = WHITE; /* cursor */ strcpy(colorname[i++],"White"); if(!alias(temp,"cursor")) insalias("cursor","white"); dcolor = BLACK; /* screen (desk) */ strcpy(colorname[i++],"Black"); if(!alias(temp,"desk")) insalias("desk","black"); lcolor = WHITE; /* letters */ strcpy(colorname[i++],"White"); if(!alias(temp,"letter")) insalias("letter","white"); first = FALSE; } /* check for user preferences */ i = 0; if (alias(colornm,"border")) { if (strcmp(colornm,"red")==NULL) { bcolor = RED; strcpy(colornames[0],"Red"); } else if (strcmp(colornm,"black")==NULL) { bcolor = BLACK; strcpy(colornames[0],"Black"); } else if (strcmp(colornm,"white")==NULL) { bcolor = WHITE; strcpy(colornames[0],"White"); } else if (strcmp(colornm,"cobalt")==NULL) { bcolor = COBALT; strcpy(colornames[0],"Cobalt"); } else if (strcmp(colornm,"green")==NULL) { bcolor = GREEN; strcpy(colornames[0],"Green"); } else if (strcmp(colornm,"magenta")==NULL) { bcolor = MAGENTA; strcpy(colornames[0],"Magenta"); } else if (strcmp(colornm,"yellow")==NULL) { bcolor = YELLOW; strcpy(colornames[0],"Yellow"); } else if (strcmp(colornm,"grey")==NULL) { bcolor = GREY; strcpy(colornames[0],"Grey"); } else if (strcmp(colornm,"teal")==NULL) { bcolor = TEAL; strcpy(colornames[0],"Teal"); } } if (alias(colornm,"cursor")) { if (strcmp(colornm,"red")==NULL) { ccolor = RED; strcpy(colornames[1],"Red"); } else if (strcmp(colornm,"black")==NULL) { ccolor = BLACK; strcpy(colornames[1],"Black"); } else if (strcmp(colornm,"white")==NULL) { ccolor = WHITE; strcpy(colornames[1],"White"); } else if (strcmp(colornm,"cobalt")==NULL) { ccolor = COBALT; strcpy(colornames[1],"Cobalt"); } else if (strcmp(colornm,"green")==NULL) { ccolor = GREEN; strcpy(colornames[1],"Green"); } else if (strcmp(colornm,"magenta")==NULL) { ccolor = MAGENTA; strcpy(colornames[1],"Magenta"); } else if (strcmp(colornm,"yellow")==NULL) { ccolor = YELLOW; strcpy(colornames[1],"Yellow"); } else if (strcmp(colornm,"grey")==NULL) { ccolor = GREY; strcpy(colornames[1],"Grey"); } else if (strcmp(colornm,"teal")==NULL) { ccolor = TEAL; strcpy(colornames[1],"Teal"); } } if (alias(colornm,"desk")) { if (strcmp(colornm,"red")==NULL) { dcolor = RED; strcpy(colornames[2],"Red"); } else if (strcmp(colornm,"black")==NULL) { dcolor = BLACK; strcpy(colornames[2],"Black"); } else if (strcmp(colornm,"white")==NULL) { dcolor = WHITE; strcpy(colornames[2],"White"); } else if (strcmp(colornm,"cobalt")==NULL) { dcolor = COBALT; strcpy(colornames[2],"Cobalt"); } else if (strcmp(colornm,"green")==NULL) { dcolor = GREEN; strcpy(colornames[2],"Green"); } else if (strcmp(colornm,"magenta")==NULL) { dcolor = MAGENTA; strcpy(colornames[2],"Magenta"); } else if (strcmp(colornm,"yellow")==NULL) { dcolor = YELLOW; strcpy(colornames[2],"Yellow"); } else if (strcmp(colornm,"grey")==NULL) { dcolor = GREY; strcpy(colornames[2],"Grey"); } else if (strcmp(colornm,"teal")==NULL) { dcolor = TEAL; strcpy(colornames[2],"Teal"); } } if (alias(colornm,"letter")) { if (strcmp(colornm,"red")==NULL) { lcolor = RED; strcpy(colornames[3],"Red"); } else if (strcmp(colornm,"black")==NULL) { lcolor = BLACK; strcpy(colornames[3],"Black"); } else if (strcmp(colornm,"white")==NULL) { lcolor = WHITE; strcpy(colornames[3],"White"); } else if (strcmp(colornm,"cobalt")==NULL) { lcolor = COBALT; strcpy(colornames[3],"Cobalt"); } else if (strcmp(colornm,"green")==NULL) { lcolor = GREEN; strcpy(colornames[3],"Green"); } else if (strcmp(colornm,"magenta")==NULL) { lcolor = MAGENTA; strcpy(colornames[3],"Magenta"); } else if (strcmp(colornm,"yellow")==NULL) { lcolor = YELLOW; strcpy(colornames[3],"Yellow"); } else if (strcmp(colornm,"grey")==NULL) { lcolor = GREY; strcpy(colornames[3],"Grey"); } else if (strcmp(colornm,"teal")==NULL) { lcolor = TEAL; strcpy(colornames[3],"Teal"); } } Setcolor(BORDER,bcolor); Setcolor(CURSOR,ccolor); Setcolor(DESK,dcolor); Setcolor(LETTER,lcolor); Crawio(0x1b); /* No wrap mode */ Crawio('w'); Crawio(0x1b); /* Turn on standout mode */ Crawio('c'); /* background == dcolor # */ Crawio('2'); Crawio(0x1b); Crawio('b'); /* foreground == lcolor # */ Crawio('3'); #endif #if MSDOS #endif #if V7 gtty(1, &ostate); /* save old state */ gtty(1, &nstate); /* get base of new state */ nstate.sg_flags |= RAW; nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */ stty(1, &nstate); /* set mode */ #endif } /* * This function gets called just * before we go back home to the command interpreter. * On VMS it puts the terminal back in a reasonable state. * Another no-operation on ST. */ ttclose() { #if VMS int status; int iosb[1]; ttflush(); status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, oldmode, sizeof(oldmode), 0, 0, 0, 0); if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status); status = SYS$DASSGN(iochan); if (status != SS$_NORMAL) exit(status); #endif #if ST Crawio(0x1b); /* turn off standout mode */ Crawio('c'); Crawio('0'); Crawio(0x1b); Crawio('b'); Crawio('3'); Setcolor(BORDER,bordcol); Setcolor(CURSOR,curscol); Setcolor(DESK,deskcol); /* reset color the way I like it */ Setcolor(LETTER,letcol); #endif #if MSDOS #endif #if V7 stty(1, &ostate); #endif } /* * Write a character to the display. * On VMS, terminal output is buffered, and * we just put the characters in the big array, * after cheching for overflow. On ST terminal I/O * unbuffered, so we just write the byte out. * Ditto on MS-DOS (use the very very raw console * output routine). */ #if ST /* use assembly */ #else ttputc(c) register int c; { #if VMS if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = c; #endif #if MSDOS dosb(CONDIO, c, 0); #endif #if V7 fputc(c, stdout); #endif } #endif /* * Flush terminal buffer. Does real work * where the terminal output is buffered up. A * no-operation on systems where byte at a time * terminal I/O is done. */ ttflush() { #if VMS int status; int iosb[2]; status = SS$_NORMAL; if (nobuf != 0) { status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT, iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0); if (status == SS$_NORMAL) status = iosb[0] & 0xFFFF; nobuf = 0; } return (status); #endif #if ST #endif #if MSDOS #endif #if V7 fflush(stdout); #endif } /* * Read a character from the terminal, * performing no editing and doing no echo at all. * More complex in VMS that almost anyplace else, which * figures. Very simple on ST, because the system can * do exactly what you want. */ #if ST /* ST needs to get scancode, so we do it in assembly */ #else ttgetc() { #if VMS int status; int iosb[2]; int term[2]; while (ibufi >= nibuf) { ibufi = 0; term[0] = 0; term[1] = 0; status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED, iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0); if (status != SS$_NORMAL) exit(status); status = iosb[0] & 0xFFFF; if (status!=SS$_NORMAL && status!=SS$_TIMEOUT) exit(status); nibuf = (iosb[0]>>16) + (iosb[1]>>16); if (nibuf == 0) { status = sys$qiow(EFN, iochan, IO$_READLBLK, iosb, 0, 0, ibuf, 1, 0, term, 0, 0); if (status != SS$_NORMAL || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL) exit(status); nibuf = (iosb[0]>>16) + (iosb[1]>>16); } } return (ibuf[ibufi++] & 0xFF); /* Allow multinational */ #endif #if MSDOS return (dosb(CONRAW, 0, 0)); #endif #if V7 return(fgetc(stdin)); #endif } #endif #if ST /* save current color values so they can be reinstalled on exit */ savecolor() { bordcol=(int)Getcolor(BORDER); deskcol=(int)Getcolor(DESK); curscol=(int)Getcolor(CURSOR); letcol=(int)Getcolor(LETTER); } paintbuffer(f,n) register int f, n; { char mycolor[20]; char clrtwo[20]; register char *ptr; extern char *index(); if((f=mlreply("New background color: ",mycolor,12)) != TRUE) return(f); /* don't fail because of stray spaces */ if ((ptr=index(mycolor,' '))!=NULL) *ptr = '\0'; else if ((ptr=index(mycolor,'\t'))!=NULL) *ptr = '\0'; n = strlen(mycolor); /* adjust case */ for (f=0;f<=n;f++) if (f == 0) mycolor[f] = toupper(mycolor[f]); else mycolor[f] = tolower(mycolor[f]); for (f=0;f<=LETTER;f++) { if (strcmp(colornames[f],mycolor)==0) { switch(f) { case BORDER: strcpy(mycolor,colornames[BORDER]); mycolor[0] = tolower(mycolor[0]); strcpy(clrtwo,colornames[DESK]); clrtwo[0] = tolower(clrtwo[0]); insalias("desk",mycolor); insalias("border",clrtwo); if (strcmp(colornames[BORDER], colornames[LETTER])==NULL) insalias("letter",clrtwo); break; case CURSOR: strcpy(mycolor,colornames[CURSOR]); mycolor[0] = tolower(mycolor[0]); strcpy(clrtwo,colornames[DESK]); clrtwo[0] = tolower(clrtwo[0]); insalias("desk",mycolor); insalias("cursor",clrtwo); break; case DESK: /* no sense in this */ break; case LETTER: strcpy(mycolor,colornames[LETTER]); mycolor[0] = tolower(mycolor[0]); strcpy(clrtwo,colornames[DESK]); clrtwo[0] = tolower(clrtwo[0]); insalias("desk",mycolor); insalias("letter",clrtwo); break; default: return(FALSE); } ttopen(); return(TRUE); } } mlwrite("No match"); return(FALSE); } #else paintbuffer(f,n) int f,n; { mlwrite("Buy a color computer like an ST"); return(FALSE); } #endif