home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* window 3
- /* SUMMARY
- /* screen manager
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* mailsh
- /* SYNOPSIS
- /* #include "window.h"
- /*
- /* int printcl(window,line,s)
- /* int window;
- /* int line;
- /* char *s;
- /*
- /* int printat(window,line,s)
- /* int window;
- /* int line;
- /* char *s;
- /*
- /* int putw(c)
- /* int c;
- /*
- /* int printw(s)
- /* char *s;
- /*
- /* void clrtoeol()
- /*
- /* void clrtobot()
- /*
- /* void clrscreen()
- /*
- /* void beep()
- /*
- /* int fputchar(c)
- /* int c;
- /*
- /* void wininit() /* extract terminal control from database */
- /* DESCRIPTION
- /* The window manipulator is responsable for three screen windows:
- /* the top window for key labels, the middle window for
- /* information, and the lower window for messages and dialogue.
- /* Use is made of the terminal capability database termcap.
- /*
- /* For MS-DOS systems, there is a termcap facility that generates
- /* escape sequences for the ANSI.SYS terminal driver.
- /*
- /* Appropriate macros for window selection are given in window.h.
- /* Needless to say, all screen output should proceed through
- /* functions in this module.
- /*
- /* All character output functions return the number of screen lines
- /* used for outputting the text (at least 1).
- /*
- /* printat() writes the specified line in the specified window,
- /* starting at the left margin.
- /*
- /* printcl() performs the same functions as printat() and erases to
- /* the end of the line.
- /*
- /* printw() writes a character string to the current cursor location.
- /* putw() does the same for characters. These two functions are
- /* mostly used for output to the top and bottom windows.
- /*
- /* cltroeol(), clrtobot() erase the screen from the cursor to the
- /* end of the line and screen respectively. beep() makes some noise.
- /*
- /* fputchar() outputs a character to stdout, just as putchar,
- /* but it is not a macro.
- /*
- /* wininit() initializes the window manipulator. It reads the
- /* terminal capabilities from the termcap database.
- /* FILES
- /* /etc/termcap, $TERMCAP on V7 or BSD UNIX
- /* /usr/lib/terminfo, $TERMINFO on System-V UNIX
- /* SEE ALSO
- /* window(5) window manager definitions
- /* DIAGNOSTICS
- /* The program is terminated with an error message if no terminal
- /* descriptions could be found, if the terminal lacks some
- /* essential features or if an attempt is made to write outside
- /* a window.
- /* BUGS
- /* This module is a big mess. It should be replaced by a PD
- /* curses/termcap library.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Wed Apr 1 21:14:53 GMT+1:00 1987
- /* LAST MODIFICATION
- /* Mon Apr 4 23:51:29 MET 1988
- /* VERSION/RELEASE
- /* 1.3
- /*--*/
-
- #include <ctype.h>
- #include "defs.h"
- #include "window.h"
-
- #define BUFFERSIZE 1024 /* max. length of termcap entry */
-
- hidden char outbuf[BUFSIZ]; /* for stdio */
-
- hidden char tcapent[BUFFERSIZE]; /* storage for termcap entry */
- hidden char capst[BUFFERSIZE]; /* storage for tgetstr */
- hidden char *capptr = capst; /* pointer to next tgetstr output */
-
- extern char *tgetstr(); /* returns capability string */
- extern char *getenv();
- extern char *tgoto(); /* returns cursor addressing code */
-
- public char *KU,*KD,*KL,*KR,*PU,*PD; /* function-key strings */
- public char *KS,*KE; /* keypad enable/disable */
-
- hidden char *CL,*CD,*CM,*CE,*SO,*SE; /* screen capabilities */
- public int CO,LI; /* screen size */
-
- public int wbase[BOT+1]; /* where windows start */
- public int wsize[BOT+1]; /* how big windows are */
-
- hidden int curwin = 0; /* what window we are in */
- hidden int curx = 0; /* where we are on the screen */
- hidden int cury = 0; /* line in that window */
-
- hidden void winout();
-
- /* printcl - print one line in a window, then clear to end of line */
-
- public int printcl(window,line,s)
- int window;
- int line;
- char *s;
- {
- if (line < 0 || line >= wsize[window])
- fatal("line %d not in window %d",line,window);
-
- tputs(tgoto(CM,curx = 0,(cury = line)+wbase[curwin = window]),1,fputchar);
- winout(s);
- if (cury < wsize[curwin])
- tputs(CE,1,fputchar);
- fflush(stdout);
- return(cury-line+1);
- }
-
- /* printat - print one line in a window */
-
- public int printat(window,line,s)
- int window;
- int line;
- char *s;
- {
- if (line < 0 || line >= wsize[window])
- fatal("line %d not in window %d",line,window);
-
- tputs(tgoto(CM,curx = 0,(cury = line)+wbase[curwin = window]),1,fputchar);
- winout(s);
- fflush(stdout);
- return(cury-line+1);
- }
-
- /* putw - put character at current location */
-
- public int putw(c)
- int c;
- {
- register int line = cury;
- char buf[2];
-
- buf[0] = c;
- buf[1] = '\0';
- winout(buf);
- fflush(stdout);
- return(cury-line+1);
- }
-
- /* printw - formatted print at current location */
-
- public int printw(s)
- char *s;
- {
- register int line = cury;
-
- winout(s);
- fflush(stdout);
- return(cury-line+1);
- }
-
- /* winout - keep track of the column we are in (clean this up) */
-
- /*
- * Routine to check that output stays within its window.
- * It takes care of terminals that cannot wrap long lines
- * or cannot backspace across the beginning of a line.
- */
-
- hidden void winout(s) /* implicit inputs/outputs: cury,curx,curwin,wsize */
- register char *s;
- {
- register int ch;
- int limit;
-
- for (limit = wsize[curwin]; (ch = (*s&0177)) && cury < limit; s++) {
- if (isprint(ch) || ch == ' ') { /* if printable */
- putchar(ch),curx++; /* leave it alone */
- } else if (ch == '\t') { /* if horizontal tab */
- do {
- winout(" "); /* expand it */
- } while (curx&7 && cury < limit);
- } else if (ch == '\b') { /* backspace */
- if (curx == 0 && cury == 0) {
- /* void */ ; /* don't leave the window */
- } else if ((curx = (curx > 0 ? curx-1 : (cury--,CO-1))) != CO-1) {
- putchar(ch); /* not at start of line */
- } else {
- tputs(tgoto(CM,curx,cury+wbase[curwin]),1,fputchar);
- }
- } else if (ch == '\n') { /* if newline */
- tputs(CE,1,fputchar); /* erase rest of line */
- if ((curx = 0),++cury < limit) /* advance virtual cursor */
- fputs("\r\n",stdout); /* advance physical cursor */
- } else if (ch == '\r') { /* if carriage return */
- putchar(ch),curx = 0; /* output it and reset curx */
- } else if (ch == '\07') { /* if the bell */
- putchar(ch); /* make them sound */
- } else { /* otherwise garbage */
- char buf[3];
- sprintf(buf,"^%c",ch^0100); /* uncontrollify */
- winout(buf); /* output it */
- }
- if (curx >= CO) /* at rhs of screen */
- tputs(tgoto(CM,curx = 0,++cury+wbase[curwin]),1,fputchar);
- }
- }
-
- #ifdef unix
-
- /* fputchar - output a character on stdout */
-
- public int fputchar(c)
- int c;
- {
- return(putchar(c));
- }
-
- #endif /* unix */
-
- /* clrtoeol - clear to end of line */
-
- public void clrtoeol()
- {
- tputs(CE,1,fputchar);
- }
-
- /* clrtobot - clear to end of screen */
-
- public void clrtobot()
- {
- tputs(CD,1,fputchar);
- }
-
- /* clrscreen - clear screen */
-
- public void clrscreen()
- {
- tputs(CL,1,fputchar);
- }
-
- /* beep - ring the bell */
-
- public void beep()
- {
- putw('\07');
- }
- /* wininit - extract terminal info and initialize window manager */
-
- public void wininit()
- {
- char *term;
-
- setbuf(stdout,outbuf); /* buffer stdout */
-
- term = getenv("TERM");
- switch(tgetent(tcapent,term = getenv("TERM"))) {
- case -1:
- fatal("termcap database not found\n");
- /* NOTREACHED */
- case 0:
- fatal("unknown terminal: %s\n",term);
- /* NOTREACHED */
- }
- /* extract capabilities. should use tables, but what the heck */
-
- if ((CE = tgetstr("ce",&capptr)) == 0 /* clear to end of line */
- || (CD = tgetstr("cd",&capptr)) == 0 /* clear to end of screen */
- || (CL = tgetstr("cl",&capptr)) == 0 /* clear to end of screen */
- #ifdef someday
- || (SO = tgetstr("so",&capptr)) == 0 /* stand-out on */
- || (SE = tgetstr("se",&capptr)) == 0 /* stand-out off */
- #endif
- || (CM = tgetstr("cm",&capptr)) == 0 /* cursor movement */
- || (KU = tgetstr("ku",&capptr)) == 0 /* up-arrow */
- || (KD = tgetstr("kd",&capptr)) == 0 /* down_arrow */
- || (KL = tgetstr("kl",&capptr)) == 0 /* left-arrow */
- || (KR = tgetstr("kr",&capptr)) == 0 /* right-arrow */
- #ifdef unix
- || (PU = tgetstr("k1",&capptr)) == 0 /* page-up (F1) */
- || (PD = tgetstr("k2",&capptr)) == 0 /* page down (F2) */
- #endif
- #ifdef MSDOS
- || (PU = tgetstr("PU",&capptr)) == 0 /* really PgUp */
- || (PD = tgetstr("PD",&capptr)) == 0 /* really PgDn */
- #endif
- || (CO = tgetnum("co")) == 0
- || (LI = tgetnum("li")) == 0)
- fatal("Your terminal is too dumb");
-
- /* the following capabilities are not mandatory */
-
- KS = tgetstr("ks",&capptr); /* keypad on */
- KE = tgetstr("ke",&capptr); /* keypad off */
-
- /* set window base and size */
-
- if (CO < 80)
- fatal("Terminal screen is to narrow");
- wsize[TOP] = 2;
- wbase[TOP] = 0;
- wsize[BOT] = 5;
- wbase[BOT] = LI-wsize[BOT];
- wbase[MID] = wbase[TOP]+wsize[TOP];
- if ((wsize[MID] = wbase[BOT]-wbase[MID]) < 5)
- fatal("Not enough lines on this terminal");
- }
-