-
-/*
- * termsbr.c -- termcap support
+/* terminal.c -- termcap support
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
*/
#include <h/mh.h>
+#include <h/utils.h>
-#include <termios.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 <sys/ioctl.h>
-/* <sys/ioctl.h> is need anyway for ioctl()
-#ifdef GWINSZ_IN_SYS_IOCTL
-*/
-# include <sys/ioctl.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 long speedcode;
-
static int initLI = 0;
static int initCO = 0;
-static int HC = 0; /* are we on a hardcopy terminal? */
-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;
+ int errret, rc;
-#ifndef TGETENT_ACCEPTS_NULL
- char termbuf[TXTSIZ];
-#endif
+ if (termstatus)
+ return;
- struct termios tio;
- static int inited = 0;
+ rc = setupterm(NULL, fileno(stdout), &errret);
- if (inited++)
+ if (rc != 0 || errret != 1) {
+ termstatus = -1;
return;
+ }
+ termstatus = 1;
- if (!(term = getenv ("TERM")))
- return;
-
-/*
- * If possible, we let tgetent allocate its own termcap buffer
- */
-#ifdef TGETENT_ACCEPTS_NULL
- if (tgetent (NULL, term) != TGETENT_SUCCESS)
- return;
-#else
- if (tgetent (termbuf, term) != TGETENT_SUCCESS)
- return;
-#endif
-
- speedcode = cfgetospeed(&tio);
-
- HC = tgetflag ("hc");
-
- 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");
}
initCO++;
} else
#endif /* TIOCGWINSZ */
- read_termcap();
+ initialize_terminfo();
return CO;
}
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 && speedcode)
- tputs (CL, LI, outc);
+ if (ti_clear)
+ tputs (ti_clear, LI, outc);
else {
- printf ("\f");
- if (speedcode)
- printf ("\200");
+ putchar('\f');
}
fflush (stdout);
{
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;
}
/*
- * Is this a hardcopy terminal?
+ * 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
-sc_hardcopy(void)
+get_term_numcap(char *capability)
{
- read_termcap();
- return HC;
+ 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;
+}