ncurses 5.6 - patch 20080203
authorThomas E. Dickey <dickey@invisible-island.net>
Sun, 3 Feb 2008 20:52:12 +0000 (20:52 +0000)
committerThomas E. Dickey <dickey@invisible-island.net>
Sun, 3 Feb 2008 20:52:12 +0000 (20:52 +0000)
+ modify _nc_setupscreen() to set the legacy-coding value the same
  for both narrow/wide models.  It had been set only for wide model,
  but is needed to make unctrl() work with locale in the narrow model.
+ improve waddch() and winsch() handling of EILSEQ from mbrtowc() by
  using unctrl() to display illegal bytes rather than trying to append
  further bytes to make up a valid sequence (reported by Andrey A
  Chernov).
+ modify unctrl() to check codes in 128-255 range versus isprint().
  If they are not printable, and locale was set, use a "M-" or "~"
  sequence.
+ improve threading in test/worm.c (wrap refresh calls, and KEY_RESIZE
  handling).  Now it hangs in napms(), no matter whether nanosleep()
  or poll() or select() are used on Linux.

NEWS
dist.mk
ncurses/base/MKunctrl.awk
ncurses/base/lib_addch.c
ncurses/base/lib_insch.c
ncurses/base/lib_set_term.c
test/test.priv.h
test/worm.c

diff --git a/NEWS b/NEWS
index 8c771608fc51f1bf92a768c10303fc941130e5c0..16c55d06e16d23fb743ce4573bec49eaa47a1825 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,7 @@
 -- sale, use or other dealings in this Software without prior written        --
 -- authorization.                                                            --
 -------------------------------------------------------------------------------
 -- sale, use or other dealings in this Software without prior written        --
 -- authorization.                                                            --
 -------------------------------------------------------------------------------
--- $Id: NEWS,v 1.1199 2008/01/19 21:10:02 tom Exp $
+-- $Id: NEWS,v 1.1204 2008/02/03 20:34:02 tom Exp $
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
 -------------------------------------------------------------------------------
 
 This is a log of changes that ncurses has gone through since Zeyd started
@@ -45,6 +45,23 @@ See the AUTHORS file for the corresponding full names.
 Changes through 1.9.9e did not credit all contributions;
 it is not possible to add this information.
 
 Changes through 1.9.9e did not credit all contributions;
 it is not possible to add this information.
 
+20080203
+       + modify _nc_setupscreen() to set the legacy-coding value the same
+         for both narrow/wide models.  It had been set only for wide model,
+         but is needed to make unctrl() work with locale in the narrow model.
+       + improve waddch() and winsch() handling of EILSEQ from mbrtowc() by
+         using unctrl() to display illegal bytes rather than trying to append
+         further bytes to make up a valid sequence (reported by Andrey A
+         Chernov).
+       + modify unctrl() to check codes in 128-255 range versus isprint().
+         If they are not printable, and locale was set, use a "M-" or "~"
+         sequence.
+
+20080126
+       + improve threading in test/worm.c (wrap refresh calls, and KEY_RESIZE
+         handling).  Now it hangs in napms(), no matter whether nanosleep()
+         or poll() or select() are used on Linux.
+
 20080119
        + fixes to build with --disable-ext-funcs
        + add manpage for use_window and use_screen.
 20080119
        + fixes to build with --disable-ext-funcs
        + add manpage for use_window and use_screen.
diff --git a/dist.mk b/dist.mk
index 1dca2a7303693cb942dd32bd73f8d1baf54349b5..6c2b86fa87ef658e179d2921ba6763ac029ede69 100644 (file)
--- a/dist.mk
+++ b/dist.mk
@@ -25,7 +25,7 @@
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
 # use or other dealings in this Software without prior written               #
 # authorization.                                                             #
 ##############################################################################
