sloane@noscvax.UUCP (Gary K. Sloane) (08/09/86)
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # part1 # This archive created: Fri Aug 8 17:13:50 1986 # By: Gary K. Sloane (Computer Sciences Corporation, San Diego) export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'part1' then echo shar: "will not over-write existing file 'part1'" else cat << \SHAR_EOF > 'part1' /* DISPLIB - a display library for CRT-based applications. This version is for 4.[123]bsd UNIXs using termcap. Donated into the public domain for any use whatever by anyone. Please retain this header. This display library is a seriously modified version of a display library posted to USENET several years ago. Many thanks. * **************************************************************** * * Gary K. Sloane/Computer Sciences Corporation/San Diego, CA 92110 * * DDD: (619) 225-8401 * * MILNET: sloane@nosc.ARPA * * UUCP: [ihnp4,akgua,decvax,dcdwest,ucbvax]!sdcsvax!noscvax!sloane * * **************************************************************** * */ #include <sys/types.h> #include <sys/param.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/wait.h> #include <ctype.h> #include <sgtty.h> #include <signal.h> #include <stdio.h> #include <strings.h> #include "displib.h" #define makelower(c) isupper(c)?tolower(c):(c) /* pointer to environment for getenv() */ extern char **environ; /* defined here, referenced as an extern elsewhere */ TERMDEF termctrl; /************************************************************************/ /* routine to get terminal capabilities, validate & initialize terminal */ /************************************************************************/ /* *** must be called before using any other displib routines *** */ /************************************************************************/ terminit() { struct sgttyb ttystate; char tbuf[1024], *ap, *pcptr, *getenv(), *term; /* this must be run from a terminal... */ if(isatty(fileno(stdout)) == 0) { fprintf(stderr, "** This program must be run from a tty**\n"); exit(0); } /* read the current tty state from the driver */ if(ioctl(1, (int)TIOCGETP, (char *)&ttystate) != 0) { fprintf(stderr, "** Error: Cannot get tty state **\n");; exit(0); } /* set the tty speed in the external variable ospeed for tputs() */ /* an interesting note: UNIX only knows the speed of the device */ /* that's actually connected to the driver. So if you have modems */ /* or some other link (like a data concentrator) in between, UNIX */ /* will pad for the speed of the device connected to the port, */ /* NOT the speed of the terminal (which is what you want...) */ ospeed = ttystate.sg_ospeed; /* clear the XTABS bit in the sg_flags */ /* so that tab chars (^I) are NOT expanded */ /* since some terminals use them for other */ /* than tabs. (see tgoto.c in termcap) */ ttystate.sg_flags &= ~XTABS; /* write the sg_flags back to the tty */ if(ioctl(1, (int)TIOCSETP, (char *)&ttystate) != 0) { fprintf(stderr, "** Cannot set tty state **\n");; exit(0); } /* delay long enough for TIOCSETP to do it's thing */ sleep(2); /* get terminal type and termcap entry */ term = getenv("TERM"); if(term == (char *)NULL) { fprintf(stderr, "** No TERM variable in environment **\n"); exit(0); } switch(tgetent(tbuf, term)) { case -1: { fprintf(stderr, "** Cannot open termcap data file **\n"); exit(0); } case 0: { fprintf(stderr, "** %s: Unknown terminal type **\n", term); exit(0); } } /* make sure it's not a hard-copy terminal */ if(tgetnum("hc") != -1) { fprintf(stderr, "** You cannot run this program from a hard copy terminal **\n"); exit(0); } /* get terminal attributes and capabilities */ ap = termctrl.tcapbuf; termctrl.BL = tgetstr("bl", &ap); termctrl.CD = tgetstr("cd", &ap); termctrl.CE = tgetstr("ce", &ap); termctrl.CL = tgetstr("cl", &ap); termctrl.CM = tgetstr("cm", &ap); termctrl.IS = tgetstr("is", &ap); termctrl.SE = tgetstr("se", &ap); termctrl.SO = tgetstr("so", &ap); termctrl.TE = tgetstr("te", &ap); termctrl.TI = tgetstr("ti", &ap); termctrl.scrlen = tgetnum("li"); termctrl.scrwid = tgetnum("co"); /* make sure terminal has required capabilities */ if( (termctrl.CM == 0) || (termctrl.CL == 0) ) { fprintf(stderr, "** Terminal must have clear and cursor movement capabilities **\n"); exit(0); } if( (termctrl.scrlen <= 0) || (termctrl.scrwid <= 0) ) { fprintf(stderr, "** Termcap entry must show screen size **\n"); exit(0); } /* define the upline and alternate backspace string for tgoto() */ UP = tgetstr("up", &ap); if(tgetflag("bs") == 0) BC = tgetstr("bc", &ap); else BC = (char *)NULL; /* get the (correct) pad character for tputs() */ /* some networks may discard NULs... */ if((pcptr = tgetstr("pc", &ap)) != (char *)NULL) PC = *pcptr; /* specified in termcap */ else PC = '\000'; /* use a NUL if not specified */ /* send initialization string if defined */ if(termctrl.IS != 0) putpad(termctrl.IS); } /**************************************************************************/ /* Check an Input String to see if it is a Valid Abbreviation of a Target */ /* Ignoring Case - returns 0 if it is an ok abbreviation, -1 if not */ /**************************************************************************/ int abb(input, target) char *input, *target; { char *malloc(); char *tarptr = target; char *tptr, *tptr1; char *inptr = malloc((unsigned int)strlen(target)+1); /* reject <RET> - user *must* enter something... */ if( (strlen(input) == 0) || (strlen(input) > strlen(target)) ) return(-1); /* convert input to lower case for the comparison */ for(tptr=input, tptr1=inptr; *tptr!='\0'; ++tptr, ++tptr1) *tptr1= makelower(*tptr); *tptr1 = '\0'; /* we allow one character abbreviations in this program */ if(*inptr == *tarptr) return(abbrev(inptr, tarptr)); else return(-1); } static abbrev(inptr, tarptr) char *inptr, *tarptr; { for(++inptr, ++tarptr; *tarptr != '\0'; ++inptr, ++tarptr) { if(*inptr == '\0') return(0); if(*inptr != *tarptr) return(-1); } if(*inptr == '\0') return(0); else return(-1); } /*************/ /* Ring Bell */ /*************/ bell() { /* If bell is defined, put it out */ if(termctrl.BL != 0) putpad(termctrl.BL); /* If not, put out ASCII ctrl-G */ else putchar('\007'); } /***************************/ /* routine to clear screen */ /***************************/ clear() { putpad(termctrl.CL); return; } /**************************************/ /* routine to clear to end of display */ /**************************************/ cleod() { int lin, col; /* if terminal has CD, do it */ if (termctrl.CD != 0) putpad(termctrl.CD); /* if it doesn't have CD, fake it */ else { /* save cursor position */ lin = termctrl.curline; col = termctrl.curcol; /* clear rest of current line */ cleol(); /* clear rest of screen */ while (termctrl.curline < termctrl.scrlen) { gotoxy(0, ++termctrl.curline); cleol(); } /* return to correct position */ gotoxy(col,lin); } return; } /***********************************/ /* routine to clear to end of line */ /***********************************/ cleol() { int i; /* if terminal has CE, do it */ if (termctrl.CE != 0) putpad(termctrl.CE); /* if terminal doesn't have CE, fake it */ else { for(i=termctrl.curcol; i<termctrl.scrwid; i++) putchar(' '); } gotoxy(termctrl.curcol,termctrl.curline); return; } /**************************/ /* Clear the Message Area */ /**************************/ clmsg() { int lin, col; lin = termctrl.curline; col = termctrl.curcol; gotoxy(0,22); cleod(); gotoxy(col, lin); return; } SHAR_EOF fi exit 0 # End of shell archive