]> code.citadel.org Git - citadel.git/blobdiff - citadel/screen.c
* Variable names, comments, documentation, etc... removed the acronym 'BBS'
[citadel.git] / citadel / screen.c
index 374210a4f9b716d9f18bbfa6a24435d2e2332f36..7a5bdcced0593bcd32d4d2e99d7d7a57e35ded99 100644 (file)
@@ -4,65 +4,75 @@
  * 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");
        }
@@ -70,13 +80,45 @@ void status_line(const char *humannode, const char *bbs_city,
 }
 
 
+/*
+ * 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) {
@@ -89,22 +131,24 @@ void screen_new(void)
                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();
@@ -119,13 +163,27 @@ void screen_delete(void)
 {
        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
@@ -133,7 +191,7 @@ void screen_delete(void)
  */
 int screen_set(void)
 {
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
        if (myscreen) {
                set_term(myscreen);
                wrefresh(curscr);
@@ -149,9 +207,9 @@ int screen_set(void)
  */
 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 */
@@ -168,7 +226,7 @@ int scr_printf(char *fmt, ...)
        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);
        } else
@@ -188,7 +246,7 @@ int err_printf(char *fmt, ...)
        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')
@@ -208,12 +266,12 @@ int sln_printf(char *fmt, ...)
 {
        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;
                
@@ -241,7 +299,7 @@ int sln_printf(char *fmt, ...)
 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;
 
@@ -266,32 +324,68 @@ int sln_printf_if(char *fmt, ...)
 }
 
 
-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
@@ -301,7 +395,7 @@ int sln_putc(int c)
 
 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
@@ -314,9 +408,13 @@ int sln_putc_if(int c)
  */
 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 {
@@ -331,7 +429,7 @@ int scr_color(int colornum)
 
 void scr_flush(void)
 {
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
        if (mainwindow)
                wrefresh(mainwindow);
        else
@@ -342,7 +440,7 @@ void scr_flush(void)
 
 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
@@ -353,7 +451,7 @@ void err_flush(void)
 
 void sln_flush(void)
 {
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
        if (statuswindow)
                wrefresh(statuswindow);
        else
@@ -361,33 +459,47 @@ void sln_flush(void)
                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);
 }
 
 
@@ -396,7 +508,7 @@ RETSIGTYPE scr_winch(void)
  */
 void windows_new(void)
 {
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
        register int x, y;
 
        if (myscreen) {
@@ -408,7 +520,12 @@ void windows_new(void)
                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, FALSE);
                leaveok(statuswindow, FALSE);
@@ -426,7 +543,7 @@ void windows_new(void)
  */
 void windows_delete(void)
 {
-#ifdef HAVE_CURSES_H
+#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
        if (mainwindow)
                delwin(mainwindow);
        mainwindow = NULL;