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 (statuswindow
&& !isendwin()) {
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 */
113 void wait_indicator(int state
) {}
118 * Initialize the screen. If newterm() fails, myscreen will be NULL and
119 * further handlers will assume we should be in line mode.
121 void screen_new(void)
123 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
124 if (arg_screen
!= RC_NO
&& rc_screen
!= RC_NO
)
125 myscreen
= newterm(NULL
, stdout
, stdin
);
130 intrflush(stdscr
, FALSE
);
131 keypad(stdscr
, TRUE
);
132 /* Setup all our colors */
136 /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
137 init_pair(DIM_RED
, COLOR_RED
, COLOR_BLACK
);
138 init_pair(DIM_GREEN
, COLOR_GREEN
, COLOR_BLACK
);
139 init_pair(DIM_YELLOW
, COLOR_YELLOW
, COLOR_BLACK
);
140 init_pair(DIM_BLUE
, COLOR_BLUE
, COLOR_BLACK
);
141 init_pair(DIM_MAGENTA
, COLOR_MAGENTA
, COLOR_BLACK
);
142 init_pair(DIM_CYAN
, COLOR_CYAN
, COLOR_BLACK
);
143 init_pair(DIM_WHITE
, COLOR_WHITE
, COLOR_BLACK
);
146 init_pair(8, COLOR_WHITE
, COLOR_BLUE
);
148 #endif /* HAVE_CURSES_H */
161 * Kill the screen completely (used at exit). It is safe to call this
162 * function more than once.
164 void screen_delete(void)
168 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
179 void ctdl_beep(void) {
180 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
191 * Set screen/IO parameters, e.g. at start of program or return from external
196 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
202 #endif /* HAVE_CURSES_H */
208 * Reset screen/IO parameters, e.g. at exit or fork of external program.
210 int screen_reset(void)
212 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
214 if (!isendwin()) endwin();
217 #endif /* HAVE_CURSES_H */
223 * scr_printf() outputs to the main window (or screen if not in curses)
225 int scr_printf(char *fmt
, ...)
231 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
233 retval
= _vwprintw(mainwindow
, fmt
, ap
);
236 retval
= vprintf(fmt
, ap
);
243 * err_printf() outputs to error status window (or stderr if not in curses)
245 int err_printf(char *fmt
, ...)
251 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
252 if (mainwindow
) { /* FIXME: direct to error window */
253 retval
= _vwprintw(mainwindow
, fmt
, ap
);
254 if (fmt
[strlen(fmt
) - 1] == '\n')
255 wrefresh(mainwindow
);
258 retval
= vfprintf(stderr
, fmt
, ap
);
265 * sln_printf() outputs to error status window (or stderr if not in curses)
267 int sln_printf(char *fmt
, ...)
271 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
272 static char buf
[4096];
276 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
280 retval
= vsnprintf(buf
, 4096, fmt
, ap
);
281 for (i
= buf
; *i
; i
++) {
282 if (*i
== '\r' || *i
== '\n')
283 wclrtoeol(statuswindow
);
285 if (*i
== '\r' || *i
== '\n') {
286 wrefresh(statuswindow
);
287 mvwinch(statuswindow
, 0, 0);
292 retval
= vprintf(fmt
, ap
);
299 * sln_printf_if() outputs to status window, no output if not in curses
301 int sln_printf_if(char *fmt
, ...)
303 register int retval
= 1;
304 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
305 static char buf
[4096];
312 retval
= vsnprintf(buf
, 4096, fmt
, ap
);
313 for (i
= buf
; *i
; i
++) {
314 if (*i
== '\r' || *i
== '\n')
315 wclrtoeol(statuswindow
);
317 if (*i
== '\r' || *i
== '\n') {
318 wrefresh(statuswindow
);
319 mvwinch(statuswindow
, 0, 0);
329 int scr_getc(int delay
)
333 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
335 wtimeout(mainwindow
, delay
);
336 return wgetch(mainwindow
);
341 if (!read (0, &buf
, 1))
346 /* the following is unused and looks broken, but there may
347 be some input problems still lurking in curses mode, so
348 i'll leave it blocked out for now for informational
351 int scr_blockread(void)
354 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
355 wtimeout(mainwindow
, S_KEEPALIVE
);
359 a
= wgetch(mainwindow
); /* will block for food */
362 /* a = scr_getc(); */
370 * scr_putc() outputs a single character
374 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
377 if (waddch(mainwindow
, c
) != OK
)
382 if (putc(c
, stdout
) == EOF
)
390 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
392 return ((waddch(statuswindow
, c
) == OK
) ? c
: EOF
);
394 return putc(c
, stdout
);
398 int sln_putc_if(int c
)
400 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
402 return ((waddch(statuswindow
, c
) == OK
) ? c
: EOF
);
409 * scr_color() sets the window color for mainwindow
411 int scr_color(int colornum
)
413 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
415 #ifdef HAVE_WCOLOR_SET
416 wcolor_set(mainwindow
, (colornum
& 7), NULL
);
418 wattron(mainwindow
, COLOR_PAIR((colornum
& 7)));
421 wattron(mainwindow
, A_BOLD
);
423 wattroff(mainwindow
, A_BOLD
);
434 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
436 wrefresh(mainwindow
);
445 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
446 if (mainwindow
) /* FIXME: error status window needed */
447 wrefresh(mainwindow
);
456 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
458 wrefresh(statuswindow
);
464 static volatile int caught_sigwinch
= 0;
467 * this is not supposed to be called from a signal handler.
469 int scr_set_windowsize(CtdlIPC
* ipc
)
471 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
472 if (mainwindow
&& caught_sigwinch
) {
474 #ifdef HAVE_RESIZETERM
475 resizeterm(screenheight
+ 1, screenwidth
);
478 wresize(mainwindow
, screenheight
, screenwidth
);
479 wresize(statuswindow
, 1, screenwidth
);
481 mvwin(statuswindow
, screenheight
, 0);
482 status_line(ipc
->ServInfo
.humannode
, ipc
->ServInfo
.site_location
,
483 room_name
, secure
, -1);
484 wnoutrefresh(mainwindow
);
485 wnoutrefresh(statuswindow
);
489 #endif /* HAVE_CURSES_H */
494 * scr_winch() handles window size changes from SIGWINCH
495 * resizes all our windows for us
497 RETSIGTYPE
scr_winch(int signum
)
499 /* if we receive this signal, we must be running
500 in a terminal that supports resizing. */
504 signal(SIGWINCH
, scr_winch
);
509 * Initialize the window(s) we will be using.
511 void windows_new(void)
513 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
517 getmaxyx(stdscr
, y
, x
);
518 mainwindow
= newwin(y
- 1, x
, 0, 0);
520 screenheight
= y
- 1;
521 immedok(mainwindow
, FALSE
);
522 leaveok(mainwindow
, FALSE
);
523 scrollok(mainwindow
, TRUE
);
524 statuswindow
= newwin(1, x
, y
- 1, 0);
527 wbkgdset(statuswindow
, ' ' | COLOR_PAIR(8));
529 wbkgdset(statuswindow
, ' ' | COLOR_PAIR(DIM_WHITE
));
531 werase(statuswindow
);
532 immedok(statuswindow
, FALSE
);
533 leaveok(statuswindow
, FALSE
);
534 scrollok(statuswindow
, FALSE
);
535 wrefresh(statuswindow
);
537 #else /* HAVE_CURSES_H */
539 #endif /* HAVE_CURSES_H */
544 * Deinitialize the window(s) we were using (at exit).
546 void windows_delete(void)
548 #if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
553 delwin(statuswindow
);
555 #else /* HAVE_CURSES_H */
557 #endif /* HAVE_CURSES_H */