diff --git a/ChangeLog b/ChangeLog
index d3e63bd7c14ca187f16dec0e2e7541eb639f809d..7d9990ec17d0ed6d31fa8bfe9cd3ec73291b454c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,8 @@ CVS code -
 	- Make sure the special control keys are handled the same way
 	  after the window is resized or we come out of suspend mode.
 	  Changes to do_cont() and handle_sigwinch(). (DLR)
+	- Change some instances of ints that can never be negative to
+	  size_t's. (DLR)
 	- Add better explanations for and in the "Terminal breakage"
 	  comments, and handle missing key #ifdefs inside the functions
 	  that use those keys. (DLR)
@@ -48,6 +50,9 @@ CVS code -
 	  justify_format() may get a space tacked onto the end of it
 	  later, so now the entire original paragraph is always backed
 	  up.) (DLR)
+	- Wrap the long jump code in NANO_SMALL #ifdefs, since we only
+	  use it if we're resizing the window, which is disabled when
+	  NANO_SMALL is defined. (DLR)
 - files.c:
   add_open_file()
 	- Rearrange the NANO_SMALL #ifdef so that the code to set the
@@ -57,6 +62,15 @@ CVS code -
 	- Refactor so that no recursion is needed if we try to exit with
 	  a modified file that has no name when TEMP_OPT is set. (DLR)
 - nano.c:
+  do_toggle(), finish()
+	- Call blank_statusbar() and blank_bottombars() to blank out
+	  the statusbar and shortcut list in bottomwin. (DLR)
+  do_early_abort()
+	- Removed, as it's no longer called anywhere. (David Benbennick)
+  open_pipe()
+	- Call enable_signals() at the beginning and disable_signals()
+	  at the end, so that we get a SIGINT when Ctrl-C is pressed
+	  during wait() and can then call cancel_fork() properly. (DLR)
   do_delete()
 	- Tweak for efficiency. (David Benbennick)
   justify_format()
@@ -72,10 +86,32 @@ CVS code -
   print_numlock_warning()
 	- Removed, as it's no longer needed and was never called
 	  anywhere after the input overhaul. (DLR)
+  signal_init()
+	- Don't use termios and _POSIX_VDISABLE to disable keys anymore,
+	  as there's no real equivalent of it when the latter isn't
+	  defined. (DLR)
+  handle_sigwinch()
+	- Call resetty() to get the original terminal settings back.
+	  (DLR)
+	- Rework so that nano properly redraws the screen on systems
+	  that don't have resizeterm() and/or wresize().  In curses, we
+	  now leave and immediately reenter curses mode via endwin() and
+	  refresh(), and then reinitialize all windows via
+	  window_init().  In slang, the above routine will only work if
+	  the resize made the window smaller, so we now leave and
+	  immediately reenter screen management mode via
+	  SLsmg_reset_smg() and SLsmg_init_smg(), and then reinitialize
+	  all windows via window_init().  (DLR, adapted from code in
+	  Minimum Profit 3.3.0 and mutt 1.4.2.1, respectively)
   do_verbatim_input()
-	- Use size_t's instead of ints for the get_verbatim_kbinput()
-	  call and the loop that ungetch()es its returned int*,
-	  respectively. (DLR)
+	- If PRESERVE is set, disable flow control characters before
+	  getting input and reenable them after getting input. (DLR)
+  disable_signals(), enable_signals(), disable_flow_control(),
+  enable_flow_control()
+	- New functions that allow more fine-grained control of the
+	  terminal: disabling and enabling signals without having to use
+	  _POSIX_VDISABLE and disabling and enabling flow control
+	  characters. (DLR)
   main()
 	- Don't open the first file in quiet mode, since if we do, an
 	  error message won't be shown if it's unreadable. (DLR; found
@@ -88,6 +124,17 @@ CVS code -
 	  the nanorc first, both of which are unintuitive.  Multibuffer
 	  mode should only affect how the "Read File" command behaves
 	  anyway. (DLR)
+	- Remove the disabling of implementation-defined input
+	  processing, as raw mode appears to turn it off anyway. (DLR)
+	- Use raw mode instead of cbreak mode, since it comes closest to
+	  what we need by automatically disabling the special control
+	  keys. (DLR)
+	- After noecho(), call disable_signals() and
+	  disable_flow_control(), the latter only if PRESERVE is not
+	  set. (DLR)
+	- Move the savetty() call down from just after initscr() to just
+	  after the terminal is properly set up, so that we can restore
+	  it easily after a resize. (DLR)
 - nano.h:
 	- Since REGEXP_COMPILED is only used in search.c, convert it
 	  from a flag to a static int there. (DLR)
@@ -131,8 +178,6 @@ CVS code -
 	- Refactor the output in the DEBUG #ifdef.  It didn't work
 	  properly ever since this function was changed to use an int*
 	  instead of a char*. (DLR)
-	- Change kbinput_len from an int* to a size_t*, since it should
-	  never be negative. (DLR)
 	- When reading characters from input, properly reallocate
 	  verbatim_kbinput via (int*)nrealloc() instead of an uncast
 	  realloc(). (DLR)
@@ -140,8 +185,6 @@ CVS code -
 	- Add proper support for the keypad values and escape sequences
 	  generated by the NumLock glitch. (DLR)
   get_escape_seq_kbinput()
-	- Change escape_seq_len from an int to a size_t, since it should
-	  never be negative. (DLR)
 	- Add proper support for the keypad values and escape sequences
 	  generated by the NumLock glitch. (DLR)
   bottombars()
@@ -152,6 +195,14 @@ CVS code -
   edit_add()
 	- Minor cosmetic reformatting.  Also remove unused int
 	  searched_later_lines. (DLR)
+  blank_bottomwin()
+	- Removed, as it does the same thing as blank_bottombars().
+	  (David Benbennick)
+  blank_titlebar()
+	- New function used to blank the titlebar in topwin. (DLR)
+  bottombars()
+	- Call blank_bottombars() instead of blank_bottomwin(). (David
+	  Benbennick)
   edit_refresh()
 	- Remove apparently unneeded leaveok() calls. (David Benbennick)
   statusbar()
@@ -163,6 +214,7 @@ CVS code -
 	- Use napms() instead of nanosleep(), as it does the same thing
 	  (aside from taking an argument in milliseconds instead of
 	  microseconds) and curses includes it. (DLR)
+	- Overhaul for efficiency. (David Benbennick)
 - configure.ac:
 	- Add tests for isblank() and strcasestr(), and define
 	  _GNU_SOURCE so that the tests work properly.  Increase the
@@ -171,6 +223,8 @@ CVS code -
 	  fewer lines than usual, so as to make them easier to read, and
 	  remove unnecessary inclusion of stdio.h in the slang test
 	  programs. (DLR)
+	- Remove the checks for resizeterm() and wresize(), as they're
+	  no longer needed. (DLR)
 - faq.html:
 	- Removed question about the NumLock glitch, as it's no longer
 	  needed. (DLR)
diff --git a/src/files.c b/src/files.c
index bd75be9f8d7df6bb0be33e155c19be74fb398081..d0a803839d11f24fb331f3b9d712e39d0a578f53 100644
--- a/src/files.c
+++ b/src/files.c
@@ -105,7 +105,8 @@ void new_file(void)
 #endif
 }
 
-filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len)
+filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
+	len)
 {
     filestruct *fileptr = (filestruct *)nmalloc(sizeof(filestruct));
 
@@ -2454,7 +2455,7 @@ int diralphasort(const void *va, const void *vb)
 }
 
 /* Free our malloc()ed memory */
-void free_charptrarray(char **array, int len)
+void free_charptrarray(char **array, size_t len)
 {
     for (; len > 0; len--)
 	free(array[len - 1]);
diff --git a/src/nano.c b/src/nano.c
index 98af0de60125167fcc37b0be40514c1d87f358aa..ac55a3a43d2aac54e0b424cefbb4a71e61ab3cf3 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -25,7 +25,6 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <signal.h>
-#include <setjmp.h>
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
@@ -54,6 +53,10 @@
 #include <getopt.h>
 #endif
 
+#ifndef NANO_SMALL
+#include <setjmp.h>
+#endif
+
 #ifndef DISABLE_WRAPJUSTIFY
 static int fill = 0;	/* Fill - where to wrap lines, basically */
 #endif
@@ -65,21 +68,22 @@ static int same_line_wrap = 0;	/* Whether wrapped text should be
 static struct termios oldterm;	/* The user's original term settings */
 static struct sigaction act;	/* For all our fun signal handlers */
 
+#ifndef NANO_SMALL
 static sigjmp_buf jmpbuf;	/* Used to return to mainloop after SIGWINCH */
+#endif
 
 /* What we do when we're all set to exit */
 RETSIGTYPE finish(int sigage)
 {
-    if (!ISSET(NO_HELP)) {
-	mvwaddstr(bottomwin, 1, 0, hblank);
-	mvwaddstr(bottomwin, 2, 0, hblank);
-    } else
-	mvwaddstr(bottomwin, 0, 0, hblank);
+    if (!ISSET(NO_HELP))
+	blank_bottombars();
+    else
+	blank_statusbar();
 
     wrefresh(bottomwin);
     endwin();
 
-    /* Restore the old term settings */
+    /* Restore the old terminal settings. */
     tcsetattr(0, TCSANOW, &oldterm);
 
 #if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
@@ -102,7 +106,7 @@ void die(const char *msg, ...)
     endwin();
     curses_ended = TRUE;
 
-    /* Restore the old term settings */
+    /* Restore the old terminal settings. */
     tcsetattr(0, TCSANOW, &oldterm);
 
     va_start(ap, msg);
@@ -241,7 +245,7 @@ void window_init(void)
     edit = newwin(editwinrows, COLS, 2, 0);
     bottomwin = newwin(3 - no_help(), COLS, LINES - 3 + no_help(), 0);
 
-    /* Turn the keypad on in the windows we'll be reading input from. */
+    /* Turn the keypad back on. */
     keypad(edit, TRUE);
     keypad(bottomwin, TRUE);
 }
@@ -758,13 +762,6 @@ void version(void)
     printf("\n");
 }
 
