* Handle full-screen curses stuff
*/
-#include "sysdep.h"
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
+#include <stdlib.h>
+#include <unistd.h>
#include <stdio.h>
+#include <signal.h>
#include <string.h>
#include <stdarg.h>
-#include <unistd.h>
#include <sys/types.h>
-#ifdef VW_PRINTW_IN_CURSES
+#include "sysdep.h"
+#ifdef HAVE_VW_PRINTW
#define _vwprintw vw_printw
#else
-/* Ancient curses implementations, this needs testing. Anybody got XENIX? */
+/* SYSV style curses (Solaris, etc.) */
#define _vwprintw vwprintw
#endif
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
#include "citadel.h"
+#include "citadel_ipc.h"
+#include "citadel_decls.h"
#include "commands.h"
#include "screen.h"
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
static SCREEN *myscreen = NULL;
static WINDOW *mainwindow = NULL;
static WINDOW *statuswindow = NULL;
char rc_screen;
char arg_screen;
+#endif
extern int screenheight;
extern int screenwidth;
extern int rc_ansi_color;
extern void check_screen_dims(void);
-#endif
+
+void do_keepalive(void);
+int is_curses_enabled(void) {
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ return mainwindow != NULL;
+#else
+ return 0;
+#endif
+}
+
/*
* status_line() is a convenience function for writing a "typical"
* status line to the window.
*/
-void status_line(const char *humannode, const char *bbs_city,
+void status_line(const char *humannode, const char *site_location,
const char *room_name, int secure, int newmailcount)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (statuswindow) {
- if (secure)
- sln_printf("Secure ");
- else
- sln_printf("Not secure ");
- waddch(statuswindow, ACS_VLINE);
- waddch(statuswindow, ' ');
- if (humannode && bbs_city)
- sln_printf("%s at %s ", humannode, bbs_city);
+ if (secure) {
+ sln_printf("Encrypted ");
+ waddch(statuswindow, ACS_VLINE);
+ waddch(statuswindow, ' ');
+ }
if (room_name)
- sln_printf("in %s ", room_name);
- if (newmailcount > -1) {
+ sln_printf("%s on ", room_name);
+ if (humannode)
+ sln_printf("%s ", humannode);
+ if (newmailcount > 0) {
waddch(statuswindow, ACS_VLINE);
- sln_printf(" %d unread mail", newmailcount);
+ sln_printf(" %d new mail ", newmailcount);
}
sln_printf("\n");
}
}
+/*
+ * Display a 3270-style "wait" indicator at the bottom of the screen
+ */
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+void wait_indicator(int state) {
+
+ if (!isendwin() && statuswindow) {
+
+ mvwinch(statuswindow, 0, screenwidth - 2);
+ switch (state) {
+ default:
+ case 0: /* Idle */
+ waddch(statuswindow, ' ');
+ break;
+ case 1: /* Waiting */
+ waddch(statuswindow, 'X');
+ break;
+ case 2: /* Receiving */
+ waddch(statuswindow, '<');
+ break;
+ case 3: /* Sending */
+ waddch(statuswindow, '>');
+ break;
+ }
+ waddch(statuswindow, '\r');
+ wrefresh(statuswindow);
+ wrefresh(mainwindow); /* this puts the cursor back */
+ }
+}
+#endif
+
+
/*
* Initialize the screen. If newterm() fails, myscreen will be NULL and
* further handlers will assume we should be in line mode.
*/
void screen_new(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (arg_screen != RC_NO && rc_screen != RC_NO)
myscreen = newterm(NULL, stdout, stdin);
if (myscreen) {
start_color();
if (rc_ansi_color)
enable_color = 1;
- init_pair(1+DIM_BLACK, COLOR_BLACK, COLOR_BLACK);
- init_pair(1+DIM_RED, COLOR_RED, COLOR_BLACK);
- init_pair(1+DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
- init_pair(1+DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
- init_pair(1+DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
- init_pair(1+DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
- init_pair(1+DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
- init_pair(1+DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
- init_pair(17, COLOR_WHITE, COLOR_BLUE);
+ /*init_pair(DIM_BLACK, COLOR_BLACK, COLOR_BLACK);*/
+ init_pair(DIM_RED, COLOR_RED, COLOR_BLACK);
+ init_pair(DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
+ init_pair(DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
+ init_pair(DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
+ init_pair(DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
+ init_pair(DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
+ init_pair(DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
+
+ if (COLOR_PAIRS > 8)
+ init_pair(8, COLOR_WHITE, COLOR_BLUE);
} else
#endif /* HAVE_CURSES_H */
{
send_ansi_detect();
look_for_ansi();
cls(0);
- color(1+DIM_WHITE);
+ color(DIM_WHITE);
}
screen_set();
windows_new();
{
windows_delete();
screen_reset();
-#ifdef HAVE_CURSES_H
- if (myscreen)
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ if (myscreen) {
delscreen(myscreen);
+ }
myscreen = NULL;
#endif
}
+/*
+ * Beep.
+ */
+void ctdl_beep(void) {
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ if (myscreen)
+ beep();
+ else
+#endif
+ putc(7, stdout);
+}
+
+
/*
* Set screen/IO parameters, e.g. at start of program or return from external
*/
int screen_set(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (myscreen) {
set_term(myscreen);
wrefresh(curscr);
*/
int screen_reset(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (myscreen) {
- endwin();
+ if (!isendwin()) endwin();
return 1;
}
#endif /* HAVE_CURSES_H */
register int retval;
va_start(ap, fmt);
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow) {
retval = _vwprintw(mainwindow, fmt, ap);
- /*
- if (fmt[strlen(fmt) - 1] == '\n')
- wrefresh(mainwindow);
- */
} else
#endif
retval = vprintf(fmt, ap);
register int retval;
va_start(ap, fmt);
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow) { /* FIXME: direct to error window */
retval = _vwprintw(mainwindow, fmt, ap);
if (fmt[strlen(fmt) - 1] == '\n')
{
va_list ap;
register int retval;
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
static char buf[4096];
#endif
va_start(ap, fmt);
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (statuswindow) {
register char *i;
if (*i == '\r' || *i == '\n')
wclrtoeol(statuswindow);
sln_putc(*i);
- if (*i == '\r' || *i == '\n')
+ if (*i == '\r' || *i == '\n') {
+ wrefresh(statuswindow);
mvwinch(statuswindow, 0, 0);
+ }
}
} else
#endif
int sln_printf_if(char *fmt, ...)
{
register int retval = 1;
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
static char buf[4096];
va_list ap;
if (*i == '\r' || *i == '\n')
wclrtoeol(statuswindow);
sln_putc(*i);
- if (*i == '\r' || *i == '\n')
+ if (*i == '\r' || *i == '\n') {
+ wrefresh(statuswindow);
mvwinch(statuswindow, 0, 0);
+ }
}
}
va_end(ap);
}
-int scr_getc(void)
+int scr_getc(int delay)
{
-#ifdef HAVE_CURSES_H
- if (mainwindow)
+ unsigned char buf;
+
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ if (mainwindow) {
+ wtimeout(mainwindow, delay);
return wgetch(mainwindow);
+ }
#endif
- return getchar();
+
+ buf = '\0';
+ if (!read (0, &buf, 1))
+ logoff(NULL, 3);
+ return buf;
}
+/* the following is unused and looks broken, but there may
+ be some input problems still lurking in curses mode, so
+ i'll leave it blocked out for now for informational
+ purposes. */
+#if 0
+int scr_blockread(void)
+ {
+ int a = 0;
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ wtimeout(mainwindow, S_KEEPALIVE);
+ while (1)
+ {
+ do_keepalive();
+ a = wgetch(mainwindow); /* will block for food */
+ if (a != ERR)
+ break;
+ /* a = scr_getc(); */
+ }
+#endif
+ return a;
+ }
+#endif /* 0 */
/*
* scr_putc() outputs a single character
*/
int scr_putc(int c)
{
-#ifdef HAVE_CURSES_H
- if (mainwindow)
- return ((waddch(mainwindow, c) == OK) ? c : EOF);
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ if (mainwindow) {
+ if (c == 7) beep();
+ if (waddch(mainwindow, c) != OK)
+ logoff(NULL, 3);
+ return c;
+ }
#endif
- return putc(c, stdout);
+ if (putc(c, stdout) == EOF)
+ logoff(NULL, 3);
+ return c;
}
int sln_putc(int c)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (statuswindow)
return ((waddch(statuswindow, c) == OK) ? c : EOF);
#endif
int sln_putc_if(int c)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (statuswindow)
return ((waddch(statuswindow, c) == OK) ? c : EOF);
#endif
*/
int scr_color(int colornum)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow) {
- wcolor_set(mainwindow, 1 + (colornum & 7), NULL);
+#ifdef HAVE_WCOLOR_SET
+ wcolor_set(mainwindow, (colornum & 7), NULL);
+#else
+ wattron(mainwindow, COLOR_PAIR((colornum & 7)));
+#endif
if (colornum & 8) {
wattron(mainwindow, A_BOLD);
} else {
void scr_flush(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow)
wrefresh(mainwindow);
else
void err_flush(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow) /* FIXME: error status window needed */
wrefresh(mainwindow);
else
void sln_flush(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (statuswindow)
wrefresh(statuswindow);
else
fflush(stdout);
}
+static volatile int caught_sigwinch = 0;
-int scr_set_windowsize(void)
+/*
+ * this is not supposed to be called from a signal handler.
+ */
+int scr_set_windowsize(CtdlIPC* ipc)
{
-#ifdef HAVE_CURSES_H
- int y, x;
-
- if (mainwindow) {
- getmaxyx(mainwindow, y, x);
- screenheight = y;
- screenwidth = x;
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
+ if (mainwindow && caught_sigwinch) {
+ caught_sigwinch = 0;
+#ifdef HAVE_RESIZETERM
+ resizeterm(screenheight + 1, screenwidth);
+#endif
+#ifdef HAVE_WRESIZE
+ wresize(mainwindow, screenheight, screenwidth);
+ wresize(statuswindow, 1, screenwidth);
+#endif
+ mvwin(statuswindow, screenheight, 0);
+ status_line(ipc->ServInfo.humannode, ipc->ServInfo.site_location,
+ room_name, secure, -1);
+ wnoutrefresh(mainwindow);
+ wnoutrefresh(statuswindow);
+ doupdate();
return 1;
}
#endif /* HAVE_CURSES_H */
return 0;
}
-
/*
* scr_winch() handles window size changes from SIGWINCH
* resizes all our windows for us
*/
-RETSIGTYPE scr_winch(void)
+RETSIGTYPE scr_winch(int signum)
{
-#ifdef HAVE_CURSES_H
- /* FIXME: not implemented */
-#endif
+ /* if we receive this signal, we must be running
+ in a terminal that supports resizing. */
+ have_xterm = 1;
+ caught_sigwinch = 1;
check_screen_dims();
+ signal(SIGWINCH, scr_winch);
}
*/
void windows_new(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
register int x, y;
if (myscreen) {
leaveok(mainwindow, FALSE);
scrollok(mainwindow, TRUE);
statuswindow = newwin(1, x, y - 1, 0);
- wbkgdset(statuswindow, COLOR_PAIR(17));
+
+ if (COLOR_PAIRS > 8)
+ wbkgdset(statuswindow, ' ' | COLOR_PAIR(8));
+ else
+ wbkgdset(statuswindow, ' ' | COLOR_PAIR(DIM_WHITE));
+
werase(statuswindow);
- immedok(statuswindow, TRUE);
+ immedok(statuswindow, FALSE);
leaveok(statuswindow, FALSE);
scrollok(statuswindow, FALSE);
wrefresh(statuswindow);
*/
void windows_delete(void)
{
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
if (mainwindow)
delwin(mainwindow);
mainwindow = NULL;