From a8845f1feadb0b4d906e9040e465b93fd3f72660 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 28 Sep 2014 00:19:13 +0000 Subject: [PATCH] ncurses 5.9 - patch 20140927 + implement curs_set in win_driver.c + implement flash in win_driver.c + fix an infinite loop in win_driver.c if the command-window loses focus. + improve the non-buffered mode, i.e., NCURSES_CONSOLE2, of win_driver.c by temporarily changing the buffer-size to match the window-size to eliminate the scrollback. Also enforce a minimum screen-size of 24x80 in the non-buffered mode. + modify generated misc/Makefile to suppress install.data from the dependencies if the --disable-db-install option is used, compensating for the top-level makefile changes used to add ncurses*-config in the 20140920 changes (report by Steven Honeyman). --- NEWS | 18 ++- configure | 47 ++++--- configure.in | 17 ++- dist.mk | 4 +- form/frm_driver.c | 4 +- misc/Makefile.in | 8 +- ncurses/curses.priv.h | 3 +- ncurses/tinfo/lib_options.c | 12 +- ncurses/tinfo/tinfo_driver.c | 34 ++++- ncurses/trace/visbuf.c | 6 +- ncurses/win32con/win_driver.c | 233 ++++++++++++++++++++++++++----- package/debian-mingw/changelog | 4 +- package/debian-mingw64/changelog | 4 +- package/debian/changelog | 4 +- package/mingw-ncurses.nsi | 4 +- package/mingw-ncurses.spec | 2 +- package/ncurses.spec | 2 +- test/dots_termcap.c | 4 +- 18 files changed, 325 insertions(+), 85 deletions(-) diff --git a/NEWS b/NEWS index 78dc516c..2c74afe8 100644 --- a/NEWS +++ b/NEWS @@ -25,7 +25,7 @@ -- sale, use or other dealings in this Software without prior written -- -- authorization. -- ------------------------------------------------------------------------------- --- $Id: NEWS,v 1.2275 2014/09/20 22:43:35 tom Exp $ +-- $Id: NEWS,v 1.2281 2014/09/27 22:15:56 tom Exp $ ------------------------------------------------------------------------------- This is a log of changes that ncurses has gone through since Zeyd started @@ -45,6 +45,20 @@ 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. +20140927 + + implement curs_set in win_driver.c + + implement flash in win_driver.c + + fix an infinite loop in win_driver.c if the command-window loses + focus. + + improve the non-buffered mode, i.e., NCURSES_CONSOLE2, of + win_driver.c by temporarily changing the buffer-size to match the + window-size to eliminate the scrollback. Also enforce a minimum + screen-size of 24x80 in the non-buffered mode. + + modify generated misc/Makefile to suppress install.data from the + dependencies if the --disable-db-install option is used, compensating + for the top-level makefile changes used to add ncurses*-config in the + 20140920 changes (report by Steven Honeyman). + 20140920 + add ncurses*-config to bin-directory of sample package-scripts. + add check to ensure that getopt is available; this is a problem in @@ -156,7 +170,7 @@ it is not possible to add this information. + add test/dots_curses.c, for comparison with the low-level examples. 20140614 - + fix dereference before null check found by Coverity in tic.c + + fix dereference before null check found by Coverity in tic.c (cf: 20140524). + fix sign-extension bug in read_entry.c which prevented "toe" from reading empty "screen+italics" entry. diff --git a/configure b/configure index 4b2f1315..78167940 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.585 . +# From configure.in Revision: 1.586 . # Guess values for system-dependent variables and create Makefiles. # Generated by Autoconf 2.52.20121002. # @@ -21769,6 +21769,17 @@ xshort|xint|xlong) ;; esac +# substitute into misc/Makefile to suppress +# (un)install.data from the +# (un)install rules. +if test "x$cf_with_db_install" = "xno"; then + MISC_INSTALL_DATA= + MISC_UNINSTALL_DATA= +else + MISC_INSTALL_DATA=install.data + MISC_UNINSTALL_DATA=uninstall.data +fi + SUB_SCRIPTS= ac_config_files="$ac_config_files include/MKterm.h.awk include/curses.head:include/curses.h.in include/ncurses_dll.h include/termcap.h include/unctrl.h $SUB_SCRIPTS $SUB_MAKEFILES Makefile" @@ -21852,7 +21863,7 @@ DEFS=-DHAVE_CONFIG_H : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:21855: creating $CONFIG_STATUS" >&5 +{ echo "$as_me:21866: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL @@ -22028,7 +22039,7 @@ cat >>$CONFIG_STATUS <<\EOF echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header - { { echo "$as_me:22031: error: ambiguous option: $1 + { { echo "$as_me:22042: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} @@ -22047,7 +22058,7 @@ Try \`$0 --help' for more information." >&2;} ac_need_defaults=false;; # This is an error. - -*) { { echo "$as_me:22050: error: unrecognized option: $1 + -*) { { echo "$as_me:22061: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} @@ -22158,7 +22169,7 @@ do "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; "include/ncurses_cfg.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/ncurses_cfg.h:include/ncurses_cfg.hin" ;; - *) { { echo "$as_me:22161: error: invalid argument: $ac_config_target" >&5 + *) { { echo "$as_me:22172: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac @@ -22479,6 +22490,8 @@ s,@PANEL_NAME@,$PANEL_NAME,;t t s,@MENU_NAME@,$MENU_NAME,;t t s,@FORM_NAME@,$FORM_NAME,;t t s,@CXX_NAME@,$CXX_NAME,;t t +s,@MISC_INSTALL_DATA@,$MISC_INSTALL_DATA,;t t +s,@MISC_UNINSTALL_DATA@,$MISC_UNINSTALL_DATA,;t t CEOF EOF @@ -22593,7 +22606,7 @@ done; } esac if test x"$ac_file" != x-; then - { echo "$as_me:22596: creating $ac_file" >&5 + { echo "$as_me:22609: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi @@ -22611,7 +22624,7 @@ echo "$as_me: creating $ac_file" >&6;} -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:22614: error: cannot find input file: $f" >&5 + test -f "$f" || { { echo "$as_me:22627: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; @@ -22624,7 +22637,7 @@ echo "$as_me: error: cannot find input file: $f" >&2;} echo $srcdir/$f else # /dev/null tree - { { echo "$as_me:22627: error: cannot find input file: $f" >&5 + { { echo "$as_me:22640: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; @@ -22640,7 +22653,7 @@ cat >>$CONFIG_STATUS <<\EOF if test -n "$ac_seen"; then ac_used=`grep '@datarootdir@' $ac_item` if test -z "$ac_used"; then - { echo "$as_me:22643: WARNING: datarootdir was used implicitly but not set: + { echo "$as_me:22656: WARNING: datarootdir was used implicitly but not set: $ac_seen" >&5 echo "$as_me: WARNING: datarootdir was used implicitly but not set: $ac_seen" >&2;} @@ -22649,7 +22662,7 @@ $ac_seen" >&2;} fi ac_seen=`grep '${datarootdir}' $ac_item` if test -n "$ac_seen"; then - { echo "$as_me:22652: WARNING: datarootdir was used explicitly but not set: + { echo "$as_me:22665: WARNING: datarootdir was used explicitly but not set: $ac_seen" >&5 echo "$as_me: WARNING: datarootdir was used explicitly but not set: $ac_seen" >&2;} @@ -22686,7 +22699,7 @@ s,@INSTALL@,$ac_INSTALL,;t t ac_init=`egrep '[ ]*'$ac_name'[ ]*=' $ac_file` if test -z "$ac_init"; then ac_seen=`echo "$ac_seen" |sed -e 's,^,'$ac_file':,'` - { echo "$as_me:22689: WARNING: Variable $ac_name is used but was not set: + { echo "$as_me:22702: WARNING: Variable $ac_name is used but was not set: $ac_seen" >&5 echo "$as_me: WARNING: Variable $ac_name is used but was not set: $ac_seen" >&2;} @@ -22697,7 +22710,7 @@ $ac_seen" >&2;} egrep -n '@[A-Z_][A-Z_0-9]+@' $ac_file >>$tmp/out if test -s $tmp/out; then ac_seen=`sed -e 's,^,'$ac_file':,' < $tmp/out` - { echo "$as_me:22700: WARNING: Some variables may not be substituted: + { echo "$as_me:22713: WARNING: Some variables may not be substituted: $ac_seen" >&5 echo "$as_me: WARNING: Some variables may not be substituted: $ac_seen" >&2;} @@ -22746,7 +22759,7 @@ for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue * ) ac_file_in=$ac_file.in ;; esac - test x"$ac_file" != x- && { echo "$as_me:22749: creating $ac_file" >&5 + test x"$ac_file" != x- && { echo "$as_me:22762: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the @@ -22757,7 +22770,7 @@ echo "$as_me: creating $ac_file" >&6;} -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:22760: error: cannot find input file: $f" >&5 + test -f "$f" || { { echo "$as_me:22773: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo $f;; @@ -22770,7 +22783,7 @@ echo "$as_me: error: cannot find input file: $f" >&2;} echo $srcdir/$f else # /dev/null tree - { { echo "$as_me:22773: error: cannot find input file: $f" >&5 + { { echo "$as_me:22786: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; @@ -22828,7 +22841,7 @@ cat >>$CONFIG_STATUS <<\EOF rm -f $tmp/in if test x"$ac_file" != x-; then if cmp -s $ac_file $tmp/config.h 2>/dev/null; then - { echo "$as_me:22831: $ac_file is unchanged" >&5 + { echo "$as_me:22844: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ @@ -23131,7 +23144,7 @@ cf_ITEM=`echo "$cf_item" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQ cygdll|msysdll|mingw) #(vi test "x$with_shared_cxx" = xno && test -n "$verbose" && echo " overriding CXX_MODEL to SHARED" 1>&6 -echo "${as_me:-configure}:23134: testing overriding CXX_MODEL to SHARED ..." 1>&5 +echo "${as_me:-configure}:23147: testing overriding CXX_MODEL to SHARED ..." 1>&5 with_shared_cxx=yes ;; diff --git a/configure.in b/configure.in index f3a5da8e..af15142f 100644 --- a/configure.in +++ b/configure.in @@ -28,14 +28,14 @@ dnl*************************************************************************** dnl dnl Author: Thomas E. Dickey 1995-on dnl -dnl $Id: configure.in,v 1.585 2014/09/20 20:42:49 tom Exp $ +dnl $Id: configure.in,v 1.586 2014/09/23 22:18:46 tom Exp $ dnl Process this file with autoconf to produce a configure script. dnl dnl See http://invisible-island.net/autoconf/ for additional information. dnl dnl --------------------------------------------------------------------------- AC_PREREQ(2.52.20030208) -AC_REVISION($Revision: 1.585 $) +AC_REVISION($Revision: 1.586 $) AC_INIT(ncurses/base/lib_initscr.c) AC_CONFIG_HEADER(include/ncurses_cfg.h:include/ncurses_cfg.hin) @@ -2044,6 +2044,19 @@ xshort|xint|xlong) ;; esac +# substitute into misc/Makefile to suppress +# (un)install.data from the +# (un)install rules. +if test "x$cf_with_db_install" = "xno"; then + MISC_INSTALL_DATA= + MISC_UNINSTALL_DATA= +else + MISC_INSTALL_DATA=install.data + MISC_UNINSTALL_DATA=uninstall.data +fi +AC_SUBST(MISC_INSTALL_DATA) +AC_SUBST(MISC_UNINSTALL_DATA) + SUB_SCRIPTS= AC_OUTPUT( \ diff --git a/dist.mk b/dist.mk index d5683cee..fbc88627 100644 --- a/dist.mk +++ b/dist.mk @@ -25,7 +25,7 @@ # use or other dealings in this Software without prior written # # authorization. # ############################################################################## -# $Id: dist.mk,v 1.1007 2014/09/19 22:03:06 tom Exp $ +# $Id: dist.mk,v 1.1008 2014/09/23 20:52:38 tom Exp $ # 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 = 9 -NCURSES_PATCH = 20140920 +NCURSES_PATCH = 20140927 # We don't append the patch to the version, since this only applies to releases VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR) diff --git a/form/frm_driver.c b/form/frm_driver.c index 160fdeb7..eebde42b 100644 --- a/form/frm_driver.c +++ b/form/frm_driver.c @@ -32,7 +32,7 @@ #include "form.priv.h" -MODULE_ID("$Id: frm_driver.c,v 1.114 2014/07/26 20:46:51 tom Exp $") +MODULE_ID("$Id: frm_driver.c,v 1.115 2014/09/25 21:55:24 tom Exp $") /*---------------------------------------------------------------------------- This is the core module of the form library. It contains the majority @@ -4924,7 +4924,7 @@ _nc_Widen_String(char *source, int *lengthp) { if (pass) { - result[need] = source[passed]; + result[need] = (wchar_t)source[passed]; } ++need; ++passed; diff --git a/misc/Makefile.in b/misc/Makefile.in index 34c9a524..127bb9d8 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -1,6 +1,6 @@ -# $Id: Makefile.in,v 1.61 2013/08/04 20:23:20 tom Exp $ +# $Id: Makefile.in,v 1.62 2014/09/23 22:12:42 tom Exp $ ############################################################################## -# Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. # +# Copyright (c) 1998-2013,2014 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"), # @@ -81,7 +81,7 @@ depend : sources :: terminfo.tmp -install : install.data install.libs +install : @MISC_INSTALL_DATA@ install.libs install.data : terminfo.tmp \ $(DESTDIR)$(libdir) \ @@ -135,7 +135,7 @@ $(DESTDIR)$(tabsetdir) \ $(DESTDIR)$(PKG_CONFIG_LIBDIR) : mkdir -p $@ -uninstall : uninstall.data uninstall.libs +uninstall : @MISC_UNINSTALL_DATA@ uninstall.libs uninstall.data : -test -d $(DESTDIR)$(tabsetdir) && rm -rf $(DESTDIR)$(tabsetdir) diff --git a/ncurses/curses.priv.h b/ncurses/curses.priv.h index 0804b0b9..2c3df406 100644 --- a/ncurses/curses.priv.h +++ b/ncurses/curses.priv.h @@ -34,7 +34,7 @@ ****************************************************************************/ /* - * $Id: curses.priv.h,v 1.539 2014/09/04 22:52:07 tom Exp $ + * $Id: curses.priv.h,v 1.540 2014/09/27 21:44:28 tom Exp $ * * curses.priv.h * @@ -2272,6 +2272,7 @@ typedef struct term_driver { int (*td_kpad)(struct DriverTCB*, int); int (*td_kyOk)(struct DriverTCB*, int, int); bool (*td_kyExist)(struct DriverTCB*, int); + int (*td_cursorSet)(struct DriverTCB*, int); } TERM_DRIVER; typedef struct DriverTCB diff --git a/ncurses/tinfo/lib_options.c b/ncurses/tinfo/lib_options.c index 8e31d484..b736d5fc 100644 --- a/ncurses/tinfo/lib_options.c +++ b/ncurses/tinfo/lib_options.c @@ -46,7 +46,7 @@ #define CUR SP_TERMTYPE #endif -MODULE_ID("$Id: lib_options.c,v 1.77 2014/03/08 20:32:59 tom Exp $") +MODULE_ID("$Id: lib_options.c,v 1.78 2014/09/27 21:55:24 tom Exp $") NCURSES_EXPORT(int) idlok(WINDOW *win, bool flag) @@ -196,11 +196,13 @@ NCURSES_SP_NAME(curs_set) (NCURSES_SP_DCLx int vis) if (SP_PARM != 0 && vis >= 0 && vis <= 2) { int cursor = SP_PARM->_cursor; - bool bBuiltIn = !IsTermInfo(SP_PARM); if (vis == cursor) { code = cursor; } else { - if (!bBuiltIn) { +#ifdef USE_TERM_DRIVER + code = CallDriver_1(SP_PARM, td_cursorSet, vis); +#else + if (IsTermInfo(SP_PARM)) { switch (vis) { case 2: code = NCURSES_PUTP2_FLUSH("cursor_visible", @@ -215,8 +217,10 @@ NCURSES_SP_NAME(curs_set) (NCURSES_SP_DCLx int vis) cursor_invisible); break; } - } else + } else { code = ERR; + } +#endif if (code != ERR) code = (cursor == -1 ? 1 : cursor); SP_PARM->_cursor = vis; diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c index e0f1d015..a17accd3 100644 --- a/ncurses/tinfo/tinfo_driver.c +++ b/ncurses/tinfo/tinfo_driver.c @@ -50,7 +50,7 @@ # endif #endif -MODULE_ID("$Id: tinfo_driver.c,v 1.38 2014/04/26 18:47:20 juergen Exp $") +MODULE_ID("$Id: tinfo_driver.c,v 1.39 2014/09/27 21:58:57 tom Exp $") /* * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, @@ -1298,6 +1298,35 @@ drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int c, int flag) return (code); } +static int +drv_cursorSet(TERMINAL_CONTROL_BLOCK * TCB, int vis) +{ + SCREEN *sp; + int code = ERR; + + AssertTCB(); + SetSP(); + + T((T_CALLED("tinfo:drv_cursorSet(%p,%d)"), (void *) SP_PARM, vis)); + + if (SP_PARM != 0 && IsTermInfo(SP_PARM)) { + switch (vis) { + case 2: + code = NCURSES_PUTP2_FLUSH("cursor_visible", cursor_visible); + break; + case 1: + code = NCURSES_PUTP2_FLUSH("cursor_normal", cursor_normal); + break; + case 0: + code = NCURSES_PUTP2_FLUSH("cursor_invisible", cursor_invisible); + break; + } + } else { + code = ERR; + } + returnCode(code); +} + static bool drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int key) { @@ -1346,5 +1375,6 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = { drv_nap, /* nap */ drv_kpad, /* kpad */ drv_keyok, /* kyOk */ - drv_kyExist /* kyExist */ + drv_kyExist, /* kyExist */ + drv_cursorSet /* cursorSet */ }; diff --git a/ncurses/trace/visbuf.c b/ncurses/trace/visbuf.c index effa8435..fec06439 100644 --- a/ncurses/trace/visbuf.c +++ b/ncurses/trace/visbuf.c @@ -42,12 +42,12 @@ #include #include -MODULE_ID("$Id: visbuf.c,v 1.43 2014/02/23 01:21:08 tom Exp $") +MODULE_ID("$Id: visbuf.c,v 1.44 2014/09/25 08:51:13 tom Exp $") #define NUM_VISBUFS 4 #define NormalLen(len) (size_t) (((size_t)(len) + 1) * 4) -#define WideLen(len) (size_t) (((size_t)(len) + 1) * 4 * MB_CUR_MAX) +#define WideLen(len) (size_t) (((size_t)(len) + 1) * 4 * (size_t) MB_CUR_MAX) #ifdef TRACE static const char d_quote[] = StringOf(D_QUOTE); @@ -69,7 +69,7 @@ _nc_vischar(char *tp, unsigned c LIMIT_ARG) if (c == '"' || c == '\\') { *tp++ = '\\'; *tp++ = (char) c; - } else if (is7bits((int)c) && (isgraph((int)c) || c == ' ')) { + } else if (is7bits((int) c) && (isgraph((int) c) || c == ' ')) { *tp++ = (char) c; } else if (c == '\n') { *tp++ = '\\'; diff --git a/ncurses/win32con/win_driver.c b/ncurses/win32con/win_driver.c index bc883004..5acc6035 100644 --- a/ncurses/win32con/win_driver.c +++ b/ncurses/win32con/win_driver.c @@ -34,9 +34,8 @@ /* * TODO - GetMousePos(POINT * result) from ntconio.c * TODO - implement nodelay - * TODO - implement flash - * TODO - improve screen-repainting, using implied wraparound - * TODO - if non-buffered, change buffer size (temporarily) to window-size - SetConsoleScreenBufferSize + * TODO - improve screen-repainting performance, using implied wraparound to reduce write's + * TODO - make it optional whether screen is restored or not when non-buffered */ #include @@ -48,7 +47,7 @@ #define CUR my_term.type. -MODULE_ID("$Id: win_driver.c,v 1.43 2014/08/09 20:31:40 tom Exp $") +MODULE_ID("$Id: win_driver.c,v 1.51 2014/09/27 22:17:36 tom Exp $") #ifndef __GNUC__ # error We need GCC to compile for MinGW @@ -69,6 +68,14 @@ MODULE_ID("$Id: win_driver.c,v 1.43 2014/08/09 20:31:40 tom Exp $") #define AdjustY() (CON.buffered ? 0 : (int) CON.SBI.srWindow.Top) +#if USE_WIDEC_SUPPORT +#define write_screen WriteConsoleOutputW +#define read_screen ReadConsoleOutputW +#else +#define write_screen WriteConsoleOutput +#define read_screen ReadConsoleOutput +#endif + static const LONG keylist[] = { GenMap(VK_PRIOR, KEY_PPAGE), @@ -111,6 +118,8 @@ static struct { COORD save_size; SMALL_RECT save_region; CONSOLE_SCREEN_BUFFER_INFO SBI; + CONSOLE_SCREEN_BUFFER_INFO save_SBI; + CONSOLE_CURSOR_INFO save_CI; } CON; static BOOL console_initialized = FALSE; @@ -130,6 +139,11 @@ MapColor(bool fore, int color) return (WORD) a; } +#define RevAttr(attr) \ + (WORD) (((attr) & 0xff00) | \ + ((((attr) & 0x07) << 4) | \ + (((attr) & 0x70) >> 4))) + static WORD MapAttr(WORD res, attr_t ch) { @@ -145,16 +159,11 @@ MapAttr(WORD res, attr_t ch) } if (ch & A_REVERSE) { - res = (WORD) ((res & 0xff00) | - (((res & 0x07) << 4) | - ((res & 0x70) >> 4))); + res = RevAttr(res); } if (ch & A_STANDOUT) { - res = (WORD) ((res & 0xff00) | - (((res & 0x07) << 4) | - ((res & 0x70) >> 4)) | - BACKGROUND_INTENSITY); + res = RevAttr(res) | BACKGROUND_INTENSITY; } if (ch & A_BOLD) @@ -189,11 +198,11 @@ dump_screen(const char *fn, int ln) bufferCoord.X = bufferCoord.Y = 0; - if (ReadConsoleOutput(CON.hdl, - save_screen, - save_size, - bufferCoord, - &save_region)) { + if (read_screen(CON.hdl, + save_screen, + save_size, + bufferCoord, + &save_region)) { int i, j; int ij = 0; int k = 0; @@ -272,7 +281,7 @@ con_write16(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, cchar_t *str, int limit) rec.Right = (SHORT) (x + limit - 1); rec.Bottom = rec.Top; - return WriteConsoleOutputW(CON.hdl, ci, siz, loc, &rec); + return write_screen(CON.hdl, ci, siz, loc, &rec); } #define con_write(tcb, y, x, str, n) con_write16(tcb, y, x, str, n) #else @@ -311,7 +320,7 @@ con_write8(TERMINAL_CONTROL_BLOCK * TCB, int y, int x, chtype *str, int n) rec.Right = (short) (x + n - 1); rec.Bottom = rec.Top; - return WriteConsoleOutput(CON.hdl, ci, siz, loc, &rec); + return write_screen(CON.hdl, ci, siz, loc, &rec); } #define con_write(tcb, y, x, str, n) con_write8(tcb, y, x, str, n) #endif @@ -413,13 +422,14 @@ restore_original_screen(void) T(("... restoring %s", CON.window_only ? "window" : "entire buffer")); - bufferCoord.X = bufferCoord.Y = 0; + bufferCoord.X = (SHORT) (CON.window_only ? CON.SBI.srWindow.Left : 0); + bufferCoord.Y = (SHORT) (CON.window_only ? CON.SBI.srWindow.Top : 0); - if (WriteConsoleOutput(CON.hdl, - CON.save_screen, - CON.save_size, - bufferCoord, - &save_region)) { + if (write_screen(CON.hdl, + CON.save_screen, + CON.save_size, + bufferCoord, + &save_region)) { result = TRUE; mvcur(-1, -1, LINES - 2, 0); T(("... restore original screen contents ok %dx%d (%d,%d - %d,%d)", @@ -631,15 +641,57 @@ wcon_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, static int wcon_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, - int beepFlag GCC_UNUSED) + int beepFlag) { SCREEN *sp; int res = OK; + int high = (CON.SBI.srWindow.Bottom - CON.SBI.srWindow.Top + 1); + int wide = (CON.SBI.srWindow.Right - CON.SBI.srWindow.Left + 1); + int max_cells = (high * wide); + int i; + + CHAR_INFO this_screen[max_cells]; + CHAR_INFO that_screen[max_cells]; + COORD this_size; + SMALL_RECT this_region; + COORD bufferCoord; + AssertTCB(); + SetSP(); - MessageBeep(MB_ICONWARNING); /* MB_OK might be better */ + this_region.Top = CON.SBI.srWindow.Top; + this_region.Left = CON.SBI.srWindow.Left; + this_region.Bottom = CON.SBI.srWindow.Bottom; + this_region.Right = CON.SBI.srWindow.Right; + + this_size.X = (SHORT) wide; + this_size.Y = (SHORT) high; + + bufferCoord.X = this_region.Left; + bufferCoord.Y = this_region.Top; + + if (!beepFlag && + read_screen(CON.hdl, + this_screen, + this_size, + bufferCoord, + &this_region)) { + + memcpy(that_screen, this_screen, sizeof(that_screen)); + + for (i = 0; i < max_cells; i++) { + that_screen[i].Attributes = RevAttr(that_screen[i].Attributes); + } + + write_screen(CON.hdl, that_screen, this_size, bufferCoord, &this_region); + Sleep(200); + write_screen(CON.hdl, this_screen, this_size, bufferCoord, &this_region); + + } else { + MessageBeep(MB_ICONWARNING); /* MB_OK might be better */ + } return res; } @@ -849,6 +901,84 @@ wcon_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf) return OK; } +#define MIN_WIDE 80 +#define MIN_HIGH 24 + +/* + * In "normal" mode, reset the buffer- and window-sizes back to their original values. + */ +static void +set_scrollback(bool normal, CONSOLE_SCREEN_BUFFER_INFO * info) +{ + SMALL_RECT rect; + COORD coord; + bool changed = FALSE; + + T((T_CALLED("win32con::set_scrollback(%s)"), + (normal + ? "normal" + : "application"))); + + T(("... SBI.srWindow %d,%d .. %d,%d", + info->srWindow.Top, + info->srWindow.Left, + info->srWindow.Bottom, + info->srWindow.Right)); + T(("... SBI.dwSize %dx%d", + info->dwSize.Y, + info->dwSize.X)); + + if (normal) { + rect = info->srWindow; + coord = info->dwSize; + if (memcmp(info, &CON.SBI, sizeof(*info)) != 0) { + changed = TRUE; + CON.SBI = *info; + } + } else { + int high = info->srWindow.Bottom - info->srWindow.Top + 1; + int wide = info->srWindow.Right - info->srWindow.Left + 1; + + if (high < MIN_HIGH) { + T(("... height %d < %d", high, MIN_HIGH)); + high = MIN_HIGH; + changed = TRUE; + } + if (wide < MIN_WIDE) { + T(("... width %d < %d", wide, MIN_WIDE)); + wide = MIN_WIDE; + changed = TRUE; + } + + rect.Left = + rect.Top = 0; + rect.Right = (SHORT) (wide - 1); + rect.Bottom = (SHORT) (high - 1); + + coord.X = (SHORT) wide; + coord.Y = (SHORT) high; + + if (info->dwSize.Y != high || + info->dwSize.X != wide || + info->srWindow.Top != 0 || + info->srWindow.Left != 0) { + changed = TRUE; + } + + } + + if (changed) { + T(("... coord %d,%d", coord.Y, coord.X)); + T(("... rect %d,%d - %d,%d", + rect.Top, rect.Left, + rect.Bottom, rect.Right)); + SetConsoleScreenBufferSize(CON.hdl, coord); /* dwSize */ + SetConsoleWindowInfo(CON.hdl, TRUE, &rect); /* srWindow */ + get_SBI(); + } + returnVoid; +} + static int wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) { @@ -877,6 +1007,9 @@ wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) if (sp->_keypad_on) _nc_keypad(sp, TRUE); } + if (!CON.buffered) { + set_scrollback(FALSE, &CON.SBI); + } code = OK; } } @@ -895,9 +1028,11 @@ wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) } code = wcon_sgmode(TCB, TRUE, &(_term->Ottyb)); if (!CON.buffered) { + set_scrollback(TRUE, &CON.save_SBI); if (!restore_original_screen()) code = ERR; } + SetConsoleCursorInfo(CON.hdl, &CON.save_CI); } } @@ -982,7 +1117,8 @@ read_screen_data(void) want = (size_t) (CON.save_size.X * CON.save_size.Y); if ((CON.save_screen = malloc(want * sizeof(CHAR_INFO))) != 0) { - bufferCoord.X = bufferCoord.Y = 0; + bufferCoord.X = (SHORT) (CON.window_only ? CON.SBI.srWindow.Left : 0); + bufferCoord.Y = (SHORT) (CON.window_only ? CON.SBI.srWindow.Top : 0); T(("... reading console %s %dx%d into %d,%d - %d,%d at %d,%d", CON.window_only ? "window" : "buffer", @@ -994,11 +1130,11 @@ read_screen_data(void) bufferCoord.Y, bufferCoord.X)); - if (ReadConsoleOutput(CON.hdl, - CON.save_screen, - CON.save_size, - bufferCoord, - &CON.save_region)) { + if (read_screen(CON.hdl, + CON.save_screen, + CON.save_size, + bufferCoord, + &CON.save_region)) { result = TRUE; } else { T((" error %#lx", (unsigned long) GetLastError())); @@ -1363,7 +1499,7 @@ console_twait( diff = (int) tdiff(fstart, fend); milliseconds = Adjust(milliseconds, diff); - if (!isImmed && milliseconds == 0) + if (!isImmed && milliseconds <= 0) break; if (rc == WAIT_OBJECT_0) { @@ -1403,7 +1539,9 @@ console_twait( goto end; } continue; + /* e.g., FOCUS_EVENT */ default: + CONSUME(); selectActiveHandle(); continue; } @@ -1519,6 +1657,26 @@ wcon_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms) returnCode(OK); } +static int +wcon_cursorSet(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int mode) +{ + int res = -1; + CONSOLE_CURSOR_INFO this_CI = CON.save_CI; + T((T_CALLED("win32con:wcon_cursorSet(%d)"), mode)); + switch (mode) { + case 0: + this_CI.bVisible = FALSE; + break; + case 1: + break; + case 2: + this_CI.dwSize = 100; + break; + } + SetConsoleCursorInfo(CON.hdl, &this_CI); + returnCode(res); +} + static bool wcon_kyExist(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int keycode) { @@ -1629,7 +1787,8 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = { wcon_nap, /* nap */ wcon_kpad, /* kpad */ wcon_keyok, /* kyOk */ - wcon_kyExist /* kyExist */ + wcon_kyExist, /* kyExist */ + wcon_cursorSet /* cursorSet */ }; /* --------------------------------------------------------- */ @@ -1986,9 +2145,15 @@ __attribute__((constructor)) if (CON.hdl != INVALID_HANDLE_VALUE) { CON.buffered = buffered; get_SBI(); + CON.save_SBI = CON.SBI; if (!buffered) { save_original_screen(); + set_scrollback(FALSE, &CON.SBI); } + GetConsoleCursorInfo(CON.hdl, &CON.save_CI); + T(("... initial cursor is %svisible, %d%%", + (CON.save_CI.bVisible ? "" : "not-"), + (int) CON.save_CI.dwSize)); } console_initialized = TRUE; diff --git a/package/debian-mingw/changelog b/package/debian-mingw/changelog index 7244d41a..f50b132a 100644 --- a/package/debian-mingw/changelog +++ b/package/debian-mingw/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20140920) unstable; urgency=low +ncurses6 (5.9-20140927) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Fri, 19 Sep 2014 18:03:06 -0400 + -- Thomas E. Dickey Tue, 23 Sep 2014 16:52:38 -0400 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian-mingw64/changelog b/package/debian-mingw64/changelog index 7244d41a..f50b132a 100644 --- a/package/debian-mingw64/changelog +++ b/package/debian-mingw64/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20140920) unstable; urgency=low +ncurses6 (5.9-20140927) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Fri, 19 Sep 2014 18:03:06 -0400 + -- Thomas E. Dickey Tue, 23 Sep 2014 16:52:38 -0400 ncurses6 (5.9-20131005) unstable; urgency=low diff --git a/package/debian/changelog b/package/debian/changelog index e776e8c6..26e8499f 100644 --- a/package/debian/changelog +++ b/package/debian/changelog @@ -1,8 +1,8 @@ -ncurses6 (5.9-20140920) unstable; urgency=low +ncurses6 (5.9-20140927) unstable; urgency=low * latest weekly patch - -- Thomas E. Dickey Fri, 19 Sep 2014 18:03:05 -0400 + -- Thomas E. Dickey Tue, 23 Sep 2014 16:52:38 -0400 ncurses6 (5.9-20120608) unstable; urgency=low diff --git a/package/mingw-ncurses.nsi b/package/mingw-ncurses.nsi index 0ac1c038..307d3d53 100644 --- a/package/mingw-ncurses.nsi +++ b/package/mingw-ncurses.nsi @@ -1,4 +1,4 @@ -; $Id: mingw-ncurses.nsi,v 1.62 2014/09/19 22:03:06 tom Exp $ +; $Id: mingw-ncurses.nsi,v 1.63 2014/09/23 20:52:38 tom Exp $ ; TODO add examples ; TODO bump ABI to 6 @@ -10,7 +10,7 @@ !define VERSION_MAJOR "5" !define VERSION_MINOR "9" !define VERSION_YYYY "2014" -!define VERSION_MMDD "0920" +!define VERSION_MMDD "0927" !define VERSION_PATCH ${VERSION_YYYY}${VERSION_MMDD} !define MY_ABI "5" diff --git a/package/mingw-ncurses.spec b/package/mingw-ncurses.spec index d293d4a5..fe3a6b5e 100644 --- a/package/mingw-ncurses.spec +++ b/package/mingw-ncurses.spec @@ -3,7 +3,7 @@ Summary: shared libraries for terminal handling Name: mingw32-ncurses6 Version: 5.9 -Release: 20140920 +Release: 20140927 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/package/ncurses.spec b/package/ncurses.spec index 3b1be75b..ae621d71 100644 --- a/package/ncurses.spec +++ b/package/ncurses.spec @@ -1,7 +1,7 @@ Summary: shared libraries for terminal handling Name: ncurses6 Version: 5.9 -Release: 20140920 +Release: 20140927 License: X11 Group: Development/Libraries Source: ncurses-%{version}-%{release}.tgz diff --git a/test/dots_termcap.c b/test/dots_termcap.c index 4c1d62d9..9918e368 100644 --- a/test/dots_termcap.c +++ b/test/dots_termcap.c @@ -29,7 +29,7 @@ /* * Author: Thomas E. Dickey * - * $Id: dots_termcap.c,v 1.7 2013/09/28 21:50:35 tom Exp $ + * $Id: dots_termcap.c,v 1.8 2014/09/25 09:00:56 tom Exp $ * * A simple demo of the termcap interface. */ @@ -154,7 +154,7 @@ static void my_napms(int ms) { #if defined(__MINGW32__) || !HAVE_GETTIMEOFDAY - Sleep(ms); + Sleep((DWORD) ms); #else struct timeval data; data.tv_sec = 0; -- 2.44.0