-/* Stuff we do when we abort from programs and want to clean up the
- * screen.  This doesn't do much right now. */
-void do_early_abort(void)
-{
-    blank_statusbar_refresh();
-}
-
 int no_help(void)
 {
     return ISSET(NO_HELP) ? 2 : 0;
@@ -792,13 +789,10 @@ int open_pipe(const char *command)
     FILE *f;
     struct sigaction oldaction, newaction;
 			/* original and temporary handlers for SIGINT */
-#ifdef _POSIX_VDISABLE
-    struct termios term, newterm;
-#endif /* _POSIX_VDISABLE */
     int cancel_sigs = 0;
     /* cancel_sigs == 1 means that sigaction() failed without changing
      * the signal handlers.  cancel_sigs == 2 means the signal handler
-     * was changed, but the tcsetattr didn't succeed.
+     * was changed, but the tcsetattr() didn't succeed.
      *
      * I use this variable since it is important to put things back when
      * we finish, even if we get errors. */
@@ -834,6 +828,9 @@ int open_pipe(const char *command)
 
     /* Before we start reading the forked command's output, we set
      * things up so that ^C will cancel the new process. */
+
+    enable_signals();
+
     if (sigaction(SIGINT, NULL, &newaction) == -1) {
 	cancel_sigs = 1;
 	nperror("sigaction");
@@ -847,24 +844,6 @@ int open_pipe(const char *command)
     /* Note that now oldaction is the previous SIGINT signal handler,
      * to be restored later. */
 
-    /* See if the platform supports disabling individual control
-     * characters. */
-#ifdef _POSIX_VDISABLE
-    if (cancel_sigs == 0 && tcgetattr(0, &term) == -1) {
-	cancel_sigs = 2;
-	nperror("tcgetattr");
-    }
-    if (cancel_sigs == 0) {
-	newterm = term;
-	/* Grab oldterm's VINTR key :-) */
-	newterm.c_cc[VINTR] = oldterm.c_cc[VINTR];
-	if (tcsetattr(0, TCSANOW, &newterm) == -1) {
-	    cancel_sigs = 2;
-	    nperror("tcsetattr");
-	}
-    }
-#endif   /* _POSIX_VDISABLE */
-
     f = fdopen(fd[0], "rb");
     if (f == NULL)
       nperror("fdopen");
@@ -878,14 +857,11 @@ int open_pipe(const char *command)
     if (wait(NULL) == -1)
 	nperror("wait");
 
-#ifdef _POSIX_VDISABLE
-    if (cancel_sigs == 0 && tcsetattr(0, TCSANOW, &term) == -1)
-	nperror("tcsetattr");
-#endif   /* _POSIX_VDISABLE */
-
     if (cancel_sigs != 1 && sigaction(SIGINT, &oldaction, NULL) == -1)
 	nperror("sigaction");
 
+    disable_signals();
+
     return 0;
 }
 #endif /* !NANO_SMALL */
@@ -2769,10 +2745,6 @@ int do_exit(void)
 
 void signal_init(void)
 {
-#ifdef _POSIX_VDISABLE
-    struct termios term;
-#endif
-
     /* Trap SIGINT and SIGQUIT because we want them to do useful
      * things. */
     memset(&act, 0, sizeof(struct sigaction));
@@ -2792,31 +2764,10 @@ void signal_init(void)
     allow_pending_sigwinch(FALSE);
 #endif
 
-#ifdef _POSIX_VDISABLE
-    tcgetattr(0, &term);
-
-    if (!ISSET(PRESERVE)) {
-	/* Trap XOFF (^S) and XON (^Q), much to Chris' chagrin, because
-	 * we want to block them. */
-	term.c_cc[VSTOP] = _POSIX_VDISABLE;
-	term.c_cc[VSTART] = _POSIX_VDISABLE;
-    }
-#ifdef VDSUSP
-    /* Trap delayed suspend (^Y) so we can handle it ourselves. */
-    term.c_cc[VDSUSP] = _POSIX_VDISABLE;
-#endif
-
-#endif /* _POSIX_VDISABLE */
-
+    /* Trap normal suspend (^Z) so we can handle it ourselves. */
     if (!ISSET(SUSPEND)) {
-        /* Trap normal suspend (^Z) so we can handle it ourselves.  If
-	 * we can't trap the key, trap the signal instead.  Insane! */
-#ifdef _POSIX_VDISABLE
-	term.c_cc[VSUSP] = _POSIX_VDISABLE;
-#else
 	act.sa_handler = SIG_IGN;
 	sigaction(SIGTSTP, &act, NULL);
-#endif
     } else {
 	/* Block all other signals in the suspend and continue handlers.
 	 * If we don't do this, other stuff interrupts them! */
@@ -2828,54 +2779,44 @@ void signal_init(void)
 	act.sa_handler = do_cont;
 	sigaction(SIGCONT, &act, NULL);
     }
-
-#ifdef _POSIX_VDISABLE
-    tcsetattr(0, TCSANOW, &term);
-#endif
 }
 
-/* Handler for SIGHUP and SIGTERM. */
+/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
 RETSIGTYPE handle_hupterm(int signal)
 {
     die(_("Received SIGHUP or SIGTERM\n"));
 }
 
-/* What do we do when we catch the suspend signal */
+/* Handler for SIGTSTP (suspend). */
 RETSIGTYPE do_suspend(int signal)
 {
     endwin();
     printf("\n\n\n\n\n%s\n", _("Use \"fg\" to return to nano"));
     fflush(stdout);
 
-    /* Restore the terminal settings for the disabled keys */
+    /* Restore the old terminal settings. */
     tcsetattr(0, TCSANOW, &oldterm);
 
     /* Trap SIGHUP and SIGTERM so we can properly deal with them while
-       suspended */
+     * suspended. */
     act.sa_handler = handle_hupterm;
     sigaction(SIGHUP, &act, NULL);
     sigaction(SIGTERM, &act, NULL);
 
-    /* We used to re-enable the default SIG_DFL and raise SIGTSTP, but 
-       then we could be (and were) interrupted in the middle of the call.
-       So we do it the mutt way instead */
+    /* Do what mutt does: send ourselves a SIGSTOP. */
     kill(0, SIGSTOP);
 }
 
-/* Restore the suspend handler when we come back into the prog */
+/* Handler for SIGCONT (continue after suspend). */
 RETSIGTYPE do_cont(int signal)
 {
-    /* Now we just update the screen instead of having to reenable the
-     * SIGTSTP handler. */
-    doupdate();
-
 #ifndef NANO_SMALL
-    /* Perhaps the user resized the window while we slept. */
+    /* Perhaps the user resized the window while we slept.  Handle it
+     * and update the screen in the process. */
     handle_sigwinch(0);
 #else
-    /* Set up the signal handlers again, so that the special control
-     * keys all work the same as before. */
-    signal_init();
+    /* Just update the screen. */
+    doupdate();
 #endif
 }
 
@@ -2919,45 +2860,35 @@ void handle_sigwinch(int s)
     memset(hblank, ' ', COLS);
     hblank[COLS] = '\0';
 
-#ifdef HAVE_RESIZETERM
-    resizeterm(LINES, COLS);
-#ifdef HAVE_WRESIZE
-    if (wresize(topwin, 2, COLS) == ERR)
-	die(_("Cannot resize top win"));
-    if (mvwin(topwin, 0, 0) == ERR)
-	die(_("Cannot move top win"));
-    if (wresize(edit, editwinrows, COLS) == ERR)
-	die(_("Cannot resize edit win"));
-    if (mvwin(edit, 2, 0) == ERR)
-	die(_("Cannot move edit win"));
-    if (wresize(bottomwin, 3 - no_help(), COLS) == ERR)
-	die(_("Cannot resize bottom win"));
-    if (mvwin(bottomwin, LINES - 3 + no_help(), 0) == ERR)
-	die(_("Cannot move bottom win"));
-#endif				/* HAVE_WRESIZE */
-#endif				/* HAVE_RESIZETERM */
+#ifdef USE_SLANG
+    /* Slang curses emulation brain damage, part 1: If we just do what
+     * curses does here, it'll only work properly if the resize made the
+     * window smaller.  Do what mutt does: Leave and immediately reenter
+     * Slang screen management mode. */
+    SLsmg_reset_smg();
+    SLsmg_init_smg();
+#else
+    /* Do the equivalent of what Minimum Profit does: Leave and
+     * immediately reenter curses mode. */
+    endwin();
+    refresh();
+#endif
 
-    display_main_list();
+    /* Do the equivalent of what both mutt and Minimum Profit do:
+     * Reinitialize all the windows based on the new screen
+     * dimensions. */
+    window_init();
+
+    /* Redraw the contents of the windows that need it. */
     blank_statusbar();
+    display_main_list();
     total_refresh();
 
     /* Turn cursor back on for sure. */
     curs_set(1);
 
-    /* Put the terminal in cbreak mode (read one character at a time and
-     * interpret the special control keys) if we can selectively disable
-     * the special control keys. */
-#ifdef _POSIX_VDISABLE
-    cbreak();
-#endif
-
-    /* Set up the signal handlers again, so that the special control
-     * keys all work the same as before. */
-    signal_init();
-
-    /* Turn the keypad on in the windows we'll be reading input from. */
-    keypad(edit, TRUE);
-    keypad(bottomwin, TRUE);
+    /* Restore the terminal to its previously saved state. */
+    resetty();
 
     /* Jump back to the main loop. */
     siglongjmp(jmpbuf, 1);
@@ -2993,7 +2924,8 @@ void do_toggle(const toggle *which)
 	break;
 #endif
     case TOGGLE_NOHELP_KEY:
-	wclear(bottomwin);
+	blank_statusbar();
+	blank_bottombars();
 	wrefresh(bottomwin);
 	window_init();
 	edit_refresh();
@@ -3022,6 +2954,46 @@ void do_toggle(const toggle *which)
 }
 #endif /* !NANO_SMALL */
 