-# $Id: dist.mk,v 1.625 2008/01/19 18:22:11 tom Exp $
+# $Id: dist.mk,v 1.628 2008/02/03 14:36:09 tom Exp $
 # Makefile for creating ncurses distributions.
 #
 # This only needs to be used directly as a makefile by developers, but
 # Makefile for creating ncurses distributions.
 #
 # This only needs to be used directly as a makefile by developers, but
@@ -37,7 +37,7 @@ SHELL = /bin/sh
 # These define the major/minor/patch versions of ncurses.
 NCURSES_MAJOR = 5
 NCURSES_MINOR = 6
 # These define the major/minor/patch versions of ncurses.
 NCURSES_MAJOR = 5
 NCURSES_MINOR = 6
-NCURSES_PATCH = 20080119
+NCURSES_PATCH = 20080203
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
 
 # We don't append the patch to the version, since this only applies to releases
 VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
index 5d187a8cfb7e790cbce25253d7a27f0465331950..1ba511d72323bf2ffcffe39293c2f8cde1ca99c5 100644 (file)
@@ -1,6 +1,6 @@
-# $Id: MKunctrl.awk,v 1.14 2007/07/28 21:13:21 tom Exp $
+# $Id: MKunctrl.awk,v 1.21 2008/02/03 20:24:30 tom Exp $
 ##############################################################################
 ##############################################################################
-# Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.                #
+# Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.                #
 #                                                                            #
 # Permission is hereby granted, free of charge, to any person obtaining a    #
 # copy of this software and associated documentation files (the "Software"), #
 #                                                                            #
 # Permission is hereby granted, free of charge, to any person obtaining a    #
 # copy of this software and associated documentation files (the "Software"), #
 # authorization.                                                             #
 ##############################################################################
 #
 # authorization.                                                             #
 ##############################################################################
 #
