]> diplodocus.org Git - nmh/blobdiff - sbr/terminal.c
Escape literal leading full stop in man/new.man.
[nmh] / sbr / terminal.c
index 9ab81e0d0e4c61d730d994e6266f5be705f3329c..36e247b62ecce2d698f0ad16768f32e747ff7ca1 100644 (file)
@@ -8,81 +8,63 @@
  */
 
 #include <h/mh.h>
+#include <h/utils.h>
 
-#include <termios.h>
+#include <sys/ioctl.h>
 
-/* It might be better to tie this to the termcap_curses_order in
-   configure.ac.  It would be fine to check for ncurses/termcap.h
-   first on Linux, it's a symlink to termcap.h.  */
-#ifdef HAVE_TERMCAP_H
-# include <termcap.h>
-#elif defined (HAVE_NCURSES_TERMCAP_H)
-# include <ncurses/termcap.h>
-#endif
+#include <curses.h>
+#include <term.h>
+#include <termios.h>
 
 #ifdef WINSIZE_IN_PTEM
 # include <sys/stream.h>
 # include <sys/ptem.h>
 #endif
 
-#if BUFSIZ<2048
-# define TXTSIZ        2048
-#else
-# define TXTSIZ BUFSIZ
-#endif
-
 static int initLI = 0;
 static int initCO = 0;
 
-static int LI = 40;      /* number of lines                       */
-static int CO = 80;      /* number of colums                      */
-static char *CL = NULL;  /* termcap string to clear screen        */
-static char *SE = NULL;  /* termcap string to end standout mode   */
-static char *SO = NULL;  /* termcap string to begin standout mode */
+static int LI = 40;                /* number of lines                        */
+static int CO = 80;                /* number of columns                      */
+static char *ti_clear = NULL;      /* terminfo string to clear screen        */
+static char *ti_standend = NULL;   /* terminfo string to end standout mode   */
+static char *ti_standbegin = NULL; /* terminfo string to begin standout mode */
+static int termstatus = 0;        /* terminfo initialization status         */
+static char *termcbuf = NULL;     /* tputs() output buffer                  */
+static char *termcbufp = NULL;    /* tputs() output buffer pointer          */
+static size_t termcbufsz = 0;     /* Size of termcbuf                       */
 
-static char termcap[TXTSIZ];
+static void initialize_terminfo(void);
+static int termbytes(TPUTS_PUTC_ARG);
 
+/*
+ * Initialize the terminfo library.
+ */
 
 static void
-read_termcap(void)
+initialize_terminfo(void)
 {
-    char *cp;
-    char *term;
-
-#ifndef TGETENT_ACCEPTS_NULL
-    char termbuf[TXTSIZ];
-#endif
+    int errret, rc;
 
-    static int inited = 0;
+    if (termstatus)
+       return;
 
-    if (inited++)
-       return;
-
-    if (!(term = getenv ("TERM")))
-       return;
+    rc = setupterm(NULL, fileno(stdout), &errret);
 
-/*
- * If possible, we let tgetent allocate its own termcap buffer
- */
-#ifdef TGETENT_ACCEPTS_NULL
-    if (tgetent (NULL, term) != TGETENT_SUCCESS)
+    if (rc != 0 || errret != 1) {
+       termstatus = -1;
        return;
-#else
-    if (tgetent (termbuf, term) != TGETENT_SUCCESS)
-       return;
-#endif
+    }
+    termstatus = 1;
 
-    if (!initCO && (CO = tgetnum ("co")) <= 0)
+    if (!initCO && (CO = tigetnum ("cols")) <= 0)
        CO = 80;
-    if (!initLI && (LI = tgetnum ("li")) <= 0)
+    if (!initLI && (LI = tigetnum ("lines")) <= 0)
        LI = 24;
 
-    cp = termcap;
-    CL = tgetstr ("cl", &cp);
-    if (tgetnum ("sg") <= 0) {
-       SE = tgetstr ("se", &cp);
-       SO = tgetstr ("so", &cp);
-    }
+    ti_clear = tigetstr ("clear");
+    ti_standbegin = tigetstr ("smso");
+    ti_standend = tigetstr ("rmso");
 }
 
 