+#if !defined(NANO_SMALL) || defined(USE_SLANG)
+void disable_signals(void)
+{
+    struct termios term;
+
+    tcgetattr(0, &term);
+    term.c_lflag &= ~ISIG;
+    tcsetattr(0, TCSANOW, &term);
+}
+#endif
+
+#ifndef NANO_SMALL
+void enable_signals(void)
+{
+    struct termios term;
+
+    tcgetattr(0, &term);
+    term.c_lflag |= ISIG;
+    tcsetattr(0, TCSANOW, &term);
+}
+#endif
+
+void disable_flow_control(void)
+{
+    struct termios term;
+
+    tcgetattr(0, &term);
+    term.c_iflag &= ~(IXON|IXOFF);
+    tcsetattr(0, TCSANOW, &term);
+}
+
+void enable_flow_control(void)
+{
+    struct termios term;
+
+    tcgetattr(0, &term);
+    term.c_iflag |= (IXON|IXOFF);
+    tcsetattr(0, TCSANOW, &term);
+}
+
 int main(int argc, char *argv[])
 {
     int optchr;
@@ -3036,9 +3008,6 @@ int main(int argc, char *argv[])
 #ifndef NANO_SMALL
     const toggle *t;
 #endif
-#ifdef _POSIX_VDISABLE
-    struct termios term;
-#endif
 #ifdef HAVE_GETOPT_LONG
     const struct option long_options[] = {
 	{"help", 0, 0, 'h'},
@@ -3428,36 +3397,35 @@ int main(int argc, char *argv[])
 	    filename = mallocstrcpy(filename, argv[optind]);
     }
 
-    /* Termios initialization stuff: Back up the old settings so that
-     * they can be restored, disable SIGINT on ^C and SIGQUIT on ^\,
-     * since we need them for Cancel and Replace, and disable
-     * implementation-defined input processing. */
+    /* Back up the old terminal settings so that they can be restored. */
     tcgetattr(0, &oldterm);
-#ifdef _POSIX_VDISABLE
-    term = oldterm;
-    term.c_cc[VINTR] = _POSIX_VDISABLE;
-    term.c_cc[VQUIT] = _POSIX_VDISABLE;
-    term.c_lflag &= ~IEXTEN;
-    tcsetattr(0, TCSANOW, &term);
-#endif
 
    /* Curses initialization stuff: Start curses, save the state of the
-    * the terminal mode, disable translation of carriage return (^M)
-    * into newline (^J) so we can catch the Enter key and use ^J for
-    * Justify, put the terminal in cbreak mode (read one character at a
-    * time and interpret the special control keys) if we can selectively
-    * disable the special control keys or raw mode (read one character
-    * at a time and don't interpret the special control keys) if we
-    * can't, and turn off echoing of characters as they're typed. */
+    * terminal mode, put the terminal in raw mode (read one character at
+    * a time and don't interpret the special control keys), disable
+    * translation of carriage return (^M) into newline (^J) so that we
+    * can tell the difference between the Enter key and ^J, and disable
+    * echoing of characters as they're typed.  Finally, if we're in
+    * preserve mode, turn the flow control characters back on. */
     initscr();
-    savetty();
-    nonl();
-#ifdef _POSIX_VDISABLE
-    cbreak();
-#else
     raw();
+#ifdef USE_SLANG
+    /* Slang curses emulation brain damage, part 2: Raw mode acts just
+     * like cbreak mode here and doesn't disable interpretation of the
+     * special control keys.  Work around this by manually disabling
+     * interpretation of the special control keys. */
+    disable_signals();
 #endif
+    nonl();
     noecho();
+    if (ISSET(PRESERVE))
+	enable_flow_control();
+
+#ifndef NANO_SMALL
+    /* Save the terminal's current state, so that we can restore it
+     * after a resize. */
+    savetty();
+#endif
 
     /* Set up the global variables and the shortcuts. */
     global_init(0);
@@ -3511,8 +3479,10 @@ int main(int argc, char *argv[])
     if (startline > 0)
 	do_gotoline(startline, 0);
 
-    /* Return here after a sigwinch */
+#ifndef NANO_SMALL
+    /* Return here after a SIGWINCH. */
     sigsetjmp(jmpbuf, 1);
+#endif
 
     /* SHUT UP GCC! */
     startline = 0;
@@ -3598,13 +3568,12 @@ int main(int argc, char *argv[])
 	if (!keyhandled)
 	    UNSET(KEEP_CUTBUFFER);
 
-#ifdef _POSIX_VDISABLE
 	/* Don't even think about changing this string */
 	if (kbinput == NANO_CONTROL_Q)
 	    statusbar(_("XON ignored, mumble mumble."));
 	if (kbinput == NANO_CONTROL_S)
 	    statusbar(_("XOFF ignored, mumble mumble."));
-#endif
+
 	/* If we're in raw mode or using Alt-Alt-x, we have to catch
 	   Control-S and Control-Q */
 	if (kbinput == NANO_CONTROL_Q || kbinput == NANO_CONTROL_S)
diff --git a/src/nano.h b/src/nano.h
index ffdd6bfd01b000c0c3731f5dc2480a540cb20b36..5f711d04b68d4a6f66bf702ebf03d572428ff6b7 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -54,9 +54,10 @@
 #endif
 
 #ifdef USE_SLANG
-/* Slang support enabled.  Work around Slang's not defining KEY_DC or
- * KEY_IC. */
+/* Slang support enabled. */
 #include <slcurses.h>
+/* Slang curses emulation brain damage, part 3: Slang doesn't define the
+ * curses equivalents of the Insert or Delete keys. */
 #define KEY_DC SL_KEY_DELETE
 #define KEY_IC SL_KEY_IC
 #elif defined(HAVE_NCURSES_H)
diff --git a/src/proto.h b/src/proto.h
index b934c2351f808ae083a057e0ba2f16097fb35d91..0e0ca45aa417aba6400c5a43d5208cb02c0d17cb 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -54,7 +54,7 @@ extern char *quotestr;
 extern char *backup_dir;
 #endif
 
-extern WINDOW *edit, *topwin, *bottomwin;
+extern WINDOW *topwin, *edit, *bottomwin;
 extern char *filename;
 extern struct stat originalfilestat;
 extern char *answer;
@@ -151,7 +151,8 @@ int do_uncut_text(void);
 /* Public functions in files.c */
 void load_file(int update);
 void new_file(void);
-filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len);
+filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
+	len);
 int read_file(FILE *f, const char *filename, int quiet);
 int open_file(const char *filename, int insert, int quiet);
 char *get_next_filename(const char *name);
