Replace deprecated `mdwopt' flag name with new version.
[sw-tools] / src / pres_curses.c
CommitLineData
3315e8b3 1/* -*-c-*-
2 *
5636c0ce 3 * $Id: pres_curses.c,v 1.3 1999/07/16 12:49:58 mdw Exp $
3315e8b3 4 *
5 * Curses-based output presentation
6 *
7 * (c) 1999 EBI
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of sw-tools.
13 *
14 * sw-tools is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * sw-tools is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with sw-tools; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: pres_curses.c,v $
5636c0ce 32 * Revision 1.3 1999/07/16 12:49:58 mdw
33 * Improve exit status display. New interface from `doto' project.
34 *
63124806 35 * Revision 1.2 1999/06/24 15:51:16 mdw
36 * Fix signal handlers so they don't corrupt `errno'.
37 *
38 * Revision 1.1.1.1 1999/06/02 16:53:35 mdw
39 * Initial import.
3315e8b3 40 *
41 */
42
43/*----- Header files ------------------------------------------------------*/
44
45#include "config.h"
46#ifdef HAVE_CURSES
47
48#include <errno.h>
49#include <signal.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53
54#include <sys/types.h>
55#include <unistd.h>
56
57#if defined(HAVE_NCURSES_H)
58# include <ncurses.h>
59#elif defined(HAVE_NCURSES_NCURSES_H)
60# include <ncurses/ncurses.h>
61#elif defined(HAVE_CURSES_H)
62# include <curses.h>
63#else
64# error "Where's your <curses.h> header?"
65#endif
66#include <term.h>
67
68#include <mLib/alloc.h>
69#include <mLib/report.h>
70
71#include "sw.h"
72#include "sw_arch.h"
73#include "pres_curses.h"
74
75#ifndef SIGWINCH
76# undef HAVE_WRESIZE
77#endif
78
79/*----- Data structures ---------------------------------------------------*/
80
81typedef struct cwin {
82 struct cwin *next;
83 WINDOW *w;
84 int top;
85 int height;
86 WINDOW *s;
87 archent *e;
88} cwin;
89
90/*----- Static variables --------------------------------------------------*/
91
92static cwin *cwins = 0;
93static int nwins = 0;
94
95/*----- Main code ---------------------------------------------------------*/
96
97/* --- @sizes@ --- *
98 *
99 * Arguments: ---
100 *
101 * Returns: ---
102 *
103 * Use: Calculates window sizes for all the windows. The heights are
104 * determined in a way which doesn't allow rounding errors to be
105 * an issue (although there will be up to a line's height
106 * difference between two windows). No actual changing of
107 * curses structures is done.
108 */
109
110static void sizes(void)
111{
112 cwin *c;
113 int t = 0, h = LINES, w = nwins;
114
115 for (c = cwins; c; c = c->next) {
116 int a = h / w;
117 c->top = t;
118 c->height = a - 1;
119 t += a;
120 h -= a;
121 w--;
122 }
123}
124
125/* --- @sig_tstp@ --- */
126
127#ifdef SIGTSTP
128static void sig_tstp(int s)
129{
63124806 130 int e = errno;
3315e8b3 131 endwin();
63124806 132 errno = e;
3315e8b3 133 raise(SIGSTOP);
134}
135#endif
136
137/* --- @sig_cont@ --- */
138
139#ifdef SIGTSTP
140static void sig_cont(int s)
141{
63124806 142 int e = errno;
3315e8b3 143 wrefresh(curscr);
63124806 144 errno = e;
3315e8b3 145}
146#endif
147
148/* --- @sig_winch@ --- */
149
150#ifdef HAVE_WRESIZE
151
152static void sig_winch(int s)
153{
154 cwin *c;
63124806 155 int e = errno;
156
3315e8b3 157 endwin();
158 refresh();
159 sizes();
160 for (c = cwins; c; c = c->next) {
161 mvwin(c->w, c->top, 0);
162 wresize(c->w, c->height, COLS);
163 mvwin(c->s, c->top + c->height, 0);
164 wnoutrefresh(c->w);
165 wnoutrefresh(c->s);
166 }
167 doupdate();
63124806 168 errno = e;
3315e8b3 169}
170
171#endif
172
173/* --- @curses_ok@ --- */
174
175int curses_ok(void)
176{
177 if (!isatty(STDOUT_FILENO)) {
178 moan("can't use curses: stdout isn't a terminal");
179 return (0);
180 }
181 if (setupterm(0, STDOUT_FILENO, 0) == ERR) {
182 moan("can't use curses: couldn't read terminfo");
183 return (0);
184 }
185 if (!tigetstr("cup")) {
186 moan("can't use curses: terminal insufficiently winning");
187 return (0);
188 }
189 return (1);
190}
191
192/* --- @curses_init@ --- */
193
194int curses_init(archcons *a)
195{
196 cwin **cc = &cwins, *c;
197
198 /* --- Allocate my window structures --- */
199
200 nwins = 0;
201 for (; a; a = a->cdr) {
202 archent *e = a->car;
203 if (!e->r)
204 continue;
205 c = xmalloc(sizeof(cwin));
206 e->pres = c;
207 c->w = 0;
208 c->e = e;
209 nwins++;
210 *cc = c;
211 cc = &c->next;
212 }
213 *cc = 0;
214
215 /* --- Haul curses up by its naughty bits --- */
216
217 initscr();
218 keypad(stdscr, TRUE);
219 cbreak();
220 noecho();
221 nonl();
222 def_prog_mode();
223
224 /* --- Grind through everything setting up windows --- */
225
226 sizes();
227 for (c = cwins; c; c = c->next) {
228 if ((c->w = newwin(c->height, COLS, c->top, 0)) == 0 ||
229 (c->s = newwin(1, COLS, c->top + c->height, 0)) == 0)
230 goto fail_0;
231 scrollok(c->w, TRUE);
232 leaveok(c->w, TRUE);
233 leaveok(c->s, TRUE);
234 wbkgdset(c->s, A_STANDOUT);
235 werase(c->s);
5636c0ce 236 mvwprintw(c->s, 0, 0, " %s [running]\n", c->e->arch);
3315e8b3 237 wnoutrefresh(c->w);
238 wnoutrefresh(c->s);
239 }
240 doupdate();
241
242#ifdef HAVE_WRESIZE
243 signal(SIGWINCH, sig_winch);
244#endif
245#ifdef SIGTSTP
246 signal(SIGTSTP, sig_tstp);
247 signal(SIGCONT, sig_cont);
248#endif
249 return (0);
250
251fail_0:
252 c = cwins;
253 while (c) {
254 cwin *cc = c->next;
255 if (c->w)
256 delwin(c->w);
257 if (c->s)
258 delwin(c->s);
259 free(c);
260 c = cc;
261 }
262 endwin();
263 return (-1);
264}
265
266/* --- @curses_output@ --- */
267
268void curses_output(archent *e, const char *p, size_t sz)
269{
270 cwin *c = e->pres;
271 while (sz) {
272 waddch(c->w, *p);
273 p++;
274 sz--;
275 }
276 wrefresh(c->w);
277}
278
279/* --- @curses_close@ --- */
280
5636c0ce 281void curses_close(archent *e, int ok, const char *summ)
3315e8b3 282{
283 cwin *c = e->pres;
5636c0ce 284 mvwprintw(c->s, 0, 0, " %s [%s]\n", e->arch, summ);
3315e8b3 285 wrefresh(c->s);
286}
287
288/* --- @curses_done@ --- */
289
290void curses_done(archcons *a)
291{
292 if (opt_flags & optFlag_beep) {
293 beep();
294 doupdate();
295 }
296 wgetch(cwins->w);
297 cwins = 0;
298 for (; a; a = a->cdr) {
299 archent *e = a->car;
300 cwin *c = e->pres;
301 delwin(c->w);
302 delwin(c->s);
303 free(c);
304 }
305 curses_abort(0);
306}
307
308/* --- @curses_abort@ --- */
309
310void curses_abort(archcons *a)
311{
312#ifdef HAVE_WRESIZE
313 signal(SIGWINCH, SIG_DFL);
314#endif
315#ifdef SIGTSTP
316 signal(SIGTSTP, SIG_DFL);
317 signal(SIGCONT, SIG_DFL);
318#endif
319 endwin();
320}
321
322/*----- That's all, folks -------------------------------------------------*/
323
324#else
325 int pres_curses__built = 1;
326#endif