-ltermcap
Chris Torek
chris at umcp-cs.UUCP
Mon Aug 4 14:33:59 AEST 1986
>In article <2773 at mit-eddie.MIT.EDU> shawn at mit-eddie.MIT.EDU
>(Shawn F. Mckay) writes:
>>One would think I could say something like:
>>
>>char buff[20];
>> tgetstr ("cl", buff);
In article <2565 at rsch.wisc.edu> dave at rsch.wisc.edu (Dave Cohrs) replies:
>Read the termcap(3) man page more carefully. ... So you want to do:
>
> char buff[20];
> char *bufptr = buff;
> (void) tgetstr("cl", &bufptr);
Closer; but it is worse than that. Termcap's design is quite messy
and error-prone. I once outlined a better design, but have never
bothered to implement it.
Termcap first requires that you copy the terminal capability string
into a buffer. It then interprets the copied string into another
buffer. Both buffers are `owned' by you but `taken over' by termcap;
the first must last through all tget* calls, and the second as long
as you wish to use the decoded strings. The following is pretty
much the minimum code required to obtain just the clear screen
entry:
#ifdef this_works_but_is_not_a_good_idea_anyway
char *getenv();
char *
get_clear_screen()
{
char tbuf[1024]; /* used only during interpretation */
static char expbuf[1024]; /* stores interpreted strings */
char *ep; /* pointer into expbuf */
char *term;
if ((term = getenv("TERM")) == NULL)
return (NULL); /* terminal type unavailable */
/* -1 => no termcap file; 0 => termcap file but $TERM not found */
if (tgetent(tbuf, term) != 1)
return (NULL); /* failed for some reason */
ep = expbuf;
return (tgetstr("cl", &ep));
}
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
/*
* Before you can use `cl', you must also set `ospeed' and `PC':
*/
extern short ospeed;
extern char PC;
/*
* ospeed should be set to the output speed of the terminal, as
* returned by gtty() / ioctl(TIOCGETP). PC should be set to
* the terminal's pad character (result from tgetstr("pc")),
* or the default, NUL ('\0'). Note that tgetstr("pc") either
* returns NULL (in which case PC should be '\0') or a pointer
* which must be dereferenced to get the pad character.
*
* For this reason, the `get_clear_screen' routine defined above
* is pretty much useless anyway. Instead, you need something
* more like this:
*/
static char tbuf[1024]; /* for intermediate results */
static char expbuf[1024]; /* for expanded (decoded) strings */
static char *expp; /* pointer into expbuf */
static int started_tc; /* true => got termcap started */
static int no_tc; /* true => termcap unavailable */
char *getenv();
#define start_tc() if (started_tc) /*void*/; else fire_up_termcap()
/*
* Set things up so that tgetent() et al. are OK
*/
static void
fire_up_termcap()
{
char *term;
struct sgttyb sg;
started_tc++; /* well, soon */
if ((term = getenv("TERM")) == NULL || tgetent(tbuf, term) != 1) {
no_tc++; /* no termcap available */
return;
}
expp = expbuf; /* init expansion pointer *?
if (ioctl(0, TIOCGETP, &sg))
ospeed = B1200; /* just a guess */
else
ospeed = sg.sg_ospeed;
}
/*
* Wrapper for tgetstr().
*/
char *
get_termcap_string(name)
char *name;
{
start_tc();
return (no_tc ? NULL : tgetstr(name, &expp));
}
/*
* Get the clear screen entry, and set up the pad character so that
* we can use it.
*/
char *
get_clear_screen()
{
char *p;
if ((p = get_termcap_string("pc")) != NULL)
PC = *p;
return (get_termcap_string("cl"));
}
/*
* This can now be printed via
*
* int outc(c) int c; { return (putchar(c)); }
* ...
* p = get_clear_screen();
* tputs(p, 1, outc);
*
*/
/*
* For good measure, some interface routines for other termcap things,
* and an `outc' routine:
*/
int
outc(c)
int c;
{
return (putchar(c));
}
/*
* Wrapper for tgetnum().
*/
int
get_termcap_number(name)
char *name;
{
start_tc();
return (no_tc ? -1 : tgetnum(name));
}
/*
* Wrapper for tgetflag().
*/
int
get_termcap_flag(name)
char *name;
{
start_tc();
return (no_tc ? 0 : tgetflag(name));
}
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris at umcp-cs ARPA: chris at mimsy.umd.edu
More information about the Comp.unix.wizards
mailing list