X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/e96b045f0c9576f118c340fc533bb3cff396117d..803f25412:/sbr/terminal.c?ds=inline diff --git a/sbr/terminal.c b/sbr/terminal.c index 82051e94..5ba6dcd1 100644 --- a/sbr/terminal.c +++ b/sbr/terminal.c @@ -8,89 +8,64 @@ */ #include +#include -#include - -/* 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 -#elif defined (HAVE_NCURSES_TERMCAP_H) -# include -#endif +#include -/* is need anyway for ioctl() -#ifdef GWINSZ_IN_SYS_IOCTL -*/ -# include -/* -#endif -*/ +#include +#include +#include #ifdef WINSIZE_IN_PTEM # include # include #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 colums */ +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; - static int inited = 0; + rc = setupterm(NULL, fileno(stdout), &errret); - if (inited++) - return; - - 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) + if (rc != 0 || errret != 1) { + termstatus = -1; return; -#endif + } else { + 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"); } @@ -107,7 +82,7 @@ sc_width (void) initCO++; } else #endif /* TIOCGWINSZ */ - read_termcap(); + initialize_terminfo(); return CO; } @@ -124,26 +99,26 @@ 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"); } @@ -160,18 +135,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; +}