@@ -99,7 +81,7 @@ sc_width (void)
        initCO++;
     } else
 #endif /* TIOCGWINSZ */
-       read_termcap();
+       initialize_terminfo();
 
     return CO;
 }
@@ -116,28 +98,28 @@ sc_length (void)
        initLI++;
     else
 #endif /* TIOCGWINSZ */
-       read_termcap();
+       initialize_terminfo();
 
     return LI;
 }
 
 
 static int
-outc (int c)
+outc (TPUTS_PUTC_ARG c)
 {
     return putchar(c);
 }
 
 
 void
-clear_screen (void)
+nmh_clear_screen (void)
 {
-    read_termcap ();
+    initialize_terminfo ();
 
-    if (CL)
-       tputs (CL, LI, outc);
+    if (ti_clear)
+       tputs (ti_clear, LI, outc);
     else {
-       printf ("\f");
+       putchar('\f');
     }
 
     fflush (stdout);
@@ -152,18 +134,118 @@ SOprintf (char *fmt, ...)
 {
     va_list ap;
 
-    read_termcap ();
-    if (!(SO && SE))
+    initialize_terminfo ();
+    if (!(ti_standbegin && ti_standend))
        return NOTOK;
 
-    tputs (SO, 1, outc);
+    tputs (ti_standbegin, 1, outc);
 
     va_start(ap, fmt);
     vprintf (fmt, ap);
     va_end(ap);
 
-    tputs (SE, 1, outc);
+    tputs (ti_standend, 1, outc);
 
     return OK;
 }
 
+/*
+ * Return the specified capability as a string that has already been
+ * processed with tputs().
+ */
+
+char *
+get_term_stringcap(char *capability)
+{
+    char *parm;
+
+    initialize_terminfo();
+
+    if (termstatus == -1)
+       return NULL;
+
+    termcbufp = termcbuf;
+
+    parm = tigetstr(capability);
+
+    if (parm == (char *) -1 || parm == NULL) {
+       return NULL;
+    }
+
+    tputs(parm, 1, termbytes);
+
+    *termcbufp = '\0';
+
+    return termcbuf;
+}
+
+/*
+ * Return a parameterized terminfo capability
+ */
+
+char *
+get_term_stringparm(char *capability, long arg1, long arg2)
+{
+    char *parm;
+
+    initialize_terminfo();
+
+    if (termstatus == -1)
+       return NULL;
+
+    termcbufp = termcbuf;
+
+    parm = tigetstr(capability);
+
+    if (parm == (char *) -1 || parm == NULL) {
+       return NULL;
+    }
+
+    parm = tparm(parm, arg1, arg2, 0, 0, 0, 0, 0, 0, 0);
+
+    tputs(parm, 1, termbytes);
+
+    *termcbufp = '\0';
+
+    return termcbuf;
+}
+
+/*
+ * Return the value of the specified numeric capability
+ */
+
+int
+get_term_numcap(char *capability)
+{
+    initialize_terminfo();
+
+    if (termstatus == -1)
+       return -1;
+
+    return tigetnum(capability);
+}
+
+/*
+ * Store a sequence of characters in our local buffer
+ */
+
+static int
+termbytes(TPUTS_PUTC_ARG c)
+{
+    size_t offset;
+
+    /*
+     * Bump up the buffer size if we've reached the end (leave room for
+     * a trailing NUL)
+     */
+
+    if ((offset = termcbufp - termcbuf) - 1 >= termcbufsz) {
+        termcbufsz += 64;
+       termcbuf = mh_xrealloc(termcbuf, termcbufsz);
+       termcbufp = termcbuf + offset;
+    }
+
+    *termcbufp++ = c;
+
+    return 0;
+}