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 return ((waddch(mainwindow, c) == OK) ? c : EOF);
377 return putc(c, stdout);
383 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
385 return ((waddch(statuswindow, c) == OK) ? c : EOF);
387 return putc(c, stdout);
391 int sln_putc_if(int c)
393 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
395 return ((waddch(statuswindow, c) == OK) ? c : EOF);
402 * scr_color() sets the window color for mainwindow
404 int scr_color(int colornum)
406 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
408 #ifdef HAVE_WCOLOR_SET
409 wcolor_set(mainwindow, (colornum & 7), NULL);
411 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
414 wattron(mainwindow, A_BOLD);
416 wattroff(mainwindow, A_BOLD);
427 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
429 wrefresh(mainwindow);
438 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
439 if (mainwindow) /* FIXME: error status window needed */
440 wrefresh(mainwindow);
449 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
451 wrefresh(statuswindow);
457 static volatile int caught_sigwinch = 0;
460 * this is not supposed to be called from a signal handler.
462 int scr_set_windowsize()
464 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
465 if (mainwindow && caught_sigwinch) {
467 #ifdef HAVE_RESIZETERM
468 resizeterm(screenheight + 1, screenwidth);
471 wresize(mainwindow, screenheight, screenwidth);
472 wresize(statuswindow, 1, screenwidth);
474 mvwin(statuswindow, screenheight, 0);
475 status_line(serv_info.serv_humannode, serv_info.serv_bbs_city,
476 room_name, secure, -1);
477 wnoutrefresh(mainwindow);
478 wnoutrefresh(statuswindow);
482 #endif /* HAVE_CURSES_H */
487 * scr_winch() handles window size changes from SIGWINCH
488 * resizes all our windows for us
490 RETSIGTYPE scr_winch(int signum)
492 /* if we receive this signal, we must be running
493 in a terminal that supports resizing. */
497 signal(SIGWINCH, scr_winch);
502 * Initialize the window(s) we will be using.
504 void windows_new(void)
506 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
510 getmaxyx(stdscr, y, x);
511 mainwindow = newwin(y - 1, x, 0, 0);
513 screenheight = y - 1;
514 immedok(mainwindow, FALSE);
515 leaveok(mainwindow, FALSE);
516 scrollok(mainwindow, TRUE);
517 statuswindow = newwin(1, x, y - 1, 0);
520 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
522 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
524 werase(statuswindow);
525 immedok(statuswindow, FALSE);
526 leaveok(statuswindow, FALSE);
527 scrollok(statuswindow, FALSE);
528 wrefresh(statuswindow);
530 #else /* HAVE_CURSES_H */
532 #endif /* HAVE_CURSES_H */
537 * Deinitialize the window(s) we were using (at exit).
539 void windows_delete(void)
541 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
546 delwin(statuswindow);
548 #else /* HAVE_CURSES_H */
550 #endif /* HAVE_CURSES_H */