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
24 #include <libcitadel.h>
26 #include "citadel_ipc.h"
27 #include "citadel_decls.h"
31 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
32 static SCREEN *myscreen = NULL;
33 static WINDOW *mainwindow = NULL;
34 static WINDOW *statuswindow = NULL;
40 extern int screenheight;
41 extern int screenwidth;
42 extern int rc_ansi_color;
43 extern void check_screen_dims(void);
45 void do_keepalive(void);
48 int is_curses_enabled(void) {
49 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
50 return mainwindow != NULL;
57 * status_line() is a convenience function for writing a "typical"
58 * status line to the window.
60 void status_line(const char *humannode, const char *site_location,
61 const char *room_name, int secure, int newmailcount)
63 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
66 sln_printf("Encrypted ");
67 waddch(statuswindow, ACS_VLINE);
68 waddch(statuswindow, ' ');
71 sln_printf("%s on ", room_name);
73 sln_printf("%s ", humannode);
74 if (newmailcount > 0) {
75 waddch(statuswindow, ACS_VLINE);
76 sln_printf(" %d new mail ", newmailcount);
80 #endif /* HAVE_CURSES_H */
85 * Display a 3270-style "wait" indicator at the bottom of the screen
87 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
88 void wait_indicator(int state) {
90 if (statuswindow && !isendwin()) {
92 mvwinch(statuswindow, 0, screenwidth - 2);
96 waddch(statuswindow, ' ');
99 waddch(statuswindow, 'X');
101 case 2: /* Receiving */
102 waddch(statuswindow, '<');
104 case 3: /* Sending */
105 waddch(statuswindow, '>');
108 waddch(statuswindow, '\r');
109 wrefresh(statuswindow);
110 wrefresh(mainwindow); /* this puts the cursor back */
114 void wait_indicator(int state) {}
119 * Initialize the screen. If newterm() fails, myscreen will be NULL and
120 * further handlers will assume we should be in line mode.
122 void screen_new(void)
124 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
125 if (arg_screen != RC_NO && rc_screen != RC_NO)
126 myscreen = newterm(NULL, stdout, stdin);
131 intrflush(stdscr, FALSE);
132 keypad(stdscr, TRUE);
133 /* Setup all our colors */
137 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
138 init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
139 init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
140 init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
141 init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
142 init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
143 init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
144 init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
147 init_pair(8, COLOR_WHITE, COLOR_BLUE);
149 #endif /* HAVE_CURSES_H */
162 * Kill the screen completely (used at exit). It is safe to call this
163 * function more than once.
165 void screen_delete(void)
169 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
180 void ctdl_beep(void) {
181 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
192 * Set screen/IO parameters, e.g. at start of program or return from external
197 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
203 #endif /* HAVE_CURSES_H */
209 * Reset screen/IO parameters, e.g. at exit or fork of external program.
211 int screen_reset(void)
213 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
215 if (!isendwin()) endwin();
218 #endif /* HAVE_CURSES_H */
224 * scr_printf() outputs to the main window (or screen if not in curses)
226 int scr_printf(char *fmt, ...)
232 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
234 retval = _vwprintw(mainwindow, fmt, ap);
237 retval = vprintf(fmt, ap);
244 * err_printf() outputs to error status window (or stderr if not in curses)
246 int err_printf(char *fmt, ...)
252 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
253 if (mainwindow) { /* FIXME: direct to error window */
254 retval = _vwprintw(mainwindow, fmt, ap);
255 if (fmt[strlen(fmt) - 1] == '\n')
256 wrefresh(mainwindow);
259 retval = vfprintf(stderr, fmt, ap);
266 * sln_printf() outputs to error status window (or stderr if not in curses)
268 int sln_printf(char *fmt, ...)
272 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
273 static char buf[4096];
277 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
281 retval = vsnprintf(buf, 4096, fmt, ap);
282 for (i = buf; *i; i++) {
283 if (*i == '\r' || *i == '\n')
284 wclrtoeol(statuswindow);
286 if (*i == '\r' || *i == '\n') {
287 wrefresh(statuswindow);
288 mvwinch(statuswindow, 0, 0);
293 retval = vprintf(fmt, ap);
300 * sln_printf_if() outputs to status window, no output if not in curses
302 int sln_printf_if(char *fmt, ...)
304 register int retval = 1;
305 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
306 static char buf[4096];
313 retval = vsnprintf(buf, 4096, fmt, ap);
314 for (i = buf; *i; i++) {
315 if (*i == '\r' || *i == '\n')
316 wclrtoeol(statuswindow);
318 if (*i == '\r' || *i == '\n') {
319 wrefresh(statuswindow);
320 mvwinch(statuswindow, 0, 0);
330 int scr_getc(int delay)
334 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
336 wtimeout(mainwindow, delay);
337 return wgetch(mainwindow);
342 if (!read (0, &buf, 1))
347 /* the following is unused and looks broken, but there may
348 be some input problems still lurking in curses mode, so
349 i'll leave it blocked out for now for informational
352 int scr_blockread(void)
355 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
356 wtimeout(mainwindow, S_KEEPALIVE);
360 a = wgetch(mainwindow); /* will block for food */
363 /* a = scr_getc(); */
371 * scr_putc() outputs a single character
375 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
378 if (waddch(mainwindow, c) != OK)
383 if (putc(c, stdout) == EOF)
391 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
393 return ((waddch(statuswindow, c) == OK) ? c : EOF);
395 return putc(c, stdout);
399 int sln_putc_if(int c)
401 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
403 return ((waddch(statuswindow, c) == OK) ? c : EOF);
410 * scr_color() sets the window color for mainwindow
412 int scr_color(int colornum)
414 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
416 #ifdef HAVE_WCOLOR_SET
417 wcolor_set(mainwindow, (colornum & 7), NULL);
419 wattron(mainwindow, COLOR_PAIR((colornum & 7)));
422 wattron(mainwindow, A_BOLD);
424 wattroff(mainwindow, A_BOLD);
435 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
437 wrefresh(mainwindow);
446 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
447 if (mainwindow) /* FIXME: error status window needed */
448 wrefresh(mainwindow);
457 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
459 wrefresh(statuswindow);
465 static volatile int caught_sigwinch = 0;
468 * this is not supposed to be called from a signal handler.
470 int scr_set_windowsize(CtdlIPC* ipc)
472 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
473 if (mainwindow && caught_sigwinch) {
475 #ifdef HAVE_RESIZETERM
476 resizeterm(screenheight + 1, screenwidth);
479 wresize(mainwindow, screenheight, screenwidth);
480 wresize(statuswindow, 1, screenwidth);
482 mvwin(statuswindow, screenheight, 0);
483 status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location,
484 room_name, secure, -1);
485 wnoutrefresh(mainwindow);
486 wnoutrefresh(statuswindow);
490 #endif /* HAVE_CURSES_H */
495 * scr_winch() handles window size changes from SIGWINCH
496 * resizes all our windows for us
498 RETSIGTYPE scr_winch(int signum)
500 /* if we receive this signal, we must be running
501 in a terminal that supports resizing. */
505 signal(SIGWINCH, scr_winch);
510 * Initialize the window(s) we will be using.
512 void windows_new(void)
514 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
518 getmaxyx(stdscr, y, x);
519 mainwindow = newwin(y - 1, x, 0, 0);
521 screenheight = y - 1;
522 immedok(mainwindow, FALSE);
523 leaveok(mainwindow, FALSE);
524 scrollok(mainwindow, TRUE);
525 statuswindow = newwin(1, x, y - 1, 0);
528 wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
530 wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
532 werase(statuswindow);
533 immedok(statuswindow, FALSE);
534 leaveok(statuswindow, FALSE);
535 scrollok(statuswindow, FALSE);
536 wrefresh(statuswindow);
538 #else /* HAVE_CURSES_H */
540 #endif /* HAVE_CURSES_H */
545 * Deinitialize the window(s) we were using (at exit).
547 void windows_delete(void)
549 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
554 delwin(statuswindow);
556 #else /* HAVE_CURSES_H */
558 #endif /* HAVE_CURSES_H */