4 * Handle full-screen curses stuff
13 #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"
30 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
31 static SCREEN *myscreen = NULL;
32 static WINDOW *mainwindow = NULL;
33 static WINDOW *statuswindow = NULL;
39 extern int screenheight;
40 extern int screenwidth;
41 extern int rc_ansi_color;
42 extern void check_screen_dims(void);
44 void do_keepalive(void);
47 int is_curses_enabled(void) {
48 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
49 return mainwindow != NULL;
56 * status_line() is a convenience function for writing a "typical"
57 * status line to the window.
59 void status_line(const char *humannode, const char *site_location,
60 const char *room_name, int secure, int newmailcount)
62 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
65 sln_printf("Encrypted ");
66 waddch(statuswindow, ACS_VLINE);
67 waddch(statuswindow, ' ');
70 sln_printf("%s on ", room_name);
72 sln_printf("%s ", humannode);
73 if (newmailcount > 0) {
74 waddch(statuswindow, ACS_VLINE);
75 sln_printf(" %d new mail ", newmailcount);
79 #endif /* HAVE_CURSES_H */
84 * Display a 3270-style "wait" indicator at the bottom of the screen
86 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
87 void wait_indicator(int state) {
89 if (!isendwin() && statuswindow) {
91 mvwinch(statuswindow, 0, screenwidth - 2);
95 waddch(statuswindow, ' ');
98 waddch(statuswindow, 'X');
100 case 2: /* Receiving */
101 waddch(statuswindow, '<');
103 case 3: /* Sending */
104 waddch(statuswindow, '>');
107 waddch(statuswindow, '\r');
108 wrefresh(statuswindow);
109 wrefresh(mainwindow); /* this puts the cursor back */
116 * Initialize the screen. If newterm() fails, myscreen will be NULL and
117 * further handlers will assume we should be in line mode.
119 void screen_new(void)
121 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
122 if (arg_screen != RC_NO && rc_screen != RC_NO)
123 myscreen = newterm(NULL, stdout, stdin);
128 intrflush(stdscr, FALSE);
129 keypad(stdscr, TRUE);
130 /* Setup all our colors */
134 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
135 init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
136 init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
137 init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
138 init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
139 init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
140 init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
141 init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
144 init_pair(8, COLOR_WHITE, COLOR_BLUE);
146 #endif /* HAVE_CURSES_H */
159 * Kill the screen completely (used at exit). It is safe to call this
160 * function more than once.
162 void screen_delete(void)
166 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
177 void ctdl_beep(void) {
178 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
189 * Set screen/IO parameters, e.g. at start of program or return from external
194 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
200 #endif /* HAVE_CURSES_H */
206 * Reset screen/IO parameters, e.g. at exit or fork of external program.
208 int screen_reset(void)
210 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
212 if (!isendwin()) endwin();
215 #endif /* HAVE_CURSES_H */
221 * scr_printf() outputs to the main window (or screen if not in curses)
223 int scr_printf(char *fmt, ...)
229 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
231 retval = _vwprintw(mainwindow, fmt, ap);
234 retval = vprintf(fmt, ap);
241 * err_printf() outputs to error status window (or stderr if not in curses)
243 int err_printf(char *fmt, ...)
249 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
250 if (mainwindow) { /* FIXME: direct to error window */
251 retval = _vwprintw(mainwindow, fmt, ap);
252 if (fmt[strlen(fmt) - 1] == '\n')
253 wrefresh(mainwindow);
256 retval = vfprintf(stderr, fmt, ap);
263 * sln_printf() outputs to error status window (or stderr if not in curses)
265 int sln_printf(char *fmt, ...)
269 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
270 static char buf[4096];
274 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
278 retval = vsnprintf(buf, 4096, fmt, ap);
279 for (i = buf; *i; i++) {
280 if (*i == '\r' || *i == '\n')
281 wclrtoeol(statuswindow);
283 if (*i == '\r' || *i == '\n') {
284 wrefresh(statuswindow);
285 mvwinch(statuswindow, 0, 0);
290 retval = vprintf(fmt, ap);
297 * sln_printf_if() outputs to status window, no output if not in curses
299 int sln_printf_if(char *fmt, ...)
301 register int retval = 1;
302 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
303 static char buf[4096];
310 retval = vsnprintf(buf, 4096, fmt, ap);
311 for (i = buf; *i; i++) {
312 if (*i == '\r' || *i == '\n')
313 wclrtoeol(statuswindow);
315 if (*i == '\r' || *i == '\n') {
316 wrefresh(statuswindow);
317 mvwinch(statuswindow, 0, 0);
327 int scr_getc(int delay)
331 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
333 wtimeout(mainwindow, delay);
334 return wgetch(mainwindow);
339 if (!read (0, &buf, 1))
344 /* the following is unused and looks broken, but there may
345 be some input problems still lurking in curses mode, so
346 i'll leave it blocked out for now for informational
349 int scr_blockread(void)
352 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
353 wtimeout(mainwindow, S_KEEPALIVE);
357 a = wgetch(mainwindow); /* will block for food */
360 /* a = scr_getc(); */
368 * scr_putc() outputs a single character
372 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
375 if (waddch(mainwindow, c) != OK)
380 if (putc(c, stdout) == EOF)
388 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
390 return ((waddch(statuswindow, c) == OK) ? c : EOF);
392 return putc(c, stdout);
396 int sln_putc_if(int c)
398 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
400 return ((waddch(statuswindow, c) == OK) ? c : EOF);
407 * scr_color() sets the window color for mainwindow
409 int scr_color(int colornum)
411 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
413 #ifdef HAVE_WCOLOR_SET
414 wcolor_set(mainwindow, (colornum & 7), NULL);
416 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
419 wattron(mainwindow, A_BOLD);
421 wattroff(mainwindow, A_BOLD);
432 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
434 wrefresh(mainwindow);
443 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
444 if (mainwindow) /* FIXME: error status window needed */
445 wrefresh(mainwindow);
454 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
456 wrefresh(statuswindow);
462 static volatile int caught_sigwinch = 0;
465 * this is not supposed to be called from a signal handler.
467 int scr_set_windowsize(CtdlIPC* ipc)
469 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
470 if (mainwindow && caught_sigwinch) {
472 #ifdef HAVE_RESIZETERM
473 resizeterm(screenheight + 1, screenwidth);
476 wresize(mainwindow, screenheight, screenwidth);
477 wresize(statuswindow, 1, screenwidth);
479 mvwin(statuswindow, screenheight, 0);
480 status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location,
481 room_name, secure, -1);
482 wnoutrefresh(mainwindow);
483 wnoutrefresh(statuswindow);
487 #endif /* HAVE_CURSES_H */
492 * scr_winch() handles window size changes from SIGWINCH
493 * resizes all our windows for us
495 RETSIGTYPE scr_winch(int signum)
497 /* if we receive this signal, we must be running
498 in a terminal that supports resizing. */
502 signal(SIGWINCH, scr_winch);
507 * Initialize the window(s) we will be using.
509 void windows_new(void)
511 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
515 getmaxyx(stdscr, y, x);
516 mainwindow = newwin(y - 1, x, 0, 0);
518 screenheight = y - 1;
519 immedok(mainwindow, FALSE);
520 leaveok(mainwindow, FALSE);
521 scrollok(mainwindow, TRUE);
522 statuswindow = newwin(1, x, y - 1, 0);
525 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
527 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
529 werase(statuswindow);
530 immedok(statuswindow, FALSE);
531 leaveok(statuswindow, FALSE);
532 scrollok(statuswindow, FALSE);
533 wrefresh(statuswindow);
535 #else /* HAVE_CURSES_H */
537 #endif /* HAVE_CURSES_H */
542 * Deinitialize the window(s) we were using (at exit).
544 void windows_delete(void)
546 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
551 delwin(statuswindow);
553 #else /* HAVE_CURSES_H */
555 #endif /* HAVE_CURSES_H */