home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / termcap.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  9KB  |  353 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 by Jonathan Payne.  JOVE is  *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. #include "jove.h"
  9.  
  10. #ifdef TERMCAP    /* the body is the rest of the file */
  11.  
  12. #include "term.h"
  13.  
  14. #include "disp.h"
  15. #include "fmt.h"
  16. #include "fp.h"
  17. #include "jctype.h"
  18. #include "screen.h"
  19.  
  20. extern int    UNMACRO(tgetent) proto((char */*buf*/, const char */*name*/));
  21. extern int    UNMACRO(tgetflag) proto((const char */*id*/));
  22. extern int    UNMACRO(tgetnum) proto((const char */*id*/));
  23. extern char    *UNMACRO(tgetstr) proto((const char */*id*/, char **/*area*/));
  24. extern void    UNMACRO(tputs) proto((const char *, int, void (*) proto((int))));
  25.  
  26. /* Termcap definitions */
  27.  
  28. char
  29.     *CS,    /* change scrolling region */
  30.     *SO,    /* Start standout */
  31.     *SE,    /* End standout */
  32.     *US,    /* Start underlining */
  33.     *UE,    /* End underlining */
  34.     *CM,    /* The cursor motion string */
  35.     *CL,    /* Clear screen */
  36.     *CE,    /* Clear to end of line */
  37.     *HO,    /* Home cursor */
  38.     *AL,    /* Addline (insert line) */
  39.     *DL,    /* Delete line */
  40.     *VS,    /* Visual start */
  41.     *VE,    /* Visual end */
  42.     *KS,    /* Keypad mode start */
  43.     *KE,    /* Keypad mode end */
  44.     *TI,    /* Cursor addressing start */
  45.     *TE,    /* Cursor addressing end */
  46.     *LL,    /* Last line, first column */
  47.     *SF = "\n",    /* Scroll forward (defaults to \n) */
  48.     *SR,    /* Scroll reverse */
  49.     *VB,    /* visible bell */
  50.     *BL = "\007",    /* audible bell (defaults to BEL) */
  51.     *lPC,    /* pad character (as a string!) */
  52.     *NL = "\n",    /* newline character (defaults to \n) */
  53.     *DO = "\n",    /* down one line (defaults to \n capability) */
  54.     *M_AL,    /* Insert line with arg */
  55.     *M_DL,    /* Delete line with arg */
  56.     *M_SF,    /* Scroll forward with arg */
  57.     *M_SR;    /* Scroll back with arg */
  58.  
  59. int
  60.     UPlen = INFINITY,        /* length of the UP string */
  61.     HOlen = INFINITY,        /* length of Home string */
  62.     LLlen = INFINITY,        /* length of last line string */
  63.  
  64.     phystab = 8,    /* ("it") terminal's tabstop settings */
  65.     UG;        /* number of magic cookies left by US and UE */
  66.  
  67. bool
  68.     Hazeltine,    /* Hazeltine tilde kludge */
  69.     UL,        /* underscores don't replace chars already on screen */
  70.     NP;        /* there is No Pad character */
  71.  
  72. #  ifdef DEFINE_PC_BC_UP_OSPEED
  73.     /* This is needed for HP-UX, possibly for other SYSVR2 systems */
  74. char
  75.     PC,        /* pad character, as a char (set from lPC; defaults to NUL) */
  76.     *BC,    /* back space (defaults to BS) */
  77.     *UP;    /* Scroll reverse, or up */
  78.  
  79. short    ospeed;
  80. #  endif /* DEFINE_PC_BC_UP_OSPEED */
  81.  
  82. bool    CanScroll;    /* can this terminal scroll? */
  83.  
  84. #  ifdef ID_CHAR
  85.  
  86. char
  87.     *IC,    /* Insert char */
  88.     *DC,    /* Delete char */
  89.     *IM,    /* Insert mode */
  90.     *EI,    /* End insert mode */
  91.     *IP,    /* insert pad after character inserted */
  92.     *M_IC,    /* Insert char with arg */
  93.     *M_DC;    /* Delete char with arg */
  94.  
  95. bool    UseIC = NO;    /* VAR: whether or not to use i/d char processesing */
  96.  
  97. int
  98.     IMlen = 0,    /* length of insert mode */
  99.     EIlen = 0,    /* length of end insert mode string */
  100.     IClen = 0,    /* length of insert char */
  101.     DClen = 0,    /* length of delete char */
  102.     MIClen = INFINITY,    /* length of insert char with arg */
  103.     MDClen = INFINITY,    /* length of delete char with arg */
  104.     CElen = 0;    /* length of clear to end of line */
  105.  
  106. bool
  107.     MI;        /* okay to move while in insert mode */
  108.  
  109. #  endif /* ID_CHAR */
  110.  
  111. private char    tspace[256];    /* space for termcap strings */
  112.  
  113. /* The ordering of ts and meas must agree !! */
  114. private const char    ts[] =
  115. #  ifdef ID_CHAR
  116. /*                   |                   |                   | |             */
  117. "vsvealdlcssoseusuecmclcehoupbcllsfsrvbksketitepcblnldoALDLSFSRicimdceiipICDC";
  118. #  else
  119. "vsvealdlcssoseusuecmclcehoupbcllsfsrvbksketitepcblnldoALDLSFSR";
  120. #  endif
  121.  
  122. private char    **const meas[] = {
  123.     &VS, &VE, &AL, &DL, &CS, &SO, &SE, &US, &UE, &CM,
  124.     &CL, &CE, &HO, &UP, &BC, &LL, &SF, &SR, &VB, &KS,
  125.     &KE, &TI, &TE, &lPC, &BL, &NL, &DO, &M_AL, &M_DL, &M_SF,
  126.     &M_SR,
  127. #  ifdef ID_CHAR
  128.     &IC, &IM, &DC, &EI, &IP, &M_IC, &M_DC,
  129. #  endif
  130.     NULL
  131. };
  132.  
  133. struct CapLen {
  134.     char    **cap_var;
  135.     int    *len_var;
  136. };
  137.  
  138. private const struct CapLen    CapLenTab[] = {
  139.     { &HO,    &HOlen },
  140.     { &LL,    &LLlen },
  141.     { &UP,    &UPlen },
  142. #  ifdef ID_CHAR
  143.     { &IM,    &IMlen },
  144.     { &EI,    &EIlen },
  145.     { &IC,    &IClen },
  146.     { &DC,    &DClen },
  147.     { &M_IC,    &MIClen },
  148.     { &M_DC,    &MDClen },
  149.     { &CE,    &CElen },
  150. #  endif
  151.     { NULL,    NULL }
  152. };
  153.  
  154. private void
  155. tcbad(termname, why)
  156. const char
  157.     *termname,
  158.     *why;
  159. {
  160.     writef("You can't run JOVE on a %s terminal: %s\n", termname, why);
  161.     flushscreen();
  162.     _exit(1);
  163. }
  164.  
  165. void
  166. getTERM()
  167. {
  168.     char    termnmbuf[13],
  169.         *termname = getenv("TERM"),
  170.         *termp = tspace,
  171.         tbuff[2048];    /* Good grief! */
  172.  
  173.     if (termname == NULL || *termname == '\0'
  174.     || strcmp(termname, "dumb") == 0
  175.     || strcmp(termname, "unknown") == 0
  176.     || strcmp(termname, "network") == 0)
  177.     {
  178.         int    len;
  179. #ifdef __amigaos__
  180.           putstr("No TERM environment variable set, recommend \"setenv TERM=amiga\"\n");
  181.         putstr("Enter terminal type (e.g, amiga): ");
  182. #else
  183.         putstr("Enter terminal type (e.g, vt100): ");
  184. #endif
  185.         flushscreen();
  186.         len = read(0, (UnivPtr) termnmbuf, sizeof(termnmbuf));
  187.         termnmbuf[len > 1? len - 1 : 0] = '\0';
  188.         termname = termnmbuf;
  189.     }
  190.  
  191.     if (tgetent(tbuff, termname) < 1)
  192.         tcbad(termname, "type unknown");
  193.  
  194.     /* get numeric capabilities */
  195.  
  196.     if ((CO = tgetnum("co")) == -1)
  197.         tcbad(termname, "co unknown (width)");
  198.  
  199.     if (CO > MAXCOLS)
  200.         CO = MAXCOLS;
  201.  
  202.     if ((LI = tgetnum("li")) == -1)
  203.         tcbad(termname, "li unknown (height)");
  204.  
  205.     if ((phystab = tgetnum("it")) == -1 || phystab <= 0)
  206.         phystab = 8;
  207.  
  208.     if ((SG = tgetnum("sg")) == -1)
  209.         SG = 0;            /* Used for mode line only */
  210.  
  211.     if ((UG = tgetnum("ug")) == -1)
  212.         UG = 0;            /* We shan't bother if != 0 */
  213.  
  214.     /* get string capabilities */
  215.     {
  216.         const char    *tsp = ts;
  217.         char    **const *measp;
  218.  
  219.         for (measp = meas; *measp != NULL; measp++) {
  220.             static char    nm[3] = "xx";
  221.             char    *val;
  222.  
  223.             nm[0] = *tsp++;
  224.             nm[1] = *tsp++;
  225.             val = tgetstr(nm, &termp);
  226.             if (val != NULL)
  227.                 **measp = val;
  228.             if (termp > tspace + sizeof(tspace))
  229.                 tcbad(termname, "too many bytes of termcap strings");
  230.         }
  231.     }
  232.     if (lPC)
  233.         PC = *lPC;    /* convert lPC string attribute to char PC */
  234.  
  235.     /* get boolean capabilities */
  236.  
  237.     Hazeltine = tgetflag("hz")==YES;    /* Hazeltine tilde kludge */
  238.     NP = tgetflag("NP")==YES;    /* there is No Pad character */
  239.     UL = tgetflag("ul")==YES;    /* underscores don't replace chars already on screen */
  240.  
  241.     /* adjust capabilities */
  242.  
  243.     if (tgetflag("km") == YES
  244. #  if defined(USE_CTYPE) && !defined(NO_SETLOCALE)
  245.     && strcmp(LcCtype, "C") == 0
  246. #  endif
  247.     )
  248.         MetaKey = YES;    /* has meta-key and default locale */
  249.  
  250.     if (tgetflag("xs") == YES) {
  251.         SO = SE = NULL;    /* don't use braindamaged standout mode */
  252.         SG = 0;
  253.     }
  254.  
  255.     if (SR == NULL && M_SR == NULL)
  256.         CS = NULL;    /* don't use scrolling region without way of reverse scrolling */
  257.  
  258.     /* Note: the way termcap/terminfo is defined, we must use *both*
  259.      * IC and IM to insert, but normally only one will be defined.
  260.      * See terminfo(5), under the heading "Insert/Delete Character".
  261.      * Because of this, IM might be defined as a null string.
  262.      */
  263. #  ifdef ID_CHAR
  264.     if (IM != NULL && *IM == '\0')
  265.         IM = NULL;    /* If IM is empty, supress. */
  266.  
  267.     UseIC = (IC != NULL || IM != NULL || M_IC != NULL);
  268.     MI = tgetflag("mi")==YES;    /* okay to move while in insert mode */
  269. #  endif /* ID_CHAR */
  270.  
  271.     /* strip stupid padding information */
  272.     while ('0' <= *NL && *NL <= '9')
  273.         NL += 1;
  274.     if (*NL == '*')
  275.         NL += 1;
  276.  
  277.     if (BC == NULL)
  278.         BC = "\b";    /* default back space to BS */
  279.  
  280.     CanScroll = (AL != NULL && DL != NULL) || CS != NULL;
  281.  
  282.     /* calculate lengths */
  283.     {
  284.         static const struct CapLen    *p;
  285.  
  286.         for (p = CapLenTab; p->cap_var != NULL; p++)
  287.             if (*p->cap_var != NULL)
  288.                 *p->len_var = strlen(*p->cap_var);
  289.     }
  290.     if (!(CM != NULL || HO != NULL))
  291.         tcbad(termname, "JOVE needs either cm or ho termcap/terminfo capability");
  292. }
  293.  
  294. /* Put multi-unit or multiple single-unit strings, as appropriate. */
  295.  
  296. private void
  297. tputc(c)
  298. char    c;
  299. {
  300.     scr_putchar(c);
  301. }
  302.  
  303. void
  304. putmulti(ss, ms, num, lines)
  305. const char
  306.     *ss,    /* single line */
  307.     *ms;    /* multiline */
  308. int
  309.     num,    /* number of iterations */
  310.     lines;    /* lines affected (for padding) */
  311. {
  312.     if (ms && (num > 1 || !ss)) {
  313.         /* use the multi string */
  314.         tputs(targ1(ms, num), lines, tputc);
  315.     } else {
  316.         /* repeatedly use single string */
  317.         while (num--)
  318.             putpad(ss, lines);
  319.     }
  320. }
  321.  
  322. /* put a string with padding */
  323.  
  324. void
  325. putpad(str, lines)
  326. const char    *str;
  327. int    lines;
  328. {
  329.     if (str != NULL)
  330.         tputs(str, lines, tputc);
  331. }
  332.  
  333. void
  334. dobell(n)    /* declared in term.h */
  335. int    n;
  336. {
  337.     while (--n >= 0) {
  338.         if (VisBell && VB)
  339.             putstr(VB);
  340.         else
  341.             putpad(BL, 1);
  342.     }
  343.     flushscreen();
  344. }
  345.  
  346. void
  347. clr_page()
  348. {
  349.     putpad(CL, LI);
  350. }
  351.  
  352. #endif /* TERMCAP */
  353.