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) {
88 if (!isendwin() && statuswindow) {
90 mvwinch(statuswindow, 0, screenwidth - 2);
94 waddch(statuswindow, ' ');
97 waddch(statuswindow, 'X');
99 case 2: /* Receiving */
100 waddch(statuswindow, '<');
102 case 3: /* Sending */
103 waddch(statuswindow, '>');
106 waddch(statuswindow, '\r');
107 wrefresh(statuswindow);
108 wrefresh(mainwindow); /* this puts the cursor back */
115 * Initialize the screen. If newterm() fails, myscreen will be NULL and
116 * further handlers will assume we should be in line mode.
118 void screen_new(void)
120 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
121 if (arg_screen != RC_NO && rc_screen != RC_NO)
122 myscreen = newterm(NULL, stdout, stdin);
127 intrflush(stdscr, FALSE);
128 keypad(stdscr, TRUE);
129 /* Setup all our colors */
133 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
134 init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
135 init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
136 init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
137 init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
138 init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
139 init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
140 init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
143 init_pair(8, COLOR_WHITE, COLOR_BLUE);
145 #endif /* HAVE_CURSES_H */
158 * Kill the screen completely (used at exit). It is safe to call this
159 * function more than once.
161 void screen_delete(void)
165 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
176 void ctdl_beep(void) {
177 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
188 * Set screen/IO parameters, e.g. at start of program or return from external
193 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
199 #endif /* HAVE_CURSES_H */
205 * Reset screen/IO parameters, e.g. at exit or fork of external program.
207 int screen_reset(void)
209 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
214 #endif /* HAVE_CURSES_H */
220 * scr_printf() outputs to the main window (or screen if not in curses)
222 int scr_printf(char *fmt, ...)
228 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
230 retval = _vwprintw(mainwindow, fmt, ap);
233 retval = vprintf(fmt, ap);
240 * err_printf() outputs to error status window (or stderr if not in curses)
242 int err_printf(char *fmt, ...)
248 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
249 if (mainwindow) { /* FIXME: direct to error window */
250 retval = _vwprintw(mainwindow, fmt, ap);
251 if (fmt[strlen(fmt) - 1] == '\n')
252 wrefresh(mainwindow);
255 retval = vfprintf(stderr, fmt, ap);
262 * sln_printf() outputs to error status window (or stderr if not in curses)
264 int sln_printf(char *fmt, ...)
268 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
269 static char buf[4096];
273 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
277 retval = vsnprintf(buf, 4096, fmt, ap);
278 for (i = buf; *i; i++) {
279 if (*i == '\r' || *i == '\n')
280 wclrtoeol(statuswindow);
282 if (*i == '\r' || *i == '\n') {
283 wrefresh(statuswindow);
284 mvwinch(statuswindow, 0, 0);
289 retval = vprintf(fmt, ap);
296 * sln_printf_if() outputs to status window, no output if not in curses
298 int sln_printf_if(char *fmt, ...)
300 register int retval = 1;
301 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
302 static char buf[4096];
309 retval = vsnprintf(buf, 4096, fmt, ap);
310 for (i = buf; *i; i++) {
311 if (*i == '\r' || *i == '\n')
312 wclrtoeol(statuswindow);
314 if (*i == '\r' || *i == '\n') {
315 wrefresh(statuswindow);
316 mvwinch(statuswindow, 0, 0);
326 int scr_getc(int delay)
330 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
332 wtimeout(mainwindow, delay);
333 return wgetch(mainwindow);
342 /* the following is unused and looks broken, but there may
343 be some input problems still lurking in curses mode, so
344 i'll leave it blocked out for now for informational
347 int scr_blockread(void)
350 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
351 wtimeout(mainwindow, S_KEEPALIVE);
355 a = wgetch(mainwindow); /* will block for food */
358 /* a = scr_getc(); */
366 * scr_putc() outputs a single character
370 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
373 return ((waddch(mainwindow, c) == OK) ? c : EOF);
376 return putc(c, stdout);
382 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
384 return ((waddch(statuswindow, c) == OK) ? c : EOF);
386 return putc(c, stdout);
390 int sln_putc_if(int c)
392 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
394 return ((waddch(statuswindow, c) == OK) ? c : EOF);
401 * scr_color() sets the window color for mainwindow
403 int scr_color(int colornum)
405 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
407 #ifdef HAVE_WCOLOR_SET
408 wcolor_set(mainwindow, (colornum & 7), NULL);
410 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
413 wattron(mainwindow, A_BOLD);
415 wattroff(mainwindow, A_BOLD);
426 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
428 wrefresh(mainwindow);
437 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
438 if (mainwindow) /* FIXME: error status window needed */
439 wrefresh(mainwindow);
448 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
450 wrefresh(statuswindow);
456 static volatile int caught_sigwinch = 0;
459 * this is not supposed to be called from a signal handler.
461 int scr_set_windowsize()
463 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
464 if (mainwindow && caught_sigwinch) {
466 #ifdef HAVE_RESIZETERM
467 resizeterm(screenheight + 1, screenwidth);
470 wresize(mainwindow, screenheight, screenwidth);
471 wresize(statuswindow, 1, screenwidth);
473 mvwin(statuswindow, screenheight, 0);
474 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
475 room_name, secure, -1);
476 wnoutrefresh(mainwindow);
477 wnoutrefresh(statuswindow);
481 #endif /* HAVE_CURSES_H */
486 * scr_winch() handles window size changes from SIGWINCH
487 * resizes all our windows for us
489 RETSIGTYPE scr_winch(int signum)
491 /* if we receive this signal, we must be running
492 in a terminal that supports resizing. */
496 signal(SIGWINCH, scr_winch);
501 * Initialize the window(s) we will be using.
503 void windows_new(void)
505 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
509 getmaxyx(stdscr, y, x);
510 mainwindow = newwin(y - 1, x, 0, 0);
512 screenheight = y - 1;
513 immedok(mainwindow, FALSE);
514 leaveok(mainwindow, FALSE);
515 scrollok(mainwindow, TRUE);
516 statuswindow = newwin(1, x, y - 1, 0);
519 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
521 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
523 werase(statuswindow);
524 immedok(statuswindow, FALSE);
525 leaveok(statuswindow, FALSE);
526 scrollok(statuswindow, FALSE);
527 wrefresh(statuswindow);
529 #else /* HAVE_CURSES_H */
531 #endif /* HAVE_CURSES_H */
536 * Deinitialize the window(s) we were using (at exit).
538 void windows_delete(void)
540 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
545 delwin(statuswindow);
547 #else /* HAVE_CURSES_H */
549 #endif /* HAVE_CURSES_H */