-# Author: Thomas E. Dickey <dickey@clark.net> 1997
+# Author: Thomas E. Dickey (1997-on)
 #
 
 BEGIN  {
                print "/* generated by MKunctrl.awk */"
                print ""
                print "#include <curses.priv.h>"
 #
 
 BEGIN  {
                print "/* generated by MKunctrl.awk */"
                print ""
                print "#include <curses.priv.h>"
+               print "#include <ctype.h>"
+               print ""
+               print "#if USE_WIDEC_SUPPORT"
+               print "#if HAVE_WCTYPE_H"
+               print "#include <wctype.h>"
+               print "#endif"
+               print "#endif"
                print ""
                print "#undef unctrl"
                print ""
                print ""
                print "#undef unctrl"
                print ""
@@ -69,6 +76,12 @@ END  {
                        } else if (ch >= 128 && ch < 160) {
                                part = sprintf("~\\%03o", ch - 64);
                                offset = offset + 3;
                        } else if (ch >= 128 && ch < 160) {
                                part = sprintf("~\\%03o", ch - 64);
                                offset = offset + 3;
+                       } else if (ch == 255) {
+                               part = "~?";
+                               offset = offset + 3;
+                       } else if (ch >= 160) {
+                               part = sprintf("M-\\%03o", ch - 128);
+                               offset = offset + 4;
                        } else {
                                gap = gap " "
                                part = sprintf("\\%03o", ch);
                        } else {
                                gap = gap " "
                                part = sprintf("\\%03o", ch);
@@ -88,14 +101,13 @@ END        {
                blob = blob "\"";
 
                print ""
                blob = blob "\"";
 
                print ""
-               print "#if NCURSES_EXT_FUNCS"
                if (bigstrings) {
                if (bigstrings) {
-                       blob = blob "\n#if NCURSES_EXT_FUNCS"
+                       blob = blob "\n/* printable values in 128-255 range */"
                        printf "static const short unctrl_c1[] = {"
                } else {
                        printf "static const char* const unctrl_c1[] = {"
                }
                        printf "static const short unctrl_c1[] = {"
                } else {
                        printf "static const char* const unctrl_c1[] = {"
                }
-               for ( ch = 128; ch < 160; ch++ ) {
+               for ( ch = 128; ch < 256; ch++ ) {
                        gap = ","
                        if ((ch % 8) == 0) {
                                if (ch != 128)
                        gap = ","
                        if ((ch % 8) == 0) {
                                if (ch != 128)
@@ -111,7 +123,7 @@ END {
                                if (((ch + 1) % 8) != 0)
                                        gap = gap " "
                        } else {
                                if (((ch + 1) % 8) != 0)
                                        gap = gap " "
                        } else {
-                               if (ch >= 128 && ch < 160) {
+                               if (ch >= 128) {
                                        printf "\"\\%03o\"", ch
                                        gap = gap " "
                                }
                                        printf "\"\\%03o\"", ch
                                        gap = gap " "
                                }
@@ -123,8 +135,7 @@ END {
                        }
                }
                print "};"
                        }
                }
                print "};"
-               print "#endif /* NCURSES_EXT_FUNCS */"
-               blob = blob "\"\n#endif /* NCURSES_EXT_FUNCS */\n"
+               blob = blob "\"\n"
 
                print ""
                if (bigstrings) {
 
                print ""
                if (bigstrings) {
@@ -134,22 +145,41 @@ END       {
                } else {
                        stringname = "unctrl"
                }
                } else {
                        stringname = "unctrl"
                }
-               print "\tint check = ChCharOf(ch);"
-               print "\tconst char *result;"
-               print ""
-               print "\tif (check >= 0 && check < (int)SIZEOF(unctrl_table)) {"
-               print "#if NCURSES_EXT_FUNCS"
-               print "\t\tif ((SP != 0)"
-               print "\t\t && (SP->_legacy_coding > 1)"
-               print "\t\t && (check >= 128)"
-               print "\t\t && (check < 160))"
+               print  "\tint check = ChCharOf(ch);"
+               print  "\tconst char *result;"
+               print  ""
+               print  "\tif (check >= 0 && check < (int)SIZEOF(unctrl_table)) {"
+               print  "#if NCURSES_EXT_FUNCS"
+               print  "\t\tif ((SP != 0)"
+               print  "\t\t && (SP->_legacy_coding > 1)"
+               print  "\t\t && (check >= 128)"
+               print  "\t\t && (check < 160))"
+               printf "\t\t\tresult = %s_c1[check - 128];\n", stringname;
+               print  "\t\telse"
+               print  "#if USE_WIDEC_SUPPORT"
+               print  "\t\tif ((check >= 160)"
+               print  "\t\t && (check < 256)"
+               print  "\t\t && ((SP != 0)"
+               print  "\t\t  && ((SP->_legacy_coding > 0)"
+               print  "\t\t   || (SP->_legacy_coding == 0"
+               print  "\t\t       && (isprint(check) || iswprint(check))))))"
+               printf "\t\t\tresult = %s_c1[check - 128];\n", stringname;
+               print  "\t\telse"
+               print  "#else"
+               print  "\t\tif ((check >= 160)"
+               print  "\t\t && (check < 256)"
+               print  "\t\t && ((SP != 0)"
+               print  "\t\t  && ((SP->_legacy_coding > 0)"
+               print  "\t\t   || (SP->_legacy_coding == 0"
+               print  "\t\t       && isprint(check)))))"
                printf "\t\t\tresult = %s_c1[check - 128];\n", stringname;
                printf "\t\t\tresult = %s_c1[check - 128];\n", stringname;
-               print "\t\telse"
-               print "#endif /* NCURSES_EXT_FUNCS */"
+               print  "\t\telse"
+               print  "#endif /* USE_WIDEC_SUPPORT */"
+               print  "#endif /* NCURSES_EXT_FUNCS */"
                printf "\t\t\tresult = %s_table[check];\n", stringname;
                printf "\t\t\tresult = %s_table[check];\n", stringname;
-               print "\t} else {"
-               print "\t\tresult = 0;"
-               print "\t}"
-               print "\treturn (NCURSES_CONST char *)result;"
-               print "}"
+               print  "\t} else {"
+               print  "\t\tresult = 0;"
+               print  "\t}"
+               print  "\treturn (NCURSES_CONST char *)result;"
+               print  "}"
        }
        }
index 9d73edfde5dea44ac6b44450560c8718394a2d8e..1ef6cc5803d3f3dca39cd370d1faad2c57e00fcb 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2006,2008 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -36,7 +36,7 @@
 #include <curses.priv.h>
 #include <ctype.h>
 
 #include <curses.priv.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: lib_addch.c,v 1.104 2006/10/14 20:31:19 tom Exp $")
+MODULE_ID("$Id: lib_addch.c,v 1.108 2008/02/03 18:50:27 tom Exp $")
 
 static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT);
 
 
 static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT);
 
@@ -219,17 +219,15 @@ _nc_build_wch(WINDOW *win, ARG_CH_T ch)
        attr_t attrs = AttrOf(CHDEREF(ch));
        SetChar(CHDEREF(ch), result, attrs);
        WINDOW_EXT(win, addch_used) = 0;
        attr_t attrs = AttrOf(CHDEREF(ch));
        SetChar(CHDEREF(ch), result, attrs);
        WINDOW_EXT(win, addch_used) = 0;
-    } else {
-       if (len == -1) {
-           /*
-            * An error occurred.  We could either discard everything,
-            * or assume that the error was in the previous input.
-            * Try the latter.
-            */
-           TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error"));
-           buffer[0] = CharOf(CHDEREF(ch));
-           WINDOW_EXT(win, addch_used) = 1;
-       }
+    } else if (len == -1) {
+       /*
+        * An error occurred.  We could either discard everything,
+        * or assume that the error was in the previous input.
+        * Try the latter.
+        */
+       TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error"));
+       /* handle this with unctrl() */
+       WINDOW_EXT(win, addch_used) = 0;
     }
     return len;
 }
     }
     return len;
 }
