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 state) {
89 mvwinch(statuswindow, 0, screenwidth - 2);
93 waddch(statuswindow, ' ');
96 waddch(statuswindow, 'X');
98 case 2: /* Receiving */
99 waddch(statuswindow, '<');
101 case 3: /* Sending */
102 waddch(statuswindow, '>');
105 waddch(statuswindow, '\r');
106 wrefresh(statuswindow);
107 wrefresh(mainwindow); /* this puts the cursor back */
114 * Initialize the screen. If newterm() fails, myscreen will be NULL and
115 * further handlers will assume we should be in line mode.
117 void screen_new(void)
119 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
120 if (arg_screen != RC_NO && rc_screen != RC_NO)
121 myscreen = newterm(NULL, stdout, stdin);
126 intrflush(stdscr, FALSE);
127 keypad(stdscr, TRUE);
128 /* Setup all our colors */
132 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
133 init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
134 init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
135 init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
136 init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
137 init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
138 init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
139 init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
142 init_pair(8, COLOR_WHITE, COLOR_BLUE);
144 #endif /* HAVE_CURSES_H */
157 * Kill the screen completely (used at exit). It is safe to call this
158 * function more than once.
160 void screen_delete(void)
164 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
173 * Set screen/IO parameters, e.g. at start of program or return from external
178 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
184 #endif /* HAVE_CURSES_H */
190 * Reset screen/IO parameters, e.g. at exit or fork of external program.
192 int screen_reset(void)
194 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
199 #endif /* HAVE_CURSES_H */
205 * scr_printf() outputs to the main window (or screen if not in curses)
207 int scr_printf(char *fmt, ...)
213 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
215 retval = _vwprintw(mainwindow, fmt, ap);
218 retval = vprintf(fmt, ap);
225 * err_printf() outputs to error status window (or stderr if not in curses)
227 int err_printf(char *fmt, ...)
233 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
234 if (mainwindow) { /* FIXME: direct to error window */
235 retval = _vwprintw(mainwindow, fmt, ap);
236 if (fmt[strlen(fmt) - 1] == '\n')
237 wrefresh(mainwindow);
240 retval = vfprintf(stderr, fmt, ap);
247 * sln_printf() outputs to error status window (or stderr if not in curses)
249 int sln_printf(char *fmt, ...)
253 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
254 static char buf[4096];
258 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
262 retval = vsnprintf(buf, 4096, fmt, ap);
263 for (i = buf; *i; i++) {
264 if (*i == '\r' || *i == '\n')
265 wclrtoeol(statuswindow);
267 if (*i == '\r' || *i == '\n') {
268 wrefresh(statuswindow);
269 mvwinch(statuswindow, 0, 0);
274 retval = vprintf(fmt, ap);
281 * sln_printf_if() outputs to status window, no output if not in curses
283 int sln_printf_if(char *fmt, ...)
285 register int retval = 1;
286 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
287 static char buf[4096];
294 retval = vsnprintf(buf, 4096, fmt, ap);
295 for (i = buf; *i; i++) {
296 if (*i == '\r' || *i == '\n')
297 wclrtoeol(statuswindow);
299 if (*i == '\r' || *i == '\n') {
300 wrefresh(statuswindow);
301 mvwinch(statuswindow, 0, 0);
311 int scr_getc(int delay)
315 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
317 wtimeout(mainwindow, delay);
318 return wgetch(mainwindow);
327 /* the following is unused and looks broken, but there may
328 be some input problems still lurking in curses mode, so
329 i'll leave it blocked out for now for informational
332 int scr_blockread(void)
335 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
336 wtimeout(mainwindow, S_KEEPALIVE);
340 a = wgetch(mainwindow); /* will block for food */
343 /* a = scr_getc(); */
351 * scr_putc() outputs a single character
355 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
358 return ((waddch(mainwindow, c) == OK) ? c : EOF);
361 return putc(c, stdout);
367 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
369 return ((waddch(statuswindow, c) == OK) ? c : EOF);
371 return putc(c, stdout);
375 int sln_putc_if(int c)
377 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
379 return ((waddch(statuswindow, c) == OK) ? c : EOF);
386 * scr_color() sets the window color for mainwindow
388 int scr_color(int colornum)
390 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
392 #ifdef HAVE_WCOLOR_SET
393 wcolor_set(mainwindow, (colornum & 7), NULL);
395 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
398 wattron(mainwindow, A_BOLD);
400 wattroff(mainwindow, A_BOLD);
411 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
413 wrefresh(mainwindow);
422 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
423 if (mainwindow) /* FIXME: error status window needed */
424 wrefresh(mainwindow);
433 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
435 wrefresh(statuswindow);
441 static volatile int caught_sigwinch = 0;
444 * this is not supposed to be called from a signal handler.
446 int scr_set_windowsize()
448 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
449 if (mainwindow && caught_sigwinch) {
451 #ifdef HAVE_RESIZETERM
452 resizeterm(screenheight + 1, screenwidth);
455 wresize(mainwindow, screenheight, screenwidth);
456 wresize(statuswindow, 1, screenwidth);
458 mvwin(statuswindow, screenheight, 0);
459 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
460 room_name, secure, -1);
461 wnoutrefresh(mainwindow);
462 wnoutrefresh(statuswindow);
466 #endif /* HAVE_CURSES_H */
471 * scr_winch() handles window size changes from SIGWINCH
472 * resizes all our windows for us
474 RETSIGTYPE scr_winch(int signum)
476 /* if we receive this signal, we must be running
477 in a terminal that supports resizing. */
481 signal(SIGWINCH, scr_winch);
486 * Initialize the window(s) we will be using.
488 void windows_new(void)
490 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
494 getmaxyx(stdscr, y, x);
495 mainwindow = newwin(y - 1, x, 0, 0);
497 screenheight = y - 1;
498 immedok(mainwindow, FALSE);
499 leaveok(mainwindow, FALSE);
500 scrollok(mainwindow, TRUE);
501 statuswindow = newwin(1, x, y - 1, 0);
504 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
506 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
508 werase(statuswindow);
509 immedok(statuswindow, FALSE);
510 leaveok(statuswindow, FALSE);
511 scrollok(statuswindow, FALSE);
512 wrefresh(statuswindow);
514 #else /* HAVE_CURSES_H */
516 #endif /* HAVE_CURSES_H */
521 * Deinitialize the window(s) we were using (at exit).
523 void windows_delete(void)
525 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
530 delwin(statuswindow);
532 #else /* HAVE_CURSES_H */
534 #endif /* HAVE_CURSES_H */