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)
175 * Set screen/IO parameters, e.g. at start of program or return from external
180 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
186 #endif /* HAVE_CURSES_H */
192 * Reset screen/IO parameters, e.g. at exit or fork of external program.
194 int screen_reset(void)
196 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
201 #endif /* HAVE_CURSES_H */
207 * scr_printf() outputs to the main window (or screen if not in curses)
209 int scr_printf(char *fmt, ...)
215 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
217 retval = _vwprintw(mainwindow, fmt, ap);
220 retval = vprintf(fmt, ap);
227 * err_printf() outputs to error status window (or stderr if not in curses)
229 int err_printf(char *fmt, ...)
235 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
236 if (mainwindow) { /* FIXME: direct to error window */
237 retval = _vwprintw(mainwindow, fmt, ap);
238 if (fmt[strlen(fmt) - 1] == '\n')
239 wrefresh(mainwindow);
242 retval = vfprintf(stderr, fmt, ap);
249 * sln_printf() outputs to error status window (or stderr if not in curses)
251 int sln_printf(char *fmt, ...)
255 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
256 static char buf[4096];
260 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
264 retval = vsnprintf(buf, 4096, fmt, ap);
265 for (i = buf; *i; i++) {
266 if (*i == '\r' || *i == '\n')
267 wclrtoeol(statuswindow);
269 if (*i == '\r' || *i == '\n') {
270 wrefresh(statuswindow);
271 mvwinch(statuswindow, 0, 0);
276 retval = vprintf(fmt, ap);
283 * sln_printf_if() outputs to status window, no output if not in curses
285 int sln_printf_if(char *fmt, ...)
287 register int retval = 1;
288 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
289 static char buf[4096];
296 retval = vsnprintf(buf, 4096, fmt, ap);
297 for (i = buf; *i; i++) {
298 if (*i == '\r' || *i == '\n')
299 wclrtoeol(statuswindow);
301 if (*i == '\r' || *i == '\n') {
302 wrefresh(statuswindow);
303 mvwinch(statuswindow, 0, 0);
313 int scr_getc(int delay)
317 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
319 wtimeout(mainwindow, delay);
320 return wgetch(mainwindow);
329 /* the following is unused and looks broken, but there may
330 be some input problems still lurking in curses mode, so
331 i'll leave it blocked out for now for informational
334 int scr_blockread(void)
337 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
338 wtimeout(mainwindow, S_KEEPALIVE);
342 a = wgetch(mainwindow); /* will block for food */
345 /* a = scr_getc(); */
353 * scr_putc() outputs a single character
357 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
360 return ((waddch(mainwindow, c) == OK) ? c : EOF);
363 return putc(c, stdout);
369 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
371 return ((waddch(statuswindow, c) == OK) ? c : EOF);
373 return putc(c, stdout);
377 int sln_putc_if(int c)
379 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
381 return ((waddch(statuswindow, c) == OK) ? c : EOF);
388 * scr_color() sets the window color for mainwindow
390 int scr_color(int colornum)
392 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
394 #ifdef HAVE_WCOLOR_SET
395 wcolor_set(mainwindow, (colornum & 7), NULL);
397 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
400 wattron(mainwindow, A_BOLD);
402 wattroff(mainwindow, A_BOLD);
413 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
415 wrefresh(mainwindow);
424 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
425 if (mainwindow) /* FIXME: error status window needed */
426 wrefresh(mainwindow);
435 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
437 wrefresh(statuswindow);
443 static volatile int caught_sigwinch = 0;
446 * this is not supposed to be called from a signal handler.
448 int scr_set_windowsize()
450 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
451 if (mainwindow && caught_sigwinch) {
453 #ifdef HAVE_RESIZETERM
454 resizeterm(screenheight + 1, screenwidth);
457 wresize(mainwindow, screenheight, screenwidth);
458 wresize(statuswindow, 1, screenwidth);
460 mvwin(statuswindow, screenheight, 0);
461 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
462 room_name, secure, -1);
463 wnoutrefresh(mainwindow);
464 wnoutrefresh(statuswindow);
468 #endif /* HAVE_CURSES_H */
473 * scr_winch() handles window size changes from SIGWINCH
474 * resizes all our windows for us
476 RETSIGTYPE scr_winch(int signum)
478 /* if we receive this signal, we must be running
479 in a terminal that supports resizing. */
483 signal(SIGWINCH, scr_winch);
488 * Initialize the window(s) we will be using.
490 void windows_new(void)
492 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
496 getmaxyx(stdscr, y, x);
497 mainwindow = newwin(y - 1, x, 0, 0);
499 screenheight = y - 1;
500 immedok(mainwindow, FALSE);
501 leaveok(mainwindow, FALSE);
502 scrollok(mainwindow, TRUE);
503 statuswindow = newwin(1, x, y - 1, 0);
506 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
508 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
510 werase(statuswindow);
511 immedok(statuswindow, FALSE);
512 leaveok(statuswindow, FALSE);
513 scrollok(statuswindow, FALSE);
514 wrefresh(statuswindow);
516 #else /* HAVE_CURSES_H */
518 #endif /* HAVE_CURSES_H */
523 * Deinitialize the window(s) we were using (at exit).
525 void windows_delete(void)
527 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
532 delwin(statuswindow);
534 #else /* HAVE_CURSES_H */
536 #endif /* HAVE_CURSES_H */