@@ -264,13 +262,16 @@ waddch_literal(WINDOW *win, NCURSES_CH_T ch)
        if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) {
            int len = _nc_build_wch(win, CHREF(ch));
 
        if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) {
            int len = _nc_build_wch(win, CHREF(ch));
 
-           if (len > 0) {
+           if (len >= -1) {
+               /* handle EILSEQ */
                if (is8bits(CharOf(ch))) {
                    const char *s = unctrl((chtype) CharOf(ch));
                    if (s[1] != 0) {
                        return waddstr(win, s);
                    }
                }
                if (is8bits(CharOf(ch))) {
                    const char *s = unctrl((chtype) CharOf(ch));
                    if (s[1] != 0) {
                        return waddstr(win, s);
                    }
                }
+               if (len == -1)
+                   return waddch(win, ' ');
            } else {
                return OK;
            }
            } else {
                return OK;
            }
index b8a856df3a82fc9c0c157b437ab2e8439338727c..9166ea5240e7f3adf62c9631bca98ffd50847dfa 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -43,7 +43,7 @@
 #include <curses.priv.h>
 #include <ctype.h>
 
 #include <curses.priv.h>
 #include <ctype.h>
 
-MODULE_ID("$Id: lib_insch.c,v 1.24 2005/02/26 19:27:28 tom Exp $")
+MODULE_ID("$Id: lib_insch.c,v 1.25 2008/02/03 00:14:37 tom Exp $")
 
 /*
  * Insert the given character, updating the current location to simplify
 
 /*
  * Insert the given character, updating the current location to simplify
@@ -95,7 +95,8 @@ _nc_insert_ch(WINDOW *win, chtype ch)
        } else if (is8bits(ChCharOf(ch)) && iscntrl(ChCharOf(ch))) {
            s = unctrl(ChCharOf(ch));
            while (*s != '\0') {
        } else if (is8bits(ChCharOf(ch)) && iscntrl(ChCharOf(ch))) {
            s = unctrl(ChCharOf(ch));
            while (*s != '\0') {
-               if ((code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s))) != OK)
+               code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s));
+               if (code != OK)
                    break;
                ++s;
            }
                    break;
                ++s;
            }
@@ -107,8 +108,23 @@ _nc_insert_ch(WINDOW *win, chtype ch)
             */
            SetChar2(wch, ch);
            wch = _nc_render(win, wch);
             */
            SetChar2(wch, ch);
            wch = _nc_render(win, wch);
-           if (_nc_build_wch(win, &wch) >= 0)
+           count = _nc_build_wch(win, &wch);
+           if (count > 0) {
                code = wins_wch(win, &wch);
                code = wins_wch(win, &wch);
+           } else if (count == -1) {
+               /* handle EILSEQ */
+               if (is8bits(ch)) {
+                   s = unctrl(ChCharOf(ch));
+                   while (*s != '\0') {
+                       code = _nc_insert_ch(win, ChAttrOf(ch) | UChar(*s));
+                       if (code != OK)
+                           break;
+                       ++s;
+                   }
+               } else {
+                   code = ERR;
+               }
+           }
        }
 #endif
        break;
        }
 #endif
        break;
