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