home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / TERMCAP.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  7KB  |  329 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* termcap.c - version 1.0.3 */
  3.  
  4. #include <stdio.h>
  5. #include "config.h"    /* for ROWNO and COLNO */
  6. #include "flag.h"    /* for flags.nonull */
  7. extern char *tgetstr(), *tgoto(), *getenv();
  8. extern long *alloc();
  9.  
  10. #ifndef lint
  11. extern            /* it is defined in libtermlib (libtermcap) */
  12. #endif lint
  13.     short ospeed;        /* terminal baudrate; used by tputs */
  14. static char tbuf[512];
  15. #ifdef DGK
  16. char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE, *HI, *HE;
  17. #else
  18. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  19. #endif DGK
  20. static char *VS, *VE;
  21. static int SG;
  22. static char PC = '\0';
  23. char *CD;        /* tested in pri.c: docorner() */
  24. int CO, LI;        /* used in pri.c and whatis.c */
  25.  
  26. #ifdef MSDOS
  27. static char tgotobuf[20];
  28. #define tgoto(fmt, x, y)    (sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
  29. #endif MSDOS
  30.  
  31. startup()
  32. {
  33. #ifdef MSDOS
  34.     HO = "\033[H";
  35.     CL = "\033[2J";        /* the ANSI termcap */
  36.     CE = "\033[K";
  37.     UP = "\033[A";
  38.     CM = "\033[%d;%dH";    /* used with function tgoto() */
  39.     ND = "\033[C";
  40.     XD = "\033[B";
  41.     BC = "\033[D";
  42.     SO = "\033[7m";
  43.     SE = "\033[0m";
  44.     TI = "";
  45.     TE = "";
  46.     VS = "";
  47.     VE = "";
  48. #ifdef DGK
  49.     /* Both HI and HE have 4 characters.  The function let_to_name()
  50.      * in msdos.c uses this length when creating a buffer.  If you
  51.      * make HI and HE longer, you must also change the length of buf[]
  52.      * in let_to_name()
  53.      */
  54.     HI = "\033[4m";
  55.     HE = "\033[0m";
  56. #endif DGK
  57.     CD = "\033";
  58.     CO = COLNO;
  59.     LI = ROWNO;
  60. #else
  61.     register char *term;
  62.     register char *tptr;
  63.     char *tbufptr, *pc;
  64.  
  65.     tptr = (char *) alloc(1024);
  66.  
  67.     tbufptr = tbuf;
  68.     if(!(term = getenv("TERM")))
  69.         error("Can't get TERM.");
  70.     if(!strncmp(term, "5620", 4))
  71.         flags.nonull = 1;    /* this should be a termcap flag */
  72.     if(tgetent(tptr, term) < 1)
  73.         error("Unknown terminal type: %s.", term);
  74.     if(pc = tgetstr("pc", &tbufptr))
  75.         PC = *pc;
  76.     if(!(BC = tgetstr("bc", &tbufptr))) {    
  77.         if(!tgetflag("bs"))
  78.             error("Terminal must backspace.");
  79.         BC = tbufptr;
  80.         tbufptr += 2;
  81.         *BC = '\b';
  82.     }
  83.     HO = tgetstr("ho", &tbufptr);
  84.     CO = tgetnum("co");
  85.     LI = tgetnum("li");
  86.     if(CO < COLNO || LI < ROWNO+2)
  87.         setclipped();
  88.     if(!(CL = tgetstr("cl", &tbufptr)))
  89.         error("Hack needs CL.");
  90.     ND = tgetstr("nd", &tbufptr);
  91.     if(tgetflag("os"))
  92.         error("Hack can't have OS.");
  93.     CE = tgetstr("ce", &tbufptr);
  94.     UP = tgetstr("up", &tbufptr);
  95.     /* It seems that xd is no longer supported, and we should use
  96.        a linefeed instead; unfortunately this requires resetting
  97.        CRMOD, and many output routines will have to be modified
  98.        slightly. Let's leave that till the next release. */
  99.     XD = tgetstr("xd", &tbufptr);
  100. /* not:         XD = tgetstr("do", &tbufptr); */
  101.     if(!(CM = tgetstr("cm", &tbufptr))) {
  102.         if(!UP && !HO)
  103.             error("Hack needs CM or UP or HO.");
  104.         printf("Playing hack on terminals without cm is suspect...\n");
  105.         getret();
  106.     }
  107.     SO = tgetstr("so", &tbufptr);
  108.     SE = tgetstr("se", &tbufptr);
  109.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  110.     if(!SO || !SE || (SG > 0)) SO = SE = 0;
  111.     CD = tgetstr("cd", &tbufptr);
  112.     set_whole_screen();        /* uses LI and CD */
  113.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  114.     free(tptr);
  115. #endif MSDOS
  116. }
  117.  
  118. start_screen()
  119. {
  120.     xputs(TI);
  121.     xputs(VS);
  122. }
  123.  
  124. end_screen()
  125. {
  126.     xputs(VE);
  127.     xputs(TE);
  128. }
  129.  
  130. /* Cursor movements */
  131. extern xchar curx, cury;
  132.  
  133. curs(x, y)
  134. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  135.                curx-x would be unsigned as well */
  136. {
  137.  
  138.     if (y == cury && x == curx)
  139.         return;
  140.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  141.         cmov(x, y);            /* bunker!wtm */
  142.         return;
  143.     }
  144.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  145.         nocmov(x, y);
  146.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  147.         (void) putchar('\r');
  148.         curx = 1;
  149.         nocmov(x, y);
  150.     } else if(!CM) {
  151.         nocmov(x, y);
  152.     } else
  153.         cmov(x, y);
  154. }
  155.  
  156. nocmov(x, y)
  157. {
  158.     if (cury > y) {
  159.         if(UP) {
  160.             while (cury > y) {    /* Go up. */
  161.                 xputs(UP);
  162.                 cury--;
  163.             }
  164.         } else if(CM) {
  165.             cmov(x, y);
  166.         } else if(HO) {
  167.             home();
  168.             curs(x, y);
  169.         } /* else impossible("..."); */
  170.     } else if (cury < y) {
  171.         if(XD) {
  172.             while(cury < y) {
  173.                 xputs(XD);
  174.                 cury++;
  175.             }
  176.         } else if(CM) {
  177.             cmov(x, y);
  178.         } else {
  179.             while(cury < y) {
  180.                 xputc('\n');
  181.                 curx = 1;
  182.                 cury++;
  183.             }
  184.         }
  185.     }
  186.     if (curx < x) {        /* Go to the right. */
  187.         if(!ND) cmov(x, y); else    /* bah */
  188.             /* should instead print what is there already */
  189.         while (curx < x) {
  190.             xputs(ND);
  191.             curx++;
  192.         }
  193.     } else if (curx > x) {
  194.         while (curx > x) {    /* Go to the left. */
  195.             xputs(BC);
  196.             curx--;
  197.         }
  198.     }
  199. }
  200.  
  201. cmov(x, y)
  202. register x, y;
  203. {
  204.     xputs(tgoto(CM, x-1, y-1));
  205.     cury = y;
  206.     curx = x;
  207. }
  208.  
  209. xputc(c) char c; {
  210.     (void) fputc(c, stdout);
  211. }
  212.  
  213. xputs(s) char *s; {
  214. #ifdef MSDOS
  215.     fputs(s, stdout);
  216. #else
  217.     tputs(s, 1, xputc);
  218. #endif
  219. }
  220.  
  221. cl_end() {
  222.     if(CE)
  223.         xputs(CE);
  224.     else {    /* no-CE fix - free after Harold Rynes */
  225.         /* this looks terrible, especially on a slow terminal
  226.            but is better than nothing */
  227.         register cx = curx, cy = cury;
  228.  
  229.         while(curx < COLNO) {
  230.             xputc(' ');
  231.             curx++;
  232.         }
  233.         curs(cx, cy);
  234.     }
  235. }
  236.  
  237. clear_screen() {
  238.     xputs(CL);
  239.     curx = cury = 1;
  240. }
  241.  
  242. home()
  243. {
  244.     if(HO)
  245.         xputs(HO);
  246.     else if(CM)
  247.         xputs(tgoto(CM, 0, 0));
  248.     else
  249.         curs(1, 1);    /* using UP ... */
  250.     curx = cury = 1;
  251. }
  252.  
  253. standoutbeg()
  254. {
  255.     if(SO) xputs(SO);
  256. }
  257.  
  258. standoutend()
  259. {
  260.     if(SE) xputs(SE);
  261. }
  262.  
  263. backsp()
  264. {
  265.     xputs(BC);
  266.     curx--;
  267. }
  268.  
  269. bell()
  270. {
  271. #ifdef DGK
  272.     if (flags.silent) return;
  273. #endif DGK
  274.     (void) putchar('\007');        /* curx does not change */
  275.     (void) fflush(stdout);
  276. }
  277.  
  278. static short tmspc10[] = {        /* from termcap */
  279.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  280. };
  281.  
  282. delay_output() {
  283.     /* delay 50 ms - could also use a 'nap'-system call */
  284.     /* BUG: if the padding character is visible, as it is on the 5620
  285.        then this looks terrible. */
  286. #ifdef MSDOS
  287.     /* simulate the delay with "cursor here" 5 times*/
  288.     register i;
  289.     for (i = 0; i < 5; i++)
  290.         cmov(curx, cury);
  291. #else
  292.     if(!flags.nonull)
  293.         tputs("50", 1, xputc);
  294.  
  295.         /* cbosgd!cbcephus!pds for SYS V R2 */
  296.         /* is this terminfo, or what? */
  297.         /* tputs("$<50>", 1, xputc); */
  298.  
  299.     else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
  300.         /* delay by sending cm(here) an appropriate number of times */
  301.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  302.         register int i = 500 + tmspc10[ospeed]/2;
  303.  
  304.         while(i > 0) {
  305.             cmov(curx, cury);
  306.             i -= cmlen*tmspc10[ospeed];
  307.         }
  308.     }
  309. #endif MSDOS
  310. }
  311.  
  312. cl_eos()            /* free after Robert Viduya */
  313. {                /* must only be called with curx = 1 */
  314.  
  315.     if(CD)
  316.         xputs(CD);
  317.     else {
  318.         register int cx = curx, cy = cury;
  319.         while(cury <= LI-2) {
  320.             cl_end();
  321.             xputc('\n');
  322.             curx = 1;
  323.             cury++;
  324.         }
  325.         cl_end();
  326.         curs(cx, cy);
  327.     }
  328. }
  329.