index 8c15de8b05bf88e6bd080e5fabe191995f641a82..e44850c6a15a2fb81e2eb728a76ca3c2da8e7edd 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -44,7 +44,7 @@
 #include <term.h>              /* cur_term */
 #include <tic.h>
 
 #include <term.h>              /* cur_term */
 #include <tic.h>
 
-MODULE_ID("$Id: lib_set_term.c,v 1.102 2007/12/29 20:36:32 tom Exp $")
+MODULE_ID("$Id: lib_set_term.c,v 1.103 2008/02/03 20:31:08 tom Exp $")
 
 NCURSES_EXPORT(SCREEN *)
 set_term(SCREEN *screenp)
 
 NCURSES_EXPORT(SCREEN *)
 set_term(SCREEN *screenp)
@@ -229,6 +229,7 @@ _nc_setupscreen(int slines GCC_UNUSED,
                bool filtered,
                int slk_format)
 {
                bool filtered,
                int slk_format)
 {
+    char *env;
     int bottom_stolen = 0;
     bool support_cookies = USE_XMC_SUPPORT;
     ripoff_t *rop;
     int bottom_stolen = 0;
     bool support_cookies = USE_XMC_SUPPORT;
     ripoff_t *rop;
@@ -501,13 +502,12 @@ _nc_setupscreen(int slines GCC_UNUSED,
     _nc_init_wacs();
 
     SP->_screen_acs_fix = (_nc_unicode_locale() && _nc_locale_breaks_acs());
     _nc_init_wacs();
 
     SP->_screen_acs_fix = (_nc_unicode_locale() && _nc_locale_breaks_acs());
-    {
-       char *env = _nc_get_locale();
-       SP->_legacy_coding = ((env == 0)
-                             || !strcmp(env, "C")
-                             || !strcmp(env, "POSIX"));
-    }
 #endif
 #endif
+    env = _nc_get_locale();
+    SP->_legacy_coding = ((env == 0)
+                         || !strcmp(env, "C")
+                         || !strcmp(env, "POSIX"));
+    T(("legacy-coding %d", SP->_legacy_coding));
 
     _nc_idcok = TRUE;
     _nc_idlok = FALSE;
 
     _nc_idcok = TRUE;
     _nc_idlok = FALSE;
index 4f472d33a4b90773843597b40f65bea053b74024..5447fa6eae2562ea5824978d392a347661b05348 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -29,7 +29,7 @@
 /****************************************************************************
  *  Author: Thomas E. Dickey                    1996-on                     *
  ****************************************************************************/
 /****************************************************************************
  *  Author: Thomas E. Dickey                    1996-on                     *
  ****************************************************************************/
-/* $Id: test.priv.h,v 1.68 2007/06/30 17:53:09 tom Exp $ */
+/* $Id: test.priv.h,v 1.69 2008/01/26 22:05:48 tom Exp $ */
 
 #ifndef __TEST_PRIV_H
 #define __TEST_PRIV_H 1
 
 #ifndef __TEST_PRIV_H
 #define __TEST_PRIV_H 1
@@ -459,4 +459,21 @@ extern int optind;
                        signal(nsig, handler); \
            }
 
                        signal(nsig, handler); \
            }
 