@@ -202,7 +203,7 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
 const char *tail(const char *foo);
 #ifndef DISABLE_BROWSER
 int diralphasort(const void *va, const void *vb);
-void free_charptrarray(char **array, int len);
+void free_charptrarray(char **array, size_t len);
 void striponedir(char *foo);
 int readable_dir(const char *path);
 char **browser_init(const char *path, int *longest, int *numents);
@@ -268,7 +269,6 @@ void print1opt(const char *shortflag, const char *longflag,
 		const char *desc);
 void usage(void);
 void version(void);
-void do_early_abort(void);
 int no_help(void);
 int nano_disabled_msg(void);
 #ifndef NANO_SMALL
@@ -342,6 +342,14 @@ void allow_pending_sigwinch(int allow);
 #ifndef NANO_SMALL
 void do_toggle(const toggle *which);
 #endif
+#if !defined(NANO_SMALL) || defined(USE_SLANG)
+void disable_signals(void);
+#endif
+#ifndef NANO_SMALL
+void enable_signals(void);
+#endif
+void disable_flow_control(void);
+void enable_flow_control(void);
 
 /* Public functions in rcfile.c */
 #ifdef ENABLE_NANORC
@@ -469,13 +477,13 @@ size_t xplustabs(void);
 size_t actual_x(const char *str, size_t xplus);
 size_t strnlenpt(const char *buf, size_t size);
 size_t strlenpt(const char *buf);
