home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / EDITOR / NVI179B / NVI179B.ZIP / cl / cl_bsd.c next >
C/C++ Source or Header  |  1996-07-01  |  8KB  |  346 lines

  1. /*-
  2.  * Copyright (c) 1995, 1996
  3.  *    Keith Bostic.  All rights reserved.
  4.  *
  5.  * See the LICENSE file for redistribution information.
  6.  */
  7.  
  8. #include "config.h"
  9.  
  10. #ifndef lint
  11. static const char sccsid[] = "@(#)cl_bsd.c    8.29 (Berkeley) 7/1/96";
  12. #endif /* not lint */
  13.  
  14. #include <sys/types.h>
  15. #include <sys/queue.h>
  16. #include <sys/time.h>
  17.  
  18. #include <bitstring.h>
  19. #include <ctype.h>
  20. #include <curses.h>
  21. #include <signal.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <termios.h>
  26. #include <unistd.h>
  27.  
  28. #include "../common/common.h"
  29. #include "../vi/vi.h"
  30. #include "cl.h"
  31.  
  32. static char    *ke;                /* Keypad on. */
  33. static char    *ks;                /* Keypad off. */
  34. static char    *vb;                /* Visible bell string. */
  35.  
  36. /*
  37.  * HP's support the entire System V curses package except for the tigetstr
  38.  * and tigetnum functions.  Ultrix supports the BSD curses package except
  39.  * for the idlok function.  Cthulu only knows why.  Break things up into a
  40.  * minimal set of functions.
  41.  */
  42.  
  43. #ifndef HAVE_CURSES_ADDNSTR
  44. /*
  45.  * addnstr --
  46.  *
  47.  * PUBLIC: #ifndef HAVE_CURSES_ADDNSTR
  48.  * PUBLIC: int addnstr __P((char *, int));
  49.  * PUBLIC: #endif
  50.  */
  51. int
  52. addnstr(s, n)
  53.     char *s;
  54.     int n;
  55. {
  56.     int ch;
  57.  
  58.     while (n-- && (ch = *s++))
  59.         addch(ch);
  60.     return (OK);
  61. }
  62. #endif
  63.  
  64. #ifndef    HAVE_CURSES_BEEP
  65. /*
  66.  * beep --
  67.  *
  68.  * PUBLIC: #ifndef HAVE_CURSES_BEEP
  69.  * PUBLIC: void beep __P((void));
  70.  * PUBLIC: #endif
  71.  */
  72. void
  73. beep()
  74. {
  75.     (void)write(1, "\007", 1);    /* '\a' */
  76. }
  77. #endif /* !HAVE_CURSES_BEEP */
  78.  
  79. #ifndef    HAVE_CURSES_FLASH
  80. /*
  81.  * flash --
  82.  *    Flash the screen.
  83.  *
  84.  * PUBLIC: #ifndef HAVE_CURSES_FLASH
  85.  * PUBLIC: void flash __P((void));
  86.  * PUBLIC: #endif
  87.  */
  88. void
  89. flash()
  90. {
  91.     if (vb != NULL) {
  92.         (void)tputs(vb, 1, cl_putchar);
  93.         (void)fflush(stdout);
  94.     } else
  95.         beep();
  96. }
  97. #endif /* !HAVE_CURSES_FLASH */
  98.  
  99. #ifndef    HAVE_CURSES_IDLOK
  100. /*
  101.  * idlok --
  102.  *    Turn on/off hardware line insert/delete.
  103.  *
  104.  * PUBLIC: #ifndef HAVE_CURSES_IDLOK
  105.  * PUBLIC: void idlok __P((WINDOW *, int));
  106.  * PUBLIC: #endif
  107.  */
  108. void
  109. idlok(win, bf)
  110.     WINDOW *win;
  111.     int bf;
  112. {
  113.     return;
  114. }
  115. #endif /* !HAVE_CURSES_IDLOK */
  116.  
  117. #ifndef    HAVE_CURSES_KEYPAD
  118. /*
  119.  * keypad --
  120.  *    Put the keypad/cursor arrows into or out of application mode.
  121.  *
  122.  * PUBLIC: #ifndef HAVE_CURSES_KEYPAD
  123.  * PUBLIC: int keypad __P((void *, int));
  124.  * PUBLIC: #endif
  125.  */
  126. int
  127. keypad(a, on)
  128.     void *a;
  129.     int on;
  130. {
  131.     char *p;
  132.  
  133.     if ((p = tigetstr(on ? "smkx" : "rmkx")) != (char *)-1) {
  134.         (void)tputs(p, 0, cl_putchar);
  135.         (void)fflush(stdout);
  136.     }
  137.     return (0);
  138. }
  139. #endif /* !HAVE_CURSES_KEYPAD */
  140.  
  141. #ifndef    HAVE_CURSES_NEWTERM
  142. /*
  143.  * newterm --
  144.  *    Create a new curses screen.
  145.  *
  146.  * PUBLIC: #ifndef HAVE_CURSES_NEWTERM
  147.  * PUBLIC: void *newterm __P((const char *, FILE *, FILE *));
  148.  * PUBLIC: #endif
  149.  */
  150. void *
  151. newterm(a, b, c)
  152.     const char *a;
  153.     FILE *b, *c;
  154. {
  155.     return (initscr());
  156. }
  157. #endif /* !HAVE_CURSES_NEWTERM */
  158.  
  159. #ifndef    HAVE_CURSES_SETUPTERM
  160. /*
  161.  * setupterm --
  162.  *    Set up terminal.
  163.  *
  164.  * PUBLIC: #ifndef HAVE_CURSES_SETUPTERM
  165.  * PUBLIC: void setupterm __P((char *, int, int *));
  166.  * PUBLIC: #endif
  167.  */
  168. void
  169. setupterm(ttype, fno, errp)
  170.     char *ttype;
  171.     int fno, *errp;
  172. {
  173.     static char buf[2048];
  174.     char *p;
  175.  
  176.     if ((*errp = tgetent(buf, ttype)) > 0) {
  177.         if (ke != NULL)
  178.             free(ke);
  179.         ke = ((p = tigetstr("rmkx")) == (char *)-1) ?
  180.             NULL : strdup(p);
  181.         if (ks != NULL)
  182.             free(ks);
  183.         ks = ((p = tigetstr("smkx")) == (char *)-1) ?
  184.             NULL : strdup(p);
  185.         if (vb != NULL)
  186.             free(vb);
  187.         vb = ((p = tigetstr("flash")) == (char *)-1) ?
  188.             NULL : strdup(p);
  189.     }
  190. }
  191. #endif /* !HAVE_CURSES_SETUPTERM */
  192.  
  193. #ifndef    HAVE_CURSES_TIGETSTR
  194. /* Terminfo-to-termcap translation table. */
  195. typedef struct _tl {
  196.     char *terminfo;            /* Terminfo name. */
  197.     char *termcap;            /* Termcap name. */
  198. } TL;
  199. static const TL list[] = {
  200.     "cols",        "co",        /* Terminal columns. */
  201.     "cup",        "cm",        /* Cursor up. */
  202.     "cuu1",        "up",        /* Cursor up. */
  203.     "el",        "ce",        /* Clear to end-of-line. */
  204.     "flash",    "vb",        /* Visible bell. */
  205.     "kcub1",      "kl",        /* Cursor left. */
  206.     "kcud1",    "kd",        /* Cursor down. */
  207.     "kcuf1",    "kr",        /* Cursor right. */
  208.     "kcuu1",      "ku",        /* Cursor up. */
  209.     "kdch1",    "kD",        /* Delete character. */
  210.     "kdl1",        "kL",        /* Delete line. */
  211.     "ked",        "kS",        /* Delete to end of screen. */
  212.     "kel",        "kE",        /* Delete to eol. */
  213.     "khome",    "kh",        /* Go to sol. */
  214.     "kich1",    "kI",        /* Insert at cursor. */
  215.     "kil1",        "kA",        /* Insert line. */
  216.     "kind",        "kF",        /* Scroll down. */
  217.     "kll",        "kH",        /* Go to eol. */
  218.     "knp",        "kN",        /* Page down. */
  219.     "kpp",        "kP",        /* Page up. */
  220.     "kri",        "kR",        /* Scroll up. */
  221.     "lines",    "li",        /* Terminal lines. */
  222.     "rmcup",    "te",        /* Terminal end string. */
  223.     "rmkx",        "ke",        /* Exit "keypad-transmit" mode. */
  224.     "rmso",        "se",        /* Standout end. */
  225.     "smcup",    "ti",        /* Terminal initialization string. */
  226.     "smkx",        "ks",        /* Enter "keypad-transmit" mode. */
  227.     "smso",        "so",        /* Standout begin. */
  228. };
  229.  
  230. #ifdef _AIX
  231. /*
  232.  * AIX's implementation for function keys greater than 10 is different and
  233.  * only goes as far as 36.
  234.  */
  235. static const char codes[] = {
  236. /*  0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
  237. /* 11-20 */ '<', '>', '!', '@', '#', '$', '%', '^', '&', '*',
  238. /* 21-30 */ '(', ')', '-', '_', '+', ',', ':', '?', '[', ']',
  239. /* 31-36 */ '{', '}', '|', '~', '/', '='
  240. };
  241.  
  242. #else
  243.  
  244. /*
  245.  * !!!
  246.  * Historically, the 4BSD termcap code didn't support functions keys greater
  247.  * than 9.  This was silently enforced -- asking for key k12 would return the
  248.  * value for k1.  We try and get around this by using the tables specified in
  249.  * the terminfo(TI_ENV) man page from the 3rd Edition SVID.  This assumes the
  250.  * implementors of any System V compatibility code or an extended termcap used
  251.  * those codes.
  252.  */
  253. static const char codes[] = {
  254. /*  0-10 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ';',
  255. /* 11-19 */ '1', '2', '3', '4', '5', '6', '7', '8', '9',
  256. /* 20-63 */ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  257.         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  258.         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  259.         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  260. };
  261. #endif /* _AIX */
  262.  
  263. /*
  264.  * lcmp --
  265.  *    list comparison routine for bsearch.
  266.  */
  267. static int
  268. lcmp(a, b)
  269.     const void *a, *b;
  270. {
  271.     return (strcmp(a, ((TL *)b)->terminfo));
  272. }
  273.  
  274. /*
  275.  * tigetstr --
  276.  *
  277.  * Vendors put the prototype for tigetstr into random include files, including
  278.  * <term.h>, which we can't include because it makes other systems unhappy.
  279.  * Try and work around the problem, since we only care about the return value.
  280.  *
  281.  * PUBLIC: #ifdef HAVE_CURSES_TIGETSTR
  282.  * PUBLIC: char *tigetstr();
  283.  * PUBLIC: #else
  284.  * PUBLIC: char *tigetstr __P((char *));
  285.  * PUBLIC: #endif
  286.  */
  287. char *
  288. tigetstr(name)
  289.     char *name;
  290. {
  291.     static char sbuf[256];
  292.     TL *tlp;
  293.     int n;
  294.     char *p, keyname[3];
  295.  
  296.     if ((tlp = bsearch(name,
  297.         list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) == NULL) {
  298. #ifdef _AIX
  299.         if (name[0] == 'k' &&
  300.             name[1] == 'f' && (n = atoi(name + 2)) <= 36) {
  301.             keyname[0] = 'k';
  302.             keyname[1] = codes[n];
  303.             keyname[2] = '\0';
  304. #else
  305.         if (name[0] == 'k' &&
  306.             name[1] == 'f' && (n = atoi(name + 2)) <= 63) {
  307.             keyname[0] = n <= 10 ? 'k' : 'F';
  308.             keyname[1] = codes[n];
  309.             keyname[2] = '\0';
  310. #endif
  311.             name = keyname;
  312.         }
  313.     } else
  314.         name = tlp->termcap;
  315.  
  316.     p = sbuf;
  317. #ifdef _AIX
  318.     return ((p = tgetstr(name, &p)) == NULL ? (char *)-1 : strcpy(sbuf, p));
  319. #else
  320.     return (tgetstr(name, &p) == NULL ? (char *)-1 : sbuf);
  321. #endif
  322. }
  323.  
  324. /*
  325.  * tigetnum --
  326.  *
  327.  * PUBLIC: #ifndef HAVE_CURSES_TIGETSTR
  328.  * PUBLIC: int tigetnum __P((char *));
  329.  * PUBLIC: #endif
  330.  */
  331. int
  332. tigetnum(name)
  333.     char *name;
  334. {
  335.     TL *tlp;
  336.     int val;
  337.  
  338.     if ((tlp = bsearch(name,
  339.         list, sizeof(list) / sizeof(TL), sizeof(TL), lcmp)) != NULL) {
  340.         name = tlp->termcap;
  341.     }
  342.  
  343.     return ((val = tgetnum(name)) == -1 ? -2 : val);
  344. }
  345. #endif /* !HAVE_CURSES_TIGETSTR */
  346.