+/*
+ * Simplify setting up demo of threading with these macros.
+ */
+#if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915) || !NCURSES_EXT_FUNCS
+#define WANT_USE_WINDOW() \
+static int \
+use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data) \
+{ \
+    return func(win, data); \
+}
+#define USING_WINDOW(w,func) use_window(w, (NCURSES_CALLBACK) func, w)
+#else
+#define WANT_USE_WINDOW() /* nothing */
+#define USING_WINDOW(w,func) func(w)
+#endif
+
+
 #endif /* __TEST_PRIV_H */
 #endif /* __TEST_PRIV_H */
index ea407a0c0606827ff629205bfdde8358677ade63..23b0ef4ae85c70792dae3b0ee12d7298942bbba5 100644 (file)
@@ -61,7 +61,7 @@ Options:
   traces will be dumped.  The program stops and waits for one character of
   input at the beginning and end of the interval.
 
   traces will be dumped.  The program stops and waits for one character of
   input at the beginning and end of the interval.
 
-  $Id: worm.c,v 1.53 2008/01/19 20:56:38 tom Exp $
+  $Id: worm.c,v 1.55 2008/01/26 22:07:57 tom Exp $
 */
 
 #include <test.priv.h>
 */
 
 #include <test.priv.h>
@@ -70,6 +70,11 @@ Options:
 #include <pthread.h>
 #endif
 
 #include <pthread.h>
 #endif
 
