Initial revision
[mmh] / uip / termsbr.c
1
2 /*
3  * termsbr.c -- termcap support
4  *
5  * $Id$
6  */
7
8 #include <h/mh.h>
9
10 #ifdef HAVE_TERMIOS_H
11 # include <termios.h>
12 #else
13 # ifdef HAVE_TERMIO_H
14 #  include <termio.h>
15 # else
16 #  include <sgtty.h>
17 # endif
18 #endif
19
20 #ifdef HAVE_TERMCAP_H
21 # include <termcap.h>
22 #endif
23
24 #ifdef GWINSZ_IN_SYS_IOCTL
25 # include <sys/ioctl.h>
26 #endif
27 #ifdef WINSIZE_IN_PTEM
28 # include <sys/stream.h>
29 # include <sys/ptem.h>
30 #endif
31
32 #if BUFSIZ<2048
33 # define TXTSIZ 2048
34 #else
35 # define TXTSIZ BUFSIZ
36 #endif
37
38 /*
39  * These variables are sometimes defined in,
40  * and needed by the termcap library.
41  */
42 #ifdef HAVE_OSPEED
43 # ifdef MUST_DEFINE_OSPEED
44 extern short ospeed;
45 extern char PC;
46 # endif
47 #else
48 short ospeed;
49 char PC;
50 #endif
51
52 static long speedcode;
53
54 static int initLI = 0;
55 static int initCO = 0;
56
57 static int HC = 0;       /* are we on a hardcopy terminal?        */
58 static int LI = 40;      /* number of lines                       */
59 static int CO = 80;      /* number of colums                      */
60 static char *CL = NULL;  /* termcap string to clear screen        */
61 static char *SE = NULL;  /* termcap string to end standout mode   */
62 static char *SO = NULL;  /* termcap string to begin standout mode */
63
64 static char termcap[TXTSIZ];
65
66
67 static void
68 read_termcap(void)
69 {
70     char *bp, *cp;
71     char *term;
72
73 #ifndef TGETENT_ACCEPTS_NULL
74     char termbuf[TXTSIZ];
75 #endif
76
77 #ifdef HAVE_TERMIOS_H
78     struct termios tio;
79 #else
80 # ifdef HAVE_TERMIO_H
81     struct termio tio;
82 # else
83     struct sgttyb tio;
84 # endif
85 #endif
86
87     static int inited = 0;
88
89     if (inited++)
90         return;
91
92     if (!(term = getenv ("TERM")))
93         return;
94
95 /*
96  * If possible, we let tgetent allocate its own termcap buffer
97  */
98 #ifdef TGETENT_ACCEPTS_NULL
99     if (tgetent (NULL, term) <= 0)
100         return
101 #else
102     if (tgetent (termbuf, term) <= 0)
103         return;
104 #endif
105
106 #ifdef HAVE_TERMIOS_H
107     speedcode = cfgetospeed(&tio);
108 #else
109 # ifdef HAVE_TERMIO_H
110     speedcode = ioctl(fileno(stdout), TCGETA, &tio) != NOTOK ? tio.c_cflag & CBAUD : 0;
111 # else
112     speedcode = ioctl(fileno(stdout), TIOCGETP, (char *) &tio) != NOTOK ? tio.sg_ospeed : 0;
113 # endif
114 #endif
115
116     HC = tgetflag ("hc");
117
118     if (!initCO && (CO = tgetnum ("co")) <= 0)
119         CO = 80;
120     if (!initLI && (LI = tgetnum ("li")) <= 0)
121         LI = 24;
122
123     cp = termcap;
124     CL = tgetstr ("cl", &cp);
125     if ((bp = tgetstr ("pc", &cp)))
126         PC = *bp;
127     if (tgetnum ("sg") <= 0) {
128         SE = tgetstr ("se", &cp);
129         SO = tgetstr ("so", &cp);
130     }
131 }
132
133
134 int
135 sc_width (void)
136 {
137 #ifdef TIOCGWINSZ
138     struct winsize win;
139     int width;
140
141     if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
142             && (width = win.ws_col) > 0) {
143         CO = width;
144         initCO++;
145     } else
146 #endif /* TIOCGWINSZ */
147         read_termcap();
148
149     return CO;
150 }
151
152
153 int
154 sc_length (void)
155 {
156 #ifdef TIOCGWINSZ
157     struct winsize win;
158
159     if (ioctl (fileno (stderr), TIOCGWINSZ, &win) != NOTOK
160             && (LI = win.ws_row) > 0)
161         initLI++;
162     else
163 #endif /* TIOCGWINSZ */
164         read_termcap();
165
166     return LI;
167 }
168
169
170 static int
171 outc (int c)
172 {
173     putchar(c);
174 }
175
176
177 void
178 clear_screen (void)
179 {
180     read_termcap ();
181
182     if (CL && speedcode)
183         tputs (CL, LI, outc);
184     else {
185         printf ("\f");
186         if (speedcode)
187             printf ("\200");
188     }
189
190     fflush (stdout);
191 }
192
193
194 /*
195  * print in standout mode
196  */
197 int
198 SOprintf (char *fmt, ...)
199 {
200     va_list ap;
201
202     read_termcap ();
203     if (!(SO && SE))
204         return NOTOK;
205
206     tputs (SO, 1, outc);
207
208     va_start(ap, fmt);
209     vprintf (fmt, ap);
210     va_end(ap);
211
212     tputs (SE, 1, outc);
213
214     return OK;
215 }
216
217 /*
218  * Is this a hardcopy terminal?
219  */
220
221 int
222 sc_hardcopy(void)
223 {
224     read_termcap();
225     return HC;
226 }
227