-void blank_bottombars(void);
-void blank_bottomwin(void);
+void blank_titlebar(void);
 void blank_edit(void);
 void blank_statusbar(void);
 void blank_statusbar_refresh(void);
 void check_statblank(void);
-char *display_string(const char *buf, size_t start_col, int len);
+void blank_bottombars(void);
+char *display_string(const char *buf, size_t start_col, size_t len);
 void nanoget_repaint(const char *buf, const char *inputbuf, size_t x);
 int nanogetstr(int allowtabs, const char *buf, const char *def,
 #ifndef NANO_SMALL
@@ -486,8 +494,9 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
 		, int *list
 #endif
 		);
-void set_modified(void);
 void titlebar(const char *path);
+void set_modified(void);
+void statusbar(const char *msg, ...);
 void bottombars(const shortcut *s);
 void onekey(const char *keystroke, const char *desc, int len);
 #ifndef NDEBUG
@@ -511,7 +520,6 @@ int statusq(int allowtabs, const shortcut *s, const char *def,
 int do_yesno(int all, const char *msg);
 int total_refresh(void);
 void display_main_list(void);
-void statusbar(const char *msg, ...);
 int do_cursorpos(int constant);
 int do_cursorpos_void(void);
 int line_len(const char *ptr);
diff --git a/src/winio.c b/src/winio.c
index b1e84b18ef8b4576cd4ce8c6e27239ab9bc0e29e..5fffd4df443c243d9f5925405b8d47f59ec97af1 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -129,14 +129,11 @@ int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len, int
     allow_pending_sigwinch(TRUE);
 #endif
 
-    /* Switch to raw mode if necessary so that we can type ^C, ^Q, ^S,
-     * ^Z, and ^\ (and ^Y on systems supporting delayed suspend) without
-     * getting interrupts, and turn the keypad off so that we don't get
-     * extended keypad values, all of which are outside the ASCII
-     * range. */
-#ifdef _POSIX_VDISABLE
-    raw();
-#endif
+    /* Turn off flow control characters if necessary so that we can type
+     * them in verbatim, and turn the keypad off so that we don't get
+     * extended keypad values outside the ASCII range. */
+    if (ISSET(PRESERVE))
+	disable_flow_control();
     keypad(win, FALSE);
 
     kbinput = wgetch(win);
@@ -165,11 +162,10 @@ int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len, int
 	nodelay(win, FALSE);
     }
 
-    /* Switch back to cbreak mode if necessary and turn the keypad back
-     * on now that we're done. */
-#ifdef _POSIX_VDISABLE
-    cbreak();
-#endif
+    /* Turn flow control characters back on if necessary and turn the
+     * keypad back on now that we're done. */
+    if (ISSET(PRESERVE))
+	enable_flow_control();
     keypad(win, TRUE);
 
 #ifndef NANO_SMALL
@@ -1096,26 +1092,14 @@ size_t strlenpt(const char *buf)
     return strnlenpt(buf, (size_t)-1);
 }
 
-void blank_bottombars(void)
+void blank_titlebar(void)
 {
-    if (!ISSET(NO_HELP)) {
-	mvwaddstr(bottomwin, 1, 0, hblank);
-	mvwaddstr(bottomwin, 2, 0, hblank);
-    }
-}
-
-void blank_bottomwin(void)
-{
-    if (ISSET(NO_HELP))
-	return;
-
-    mvwaddstr(bottomwin, 1, 0, hblank);
-    mvwaddstr(bottomwin, 2, 0, hblank);
+    mvwaddstr(topwin, 0, 0, hblank);
 }
 
 void blank_edit(void)
 {
-    int i;
+    size_t i;
     for (i = 0; i < editwinrows; i++)
 	mvwaddstr(edit, i, 0, hblank);
 }
@@ -1141,12 +1125,20 @@ void check_statblank(void)
     }
 }
 
+void blank_bottombars(void)
+{
+    if (!ISSET(NO_HELP)) {
+	mvwaddstr(bottomwin, 1, 0, hblank);
+	mvwaddstr(bottomwin, 2, 0, hblank);
+    }
+}
+
 /* Convert buf into a string that can be displayed on screen.  The
  * caller wants to display buf starting with column start_col, and
  * extending for at most len columns.  start_col is zero-based.  len is
  * one-based, so len == 0 means you get "" returned.  The returned
  * string is dynamically allocated, and should be freed. */
-char *display_string(const char *buf, size_t start_col, int len)
+char *display_string(const char *buf, size_t start_col, size_t len)
 {
     size_t start_index;
 	/* Index in buf of first character shown in return value. */
@@ -1539,16 +1531,6 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
 	return 0;
 }
 
-/* If modified is not already set, set it and update titlebar. */
-void set_modified(void)
-{
-    if (!ISSET(MODIFIED)) {
-	SET(MODIFIED);
-	titlebar(NULL);
-	wrefresh(topwin);
-    }
-}
-
 void titlebar(const char *path)
 {
     int namelen, space;
@@ -1559,7 +1541,7 @@ void titlebar(const char *path)
 
     wattron(topwin, A_REVERSE);
 
-    mvwaddstr(topwin, 0, 0, hblank);
+    blank_titlebar();
     mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3);
 
     space = COLS - sizeof(VERMSG) - 23;
@@ -1597,6 +1579,64 @@ void titlebar(const char *path)
     reset_cursor();
 }
 