+WANT_USE_WINDOW();
+
+#define MAX_WORMS      40
+#define MAX_LENGTH     1024
+
 static chtype flavor[] =
 {
     'O', '*', '#', '$', '%', '0', '@',
 static chtype flavor[] =
 {
     'O', '*', '#', '$', '%', '0', '@',
@@ -96,8 +101,9 @@ typedef struct worm {
 static unsigned long sequence = 0;
 static bool quitting = FALSE;
 
 static unsigned long sequence = 0;
 static bool quitting = FALSE;
 
-static WORM worm[40];
+static WORM worm[MAX_WORMS];
 static short **refs;
 static short **refs;
+static int last_x, last_y;
 
 static const char *field;
 static int length = 16, number = 3;
 
 static const char *field;
 static int length = 16, number = 3;
@@ -197,8 +203,7 @@ static const struct options {
 static void
 cleanup(void)
 {
 static void
 cleanup(void)
 {
-    standend();
-    refresh();
+    USING_WINDOW(stdscr, wrefresh);
     curs_set(1);
     endwin();
 }
     curs_set(1);
     endwin();
 }
@@ -227,23 +232,20 @@ draw_worm(WINDOW *win, void *data)
     int y;
     int h;
 
     int y;
     int h;
 
-    int bottom = LINES - 1;
-    int last = COLS - 1;
-
     bool done = FALSE;
 
     if ((x = w->xpos[h = w->head]) < 0) {
     bool done = FALSE;
 
     if ((x = w->xpos[h = w->head]) < 0) {
-       wmove(win, y = w->ypos[h] = bottom, x = w->xpos[h] = 0);
+       wmove(win, y = w->ypos[h] = last_y, x = w->xpos[h] = 0);
        waddch(win, w->attrs);
        refs[y][x]++;
     } else {
        y = w->ypos[h];
     }
 
        waddch(win, w->attrs);
        refs[y][x]++;
     } else {
        y = w->ypos[h];
     }
 
-    if (x > last)
-       x = last;
-    if (y > bottom)
-       y = bottom;
+    if (x > last_x)
+       x = last_x;
+    if (y > last_y)
+       y = last_y;
 
     if (++h == length)
        h = 0;
 
     if (++h == length)
        h = 0;
@@ -263,18 +265,18 @@ draw_worm(WINDOW *win, void *data)
     op = &(x == 0
           ? (y == 0
              ? upleft
     op = &(x == 0
           ? (y == 0
              ? upleft
-             : (y == bottom
+             : (y == last_y
                 ? lowleft
                 : left))
                 ? lowleft
                 : left))
-          : (x == last
+          : (x == last_x
              ? (y == 0
                 ? upright
              ? (y == 0
                 ? upright
-                : (y == bottom
+                : (y == last_y
                    ? lowright
                    : right))
              : (y == 0
                 ? upper
                    ? lowright
                    : right))
              : (y == 0
                 ? upper
-                : (y == bottom
+                : (y == last_y
                    ? lower
                    : normal))))[w->orientation];
 
                    ? lower
                    : normal))))[w->orientation];
 
@@ -307,14 +309,6 @@ draw_worm(WINDOW *win, void *data)
     return done;
 }
 
     return done;
 }
 
-#if !defined(NCURSES_VERSION_PATCH) || (NCURSES_VERSION_PATCH < 20070915) || !NCURSES_EXT_FUNCS
-static int
-use_window(WINDOW *win, int (*func) (WINDOW *, void *), void *data)
-{
-    return func(win, data);
-}
-#endif
-
 #ifdef USE_PTHREADS
 static bool
 quit_worm(void)
 #ifdef USE_PTHREADS
 static bool
 quit_worm(void)
@@ -366,14 +360,40 @@ static int
 get_input(void)
 {
     int ch;
 get_input(void)
 {
     int ch;
-#ifdef USE_PTHREADS
-    ch = use_window(stdscr, (NCURSES_CALLBACK) wgetch, stdscr);
-#else
-    ch = getch();
-#endif
+    ch = USING_WINDOW(stdscr, wgetch);
     return ch;
 }
 
     return ch;
 }
 
+#ifdef KEY_RESIZE
+static int
+update_refs(WINDOW *win)
+{
+    int x, y;
+
+    (void) win;
+    if (last_x != COLS - 1) {
+       for (y = 0; y <= last_y; y++) {
+           refs[y] = typeRealloc(short, COLS, refs[y]);
+           for (x = last_x + 1; x < COLS; x++)
+               refs[y][x] = 0;
+       }
+       last_x = COLS - 1;
+    }
+    if (last_y != LINES - 1) {
+       for (y = LINES; y <= last_y; y++)
+           free(refs[y]);
+       refs = typeRealloc(short *, LINES, refs);
+       for (y = last_y + 1; y < LINES; y++) {
+           refs[y] = typeMalloc(short, COLS);
+           for (x = 0; x < COLS; x++)
+               refs[y][x] = 0;
+       }
+       last_y = LINES - 1;
+    }
+    return OK;
+}
+#endif
+
 int
 main(int argc, char *argv[])
 {
 int
 main(int argc, char *argv[])
 {
@@ -381,7 +401,6 @@ main(int argc, char *argv[])
     int n;
     struct worm *w;
     short *ip;
     int n;
     struct worm *w;
     short *ip;
-    int last, bottom;
     bool done = FALSE;
 
     setlocale(LC_ALL, "");
     bool done = FALSE;
 
     setlocale(LC_ALL, "");
@@ -398,7 +417,7 @@ main(int argc, char *argv[])
        case 'l':
            if (++x == argc)
                goto usage;
        case 'l':
            if (++x == argc)
                goto usage;
-           if ((length = atoi(argv[x])) < 2 || length > 1024) {
+           if ((length = atoi(argv[x])) < 2 || length > MAX_LENGTH) {
                fprintf(stderr, "%s: Invalid length\n", *argv);
                ExitProgram(EXIT_FAILURE);
            }
                fprintf(stderr, "%s: Invalid length\n", *argv);
                ExitProgram(EXIT_FAILURE);
            }
@@ -406,7 +425,7 @@ main(int argc, char *argv[])
        case 'n':
            if (++x == argc)
                goto usage;
        case 'n':
            if (++x == argc)
                goto usage;
-           if ((number = atoi(argv[x])) < 1 || number > 40) {
+           if ((number = atoi(argv[x])) < 1 || number > MAX_WORMS) {
                fprintf(stderr, "%s: Invalid number of worms\n", *argv);
                ExitProgram(EXIT_FAILURE);
            }
                fprintf(stderr, "%s: Invalid number of worms\n", *argv);
                ExitProgram(EXIT_FAILURE);
            }
@@ -439,8 +458,8 @@ main(int argc, char *argv[])
 
     curs_set(0);
 
 
     curs_set(0);
 
-    bottom = LINES - 1;
-    last = COLS - 1;
+    last_y = LINES - 1;
+    last_x = COLS - 1;
 
 #ifdef A_COLOR
     if (has_colors()) {
 
 #ifdef A_COLOR
     if (has_colors()) {
@@ -475,7 +494,7 @@ main(int argc, char *argv[])
 
 #ifdef BADCORNER
     /* if addressing the lower right corner doesn't work in your curses */
 
 #ifdef BADCORNER
     /* if addressing the lower right corner doesn't work in your curses */
-    refs[bottom][last] = 1;
+    refs[last_y][last_x] = 1;
 #endif /* BADCORNER */
 
     for (n = number, w = &worm[0]; --n >= 0; w++) {
 #endif /* BADCORNER */
 
     for (n = number, w = &worm[0]; --n >= 0; w++) {
@@ -501,7 +520,7 @@ main(int argc, char *argv[])
     if (field) {
        const char *p;
        p = field;
     if (field) {
        const char *p;
        p = field;
-       for (y = bottom; --y >= 0;) {
+       for (y = last_y; --y >= 0;) {
            for (x = COLS; --x >= 0;) {
                addch((chtype) (*p++));
                if (!*p)
            for (x = COLS; --x >= 0;) {
                addch((chtype) (*p++));
                if (!*p)
@@ -509,7 +528,7 @@ main(int argc, char *argv[])
            }
        }
     }
            }
        }
     }
-    refresh();
+    USING_WINDOW(stdscr, wrefresh);
     nodelay(stdscr, TRUE);
 
     while (!done) {
     nodelay(stdscr, TRUE);
 
     while (!done) {
@@ -530,29 +549,13 @@ main(int argc, char *argv[])
                generation++;
            }
 #endif
                generation++;
            }
 #endif
+
 #ifdef KEY_RESIZE
            if (ch == KEY_RESIZE) {
 #ifdef KEY_RESIZE
            if (ch == KEY_RESIZE) {
-               if (last != COLS - 1) {
-                   for (y = 0; y <= bottom; y++) {
-                       refs[y] = typeRealloc(short, COLS, refs[y]);
-                       for (x = last + 1; x < COLS; x++)
-                           refs[y][x] = 0;
-                   }
-                   last = COLS - 1;
-               }
-               if (bottom != LINES - 1) {
-                   for (y = LINES; y <= bottom; y++)
-                       free(refs[y]);
-                   refs = typeRealloc(short *, LINES, refs);
-                   for (y = bottom + 1; y < LINES; y++) {
-                       refs[y] = typeMalloc(short, COLS);
-                       for (x = 0; x < COLS; x++)
-                           refs[y][x] = 0;
-                   }
-                   bottom = LINES - 1;
-               }
+               USING_WINDOW(stdscr, update_refs);
            }
 #endif
            }
 #endif
+
            /*
             * Make it simple to put this into single-step mode, or resume
             * normal operation -T.Dickey
            /*
             * Make it simple to put this into single-step mode, or resume
             * normal operation -T.Dickey
@@ -570,7 +573,7 @@ main(int argc, char *argv[])
 
        done = draw_all_worms();
        napms(10);
 
        done = draw_all_worms();
        napms(10);
-       refresh();
+       USING_WINDOW(stdscr, wrefresh);
     }
 
     cleanup();
     }
 
     cleanup();