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)
211 if (!isendwin()) endwin();
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);
338 if (!read (0, &buf, 1))
343 /* the following is unused and looks broken, but there may
344 be some input problems still lurking in curses mode, so
345 i'll leave it blocked out for now for informational
348 int scr_blockread(void)
351 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
352 wtimeout(mainwindow, S_KEEPALIVE);
356 a = wgetch(mainwindow); /* will block for food */
359 /* a = scr_getc(); */
367 * scr_putc() outputs a single character
371 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
374 if (waddch(mainwindow, c) != OK)
379 if (putc(c, stdout) == EOF)
387 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
389 return ((waddch(statuswindow, c) == OK) ? c : EOF);
391 return putc(c, stdout);
395 int sln_putc_if(int c)
397 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
399 return ((waddch(statuswindow, c) == OK) ? c : EOF);
406 * scr_color() sets the window color for mainwindow
408 int scr_color(int colornum)
410 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
412 #ifdef HAVE_WCOLOR_SET
413 wcolor_set(mainwindow, (colornum & 7), NULL);
415 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
418 wattron(mainwindow, A_BOLD);
420 wattroff(mainwindow, A_BOLD);
431 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
433 wrefresh(mainwindow);
442 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
443 if (mainwindow) /* FIXME: error status window needed */
444 wrefresh(mainwindow);
453 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
455 wrefresh(statuswindow);
461 static volatile int caught_sigwinch = 0;
464 * this is not supposed to be called from a signal handler.
466 int scr_set_windowsize()
468 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
469 if (mainwindow && caught_sigwinch) {
471 #ifdef HAVE_RESIZETERM
472 resizeterm(screenheight + 1, screenwidth);
475 wresize(mainwindow, screenheight, screenwidth);
476 wresize(statuswindow, 1, screenwidth);
478 mvwin(statuswindow, screenheight, 0);
479 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
480 room_name, secure, -1);
481 wnoutrefresh(mainwindow);
482 wnoutrefresh(statuswindow);
486 #endif /* HAVE_CURSES_H */
491 * scr_winch() handles window size changes from SIGWINCH
492 * resizes all our windows for us
494 RETSIGTYPE scr_winch(int signum)
496 /* if we receive this signal, we must be running
497 in a terminal that supports resizing. */
501 signal(SIGWINCH, scr_winch);
506 * Initialize the window(s) we will be using.
508 void windows_new(void)
510 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
514 getmaxyx(stdscr, y, x);
515 mainwindow = newwin(y - 1, x, 0, 0);
517 screenheight = y - 1;
518 immedok(mainwindow, FALSE);
519 leaveok(mainwindow, FALSE);
520 scrollok(mainwindow, TRUE);
521 statuswindow = newwin(1, x, y - 1, 0);
524 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
526 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
528 werase(statuswindow);
529 immedok(statuswindow, FALSE);
530 leaveok(statuswindow, FALSE);
531 scrollok(statuswindow, FALSE);
532 wrefresh(statuswindow);
534 #else /* HAVE_CURSES_H */
536 #endif /* HAVE_CURSES_H */
541 * Deinitialize the window(s) we were using (at exit).
543 void windows_delete(void)
545 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
550 delwin(statuswindow);
552 #else /* HAVE_CURSES_H */
554 #endif /* HAVE_CURSES_H */