+/* If modified is not already set, set it and update titlebar. */
+void set_modified(void)
+{
+    if (!ISSET(MODIFIED)) {
+	SET(MODIFIED);
+	titlebar(NULL);
+	wrefresh(topwin);
+    }
+}
+
+void statusbar(const char *msg, ...)
+{
+    va_list ap;
+
+    va_start(ap, msg);
+
+    /* Curses mode is turned off.  If we use wmove() now, it will muck
+     * up the terminal settings.  So we just use vfprintf(). */
+    if (curses_ended) {
+	vfprintf(stderr, msg, ap);
+	va_end(ap);
+	return;
+    }
+
+    /* Blank out the line. */
+    blank_statusbar();
+
+    if (COLS >= 4) {
+	char *bar;
+	char *foo;
+	size_t start_x = 0, foo_len;
+	bar = charalloc(COLS - 3);
+	vsnprintf(bar, COLS - 3, msg, ap);
+	va_end(ap);
+	foo = display_string(bar, 0, COLS - 4);
+	free(bar);
+	foo_len = strlen(foo);
+	start_x = (COLS - foo_len - 4) / 2;
+
+	wmove(bottomwin, 0, start_x);
+	wattron(bottomwin, A_REVERSE);
+
+	waddstr(bottomwin, "[ ");
+	waddstr(bottomwin, foo);
+	free(foo);
+	waddstr(bottomwin, " ]");
+	wattroff(bottomwin, A_REVERSE);
+	wnoutrefresh(bottomwin);
+	reset_cursor();
+	wrefresh(edit);
+	    /* Leave the cursor at its position in the edit window, not
+	     * in the statusbar. */
+    }
+
+    SET(DISABLE_CURPOS);
+    statblank = 26;
+}
+
 void bottombars(const shortcut *s)
 {
     int i, j, numcols;
@@ -1620,7 +1660,7 @@ void bottombars(const shortcut *s)
     /* There will be this many columns of shortcuts */
     numcols = (slen + (slen % 2)) / 2;
 
-    blank_bottomwin();
+    blank_bottombars();
 
     for (i = 0; i < numcols; i++) {
 	for (j = 0; j <= 1; j++) {
@@ -2370,15 +2410,15 @@ int do_yesno(int all, const char *msg)
 
 int total_refresh(void)
 {
-    clearok(edit, TRUE);
     clearok(topwin, TRUE);
+    clearok(edit, TRUE);
     clearok(bottomwin, TRUE);
-    wnoutrefresh(edit);
     wnoutrefresh(topwin);
+    wnoutrefresh(edit);
     wnoutrefresh(bottomwin);
     doupdate();
-    clearok(edit, FALSE);
     clearok(topwin, FALSE);
+    clearok(edit, FALSE);
     clearok(bottomwin, FALSE);
     edit_refresh();
     titlebar(NULL);
@@ -2390,62 +2430,13 @@ void display_main_list(void)
     bottombars(main_list);
 }
 
-void statusbar(const char *msg, ...)
-{
-    va_list ap;
-
-    va_start(ap, msg);
-
-    /* Curses mode is turned off.  If we use wmove() now, it will muck
-     * up the terminal settings.  So we just use vfprintf(). */
-    if (curses_ended) {
-	vfprintf(stderr, msg, ap);
-	va_end(ap);
-	return;
-    }
-
-    /* Blank out the line. */
-    blank_statusbar();
-
-    if (COLS >= 4) {
-	char *bar;
-	char *foo;
-	int start_x = 0;
-	size_t foo_len;
-	bar = charalloc(COLS - 3);
-	vsnprintf(bar, COLS - 3, msg, ap);
-	va_end(ap);
-	foo = display_string(bar, 0, COLS - 4);
-	free(bar);
-	foo_len = strlen(foo);
-	start_x = (COLS - foo_len - 4) / 2;
-
-	wmove(bottomwin, 0, start_x);
-	wattron(bottomwin, A_REVERSE);
-
-	waddstr(bottomwin, "[ ");
-	waddstr(bottomwin, foo);
-	free(foo);
-	waddstr(bottomwin, " ]");
-	wattroff(bottomwin, A_REVERSE);
-	wnoutrefresh(bottomwin);
-	reset_cursor();
-	wrefresh(edit);
-	    /* Leave the cursor at its position in the edit window, not
-	     * in the statusbar. */
-    }
-
-    SET(DISABLE_CURPOS);
-    statblank = 26;
-}
-
-/* If constant is false, the user typed ^C so we unconditionally display
+/* If constant is FALSE, the user typed ^C so we unconditionally display
  * the cursor position.  Otherwise, we display it only if the character
  * position changed, and DISABLE_CURPOS is not set.
  *
- * If constant and DISABLE_CURPOS is set, we unset it and update old_i and
- * old_totsize.  That way, we leave the current statusbar alone, but next
- * time we will display. */
+ * If constant is TRUE and DISABLE_CURPOS is set, we unset it and update
+ * old_i and old_totsize.  That way, we leave the current statusbar
+ * alone, but next time we will display. */
 int do_cursorpos(int constant)
 {
     const filestruct *fileptr;
@@ -2533,7 +2524,7 @@ int line_len(const char *ptr)
 int do_help(void)
 {
     int i, page = 0, kbinput = ERR, meta_key, no_more = 0;
-    int no_help_flag = 0;
+    int no_help_flag = FALSE;
     const shortcut *oldshortcut;
 
     blank_edit();
@@ -2553,7 +2544,7 @@ int do_help(void)
 
 	/* Well, if we're going to do this, we should at least do it the
 	 * right way. */
-	no_help_flag = 1;
+	no_help_flag = TRUE;
 	UNSET(NO_HELP);
 	window_init();
 	bottombars(help_list);
@@ -2701,17 +2692,13 @@ void dump_buffer_reverse(void)
 /* Easter egg: Display credits.  Assume nodelay(edit) is FALSE. */
 void do_credits(void)
 {
-    int i, j = 0, k, place = 0, start_x;
-
-    const char *what;
-    const char *xlcredits[XLCREDIT_LEN];
-
-    const char *credits[CREDIT_LEN] = { 
-	"0",				/* "The nano text editor" */
-	"1",				/* "version" */
+    int crpos = 0, xlpos = 0;
+    const char *credits[CREDIT_LEN] = {
+	NULL,				/* "The nano text editor" */
+	NULL,				/* "version" */
 	VERSION,
 	"",
-	"2",				/* "Brought to you by:" */
+	NULL,				/* "Brought to you by:" */
 	"Chris Allegretta",
 	"Jordi Mallach",
 	"Adam Rogoyski",
@@ -2734,80 +2721,82 @@ void do_credits(void)
 	"Ryan Krebs",
 	"Albert Chin",
 	"",
-	"3",				/* "Special thanks to:" */
+	NULL,				/* "Special thanks to:" */
 	"Plattsburgh State University",
 	"Benet Laboratories",
 	"Amy Allegretta",
 	"Linda Young",
 	"Jeremy Robichaud",
 	"Richard Kolb II",
-	"4",				/* "The Free Software Foundation" */
+	NULL,				/* "The Free Software Foundation" */
 	"Linus Torvalds",
-	"5",				/* "For ncurses:" */
+	NULL,				/* "For ncurses:" */
 	"Thomas Dickey",
 	"Pavel Curtis",
 	"Zeyd Ben-Halim",
 	"Eric S. Raymond",
-	"6",				/* "and anyone else we forgot..." */
-	"7",				/* "Thank you for using nano!\n" */
-	"", "", "", "",
+	NULL,				/* "and anyone else we forgot..." */
+	NULL,				/* "Thank you for using nano!" */
+	"",
+	"",
+	"",
+	"",
 	"(c) 1999-2004 Chris Allegretta",
-	"", "", "", "",
+	"",
+	"",
+	"",
+	"",
 	"http://www.nano-editor.org/"
     };
 
-    xlcredits[0] = _("The nano text editor");
-    xlcredits[1] = _("version ");
-    xlcredits[2] = _("Brought to you by:");
-    xlcredits[3] = _("Special thanks to:");
-    xlcredits[4] = _("The Free Software Foundation");
-    xlcredits[5] = _("For ncurses:");
-    xlcredits[6] = _("and anyone else we forgot...");
-    xlcredits[7] = _("Thank you for using nano!\n");
+    const char *xlcredits[XLCREDIT_LEN] = {
+	_("The nano text editor"),
+	_("version"),
+	_("Brought to you by:"),
+	_("Special thanks to:"),
+	_("The Free Software Foundation"),
+	_("For ncurses:"),
+	_("and anyone else we forgot..."),
+	_("Thank you for using nano!")
+    };
 
     curs_set(0);
     nodelay(edit, TRUE);
-    blank_bottombars();
-    mvwaddstr(topwin, 0, 0, hblank);
+    scrollok(edit, TRUE);
+    blank_titlebar();
     blank_edit();
+    blank_statusbar();
+    blank_bottombars();
+    wrefresh(topwin);
     wrefresh(edit);
     wrefresh(bottomwin);
-    wrefresh(topwin);
 
-    while (wgetch(edit) == ERR) {
-	for (k = 0; k <= 1; k++) {
-	    blank_edit();
-	    for (i = editwinrows / 2 - 1; i >= (editwinrows / 2 - 1 - j);
-		 i--) {
-		mvwaddstr(edit, i * 2 - k, 0, hblank);
-
-		if (place - (editwinrows / 2 - 1 - i) < CREDIT_LEN) {
-		    what = credits[place - (editwinrows / 2 - 1 - i)];
-
-		    /* God I've missed hacking.  If what is exactly
-			1 char long, it's a sentinel for a translated
-			string, so use that instead.  This means no
-			thanking people with 1 character long names ;-) */
-		    if (strlen(what) == 1)
-			what = xlcredits[atoi(what)];
-		} else
-		    what = "";
-
-		start_x = COLS / 2 - strlen(what) / 2 - 1;
-		mvwaddstr(edit, i * 2 - k, start_x, what);
+    for (crpos = 0; crpos < CREDIT_LEN + editwinrows / 2; crpos++) {
+	if (wgetch(edit) != ERR)
+	    break;
+	if (crpos < CREDIT_LEN) {
+	    const char *what = credits[crpos];
+	    size_t start_x;
+
+	    if (what == NULL) {
+		assert(0 <= xlpos && xlpos < XLCREDIT_LEN);
+		what = xlcredits[xlpos];
+		xlpos++;
 	    }
-	    napms(700);
-	    wrefresh(edit);
+	    start_x = COLS / 2 - strlen(what) / 2 - 1;
+	    mvwaddstr(edit, editwinrows - 1 - editwinrows % 2, start_x, what);
 	}
-	if (j < editwinrows / 2 - 1)
-	    j++;
-
-	place++;
-
-	if (place >= CREDIT_LEN + editwinrows / 2)
+	napms(700);
+	scroll(edit);
+	wrefresh(edit);
+	if (wgetch(edit) != ERR)
 	    break;
+	napms(700);
+	scroll(edit);
+	wrefresh(edit);
     }
 
+    scrollok(edit, FALSE);
     nodelay(edit, FALSE);
     curs_set(1);
     display_main_list();