]> code.citadel.org Git - citadel.git/blob - citadel/screen.c
* Revised status_line() display, it's much more compact now
[citadel.git] / citadel / screen.c
1 /* $Id$ */
2
3 /*
4  * Handle full-screen curses stuff
5  */
6
7 #include "sysdep.h"
8 #ifdef HAVE_CURSES_H
9 #include <curses.h>
10 #endif
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdarg.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #ifdef VW_PRINTW_IN_CURSES
17 #define _vwprintw vw_printw
18 #else
19 /* Ancient curses implementations, this needs testing. Anybody got XENIX? */
20 #define _vwprintw vwprintw
21 #endif
22 #ifndef HAVE_SNPRINTF
23 #include "snprintf.h"
24 #endif
25 #include "citadel.h"
26 #include "commands.h"
27 #include "screen.h"
28
29 #ifdef HAVE_CURSES_H
30 static SCREEN *myscreen = NULL;
31 static WINDOW *mainwindow = NULL;
32 static WINDOW *statuswindow = NULL;
33
34 char rc_screen;
35 char arg_screen;
36
37 extern int screenheight;
38 extern int screenwidth;
39 extern int rc_ansi_color;
40 extern void check_screen_dims(void);
41 #endif
42
43
44 /*
45  * status_line() is a convenience function for writing a "typical"
46  * status line to the window.
47  */
48 void status_line(const char *humannode, const char *bbs_city,
49                  const char *room_name, int secure, int newmailcount)
50 {
51 #ifdef HAVE_CURSES_H
52         if (statuswindow) {
53                 if (secure) {
54                         sln_printf("Encrypted ");
55                         waddch(statuswindow, ACS_VLINE);
56                         waddch(statuswindow, ' ');
57                 }
58                 if (room_name)
59                         sln_printf("%s on ", room_name);
60                 if (humannode)
61                         sln_printf("%s ", humannode);
62                 if (newmailcount > -1) {
63                         waddch(statuswindow, ACS_VLINE);
64                         sln_printf(" Mail: %d new ", newmailcount);
65                 }
66                 sln_printf("\n");
67         }
68 #endif /* HAVE_CURSES_H */
69 }
70
71
72 /*
73  * Initialize the screen.  If newterm() fails, myscreen will be NULL and
74  * further handlers will assume we should be in line mode.
75  */
76 void screen_new(void)
77 {
78 #ifdef HAVE_CURSES_H
79         if (arg_screen != RC_NO && rc_screen != RC_NO)
80                 myscreen = newterm(NULL, stdout, stdin);
81         if (myscreen) {
82                 cbreak();
83                 noecho();
84                 nonl();
85                 intrflush(stdscr, FALSE);
86                 keypad(stdscr, TRUE);
87                 /* Setup all our colors */
88                 start_color();
89                 if (rc_ansi_color)
90                         enable_color = 1;
91                 init_pair(1+DIM_BLACK, COLOR_BLACK, COLOR_BLACK);
92                 init_pair(1+DIM_RED, COLOR_RED, COLOR_BLACK);
93                 init_pair(1+DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
94                 init_pair(1+DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
95                 init_pair(1+DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
96                 init_pair(1+DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
97                 init_pair(1+DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
98                 init_pair(1+DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
99                 init_pair(17, COLOR_WHITE, COLOR_BLUE);
100         } else
101 #endif /* HAVE_CURSES_H */
102         {
103                 send_ansi_detect();
104                 look_for_ansi();
105                 cls(0);
106                 color(1+DIM_WHITE);
107         }
108         screen_set();
109         windows_new();
110 }
111
112
113 /*
114  * Kill the screen completely (used at exit).  It is safe to call this
115  * function more than once.
116  */
117 void screen_delete(void)
118 {
119         windows_delete();
120         screen_reset();
121 #ifdef HAVE_CURSES_H
122         if (myscreen)
123                 delscreen(myscreen);
124         myscreen = NULL;
125 #endif
126 }
127
128
129 /*
130  * Set screen/IO parameters, e.g. at start of program or return from external
131  * program run.
132  */
133 int screen_set(void)
134 {
135 #ifdef HAVE_CURSES_H
136         if (myscreen) {
137                 set_term(myscreen);
138                 wrefresh(curscr);
139                 return 1;
140         }
141 #endif /* HAVE_CURSES_H */
142         return 0;
143 }
144
145
146 /*
147  * Reset screen/IO parameters, e.g. at exit or fork of external program.
148  */
149 int screen_reset(void)
150 {
151 #ifdef HAVE_CURSES_H
152         if (myscreen) {
153                 endwin();
154                 return 1;
155         }
156 #endif /* HAVE_CURSES_H */
157         return 0;
158 }
159
160
161 /*
162  * scr_printf() outputs to the main window (or screen if not in curses)
163  */
164 int scr_printf(char *fmt, ...)
165 {
166         va_list ap;
167         register int retval;
168
169         va_start(ap, fmt);
170 #ifdef HAVE_CURSES_H
171         if (mainwindow) {
172                 retval = _vwprintw(mainwindow, fmt, ap);
173         } else
174 #endif
175                 retval = vprintf(fmt, ap);
176         va_end(ap);
177         return retval;
178 }
179
180
181 /*
182  * err_printf() outputs to error status window (or stderr if not in curses)
183  */
184 int err_printf(char *fmt, ...)
185 {
186         va_list ap;
187         register int retval;
188
189         va_start(ap, fmt);
190 #ifdef HAVE_CURSES_H
191         if (mainwindow) {               /* FIXME: direct to error window */
192                 retval = _vwprintw(mainwindow, fmt, ap);
193                 if (fmt[strlen(fmt) - 1] == '\n')
194                         wrefresh(mainwindow);
195         } else
196 #endif
197                 retval = vfprintf(stderr, fmt, ap);
198         va_end(ap);
199         return retval;
200 }
201
202
203 /*
204  * sln_printf() outputs to error status window (or stderr if not in curses)
205  */
206 int sln_printf(char *fmt, ...)
207 {
208         va_list ap;
209         register int retval;
210 #ifdef HAVE_CURSES_H
211         static char buf[4096];
212 #endif
213
214         va_start(ap, fmt);
215 #ifdef HAVE_CURSES_H
216         if (statuswindow) {
217                 register char *i;
218                 
219                 retval = vsnprintf(buf, 4096, fmt, ap);
220                 for (i = buf; *i; i++) {
221                         if (*i == '\r' || *i == '\n')
222                                 wclrtoeol(statuswindow);
223                         sln_putc(*i);
224                         if (*i == '\r' || *i == '\n') {
225                                 wrefresh(statuswindow);
226                                 mvwinch(statuswindow, 0, 0);
227                         }
228                 }
229         } else
230 #endif
231                 retval = vprintf(fmt, ap);
232         va_end(ap);
233         return retval;
234 }
235
236
237 /*
238  * sln_printf_if() outputs to status window, no output if not in curses
239  */
240 int sln_printf_if(char *fmt, ...)
241 {
242         register int retval = 1;
243 #ifdef HAVE_CURSES_H
244         static char buf[4096];
245         va_list ap;
246
247         va_start(ap, fmt);
248         if (statuswindow) {
249                 register char *i;
250                 
251                 retval = vsnprintf(buf, 4096, fmt, ap);
252                 for (i = buf; *i; i++) {
253                         if (*i == '\r' || *i == '\n')
254                                 wclrtoeol(statuswindow);
255                         sln_putc(*i);
256                         if (*i == '\r' || *i == '\n') {
257                                 wrefresh(statuswindow);
258                                 mvwinch(statuswindow, 0, 0);
259                         }
260                 }
261         }
262         va_end(ap);
263 #endif
264         return retval;
265 }
266
267
268 int scr_getc(void)
269 {
270 #ifdef HAVE_CURSES_H
271         if (mainwindow)
272                 return wgetch(mainwindow);
273 #endif
274         return getchar();
275 }
276
277
278 /*
279  * scr_putc() outputs a single character
280  */
281 int scr_putc(int c)
282 {
283 #ifdef HAVE_CURSES_H
284         if (mainwindow)
285                 return ((waddch(mainwindow, c) == OK) ? c : EOF);
286 #endif
287         return putc(c, stdout);
288 }
289
290
291 int sln_putc(int c)
292 {
293 #ifdef HAVE_CURSES_H
294         if (statuswindow)
295                 return ((waddch(statuswindow, c) == OK) ? c : EOF);
296 #endif
297         return putc(c, stdout);
298 }
299
300
301 int sln_putc_if(int c)
302 {
303 #ifdef HAVE_CURSES_H
304         if (statuswindow)
305                 return ((waddch(statuswindow, c) == OK) ? c : EOF);
306 #endif
307         return 1;
308 }
309
310
311 /*
312  * scr_color() sets the window color for mainwindow
313  */
314 int scr_color(int colornum)
315 {
316 #ifdef HAVE_CURSES_H
317         if (mainwindow) {
318                 wcolor_set(mainwindow, 1 + (colornum & 7), NULL);
319                 if (colornum & 8) {
320                         wattron(mainwindow, A_BOLD);
321                 } else {
322                         wattroff(mainwindow, A_BOLD);
323                 }
324                 return 1;
325         }
326 #endif
327         return 0;
328 }
329
330
331 void scr_flush(void)
332 {
333 #ifdef HAVE_CURSES_H
334         if (mainwindow)
335                 wrefresh(mainwindow);
336         else
337 #endif
338                 fflush(stdout);
339 }
340
341
342 void err_flush(void)
343 {
344 #ifdef HAVE_CURSES_H
345         if (mainwindow)         /* FIXME: error status window needed */
346                 wrefresh(mainwindow);
347         else
348 #endif
349                 fflush(stderr);
350 }
351
352
353 void sln_flush(void)
354 {
355 #ifdef HAVE_CURSES_H
356         if (statuswindow)
357                 wrefresh(statuswindow);
358         else
359 #endif
360                 fflush(stdout);
361 }
362
363
364 int scr_set_windowsize(void)
365 {
366 #ifdef HAVE_CURSES_H
367         int y, x;
368
369         if (mainwindow) {
370                 getmaxyx(mainwindow, y, x);
371                 screenheight = y;
372                 screenwidth = x;
373                 return 1;
374         }
375 #endif /* HAVE_CURSES_H */
376         return 0;
377 }
378
379
380 /*
381  * scr_winch() handles window size changes from SIGWINCH
382  * resizes all our windows for us
383  */
384 RETSIGTYPE scr_winch(void)
385 {
386 #ifdef HAVE_CURSES_H
387         /* FIXME: not implemented */
388 #endif
389         check_screen_dims();
390 }
391
392
393 /*
394  * Initialize the window(s) we will be using.
395  */
396 void windows_new(void)
397 {
398 #ifdef HAVE_CURSES_H
399         register int x, y;
400
401         if (myscreen) {
402                 getmaxyx(stdscr, y, x);
403                 mainwindow = newwin(y - 1, x, 0, 0);
404                 screenwidth = x;
405                 screenheight = y - 1;
406                 immedok(mainwindow, FALSE);
407                 leaveok(mainwindow, FALSE);
408                 scrollok(mainwindow, TRUE);
409                 statuswindow = newwin(1, x, y - 1, 0);
410                 wbkgdset(statuswindow, COLOR_PAIR(17));
411                 werase(statuswindow);
412                 immedok(statuswindow, FALSE);
413                 leaveok(statuswindow, FALSE);
414                 scrollok(statuswindow, FALSE);
415                 wrefresh(statuswindow);
416         }
417 #else /* HAVE_CURSES_H */
418
419 #endif /* HAVE_CURSES_H */
420 }
421
422
423 /*
424  * Deinitialize the window(s) we were using (at exit).
425  */
426 void windows_delete(void)
427 {
428 #ifdef HAVE_CURSES_H
429         if (mainwindow)
430                 delwin(mainwindow);
431         mainwindow = NULL;
432         if (statuswindow)
433                 delwin(statuswindow);
434         statuswindow = NULL;
435 #else /* HAVE_CURSES_H */
436
437 #endif /* HAVE_CURSES_H */
438 }