4 * Handle full-screen curses stuff
14 #include <sys/types.h>
16 #define _vwprintw vw_printw
18 /* SYSV style curses (Solaris, etc.) */
19 #define _vwprintw vwprintw
25 #include "citadel_ipc.h"
26 #include "citadel_decls.h"
29 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
30 static SCREEN *myscreen = NULL;
31 static WINDOW *mainwindow = NULL;
32 static WINDOW *statuswindow = NULL;
38 extern int screenheight;
39 extern int screenwidth;
40 extern int rc_ansi_color;
41 extern void check_screen_dims(void);
43 void do_keepalive(void);
46 int is_curses_enabled(void) {
47 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
48 return mainwindow != NULL;
55 * status_line() is a convenience function for writing a "typical"
56 * status line to the window.
58 void status_line(const char *humannode, const char *bbs_city,
59 const char *room_name, int secure, int newmailcount)
61 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
64 sln_printf("Encrypted ");
65 waddch(statuswindow, ACS_VLINE);
66 waddch(statuswindow, ' ');
69 sln_printf("%s on ", room_name);
71 sln_printf("%s ", humannode);
72 if (newmailcount > 0) {
73 waddch(statuswindow, ACS_VLINE);
74 sln_printf(" %d new mail ", newmailcount);
78 #endif /* HAVE_CURSES_H */
83 * Display a 3270-style "wait" indicator at the bottom of the screen
85 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
86 void wait_indicator(int onoff) {
89 mvwinch(statuswindow, 0, 78);
91 waddch(statuswindow, 'X');
94 waddch(statuswindow, ' ');
96 wrefresh(statuswindow);
97 wrefresh(mainwindow); /* this puts the cursor back */
104 * Initialize the screen. If newterm() fails, myscreen will be NULL and
105 * further handlers will assume we should be in line mode.
107 void screen_new(void)
109 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
110 if (arg_screen != RC_NO && rc_screen != RC_NO)
111 myscreen = newterm(NULL, stdout, stdin);
116 intrflush(stdscr, FALSE);
117 keypad(stdscr, TRUE);
118 /* Setup all our colors */
122 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
123 init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
124 init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
125 init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
126 init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
127 init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
128 init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
129 init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
132 init_pair(8, COLOR_WHITE, COLOR_BLUE);
134 setLockHook(wait_indicator);
137 #endif /* HAVE_CURSES_H */
150 * Kill the screen completely (used at exit). It is safe to call this
151 * function more than once.
153 void screen_delete(void)
157 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
166 * Set screen/IO parameters, e.g. at start of program or return from external
171 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
177 #endif /* HAVE_CURSES_H */
183 * Reset screen/IO parameters, e.g. at exit or fork of external program.
185 int screen_reset(void)
187 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
192 #endif /* HAVE_CURSES_H */
198 * scr_printf() outputs to the main window (or screen if not in curses)
200 int scr_printf(char *fmt, ...)
206 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
208 retval = _vwprintw(mainwindow, fmt, ap);
211 retval = vprintf(fmt, ap);
218 * err_printf() outputs to error status window (or stderr if not in curses)
220 int err_printf(char *fmt, ...)
226 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
227 if (mainwindow) { /* FIXME: direct to error window */
228 retval = _vwprintw(mainwindow, fmt, ap);
229 if (fmt[strlen(fmt) - 1] == '\n')
230 wrefresh(mainwindow);
233 retval = vfprintf(stderr, fmt, ap);
240 * sln_printf() outputs to error status window (or stderr if not in curses)
242 int sln_printf(char *fmt, ...)
246 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
247 static char buf[4096];
251 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
255 retval = vsnprintf(buf, 4096, fmt, ap);
256 for (i = buf; *i; i++) {
257 if (*i == '\r' || *i == '\n')
258 wclrtoeol(statuswindow);
260 if (*i == '\r' || *i == '\n') {
261 wrefresh(statuswindow);
262 mvwinch(statuswindow, 0, 0);
267 retval = vprintf(fmt, ap);
274 * sln_printf_if() outputs to status window, no output if not in curses
276 int sln_printf_if(char *fmt, ...)
278 register int retval = 1;
279 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
280 static char buf[4096];
287 retval = vsnprintf(buf, 4096, fmt, ap);
288 for (i = buf; *i; i++) {
289 if (*i == '\r' || *i == '\n')
290 wclrtoeol(statuswindow);
292 if (*i == '\r' || *i == '\n') {
293 wrefresh(statuswindow);
294 mvwinch(statuswindow, 0, 0);
304 int scr_getc(int delay)
308 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
310 wtimeout(mainwindow, delay);
311 return wgetch(mainwindow);
320 /* the following is unused and looks broken, but there may
321 be some input problems still lurking in curses mode, so
322 i'll leave it blocked out for now for informational
325 int scr_blockread(void)
328 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
329 wtimeout(mainwindow, S_KEEPALIVE);
333 a = wgetch(mainwindow); /* will block for food */
336 /* a = scr_getc(); */
344 * scr_putc() outputs a single character
348 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
351 return ((waddch(mainwindow, c) == OK) ? c : EOF);
354 return putc(c, stdout);
360 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
362 return ((waddch(statuswindow, c) == OK) ? c : EOF);
364 return putc(c, stdout);
368 int sln_putc_if(int c)
370 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
372 return ((waddch(statuswindow, c) == OK) ? c : EOF);
379 * scr_color() sets the window color for mainwindow
381 int scr_color(int colornum)
383 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
385 #ifdef HAVE_WCOLOR_SET
386 wcolor_set(mainwindow, (colornum & 7), NULL);
388 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
391 wattron(mainwindow, A_BOLD);
393 wattroff(mainwindow, A_BOLD);
404 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
406 wrefresh(mainwindow);
415 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
416 if (mainwindow) /* FIXME: error status window needed */
417 wrefresh(mainwindow);
426 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
428 wrefresh(statuswindow);
434 static volatile int caught_sigwinch = 0;
437 * this is not supposed to be called from a signal handler.
439 int scr_set_windowsize()
441 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
442 if (mainwindow && caught_sigwinch) {
444 #ifdef HAVE_RESIZETERM
445 resizeterm(screenheight + 1, screenwidth);
448 wresize(mainwindow, screenheight, screenwidth);
449 wresize(statuswindow, 1, screenwidth);
451 mvwin(statuswindow, screenheight, 0);
452 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
453 room_name, secure, -1);
454 wnoutrefresh(mainwindow);
455 wnoutrefresh(statuswindow);
459 #endif /* HAVE_CURSES_H */
464 * scr_winch() handles window size changes from SIGWINCH
465 * resizes all our windows for us
467 RETSIGTYPE scr_winch(int signum)
469 /* if we receive this signal, we must be running
470 in a terminal that supports resizing. */
474 signal(SIGWINCH, scr_winch);
479 * Initialize the window(s) we will be using.
481 void windows_new(void)
483 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
487 getmaxyx(stdscr, y, x);
488 mainwindow = newwin(y - 1, x, 0, 0);
490 screenheight = y - 1;
491 immedok(mainwindow, FALSE);
492 leaveok(mainwindow, FALSE);
493 scrollok(mainwindow, TRUE);
494 statuswindow = newwin(1, x, y - 1, 0);
497 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
499 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
501 werase(statuswindow);
502 immedok(statuswindow, FALSE);
503 leaveok(statuswindow, FALSE);
504 scrollok(statuswindow, FALSE);
505 wrefresh(statuswindow);
507 #else /* HAVE_CURSES_H */
509 #endif /* HAVE_CURSES_H */
514 * Deinitialize the window(s) we were using (at exit).
516 void windows_delete(void)
518 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
523 delwin(statuswindow);
525 #else /* HAVE_CURSES_H */
527 #endif /* HAVE_CURSES_H */