diff options
Diffstat (limited to 'lib')
88 files changed, 6414 insertions, 3218 deletions
diff --git a/lib/libcurses/MKexpanded.sh b/lib/libcurses/MKexpanded.sh new file mode 100644 index 00000000000..e2e8363d22e --- /dev/null +++ b/lib/libcurses/MKexpanded.sh @@ -0,0 +1,96 @@ +#!/bin/sh +################################################################################ +# Copyright 1997 by Thomas E. Dickey <dickey@clark.net> # +# All Rights Reserved. # +# # +# Permission to use, copy, modify, and distribute this software and its # +# documentation for any purpose and without fee is hereby granted, provided # +# that the above copyright notice appear in all copies and that both that # +# copyright notice and this permission notice appear in supporting # +# documentation, and that the name of the above listed copyright holder(s) not # +# be used in advertising or publicity pertaining to distribution of the # +# software without specific, written prior permission. THE ABOVE LISTED # +# COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT # +# SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY SPECIAL, # +# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # +# PERFORMANCE OF THIS SOFTWARE. # +################################################################################ +# Id: MKexpanded.sh,v 1.4 1997/05/10 20:21:58 tom Exp $ +# +# Script to generate 'expanded.c', a dummy source that contains functions +# corresponding to complex macros used in this library. By making functions, +# we simplify analysis and debugging. + +if test $# != 0; then +preprocessor="$1" +else +preprocessor="cc -E" +fi +shift +if test $# != 0 ; then + preprocessor="$preprocessor $*" +else + preprocessor="$preprocessor -DHAVE_CONFIG_H -I. -I../include" +fi + +TMP=gen$$.c +trap "rm -f $TMP" 0 1 2 5 15 + +cat >expanded.c <<EOF +/* generated by MKexpanded.sh */ +#include <curses.priv.h> +#include <term.h> +#ifdef NCURSES_EXPANDED +EOF + +cat >$TMP <<EOF +#include <ncurses_cfg.h> +#undef NCURSES_EXPANDED /* this probably is set in ncurses_cfg.h */ +#include <curses.priv.h> +/* these are names we'd like to see */ +#undef ALL_BUT_COLOR +#undef PAIR_NUMBER +#undef TRUE +#undef FALSE +/* this is a marker */ +IGNORE +chtype _nc_ch_or_attr(chtype ch, attr_t at) +{ + return ch_or_attr(ch,at); +} +void _nc_toggle_attr_on(attr_t *S, attr_t at) +{ + toggle_attr_on(*S,at); +} +void _nc_toggle_attr_off(attr_t *S, attr_t at) +{ + toggle_attr_off(*S,at); +} +int _nc_can_clear_with(chtype ch) +{ + return can_clear_with(ch); +} +int _nc_DelCharCost(int count) +{ + return DelCharCost(count); +} +int _nc_InsCharCost(int count) +{ + return InsCharCost(count); +} +void _nc_UpdateAttrs(chtype c) +{ + UpdateAttrs(c); +} +EOF + +$preprocessor $TMP 2>/dev/null | sed -e '1,/^IGNORE$/d' >>expanded.c + +cat >>expanded.c <<EOF +#else /* ! NCURSES_EXPANDED */ +void _nc_expanded(void) { } +#endif /* NCURSES_EXPANDED */ +EOF diff --git a/lib/libcurses/MKkeyname.awk b/lib/libcurses/MKkeyname.awk index 4d03ae95e23..85f19457163 100644 --- a/lib/libcurses/MKkeyname.awk +++ b/lib/libcurses/MKkeyname.awk @@ -1,12 +1,13 @@ - +# Id: MKkeyname.awk,v 1.6 1997/04/05 23:38:17 tom Exp $ BEGIN { print "" + print "#include <ncurses_cfg.h>" print "#include <stdlib.h>" - print "#include \"curses.h\"" - print "#include \"term.h\"" + print "#include <term.h>" + print "#include <curses.h>" print "" print "struct kn {" - print "\tchar *name;" + print "\tconst char *name;" print "\tint code;" print "};" print "" diff --git a/lib/libcurses/MKlib_gen.sh b/lib/libcurses/MKlib_gen.sh index e384cde2185..86f1a6253d4 100644 --- a/lib/libcurses/MKlib_gen.sh +++ b/lib/libcurses/MKlib_gen.sh @@ -2,7 +2,7 @@ # # MKlib_gen.sh -- generate sources from curses.h macro definitions # -# ($Id: MKlib_gen.sh,v 1.1 1996/12/16 08:43:21 tholo Exp $) +# (Id: MKlib_gen.sh,v 1.9 1997/05/10 23:48:19 tom Exp $) # # The XSI Curses standard requires all curses entry points to exist as # functions, even though many definitions would normally be shadowed @@ -21,7 +21,7 @@ # 3. awk: generate the calls with args matching the formals # 4. sed: prefix function names in prototypes so the preprocessor won't expand # them. -# 5. cpp: macroexpand the file so the macro calls turn into C calls +# 5. cpp: macro-expand the file so the macro calls turn into C calls # 6. awk: strip the expansion junk off the front and add the new header # 7. sed: squeeze spaces, strip off gen_ prefix, create needed #undef # @@ -32,14 +32,14 @@ TMP=gen$$.c trap "rm -f $TMP" 0 1 2 5 15 (cat <<EOF -#include "curses.h" +#include <ncurses_cfg.h> +#include <curses.h> DECLARATIONS EOF sed -n -e "/^extern.*generated/s/^extern \([^;]*\);.*/\1/p" \ | sed \ - -e "/(/s// (/" \ -e "/(void)/b nc" \ -e "s/,/ a1% /" \ -e "s/,/ a2% /" \ @@ -56,30 +56,119 @@ sed -n -e "/^extern.*generated/s/^extern \([^;]*\);.*/\1/p" \ -e "s/,/ a13% /" \ -e "s/,/ a14% /" \ -e "s/,/ a15% /" \ - -e "s/%/,/g" \ + -e "s/*/ * /g" \ + -e "s/%/ , /g" \ -e "s/)/ z)/" \ -e ":nc" \ + -e "/(/s// ( /" \ + -e "s/)/ )/" \ | $AWK '{ print "\n" + print "M_" $2 print $0; print "{"; - for (i = argcount = 0; i < length($0); i++) - if (substr($0, i, 1) == ",") - argcount++; - ++argcount; + argcount = 1; + if (NF == 5 && $4 == "void") + argcount = 0; + if (argcount != 0) { + for (i = 1; i <= NF; i++) + if ($i == ",") + argcount++; + } + + # suppress trace-code for functions that we cannot do properly here, + # since they return data. + dotrace = 1; + if ($2 == "innstr") + dotrace = 0; + + call = "%%T((T_CALLED(\"" + args = "" + comma = "" + num = 0; + pointer = 0; + argtype = "" + for (i = 1; i <= NF; i++) { + ch = $i; + if ( ch == "*" ) + pointer = 1; + else if ( ch == "va_list" ) + pointer = 1; + else if ( ch == "char" ) + argtype = "char"; + else if ( ch == "int" ) + argtype = "int"; + else if ( ch == "short" ) + argtype = "short"; + else if ( ch == "chtype" ) + argtype = "chtype"; + else if ( ch == "attr_t" || ch == "NCURSES_ATTR_T" ) + argtype = "attr"; + + if ( ch == "," || ch == ")" ) { + if (pointer) { + if ( argtype == "char" ) { + call = call "%s" + comma = comma "_nc_visbuf2(" num "," + pointer = 0; + } else + call = call "%p" + } else if (argcount != 0) { + if ( argtype == "int" || argtype == "short" ) { + call = call "%d" + argtype = "" + } else if ( argtype != "" ) { + call = call "%s" + comma = comma "_trace" argtype "2(" num "," + } else { + call = call "%#lx" + comma = comma "(long)" + } + } + if (ch == ",") + args = args comma "a" ++num; + else if (argcount != 0) + args = args comma "z" + call = call ch + if (pointer == 0 && argcount != 0 && argtype != "" ) + args = args ")" + if (args != "") + comma = ", " + pointer = 0; + argtype = "" + } + if ( i == 2 || ch == "(" ) + call = call ch + } + call = call "\")" + if (args != "") + call = call ", " args + call = call ")); " + + if (dotrace) + printf "%s", call + if (match($0, "^void")) - call = "%%" + call = "" + else if (dotrace) + call = "returnCode( "; else call = "%%return "; + call = call $2 "("; for (i = 1; i < argcount; i++) - call = call " a" i ", "; - if (match($0, "\\(void\\)")) - call = call ");"; - else - call = call "z);"; - print call + call = call "a" i ", "; + if (argcount != 0) + call = call "z"; + if (!match($0, "^void")) + call = call ") "; + if (dotrace) + call = call ")"; + print call ";" + + if (match($0, "^void")) + print "%%returnVoid;" print "}"; } ' ) \ @@ -97,13 +186,13 @@ BEGIN { print " * requirement that every macro also exist as a callable" print " * function." print " *" - print " * It will neever be linked unless you call one of the entry" + print " * It will never be linked unless you call one of the entry" print " * points with its normal macro definition disabled. In that" print " * case, if you have no shared libraries, it will indirectly" print " * pull most of the rest of the library into your link image." print " * Cope with it." print " */" - print "#include \"curses.h\"" + print "#include <curses.priv.h>" print "" } /^DECLARATIONS/ {start = 1; next;} @@ -112,7 +201,12 @@ BEGIN { | sed \ -e 's/ */ /g' \ -e 's/ */ /g' \ + -e 's/ ,/,/g' \ + -e 's/ )/)/g' \ -e 's/ gen_/ /' \ -e 's/^M_/#undef /' \ - -e '/^%%/s// /' + -e '/^%%/s// /' \ +| sed \ + -e 's/^.*T_CALLED.*returnCode( \([a-z].*) \));/ return \1;/' \ + -e 's/^.*T_CALLED.*returnCode( \((wmove.*) \));/ return \1;/' diff --git a/lib/libcurses/Makefile b/lib/libcurses/Makefile index 4fa8bbb35f9..c213254d71b 100644 --- a/lib/libcurses/Makefile +++ b/lib/libcurses/Makefile @@ -1,17 +1,19 @@ -# $OpenBSD: Makefile,v 1.14 1997/04/27 20:56:09 millert Exp $ +# $OpenBSD: Makefile,v 1.15 1997/11/26 04:01:04 millert Exp $ LIB= curses -SRCS= hardscroll.c lib_acs.c lib_delch.c lib_insstr.c lib_options.c \ - lib_set_term.c lib_addch.c lib_delwin.c lib_instr.c lib_overlay.c \ - lib_slk.c lib_addstr.c lib_doupdate.c lib_isendwin.c lib_pad.c \ - lib_touch.c lib_beep.c lib_endwin.c lib_kernel.c lib_printw.c \ - lib_tstp.c lib_bkgd.c lib_erase.c lib_longname.c lib_raw.c \ - lib_twait.c lib_box.c lib_getch.c lib_mouse.c lib_refresh.c \ - lib_unctrl.c lib_clear.c lib_getstr.c lib_move.c lib_resize.c \ - lib_vidattr.c lib_clrbot.c lib_inchstr.c lib_mvcur.c lib_scanw.c \ - lib_window.c lib_clreol.c lib_initscr.c lib_mvwin.c lib_screen.c \ - lib_color.c lib_insch.c lib_newterm.c lib_scroll.c lib_data.c \ - lib_insdel.c lib_keyname.c lib_newwin.c lib_scrreg.c lib_gen.c +SRCS= hardscroll.c hashmap.c lib_acs.c lib_addch.c lib_addstr.c \ + lib_baudrate.c lib_beep.c lib_bkgd.c lib_box.c lib_clear.c \ + lib_clrbot.c lib_clreol.c lib_color.c lib_data.c lib_delch.c \ + lib_delwin.c lib_dft_fgbg.c lib_doupdate.c lib_endwin.c lib_erase.c \ + lib_getch.c lib_getstr.c lib_inchstr.c lib_initscr.c lib_insch.c \ + lib_insdel.c lib_insstr.c lib_instr.c lib_isendwin.c lib_kernel.c \ + lib_longname.c lib_mouse.c lib_move.c lib_mvcur.c lib_mvwin.c \ + lib_newterm.c lib_newwin.c lib_options.c lib_overlay.c lib_pad.c \ + lib_print.c lib_printw.c lib_raw.c lib_refresh.c lib_scanw.c \ + lib_screen.c lib_scroll.c lib_scrreg.c lib_set_term.c lib_slk.c \ + lib_touch.c lib_tstp.c lib_twait.c lib_vidattr.c lib_window.c \ + resizeterm.c unctrl.c wresize.c +SRCS+= expanded.c lib_gen.c lib_keyname.c CFLAGS+= -I. -I${.CURDIR} -DTERMIOS -DEXTERN_TERMINFO LDADD+= -ltermlib MAN= curs_addch.3 curs_addchstr.3 curs_addstr.3 curs_attr.3 curs_beep.3 \ @@ -19,11 +21,11 @@ MAN= curs_addch.3 curs_addchstr.3 curs_addstr.3 curs_attr.3 curs_beep.3 \ curs_deleteln.3 curs_getch.3 curs_getstr.3 curs_getyx.3 curs_inch.3 \ curs_inchstr.3 curs_initscr.3 curs_inopts.3 curs_insch.3 curs_insstr.3 \ curs_instr.3 curs_kernel.3 curs_mouse.3 curs_move.3 curs_outopts.3 \ - curs_overlay.3 curs_pad.3 curs_printw.3 curs_refresh.3 curs_resize.3 \ + curs_overlay.3 curs_pad.3 curs_print.3 curs_printw.3 curs_refresh.3 \ curs_scanw.3 curs_scr_dmp.3 curs_scroll.3 curs_slk.3 curs_termattrs.3 \ - curs_touch.3 curs_util.3 curs_window.3 curses.3 + curs_touch.3 curs_util.3 curs_window.3 curses.3 wresize.3 MLINKS+=curses.3 ncurses.3 -CLEANFILES+= lib_gen.c lib_keyname.c keys.tries +CLEANFILES+= lib_gen.c lib_keyname.c keys.tries expanded.c beforedepend: keys.tries @@ -45,6 +47,9 @@ lib_keyname.c: ${.CURDIR}/keys.list ${.CURDIR}/MKkeyname.awk lib_gen.c: ${.CURDIR}/curses.h ${.CURDIR}/MKlib_gen.sh sh ${.CURDIR}/MKlib_gen.sh "${CPP}" "awk" < ${.CURDIR}/curses.h > lib_gen.c +expanded.c: ${.CURDIR}/curses.h ${.CURDIR}/MKexpanded.sh + sh ${.CURDIR}/MKexpanded.sh "${CPP}" ${CPPFLAGS} + .include <bsd.lib.mk> lib_options.o lib_options.so lib_options.po lib_options.ln: keys.tries diff --git a/lib/libcurses/curs_addch.3 b/lib/libcurses/curs_addch.3 index e32eba1ef1b..2a50efa09db 100644 --- a/lib/libcurses/curs_addch.3 +++ b/lib/libcurses/curs_addch.3 @@ -43,7 +43,7 @@ Video attributes can be combined with a character argument passed to \fBaddch\fR or related functions by logical-ORing them into the character. (Thus, text, including attributes, can be copied from one place to another using \fBinch\fR and \fBaddch\fR.). See the \fBcurs_attr\fR(3X) page for -values of predefined video attribute constants that can be usefully ORed +values of predefined video attribute constants that can be usefully OR'ed into characters. The \fBechochar\fR and \fBwechochar\fR routines are equivalent to a call to @@ -115,7 +115,7 @@ The attribute A_ALTCHARSET actually forces literal display of PC ROM characters including the high-half graphics. Your console driver may still capture or translate a few (such as ESC) but this feature should give you access to the card-suit characters, up and down-arrow, and most others in the range 0-32. -(In a terminfo entry designed for use with \fBncurses\fR, the high-half +(In a terminfo entry designed for use with \fBcurses\fR, the high-half characters are obtained using this attribute with an \fBacsc\fR string in which the second of each pair is a high-half character.) @@ -133,7 +133,7 @@ The seven ACS symbols starting with \fBACS_S3\fR were not documented in any publicly released System V. However, many publicly available terminfos include \fBacsc\fR strings in which their key characters (pryz{|}) are embedded, and a second-hand list of their character descriptions has come -to light. The ACS-prefixed names for them were invented for \fBncurses\fR(3X). +to light. The ACS-prefixed names for them were invented for \fBcurses\fR(3X). .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_attr\fR(3X), \fBcurs_clear\fR(3X), \fBcurs_inch\fR(3X), \fBcurs_outopts\fR(3X), \fBcurs_refresh\fR(3X), diff --git a/lib/libcurses/curs_attr.3 b/lib/libcurses/curs_attr.3 index d08df520173..64669500bcb 100644 --- a/lib/libcurses/curs_attr.3 +++ b/lib/libcurses/curs_attr.3 @@ -1,3 +1,4 @@ +.\" Id: curs_attr.3x,v 1.12 1997/01/05 01:14:33 tom Exp $ .TH curs_attr 3X "" .SH NAME \fBattroff\fR, \fBwattroff\fR, \fBattron\fR, \fBwattron\fR, @@ -74,7 +75,7 @@ The routine \fBwattr_get\fR returns the current attribute for the given window; \fBattr_get\fR returns the current attribute for \fBstdscr\fR. The remaining \fBattr_\fR* functions operate exactly like the corresponding \fBattr\fR* functions, except that they take arguments of type \fBattr_t\fR -rather than \fBint\fR. +rather than \fBint\fR. The routine \fBchgat\fR changes the attributes of a given number of characters starting at the current cursor location of \fBstdscr\fR. It does not update @@ -87,33 +88,35 @@ of \fIinit_pair\fR, see \fBcurs_color\fR(3x)). The \fBopts\fR argument is not presently used, but is reserved for the future (leave it \fBNULL\fR). .SS Attributes The following video attributes, defined in \fB<curses.h>\fR, can be passed to -the routines \fBattron\fR, \fBattroff\fR, and \fBattrset\fR, or OR-ed with the +the routines \fBattron\fR, \fBattroff\fR, and \fBattrset\fR, or OR'ed with the characters passed to \fBaddch\fR. -.nf -\fBA_NORMAL\fR Normal display (no highlight) -\fBA_STANDOUT\fR Best highlighting mode of the terminal. -\fBA_UNDERLINE\fR Underlining -\fBA_REVERSE\fR Reverse video -\fBA_BLINK\fR Blinking -\fBA_DIM\fR Half bright -\fBA_BOLD\fR Extra bright or bold -\fBA_PROTECT\fR Protected mode -\fBA_INVIS\fR Invisible or blank mode -\fBA_ALTCHARSET\fR Alternate character set -\fBA_CHARTEXT\fR Bit-mask to extract a character -\fBCOLOR_PAIR(\fR\fIn\fR\fB)\fR Color-pair number \fIn\fR -.fi +.TS +center ; +l l . +\fBA_NORMAL\fR Normal display (no highlight) +\fBA_STANDOUT\fR Best highlighting mode of the terminal. +\fBA_UNDERLINE\fR Underlining +\fBA_REVERSE\fR Reverse video +\fBA_BLINK\fR Blinking +\fBA_DIM\fR Half bright +\fBA_BOLD\fR Extra bright or bold +\fBA_PROTECT\fR Protected mode +\fBA_INVIS\fR Invisible or blank mode +\fBA_ALTCHARSET\fR Alternate character set +\fBA_CHARTEXT\fR Bit-mask to extract a character +\fBCOLOR_PAIR(\fR\fIn\fR\fB)\fR Color-pair number \fIn\fR +.TE The following macro is the reverse of \fBCOLOR_PAIR(\fR\fIn\fR\fB)\fR: .DS C -\fBPAIR_NUMBER(\fIattrs\fR) Returns the pair number associated +\fBPAIR_NUMBER(\fIattrs\fR) Returns the pair number associated with the \fBCOLOR_PAIR(\fR\fIn\fR\fB)\fR attribute. .DE -The return values of many of these routines are not meaningful (they are -implemented as macro-expanded assignments and simply return their argument). +The return values of many of these routines are not meaningful (they are +implemented as macro-expanded assignments and simply return their argument). The SVr4 manual page claims (falsely) that these routines always return \fB1\fR. .SH NOTES @@ -128,8 +131,8 @@ not supported under SVr4. The XSI Curses standard states that whether the traditional functions \fBattron\fR/\fBattroff\fR/\fBattrset\fR can manipulate attributes other than \fBA_BLINK\fR, \fBA_BOLD\fR, \fBA_DIM\fR, \fBA_REVERSE\fR, \fBA_STANDOUT\fR, or -\fBA_UNDERLINE\fR is "unspecified". Under this implementation as well as -SVr4 curses, these functions correctly manipulate all other highlights +\fBA_UNDERLINE\fR is "unspecified". Under this implementation as well as +SVr4 curses, these functions correctly manipulate all other highlights (specifically, \fBA_ALTCHARSET\fR, \fBA_PROTECT\fR, and \fBA_INVIS\fR). XSI Curses added the new entry points, \fBattr_get\fR, \fBattr_on\fR, @@ -137,20 +140,22 @@ XSI Curses added the new entry points, \fBattr_get\fR, \fBattr_on\fR, \fBwattr_get\fR, \fBwattr_set\fR. These are intended to work with a new series of highlight macros prefixed with \fBWA_\fR. -.nf -\fBWA_NORMAL\fR Normal display (no highlight) -\fBWA_STANDOUT\fR Best highlighting mode of the terminal. -\fBWA_UNDERLINE\fR Underlining -\fBWA_REVERSE\fR Reverse video -\fBWA_BLINK\fR Blinking -\fBWA_DIM\fR Half bright -\fBWA_BOLD\fR Extra bright or bold -\fBWA_ALTCHARSET\fR Alternate character set -.fi +.TS +center ; +l l . +\fBWA_NORMAL\fR Normal display (no highlight) +\fBWA_STANDOUT\fR Best highlighting mode of the terminal. +\fBWA_UNDERLINE\fR Underlining +\fBWA_REVERSE\fR Reverse video +\fBWA_BLINK\fR Blinking +\fBWA_DIM\fR Half bright +\fBWA_BOLD\fR Extra bright or bold +\fBWA_ALTCHARSET\fR Alternate character set +.TE The XSI curses standard specifies that each pair of corresponding \fBA_\fR and \fBWA_\fR-using functions operates on the same current-highlight -information. +information. The XSI standard extended conformance level adds new highlights \fBA_HORIZONTAL\fR, \fBA_LEFT\fR, \fBA_LOW\fR, \fBA_RIGHT\fR, \fBA_TOP\fR, diff --git a/lib/libcurses/curs_bkgd.3 b/lib/libcurses/curs_bkgd.3 index cc3372c8e47..a1b823fbb2f 100644 --- a/lib/libcurses/curs_bkgd.3 +++ b/lib/libcurses/curs_bkgd.3 @@ -1,7 +1,10 @@ +.\" Id: curs_bkgd.3x,v 1.10 1996/07/20 23:48:30 tom Exp $ .TH curs_bkgd 3X "" +. .SH NAME \fBbkgdset\fR, \fBwbkgdset\fR, \fBbkgd\fR, \fBwbkgd\fR - \fBcurses\fR window background manipulation routines +. .SH SYNOPSIS \fB#include <curses.h>\fR @@ -13,43 +16,54 @@ .br \fBint wbkgd(WINDOW *win, const chtype ch);\fR .br -\fBchtype wgetbkgd(WINDOW *win);\fR +\fBchtype getbkgd(WINDOW *win);\fR .br +. .SH DESCRIPTION The \fBbkgdset\fR and \fBwbkgdset\fR routines manipulate the -background of the named window. Background is a \fBchtype\fR -consisting of any combination of attributes and a character. The -attribute part of the background is combined (ORed) with all non-blank +background of the named window. +The window background is a \fBchtype\fR consisting of +any combination of attributes (i.e., rendition) and a character. +The attribute part of the background is combined (OR'ed) with all non-blank characters that are written into the window with \fBwaddch\fR. Both the character and attribute parts of the background are combined with the blank characters. The background becomes a property of the character and moves with the character through any scrolling and -insert/delete line/character operations. To the extent possible on a -particular terminal, the attribute part of the background is displayed -as the graphic rendition of the character put on the screen. +insert/delete line/character operations. -The \fBbkgd\fR and \fBwbkgd\fR routines combine the new background -with every position in the window. Background is any combination of -attributes and a character. Only the attribute part is used to set -the background of non-blank characters, while both character and -attributes are used for blank positions. To the extent possible on a +To the extent possible on a particular terminal, the attribute part of the background is displayed as the graphic rendition of the character put on the screen. -The \fBwgetbkgd\fR function returns the given window's current background +The \fBbkgd\fR and \fBwbkgd\fR functions +set the background property of the current or specified window +and then apply this setting to every character position in that window: + +.RS +The rendition of every character on the screen is changed to +the new background rendition. + +Wherever the former background character +appears, it is changed to the new background character. +.RE + +The \fBgetbkgd\fR function returns the given window's current background character/attribute pair. +. .SH RETURN VALUE The routines \fBbkgd\fR and \fBwbkgd\fR return the integer \fBOK\fR. The SVr4.0 manual says "or a non-negative integer if \fBimmedok\fR is set", but this appears to be an error. +. .SH NOTES Note that \fBbkgdset\fR and \fBbkgd\fR may be macros. +. .SH PORTABILITY These functions are described in the XSI Curses standard, Issue 4. The draft does not include \fBconst\fR qualifiers on the arguments. The standard specifies that \fBbkgd\fR and \fBwbkgd\fR return \fBERR\fR, on failure. but -gives no failure conditions. The draft describes the new function -\fBwgetbkgd\fR, which is not in SVr4. +gives no failure conditions. +. .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_addch\fR(3X), \fBcurs_outopts\fR(3X) .\"# diff --git a/lib/libcurses/curs_border.3 b/lib/libcurses/curs_border.3 index c3d845acfc8..1ba70e61592 100644 --- a/lib/libcurses/curs_border.3 +++ b/lib/libcurses/curs_border.3 @@ -1,3 +1,4 @@ +.\" Id: curs_border.3x,v 1.8 1996/08/04 00:29:11 tom Exp $ .TH curs_border 3X "" .SH NAME \fBborder\fR, \fBwborder\fR, \fBbox\fR, @@ -23,6 +24,14 @@ .br \fBint wvline(WINDOW *win, chtype ch, int n);\fR .br +\fBmvhline(int y, int x, chtype ch, int n);\fR +.br +\fBmvwhline(WINDOW *, int y, int x, chtype ch, int n);\fR +.br +\fBint mvvline(int y, int x, chtype ch, int n);\fR +.br +\fBint mvwvline(WINDOW *, int y, int x, chtype ch, int n);\fR +.br .SH DESCRIPTION The \fBborder\fR, \fBwborder\fR and \fBbox\fR routines draw a box around the edges of a window. The argument \fIls\fR is a character and attributes used @@ -34,7 +43,7 @@ default values (defined in \fBcurses.h\fR) are used instead: \fBACS_VLINE\fR, \fBACS_VLINE\fR, \fBACS_HLINE\fR, \fBACS_HLINE\fR, \fB\fBACS_ULCORNER\fR, \fBACS_URCORNER\fR, \fBACS_BLCORNER\fR, \fBACS_BRCORNER\fR. -\fBbox(\fR\fIwin\fR\gB, \fR\fIverch\fR\fB, \fR\fIhorch\fR\fB)\fR is a shorthand +\fBbox(\fR\fIwin\fR\fB, \fR\fIverch\fR\fB, \fR\fIhorch\fR\fB)\fR is a shorthand for the following call: \fBwborder(\fR\fIwin\fR\fB,\fR \fIverch\fR\fB,\fR \fIverch\fR\fB,\fR \fIhorch\fR\fB,\fR \fIhorch\fR\fB, 0, 0, 0, 0)\fR. diff --git a/lib/libcurses/curs_clear.3 b/lib/libcurses/curs_clear.3 index 1a9efb7ce15..a923efe7753 100644 --- a/lib/libcurses/curs_clear.3 +++ b/lib/libcurses/curs_clear.3 @@ -54,7 +54,7 @@ error conditions. Some historic curses implementations had, as an undocumented feature, the ability to do the equivalent of \fBclearok(..., 1)\fR by saying \fBtouchwin(stdscr)\fR or \fBclear(stdscr)\fR. This will not work under -ncurses. +curses. .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_outopts\fR(3X), \fBcurs_refresh\fR(3X) .\"# diff --git a/lib/libcurses/curs_color.3 b/lib/libcurses/curs_color.3 index ef015207411..133baf97057 100644 --- a/lib/libcurses/curs_color.3 +++ b/lib/libcurses/curs_color.3 @@ -1,3 +1,4 @@ +.\" Id: curs_color.3x,v 1.8 1997/01/19 02:50:30 tom Exp $ .TH curs_color 3X "" .SH NAME \fBstart_color\fR, \fBinit_pair\fR, @@ -119,10 +120,16 @@ All other routines return the integer \fBERR\fR upon failure and an \fBOK\fR (SVr4 specifies only "an integer value other than \fBERR\fR") upon successful completion. .SH NOTES +In the \fIcurses\fR implementation, there is a separate color activation flag, +color palette, color pairs table, and associated COLORS and COLOR_PAIRS counts +for each screen; the \fBstart_color\fR function only affects the current +screen. The SVr4/XSI interface is not really designed with this in mind, and +historical implementations may use a single shared color palette. + Note that setting an implicit background color via a color pair affects only character cells that a character write operation explicitly touches. To change the background color used when parts of a window are blanked by erasing or -scrolling operastions, see \fBcurs_bkgd\fR(3x). +scrolling operations, see \fBcurs_bkgd\fR(3x). Several caveats apply on 386 and 486 machines with VGA-compatible graphics: @@ -136,10 +143,17 @@ Paradise and compatibles) do the wrong thing when you try to set a bright Color RGB values are not settable. .SH PORTABILITY -This implementation satisfies XSI Curses's minumum maximums +This implementation satisfies XSI Curses's minimum maximums for \fBCOLORS\fR and \fBCOLOR_PAIRS\fR. +.PP +The \fBinit_pair\fP routine accepts negative values of foreground +and background color to support the \fBuse_default_colors\fP extension, +but only if that routine has been first invoked. .SH SEE ALSO -\fBcurses\fR(3X), \fBcurs_initscr\fR(3X), \fBcurs_attr\fR(3X) +\fBcurses\fR(3X), +\fBcurs_initscr\fR(3X), +\fBcurs_attr\fR(3X), +\fBdft_fgbg\fR(3X) .\"# .\"# The following sets edit modes for GNU EMACS .\"# Local Variables: diff --git a/lib/libcurses/curs_getch.3 b/lib/libcurses/curs_getch.3 index 293bcf29fc4..ceab5335d71 100644 --- a/lib/libcurses/curs_getch.3 +++ b/lib/libcurses/curs_getch.3 @@ -1,3 +1,4 @@ +.\" Id: curs_getch.3x,v 1.10 1997/01/05 11:57:54 Jesse.Thilo Exp $ .TH curs_getch 3X "" .SH NAME \fBgetch\fR, \fBwgetch\fR, \fBmvgetch\fR, @@ -16,6 +17,8 @@ .br \fBint ungetch(int ch);\fR .br +\fBint has_key(int ch);\fR +.br .SH DESCRIPTION The \fBgetch\fR, \fBwgetch\fR, \fBmvgetch\fR and \fBmvwgetch\fR, routines read a character from the window. In no-delay mode, if no input is waiting, the @@ -23,10 +26,10 @@ value \fBERR\fR is returned. In delay mode, the program waits until the system passes text through to the program. Depending on the setting of \fBcbreak\fR, this is after one character (cbreak mode), or after the first newline (nocbreak mode). In half-delay mode, the program waits until a character is typed or the -specified timeout has been reached. +specified timeout has been reached. If \fBnoecho\fR has been set, then the character will also be echoed into the -designated window according to the following rules: +designated window according to the following rules: If the character is the current erase character, left arrow, or backspace, the cursor is moved one space to the left and that screen position is erased as if \fBdelch\fR had been called. @@ -60,109 +63,126 @@ just one input queue for all windows. The following function keys, defined in \fB<curses.h>\fR, might be returned by \fBgetch\fR if \fBkeypad\fR has been enabled. Note that not all of these are necessarily supported on any particular terminal. -.nf -__________________________________________________________________ -\fIName\fR \fIKey\fR \fIname\fR -__________________________________________________________________ -KEY_BREAK Break key -KEY_DOWN The four arrow keys ... +.sp +.TS +center tab(/) ; +l l +l l . +\fIName\fR/\fIKey\fR \fIname\fR + +KEY_BREAK/Break key +KEY_DOWN/The four arrow keys ... KEY_UP KEY_LEFT KEY_RIGHT -KEY_HOME Home key (upward+left arrow) -KEY_BACKSPACE Backspace -KEY_F0 Function keys; space for 64 keys is reserved. -KEY_F(\fIn\fR) For 0 \fI<\fR \fIn\fR \fI<\fR 63 -KEY_DL Delete line -KEY_IL Insert line -KEY_DC Delete character -KEY_IC Insert char or enter insert mode -KEY_EIC Exit insert char mode -KEY_CLEAR Clear screen -KEY_EOS Clear to end of screen -KEY_EOL Clear to end of line -KEY_SF Scroll 1 line forward -KEY_SR Scroll 1 line backward (reverse) -KEY_NPAGE Next page -KEY_PPAGE Previous page -KEY_STAB Set tab -KEY_CTAB Clear tab -KEY_CATAB Clear all tabs -KEY_ENTER Enter or send -KEY_SRESET Soft (partial) reset -KEY_RESET Reset or hard reset -KEY_PRINT Print or copy -KEY_LL Home down or bottom (lower left). Keypad is - arranged like this: - \fBA1\fR \fBup\fR \fBA3\fR - \fBleft\fR \fBB2\fR \fBright\fR - \fBC1\fR \fBdown\fR \fBC3\fR -KEY_A1 Upper left of keypad -KEY_A3 Upper right of keypad -KEY_B2 Center of keypad -KEY_C1 Lower left of keypad -KEY_C3 Lower right of keypad -KEY_BTAB Back tab key -KEY_BEG Beg(inning) key -KEY_CANCEL Cancel key -KEY_CLOSE Close key -KEY_COMMAND Cmd (command) key -KEY_COPY Copy key -KEY_CREATE Create key -KEY_END End key -KEY_EXIT Exit key -KEY_FIND Find key -KEY_HELP Help key -KEY_MARK Mark key -KEY_MESSAGE Message key -KEY_MOVE Move key -KEY_NEXT Next object key -KEY_OPEN Open key -KEY_OPTIONS Options key -KEY_PREVIOUS Previous object key -KEY_REDO Redo key -KEY_REFERENCE Ref(erence) key -KEY_REFRESH Refresh key -KEY_REPLACE Replace key -KEY_RESTART Restart key -KEY_RESUME Resume key -KEY_SAVE Save key -KEY_SBEG Shifted beginning key -KEY_SCANCEL Shifted cancel key -KEY_SCOMMAND Shifted command key -KEY_SCOPY Shifted copy key -KEY_SCREATE Shifted create key -KEY_SDC Shifted delete char key -KEY_SDL Shifted delete line key -KEY_SELECT Select key -KEY_SEND Shifted end key -KEY_SEOL Shifted clear line key -KEY_SEXIT Shifted exit key -KEY_SFIND Shifted find key -KEY_SHELP Shifted help key -KEY_SHOME Shifted home key -KEY_SIC Shifted input key -KEY_SLEFT Shifted left arrow key -KEY_SMESSAGE Shifted message key -KEY_SMOVE Shifted move key -KEY_SNEXT Shifted next key -KEY_SOPTIONS Shifted options key -KEY_SPREVIOUS Shifted prev key -KEY_SPRINT Shifted print key -KEY_SREDO Shifted redo key -KEY_SREPLACE Shifted replace key -KEY_SRIGHT Shifted right arrow -KEY_SRSUME Shifted resume key -KEY_SSAVE Shifted save key -KEY_SSUSPEND Shifted suspend key -KEY_SUNDO Shifted undo key -KEY_SUSPEND Suspend key -KEY_UNDO Undo key -.fi +KEY_HOME/Home key (upward+left arrow) +KEY_BACKSPACE/Backspace +KEY_F0/T{ +Function keys; space for 64 keys is reserved. +T} +KEY_F(\fIn\fR)/T{ +For 0 \(<= \fIn\fR \(<= 63 +T} +KEY_DL/Delete line +KEY_IL/Insert line +KEY_DC/Delete character +KEY_IC/Insert char or enter insert mode +KEY_EIC/Exit insert char mode +KEY_CLEAR/Clear screen +KEY_EOS/Clear to end of screen +KEY_EOL/Clear to end of line +KEY_SF/Scroll 1 line forward +KEY_SR/Scroll 1 line backward (reverse) +KEY_NPAGE/Next page +KEY_PPAGE/Previous page +KEY_STAB/Set tab +KEY_CTAB/Clear tab +KEY_CATAB/Clear all tabs +KEY_ENTER/Enter or send +KEY_SRESET/Soft (partial) reset +KEY_RESET/Reset or hard reset +KEY_PRINT/Print or copy +KEY_LL/Home down or bottom (lower left). +KEY_A1/Upper left of keypad +KEY_A3/Upper right of keypad +KEY_B2/Center of keypad +KEY_C1/Lower left of keypad +KEY_C3/Lower right of keypad +KEY_BTAB/Back tab key +KEY_BEG/Beg(inning) key +KEY_CANCEL/Cancel key +KEY_CLOSE/Close key +KEY_COMMAND/Cmd (command) key +KEY_COPY/Copy key +KEY_CREATE/Create key +KEY_END/End key +KEY_EXIT/Exit key +KEY_FIND/Find key +KEY_HELP/Help key +KEY_MARK/Mark key +KEY_MESSAGE/Message key +KEY_MOVE/Move key +KEY_NEXT/Next object key +KEY_OPEN/Open key +KEY_OPTIONS/Options key +KEY_PREVIOUS/Previous object key +KEY_REDO/Redo key +KEY_REFERENCE/Ref(erence) key +KEY_REFRESH/Refresh key +KEY_REPLACE/Replace key +KEY_RESTART/Restart key +KEY_RESUME/Resume key +KEY_SAVE/Save key +KEY_SBEG/Shifted beginning key +KEY_SCANCEL/Shifted cancel key +KEY_SCOMMAND/Shifted command key +KEY_SCOPY/Shifted copy key +KEY_SCREATE/Shifted create key +KEY_SDC/Shifted delete char key +KEY_SDL/Shifted delete line key +KEY_SELECT/Select key +KEY_SEND/Shifted end key +KEY_SEOL/Shifted clear line key +KEY_SEXIT/Shifted exit key +KEY_SFIND/Shifted find key +KEY_SHELP/Shifted help key +KEY_SHOME/Shifted home key +KEY_SIC/Shifted input key +KEY_SLEFT/Shifted left arrow key +KEY_SMESSAGE/Shifted message key +KEY_SMOVE/Shifted move key +KEY_SNEXT/Shifted next key +KEY_SOPTIONS/Shifted options key +KEY_SPREVIOUS/Shifted prev key +KEY_SPRINT/Shifted print key +KEY_SREDO/Shifted redo key +KEY_SREPLACE/Shifted replace key +KEY_SRIGHT/Shifted right arrow +KEY_SRSUME/Shifted resume key +KEY_SSAVE/Shifted save key +KEY_SSUSPEND/Shifted suspend key +KEY_SUNDO/Shifted undo key +KEY_SUSPEND/Suspend key +KEY_UNDO/Undo key +.TE + +Keypad is arranged like this: +.sp +.TS +center allbox tab(/) ; +c c c . +\fBA1\fR/\fBup\fR/\fBA3\fR +\fBleft\fR/\fBB2\fR/\fBright\fR +\fBC1\fR/\fBdown\fR/\fBC3\fR +.TE +.sp +The \fBhas_key\fR routine takes a key value from the above list, and +returns TRUE or FALSE according as the current terminal type recognizes +a key with that value. .SH RETURN VALUE -All routines return the integer \fBERR\fR upon failure and an integer value -other than \fBERR\fR" (\fBOK\fR in the case of ungetch()) upon successful +All routines return the integer \fBERR\fR upon failure and an integer value +other than \fBERR\fR (\fBOK\fR in the case of ungetch()) upon successful completion. .SH NOTES Use of the escape key by a programmer for a single character function is @@ -185,13 +205,29 @@ consoles typically support little more than \fBKEY_UP\fR, \fBKEY_DOWN\fR, \fBKEY_NPAGE\fR, \fBKEY_PPAGE\fR, and function keys 1 through 12. The Ins key is usually mapped to \fBKEY_IC\fR. .SH PORTABILITY -These functions are described in the XSI Curses standard, Issue 4. They read -single-byte characters only. The standard specifies that they return \fBERR\fR -on failure, but specifies no error conditions. +The *get* functions are described in the XSI Curses standard, Issue 4. They +read single-byte characters only. The standard specifies that they return +\fBERR\fR on failure, but specifies no error conditions. The echo behavior of these functions on input of \fBKEY_\fR or backspace -characters was not specified. This description is adopted from the XSI -Curses standard. +characters was not specified in the SVr4 documentation. This description is +adopted from the XSI Curses standard. + +The behavior of \fBgetch\fR and friends in the presence of handled signals is +unspecified in the SVr4 and XSI Curses documentation. Under historical curses +implementations, it varied depending on whether the operating system's +implementation of handled signal receipt interrupts a \fBread\fR(2) call in +progress or not, and also (in some implementations) depending on whether an +input timeout or non-blocking mode hsd been set. + +Programmers concerned about portability should be prepared for either of two +cases: (a) signal receipt does not interrupt \fBgetch\fR; (b) signal receipt +interrupts \fBgetch\fR and causes it to return ERR with \fBerrno\fR set to +\fBEINTR\fR. Under the \fBcurses\fR implementation, handled signals never +interrupt \fBgetch\fR. + +The \fBhas_key\fR function is unique to \fBcurses\fR. We recommend that +any code using it be conditionalized on the NCURSES feature macro. .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_inopts\fR(3X), \fBcurs_move\fR(3X), \fBcurs_refresh\fR(3X). diff --git a/lib/libcurses/curs_getstr.3 b/lib/libcurses/curs_getstr.3 index 95845739807..cd3abf4d6da 100644 --- a/lib/libcurses/curs_getstr.3 +++ b/lib/libcurses/curs_getstr.3 @@ -8,12 +8,18 @@ \fBint getstr(char *str);\fR .br +\fBint getnstr(char *str, int n);\fR +.br \fBint wgetstr(WINDOW *win, char *str);\fR .br \fBint mvgetstr(int y, int x, char *str);\fR .br \fBint mvwgetstr(WINDOW *win, int y, int x, char *str);\fR .br +\fBint mvgetnstr(int y, int x, char *str, int n);\fR +.br +\fBint mvwgetnstr(WINDOW *, int y, int x, char *str, int n);\fR +.br \fBint wgetnstr(WINDOW *win, char *str, int n);\fR .br .SH DESCRIPTION @@ -25,7 +31,8 @@ area pointed to by the character pointer \fIstr\fR. \fBwgetnstr\fR reads at most \fIn\fR characters, thus preventing a possible overflow of the input buffer. Any attempt to enter more characters (other than the terminating newline or carriage return) causes a beep. Function -keys also cause a beep and are ignored. +keys also cause a beep and are ignored. The \fBgetnstr\fR function reads +from the \fIstdscr\fR default window. The user's erase and kill characters are interpreted. If keypad mode is on for the window, \fBKEY_LEFT\fR and \fBKEY_BACKSPACE\fR diff --git a/lib/libcurses/curs_inch.3 b/lib/libcurses/curs_inch.3 index 688a12c415a..48aa2e5fcc7 100644 --- a/lib/libcurses/curs_inch.3 +++ b/lib/libcurses/curs_inch.3 @@ -1,3 +1,4 @@ +.\" Id: curs_inch.3x,v 1.7 1997/01/05 01:29:23 tom Exp $ .TH curs_inch 3X "" .SH NAME \fBinch\fR, \fBwinch\fR, \fBmvinch\fR, \fBmvwinch\fR @@ -16,18 +17,19 @@ .SH DESCRIPTION These routines return the character, of type \fBchtype\fR, at the current position in the named window. If any attributes are set for that position, -their values are OR-ed into the value returned. Constants defined in +their values are OR'ed into the value returned. Constants defined in \fB<curses.h>\fR can be used with the \fB&\fR (logical AND) operator to extract the character or attributes alone. .SS Attributes The following bit-masks may be AND-ed with characters returned by \fBwinch\fR. -.nf -\fBA_CHARTEXT\fR Bit-mask to extract character -\fBA_ATTRIBUTES\fR Bit-mask to extract attributes -\fBA_COLOR\fR Bit-mask to extract color-pair field information -.fi +.TS +l l . +\fBA_CHARTEXT\fR Bit-mask to extract character +\fBA_ATTRIBUTES\fR Bit-mask to extract attributes +\fBA_COLOR\fR Bit-mask to extract color-pair field information +.TE .SH NOTES Note that all of these routines may be macros. .SH PORTABILITY diff --git a/lib/libcurses/curs_insstr.3 b/lib/libcurses/curs_insstr.3 index 7d99d50598f..8c3c0af6a45 100644 --- a/lib/libcurses/curs_insstr.3 +++ b/lib/libcurses/curs_insstr.3 @@ -49,7 +49,7 @@ Note that all but \fBwinsnstr\fR may be macros. These functions are described in the XSI Curses standard, Issue 4, which adds const qualifiers to the arguments. The XSI Curses error conditions \fBEILSEQ\fR and \fBEILOVERFLOW\fR associated with extended-level conformance -are not yet detected (this implementation does not yet support XPG4 multibyte +are not yet detected (this implementation does not yet support XPG4 multi-byte characters). .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_clear\fR(3X), \fBcurs_inch\fR(3X). diff --git a/lib/libcurses/curs_instr.3 b/lib/libcurses/curs_instr.3 index e7c681664a5..34be1cb3c69 100644 --- a/lib/libcurses/curs_instr.3 +++ b/lib/libcurses/curs_instr.3 @@ -1,3 +1,4 @@ +.\" Id: curs_instr.3x,v 1.7 1997/03/15 23:25:24 tom Exp $ .TH curs_instr 3X "" .SH NAME \fBinstr\fR, \fBinnstr\fR, \fBwinstr\fR, \fBwinnstr\fR, @@ -24,24 +25,26 @@ of characters from a \fBcurses\fR window .br .SH DESCRIPTION These routines return a string of characters in \fIstr\fR, extracted starting -at the current cursor position in the named window and ending at the right -margin of the window. Attributes are stripped from the characters. The four +at the current cursor position in the named window. +Attributes are stripped from the characters. The four functions with \fIn\fR as the last argument return a leading substring at most \fIn\fR characters long (exclusive of the trailing NUL). .SH RETURN VALUE -All routines that return an integer return \fBERR\fR upon failure and OK (SVr4 -specifies only "an integer value other than \fBERR\fR") upon successful -completion, unless otherwise noted in the preceding routine descriptions. +All of the functions return \fBERR\fR upon failure, +or the number of characters actually read into the string. .SH NOTES -Note that all routines except \fBwinnstr\fR may be macros. SVr4 does not -document whether a length limit includes or excludes the trailing NUL, and -does not document the meaning of the return values. +Note that all routines except \fBwinnstr\fR may be macros. .SH PORTABILITY -These functions are described in the XSI Curses standard, Issue 4. The -standard specifies that they always return \fBOK\fR on success. The XSI Curses +The XSI Curses error conditions \fBEILSEQ\fR and \fBEILOVERFLOW\fR associated with -extebded-level conformance are not yet detected (this implementation does not -yet support XPG4 multibyte characters). +extended-level conformance are not yet detected (this implementation does not +yet support XPG4 multi-byte characters). +SVr4 does not +document whether a length limit includes or excludes the trailing NUL. +.PP +The curses library extends the XSI description by allowing a negative +value for \fIn\fR. +In this case, the functions return the string ending at the right margin. .SH SEE ALSO \fBcurses\fR(3X). .\"# diff --git a/lib/libcurses/curs_kernel.3 b/lib/libcurses/curs_kernel.3 index 7fda81b2560..ffba687f89c 100644 --- a/lib/libcurses/curs_kernel.3 +++ b/lib/libcurses/curs_kernel.3 @@ -27,7 +27,7 @@ .br \fBint curs_set(int visibility);\fR .br -\fBint napms(unsigned int ms);\fR +\fBint napms(int ms);\fR .br .SH DESCRIPTION The following routines give low-level access to various \fBcurses\fR diff --git a/lib/libcurses/curs_mouse.3 b/lib/libcurses/curs_mouse.3 index 4781f99bed8..988bbc32b6a 100644 --- a/lib/libcurses/curs_mouse.3 +++ b/lib/libcurses/curs_mouse.3 @@ -132,7 +132,7 @@ running on your machine, mouse events will not be visible to return \fB0\fR). The z member in the event structure is not presently used. It is intended -for use with touchscreens (which may be pressure-sensitive) or with +for use with touch screens (which may be pressure-sensitive) or with 3D-mice/trackballs/power gloves. .SH BUGS Mouse events under xterm will not in fact be ignored during cooked mode, diff --git a/lib/libcurses/curs_outopts.3 b/lib/libcurses/curs_outopts.3 index e69383b4ad4..1e56ab12a77 100644 --- a/lib/libcurses/curs_outopts.3 +++ b/lib/libcurses/curs_outopts.3 @@ -39,24 +39,25 @@ the \fIwin\fR argument to \fBclearok\fR is the global variable \fBcurscr\fR, the next call to \fBwrefresh\fR with any window causes the screen to be cleared and repainted from scratch. -If \fBidlok\fR is called with \fBTRUE\fR as argument, -\fBcurses\fR considers using the hardware insert/delete line feature of -terminals so equipped. If disabled (\fIbf\fR is \fBFALSE\fR), \fBcurses\fR -very seldom uses this feature. (The insert/delete character feature is always -considered.) This option should be enabled only if the application needs -insert/delete line, for example, for a screen editor. It is disabled by -default because insert/delete line tends to be visually annoying when used in -applications where it isn't really needed. If insert/delete line cannot be -used, \fBcurses\fR redraws the changed portions of all lines. +If \fBidlok\fR is called with \fBTRUE\fR as second argument, \fBcurses\fR +considers using the hardware insert/delete line feature of terminals so +equipped. Calling \fBidlok\fR with \fBFALSE\fR as second argument disables use +of line insertion and deletion. This option should be enabled only if the +application needs insert/delete line, for example, for a screen editor. It is +disabled by default because insert/delete line tends to be visually annoying +when used in applications where it isn't really needed. If insert/delete line +cannot be used, \fBcurses\fR redraws the changed portions of all lines. -If \fBidcok\fR is called with \fBTRUE\fR as argument, -\fBcurses\fR considers using the hardware insert/delete character feature of -terminals so equipped. This is enabled by default. +If \fBidcok\fR is called with \fBFALSE\fR as second argument, \fBcurses\fR +no longer considers using the hardware insert/delete character feature of +terminals so equipped. Use of character insert/delete is enabled by default. +Calling \fBidcok\fR with \fBTRUE\fR as second argument re-enables use +of character insertion and deletion. If \fBimmedok\fR is called with \fBTRUE as argument\fR, any change in the window image, such as the ones caused by \fBwaddch, wclrtobot, wscrl\fR, \fIetc\fR., automatically cause a call to \fBwrefresh\fR. However, it may -degrade the performance considerably, due to repeated calls to \fBwrefresh\fR. +degrade performance considerably, due to repeated calls to \fBwrefresh\fR. It is disabled by default. Normally, the hardware cursor is left at the location of the window cursor diff --git a/lib/libcurses/curs_print.3 b/lib/libcurses/curs_print.3 new file mode 100644 index 00000000000..ee45d9f51c4 --- /dev/null +++ b/lib/libcurses/curs_print.3 @@ -0,0 +1,45 @@ +.TH curs_print 3X "" +.SH NAME +\fBmcprint\fR - ship binary data to printer +.SH SYNOPSIS +\fB#include <curses.h>\fR + +\fBint mcprint(char *data, int len);\fR +.SH DESCRIPTION +This function uses the \fBmc5p\fR or \fBmc4\fR and \fBmc5\fR capabilities, +if they are present, to ship given data to a printer attached to the terminal. + +Note that the \fBmcprint\fR code has no way to do flow control with the printer +or to know how much buffering it has. Your application is responsible for +keeping the rate of writes to the printer below its continuous throughput rate +(typically about half of its nominal cps rating). Dot-matrix printers and +6-page-per-minute lasers can typically handle 80cps, so a good conservative +rule of thumb is to sleep for a second after shipping each 80-character line. + +.SH RETURN VALUE +The \fBmcprint\fR function returns \fBERR\fR if the write operation aborted +for some reason. In this case, errno will contain either an error associated +with \fBwrite(2)\fR or one of the following: +.TP 5 +ENODEV +Capabilities for printer redirection don't exist. +.TP 5 +ENOMEM +Couldn't allocate sufficient memory to buffer the printer write. + +When \fBmcprint\fR succeeds, it returns the number of characters actually +sent to the printer. +.SH PORTABILITY +The \fBmcprint\fR call was designed for \fBcurses\fR(3x), and is not found +in SVr4 curses, 4.4BSD curses, or any other previous version of curses. +.SH BUGS +Padding in the \fBmc5p\fR, \fBmc4\fR and \fBmc5\fR capabilities will not be +interpreted. +.SH SEE ALSO +\fBcurses\fR(3X)\fR +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/lib/libcurses/curs_printw.3 b/lib/libcurses/curs_printw.3 index c6db4c099ce..e3ac2e8d5ed 100644 --- a/lib/libcurses/curs_printw.3 +++ b/lib/libcurses/curs_printw.3 @@ -31,7 +31,7 @@ argument list. The third argument is a \fBva_list\fR, a pointer to a list of arguments, as defined in \fB<varargs.h>\fR. .SH RETURN VALUE Routines that return an integer return \fBERR\fR upon failure and \fBOK\fR -(SVr4 onlyspecifies "an integer value other than \fBERR\fR") upon successful +(SVr4 only specifies "an integer value other than \fBERR\fR") upon successful completion. .SH PORTABILITY The XSI Curses standard, Issue 4 describes these functions. The function diff --git a/lib/libcurses/curs_slk.3 b/lib/libcurses/curs_slk.3 index e735b9f2666..f1fda3908d7 100644 --- a/lib/libcurses/curs_slk.3 +++ b/lib/libcurses/curs_slk.3 @@ -27,6 +27,8 @@ .br \fBint slk_attrset(attr_t attrs);\fR .br +\fBattr_t slk_attr(void);\fR +.br \fBint slk_attroff(attr_t attrs);\fR .br .SH DESCRIPTION @@ -34,20 +36,29 @@ The slk* functions manipulate the set of soft function-key labels that exist on many terminals. For those terminals that do not have soft labels, \fBcurses\fR takes over the bottom line of \fBstdscr\fR, reducing the size of \fBstdscr\fR and the variable \fBLINES\fR. \fBcurses\fR standardizes on eight -labels of up to eight characters each. +labels of up to eight characters each. In addition to this, the curses +implementation supports a mode where it simulates 12 labels of up to five +characters each. This is most common for todays PC like enduser devices. +Please note that curses simulates this mode by taking over up to two lines at +the bottom of the screen, it doesn't try to use any hardware support for this +mode. The \fBslk_init\fR routine must be called before \fBinitscr\fR or \fBnewterm\fR is called. If \fBinitscr\fR eventually uses a line from \fBstdscr\fR to emulate the soft labels, then \fIfmt\fR determines how the labels are arranged on the screen. Setting \fIfmt\fR to \fB0\fR indicates a 3-2-3 arrangement of -the labels; \fB1\fR indicates a 4-4 arrangement. +the labels, \fB1\fR indicates a 4-4 arrangement and \fB2\fR indicates the +PC like 4-4-4 mode. If \fBfmt\fR is set to \fB3\fR, it is again the PC like +4-4-4 mode, but in addition an index line is generated, helping the user to +identify the key numbers easily. The \fBslk_set\fR routine requires \fIlabnum\fR to be a label number, -from \fB1\fR to \fB8\fR; \fIlabel\fR must be the string to be put on the -label, up to eight characters in length. A null string or a null -pointer sets up a blank label. \fIfmt\fR is either \fB0\fR, \fB1\fR, -or \fB2\fR, indicating whether the label is to be left-justified, -centered, or right-justified, respectively, within the label. +from \fB1\fR to \fB8\fR (resp. \fB12\fR); \fIlabel\fR must be the string +to be put on the label, up to eight (resp. five) characters in length. +A null string or a null pointer sets up a blank label. \fIfmt\fR is either +\fB0\fR, \fB1\fR, or \fB2\fR, indicating whether the label is to be +left-justified, centered, or right-justified, respectively, within the +label. The \fBslk_refresh\fR and \fBslk_noutrefresh\fR routines correspond to the \fBwrefresh\fR and \fBwnoutrefresh\fR routines. @@ -63,14 +74,15 @@ after a \fBslk_clear\fR has been performed. The \fBslk_touch\fR routine forces all the soft labels to be output the next time a \fBslk_noutrefresh\fR is performed. -The \fBslk_attron\fR, \fBslk_attrset\fR and \fBslk_attroff\fR routines -correspond to \fBattron\fR, \fBattrset\fR, and \fBattroff\fR. They -have an effect only if soft labels are simulated on the bottom line of +The \fBslk_attron\fR, \fBslk_attrset\fR, \fBslk_attroff\fR and \fBslk_attr\fR +routines correspond to \fBattron\fR, \fBattrset\fR, \fBattroff\fR and \fBattr_get\fR. +They have an effect only if soft labels are simulated on the bottom line of the screen. The default highlight for soft keys is A_STANDOUT (as in System V curses, which does not document this fact). .SH RETURN VALUE These routines return \fBERR\fR upon failure and OK (SVr4 specifies only "an -integer value other than \fBERR\fR") upon successful completion. +integer value other than \fBERR\fR") upon successful completion. \fBslk_attr\fR +returns the attribute used for the soft keys. \fBslk_label\fR returns \fBNULL\fR on error. .SH NOTES @@ -80,7 +92,8 @@ Most applications would use \fBslk_noutrefresh\fR because a The XSI Curses standard, Issue 4, describes these functions. It changes the argument type of the attribute-manipulation functions \fBslk_attron\fR, \fBslk_attroff\fR, \fBslk_attrset\fR to be \fBattr_t\fR, and adds \fBconst\fR -qualifiers. +qualifiers. The format codes \fB2\fR and \fB3\fR for \fBslk_init()\fR and the +function \fBslk_attr\fR are specific to curses. .SH SEE ALSO \fBcurses\fR(3X), \fBcurs_attr\fR(3X), \fBcurs_initscr\fR(3X), \fBcurs_refresh\fR(3X) .\"# diff --git a/lib/libcurses/curses.3 b/lib/libcurses/curses.3 index a47086d4871..6ef4b0a28bd 100644 --- a/lib/libcurses/curses.3 +++ b/lib/libcurses/curses.3 @@ -1,3 +1,4 @@ +.\" Id: ncurses.3x,v 1.19 1997/01/05 00:42:39 tom Exp $ .TH curses 3X "" .ds n 5 .ds d /usr/share/terminfo @@ -10,7 +11,7 @@ The \fBcurses\fR library routines give the user a terminal-independent method of updating character screens with reasonable optimization. This implementation is ``new curses'' (ncurses) and is the approved replacement for -4.4BSD classic curses, which is being discontinued. +4.4BSD classic curses, which has been discontinued. The \fBcurses\fR routines emulate the \fBcurses\fR(3X) library of System V Release 4 UNIX, and the XPG4 curses standard (XSI curses) but the \fBcurses\fR @@ -156,273 +157,280 @@ The following table lists each \fBcurses\fR routine and the name of the manual page on which it is described. Routines flagged with `*' are ncurses-specific, not described by XPG4 or present in SVr4. -.nf -\fBcurses\fR Routine Name Manual Page Name -___________________________________________ -addch curs_addch(3X) -addchnstr curs_addchstr(3X) -addchstr curs_addchstr(3X) -addnstr curs_addstr(3X) -addstr curs_addstr(3X) -attroff curs_attr(3X) -attron curs_attr(3X) -attrset curs_attr(3X) -baudrate curs_termattrs(3X) -beep curs_beep(3X) -bkgd curs_bkgd(3X) -bkgdset curs_bkgd(3X) -border curs_border(3X) -box curs_border(3X) -can_change_color curs_color(3X) -cbreak curs_inopts(3X) -clear curs_clear(3X) -clearok curs_outopts(3X) -clrtobot curs_clear(3X) -clrtoeol curs_clear(3X) -color_content curs_color(3X) -copywin curs_overlay(3X) -curs_set curs_kernel(3X) -def_prog_mode curs_kernel(3X) -def_shell_mode curs_kernel(3X) -del_curterm curs_terminfo(3X) -delay_output curs_util(3X) -delch curs_delch(3X) -deleteln curs_deleteln(3X) -delscreen curs_initscr(3X) -delwin curs_window(3X) -derwin curs_window(3X) -doupdate curs_refresh(3X) -dupwin curs_window(3X) -echo curs_inopts(3X) -echochar curs_addch(3X) -endwin curs_initscr(3X) -erase curs_clear(3X) -erasechar curs_termattrs(3X) -filter curs_util(3X) -flash curs_beep(3X) -flushinp curs_util(3X) -getbegyx curs_getyx(3X) -getch curs_getch(3X) -getmaxyx curs_getyx(3X) -getmouse curs_mouse(3X)* -getparyx curs_getyx(3X) -getstr curs_getstr(3X) -getsyx curs_kernel(3X) -getwin curs_util(3X) -getyx curs_getyx(3X) -halfdelay curs_inopts(3X) -has_colors curs_color(3X) -has_ic curs_termattrs(3X) -has_il curs_termattrs(3X) -hline curs_border(3X) -idcok curs_outopts(3X) -idlok curs_outopts(3X) -immedok curs_outopts(3X) -inch curs_inch(3X) -inchnstr curs_inchstr(3X) -inchstr curs_inchstr(3X) -init_color curs_color(3X) -init_pair curs_color(3X) -initscr curs_initscr(3X) -innstr curs_instr(3X) -insch curs_insch(3X) -insdelln curs_deleteln(3X) -insertln curs_deleteln(3X) -insnstr curs_insstr(3X) -insstr curs_insstr(3X) -instr curs_instr(3X) -intrflush curs_inopts(3X) -is_linetouched curs_touch(3X) -is_wintouched curs_touch(3X) -isendwin curs_initscr(3X) -keyname curs_util(3X) -keypad curs_inopts(3X) -killchar curs_termattrs(3X) -leaveok curs_outopts(3X) -longname curs_termattrs(3X) -meta curs_inopts(3X) -mouseinterval curs_mouse(3X)* -mousemask curs_mouse(3X)* -move curs_move(3X) -mvaddch curs_addch(3X) -mvaddchnstr curs_addchstr(3X) -mvaddchstr curs_addchstr(3X) -mvaddnstr curs_addstr(3X) -mvaddstr curs_addstr(3X) -mvcur curs_terminfo(3X) -mvdelch curs_delch(3X) -mvderwin curs_window(3X) -mvgetch curs_getch(3X) -mvgetstr curs_getstr(3X) -mvinch curs_inch(3X) -mvinchnstr curs_inchstr(3X) -mvinchstr curs_inchstr(3X) -mvinnstr curs_instr(3X) -mvinsch curs_insch(3X) -mvinsnstr curs_insstr(3X) -mvinsstr curs_insstr(3X) -mvinstr curs_instr(3X) -mvprintw curs_printw(3X) -mvscanw curs_scanw(3X) -mvwaddch curs_addch(3X) -mvwaddchnstr curs_addchstr(3X) -mvwaddchstr curs_addchstr(3X) -mvwaddnstr curs_addstr(3X) -mvwaddstr curs_addstr(3X) -mvwdelch curs_delch(3X) -mvwgetch curs_getch(3X) -mvwgetstr curs_getstr(3X) -mvwin curs_window(3X) -mvwinch curs_inch(3X) -mvwinchnstr curs_inchstr(3X) -mvwinchstr curs_inchstr(3X) -mvwinnstr curs_instr(3X) -mvwinsch curs_insch(3X) -mvwinsnstr curs_insstr(3X) -mvwinsstr curs_insstr(3X) -mvwinstr curs_instr(3X) -mvwprintw curs_printw(3X) -mvwscanw curs_scanw(3X) -napms curs_kernel(3X) -newpad curs_pad(3X) -newterm curs_initscr(3X) -newwin curs_window(3X) -nl curs_outopts(3X) -nocbreak curs_inopts(3X) -nodelay curs_inopts(3X) -noecho curs_inopts(3X) -nonl curs_outopts(3X) -noqiflush curs_inopts(3X) -noraw curs_inopts(3X) -notimeout curs_inopts(3X) -overlay curs_overlay(3X) -overwrite curs_overlay(3X) -pair_content curs_color(3X) -pechochar curs_pad(3X) -pnoutrefresh curs_pad(3X) -prefresh curs_pad(3X) -printw curs_printw(3X) -putp curs_terminfo(3X) -putwin curs_util(3X) -qiflush curs_inopts(3X) -raw curs_inopts(3X) -redrawwin curs_refresh(3X) -refresh curs_refresh(3X) -reset_prog_mode curs_kernel(3X) -reset_shell_mode curs_kernel(3X) -resetty curs_kernel(3X) -restartterm curs_terminfo(3X) -ripoffline curs_kernel(3X) -savetty curs_kernel(3X) -scanw curs_scanw(3X) -scr_dump curs_scr_dump(3X) -scr_init curs_scr_dump(3X) -scr_restore curs_scr_dump(3X) -scr_set curs_scr_dump(3X) -scrl curs_scroll(3X) -scroll curs_scroll(3X) -scrollok curs_outopts(3X) -set_curterm curs_terminfo(3X) -set_term curs_initscr(3X) -setscrreg curs_outopts(3X) -setsyx curs_kernel(3X) -setterm curs_terminfo(3X) -setupterm curs_terminfo(3X) -slk_attroff curs_slk(3X) -slk_attron curs_slk(3X) -slk_attrset curs_slk(3X) -slk_clear curs_slk(3X) -slk_init curs_slk(3X) -slk_label curs_slk(3X) -slk_noutrefresh curs_slk(3X) -slk_refresh curs_slk(3X) -slk_restore curs_slk(3X) -slk_set curs_slk(3X) -slk_touch curs_slk(3X) -standend curs_attr(3X) -standout curs_attr(3X) -start_color curs_color(3X) -subpad curs_pad(3X) -subwin curs_window(3X) -syncok curs_window(3X) -termattrs curs_termattrs(3X) -termname curs_termattrs(3X) -tgetent curs_termcap(3X) -tgetflag curs_termcap(3X) -tgetnum curs_termcap(3X) -tgetstr curs_termcap(3X) -tgoto curs_termcap(3X) -tigetflag curs_terminfo(3X) -tigetnum curs_terminfo(3X) -tigetstr curs_terminfo(3X) -timeout curs_inopts(3X) -touchline curs_touch(3X) -touchwin curs_touch(3X) -tparm curs_terminfo(3X) -tputs curs_termcap(3X) -tputs curs_terminfo(3X) -typeahead curs_inopts(3X) -unctrl curs_util(3X) -ungetch curs_getch(3X) -ungetmouse curs_mouse(3X)* -untouchwin curs_touch(3X) -use_env curs_util(3X) -vidattr curs_terminfo(3X) -vidputs curs_terminfo(3X) -vline curs_border(3X) -vwprintw curs_printw(3X) -vwscanw curs_scanw(3X) -waddch curs_addch(3X) -waddchnstr curs_addchstr(3X) -waddchstr curs_addchstr(3X) -waddnstr curs_addstr(3X) -waddstr curs_addstr(3X) -wattroff curs_attr(3X) -wattron curs_attr(3X) -wattrset curs_attr(3X) -wbkgd curs_bkgd(3X) -wbkgdset curs_bkgd(3X) -wborder curs_border(3X) -wclear curs_clear(3X) -wclrtobot curs_clear(3X) -wclrtoeol curs_clear(3X) -wcursyncup curs_window(3X) -wdelch curs_delch(3X) -wdeleteln curs_deleteln(3X) -wechochar curs_addch(3X) -wenclose curs_mouse(3X)* -werase curs_clear(3X) -wgetch curs_getch(3X) -wgetnstr curs_getstr(3X) -wgetstr curs_getstr(3X) -whline curs_border(3X) -winch curs_inch(3X) -winchnstr curs_inchstr(3X) -winchstr curs_inchstr(3X) -winnstr curs_instr(3X) -winsch curs_insch(3X) -winsdelln curs_deleteln(3X) -winsertln curs_deleteln(3X) -winsnstr curs_insstr(3X) -winsstr curs_insstr(3X) -winstr curs_instr(3X) -wmove curs_move(3X) -wnoutrefresh curs_refresh(3X) -wprintw curs_printw(3X) -wredrawln curs_refresh(3X) -wrefresh curs_refresh(3X) -wresize curs_resize(3x)* -wscanw curs_scanw(3X) -wscrl curs_scroll(3X) -wsetscrreg curs_outopts(3X) -wstandend curs_attr(3X) -wstandout curs_attr(3X) -wsyncdown curs_window(3X) -wsyncup curs_window(3X) -wtimeout curs_inopts(3X) -wtouchln curs_touch(3X) -wvline curs_border(3X) -.fi +.TS +center tab(/); +l l +l l . +\fBcurses\fR Routine Name/Manual Page Name += +addch/curs_addch(3X) +addchnstr/curs_addchstr(3X) +addchstr/curs_addchstr(3X) +addnstr/curs_addstr(3X) +addstr/curs_addstr(3X) +attroff/curs_attr(3X) +attron/curs_attr(3X) +attrset/curs_attr(3X) +baudrate/curs_termattrs(3X) +beep/curs_beep(3X) +bkgd/curs_bkgd(3X) +bkgdset/curs_bkgd(3X) +border/curs_border(3X) +box/curs_border(3X) +can_change_color/curs_color(3X) +cbreak/curs_inopts(3X) +clear/curs_clear(3X) +clearok/curs_outopts(3X) +clrtobot/curs_clear(3X) +clrtoeol/curs_clear(3X) +color_content/curs_color(3X) +copywin/curs_overlay(3X) +curs_set/curs_kernel(3X) +def_prog_mode/curs_kernel(3X) +def_shell_mode/curs_kernel(3X) +del_curterm/curs_terminfo(3X) +delay_output/curs_util(3X) +delch/curs_delch(3X) +deleteln/curs_deleteln(3X) +delscreen/curs_initscr(3X) +delwin/curs_window(3X) +derwin/curs_window(3X) +doupdate/curs_refresh(3X) +dupwin/curs_window(3X) +echo/curs_inopts(3X) +echochar/curs_addch(3X) +endwin/curs_initscr(3X) +erase/curs_clear(3X) +erasechar/curs_termattrs(3X) +filter/curs_util(3X) +flash/curs_beep(3X) +flushinp/curs_util(3X) +getbegyx/curs_getyx(3X) +getch/curs_getch(3X) +getmaxyx/curs_getyx(3X) +getmouse/curs_mouse(3X)* +getparyx/curs_getyx(3X) +getstr/curs_getstr(3X) +getsyx/curs_kernel(3X) +getwin/curs_util(3X) +getyx/curs_getyx(3X) +halfdelay/curs_inopts(3X) +has_colors/curs_color(3X) +has_ic/curs_termattrs(3X) +has_il/curs_termattrs(3X) +has_key/curs_getch(3X)* +hline/curs_border(3X) +idcok/curs_outopts(3X) +idlok/curs_outopts(3X) +immedok/curs_outopts(3X) +inch/curs_inch(3X) +inchnstr/curs_inchstr(3X) +inchstr/curs_inchstr(3X) +init_color/curs_color(3X) +init_pair/curs_color(3X) +initscr/curs_initscr(3X) +innstr/curs_instr(3X) +insch/curs_insch(3X) +insdelln/curs_deleteln(3X) +insertln/curs_deleteln(3X) +insnstr/curs_insstr(3X) +insstr/curs_insstr(3X) +instr/curs_instr(3X) +intrflush/curs_inopts(3X) +is_linetouched/curs_touch(3X) +is_wintouched/curs_touch(3X) +isendwin/curs_initscr(3X) +keyname/curs_util(3X) +keypad/curs_inopts(3X) +killchar/curs_termattrs(3X) +leaveok/curs_outopts(3X) +longname/curs_termattrs(3X) +mcprint/curs_print(3X)* +meta/curs_inopts(3X) +mouseinterval/curs_mouse(3X)* +mousemask/curs_mouse(3X)* +move/curs_move(3X) +mvaddch/curs_addch(3X) +mvaddchnstr/curs_addchstr(3X) +mvaddchstr/curs_addchstr(3X) +mvaddnstr/curs_addstr(3X) +mvaddstr/curs_addstr(3X) +mvcur/curs_terminfo(3X) +mvdelch/curs_delch(3X) +mvderwin/curs_window(3X) +mvgetch/curs_getch(3X) +mvgetstr/curs_getstr(3X) +mvinch/curs_inch(3X) +mvinchnstr/curs_inchstr(3X) +mvinchstr/curs_inchstr(3X) +mvinnstr/curs_instr(3X) +mvinsch/curs_insch(3X) +mvinsnstr/curs_insstr(3X) +mvinsstr/curs_insstr(3X) +mvinstr/curs_instr(3X) +mvprintw/curs_printw(3X) +mvscanw/curs_scanw(3X) +mvwaddch/curs_addch(3X) +mvwaddchnstr/curs_addchstr(3X) +mvwaddchstr/curs_addchstr(3X) +mvwaddnstr/curs_addstr(3X) +mvwaddstr/curs_addstr(3X) +mvwdelch/curs_delch(3X) +mvwgetch/curs_getch(3X) +mvwgetstr/curs_getstr(3X) +mvwin/curs_window(3X) +mvwinch/curs_inch(3X) +mvwinchnstr/curs_inchstr(3X) +mvwinchstr/curs_inchstr(3X) +mvwinnstr/curs_instr(3X) +mvwinsch/curs_insch(3X) +mvwinsnstr/curs_insstr(3X) +mvwinsstr/curs_insstr(3X) +mvwinstr/curs_instr(3X) +mvwprintw/curs_printw(3X) +mvwscanw/curs_scanw(3X) +napms/curs_kernel(3X) +newpad/curs_pad(3X) +newterm/curs_initscr(3X) +newwin/curs_window(3X) +nl/curs_outopts(3X) +nocbreak/curs_inopts(3X) +nodelay/curs_inopts(3X) +noecho/curs_inopts(3X) +nonl/curs_outopts(3X) +noqiflush/curs_inopts(3X) +noraw/curs_inopts(3X) +notimeout/curs_inopts(3X) +overlay/curs_overlay(3X) +overwrite/curs_overlay(3X) +pair_content/curs_color(3X) +pechochar/curs_pad(3X) +pnoutrefresh/curs_pad(3X) +prefresh/curs_pad(3X) +printw/curs_printw(3X) +putp/curs_terminfo(3X) +putwin/curs_util(3X) +qiflush/curs_inopts(3X) +raw/curs_inopts(3X) +redrawwin/curs_refresh(3X) +refresh/curs_refresh(3X) +reset_prog_mode/curs_kernel(3X) +reset_shell_mode/curs_kernel(3X) +resetty/curs_kernel(3X) +resizeterm/resizeterm(3x)* +restartterm/curs_terminfo(3X) +ripoffline/curs_kernel(3X) +savetty/curs_kernel(3X) +scanw/curs_scanw(3X) +scr_dump/curs_scr_dump(3X) +scr_init/curs_scr_dump(3X) +scr_restore/curs_scr_dump(3X) +scr_set/curs_scr_dump(3X) +scrl/curs_scroll(3X) +scroll/curs_scroll(3X) +scrollok/curs_outopts(3X) +set_curterm/curs_terminfo(3X) +set_term/curs_initscr(3X) +setscrreg/curs_outopts(3X) +setsyx/curs_kernel(3X) +setterm/curs_terminfo(3X) +setupterm/curs_terminfo(3X) +slk_attr/curs_slk(3X)* +slk_attroff/curs_slk(3X) +slk_attron/curs_slk(3X) +slk_attrset/curs_slk(3X) +slk_clear/curs_slk(3X) +slk_init/curs_slk(3X) +slk_label/curs_slk(3X) +slk_noutrefresh/curs_slk(3X) +slk_refresh/curs_slk(3X) +slk_restore/curs_slk(3X) +slk_set/curs_slk(3X) +slk_touch/curs_slk(3X) +standend/curs_attr(3X) +standout/curs_attr(3X) +start_color/curs_color(3X) +subpad/curs_pad(3X) +subwin/curs_window(3X) +syncok/curs_window(3X) +termattrs/curs_termattrs(3X) +termname/curs_termattrs(3X) +tgetent/curs_termcap(3X) +tgetflag/curs_termcap(3X) +tgetnum/curs_termcap(3X) +tgetstr/curs_termcap(3X) +tgoto/curs_termcap(3X) +tigetflag/curs_terminfo(3X) +tigetnum/curs_terminfo(3X) +tigetstr/curs_terminfo(3X) +timeout/curs_inopts(3X) +touchline/curs_touch(3X) +touchwin/curs_touch(3X) +tparm/curs_terminfo(3X) +tputs/curs_termcap(3X) +tputs/curs_terminfo(3X) +typeahead/curs_inopts(3X) +unctrl/curs_util(3X) +ungetch/curs_getch(3X) +ungetmouse/curs_mouse(3X)* +untouchwin/curs_touch(3X) +use_env/curs_util(3X) +vidattr/curs_terminfo(3X) +vidputs/curs_terminfo(3X) +vline/curs_border(3X) +vwprintw/curs_printw(3X) +vwscanw/curs_scanw(3X) +waddch/curs_addch(3X) +waddchnstr/curs_addchstr(3X) +waddchstr/curs_addchstr(3X) +waddnstr/curs_addstr(3X) +waddstr/curs_addstr(3X) +wattroff/curs_attr(3X) +wattron/curs_attr(3X) +wattrset/curs_attr(3X) +wbkgd/curs_bkgd(3X) +wbkgdset/curs_bkgd(3X) +wborder/curs_border(3X) +wclear/curs_clear(3X) +wclrtobot/curs_clear(3X) +wclrtoeol/curs_clear(3X) +wcursyncup/curs_window(3X) +wdelch/curs_delch(3X) +wdeleteln/curs_deleteln(3X) +wechochar/curs_addch(3X) +wenclose/curs_mouse(3X)* +werase/curs_clear(3X) +wgetch/curs_getch(3X) +wgetnstr/curs_getstr(3X) +wgetstr/curs_getstr(3X) +whline/curs_border(3X) +winch/curs_inch(3X) +winchnstr/curs_inchstr(3X) +winchstr/curs_inchstr(3X) +winnstr/curs_instr(3X) +winsch/curs_insch(3X) +winsdelln/curs_deleteln(3X) +winsertln/curs_deleteln(3X) +winsnstr/curs_insstr(3X) +winsstr/curs_insstr(3X) +winstr/curs_instr(3X) +wmove/curs_move(3X) +wnoutrefresh/curs_refresh(3X) +wprintw/curs_printw(3X) +wredrawln/curs_refresh(3X) +wrefresh/curs_refresh(3X) +wresize/wresize(3x)* +wscanw/curs_scanw(3X) +wscrl/curs_scroll(3X) +wsetscrreg/curs_outopts(3X) +wstandend/curs_attr(3X) +wstandout/curs_attr(3X) +wsyncdown/curs_window(3X) +wsyncup/curs_window(3X) +wtimeout/curs_inopts(3X) +wtouchln/curs_touch(3X) +wvline/curs_border(3X) +.TE .SH RETURN VALUE Routines that return an integer return \fBERR\fR upon failure and an integer value other than \fBERR\fR upon successful completion, unless @@ -463,6 +471,14 @@ Versions of \fBcurses\fR compiled on PC clones support display of the PC ROM characters (including ROM characters 0-31, which stock SVr4 curses cannot display). See the EXTENSIONS sections of \fBcurs_addch\fR(3x) and \fBcurs_attr\fR(3x). + +The \fBcurses\fR library includes facilities for capturing mouse events on +certain terminals (including xterm). See the \fBcurs_mouse\fR(3X) +manual page for details. + +The \fBcurses\fR library includes a function for directing application output +to a printer attached to the terminal device. See the \fBcurs_print\fR(3X) +manual page for details. .SH PORTABILITY The \fBcurses\fR library is intended to be BASE-level conformant with the XSI Curses standard. Certain portions of the EXTENDED XSI Curses functionality @@ -558,20 +574,22 @@ A small number of local differences (that is, individual differences between the XSI Curses and \fBcurses\fR calls) are described in \fBPORTABILITY\fR sections of the library man pages. .PP -The terminfo format supported by \fBcurses\fR is binary-compatible with SVr4, -but not conformant with XSI curses. This is because the XSI Curses drafters, -in a remarkable fit of braindamage, changed the undocumented SVr4 capability -\fBgetm\fR from a string to a boolean, changing the binary offsets of all -capabilities after it in the SVr4 order and making it impossible for any -SVr4-compatible implementation to be fully conformant. +The routine \fBhas_key\fR is not part of XPG4, nor is it present in SVr4. See +the \fBcurs_getch\fR(3X) manual page for details. +.PP +The routine \fBslk_attr\fR is not part of XPG4, nor is it present in SVr4. See +the \fBcurs_slk\fR(3X) manual page for details. .PP The routines \fBgetmouse\fR, \fBmousemask\fR, \fBungetmouse\fR, \fBmouseinterval\fR, and \fBwenclose\fR relating to mouse interfacing are not part of XPG4, nor are they present in SVr4. See the \fBcurs_mouse\fR(3X) manual page for details. .PP +The routine \fBmcprint\fR was not present in any previous curses +implementation. See the \fBcurs_print\fR(3X) manual page for details. +.PP The routine \fBwresize\fR is not part of XPG4, nor is it present in SVr4. See -the \fBcurs_resize\fR(3X) manual page for details. +the \fBwresize\fR(3X) manual page for details. .PP In historic curses versions, delays embedded in the capabilities \fBcr\fR, \fBind\fR, \fBcub1\fR, \fBff\fR and \fBtab\fR activated corresponding delay diff --git a/lib/libcurses/curses.h b/lib/libcurses/curses.h index 95c2c95a5a4..5710984870e 100644 --- a/lib/libcurses/curses.h +++ b/lib/libcurses/curses.h @@ -1,4 +1,3 @@ - /*************************************************************************** * COPYRIGHT NOTICE * **************************************************************************** @@ -19,21 +18,48 @@ * * ***************************************************************************/ +/* Id: curses.h.in,v 1.44 1997/04/20 01:32:08 tom Exp $ */ #ifndef __NCURSES_H #define __NCURSES_H #define CURSES 1 #define CURSES_H 1 -#define NCURSES_VERSION "1.9.9e" +/* These are defined only in curses.h, and are used for conditional compiles */ +#define NCURSES_VERSION_MAJOR 4 +#define NCURSES_VERSION_MINOR 1 +#define NCURSES_VERSION_PATCH 970515 + +/* This is defined in more than one ncurses header, for identification */ +#undef NCURSES_VERSION +#define NCURSES_VERSION "4.1" + +#ifdef NCURSES_NOMACROS +#define NCURSES_ATTR_T attr_t +#endif + +#ifndef NCURSES_ATTR_T +#define NCURSES_ATTR_T int +#endif + +#ifndef NCURSES_CONST +#define NCURSES_CONST /* nothing */ +#endif + +#ifdef EXTERN_TERMINFO #ifndef _CHTYPE_T_ -#define _CHTYPE_T_ unsigned long +#define _CHTYPE_T_ unsigned long typedef _CHTYPE_T_ chtype; #endif +#else +#ifndef _UNCTRL_H +typedef unsigned long chtype; +#endif +#endif -#include <stdio.h> +#include <stdio.h> #include <unctrl.h> -#include <stdarg.h> +#include <stdarg.h> /* we need va_list */ #ifdef _XOPEN_SOURCE_EXTENDED #include <stddef.h> /* we want wchar_t */ #endif /* _XOPEN_SOURCE_EXTENDED */ @@ -61,6 +87,10 @@ typedef CXX_TYPE_OF_BOOL bool; #define FALSE ((bool)0) #endif +#ifdef __cplusplus +extern "C" { +#endif + /* * XSI attributes. In the ncurses implementation, they are identical to the * A_ attributes because attr_t is just an int. The XSI Curses attr_* and @@ -87,7 +117,6 @@ typedef CXX_TYPE_OF_BOOL bool; /* colors */ extern int COLORS; extern int COLOR_PAIRS; -extern unsigned char *color_pairs; #define COLOR_BLACK 0 #define COLOR_RED 1 @@ -100,7 +129,7 @@ extern unsigned char *color_pairs; /* line graphics */ -extern chtype acs_map[]; +extern chtype acs_map[]; /* VT100 symbols begin here */ #define ACS_ULCORNER (acs_map['l']) /* upper left corner */ @@ -147,7 +176,7 @@ extern chtype acs_map[]; * is the right, b is the bottom, and l is the left. t, r, b, and l might * be B (blank), S (single), D (double), or T (thick). The subset defined * here only uses B and S. - */ + */ #define ACS_BSSB ACS_ULCORNER #define ACS_SSBB ACS_LLCORNER #define ACS_BBSS ACS_URCORNER @@ -175,10 +204,10 @@ extern chtype acs_map[]; #define _SCROLLWIN 0x08 /* bottom edge is at screen bottom? */ #define _ISPAD 0x10 /* is this window a pad? */ #define _HASMOVED 0x20 /* has cursor moved since last refresh? */ -#define _NEED_WRAP 0x40 /* cursor wrap pending */ +#define _WRAPPED 0x40 /* cursor was just wrappped */ /* - * this value is used in the firstchar and lastchar fields to mark + * this value is used in the firstchar and lastchar fields to mark * unchanged lines */ #define _NOCHANGE -1 @@ -262,6 +291,8 @@ struct _win_st { short _pad_top, _pad_left; short _pad_bottom, _pad_right; } _pad; + + short _yoffset; /* real begy is _begy + _yoffset */ }; extern WINDOW *stdscr, *curscr, *newscr; @@ -273,9 +304,10 @@ extern int LINES, COLS, TABSIZE; */ extern int ESCDELAY; /* ESC expire time in milliseconds */ -#ifdef __cplusplus -extern "C" { -#endif +/* non-XSI extensions (dickey@clark.net) */ +extern int resizeterm (int, int); +extern int wresize (WINDOW *, int, int); +extern int use_default_colors (void); extern char ttytype[]; /* needed for backward compatibility */ @@ -289,6 +321,30 @@ extern char ttytype[]; /* needed for backward compatibility */ #endif /* + * We cannot define these in ncurses_cfg.h, since they require parameters to be + * passed (that's non-portable). + */ +#if GCC_PRINTF +#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) +#else +#define GCC_PRINTFLIKE(fmt,var) /*nothing*/ +#endif + +#if GCC_SCANF +#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var))) +#else +#define GCC_SCANFLIKE(fmt,var) /*nothing*/ +#endif + +#ifndef GCC_NORETURN +#define GCC_NORETURN /* nothing */ +#endif + +#ifndef GCC_UNUSED +#define GCC_UNUSED /* nothing */ +#endif + +/* * Function prototypes. This is the complete XSI Curses list of required * functions. Those marked `generated' will have sources generated from the * macro definitions later in this file, in order to satisfy XPG4.2 @@ -307,13 +363,13 @@ extern int add_wch(const cchar_t *); /* missing */ extern int add_wchnstr(const cchar_t *, int); /* missing */ extern int add_wchstr(const cchar_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int attroff(int); /* generated */ -extern int attron(int); /* generated */ -extern int attrset(int); /* generated */ +extern int attroff(NCURSES_ATTR_T); /* generated */ +extern int attron(NCURSES_ATTR_T); /* generated */ +extern int attrset(NCURSES_ATTR_T); /* generated */ extern int attr_get(void); /* generated */ -extern int attr_off(int); /* implemented */ -extern int attr_on(int); /* implemented */ -extern int attr_set(int); /* generated */ +extern int attr_off(NCURSES_ATTR_T); /* generated */ +extern int attr_on(NCURSES_ATTR_T); /* generated */ +extern int attr_set(NCURSES_ATTR_T); /* generated */ extern int baudrate(void); /* implemented */ extern int beep(void); /* implemented */ extern int bkgd(chtype); /* generated */ @@ -343,7 +399,7 @@ extern int copywin(const WINDOW*,WINDOW*,int,int,int,int,int,int,int); /* implem extern int curs_set(int); /* implemented */ extern int def_prog_mode(void); /* implemented */ extern int def_shell_mode(void); /* implemented */ -extern int delay_output(float); /* implemented */ +extern int delay_output(int); /* implemented */ extern int delch(void); /* generated */ extern void delscreen(SCREEN *); /* implemented */ extern int delwin(WINDOW *); /* implemented */ @@ -364,15 +420,15 @@ extern int erase_wchar(wchar_t *); /* missing */ extern void filter(void); /* implemented */ extern int flash(void); /* implemented */ extern int flushinp(void); /* implemented */ +extern chtype getbkgd(WINDOW *); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED -extern chtype getbkgd(WINDOW *); /* missing */ extern int getbkgrnd(cchar_t *); /* missing */ extern int getcchar(const cchar_t *, wchar_t*, attr_t*, short*, void*); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int getch(void); /* generated */ extern int getnstr(char *, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED -extern int getn_wstr(wint_t *, int n); /* missing */ +extern int getn_wstr(wint_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int getstr(char *); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED @@ -383,16 +439,16 @@ extern WINDOW *getwin(FILE *); /* not in XPG4 */ extern int get_wstr(wint_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int halfdelay(int); /* implemented */ -extern int has_colors(void); /* implemented */ +extern bool has_colors(void); /* implemented */ extern int has_ic(void); /* implemented */ extern int has_il(void); /* implemented */ extern int hline(chtype, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED extern int hline_set(const cchar_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int idcok(WINDOW *, bool); /* implemented */ +extern void idcok(WINDOW *, bool); /* implemented */ extern int idlok(WINDOW *, bool); /* implemented */ -extern int immedok(WINDOW *, bool); /* implemented */ +extern void immedok(WINDOW *, bool); /* implemented */ extern chtype inch(void); /* generated */ extern int inchnstr(chtype *, int); /* generated */ extern int inchstr(chtype *); /* generated */ @@ -432,7 +488,7 @@ extern int keypad(WINDOW *,bool); /* implemented */ extern char killchar(void); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int killwchar(wchar_t *); /* missing */ -#endif /* _XOPEN_SOURCE_EXTENDED */ +#endif /* _XOPEN_SOURCE_EXTENDED */ extern int leaveok(WINDOW *,bool); /* implemented */ extern char *longname(void); /* implemented */ extern int meta(WINDOW *,bool); /* implemented */ @@ -456,7 +512,7 @@ extern int mvderwin(WINDOW *, int, int); /* implemented */ extern int mvgetch(int, int); /* generated */ extern int mvgetnstr(int, int, char *, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED -extern int mvgetn_wstr(int, int, wint_t *, int n); /* missing */ +extern int mvgetn_wstr(int, int, wint_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int mvgetstr(int, int, char *); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED @@ -489,8 +545,10 @@ extern int mvin_wch(int, int, const cchar_t *); /* missing */ extern int mvin_wchstr(int, int, const cchar_t *); /* missing */ extern int mvin_wchntr(int, int, const cchar_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int mvprintw(int,int,const char *,...); /* implemented */ -extern int mvscanw(int,int,const char *,...); /* implemented */ +extern int mvprintw(int,int,const char *,...) /* implemented */ + GCC_PRINTFLIKE(3,4); +extern int mvscanw(int,int,const char *,...) /* implemented */ + GCC_SCANFLIKE(3,4); extern int mvvline(int, int, chtype, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED extern int mvvline_set(int, int, const cchar_t *, int); /* missing */ @@ -512,7 +570,7 @@ extern int mvwdelch(WINDOW *, int, int); /* generated */ extern int mvwgetch(WINDOW *, int, int); /* generated */ extern int mvwgetnstr(WINDOW *, int, int, char *, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED -extern int mvwgetn_wstr(WINDOW *, int, int, wint_t *, int n);/* missing */ +extern int mvwgetn_wstr(WINDOW *, int, int, wint_t *, int);/* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int mvwgetstr(WINDOW *, int, int, char *); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED @@ -546,8 +604,10 @@ extern int mvwin_wch(WINDOW *, int, int, const cchar_t *); /* missing */ extern int mvwin_wchnstr(WINDOW *, int,int,const cchar_t *,int); /* missing */ extern int mvwin_wchstr(WINDOW *, int, int, const cchar_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int mvwprintw(WINDOW*,int,int,const char *,...); /* implemented */ -extern int mvwscanw(WINDOW *,int,int,const char *,...); /* implemented */ +extern int mvwprintw(WINDOW*,int,int,const char *,...) /* implemented */ + GCC_PRINTFLIKE(4,5); +extern int mvwscanw(WINDOW *,int,int,const char *,...) /* implemented */ + GCC_SCANFLIKE(4,5); extern int mvwvline(WINDOW *,int, int, chtype, int); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED extern int mvwvline_set(WINDOW *, int,int, const cchar_t *,int); /* missing */ @@ -567,15 +627,18 @@ extern int notimeout(WINDOW *,bool); /* implemented */ extern int overlay(const WINDOW*,WINDOW *); /* implemented */ extern int overwrite(const WINDOW*,WINDOW *); /* implemented */ extern int pair_content(short,short*,short*); /* implemented */ -extern int PAIR_NUMBER(int); /* generated */ +extern int PAIR_NUMBER(int); /* generated */ extern int pechochar(WINDOW *, chtype); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int pecho_wchar(WINDOW *, const cchar_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int pnoutrefresh(WINDOW*,int,int,int,int,int,int);/* implemented */ extern int prefresh(WINDOW *,int,int,int,int,int,int); /* implemented */ -extern int printw(const char *,...); /* implemented */ +extern int printw(const char *,...) /* implemented */ + GCC_PRINTFLIKE(1,2); +#ifndef EXTERN_TERMINFO extern int putp(const char *); /* implemented */ +#endif extern int putwin(WINDOW *, FILE *); /* implemented */ extern int qiflush(void); /* implemented */ extern int raw(void); /* implemented */ @@ -584,9 +647,10 @@ extern int refresh(void); /* generated */ extern int resetty(void); /* implemented */ extern int reset_prog_mode(void); /* implemented */ extern int reset_shell_mode(void); /* implemented */ -extern int ripoffline(int line, int (*init)(WINDOW *, int));/* implemented */ +extern int ripoffline(int, int (*init)(WINDOW *, int)); /* implemented */ extern int savetty(void); /* implemented */ -extern int scanw(const char *,...); /* implemented */ +extern int scanw(const char *,...) /* implemented */ + GCC_SCANFLIKE(1,2); extern int scr_dump(const char *); /* implemented */ extern int scr_init(const char *); /* implemented */ extern int scrl(int); /* generated */ @@ -599,15 +663,16 @@ extern int setcchar(cchar_t *, wchar_t *, attr_t, short, const void *); /* missi #endif /* _XOPEN_SOURCE_EXTENDED */ extern int setscrreg(int,int); /* generated */ extern SCREEN *set_term(SCREEN *); /* implemented */ -extern int slk_attroff(chtype); /* implemented */ +extern int slk_attroff(const attr_t); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int slk_attr_off(attr_t); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int slk_attron(chtype); /* implemented */ +extern int slk_attron(const attr_t); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int slk_attr_on(attr_t); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -extern int slk_attrset(chtype); /* implemented */ +extern int slk_attrset(const attr_t); /* implemented */ +extern attr_t slk_attr(void); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int slk_attr_set(attr_t); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ @@ -627,20 +692,22 @@ extern int standend(void); /* generated */ extern int start_color(void); /* implemented */ extern WINDOW *subpad(WINDOW *, int, int, int, int); /* implemented */ extern WINDOW *subwin(WINDOW *,int,int,int,int); /* implemented */ -extern int syncok(WINDOW *win, bool); /* implemented */ +extern int syncok(WINDOW *, bool); /* implemented */ extern attr_t termattrs(void); /* implemented */ extern char *termname(void); /* implemented */ extern int tigetflag(const char *); /* implemented */ extern int tigetnum(const char *); /* implemented */ extern char *tigetstr(const char *); /* implemented */ -extern int timeout(int); /* implemented */ +extern int timeout(int); /* generated */ extern int typeahead(int); /* implemented */ extern int ungetch(int); /* implemented */ #ifdef _XOPEN_SOURCE_EXTENDED extern int unget_wch(const wchar_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int untouchwin(WINDOW *); /* generated */ +#ifndef EXTERN_TERMINFO extern int vidattr(chtype); /* implemented */ +#endif #ifdef _XOPEN_SOURCE_EXTENDED extern int vid_attr(attr_t); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ @@ -653,9 +720,9 @@ extern int vline(chtype, int); /* generated */ extern int vline_set(const cchar_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int vwprintw(WINDOW *,const char *,va_list); /* implemented */ -extern int vw_printw(WINDOW *,const char *,va_list); /* implemented */ +extern int vw_printw(WINDOW *,const char *,va_list); /* generated */ extern int vwscanw(WINDOW *,const char *,va_list); /* implemented */ -extern int vw_scanw(WINDOW *,const char *,va_list); /* implemented */ +extern int vw_scanw(WINDOW *,const char *,va_list); /* generated */ extern int waddch(WINDOW *, const chtype); /* implemented */ extern int waddchnstr(WINDOW *,const chtype *const,int); /* implemented */ extern int waddchstr(WINDOW *,const chtype *); /* generated */ @@ -673,7 +740,7 @@ extern int wattrset(WINDOW *, int); /* generated */ extern attr_t wattr_get(WINDOW *); /* generated */ extern int wattr_on(WINDOW *, const attr_t); /* implemented */ extern int wattr_off(WINDOW *, const attr_t); /* implemented */ -extern int wattr_set(WINDOW *, attr_t); /* implemented */ +extern int wattr_set(WINDOW *, attr_t); /* generated */ extern int wbkgd(WINDOW *,const chtype); /* implemented */ extern void wbkgdset(WINDOW *,chtype); /* generated */ #ifdef _XOPEN_SOURCE_EXTENDED @@ -737,11 +804,12 @@ extern int win_wchstr(WINDOW *, const cchar_t *); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ extern int wmove(WINDOW *,int,int); /* implemented */ extern int wnoutrefresh(WINDOW *); /* implemented */ -extern int wprintw(WINDOW *,const char *,...); /* implemented */ +extern int wprintw(WINDOW *,const char *,...) /* implemented */ + GCC_PRINTFLIKE(2,3); extern int wredrawln(WINDOW *,int,int); /* implemented */ extern int wrefresh(WINDOW *); /* implemented */ -extern int wresize(WINDOW *, int, int); /* implemented */ -extern int wscanw(WINDOW *,const char *,...); /* implemented */ +extern int wscanw(WINDOW *,const char *,...) /* implemented */ + GCC_SCANFLIKE(2,3); extern int wscrl(WINDOW *,int); /* implemented */ extern int wsetscrreg(WINDOW *,int,int); /* implemented */ extern int wstandout(WINDOW *); /* generated */ @@ -758,10 +826,6 @@ extern int wvline(WINDOW *,chtype,int); /* implemented */ extern int wvline_set(WINDOW *, const cchar_t *, int); /* missing */ #endif /* _XOPEN_SOURCE_EXTENDED */ -#ifdef __cplusplus -} -#endif - /* attributes */ #define A_ATTRIBUTES 0xffffff00 #define A_NORMAL 0x00000000 @@ -782,8 +846,8 @@ extern int wvline_set(WINDOW *, const cchar_t *, int); /* missing */ #define A_VERTICAL 0x40000000 /* XSI Curses attr -- not yet used */ #define A_CHARTEXT 0x000000ff #define A_COLOR 0x0000ff00 -#define COLOR_PAIR(n) (n << 8) -#define PAIR_NUMBER(a) ((a & A_COLOR) >> 8) +#define COLOR_PAIR(n) ((n) << 8) +#define PAIR_NUMBER(a) (((a) & A_COLOR) >> 8) /* * pseudo functions @@ -798,7 +862,7 @@ extern int wvline_set(WINDOW *, const cchar_t *, int); /* missing */ #define saveterm() def_prog_mode() #define crmode() cbreak() #define nocrmode() nocbreak() -#define gettmode() +#define gettmode() #define getyx(win,y,x) (y = (win)->_cury, x = (win)->_curx) #define getbegyx(win,y,x) (y = (win)->_begy, x = (win)->_begx) @@ -807,7 +871,10 @@ extern int wvline_set(WINDOW *, const cchar_t *, int); /* missing */ #define getsyx(y,x) getyx(stdscr, y, x) #define setsyx(y,x) (stdscr->_cury = y, stdscr->_curx = x) -#define wbkgdset(win,ch) ((win)->_bkgd = (ch)) +#define wbkgdset(win, ch) \ + (((win)->_attrs = (((win)->_attrs & ~((win)->_bkgd & A_ATTRIBUTES)) | \ + ((ch) & A_ATTRIBUTES))), \ + ((win)->_bkgd = (ch))) /* It seems older SYSV curses versions define these */ #define getattrs(win) ((win)->_attrs) @@ -846,160 +913,164 @@ extern int wvline_set(WINDOW *, const cchar_t *, int); /* missing */ * pseudo functions for standard screen */ -#define bkgdset(ch) wbkgdset(stdscr,ch) -#define bkgd(ch) wbkgd(stdscr,ch) -#define inch() winch(stdscr) -#define standout() wstandout(stdscr) -#define standend() wstandend(stdscr) -#define attron(at) wattron(stdscr,at) -#define attroff(at) wattroff(stdscr,at) -#define attrset(at) wattrset(stdscr,at) #define addch(ch) waddch(stdscr,ch) -#define echochar(c) wechochar(stdscr, c) -#define getch() wgetch(stdscr) +#define addchnstr(str,n) waddchnstr(stdscr,str,n) +#define addchstr(str) waddchstr(stdscr,str) +#define addnstr(str,n) waddnstr(stdscr,str,n) #define addstr(str) waddnstr(stdscr,str,-1) -#define getstr(str) wgetstr(stdscr,str) -#define move(y, x) wmove(stdscr,y,x) +#define attroff(at) wattroff(stdscr,at) +#define attron(at) wattron(stdscr,at) +#define attrset(at) wattrset(stdscr,at) +#define bkgd(ch) wbkgd(stdscr,ch) +#define bkgdset(ch) wbkgdset(stdscr,ch) #define clear() wclear(stdscr) -#define erase() werase(stdscr) #define clrtobot() wclrtobot(stdscr) #define clrtoeol() wclrtoeol(stdscr) -#define insertln() winsdelln(stdscr, 1) -#define winsertln(w) winsdelln(w, 1) -#define deleteln() winsdelln(stdscr, -1) -#define wdeleteln(w) winsdelln(w, -1) -#define refresh() wrefresh(stdscr) -#define insch(c) winsch(stdscr,c) #define delch() wdelch(stdscr) -#define setscrreg(t,b) wsetscrreg(stdscr,t,b) +#define deleteln() winsdelln(stdscr,-1) +#define echochar(c) wechochar(stdscr,c) +#define erase() werase(stdscr) +#define getch() wgetch(stdscr) +#define getstr(str) wgetstr(stdscr,str) +#define inch() winch(stdscr) +#define inchnstr(s,n) winchnstr(stdscr,s,n) +#define inchstr(s) winchstr(stdscr,s) +#define innstr(s,n) winnstr(stdscr,s,n) +#define insch(c) winsch(stdscr,c) +#define insdelln(n) winsdelln(stdscr,n) +#define insertln() winsdelln(stdscr,1) +#define insnstr(s,n) winsnstr(stdscr,s,n) +#define insstr(s) winsstr(stdscr,s) +#define instr(s) winstr(stdscr,s) +#define move(y,x) wmove(stdscr,y,x) +#define refresh() wrefresh(stdscr) #define scrl(n) wscrl(stdscr,n) -#define timeout(delay) wtimeout(stdscr, delay) -#define addnstr(str,n) waddnstr(stdscr,str,n) -#define addchstr(str) waddchstr(stdscr,str) -#define addchnstr(str,n) waddchnstr(stdscr,str, n) -#define insdelln(n) winsdelln(stdscr, n) -#define insstr(s) winsstr(stdscr, s) -#define insnstr(s,n) winsnstr(stdscr, s, n) -#define instr(s) winstr(stdscr, s) -#define innstr(s,n) winnstr(stdscr, s, n) -#define inchstr(s) winchstr(stdscr, s) -#define inchnstr(s,n) winchnstr(stdscr, s, n) +#define setscrreg(t,b) wsetscrreg(stdscr,t,b) +#define standend() wstandend(stdscr) +#define standout() wstandout(stdscr) +#define timeout(delay) wtimeout(stdscr,delay) +#define wdeleteln(win) winsdelln(win,-1) +#define winsertln(win) winsdelln(win,1) /* * mv functions */ #define mvwaddch(win,y,x,ch) (wmove(win,y,x) == ERR ? ERR : waddch(win,ch)) -#define mvwgetch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wgetch(win)) #define mvwaddchnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,n)) #define mvwaddchstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,-1)) #define mvwaddnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,n)) #define mvwaddstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,-1)) -#define mvwgetstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : wgetstr(win,str)) -#define mvgetnstr(y,x,str,n) (move(y,x) == ERR ? ERR : wgetnstr(stdscr,str,n)) -#define mvwgetnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : wgetnstr(win,str,n)) -#define mvwinch(win,y,x) (wmove(win,y,x) == ERR ? ERR : winch(win)) #define mvwdelch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wdelch(win)) -#define mvwinsch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winsch(win,c)) +#define mvwgetch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wgetch(win)) +#define mvwgetnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : wgetnstr(win,str,n)) +#define mvwgetstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : wgetstr(win,str)) #define mvwhline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline(win,c,n)) +#define mvwinch(win,y,x) (wmove(win,y,x) == ERR ? (chtype)ERR : winch(win)) +#define mvwinchnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winchnstr(win,s,n)) +#define mvwinchstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winchstr(win,s)) +#define mvwinnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winnstr(win,s,n)) +#define mvwinsch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winsch(win,c)) +#define mvwinsnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winsnstr(win,s,n)) +#define mvwinsstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winsstr(win,s)) +#define mvwinstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winstr(win,s)) #define mvwvline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline(win,c,n)) + #define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch) #define mvaddchnstr(y,x,str,n) mvwaddchnstr(stdscr,y,x,str,n) #define mvaddchstr(y,x,str) mvwaddchstr(stdscr,y,x,str) -#define mvgetch(y,x) mvwgetch(stdscr,y,x) #define mvaddnstr(y,x,str,n) mvwaddnstr(stdscr,y,x,str,n) #define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str) +#define mvdelch(y,x) mvwdelch(stdscr,y,x) +#define mvgetch(y,x) mvwgetch(stdscr,y,x) +#define mvgetnstr(y,x,str,n) mvwgetnstr(stdscr,y,x,str,n) #define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str) +#define mvhline(y,x,c,n) mvwhline(stdscr,y,x,c,n) #define mvinch(y,x) mvwinch(stdscr,y,x) -#define mvdelch(y,x) mvwdelch(stdscr,y,x) +#define mvinchnstr(y,x,s,n) mvwinchnstr(stdscr,y,x,s,n) +#define mvinchstr(y,x,s) mvwinchstr(stdscr,y,x,s) +#define mvinnstr(y,x,s,n) mvwinnstr(stdscr,y,x,s,n) #define mvinsch(y,x,c) mvwinsch(stdscr,y,x,c) -#define mvhline(y,x,c,n) mvwhline(stdscr,y,x,c,n) -#define mvvline(y,x,c,n) mvwvline(stdscr,y,x,c,n) -#define mvwinsstr(w, y, x, s) (wmove(w,y,x) == ERR ? ERR : winsstr(w,s)) -#define mvwinsnstr(w, y, x, s, n) (wmove(w,y,x) == ERR ? ERR : winsnstr(w,s,n)) -#define mvinsstr(y,x,s) mvwinsstr(stdscr,y,x,s) #define mvinsnstr(y,x,s,n) mvwinsnstr(stdscr,y,x,s,n) -#define mvwinstr(w, y, x, s) (wmove(w,y,x) == ERR ? ERR : winstr(w,s)) -#define mvwinnstr(w, y, x, s, n) (wmove(w,y,x) == ERR ? ERR : winnstr(w,s,n)) +#define mvinsstr(y,x,s) mvwinsstr(stdscr,y,x,s) #define mvinstr(y,x,s) mvwinstr(stdscr,y,x,s) -#define mvinnstr(y,x,s,n) mvwinnstr(stdscr,y,x,s,n) -#define mvwinchstr(w, y, x, s) (wmove(w,y,x) == ERR ? ERR : winchstr(w,s)) -#define mvwinchnstr(w, y, x, s, n) (wmove(w,y,x) == ERR ? ERR : winchnstr(w,s,n)) -#define mvinchstr(y,x,s) mvwinchstr(stdscr,y,x,s) -#define mvinchnstr(y,x,s,n) mvwinchnstr(stdscr,y,x,s,n) +#define mvvline(y,x,c,n) mvwvline(stdscr,y,x,c,n) /* * XSI curses macros for XPG4 conformance. - * The underling functions needed to make these work are: + * The underlying functions needed to make these work are: * waddnwstr(), waddchnwstr(), wadd_wch(), wborder_set(), wchgat(), * wecho_wchar(), wgetn_wstr(), wget_wch(), whline_set(), vhline_set(), * winnwstr(), wins_nwstr(), wins_wch(), win_wch(), win_wchnstr(). * Except for wchgat(), these are not yet implemented. They will be someday. */ -#define addnwstr(wstr, n) waddnwstr(stdscr, wstr, n) -#define addwstr(wstr, n) waddnwstr(stdscr, wstr, -1) -#define mvaddnwstr(y,x,wstr, n) (wmove(stdscr,y,x) == ERR ? ERR : waddnwstr(stdscr, wstr, n)) -#define mvaddwstr(y,x,wstr, n) (wmove(stdscr,y,x) == ERR ? ERR : waddnwstr(stdscr, wstr, -1)) -#define mvwaddnwstr(y,x,win,wstr,n) (wmove(win,y,x) == ERR ? ERR : waddnwstr(stdscr, wstr, n)) -#define mvwaddwstr(y,x,win,wstr,n) (wmove(win,y,x) == ERR ? ERR : waddnwstr(stdscr, wstr, -1)) -#define waddwstr(win, wstr, n) waddnwstr(win, wstr, -1) -#define add_wch(c) wadd_wch(stsdscr, c) -#define mvadd_wch(y,x,c) (wmove(stdscr,y,x) == ERR ? ERR : wadd_wch(stsdscr, c)) -#define mvwadd_wch(y,x,win,c) (wmove(win,y,x) == ERR ? ERR : wadd_wch(stsdscr, c)) -#define wattr_get(win) ((win)->_attrs) -#define attr_get() wattr_get(stdscr) -#define attr_off(a) wattr_off(stdscr, a) -#define attr_on(a) wattr_on(stdscr, a) -#define attr_set(a) wattr_set(stdscr, a) -#define wgetbkgd(win) ((win)->_bkgd) -#define box_set(w,v,h) wborder_set(w,v,v,h,h,0,0,0,9) -#define chgat(n, a, c, o) wchgat(stdscr, n, a, c, o) -#define mvchgat(y,x, n,a,c, o) (move(y,x)==ERR ? ERR : wchgat(stdscr,n,a,c,o)) -#define mvwchgat(w,y,x,n,a,c,o) (wmove(w,y,x) == ERR ? ERR : wchgat(w,n,a,c,o)) -#define echo_wchar(c) wecho_wchar(stdscr, c) -#define getn_wstr(t, n) wgetn_wstr(stdscr, t, n) -#define get_wstr(t) wgetn_wstr(stdscr, t, -1) -#define mvgetn_wstr(y, x, t, n) (move(y,x)==ERR ? ERR:wgetn_wstr(stdscr,t,n)) -#define mvget_wstr(y, x, t) (move(y,x)==ERR ? ERR:wgetn_wstr(stdscr,t,-1)) -#define mvwgetn_wstr(w,y,x,t,n) (wmove(w,y,x)==ERR ? ERR : wgetn_wstr(w,t,n)) -#define mvwget_wstr(w, y, x, t) (wmove(w,y,x)==ERR ? ERR : wgetn_wstr(w,t,-1)) -#define wget_wstr(w, t) wgetn_wstr(w, t, -1) -#define get_wch(c) wget_wch(stdscr, c) -#define mvget_wch(y, x, c) (move(y,x) == ERR ? ERR : wget_wch(stdscr, c)) -#define mvwget_wch(y, x, c) (wmove(w,y,x) == ERR ? ERR : wget_wch(w, n)) -#define hline_set(c, n) whline_set(stdscr, c, n) -#define mvhline_set(y,x,c,n) (move(y,x)==ERR ? ERR : whline_set(stdscr,c,n)) -#define mvvline_set(y,x,c,n) (move(y,x)==ERR ? ERR : wvline_set(stdscr,c,n)) -#define mvwhline_set(w,y,x,c,n) (wmove(w,y,x)==ERR ? ERR : whline_set(w,c,n)) -#define mvwvline_set(w,y,x,c,n) (wmove(w,y,x)==ERR ? ERR : wvline_set(w,c,n)) -#define vline_set(c, n) vhline_set(stdscr, c, n) -#define innwstr(c, n) winnwstr(stdscr, c, n) -#define inwstr(c) winnwstr(stdscr, c, -1) -#define mvinnwstr(y, x, c, n) (move(y,x)==ERR ? ERR : winnwstr(stdscr, c, n)) -#define mvinwstr(y, x, c) (move(y,x)==ERR ? ERR : winnwstr(stdscr, c,-1)) -#define mvwinnwstr(w,y,x,c,n) (wmove(w,y,x)==ERR ? ERR:winnwstr(stdscr,c,n)) -#define mvwinwstr(w,y,x,c) (wmove(w,y,x)==ERR ? ERR:winnwstr(stdscr,c,-1)) -#define winwstr(w, c) winnwstr(w, c, -1) -#define ins_nwstr(t, n) wins_nwstr(stdscr, t, n) -#define ins_wstr(t) wins_nwstr(stdscr, t, -1) -#define mvins_nwstr(y,x,t,n) (move(y,x)==ERR ? ERR: wins_nwstr(stdscr,t,n)) -#define mvins_wstr(y,x,t) (move(y,x)==ERR ? ERR: wins_nwstr(stdscr,t,-1)) -#define mvwins_nwstr(w,y,x,t,n) (wmove(w,y,x)==ERR?ERR:wins_nwstr(stdscr,t,n)) -#define mvwins_wstr(w,y,x,t) (wmove(w,y,x)==ERR?ERR:wins_nwstr(stdscr,t,-1)) -#define wins_wstr(w, t) wins_nwstr(w, t, -1) -#define ins_wch(c) wins_wch(stdscr, c) -#define mvins_wch(y,x,c) (move(y,x) == ERR ? ERR : wins_wch(c)) -#define mwvins_wch(w,y,x,c) (wmove(w,y,x) == ERR ? ERR : wins_wch(c)) -#define in_wch(c) win_wch(stdscr, c) -#define mvin_wch(y,x,c) (move(y,x) == ERR ? ERR : win_wch(stdscr, c)) -#define mvwin_wch(w,y,x,c) (wmove(w, y,x) == ERR ? ERR : win_wch(w, c)) -#define in_wchnstr(c, n) win_wchnstr(stdscr, c, n) -#define in_wchstr(c) win_wchnstr(stdscr, c, -1) -#define mvin_wchnstr(y,x,c,n) (move(y,x)==ERR ? ERR:win_wchnstr(stdscr,c,n)) -#define mvin_wchstr(y, x, c) (move(y,x)==ERR ? ERR:win_wchnstr(stdscr,c,-1)) -#define mvwin_wchnstr(w,y,x,c,n) (wmove(w,y,x)==ERR ? ERR:win_wchnstr(stdscr,c,n)) -#define mvwin_wchstr(w,y,x,c) (wmove(w,y,x)==ERR ? ERR:win_wchnstr(stdscr,c,-1)) -#define win_wchstr(w, c) win_wchnstr(w, c, -1) +#define add_wch(c) wadd_wch(stsdscr,c) +#define addnwstr(wstr,n) waddnwstr(stdscr,wstr,n) +#define addwstr(wstr,n) waddnwstr(stdscr,wstr,-1) +#define attr_get() wattr_get(stdscr) +#define attr_off(a) wattr_off(stdscr,a) +#define attr_on(a) wattr_on(stdscr,a) +#define attr_set(a) wattr_set(stdscr,a) +#define box_set(w,v,h) wborder_set(w,v,v,h,h,0,0,0,9) +#define chgat(n,a,c,o) wchgat(stdscr,n,a,c,o) +#define echo_wchar(c) wecho_wchar(stdscr,c) +#define getbkgd(win) ((win)->_bkgd) +#define get_wch(c) wget_wch(stdscr,c) +#define get_wstr(t) wgetn_wstr(stdscr,t,-1) +#define getn_wstr(t,n) wgetn_wstr(stdscr,t,n) +#define hline_set(c,n) whline_set(stdscr,c,n) +#define in_wch(c) win_wch(stdscr,c) +#define in_wchnstr(c,n) win_wchnstr(stdscr,c,n) +#define in_wchstr(c) win_wchnstr(stdscr,c,-1) +#define innwstr(c,n) winnwstr(stdscr,c,n) +#define ins_nwstr(t,n) wins_nwstr(stdscr,t,n) +#define ins_wch(c) wins_wch(stdscr,c) +#define ins_wstr(t) wins_nwstr(stdscr,t,-1) +#define inwstr(c) winnwstr(stdscr,c,-1) + +#define mvadd_wch(y,x,c) mvwadd_wch(stdscr,y,x,c) +#define mvaddnwstr(y,x,wstr,n) mvwaddnwstr(stdscr,y,x,wstr,n) +#define mvaddwstr(y,x,wstr,n) mvwaddnwstr(stdscr,y,x,wstr,-1) +#define mvchgat(y,x,n,a,c,o) mvwchgat(stdscr,y,x,n,a,c,o) +#define mvget_wch(y,x,c) mvwget_wch(stdscr,y,x,c) +#define mvget_wstr(y,x,t) mvwgetn_wstr(stdscr,y,x,t,-1) +#define mvgetn_wstr(y,x,t,n) mvwgetn_wstr(stdscr,y,x,t,n) +#define mvhline_set(y,x,c,n) mvwhline_set(stdscr,y,x,c,n) +#define mvin_wch(y,x,c) mvwin_wch(stdscr,y,x,c) +#define mvin_wchnstr(y,x,c,n) mvwin_wchnstr(stdscr,y,x,c,n) +#define mvin_wchstr(y,x,c) mvwin_wchnstr(stdscr,y,x,c,-1) +#define mvinnwstr(y,x,c,n) mvwinnwstr(stdscr,y,x,c,n) +#define mvins_nwstr(y,x,t,n) mvwins_nwstr(stdscr,y,x,t,n) +#define mvins_wch(y,x,c) mvwins_wch(stdscr,y,x,c) +#define mvins_wstr(y,x,t) mvwins_nwstr(stdscr,y,x,t,-1) +#define mvinwstr(y,x,c) mvwinnwstr(stdscr,y,x,c,-1) +#define mvvline_set(y,x,c,n) mvwvline_set(stdscr,y,x,c,n) + +#define mvwadd_wch(y,x,win,c) (wmove(win,y,x) == ERR ? ERR : wadd_wch(stsdscr,c)) +#define mvwaddnwstr(y,x,win,wstr,n) (wmove(win,y,x) == ERR ? ERR : waddnwstr(stdscr,wstr,n)) +#define mvwaddwstr(y,x,win,wstr,n) (wmove(win,y,x) == ERR ? ERR : waddnwstr(stdscr,wstr,-1)) +#define mvwchgat(win,y,x,n,a,c,o) (wmove(win,y,x) == ERR ? ERR : wchgat(win,n,a,c,o)) +#define mvwget_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : wget_wch(win,n)) +#define mvwget_wstr(win,y,x,t) (wmove(win,y,x) == ERR ? ERR : wgetn_wstr(win,t,-1)) +#define mvwgetn_wstr(win,y,x,t,n) (wmove(win,y,x) == ERR ? ERR : wgetn_wstr(win,t,n)) +#define mvwhline_set(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline_set(win,c,n)) +#define mvwin_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : win_wch(win,c)) +#define mvwin_wchnstr(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : win_wchnstr(stdscr,c,n)) +#define mvwin_wchstr(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : win_wchnstr(stdscr,c,-1)) +#define mvwinnwstr(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : winnwstr(stdscr,c,n)) +#define mvwins_nwstr(win,y,x,t,n) (wmove(win,y,x) == ERR ? ERR : wins_nwstr(stdscr,t,n)) +#define mvwins_wch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : wins_wch(c)) +#define mvwins_wstr(win,y,x,t) (wmove(win,y,x) == ERR ? ERR : wins_nwstr(stdscr,t,-1)) +#define mvwinwstr(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winnwstr(stdscr,c,-1)) +#define mvwvline_set(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline_set(win,c,n)) + +#define vline_set(c,n) vhline_set(stdscr,c,n) +#define waddwstr(win,wstr,n) waddnwstr(win,wstr,-1) +#define wattr_get(win) ((win)->_attrs) +#define wget_wstr(w,t) wgetn_wstr(w,t,-1) +#define win_wchstr(w,c) win_wchnstr(w,c,-1) +#define wins_wstr(w,t) wins_nwstr(w,t,-1) +#define winwstr(w,c) winnwstr(w,c,-1) /* @@ -1169,34 +1240,56 @@ typedef struct } MEVENT; -int getmouse(MEVENT *event); -int ungetmouse(MEVENT *event); -mmask_t mousemask(mmask_t newmask, mmask_t *oldmask); -bool wenclose(WINDOW *win, int y, int x); -int mouseinterval(int); +extern int getmouse(MEVENT *); +extern int ungetmouse(MEVENT *); +extern mmask_t mousemask(mmask_t, mmask_t *); +extern bool wenclose(WINDOW *, int, int); +extern int mouseinterval(int); + +/* other non-XSI functions */ + +extern int mcprint(char *, int); /* direct data to printer */ +extern int has_key(int); /* do we have given key? */ /* Debugging : use with libncurses_g.a */ -extern void _tracef(const char *, ...) __attribute__((format(printf,1,2))); -extern void _tracedump(char *, WINDOW *); -extern char *_traceattr(attr_t mode); +extern void _tracef(const char *, ...) GCC_PRINTFLIKE(1,2); +extern void _tracedump(const char *, WINDOW *); +extern char *_traceattr(attr_t); +extern char *_traceattr2(int, chtype); +extern char *_tracebits(void); extern char *_tracechar(const unsigned char); +extern char *_tracechtype(chtype); +extern char *_tracechtype2(int, chtype); extern char *_tracemouse(const MEVENT *); -extern void trace(const unsigned int tracelevel); +extern void trace(const unsigned int); /* trace masks */ -#define TRACE_DISABLE 0x00 /* turn off tracing */ -#define TRACE_UPDATE 0x01 /* trace update actions, old & new screens */ -#define TRACE_MOVE 0x02 /* trace cursor moves and scrolls */ -#define TRACE_CHARPUT 0x04 /* trace all character outputs */ -#define TRACE_ORDINARY 0x07 /* trace all update actions */ -#define TRACE_CALLS 0x08 /* trace all curses calls */ -#define TRACE_VIRTPUT 0x10 /* trace virtual character puts */ -#define TRACE_FIFO 0x20 /* also fifo actions by getch() */ -#define TRACE_MAXIMUM 0xff /* maximum trace level */ - -#ifdef TRACE -extern bool no_optimize; /* suppress optimization */ -#endif /* TRACE */ +#define TRACE_DISABLE 0x0000 /* turn off tracing */ +#define TRACE_TIMES 0x0001 /* trace user and system times of updates */ +#define TRACE_TPUTS 0x0002 /* trace tputs calls */ +#define TRACE_UPDATE 0x0004 /* trace update actions, old & new screens */ +#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */ +#define TRACE_CHARPUT 0x0010 /* trace all character outputs */ +#define TRACE_ORDINARY 0x001F /* trace all update actions */ +#define TRACE_CALLS 0x0020 /* trace all curses calls */ +#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */ +#define TRACE_IEVENT 0x0080 /* trace low-level input processing */ +#define TRACE_BITS 0x0100 /* trace state of TTY control bits */ +#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */ +#define TRACE_CCALLS 0x0400 /* trace per-character calls */ +#define TRACE_MAXIMUM 0xffff /* maximum trace level */ + +#if defined(TRACE) || defined(NCURSES_TEST) +extern int _nc_optimize_enable; /* enable optimizations */ +#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */ +#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */ +#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */ +#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */ +#endif + +#ifdef __cplusplus +} +#endif #endif /* __NCURSES_H */ diff --git a/lib/libcurses/curses.priv.h b/lib/libcurses/curses.priv.h index a1e023265d1..b638a6ec182 100644 --- a/lib/libcurses/curses.priv.h +++ b/lib/libcurses/curses.priv.h @@ -21,6 +21,8 @@ /* + * Id: curses.priv.h,v 1.61 1997/04/26 20:54:54 tom Exp $ + * * curses.priv.h * * Header file for curses library objects which are private to @@ -28,12 +30,29 @@ * */ -#include <config.h> +#ifndef CURSES_PRIV_H +#define CURSES_PRIV_H 1 + +#include <ncurses_cfg.h> + +#ifdef USE_RCS_IDS +#define MODULE_ID(id) static const char Ident[] = id; +#else +#define MODULE_ID(id) /*nothing*/ +#endif + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> #if HAVE_UNISTD_H #include <unistd.h> #endif +#if HAVE_SYS_BSDTYPES_H +#include <sys/bsdtypes.h> /* needed for ISC */ +#endif + #if HAVE_LIMITS_H # include <limits.h> #elif HAVE_SYS_PARAM_H @@ -46,14 +65,201 @@ # elif defined(MAXPATHLEN) # define PATH_MAX MAXPATHLEN # else -# define PATH_MAX 255 /* the Posix minimum pathsize */ +# define PATH_MAX 255 /* the Posix minimum path-size */ # endif #endif #include <assert.h> +#include <stdio.h> + +#include <errno.h> + +#if !HAVE_EXTERN_ERRNO +extern int errno; +#endif + +/* Some systems have a broken 'select()', but workable 'poll()'. Use that */ +#if HAVE_POLL && HAVE_SYS_STROPTS_H && HAVE_POLL_H +#define USE_FUNC_POLL 1 +#else +#define USE_FUNC_POLL 0 +#endif + +/* Alessandro Rubini's GPM (general-purpose mouse) */ +#if HAVE_LIBGPM && HAVE_GPM_H +#define USE_GPM_SUPPORT 1 +#else +#define USE_GPM_SUPPORT 0 +#endif + +/* + * ht/cbt expansion flakes out randomly under Linux 1.1.47, but only when + * we're throwing control codes at the screen at high volume. To see this, + * re-enable TABS_OK and run worm for a while. Other systems probably don't + * want to define this either due to uncertainties about tab delays and + * expansion in raw mode. + */ +#undef TABS_OK /* OK to use tab/backtab for local motions? */ + +/* + * The internal types (e.g., struct screen) must precede <curses.h>, otherwise + * we cannot construct lint-libraries (structures must be fully-defined). + */ + +struct tries { + struct tries *child; /* ptr to child. NULL if none */ + struct tries *sibling; /* ptr to sibling. NULL if none */ + unsigned char ch; /* character at this node */ + unsigned short value; /* code of string so far. 0 if none. */ +}; + +/* + * Structure for soft labels. + */ + +typedef struct +{ + char *text; /* text for the label */ + char *form_text; /* formatted text (left/center/...) */ + int x; /* x coordinate of this field */ + char dirty; /* this label has changed */ + char visible; /* field is visible */ +} slk_ent; + +typedef struct { + char dirty; /* all labels have changed */ + char hidden; /* soft labels are hidden */ + struct _win_st *win; + slk_ent *ent; + char *buffer; /* buffer for labels */ + short maxlab; /* number of available labels */ + short labcnt; /* number of allocated labels */ + short maxlen; /* length of labels */ +} SLK; + +/* + * Definitions for color pairs + */ +#define C_SHIFT 8 /* we need more bits than there are colors */ +#define C_MASK ((1 << C_SHIFT) - 1) + +#define PAIR_OF(fg, bg) ((((fg) & C_MASK) << C_SHIFT) | ((bg) & C_MASK)) + +/* + * Structure for palette tables + */ + +typedef struct +{ + short red, green, blue; +} +color_t; + +#define MAXCOLUMNS 135 +#define MAXLINES 66 +#define FIFO_SIZE MAXLINES +struct screen { + int _ifd; /* input file ptr for screen */ + FILE *_ofp; /* output file ptr for screen */ + char *_setbuf; /* buffered I/O for output */ + int _checkfd; /* filedesc for typeahead check */ +#ifdef EXTERN_TERMINFO + struct _terminal *_term; /* terminal type information */ +#else + struct term *_term; /* terminal type information */ +#endif + short _lines; /* screen lines */ + short _columns; /* screen columns */ + short _lines_avail; /* lines available for stdscr */ + short _topstolen; /* lines stolen from top */ + struct _win_st *_curscr; /* current screen */ + struct _win_st *_newscr; /* virtual screen to be updated to */ + struct _win_st *_stdscr; /* screen's full-window context */ + struct tries *_keytry; /* "Try" for use with keypad mode */ + unsigned int _fifo[FIFO_SIZE]; /* input push-back buffer */ + signed char _fifohead, /* head of fifo queue */ + _fifotail, /* tail of fifo queue */ + _fifopeek; /* where to peek for next char */ + int _endwin; /* are we out of window mode? */ + unsigned long _current_attr; /* terminal attribute current set */ + int _coloron; /* is color enabled? */ + int _cursor; /* visibility of the cursor */ + int _cursrow; /* physical cursor row */ + int _curscol; /* physical cursor column */ + int _nl; /* True if NL -> CR/NL is on */ + int _raw; /* True if in raw mode */ + int _cbreak; /* 1 if in cbreak mode */ + /* > 1 if in halfdelay mode */ + int _echo; /* True if echo on */ + int _use_meta; /* use the meta key? */ + SLK *_slk; /* ptr to soft key struct / NULL */ + int _baudrate; /* used to compute padding */ + + /* cursor movement costs; units are 10ths of milliseconds */ + int _char_padding; /* cost of character put */ + int _cr_cost; /* cost of (carriage_return) */ + int _cup_cost; /* cost of (cursor_address) */ + int _home_cost; /* cost of (cursor_home) */ + int _ll_cost; /* cost of (cursor_to_ll) */ +#ifdef TABS_OK + int _ht_cost; /* cost of (tab) */ + int _cbt_cost; /* cost of (backtab) */ +#endif /* TABS_OK */ + int _cub1_cost; /* cost of (cursor_left) */ + int _cuf1_cost; /* cost of (cursor_right) */ + int _cud1_cost; /* cost of (cursor_down) */ + int _cuu1_cost; /* cost of (cursor_up) */ + int _cub_cost; /* cost of (parm_cursor_left) */ + int _cuf_cost; /* cost of (parm_cursor_right) */ + int _cud_cost; /* cost of (parm_cursor_down) */ + int _cuu_cost; /* cost of (parm_cursor_up) */ + int _hpa_cost; /* cost of (column_address) */ + int _vpa_cost; /* cost of (row_address) */ + /* used in lib_doupdate.c, must be chars */ + int _ed_cost; /* cost of (clr_eos) */ + int _el_cost; /* cost of (clr_eol) */ + int _el1_cost; /* cost of (clr_bol) */ + int _dch1_cost; /* cost of (delete_character) */ + int _ich1_cost; /* cost of (insert_character) */ + int _dch_cost; /* cost of (parm_dch) */ + int _ich_cost; /* cost of (parm_ich) */ + int _ech_cost; /* cost of (erase_chars) */ + int _rep_cost; /* cost of (repeat_char) */ + int _hpa_ch_cost; /* cost of (column_address) */ + int _cup_ch_cost; /* cost of (cursor_address) */ + /* used in lib_mvcur.c */ + char * _address_cursor; + int _carriage_return_length; + int _cursor_home_length; + int _cursor_to_ll_length; + /* used in lib_color.c */ + color_t *_color_table; /* screen's color palette */ + int _color_count; /* count of colors in palette */ + unsigned short *_color_pairs; /* screen's color pair list */ + int _pair_count; /* count of color pairs */ + int _default_color; /* use default colors */ +}; + +/* Ncurses' public interface follows the internal types */ #include <curses.h> /* we'll use -Ipath directive to get the right one! */ +#ifdef NCURSES_NOMACROS +#include <nomacros.h> +#endif + +#define WINDOWLIST struct _win_list + WINDOWLIST { + WINDOWLIST *next; + WINDOW *win; +}; + +typedef struct { + int line; /* lines to take, < 0 => from bottom*/ + int (*hook)(struct _win_st *, int); /* callback for user */ + struct _win_st *w; /* maybe we need this for cleanup */ +} ripoff_t; + /* The terminfo source is assumed to be 7-bit ASCII */ #define is7bits(c) ((unsigned)(c) < 128) @@ -74,6 +280,14 @@ #define STDERR_FILENO 2 #endif +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif + #ifndef R_OK #define R_OK 4 /* Test for read permission. */ #endif @@ -94,33 +308,153 @@ #define CHANGED -1 +#define typeCalloc(type,elts) (type *)calloc(elts,sizeof(type)) +#define FreeIfNeeded(p) if(p != 0) free(p) +#define FreeAndNull(p) free(p); p = 0 + +#include <nc_alloc.h> + /* - * ht/cbt expansion flakes out randomly under Linux 1.1.47, but only when - * we're throwing control codes at the screen at high volume. To see this, - * re-enable TABS_OK and run worm for a while. Other systems probably don't - * want to define this either due to uncertainties about tab delays and - * expansion in raw mode. + * Prefixes for call/return points of library function traces. We use these to + * instrument the public functions so that the traces can be easily transformed + * into regression scripts. */ -#undef TABS_OK /* OK to use tab/backtab for local motions? */ +#define T_CALLED(fmt) "called " fmt +#define T_CREATE(fmt) "create " fmt +#define T_RETURN(fmt) "return " fmt #ifdef TRACE -#define T(a) if (_nc_tracing & TRACE_CALLS) _tracef a -#define TR(n, a) if (_nc_tracing & (n)) _tracef a +#define TR(n, a) if (_nc_tracing & (n)) _tracef a +#define T(a) TR(TRACE_CALLS, a) #define TPUTS_TRACE(s) _nc_tputs_trace = s; +#define TRACE_RETURN(value,type) return _nc_retrace_##type(value) +#define returnWin(code) TRACE_RETURN(code,win) +#define returnPtr(code) TRACE_RETURN(code,ptr) +#define returnCode(code) TRACE_RETURN(code,int) +#define returnVoid T((T_RETURN(""))); return extern unsigned _nc_tracing; -extern char *_nc_tputs_trace; -extern char *_nc_visbuf(const char *); -#else +extern WINDOW * _nc_retrace_win(WINDOW *); +extern char *_nc_retrace_ptr(char *); +extern const char *_nc_tputs_trace; +extern const char *_nc_visbuf(const char *); +extern const char *_nc_visbuf2(int, const char *); +extern int _nc_retrace_int(int); +extern long _nc_outchars; +#else #define T(a) #define TR(n, a) #define TPUTS_TRACE(s) +#define returnWin(code) return code +#define returnCode(code) return code +#define returnVoid return +#endif + +#define _trace_key(ch) ((ch > KEY_MIN) ? keyname(ch) : _tracechar((unsigned char)ch)) + +#define ALL_BUT_COLOR ((chtype)~(A_COLOR)) +#define IGNORE_COLOR_OFF FALSE + + +/* Macro to put together character and attribute info and return it. + If colors are in the attribute, they have precedence. */ +#define ch_or_attr(ch,at) \ + ((PAIR_NUMBER(at) > 0) ? \ + ((((chtype)ch) & ALL_BUT_COLOR) | (at)) : ((((chtype)ch) | (at)))) + + +#define toggle_attr_on(S,at) \ + if (PAIR_NUMBER(at) > 0)\ + (S) = ((S) & ALL_BUT_COLOR) | (at);\ + else\ + (S) |= (at);\ + T(("new attribute is %s", _traceattr((S)))) + + +#define toggle_attr_off(S,at) \ + if (IGNORE_COLOR_OFF == TRUE) {\ + if (PAIR_NUMBER(at) == 0xff) /* turn off color */\ + (S) &= ~(at);\ + else /* leave color alone */\ + (S) &= ~((at)&ALL_BUT_COLOR);\ + } else {\ + if (PAIR_NUMBER(at) > 0x00) /* turn off color */\ + (S) &= ~(at|A_COLOR);\ + else /* leave color alone */\ + (S) &= ~(at);\ + }\ + T(("new attribute is %s", _traceattr((S)))); + +#define DelCharCost(count) \ + ((parm_dch != 0) \ + ? SP->_dch_cost \ + : ((delete_character != 0) \ + ? (SP->_dch1_cost * count) \ + : INFINITY)) + +#define InsCharCost(count) \ + ((parm_ich != 0) \ + ? SP->_ich_cost \ + : ((insert_character != 0) \ + ? (SP->_ich1_cost * count) \ + : INFINITY)) + +#define UpdateAttrs(c) if (SP->_current_attr != AttrOf(c)) \ + vidattr(AttrOf(c)); + +/* + * Check whether the given character can be output by clearing commands. This + * includes test for being a space and not including any 'bad' attributes, such + * as A_REVERSE. All attribute flags which don't affect appearance of a space + * or can be output by clearing (A_COLOR in case of bce-terminal) are excluded. + */ +#define NONBLANK_ATTR (A_BOLD|A_DIM|A_BLINK) +#define can_clear_with(ch) \ + ((ch & ~(NONBLANK_ATTR|(back_color_erase ? A_COLOR:0))) == BLANK) + +#ifdef NCURSES_EXPANDED + +#undef ch_or_attr +#define ch_or_attr(ch,at) _nc_ch_or_attr(ch,at) +extern chtype _nc_ch_or_attr(chtype, attr_t); + +#undef toggle_attr_on +#define toggle_attr_on(S,at) _nc_toggle_attr_on(&(S), at) +extern void _nc_toggle_attr_on(attr_t *, attr_t); + +#undef toggle_attr_off +#define toggle_attr_off(S,at) _nc_toggle_attr_off(&(S), at) +extern void _nc_toggle_attr_off(attr_t *, attr_t); + +#undef can_clear_with +#define can_clear_with(ch) _nc_can_clear_with(ch) +extern int _nc_can_clear_with(chtype); + +#undef DelCharCost +#define DelCharCost(count) _nc_DelCharCost(count) +extern int _nc_DelCharCost(int); + +#undef InsCharCost +#define InsCharCost(count) _nc_InsCharCost(count) +extern int _nc_InsCharCost(int); + +#undef UpdateAttrs +#define UpdateAttrs(c) _nc_UpdateAttrs(c) +extern void _nc_UpdateAttrs(chtype); + +#else + +extern void _nc_expanded(void); + #endif /* lib_acs.c */ extern void init_acs(void); /* no prefix, this name is traditional */ /* lib_mvcur.c */ -extern void _nc_mvcur_init(SCREEN *sp); +#define INFINITY 1000000 /* cost: too high to use */ + +extern void _nc_mvcur_init(void); +extern void _nc_mvcur_resume(void); extern void _nc_mvcur_wrap(void); extern int _nc_mvcur_scrolln(int, int, int, int); @@ -132,107 +466,35 @@ extern bool _nc_mouse_parse(int); extern void _nc_mouse_wrap(SCREEN *); extern void _nc_mouse_resume(SCREEN *); extern int _nc_max_click_interval; +extern int _nc_mouse_fd(void); /* elsewhere ... */ -extern int _nc_keypad(bool flag); -extern WINDOW *_nc_makenew(int, int, int, int); -#ifdef EXTERN_TERMINFO -#define _nc_outch _ti_outc -#endif +extern WINDOW *_nc_makenew(int, int, int, int, int); +extern chtype _nc_background(WINDOW *); +extern chtype _nc_render(WINDOW *, chtype); +extern char *_nc_trace_buf(int, size_t); +extern int _nc_initscr(void); +extern int _nc_keypad(bool); +#ifdef EXTERN_TERMINFO +#define _nc_outch _ti_outc +#endif extern int _nc_outch(int); -extern chtype _nc_render(WINDOW *, chtype, chtype); +extern int _nc_setupscreen(short, short const, FILE *); +extern int _nc_timed_wait(int, int, int *); extern int _nc_waddch_nosync(WINDOW *, const chtype); +extern void _nc_backspace(WINDOW *win); +extern void _nc_do_color(int, int (*)(int)); +extern void _nc_freeall(void); +extern void _nc_free_and_exit(int); +extern void _nc_freewin(WINDOW *win); +extern void _nc_get_screensize(void); +extern void _nc_hash_map(void); +extern void _nc_outstr(const char *str); extern void _nc_scroll_optimize(void); extern void _nc_scroll_window(WINDOW *, int const, short const, short const); -extern int _nc_setupscreen(short, short const); -extern void _nc_backspace(WINDOW *win); -extern void _nc_outstr(char *str); +extern void _nc_set_buffer(FILE *ofp, bool buffered); extern void _nc_signal_handler(bool); extern void _nc_synchook(WINDOW *win); -extern int _nc_timed_wait(int fd, int wait, int *timeleft); -extern void _nc_do_color(int, int (*)(int)); - -struct try { - struct try *child; /* ptr to child. NULL if none */ - struct try *sibling; /* ptr to sibling. NULL if none */ - unsigned char ch; /* character at this node */ - unsigned short value; /* code of string so far. 0 if none. */ -}; - -/* - * Structure for soft labels. - */ - -typedef struct { - char dirty; /* all labels have changed */ - char hidden; /* soft lables are hidden */ - WINDOW *win; - struct slk_ent { - char text[9]; /* text for the label */ - char form_text[9]; /* formatted text (left/center/...) */ - int x; /* x coordinate of this field */ - char dirty; /* this label has changed */ - char visible; /* field is visible */ - } ent[8]; -} SLK; - -#define FIFO_SIZE 32 - -struct screen { - int _ifd; /* input file ptr for screen */ - FILE *_ofp; /* output file ptr for screen */ - int _checkfd; /* filedesc for typeahead check */ -#ifdef EXTERN_TERMINFO - struct _terminal *_term; /* terminal type information */ -#else - struct term *_term; /* terminal type information */ -#endif - short _lines; /* screen lines */ - short _columns; /* screen columns */ - WINDOW *_curscr; /* current screen */ - WINDOW *_newscr; /* virtual screen to be updated to */ - WINDOW *_stdscr; /* screen's full-window context */ - struct try *_keytry; /* "Try" for use with keypad mode */ - unsigned int _fifo[FIFO_SIZE]; /* input pushback buffer */ - signed char _fifohead, /* head of fifo queue */ - _fifotail, /* tail of fifo queue */ - _fifopeek; /* where to peek for next char */ - bool _endwin; /* are we out of window mode? */ - chtype _current_attr; /* terminal attribute current set */ - bool _coloron; /* is color enabled? */ - int _cursor; /* visibility of the cursor */ - int _cursrow; /* physical cursor row */ - int _curscol; /* physical cursor column */ - bool _nl; /* True if NL -> CR/NL is on */ - bool _raw; /* True if in raw mode */ - int _cbreak; /* 1 if in cbreak mode */ - /* > 1 if in halfdelay mode */ - bool _echo; /* True if echo on */ - bool _use_meta; /* use the meta key? */ - SLK *_slk; /* ptr to soft key struct / NULL */ - int _baudrate; /* used to compute padding */ - - /* cursor movement costs; units are 10ths of milliseconds */ - int _char_padding; /* cost of character put */ - int _cr_cost; /* cost of (carriage_return) */ - int _cup_cost; /* cost of (cursor_address) */ - int _home_cost; /* cost of (cursor_home) */ - int _ll_cost; /* cost of (cursor_to_ll) */ -#ifdef TABS_OK - int _ht_cost; /* cost of (tab) */ - int _cbt_cost; /* cost of (backtab) */ -#endif /* TABS_OK */ - int _cub1_cost; /* cost of (cursor_left) */ - int _cuf1_cost; /* cost of (cursor_right) */ - int _cud1_cost; /* cost of (cursor_down) */ - int _cuu1_cost; /* cost of (cursor_up) */ - int _cub_cost; /* cost of (parm_cursor_left) */ - int _cuf_cost; /* cost of (parm_cursor_right) */ - int _cud_cost; /* cost of (parm_cursor_down) */ - int _cuu_cost; /* cost of (parm_cursor_up) */ - int _hpa_cost; /* cost of (column_address) */ - int _vpa_cost; /* cost of (row_address) */ -}; /* * On systems with a broken linker, define 'SP' as a function to force the @@ -249,10 +511,24 @@ extern int _nc_alloc_screen(void); extern void _nc_set_screen(SCREEN *); #else extern SCREEN *SP; -#define _nc_alloc_screen() ((SP = (SCREEN *) calloc(1, sizeof(*SP))) != NULL) +#define _nc_alloc_screen() ((SP = typeCalloc(SCREEN, 1)) != 0) #define _nc_set_screen(sp) SP = sp #endif +#if !HAVE_USLEEP +extern int _nc_usleep(unsigned int); +#define usleep(msecs) _nc_usleep(msecs) +#endif + +/* + * ncurses' term.h defines this but since we use our own terminfo + * we need to define it here. + */ +#ifdef EXTERN_TERMINFO +#define GET_TTY(fd, buf) tcgetattr(fd, buf) +#define SET_TTY(fd, buf) tcsetattr(fd, TCSADRAIN, buf) +#endif + /* * We don't want to use the lines or columns capabilities internally, * because if the application is running multiple screens under @@ -262,9 +538,20 @@ extern SCREEN *SP; #define screen_lines SP->_lines #define screen_columns SP->_columns -extern int _slk_init; /* TRUE if slk_init() called */ -extern int slk_initialize(WINDOW *, int); +extern int _nc_slk_format; /* != 0 if slk_init() called */ +extern int _nc_slk_initialize(WINDOW *, int); -#define MAXCOLUMNS 135 -#define MAXLINES 66 -#define UNINITIALISED ((struct try * ) -1) +/* Macro to check whether or not we use a standard format */ +#define SLK_STDFMT (_nc_slk_format < 3) +/* Macro to determine height of label window */ +#define SLK_LINES (SLK_STDFMT ? 1 : (_nc_slk_format - 2)) + +extern int _nc_ripoffline(int line, int (*init)(WINDOW *,int)); + +#define UNINITIALISED ((struct tries * ) -1) + +extern bool _nc_idlok, _nc_idcok; + +extern WINDOWLIST *_nc_windows; + +#endif /* CURSES_PRIV_H */ diff --git a/lib/libcurses/hardscroll.c b/lib/libcurses/hardscroll.c index 73d185b199e..7e6d1cc3bce 100644 --- a/lib/libcurses/hardscroll.c +++ b/lib/libcurses/hardscroll.c @@ -74,14 +74,14 @@ becomes new. For example, scrolling down the region from 12 to 16 will produce 0..11 -1 12..15 17..23. Now, an obvious property of all these operations is that they preserve the -order of old lines, though not their position in the sequence. +order of old lines, though not their position in the sequence. The key trick of this algorithm is that the original line indices described above are actually maintained as _line[].oldindex fields in the window structure, and stick to each line through scroll and insert/delete operations. Thus, it is possible at update time to look at the oldnum fields and compute -an optimal set of il/dl/scroll operations that will take the real screen +an optimal set of il/dl/scroll operations that will take the real screen lines to the virtual screen lines. Once these vertical moves have been done, we can hand off to the second stage of the update algorithm, which does line transformations. @@ -125,7 +125,7 @@ Here is pseudo-code for the remainder of the algorithm: 7: ofirst = (first line's oldnum, where it was on real screen) 8: olast = (last line's oldnum, where it was on real screen) - # figure the hunk's displacement + # figure the hunk's displacement 9: disp = first - (first virtual line's oldnum field) # does the hunk want to move? @@ -141,7 +141,7 @@ Here is pseudo-code for the remainder of the algorithm: 16: no_hunk_moved = FALSE # done trying to move this hunk -17: first = last + 1; +17: first = last + 1; end while until 18: no_hunk_moved; # quit when a complete pass finds no movable hunks @@ -151,9 +151,9 @@ HOW TO TEST THIS: Use the following production: hardscroll: hardscroll.c - $(CC) -g -DMAINDEBUG hardscroll.c -o hardscroll + $(CC) -g -DSCROLLDEBUG hardscroll.c -o hardscroll -Then just type scramble vectors and watch. The following test loads are +Then just type scramble vectors and watch. The following test loads are a representative sample of cases: ----------------------------- CUT HERE ------------------------------------ @@ -181,21 +181,20 @@ AUTHOR *****************************************************************************/ -#include "curses.priv.h" +#include <curses.priv.h> -#include <stdlib.h> -#include <string.h> +MODULE_ID("Id: hardscroll.c,v 1.17 1997/02/15 22:33:12 tom Exp $") -#if defined(TRACE) || defined(MAINDEBUG) -static void linedump(void); -#endif /* defined(TRACE) || defined(MAINDEBUG) */ +#if defined(TRACE) || defined(SCROLLDEBUG) +void _nc_linedump(void); +#endif /* defined(TRACE) || defined(SCROLLDEBUG) */ /* if only this number of lines is carried over, nuke the screen and redraw */ #define CLEAR_THRESHOLD 3 -#ifdef MAINDEBUG +#if defined(SCROLLDEBUG) || defined(HASHDEBUG) #define LINES 24 -static int oldnums[LINES], reallines[LINES]; +int oldnums[LINES], reallines[LINES]; #define OLDNUM(n) oldnums[n] #define REAL(m) reallines[m] #undef T @@ -207,7 +206,7 @@ static int oldnums[LINES], reallines[LINES]; #ifndef _NEWINDEX #define _NEWINDEX -1 #endif /* _NEWINDEX */ -#endif /* MAINDEBUG */ +#endif /* defined(SCROLLDEBUG) || defined(HASHDEBUG) */ static bool all_discarded(int const top, int const bottom, int const disp) /* has the given range of real lines been marked discarded? */ @@ -226,11 +225,11 @@ void _nc_scroll_optimize(void) { bool no_hunk_moved; /* no hunk moved on this pass? */ int n, new_lines; -#if defined(TRACE) || defined(MAINDEBUG) +#if defined(TRACE) || defined(SCROLLDEBUG) int pass = 0; -#endif /* defined(TRACE) || defined(MAINDEBUG) */ +#endif /* defined(TRACE) || defined(SCROLLDEBUG) */ - TR(TRACE_CALLS, ("_nc_scroll_optimize() begins")); + TR(TRACE_ICALLS, ("_nc_scroll_optimize() begins")); /* mark any line not carried over with _NEWINDEX */ for (n = 0; n < LINES; n++) @@ -246,7 +245,7 @@ void _nc_scroll_optimize(void) new_lines++; } - /* + /* * ^F in vi (which scrolls forward by LINES-2 in the file) exposes * a weakness in this design. Ideally, vertical motion * optimization should cost its actions and then force a @@ -256,22 +255,22 @@ void _nc_scroll_optimize(void) * carried over, don't bother with the scrolling, we just nuke the * screen and redraw the whole thing. Keith Bostic argues that * this will be a win on strictly visual grounds even if the - * resulting update is theoretically sub-optimal. Experience + * resulting update is theoretically sub-optimal. Experience * with vi says he's probably right. */ if (LINES - new_lines <= CLEAR_THRESHOLD) { T(("too few lines carried over, nuking screen")); -#ifndef MAINDEBUG +#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) clearok(stdscr, TRUE); -#endif /* MAINDEBUG */ +#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ return; } #ifdef TRACE TR(TRACE_UPDATE | TRACE_MOVE, ("After real line marking:")); if (_nc_tracing & (TRACE_UPDATE | TRACE_MOVE)) - linedump(); + _nc_linedump(); #endif /* TRACE */ /* time to shuffle lines to do scroll optimization */ @@ -284,7 +283,7 @@ void _nc_scroll_optimize(void) TR(TRACE_UPDATE | TRACE_MOVE, ("Pass %d:", pass++)); - first = 0; /* start scan at top line */ + first = 0; /* start scan at top line */ no_hunk_moved = TRUE; while (first < LINES) @@ -322,15 +321,16 @@ void _nc_scroll_optimize(void) ofirst += disp; TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", ofirst, olast, -disp)); -#ifndef MAINDEBUG - (void) _nc_mvcur_scrolln(-disp, ofirst, olast, LINES - 1); +#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) + if (_nc_mvcur_scrolln(-disp, ofirst, olast, LINES - 1) == ERR) + break; _nc_scroll_window(curscr, -disp, ofirst, olast); -#endif /* MAINDEBUG */ +#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ for (m = ofirst; m <= olast; m++) { REAL(m) = _NEWINDEX; -#ifndef MAINDEBUG +#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) /* * This will tell the second stage of the optimizer * that every line in the hunk on the real screen has @@ -338,7 +338,7 @@ void _nc_scroll_optimize(void) */ curscr->_line[m].firstchar = 0; curscr->_line[m].lastchar = curscr->_maxx; -#endif /* MAINDEBUG */ +#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ } for (m = first; m <= last; m++) OLDNUM(m) = _NEWINDEX; @@ -353,8 +353,8 @@ void _nc_scroll_optimize(void) (!no_hunk_moved); } -#if defined(TRACE) || defined(MAINDEBUG) -static void linedump(void) +#if defined(TRACE) || defined(SCROLLDEBUG) +void _nc_linedump(void) /* dump the state of the real and virtual oldnum fields */ { int n; @@ -362,7 +362,7 @@ static void linedump(void) (void) strcpy(buf, "real"); for (n = 0; n < LINES; n++) - (void) sprintf(buf + strlen(buf), " %02d", REAL(n)); + (void) sprintf(buf + strlen(buf), " %02d", REAL(n)); TR(TRACE_UPDATE | TRACE_MOVE, (buf)); (void) strcpy(buf, "virt"); @@ -370,11 +370,12 @@ static void linedump(void) (void) sprintf(buf + strlen(buf), " %02d", OLDNUM(n)); TR(TRACE_UPDATE | TRACE_MOVE, (buf)); } -#endif /* defined(TRACE) || defined(MAINDEBUG) */ +#endif /* defined(TRACE) || defined(SCROLLDEBUG) */ -#ifdef MAINDEBUG +#ifdef SCROLLDEBUG -main() +int +main(int argc GCC_UNUSED, char *argv[] GCC_UNUSED) { char line[BUFSIZ], *st; @@ -391,7 +392,7 @@ main() /* grab the test vector */ if (fgets(line, sizeof(line), stdin) == (char *)NULL) - exit(0); + exit(EXIT_SUCCESS); /* parse it */ n = 0; @@ -404,17 +405,16 @@ main() do { oldnums[n++] = atoi(st); } while - (st = strtok((char *)NULL, " ")); + ((st = strtok((char *)NULL, " ")) != 0); /* display it */ (void) fputs("Initial input:\n", stderr); - linedump(); + _nc_linedump(); - _nc_scroll_optimize(); + _nc_scroll_optimize(); } } -#endif /* MAINDEBUG */ +#endif /* SCROLLDEBUG */ /* hardscroll.c ends here */ - diff --git a/lib/libcurses/hashmap.c b/lib/libcurses/hashmap.c new file mode 100644 index 00000000000..d9557e0cf2e --- /dev/null +++ b/lib/libcurses/hashmap.c @@ -0,0 +1,319 @@ + +/*************************************************************************** +* COPYRIGHT NOTICE * +**************************************************************************** +* ncurses is copyright (C) 1992-1995 * +* Zeyd M. Ben-Halim * +* zmbenhal@netcom.com * +* Eric S. Raymond * +* esr@snark.thyrsus.com * +* * +* Permission is hereby granted to reproduce and distribute ncurses * +* by any means and for any fee, whether alone or as part of a * +* larger distribution, in source or in binary form, PROVIDED * +* this notice is included with any such distribution, and is not * +* removed from any of its header files. Mention of ncurses in any * +* applications linked with it is highly appreciated. * +* * +* ncurses comes AS IS with no warranty, implied or expressed. * +* * +***************************************************************************/ + +/****************************************************************************** + +NAME + hashmap.c -- fill in scramble vector based on text hashes + +SYNOPSIS + void _nc_hash_map(void) + +DESCRIPTION: + This code attempts to recognize pairs of old and new lines in the physical +and virtual screens. When a line pair is recognized, the old line index is +placed in the oldindex member of the virtual screen line, to be used by the +vertical-motion optimizer portion of the update logic (see hardscroll.c). + + Line pairs are recognized by applying a modified Heckel's algorithm, +sped up by hashing. If a line hash is unique in both screens, those +lines must be a pair. If the hashes of the two lines immediately following +lines known to be a pair are the same, the following lines are also a pair. +We apply these rules repeatedly until no more pairs are found. The +modifications stem from the fact that there may already be oldindex info +associated with the virtual screen, which has to be respected. + + We don't worry about false pairs produced by hash collisions, on the +assumption that such cases are rare and will only make the latter stages +of update less efficient, not introduce errors. + +HOW TO TEST THIS: + +Use the following production: + +hashmap: hashmap.c + $(CC) -g -DHASHDEBUG hashmap.c hardscroll.c ../objects/lib_trace.o -o hashmap + +AUTHOR + Eric S. Raymond <esr@snark.thyrsus.com>, May 1996 + +*****************************************************************************/ + +#include <curses.priv.h> + +MODULE_ID("Id: hashmap.c,v 1.12 1997/05/03 20:30:06 tom Exp $") + +#ifdef HASHDEBUG +#define LINES 24 +#define TEXTWIDTH 1 +int oldnums[LINES], reallines[LINES]; +static chtype oldtext[LINES][TEXTWIDTH], newtext[LINES][TEXTWIDTH]; +#define OLDNUM(n) oldnums[n] +#define REAL(m) reallines[m] +#define OLDTEXT(n) oldtext[n] +#define NEWTEXT(m) newtext[m] +#undef T +#define T(x) (void) printf x ; (void) putchar('\n'); +#else +#include <curses.h> +#define OLDNUM(n) newscr->_line[n].oldindex +#define REAL(m) curscr->_line[m].oldindex +#define OLDTEXT(n) curscr->_line[n].text +#define NEWTEXT(m) newscr->_line[m].text +#define TEXTWIDTH (curscr->_maxx+1) +#ifndef _NEWINDEX +#define _NEWINDEX -1 +#endif /* _NEWINDEX */ +#endif /* HASHDEBUG */ + +/* Chris Torek's hash function (from his DB package). */ +static inline unsigned long hash4(const void *key, size_t len) +{ + register long h, loop; + register unsigned const char *k; + +#define HASH4a h = (h << 5) - h + *k++; +#define HASH4b h = (h << 5) + h + *k++; +#define HASH4 HASH4b + h = 0; + k = (unsigned const char *)key; + if (len > 0) { + loop = (len + 8 - 1) >> 3; + switch (len & (8 - 1)) { + case 0: + do { /* All fall throughs */ + HASH4; + case 7: + HASH4; + case 6: + HASH4; + case 5: + HASH4; + case 4: + HASH4; + case 3: + HASH4; + case 2: + HASH4; + case 1: + HASH4; + } while (--loop); + } + } + return ((unsigned long)h); +} + +static inline unsigned long hash(chtype *text) +{ + return(hash4(text, TEXTWIDTH*sizeof(*text))); +} + +void _nc_hash_map(void) +{ + typedef struct + { + unsigned long hashval; + int oldcount, newcount; + int oldindex, newindex; + } + sym; + sym hashtab[MAXLINES*2], *sp; + register int i; + long oldhash[MAXLINES], newhash[MAXLINES]; + bool keepgoing; + + /* + * Set up and count line-hash values. + */ + memset(hashtab, '\0', sizeof(sym) * MAXLINES); + for (i = 0; i < LINES; i++) + { + unsigned long hashval = hash(OLDTEXT(i)); + + for (sp = hashtab; sp->hashval; sp++) + if (sp->hashval == hashval) + break; + sp->hashval = hashval; /* in case this is a new entry */ + oldhash[i] = hashval; + sp->oldcount++; + sp->oldindex = i; + } + for (i = 0; i < LINES; i++) + { + unsigned long hashval = hash(NEWTEXT(i)); + + for (sp = hashtab; sp->hashval; sp++) + if (sp->hashval == hashval) + break; + sp->hashval = hashval; /* in case this is a new entry */ + newhash[i] = hashval; + sp->newcount++; + sp->newindex = i; + + OLDNUM(i) = _NEWINDEX; + } + + /* + * Mark line pairs corresponding to unique hash pairs. + * Note: we only do this where the new line doesn't + * already have a valid oldindex -- this way we preserve the + * information left in place by the software scrolling functions. + */ + for (sp = hashtab; sp->hashval; sp++) + if (sp->oldcount == 1 && sp->newcount == 1 + && OLDNUM(sp->newindex) == _NEWINDEX) + { + TR(TRACE_UPDATE | TRACE_MOVE, + ("new line %d is hash-identical to old line %d (unique)", + sp->newindex, sp->oldindex)); + OLDNUM(sp->newindex) = sp->oldindex; + } + + /* + * Now for the tricky part. We have unique pairs to use as anchors. + * Use these to deduce the presence of spans of identical lines. + */ + do { + keepgoing = FALSE; + + for (i = 0; i < LINES-1; i++) + if (OLDNUM(i) != _NEWINDEX && OLDNUM(i+1) == _NEWINDEX) + { + if (OLDNUM(i) + 1 < LINES + && newhash[i+1] == oldhash[OLDNUM(i) + 1]) + { + OLDNUM(i+1) = OLDNUM(i) + 1; + TR(TRACE_UPDATE | TRACE_MOVE, + ("new line %d is hash-identical to old line %d (forward continuation)", + i+1, OLDNUM(i) + 1)); + keepgoing = TRUE; + } + } + + for (i = 0; i < LINES-1; i++) + if (OLDNUM(i) != _NEWINDEX && OLDNUM(i-1) == _NEWINDEX) + { + if (OLDNUM(i) - 1 >= 0 + && newhash[i-1] == oldhash[OLDNUM(i) - 1]) + { + OLDNUM(i-1) = OLDNUM(i) - 1; + TR(TRACE_UPDATE | TRACE_MOVE, + ("new line %d is hash-identical to old line %d (backward continuation)", + i-1, OLDNUM(i) - 1)); + keepgoing = TRUE; + } + } + } while + (keepgoing); +} + +#ifdef HASHDEBUG + +int +main(int argc GCC_UNUSED, char *argv[] GCC_UNUSED) +{ + extern void _nc_linedump(void); + char line[BUFSIZ], *st; + int n; + + for (n = 0; n < LINES; n++) + { + reallines[n] = n; + oldnums[n] = _NEWINDEX; + oldtext[n][0] = newtext[n][0] = '.'; + } + + _nc_tracing = TRACE_MOVE; + for (;;) + { + /* grab a test command */ + if (fgets(line, sizeof(line), stdin) == (char *)NULL) + exit(EXIT_SUCCESS); + + switch(line[0]) + { + case '#': /* comment */ + (void) fputs(line, stderr); + break; + + case 'l': /* get initial line number vector */ + for (n = 0; n < LINES; n++) + { + reallines[n] = n; + oldnums[n] = _NEWINDEX; + } + n = 0; + st = strtok(line, " "); + do { + oldnums[n++] = atoi(st); + } while + ((st = strtok((char *)NULL, " ")) != 0); + break; + + case 'n': /* use following letters as text of new lines */ + for (n = 0; n < LINES; n++) + newtext[n][0] = '.'; + for (n = 0; n < LINES; n++) + if (line[n+1] == '\n') + break; + else + newtext[n][0] = line[n+1]; + break; + + case 'o': /* use following letters as text of old lines */ + for (n = 0; n < LINES; n++) + oldtext[n][0] = '.'; + for (n = 0; n < LINES; n++) + if (line[n+1] == '\n') + break; + else + oldtext[n][0] = line[n+1]; + break; + + case 'd': /* dump state of test arrays */ + _nc_linedump(); + (void) fputs("Old lines: [", stdout); + for (n = 0; n < LINES; n++) + putchar(oldtext[n][0]); + putchar(']'); + putchar('\n'); + (void) fputs("New lines: [", stdout); + for (n = 0; n < LINES; n++) + putchar(newtext[n][0]); + putchar(']'); + putchar('\n'); + break; + + case 'h': /* apply hash mapper and see scroll optimization */ + _nc_hash_map(); + (void) fputs("Result:\n", stderr); + _nc_linedump(); + _nc_scroll_optimize(); + (void) fputs("Done.\n", stderr); + break; + } + } + return EXIT_SUCCESS; +} + +#endif /* HASHDEBUG */ + +/* hashmap.c ends here */ diff --git a/lib/libcurses/lib_acs.c b/lib/libcurses/lib_acs.c index ba867d7cc73..e72c653bebf 100644 --- a/lib/libcurses/lib_acs.c +++ b/lib/libcurses/lib_acs.c @@ -21,9 +21,10 @@ -#include "curses.priv.h" -#include "term.h" /* ena_acs, acs_chars */ -#include <string.h> +#include <curses.priv.h> +#include <term.h> /* ena_acs, acs_chars */ + +MODULE_ID("Id: lib_acs.c,v 1.8 1997/04/24 11:04:07 tom Exp $") chtype acs_map[128]; @@ -61,7 +62,7 @@ void init_acs(void) ACS_LANTERN = '#'; /* should be lantern symbol */ ACS_BLOCK = '#'; /* should be solid square block */ /* these defaults were invented for ncurses */ - ACS_S3 = '-'; /* should be scan line 3 */ + ACS_S3 = '-'; /* should be scan line 3 */ ACS_S7 = '-'; /* should be scan line 7 */ ACS_LEQUAL = '<'; /* should be less-than-or-equal-to */ ACS_GEQUAL = '>'; /* should be greater-than-or-equal-to */ @@ -78,13 +79,13 @@ void init_acs(void) #endif /* ena_acs */ #ifdef acs_chars -#define ALTCHAR(c) ((chtype)(c) & A_CHARTEXT) | A_ALTCHARSET +#define ALTCHAR(c) (TextOf(c) | A_ALTCHARSET) if (acs_chars != NULL) { size_t i = 0; size_t length = strlen(acs_chars); - - while (i < length) + + while (i < length) switch (acs_chars[i]) { case 'l':case 'm':case 'k':case 'j': case 'u':case 't':case 'v':case 'w': @@ -94,7 +95,7 @@ void init_acs(void) case '.':case '-':case 'h':case 'I': case '0':case 'p':case 'r':case 'y': case 'z':case '{':case '|':case '}': - acs_map[(unsigned int)acs_chars[i]] = + acs_map[(unsigned int)acs_chars[i]] = ALTCHAR(acs_chars[i+1]); i++; /* FALLTHRU */ @@ -104,8 +105,27 @@ void init_acs(void) } } #ifdef TRACE - else { - T(("acsc not defined, using default mapping")); +#define SIZEOF(v) (sizeof(v)/sizeof(v[0])) + /* Show the equivalent mapping, noting if it does not match the + * given attribute, whether by re-ordering or duplication. + */ + if (_nc_tracing & TRACE_CALLS) { + size_t n, m; + char show[SIZEOF(acs_map) + 1]; + for (n = 1, m = 0; n < SIZEOF(acs_map); n++) { + if (acs_map[n] != 0) { + show[m++] = (char)n; + show[m++] = TextOf(acs_map[n]); + } + } + show[m] = 0; + _tracef("%s acs_chars %s", + (acs_chars == NULL) + ? "NULL" + : (strcmp(acs_chars, show) + ? "DIFF" + : "SAME"), + _nc_visbuf(show)); } #endif /* TRACE */ #endif /* acs_char */ diff --git a/lib/libcurses/lib_addch.c b/lib/libcurses/lib_addch.c index 005c5bfbd22..5ad512c0dd1 100644 --- a/lib/libcurses/lib_addch.c +++ b/lib/libcurses/lib_addch.c @@ -26,56 +26,40 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> #include <ctype.h> -#include "unctrl.h" -#define ALL_BUT_COLOR ((chtype)~(A_COLOR)) +MODULE_ID("Id: lib_addch.c,v 1.30 1997/04/12 17:45:55 tom Exp $") int wattr_on(WINDOW *win, const attr_t at) { - T(("wattr_on(%p,%s) current = %s", win, _traceattr(at), _traceattr(win->_attrs))); - if (PAIR_NUMBER(at) > 0x00) { - win->_attrs = (win->_attrs & ALL_BUT_COLOR) | at ; - T(("new attribute is %s", _traceattr(win->_attrs))); - } else { - win->_attrs |= at; - T(("new attribute is %s", _traceattr(win->_attrs))); - } - return OK; + T((T_CALLED("wattr_on(%p,%s)"), win, _traceattr(at))); + T(("... current %s", _traceattr(win->_attrs))); + toggle_attr_on(win->_attrs,at); + returnCode(OK); } int wattr_off(WINDOW *win, const attr_t at) { -#define IGNORE_COLOR_OFF FALSE - - T(("wattr_off(%p,%s) current = %s", win, _traceattr(at), _traceattr(win->_attrs))); - if (IGNORE_COLOR_OFF == TRUE) { - if (PAIR_NUMBER(at) == 0xff) /* turn off color */ - win->_attrs &= ~at; - else /* leave color alone */ - win->_attrs &= ~(at|ALL_BUT_COLOR); - } else { - if (PAIR_NUMBER(at) > 0x00) /* turn off color */ - win->_attrs &= ~at; - else /* leave color alone */ - win->_attrs &= ~(at|ALL_BUT_COLOR); - } - T(("new attribute is %s", _traceattr(win->_attrs))); - return OK; + T((T_CALLED("wattr_off(%p,%s)"), win, _traceattr(at))); + T(("... current %s", _traceattr(win->_attrs))); + toggle_attr_off(win->_attrs,at); + returnCode(OK); } -int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts) +int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts GCC_UNUSED) { int i; + T((T_CALLED("wchgat(%p,%d,%s,%d)"), win, n, _traceattr(attr), color)); + + toggle_attr_on(attr,COLOR_PAIR(color)); + for (i = win->_curx; i <= win->_maxx && (n == -1 || (n-- > 0)); i++) win->_line[win->_cury].text[i] - = (win->_line[win->_cury].text[i] & A_CHARTEXT) - | attr - | COLOR_PAIR(color); + = ch_or_attr(TextOf(win->_line[win->_cury].text[i]),attr); - return OK; + returnCode(OK); } /* @@ -88,46 +72,48 @@ int wchgat(WINDOW *win, int n, attr_t attr, short color, const void *opts) * window sync hook, for use by string-put functions. */ -static __inline chtype render_char(WINDOW *win, chtype oldch, chtype newch) +static inline chtype render_char(WINDOW *win, chtype ch) /* compute a rendition of the given char correct for the current context */ { - if ((oldch & A_CHARTEXT) == ' ') - newch |= win->_bkgd; - else if (!(newch & A_ATTRIBUTES)) - newch |= (win->_bkgd & A_ATTRIBUTES); - TR(TRACE_VIRTPUT, ("bkg = %lx -> ch = %lx", win->_bkgd, newch)); + if (TextOf(ch) == ' ') + ch = ch_or_attr(ch, win->_bkgd); + else if (!(ch & A_ATTRIBUTES)) + ch = ch_or_attr(ch, (win->_bkgd & A_ATTRIBUTES)); + TR(TRACE_VIRTPUT, ("bkg = %#lx -> ch = %#lx", win->_bkgd, ch)); - return(newch); + return(ch); } -chtype _nc_render(WINDOW *win, chtype oldch, chtype newch) +chtype _nc_background(WINDOW *win) /* make render_char() visible while still allowing us to inline it below */ { - return(render_char(win, oldch, newch)); + return(render_char(win, BLANK)); } -/* actions needed to process a newline within addch_nosync() */ -#define DO_NEWLINE x = 0; \ - win->_flags &= ~_NEED_WRAP; \ - y++; \ - if (y > win->_regbottom) { \ - y--; \ - if (win->_scroll) \ - scroll(win); \ - } +chtype _nc_render(WINDOW *win, chtype ch) +/* make render_char() visible while still allowing us to inline it below */ +{ + chtype c = render_char(win,ch); + return (ch_or_attr(c,win->_attrs)); +} /* check if position is legal; if not, return error */ +#ifdef NDEBUG /* treat this like an assertion */ #define CHECK_POSITION(win, x, y) \ - if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0) { \ + if (y > win->_maxy \ + || x > win->_maxx \ + || y < 0 \ + || x < 0) { \ TR(TRACE_VIRTPUT, ("Alert! Win=%p _curx = %d, _cury = %d " \ "(_maxx = %d, _maxy = %d)", win, x, y, \ win->_maxx, win->_maxy)); \ - win->_curx = win->_cury = 0; \ - win->_flags &= ~_NEED_WRAP; \ - return(ERR); \ + return(ERR); \ } +#else +#define CHECK_POSITION(win, x, y) /* nothing */ +#endif -static __inline +static inline int waddch_literal(WINDOW *win, chtype ch) { register int x, y; @@ -137,21 +123,19 @@ register int x, y; CHECK_POSITION(win, x, y); - if (win->_flags & _NEED_WRAP) { - TR(TRACE_MOVE, ("new char when NEED_WRAP set at %d,%d",y,x)); - DO_NEWLINE - } - /* - * We used to pass in - * win->_line[y].text[x] - * as a second argument, but the value of the old character - * is not relevant here. + * If we're trying to add a character at the lower-right corner more + * than once, fail. (Moving the cursor will clear the flag). */ - ch = render_char(win, 0, ch); + if (win->_flags & _WRAPPED) { + if (x >= win->_maxx) + return (ERR); + win->_flags &= ~_WRAPPED; + } + ch = render_char(win, ch); + ch = ch_or_attr(ch,win->_attrs); TR(TRACE_VIRTPUT, ("win attr = %s", _traceattr(win->_attrs))); - ch |= win->_attrs; if (win->_line[y].text[x] != ch) { if (win->_line[y].firstchar == _NOCHANGE) @@ -164,14 +148,31 @@ register int x, y; } win->_line[y].text[x++] = ch; - TR(TRACE_VIRTPUT, ("(%d, %d) = %s | %s", - y, x, - _tracechar((unsigned char)(ch & A_CHARTEXT)), - _traceattr((ch & (chtype)A_ATTRIBUTES)))); + TR(TRACE_VIRTPUT, ("(%d, %d) = %s", y, x, _tracechtype(ch))); if (x > win->_maxx) { - TR(TRACE_MOVE, ("NEED_WRAP set at %d,%d",y,x)); - win->_flags |= _NEED_WRAP; - x--; + /* + * The _WRAPPED flag is useful only for telling an application + * that we've just wrapped the cursor. We don't do anything + * with this flag except set it when wrapping, and clear it + * whenever we move the cursor. If we try to wrap at the + * lower-right corner of a window, we cannot move the cursor + * (since that wouldn't be legal). So we return an error + * (which is what SVr4 does). Unlike SVr4, we can successfully + * add a character to the lower-right corner. + */ + win->_flags |= _WRAPPED; + if (++y > win->_regbottom) { + y = win->_regbottom; + x = win->_maxx; + if (win->_scroll) + scroll(win); + else { + win->_curx = x; + win->_cury = y; + return (ERR); + } + } + x = 0; } win->_curx = x; @@ -180,13 +181,12 @@ register int x, y; return OK; } -static __inline +static inline int waddch_nosync(WINDOW *win, const chtype c) /* the workhorse function -- add a character to the given window */ { register chtype ch = c; register int x, y; -int newx; x = win->_curx; y = win->_cury; @@ -196,40 +196,63 @@ int newx; if (ch & A_ALTCHARSET) goto noctrl; - switch ((int)(ch&A_CHARTEXT)) { - case '\t': - if (win->_flags & _NEED_WRAP) { - x = 0; - newx = min(TABSIZE, win->_maxx+1); - } else - newx = min(x + (TABSIZE-(x%TABSIZE)), win->_maxx+1); - while (win->_curx < newx) { - if (waddch_literal(win, ' ' | (ch&A_ATTRIBUTES)) == ERR) - return(ERR); + switch ((int)TextOf(ch)) { + case '\t': + x += (TABSIZE-(x%TABSIZE)); + + /* + * Space-fill the tab on the bottom line so that we'll get the + * "correct" cursor position. + */ + if ((! win->_scroll && (y == win->_regbottom)) + || (x <= win->_maxx)) { + while (win->_curx < x) { + if (waddch_literal(win, (' ' | AttrOf(ch))) == ERR) + return(ERR); + } + break; + } else { + wclrtoeol(win); + win->_flags |= _WRAPPED; + if (++y > win->_regbottom) { + x = win->_maxx; + y--; + if (win->_scroll) { + scroll(win); + x = 0; + } + } else { + x = 0; + } } - return(OK); - case '\n': - wclrtoeol(win); - DO_NEWLINE break; - case '\r': + case '\n': + wclrtoeol(win); + if (++y > win->_regbottom) { + y--; + if (win->_scroll) + scroll(win); + else + return (ERR); + } + /* FALLTHRU */ + case '\r': x = 0; - win->_flags &= ~_NEED_WRAP; + win->_flags &= ~_WRAPPED; break; - case '\b': - if (win->_flags & _NEED_WRAP) - win->_flags &= ~_NEED_WRAP; - else if (--x < 0) - x = 0; + case '\b': + if (x > 0) { + x--; + win->_flags &= ~_WRAPPED; + } break; - default: - if (is7bits(ch & A_CHARTEXT) && iscntrl(ch & A_CHARTEXT)) - return(waddstr(win, unctrl((unsigned char)ch))); + default: + if (is7bits(TextOf(ch)) && iscntrl(TextOf(ch))) + return(waddstr(win, unctrl((unsigned char)ch))); /* FALLTHRU */ - noctrl: - waddch_literal(win, ch); - return(OK); + noctrl: + return waddch_literal(win, ch); } win->_curx = x; @@ -238,8 +261,6 @@ int newx; return(OK); } -#undef DO_NEWLINE - int _nc_waddch_nosync(WINDOW *win, const chtype c) /* export copy of waddch_nosync() so the string-put functions can use it */ { @@ -256,32 +277,34 @@ int _nc_waddch_nosync(WINDOW *win, const chtype c) int waddch(WINDOW *win, const chtype ch) { - TR(TRACE_VIRTPUT, ("waddch(%p, %s | %s) called", win, - _tracechar((unsigned char)(ch & A_CHARTEXT)), - _traceattr((ch & (chtype)A_ATTRIBUTES)))); + int code = ERR; - if (waddch_nosync(win, ch) == ERR) - return(ERR); - else + TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_CALLED("waddch(%p, %s)"), win, _tracechtype(ch))); + + if (waddch_nosync(win, ch) != ERR) { _nc_synchook(win); - TR(TRACE_VIRTPUT, ("waddch() is done")); - return(OK); + code = OK; } + + TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_RETURN("%d"), code)); + return(code); } int wechochar(WINDOW *win, const chtype ch) { - TR(TRACE_VIRTPUT, ("wechochar(%p,%s (%s)) called", win, - _tracechar((unsigned char)(ch & A_CHARTEXT)), - _traceattr((ch & (chtype)A_ATTRIBUTES)))); + int code = ERR; + + TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"), win, _tracechtype(ch))); - if (waddch_literal(win, ch) == ERR) - return(ERR); - else + if (waddch_literal(win, ch) != ERR) { + bool save_immed = win->_immed; + win->_immed = TRUE; _nc_synchook(win); - TR(TRACE_VIRTPUT, ("wechochar() is done")); - return(OK); + win->_immed = save_immed; + code = OK; } + TR(TRACE_VIRTPUT|TRACE_CCALLS, (T_RETURN("%d"), code)); + return(code); } diff --git a/lib/libcurses/lib_addstr.c b/lib/libcurses/lib_addstr.c index 6d98d0464c6..2ece75c6cd7 100644 --- a/lib/libcurses/lib_addstr.c +++ b/lib/libcurses/lib_addstr.c @@ -26,18 +26,20 @@ ** */ -#include "curses.priv.h" -#include <string.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_addstr.c,v 1.11 1997/03/08 21:38:52 tom Exp $") int waddnstr(WINDOW *win, const char *const astr, int n) { -unsigned char *str = (unsigned char *)astr; +unsigned const char *str = (unsigned const char *)astr; int code = ERR; - T(("waddnstr(%p,\"%s\",%d) called %s", win, _nc_visbuf(astr), n, _traceattr(win->_attrs))); + T((T_CALLED("waddnstr(%p,%s,%d)"), win, _nc_visbuf(astr), n)); + T(("... current %s", _traceattr(win->_attrs))); - if (str != NULL) { + if (str != 0) { TR(TRACE_VIRTPUT, ("str is not null")); code = OK; @@ -45,7 +47,7 @@ int code = ERR; n = (int)strlen(astr); while((n-- > 0) && (*str != '\0')) { - TR(TRACE_VIRTPUT, ("*str = %x", *str)); + TR(TRACE_VIRTPUT, ("*str = %#x", *str)); if (_nc_waddch_nosync(win, (chtype)*str++) == ERR) { code = ERR; break; @@ -54,7 +56,7 @@ int code = ERR; } _nc_synchook(win); TR(TRACE_VIRTPUT, ("waddnstr returns %d", code)); - return code; + returnCode(code); } int @@ -62,16 +64,16 @@ waddchnstr(WINDOW *win, const chtype *const astr, int n) { short oy = win->_cury; short ox = win->_curx; -chtype *str = (chtype *)astr; +const chtype *str = (const chtype *)astr; int code = OK; - T(("waddchnstr(%p,%p,%d) called", win, str, n)); + T((T_CALLED("waddchnstr(%p,%p,%d)"), win, str, n)); if (n < 0) { n = 0; while (*str++ != 0) n++; - str = (chtype *)astr; + str = (const chtype *)astr; } while(n-- > 0) { @@ -84,5 +86,5 @@ int code = OK; win->_curx = ox; win->_cury = oy; _nc_synchook(win); - return code; + returnCode(code); } diff --git a/lib/libcurses/lib_baudrate.c b/lib/libcurses/lib_baudrate.c new file mode 100644 index 00000000000..2dfd34dbfb8 --- /dev/null +++ b/lib/libcurses/lib_baudrate.c @@ -0,0 +1,135 @@ + +/*************************************************************************** +* COPYRIGHT NOTICE * +**************************************************************************** +* ncurses is copyright (C) 1992-1995 * +* Zeyd M. Ben-Halim * +* zmbenhal@netcom.com * +* Eric S. Raymond * +* esr@snark.thyrsus.com * +* * +* Permission is hereby granted to reproduce and distribute ncurses * +* by any means and for any fee, whether alone or as part of a * +* larger distribution, in source or in binary form, PROVIDED * +* this notice is included with any such distribution, and is not * +* removed from any of its header files. Mention of ncurses in any * +* applications linked with it is highly appreciated. * +* * +* ncurses comes AS IS with no warranty, implied or expressed. * +* * +***************************************************************************/ + + +/* + * lib_baudrate.c + * + */ + +#include <curses.priv.h> +#include <term.h> /* cur_term, pad_char */ + +MODULE_ID("Id: lib_baudrate.c,v 1.7 1997/04/26 17:41:48 tom Exp $") + +/* + * int + * baudrate() + * + * Returns the current terminal's baud rate. + * + */ + +struct speed { + speed_t s; + int sp; +}; + +static struct speed const speeds[] = { + {B0, 0}, + {B50, 50}, + {B75, 75}, + {B110, 110}, + {B134, 134}, + {B150, 150}, + {B200, 200}, + {B300, 300}, + {B600, 600}, + {B1200, 1200}, + {B1800, 1800}, + {B2400, 2400}, + {B4800, 4800}, + {B9600, 9600}, +#define MAX_BAUD B9600 +#ifdef B19200 +#undef MAX_BAUD +#define MAX_BAUD B19200 + {B19200, 19200}, +#else +#ifdef EXTA +#define MAX_BAUD EXTA + {EXTA, 19200}, +#endif +#endif +#ifdef B38400 +#undef MAX_BAUD +#define MAX_BAUD B38400 + {B38400, 38400}, +#else +#ifdef EXTB +#define MAX_BAUD EXTB + {EXTB, 38400}, +#endif +#endif +#ifdef B57600 +#undef MAX_BAUD +#define MAX_BAUD B57600 + {B57600, 57600}, +#endif +#ifdef B115200 +#undef MAX_BAUD +#define MAX_BAUD B115200 + {B115200, 115200}, +#endif +}; + +int +baudrate(void) +{ +size_t i; +int ret; +#ifdef TRACE +char *debug_rate; +#endif + + T((T_CALLED("baudrate()"))); + + /* + * In debugging, allow the environment symbol to override when we're + * redirecting to a file, so we can construct repeatable test-cases + * that take into account costs that depend on baudrate. + */ +#ifdef TRACE + if (!isatty(fileno(SP->_ofp)) + && (debug_rate = getenv("BAUDRATE")) != 0) { + if (sscanf(debug_rate, "%d", &ret) != 1) + ret = 9600; + returnCode(ret); + } + else +#endif + +#ifdef TERMIOS + ret = cfgetospeed(&cur_term->Nttyb); +#else + ret = cur_term->Nttyb.sg_ospeed; +#endif + if(ret < 0 || ret > MAX_BAUD) + returnCode(ERR); + SP->_baudrate = ERR; + for (i = 0; i < (sizeof(speeds) / sizeof(struct speed)); i++) + if (speeds[i].s == (speed_t)ret) + { + SP->_baudrate = speeds[i].sp; + break; + } + returnCode(SP->_baudrate); +} diff --git a/lib/libcurses/lib_beep.c b/lib/libcurses/lib_beep.c index 0beee7c160c..4439162e44d 100644 --- a/lib/libcurses/lib_beep.c +++ b/lib/libcurses/lib_beep.c @@ -27,8 +27,10 @@ * */ -#include "curses.priv.h" -#include "term.h" /* beep, flash */ +#include <curses.priv.h> +#include <term.h> /* beep, flash */ + +MODULE_ID("Id: lib_beep.c,v 1.3 1997/02/02 00:27:01 tom Exp $") /* * beep() @@ -40,9 +42,9 @@ int beep(void) { - T(("beep() called")); + T((T_CALLED("beep()"))); - /* should make sure that we are not in altchar mode */ + /* FIXME: should make sure that we are not in altchar mode */ if (bell) { TPUTS_TRACE("bell"); return(putp(bell)); @@ -51,7 +53,7 @@ int beep(void) return(putp(flash_screen)); } else - return(ERR); + returnCode(ERR); } /* @@ -64,16 +66,16 @@ int beep(void) int flash(void) { - T(("flash() called")); + T((T_CALLED("flash()"))); - /* should make sure that we are not in altchar mode */ + /* FIXME: should make sure that we are not in altchar mode */ if (flash_screen) { TPUTS_TRACE("flash_screen"); - return(putp(flash_screen)); + returnCode(putp(flash_screen)); } else if (bell) { TPUTS_TRACE("bell"); - return(putp(bell)); + returnCode(putp(bell)); } else - return(ERR); + returnCode(ERR); } diff --git a/lib/libcurses/lib_bkgd.c b/lib/libcurses/lib_bkgd.c index aa6ff7a7ff1..3d4c0be6bd7 100644 --- a/lib/libcurses/lib_bkgd.c +++ b/lib/libcurses/lib_bkgd.c @@ -19,23 +19,34 @@ * * ***************************************************************************/ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_bkgd.c,v 1.7 1997/04/12 17:44:37 tom Exp $") int wbkgd(WINDOW *win, const chtype ch) { int x, y; +chtype old_bkgd = getbkgd(win); +chtype new_bkgd = ch; + + T((T_CALLED("wbkgd(%p,%s)"), win, _tracechtype(new_bkgd))); - T(("wbkgd(%p, %lx) called", win, ch)); - wbkgdset(win, ch); + if (TextOf(new_bkgd) == 0) + new_bkgd |= BLANK; + wbkgdset(win, new_bkgd); + wattrset(win, AttrOf(new_bkgd)); - for (y = 0; y <= win->_maxy; y++) - for (x = 0; x <= win->_maxx; x++) - if ((win->_line[y].text[x]&A_CHARTEXT) == ' ') - win->_line[y].text[x] |= ch; + for (y = 0; y <= win->_maxy; y++) { + for (x = 0; x <= win->_maxx; x++) { + if (win->_line[y].text[x] == old_bkgd) + win->_line[y].text[x] = new_bkgd; else - win->_line[y].text[x] |= (ch&A_ATTRIBUTES); + win->_line[y].text[x] = + TextOf(win->_line[y].text[x]) + | AttrOf(new_bkgd); + } + } touchwin(win); _nc_synchook(win); - return OK; + returnCode(OK); } - diff --git a/lib/libcurses/lib_box.c b/lib/libcurses/lib_box.c index bf45be33336..2eaf312238a 100644 --- a/lib/libcurses/lib_box.c +++ b/lib/libcurses/lib_box.c @@ -31,7 +31,9 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_box.c,v 1.7 1997/04/12 17:51:49 tom Exp $") int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br) @@ -39,7 +41,16 @@ int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, short i; short endx, endy; - T(("wborder() called")); + T((T_CALLED("wborder(%p,%s,%s,%s,%s,%s,%s,%s,%s)"), + win, + _tracechtype2(1,ls), + _tracechtype2(2,rs), + _tracechtype2(3,ts), + _tracechtype2(4,bs), + _tracechtype2(5,tl), + _tracechtype2(6,tr), + _tracechtype2(7,bl), + _tracechtype2(8,br))); if (ls == 0) ls = ACS_VLINE; if (rs == 0) rs = ACS_VLINE; @@ -50,23 +61,23 @@ short endx, endy; if (bl == 0) bl = ACS_LLCORNER; if (br == 0) br = ACS_LRCORNER; - ls |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - rs |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - ts |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - bs |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - tl |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - tr |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - bl |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); - br |= (win->_attrs ? win->_attrs : (win->_bkgd & A_ATTRIBUTES)); + ls = _nc_render(win, ls); + rs = _nc_render(win, rs); + ts = _nc_render(win, ts); + bs = _nc_render(win, bs); + tl = _nc_render(win, tl); + tr = _nc_render(win, tr); + bl = _nc_render(win, bl); + br = _nc_render(win, br); - T(("using %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx", ls, rs, ts, bs, tl, tr, bl, br)); + T(("using %#lx, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx", ls, rs, ts, bs, tl, tr, bl, br)); endx = win->_maxx; endy = win->_maxy; for (i = 0; i <= endx; i++) { - win->_line[0].text[i] = ts; - win->_line[endy].text[i] = bs; + win->_line[0].text[i] = ts; + win->_line[endy].text[i] = bs; } win->_line[endy].firstchar = win->_line[0].firstchar = 0; win->_line[endy].lastchar = win->_line[0].lastchar = endx; @@ -83,7 +94,7 @@ short endx, endy; win->_line[endy].text[endx] = br; _nc_synchook(win); - return OK; + returnCode(OK); } int whline(WINDOW *win, chtype ch, int n) @@ -92,27 +103,29 @@ short line; short start; short end; - T(("whline(%p,%lx,%d) called", win, ch, n)); + T((T_CALLED("whline(%p,%s,%d)"), win, _tracechtype(ch), n)); line = win->_cury; start = win->_curx; end = start + n - 1; - if (end > win->_maxx) + if (end > win->_maxx) end = win->_maxx; - if (win->_line[line].firstchar == _NOCHANGE || win->_line[line].firstchar > start) + if (win->_line[line].firstchar == _NOCHANGE || win->_line[line].firstchar > start) win->_line[line].firstchar = start; - if (win->_line[line].lastchar == _NOCHANGE || win->_line[line].lastchar < start) + if (win->_line[line].lastchar == _NOCHANGE || win->_line[line].lastchar < start) win->_line[line].lastchar = end; if (ch == 0) ch = ACS_HLINE; + ch = _nc_render(win, ch); + while ( end >= start) { - win->_line[line].text[end] = ch | win->_attrs; + win->_line[line].text[end] = ch; end--; } - return OK; + returnCode(OK); } int wvline(WINDOW *win, chtype ch, int n) @@ -120,27 +133,28 @@ int wvline(WINDOW *win, chtype ch, int n) short row, col; short end; - T(("wvline(%p,%lx,%d) called", win, ch, n)); + T((T_CALLED("wvline(%p,%s,%d)"), win, _tracechtype(ch), n)); row = win->_cury; col = win->_curx; end = row + n - 1; - if (end > win->_maxy) + if (end > win->_maxy) end = win->_maxy; if (ch == 0) ch = ACS_VLINE; + ch = _nc_render(win, ch); while(end >= row) { - win->_line[end].text[col] = ch | win->_attrs; - if (win->_line[end].firstchar == _NOCHANGE || win->_line[end].firstchar > col) + win->_line[end].text[col] = ch; + if (win->_line[end].firstchar == _NOCHANGE || win->_line[end].firstchar > col) win->_line[end].firstchar = col; - if (win->_line[end].lastchar == _NOCHANGE || win->_line[end].lastchar < col) + if (win->_line[end].lastchar == _NOCHANGE || win->_line[end].lastchar < col) win->_line[end].lastchar = col; end--; } _nc_synchook(win); - return OK; + returnCode(OK); } - + diff --git a/lib/libcurses/lib_clear.c b/lib/libcurses/lib_clear.c index 6f329139818..3318a9f68d7 100644 --- a/lib/libcurses/lib_clear.c +++ b/lib/libcurses/lib_clear.c @@ -26,15 +26,17 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_clear.c,v 1.3 1997/02/01 23:18:18 tom Exp $") int wclear(WINDOW *win) { - T(("wclear(%p) called", win)); + T((T_CALLED("wclear(%p)"), win)); werase(win); win->_clear = TRUE; - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_clrbot.c b/lib/libcurses/lib_clrbot.c index f7feca7ec5d..9580df1a904 100644 --- a/lib/libcurses/lib_clrbot.c +++ b/lib/libcurses/lib_clrbot.c @@ -26,18 +26,18 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_clrbot.c,v 1.9 1997/02/01 23:18:18 tom Exp $") int wclrtobot(WINDOW *win) { chtype *ptr, *end, *maxx = NULL; short y, startx, minx; - T(("wclrtobot(%p) called", win)); + T((T_CALLED("wclrtobot(%p)"), win)); startx = win->_curx; - if (win->_flags & _NEED_WRAP) - startx++; T(("clearing from y = %d to y = %d with maxx = %d", win->_cury, win->_maxy, win->_maxx)); @@ -46,7 +46,7 @@ short y, startx, minx; end = &win->_line[y].text[win->_maxx]; for (ptr = &win->_line[y].text[startx]; ptr <= end; ptr++) { - int blank = _nc_render(win, *ptr, BLANK); + chtype blank = _nc_background(win); if (*ptr != blank) { maxx = ptr; @@ -68,5 +68,5 @@ short y, startx, minx; startx = 0; } _nc_synchook(win); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_clreol.c b/lib/libcurses/lib_clreol.c index 146432ac575..6ffd0fcee53 100644 --- a/lib/libcurses/lib_clreol.c +++ b/lib/libcurses/lib_clreol.c @@ -27,28 +27,35 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_clreol.c,v 1.9 1997/02/01 23:22:54 tom Exp $") int wclrtoeol(WINDOW *win) { chtype *maxx, *ptr, *end; short y, x, minx; - T(("wclrtoeol(%p) called", win)); + T((T_CALLED("wclrtoeol(%p)"), win)); y = win->_cury; x = win->_curx; - if (win->_flags & _NEED_WRAP + + /* + * We don't want to clear if we just wrapped the cursor. There's no + * point in clearing if we're not on a legal position, either. + */ + if (win->_flags & _WRAPPED || y > win->_maxy || x > win->_maxx) - return ERR; + returnCode(ERR); end = &win->_line[y].text[win->_maxx]; minx = _NOCHANGE; maxx = &win->_line[y].text[x]; for (ptr = maxx; ptr <= end; ptr++) { - int blank = _nc_render(win, win->_line[y].text[x], BLANK); + chtype blank = _nc_background(win); if (*ptr != blank) { maxx = ptr; @@ -66,5 +73,5 @@ short y, x, minx; win->_line[y].lastchar = maxx - win->_line[y].text; } _nc_synchook(win); - return(OK); + returnCode(OK); } diff --git a/lib/libcurses/lib_color.c b/lib/libcurses/lib_color.c index b690cb71f33..68f8c6902ec 100644 --- a/lib/libcurses/lib_color.c +++ b/lib/libcurses/lib_color.c @@ -19,27 +19,25 @@ * * ***************************************************************************/ -/* lib_color.c - * +/* lib_color.c + * * Handles color emulation of SYS V curses * */ -#include "curses.priv.h" -#include <stdlib.h> -#include <string.h> -#include "term.h" +#include <curses.priv.h> + +#include <term.h> + +MODULE_ID("Id: lib_color.c,v 1.17 1997/05/03 19:16:05 tom Exp $") +/* + * These should be screen structure members. They need to be globals for + * hystorical reasons. So we assign them in start_color() and also in + * set_term()'s screen-switching logic. + */ int COLOR_PAIRS; int COLORS; -unsigned char *color_pairs; - -typedef struct -{ - short red, green, blue; -} -color_t; -static color_t *color_table; static const color_t cga_palette[] = { @@ -68,7 +66,7 @@ static const color_t hls_palette[] = int start_color(void) { - T(("start_color() called.")); + T((T_CALLED("start_color()"))); #ifdef orig_pair if (orig_pair != NULL) @@ -86,26 +84,27 @@ int start_color(void) #endif /* orig_colors */ #if defined(orig_pair) && defined(orig_colors) if (!orig_pair && !orig_colors) - return ERR; + returnCode(ERR); #endif /* defined(orig_pair) && defined(orig_colors) */ if (max_pairs != -1) - COLOR_PAIRS = max_pairs; + COLOR_PAIRS = SP->_pair_count = max_pairs; else - return ERR; - color_pairs = calloc((unsigned int)max_pairs, sizeof(char)); + returnCode(ERR); + SP->_color_pairs = typeCalloc(unsigned short, max_pairs); + SP->_color_pairs[0] = PAIR_OF(COLOR_WHITE, COLOR_BLACK); if (max_colors != -1) - COLORS = max_colors; + COLORS = SP->_color_count = max_colors; else - return ERR; + returnCode(ERR); SP->_coloron = 1; + SP->_color_table = malloc(sizeof(color_t) * COLORS); #ifdef hue_lightness_saturation - color_table = malloc(sizeof(color_t) * COLORS); if (hue_lightness_saturation) - memcpy(color_table, hls_palette, sizeof(color_t) * COLORS); + memcpy(SP->_color_table, hls_palette, sizeof(color_t) * COLORS); else #endif /* hue_lightness_saturation */ - memcpy(color_table, cga_palette, sizeof(color_t) * COLORS); + memcpy(SP->_color_table, cga_palette, sizeof(color_t) * COLORS); if (orig_colors) { @@ -115,7 +114,7 @@ int start_color(void) T(("started color: COLORS = %d, COLOR_PAIRS = %d", COLORS, COLOR_PAIRS)); - return OK; + returnCode(OK); } #ifdef hue_lightness_saturation @@ -155,28 +154,45 @@ static void rgb2hls(short r, short g, short b, short *h, short *l, short *s) } #endif /* hue_lightness_saturation */ +/* + * Extension (1997/1/18) - Allow negative f/b values to set default color + * values. + */ int init_pair(short pair, short f, short b) { - T(("init_pair( %d, %d, %d )", pair, f, b)); + T((T_CALLED("init_pair(%d,%d,%d)"), pair, f, b)); if ((pair < 1) || (pair >= COLOR_PAIRS)) - return ERR; - if ((f < 0) || (f >= COLORS) || (b < 0) || (b >= COLORS)) - return ERR; + returnCode(ERR); + if (SP->_default_color) + { + if (f < 0) + f = C_MASK; + if (b < 0) + b = C_MASK; + if (f >= COLORS && f != C_MASK) + returnCode(ERR); + if (b >= COLORS && b != C_MASK) + returnCode(ERR); + } + else + if ((f < 0) || (f >= COLORS) + || (b < 0) || (b >= COLORS)) + returnCode(ERR); - /* + /* * FIXME: when a pair's content is changed, replace its colors * (if pair was initialized before a screen update is performed * replacing original pair colors with the new ones) */ - color_pairs[pair] = ( (f & 0x0f) | (b & 0x0f) << 4 ); + SP->_color_pairs[pair] = PAIR_OF(f,b); if (initialize_pair) { const color_t *tp = hue_lightness_saturation ? hls_palette : cga_palette; - T(("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)\n", + T(("initializing pair: pair = %d, fg=(%d,%d,%d), bg=(%d,%d,%d)", pair, tp[f].red, tp[f].green, tp[f].blue, tp[b].red, tp[b].green, tp[b].blue)); @@ -188,42 +204,43 @@ int init_pair(short pair, short f, short b) pair, tp[f].red, tp[f].green, tp[f].blue, tp[b].red, tp[b].green, tp[b].blue)); - } + } } - return OK; + returnCode(OK); } int init_color(short color, short r, short g, short b) { + T((T_CALLED("init_color(%d,%d,%d,%d)"), color, r, g, b)); #ifdef initialize_color if (initialize_color == NULL) - return ERR; + returnCode(ERR); #endif /* initialize_color */ if (color < 0 || color >= COLORS) - return ERR; + returnCode(ERR); #ifdef hue_lightness_saturation if (hue_lightness_saturation == TRUE) if (r < 0 || r > 360 || g < 0 || g > 100 || b < 0 || b > 100) - return ERR; + returnCode(ERR); if (hue_lightness_saturation == FALSE) #endif /* hue_lightness_saturation */ if (r < 0 || r > 1000 || g < 0 || g > 1000 || b < 0 || b > 1000) - return ERR; - + returnCode(ERR); + #ifdef hue_lightness_saturation if (hue_lightness_saturation) rgb2hls(r, g, b, - &color_table[color].red, - &color_table[color].green, - &color_table[color].blue); + &SP->_color_table[color].red, + &SP->_color_table[color].green, + &SP->_color_table[color].blue); else #endif /* hue_lightness_saturation */ { - color_table[color].red = r; - color_table[color].green = g; - color_table[color].blue = b; + SP->_color_table[color].red = r; + SP->_color_table[color].green = g; + SP->_color_table[color].blue = b; } #ifdef initialize_color @@ -233,19 +250,21 @@ int init_color(short color, short r, short g, short b) putp(tparm(initialize_color, color, r, g, b)); } #endif /* initialize_color */ - return OK; + returnCode(OK); } bool can_change_color(void) { - return (can_change != 0); + T((T_CALLED("can_change_color()"))); + returnCode(can_change != 0); } -int has_colors(void) +bool has_colors(void) { - return ((orig_pair != NULL || orig_colors != NULL) + T((T_CALLED("has_colors()"))); + returnCode((orig_pair != NULL || orig_colors != NULL) && (max_colors != -1) && (max_pairs != -1) - && + && (((set_foreground != NULL) && (set_background != NULL)) || ((set_a_foreground != NULL) && (set_a_background != NULL)) || set_color_pair) @@ -254,32 +273,49 @@ int has_colors(void) int color_content(short color, short *r, short *g, short *b) { + T((T_CALLED("color_content(%d,%p,%p,%p)"), color, r, g, b)); if (color < 0 || color > COLORS) - return ERR; + returnCode(ERR); - *r = color_table[color].red; - *g = color_table[color].green; - *b = color_table[color].blue; - return OK; + *r = SP->_color_table[color].red; + *g = SP->_color_table[color].green; + *b = SP->_color_table[color].blue; + returnCode(OK); } int pair_content(short pair, short *f, short *b) { + T((T_CALLED("pair_content(%d,%p,%p)"), pair, f, b)); - if ((pair < 1) || (pair > COLOR_PAIRS)) - return ERR; - *f = color_pairs[pair] & 0x0f; - *b = color_pairs[pair] & 0xf0; - *b >>= 4; - return OK; + if ((pair < 0) || (pair > COLOR_PAIRS)) + returnCode(ERR); + *f = ((SP->_color_pairs[pair] >> C_SHIFT) & C_MASK); + *b = (SP->_color_pairs[pair] & C_MASK); + + returnCode(OK); } +/* + * SVr4 curses is known to interchange color codes (1,4) and (3,6), possibly + * to maintain compatibility with a pre-ANSI scheme. The same scheme is + * also used in the FreeBSD syscons. + */ +static int toggled_colors(int c) +{ + if (c < 16) { + static const int table[] = + { 0, 4, 2, 6, 1, 5, 3, 7, + 8, 12, 10, 14, 9, 13, 11, 15}; + c = table[c]; + } + return c; +} void _nc_do_color(int pair, int (*outc)(int)) { short fg, bg; - if (pair == 0) + if (pair == 0) { if (orig_pair) { @@ -298,27 +334,46 @@ void _nc_do_color(int pair, int (*outc)(int)) { pair_content(pair, &fg, &bg); - T(("setting colors: pair = %d, fg = %d, bg = %d\n", pair, fg, bg)); + T(("setting colors: pair = %d, fg = %d, bg = %d", pair, fg, bg)); - if (set_a_foreground) - { - TPUTS_TRACE("set_a_foreground"); - tputs(tparm(set_a_foreground, fg), 1, outc); - } - else + if (fg == C_MASK || bg == C_MASK) { - TPUTS_TRACE("set_foreground"); - tputs(tparm(set_foreground, fg), 1, outc); + if (orig_pair) + { + TPUTS_TRACE("orig_pair"); + tputs(orig_pair, 1, outc); + } + else + { + TPUTS_TRACE("orig_colors"); + tputs(orig_colors, 1, outc); + } } - if (set_a_background) + if (fg != C_MASK) { - TPUTS_TRACE("set_a_background"); - tputs(tparm(set_a_background, bg), 1, outc); + if (set_a_foreground) + { + TPUTS_TRACE("set_a_foreground"); + tputs(tparm(set_a_foreground, fg), 1, outc); + } + else + { + TPUTS_TRACE("set_foreground"); + tputs(tparm(set_foreground, toggled_colors(fg)), 1, outc); + } } - else + if (bg != C_MASK) { - TPUTS_TRACE("set_background"); - tputs(tparm(set_background, bg), 1, outc); + if (set_a_background) + { + TPUTS_TRACE("set_a_background"); + tputs(tparm(set_a_background, bg), 1, outc); + } + else + { + TPUTS_TRACE("set_background"); + tputs(tparm(set_background, toggled_colors(bg)), 1, outc); + } } } } diff --git a/lib/libcurses/lib_data.c b/lib/libcurses/lib_data.c index b3c962e3c16..c7d6c559590 100644 --- a/lib/libcurses/lib_data.c +++ b/lib/libcurses/lib_data.c @@ -26,13 +26,28 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> -#include <stdlib.h> +MODULE_ID("Id: lib_data.c,v 1.8 1997/01/18 23:02:54 tom Exp $") WINDOW *stdscr, *curscr, *newscr; /* + * Linked-list of all windows, to support '_nc_resizeall()' and '_nc_freeall()' + */ +WINDOWLIST *_nc_windows; + +/* + * These data correspond to the state of the idcok() and idlok() functions. A + * caveat is in order here: the XSI and SVr4 documentation specify that these + * functions apply to the window which is given as an argument. However, + * ncurses implements this logic only for the newscr/curscr update process, + * _not_ per-window. + */ +bool _nc_idcok = TRUE; +bool _nc_idlok = FALSE; + +/* * The variable 'SP' will be defined as a function on systems that cannot link * data-only modules, since it is used in a lot of places within ncurses and we * cannot guarantee that any application will use any particular function. We @@ -52,7 +67,7 @@ SCREEN *_nc_screen(void) int _nc_alloc_screen(void) { - return ((my_screen = (SCREEN *) calloc(sizeof(*SP), 1)) != NULL); + return ((my_screen = typeCalloc(SCREEN, 1)) != 0); } void _nc_set_screen(SCREEN *sp) diff --git a/lib/libcurses/lib_delch.c b/lib/libcurses/lib_delch.c index 6f8f37185dd..4813c4b2fd2 100644 --- a/lib/libcurses/lib_delch.c +++ b/lib/libcurses/lib_delch.c @@ -26,15 +26,17 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_delch.c,v 1.5 1997/02/01 23:18:18 tom Exp $") int wdelch(WINDOW *win) { chtype *temp1, *temp2; chtype *end; -chtype blank = _nc_render(win, ' ', BLANK | win->_attrs); +chtype blank = _nc_background(win); - T(("wdelch(%p) called", win)); + T((T_CALLED("wdelch(%p)"), win)); end = &win->_line[win->_cury].text[win->_maxx]; temp2 = &win->_line[win->_cury].text[win->_curx + 1]; @@ -52,5 +54,5 @@ chtype blank = _nc_render(win, ' ', BLANK | win->_attrs); win->_line[win->_cury].firstchar = win->_curx; _nc_synchook(win); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_delwin.c b/lib/libcurses/lib_delwin.c index b3453cad74a..542abcaf437 100644 --- a/lib/libcurses/lib_delwin.c +++ b/lib/libcurses/lib_delwin.c @@ -26,28 +26,35 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> +#include <curses.priv.h> -int delwin(WINDOW *win) -{ -int i; - - T(("delwin(%p) called", win)); +MODULE_ID("Id: lib_delwin.c,v 1.8 1997/02/01 23:22:54 tom Exp $") - if (win == NULL) - return(ERR); - - if (! (win->_flags & _SUBWIN)) { - for (i = 0; i <= win->_maxy && win->_line[i].text; i++) - free(win->_line[i].text); +static bool have_children(WINDOW *win) +{ + WINDOWLIST *p; + for (p = _nc_windows; p != 0; p = p->next) { + if (p->win->_flags & _SUBWIN + && p->win->_parent == win) + return TRUE; } + return FALSE; +} + +int delwin(WINDOW *win) +{ + T((T_CALLED("delwin(%p)"), win)); - free(win->_line); + if (win == 0 + || have_children(win)) + returnCode(ERR); - touchwin((win->_flags & _SUBWIN) ? win->_parent : curscr); + if (win->_flags & _SUBWIN) + touchwin(win->_parent); + else if (curscr != 0) + touchwin(curscr); - free(win); + _nc_freewin(win); - return(OK); + returnCode(OK); } diff --git a/lib/libcurses/lib_dft_fgbg.c b/lib/libcurses/lib_dft_fgbg.c new file mode 100644 index 00000000000..1494f39a307 --- /dev/null +++ b/lib/libcurses/lib_dft_fgbg.c @@ -0,0 +1,48 @@ +/****************************************************************************** + * Copyright 1997 by Thomas E. Dickey <dickey@clark.net> * + * All Rights Reserved. * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose and without fee is hereby granted, provided * + * that the above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the above listed copyright holder(s) * + * not be used in advertising or publicity pertaining to distribution of the * + * software without specific, written prior permission. THE ABOVE LISTED * + * COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * + * EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ******************************************************************************/ +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: lib_dft_fgbg.c,v 1.2 1997/02/02 01:45:36 tom Exp $") + +/* + * Modify the behavior of color-pair 0 so that the library doesn't assume that + * it is black on white. This is an extension to XSI curses. + * + * Invoke this function after 'start_color()'. + */ +int +use_default_colors(void) +{ + T((T_CALLED("use_default_colors()"))); + + if (!SP->_coloron) + returnCode(ERR); + + if (!orig_pair && !orig_colors) + returnCode(ERR); + + if (initialize_pair) /* don't know how to handle this */ + returnCode(ERR); + + SP->_default_color = TRUE; + SP->_color_pairs[0] = PAIR_OF(C_MASK, C_MASK); + returnCode(OK); +} diff --git a/lib/libcurses/lib_doupdate.c b/lib/libcurses/lib_doupdate.c index 3d6f2d79e38..0c20ebd72c3 100644 --- a/lib/libcurses/lib_doupdate.c +++ b/lib/libcurses/lib_doupdate.c @@ -1,4 +1,3 @@ - /*************************************************************************** * COPYRIGHT NOTICE * **************************************************************************** @@ -25,22 +24,39 @@ * lib_doupdate.c * * The routine doupdate() and its dependents. Also _nc_outstr(), - * so all physcal output is concentrated here. + * so all physical output is concentrated here (except _nc_outch() + * in lib_tputs.c). * *-----------------------------------------------------------------*/ -#include "curses.priv.h" -#include <stdlib.h> -#include <sys/types.h> +#include <curses.priv.h> + +#if defined(TRACE) && HAVE_SYS_TIMES_H && HAVE_TIMES +#define USE_TRACE_TIMES 1 +#else +#define USE_TRACE_TIMES 0 +#endif + #if HAVE_SYS_TIME_H && ! SYSTEM_LOOKS_LIKE_SCO #include <sys/time.h> #endif + +#if USE_TRACE_TIMES +#include <sys/times.h> +#endif + +#if USE_FUNC_POLL +#include <stropts.h> +#include <poll.h> +#elif HAVE_SELECT #if HAVE_SYS_SELECT_H -#include <sys/types.h> #include <sys/select.h> #endif -#include <string.h> -#include "term.h" +#endif + +#include <term.h> + +MODULE_ID("Id: lib_doupdate.c,v 1.60 1997/05/03 19:32:55 Alexander.V.Lukyanov Exp $") /* * This define controls the line-breakout optimization. Every once in a @@ -60,18 +76,14 @@ */ /* #define POSITION_DEBUG */ -static void ClrUpdate( WINDOW *scr ); -static void TransformLine( int const lineno ); -static void NoIDcTransformLine( int const lineno ); -static void IDcTransformLine( int const lineno ); -static void ClearScreen( void ); +static inline chtype ClrBlank ( WINDOW *win ); +static inline chtype ClrSetup ( WINDOW *scr ); +static int ClrBottom(int total); static int InsStr( chtype *line, int count ); +static void ClearScreen( void ); +static void ClrUpdate( WINDOW *scr ); static void DelChar( int count ); - -#define UpdateAttrs(c) if (curscr->_attrs != AttrOf(c)) { \ - curscr->_attrs = AttrOf(c); \ - vidputs(curscr->_attrs, _nc_outch); \ - } +static void TransformLine( int const lineno ); #ifdef POSITION_DEBUG /**************************************************************************** @@ -111,7 +123,7 @@ void position_check(int expected_y, int expected_x, char *legend) * ****************************************************************************/ -static __inline void GoTo(int const row, int const col) +static inline void GoTo(int const row, int const col) { chtype oldattr = SP->_current_attr; @@ -130,10 +142,9 @@ static __inline void GoTo(int const row, int const col) if ((oldattr & A_ALTCHARSET) || (oldattr && !move_standout_mode)) { - TR(TRACE_CHARPUT, ("turning off (%lx) %s before move", + TR(TRACE_CHARPUT, ("turning off (%#lx) %s before move", oldattr, _traceattr(oldattr))); vidattr(A_NORMAL); - curscr->_attrs = A_NORMAL; } mvcur(SP->_cursrow, SP->_curscol, row, col); @@ -141,17 +152,19 @@ static __inline void GoTo(int const row, int const col) SP->_curscol = col; } -static __inline void PutAttrChar(chtype ch) +static inline void PutAttrChar(chtype ch) { if (tilde_glitch && (TextOf(ch) == '~')) ch = ('`' | AttrOf(ch)); - TR(TRACE_CHARPUT, ("PutAttrChar(%s, %s) at (%d, %d)", - _tracechar((unsigned char)TextOf(ch)), - _traceattr(AttrOf(ch)), + TR(TRACE_CHARPUT, ("PutAttrChar(%s) at (%d, %d)", + _tracechtype(ch), SP->_cursrow, SP->_curscol)); UpdateAttrs(ch); putc((int)TextOf(ch), SP->_ofp); +#ifdef TRACE + _nc_outchars++; +#endif /* TRACE */ SP->_curscol++; if (char_padding) { TPUTS_TRACE("char_padding"); @@ -163,19 +176,30 @@ static bool check_pending(void) /* check for pending input */ { if (SP->_checkfd >= 0) { - fd_set fdset; - struct timeval ktimeout; +#if USE_FUNC_POLL + struct pollfd fds[1]; + fds[0].fd = SP->_checkfd; + fds[0].events = POLLIN; + if (poll(fds, 1, 0) > 0) + { + fflush(SP->_ofp); + return TRUE; + } +#elif HAVE_SELECT + fd_set fdset; + struct timeval ktimeout; ktimeout.tv_sec = ktimeout.tv_usec = 0; FD_ZERO(&fdset); FD_SET(SP->_checkfd, &fdset); - if (select(SP->_checkfd+1, &fdset, NULL, NULL, &ktimeout) != 0) + if (select(SP->_checkfd+1, &fdset, NULL, NULL, &ktimeout) > 0) { fflush(SP->_ofp); return TRUE; } +#endif } return FALSE; } @@ -190,7 +214,7 @@ static void callPutChar(chtype const); #define callPutChar(ch) PutChar(ch) #endif -static __inline void PutChar(chtype const ch) +static inline void PutChar(chtype const ch) /* insert character, handling automargin stuff */ { if (!(SP->_cursrow == screen_lines-1 && SP->_curscol == screen_columns-1 @@ -198,7 +222,7 @@ static __inline void PutChar(chtype const ch) { PutAttrChar(ch); /* normal case */ } - else if (!auto_right_margin /* maybe we can suppress automargin */ + else if (!auto_right_margin /* maybe we can suppress automargin */ || (enter_am_mode && exit_am_mode)) { bool old_am = auto_right_margin; @@ -262,6 +286,140 @@ static __inline void PutChar(chtype const ch) #endif /* POSITION_DEBUG */ } +/* + * Issue a given span of characters from an array. + * Must be functionally equivalent to: + * for (i = 0; i < num; i++) + * PutChar(ntext[i]); + * but can leave the cursor positioned at the middle of the interval. + * + * Returns: 0 - cursor is at the end of interval + * 1 - cursor is somewhere in the middle + * + * This code is optimized using ech and rep. + */ +static inline int EmitRange(const chtype *ntext, int num) +{ + int i; + + if (erase_chars || repeat_char) + { + while (num > 0) + { + int runcount; + chtype ntext0; + + while (num>1 && ntext[0]!=ntext[1]) + { + PutChar(ntext[0]); + ntext++; + num--; + } + ntext0 = ntext[0]; + if (num==1) + { + PutChar(ntext0); + return 0; + } + runcount = 2; + + while (runcount < num && ntext[runcount] == ntext0) + runcount++; + + /* + * The cost expression in the middle isn't exactly right. + * _cup_cost is an upper bound on the cost for moving to the + * end of the erased area, but not the cost itself (which we + * can't compute without emitting the move). This may result + * in erase_chars not getting used in some situations for + * which it would be marginally advantageous. + */ + if (erase_chars + && runcount > SP->_ech_cost + SP->_cup_cost + && can_clear_with(ntext0)) + { + UpdateAttrs(ntext0); + putp(tparm(erase_chars, runcount)); + + /* + * If this is the last part of the given interval, + * don't bother moving cursor, since it can be the + * last update on the line. + */ + if (runcount < num) + GoTo(SP->_cursrow, SP->_curscol + runcount); + else + return 1; /* cursor stays in the middle */ + } + else if (repeat_char && runcount > SP->_rep_cost) + { + bool wrap_possible = (SP->_curscol + runcount >= screen_columns); + int rep_count = runcount; + + if (wrap_possible) + rep_count--; + + UpdateAttrs(ntext0); + putp(tparm(repeat_char, TextOf(ntext0), rep_count)); + SP->_curscol += rep_count; + + if (wrap_possible) + PutChar(ntext0); + } + else + { + for (i = 0; i < runcount; i++) + PutChar(ntext[i]); + } + ntext += runcount; + num -= runcount; + } + return 0; + } + + for (i = 0; i < num; i++) + PutChar(ntext[i]); + return 0; +} + +/* + * Output the line in the given range [first .. last] + * + * If there's a run of identical characters that's long enough to justify + * cursor movement, use that also. + * + * Returns: same as EmitRange + */ +static int PutRange( + const chtype *otext, + const chtype *ntext, + int row, + int first, int last) +{ + int j, run; + int cost = min(SP->_cup_ch_cost, SP->_hpa_ch_cost); + + TR(TRACE_CHARPUT, ("PutRange(%p, %p, %d, %d, %d)", + otext, ntext, row, first, last)); + + if (otext != ntext + && (last-first+1) > cost) { + for (j = first, run = 0; j <= last; j++) { + if (otext[j] == ntext[j]) { + run++; + } else { + if (run > cost) { + int before_run = (j - run); + EmitRange(ntext+first, before_run-first); + GoTo(row, first = j); + } + run = 0; + } + } + } + return EmitRange(ntext + first, last-first+1); +} + #if CC_HAS_INLINE_FUNCS static void callPutChar(chtype const ch) { @@ -269,11 +427,22 @@ static void callPutChar(chtype const ch) } #endif +#define MARK_NOCHANGE(win,row) \ + { \ + win->_line[row].firstchar = _NOCHANGE; \ + win->_line[row].lastchar = _NOCHANGE; \ + win->_line[row].oldindex = row; \ + } + int doupdate(void) { int i; +int nonempty; +#if USE_TRACE_TIMES +struct tms before, after; +#endif /* USE_TRACE_TIMES */ - T(("doupdate() called")); + T((T_CALLED("doupdate()"))); #ifdef TRACE if (_nc_tracing & TRACE_UPDATE) @@ -289,109 +458,230 @@ int i; _nc_signal_handler(FALSE); if (SP->_endwin == TRUE) { + T(("coming back from shell mode")); reset_prog_mode(); - if (enter_ca_mode) - { - TPUTS_TRACE("enter_ca_mode"); - putp(enter_ca_mode); - } + +#ifndef EXTERN_TERMINFO /* - * Undo the effects of terminal init strings that assume - * they know the screen size. Useful when you're running - * a vt100 emulation through xterm. Note: this may change - * the physical cursor location. + * This is a transparent extension: XSI does not address it, + * and applications need not know that ncurses can do it. + * + * Check if the terminal size has changed while curses was off + * (this can happen in an xterm, for example), and resize the + * ncurses data structures accordingly. */ - if (change_scroll_region) - { - TPUTS_TRACE("change_scroll_region"); - putp(tparm(change_scroll_region, 0, screen_lines - 1)); - } + _nc_get_screensize(); + resizeterm(LINES, COLS); +#endif + _nc_mvcur_resume(); _nc_mouse_resume(SP); newscr->_clear = TRUE; SP->_endwin = FALSE; } - /* - * FIXME: Full support for magic-cookie terminals could go in here. - * The theory: we scan the virtual screen looking for attribute - * changes. Where we find one, check to make sure it's realizable - * by seeing if the required number of un-attributed blanks are - * present before or after the change. If not, nuke the attributes - * out of the following or preceding cells on the virtual screen, - * forward to the next change or backwards to the previous one. If - * so, displace the change by the required number of characters. +#if USE_TRACE_TIMES + /* zero the metering machinery */ + _nc_outchars = 0; + (void) times(&before); +#endif /* USE_TRACE_TIMES */ + + /* + * This is the support for magic-cookie terminals. The + * theory: we scan the virtual screen looking for attribute + * turnons. Where we find one, check to make sure it's + * realizable by seeing if the required number of + * un-attributed blanks are present before and after the + * attributed range; try to shift the range boundaries over + * blanks (not changing the screen display) so this becomes + * true. If it is, shift the beginning attribute change + * appropriately (the end one, if we've gotten this far, is + * guaranteed room for its cookie). If not, nuke the added + * attributes out of the span. */ + if (magic_cookie_glitch > 0) { + int j, k; + attr_t rattr = A_NORMAL; + + for (i = 0; i < screen_lines; i++) + for (j = 0; j < screen_columns; j++) + { + bool failed = FALSE; + chtype turnon = AttrOf(newscr->_line[i].text[j]) & ~rattr; + + /* is an attribute turned on here? */ + if (turnon == 0) + continue; + + T(("At (%d, %d): from %s...", i, j, _traceattr(rattr))); + T(("...to %s",_traceattr(turnon))); + + /* + * If the attribute change location is a blank with a + * "safe" attribute, undo the attribute turnon. This may + * ensure there's enough room to set the attribute before + * the first non-blank in the run. + */ +#define SAFE(a) !((a) & ~NONBLANK_ATTR) + if (TextOf(newscr->_line[i].text[j])==' ' && SAFE(turnon)) + { + newscr->_line[i].text[j] &= ~turnon; + continue; + } + + /* check that there's enough room at start of span */ + for (k = 1; k <= magic_cookie_glitch; k++) + if (j-k < 0 + || TextOf(newscr->_line[i].text[j-k]) != ' ' + || !SAFE(AttrOf(newscr->_line[i].text[j-k]))) + failed = TRUE; + if (!failed) + { + bool end_onscreen = FALSE; + int m, n = -1; + + /* find end of span, if it's onscreen */ + for (m = i; m < screen_lines; m++) + for (n = j; n < screen_columns; n++) + if (AttrOf(newscr->_line[m].text[n]) == rattr) + { + end_onscreen = TRUE; + T(("Range attributed with %s ends at (%d, %d)", + _traceattr(turnon),m,n)); + goto foundit; + } + T(("Range attributed with %s ends offscreen", + _traceattr(turnon))); + foundit:; + if (end_onscreen) + { + chtype *lastline = newscr->_line[m].text; + + /* + * If there are safely-attributed blanks at the + * end of the range, shorten the range. This will + * help ensure that there is enough room at end + * of span. + */ + while (n >= 0 + && TextOf(lastline[n]) == ' ' + && SAFE(AttrOf(lastline[n]))) + lastline[n--] &=~ turnon; + + /* check that there's enough room at end of span */ + for (k = 1; k <= magic_cookie_glitch; k++) + if (n + k >= screen_columns + || TextOf(lastline[n + k]) != ' ' + || !SAFE(AttrOf(lastline[n+k]))) + failed = TRUE; + } + } + + if (failed) + { + int p, q; + + T(("Clearing %s beginning at (%d, %d)", + _traceattr(turnon), i, j)); + + /* turn off new attributes over span */ + for (p = i; p < screen_lines; p++) + for (q = j; q < screen_columns; q++) + if (AttrOf(newscr->_line[p].text[q]) == rattr) + goto foundend; + else + newscr->_line[p].text[q] &=~ turnon; + foundend:; + } + else + { + T(("Cookie space for %s found before (%d, %d)", + _traceattr(turnon), i, j)); + + /* + * back up the start of range so there's room + * for cookies before the first nonblank character + */ + for (k = 1; k <= magic_cookie_glitch; k++) + newscr->_line[i].text[j-k] |= turnon; + } + + rattr = AttrOf(newscr->_line[i].text[j]); + } + +#ifdef TRACE + /* show altered highlights after magic-cookie check */ + if (_nc_tracing & TRACE_UPDATE) + { + _tracef("After magic-cookie check..."); + _tracedump("newscr", newscr); + } +#endif /* TRACE */ + } + + nonempty = 0; if (curscr->_clear) { /* force refresh ? */ T(("clearing and updating curscr")); - ClrUpdate(curscr); /* yes, clear all & update */ + ClrUpdate(newscr); /* yes, clear all & update */ curscr->_clear = FALSE; /* reset flag */ + } else if (newscr->_clear) { + T(("clearing and updating newscr")); + ClrUpdate(newscr); + newscr->_clear = FALSE; } else { - if (newscr->_clear) { - T(("clearing and updating newscr")); - ClrUpdate(newscr); - newscr->_clear = FALSE; - } else { - int changedlines; - - _nc_scroll_optimize(); - - T(("Transforming lines")); - for (i = changedlines = 0; - i < min(screen_lines,newscr->_maxy+1); - i++) + int changedlines; + + nonempty = min(screen_lines, newscr->_maxy+1); +#if 0 /* still 5% slower 960928 */ +#if defined(TRACE) || defined(NCURSES_TEST) + if (_nc_optimize_enable & OPTIMIZE_HASHMAP) +#endif /*TRACE */ + _nc_hash_map(); +#endif +#if defined(TRACE) || defined(NCURSES_TEST) + if (_nc_optimize_enable & OPTIMIZE_SCROLL) +#endif /*TRACE */ + _nc_scroll_optimize(); + + if (clr_eos) + nonempty = ClrBottom(nonempty); + + T(("Transforming lines, nonempty %d", nonempty)); + for (i = changedlines = 0; i < nonempty; i++) { + /* + * newscr->line[i].firstchar is normally set + * by wnoutrefresh. curscr->line[i].firstchar + * is normally set by _nc_scroll_window in the + * vertical-movement optimization code, + */ + if (newscr->_line[i].firstchar != _NOCHANGE + || curscr->_line[i].firstchar != _NOCHANGE) { - /* - * newscr->line[i].firstchar is normally set - * by wnoutrefresh. curscr->line[i].firstchar - * is normally set by _nc_scroll_window in the - * vertical-movement optimization code, - */ - if (newscr->_line[i].firstchar != _NOCHANGE - || curscr->_line[i].firstchar != _NOCHANGE) - { - TransformLine(i); - changedlines++; - } - - /* mark line changed successfully */ - if (i <= newscr->_maxy) - { - newscr->_line[i].firstchar = _NOCHANGE; - newscr->_line[i].lastchar = _NOCHANGE; - newscr->_line[i].oldindex = i; - } - if (i <= curscr->_maxy) - { - curscr->_line[i].firstchar = _NOCHANGE; - curscr->_line[i].lastchar = _NOCHANGE; - curscr->_line[i].oldindex = i; - } - - /* - * Here is our line-breakout optimization. - */ - if ((changedlines % CHECK_INTERVAL) == changedlines-1 - && check_pending()) - goto cleanup; + TransformLine(i); + changedlines++; } + + /* mark line changed successfully */ + if (i <= newscr->_maxy) + MARK_NOCHANGE(newscr,i) + if (i <= curscr->_maxy) + MARK_NOCHANGE(curscr,i) + + /* + * Here is our line-breakout optimization. + */ + if ((changedlines % CHECK_INTERVAL) == CHECK_INTERVAL-1 + && check_pending()) + goto cleanup; } } - /* this code won't be executed often */ - for (i = screen_lines; i <= newscr->_maxy; i++) - { - newscr->_line[i].firstchar = _NOCHANGE; - newscr->_line[i].lastchar = _NOCHANGE; - newscr->_line[i].oldindex = i; - } - for (i = screen_lines; i <= curscr->_maxy; i++) - { - curscr->_line[i].firstchar = _NOCHANGE; - curscr->_line[i].lastchar = _NOCHANGE; - curscr->_line[i].oldindex = i; - } + /* put everything back in sync */ + for (i = nonempty; i <= newscr->_maxy; i++) + MARK_NOCHANGE(newscr,i) + for (i = nonempty; i <= curscr->_maxy; i++) + MARK_NOCHANGE(curscr,i) curscr->_curx = newscr->_curx; curscr->_cury = newscr->_cury; @@ -399,14 +689,64 @@ int i; GoTo(curscr->_cury, curscr->_curx); cleanup: - if (curscr->_attrs != A_NORMAL) - vidattr(curscr->_attrs = A_NORMAL); + /* + * Keep the physical screen in normal mode in case we get other + * processes writing to the screen. + */ + UpdateAttrs(A_NORMAL); fflush(SP->_ofp); + curscr->_attrs = newscr->_attrs; +/* curscr->_bkgd = newscr->_bkgd; */ + +#if USE_TRACE_TIMES + (void) times(&after); + TR(TRACE_TIMES, ("Update cost: %ld chars, %ld clocks system time, %ld clocks user time", + _nc_outchars, + after.tms_stime-before.tms_stime, + after.tms_utime-before.tms_utime)); +#endif /* USE_TRACE_TIMES */ _nc_signal_handler(TRUE); - return OK; + returnCode(OK); +} + +/* + * ClrBlank(win) + * + * Returns the attributed character that corresponds to the "cleared" + * screen. If the terminal has the back-color-erase feature, this will be + * colored according to the wbkgd() call. (Other attributes are + * unspecified, hence assumed to be reset in accordance with + * 'ClrSetup()'). + * + * We treat 'curscr' specially because it isn't supposed to be set directly + * in the wbkgd() call. Assume 'stdscr' for this case. + */ +#define BCE_ATTRS (A_NORMAL|A_COLOR) +#define BCE_BKGD(win) (((win) == curscr ? stdscr : (win))->_bkgd) + +static inline chtype ClrBlank (WINDOW *win) +{ +chtype blank = BLANK; + if (back_color_erase) + blank |= (BCE_BKGD(win) & BCE_ATTRS); + return blank; +} + +/* + * ClrSetup(win) + * + * Ensures that if the terminal recognizes back-color-erase, that we + * set the video attributes to match the window's background color + * before an erase operation. + */ +static inline chtype ClrSetup (WINDOW *win) +{ + if (back_color_erase) + vidattr(BCE_BKGD(win) & BCE_ATTRS); + return ClrBlank(win); } /* @@ -420,172 +760,141 @@ static void ClrUpdate(WINDOW *scr) { int i = 0, j = 0; int lastNonBlank; +chtype blank = ClrSetup(scr); T(("ClrUpdate(%p) called", scr)); - if (back_color_erase) { - T(("back_color_erase, turning attributes off")); - vidattr(A_NORMAL); - } ClearScreen(); if (scr != curscr) { for (i = 0; i < screen_lines ; i++) for (j = 0; j < screen_columns; j++) - curscr->_line[i].text[j] = ' '; /* shouldn't this include the bkgd? */ + curscr->_line[i].text[j] = blank; } T(("updating screen from scratch")); for (i = 0; i < min(screen_lines, scr->_maxy + 1); i++) { - GoTo(i, 0); lastNonBlank = scr->_maxx; - while (scr->_line[i].text[lastNonBlank] == BLANK && lastNonBlank > 0) + while (lastNonBlank >= 0 + && scr->_line[i].text[lastNonBlank] == blank) lastNonBlank--; - for (j = 0; j <= min(lastNonBlank, screen_columns); j++) { - PutChar(scr->_line[i].text[j]); + if (lastNonBlank >= 0) { + if (lastNonBlank > screen_columns) + lastNonBlank = screen_columns; + GoTo(i, 0); + PutRange(curscr->_line[i].text, + scr->_line[i].text, i, 0, lastNonBlank); } } - if (scr != curscr) { for (i = 0; i < screen_lines ; i++) - for (j = 0; j < screen_columns; j++) - curscr->_line[i].text[j] = scr->_line[i].text[j]; + memcpy(curscr->_line[i].text, + scr->_line[i].text, + screen_columns * sizeof(chtype)); } } /* -** ClrToEOL() +** ClrToEOL(blank) ** -** Clear to EOL. Deal with background color erase if terminal has this -** glitch. This code forces the current color and highlight to A_NORMAL -** before emitting the erase sequence, then restores the current -** attribute. +** Clear to end of current line, starting at the cursor position */ -static void ClrToEOL(void) +static void ClrToEOL(chtype blank) { int j; -attr_t oldcolor = 0; /* initialization pacifies -Wall */ - - if (back_color_erase) { - TPUTS_TRACE("orig_pair"); - putp(orig_pair); - oldcolor = SP->_current_attr & A_COLOR; - SP->_current_attr &=~ A_COLOR; - } - TPUTS_TRACE("clr_eol"); - putp(clr_eol); - if (back_color_erase) - vidattr(SP->_current_attr | oldcolor); +bool needclear = FALSE; for (j = SP->_curscol; j < screen_columns; j++) - curscr->_line[SP->_cursrow].text[j] = ' '; -} + { + chtype *cp = &(curscr->_line[SP->_cursrow].text[j]); -static void ClrToBOL(void) -{ -int j; -attr_t oldcolor = 0; /* initialization pacifies -Wall */ - - if (back_color_erase) { - TPUTS_TRACE("orig_pair"); - putp(orig_pair); - oldcolor = SP->_current_attr & A_COLOR; - SP->_current_attr &=~ A_COLOR; + if (*cp != blank) + { + *cp = blank; + needclear = TRUE; + } } - TPUTS_TRACE("clr_bol"); - putp(clr_bol); - if (back_color_erase) - vidattr(SP->_current_attr | oldcolor); - - for (j = 0; j <= SP->_curscol; j++) - curscr->_line[SP->_cursrow].text[j] = ' '; -} - -/* -** TransformLine(lineno) -** -** Call either IDcTransformLine or NoIDcTransformLine to do the -** update, depending upon availability of insert/delete character. -*/ - -static void TransformLine(int const lineno) -{ - - T(("TransformLine(%d) called",lineno)); - if ( (insert_character || (enter_insert_mode && exit_insert_mode)) - && delete_character) - IDcTransformLine(lineno); - else - NoIDcTransformLine(lineno); + if (needclear) + { + UpdateAttrs(blank); + TPUTS_TRACE("clr_eol"); + if (SP->_el_cost > (screen_columns - SP->_curscol)) + { + int count = (screen_columns - SP->_curscol); + while (count-- > 0) + PutChar(blank); + } + else + putp(clr_eol); + } } - - /* -** NoIDcTransformLine(lineno) -** -** Transform the given line in curscr to the one in newscr, without -** using Insert/Delete Character. -** -** firstChar = position of first different character in line -** lastChar = position of last different character in line -** -** overwrite all characters between firstChar and lastChar. -** -*/ - -static void NoIDcTransformLine(int const lineno) + * ClrBottom(total) + * + * Test if clearing the end of the screen would satisfy part of the + * screen-update. Do this by scanning backwards through the lines in the + * screen, checking if each is blank, and one or more are changed. + */ +static int ClrBottom(int total) { -int firstChar, lastChar; -chtype *newLine = newscr->_line[lineno].text; -chtype *oldLine = curscr->_line[lineno].text; -int k; -int attrchanged = 0; - - T(("NoIDcTransformLine(%d) called", lineno)); - - firstChar = 0; - while (firstChar < screen_columns - 1 && newLine[firstChar] == oldLine[firstChar]) { - if(ceol_standout_glitch) { - if(AttrOf(newLine[firstChar]) != AttrOf(oldLine[firstChar])) - attrchanged = 1; +static chtype *tstLine; +static size_t lenLine; + +int row, col; +int top = total; +int last = min(screen_columns, newscr->_maxx+1); +size_t length = sizeof(chtype) * last; +chtype blank = newscr->_line[total-1].text[last-1]; /* lower right char */ + + if(!can_clear_with(blank)) + return total; + + if (tstLine == 0) + tstLine = (chtype *)malloc(length); + else if (length > lenLine) + tstLine = (chtype *)realloc(tstLine, length); + + if (tstLine != 0) { + lenLine = length; + for (col = 0; col < last; col++) + tstLine[col] = blank; + + for (row = total-1; row >= 0; row--) { + if (memcmp(tstLine, newscr->_line[row].text, length)) + break; + if (newscr->_line[row].firstchar != _NOCHANGE) + top = row; } - firstChar++; - } - - T(("first char at %d is %lx", firstChar, newLine[firstChar])); - if (firstChar > screen_columns) - return; - - if(ceol_standout_glitch && attrchanged) { - firstChar = 0; - lastChar = screen_columns - 1; - GoTo(lineno, firstChar); - if(clr_eol) - ClrToEOL(); - } else { - lastChar = screen_columns - 1; - while (lastChar > firstChar && newLine[lastChar] == oldLine[lastChar]) - lastChar--; - GoTo(lineno, firstChar); - } - T(("updating chars %d to %d", firstChar, lastChar)); - for (k = firstChar; k <= lastChar; k++) { - PutChar(newLine[k]); - oldLine[k] = newLine[k]; + if (top < total) { + GoTo(top,0); + UpdateAttrs(blank); + TPUTS_TRACE("clr_eos"); + putp(clr_eos); + while (total-- > top) { + for (col = 0; col <= curscr->_maxx; col++) + curscr->_line[total].text[col] = blank; + } + total++; + } } +#if NO_LEAKS + FreeAndNull(tstLine); +#endif + return total; } + /* -** IDcTransformLine(lineno) +** TransformLine(lineno) ** ** Transform the given line in curscr to the one in newscr, using -** Insert/Delete Character. +** Insert/Delete Character if _nc_idcok && has_ic(). ** ** firstChar = position of first different character in line ** oLastChar = position of last different character in old line @@ -599,86 +908,123 @@ int attrchanged = 0; ** delete oLastChar - nLastChar spaces */ -static void IDcTransformLine(int const lineno) +static void TransformLine(int const lineno) { int firstChar, oLastChar, nLastChar; chtype *newLine = newscr->_line[lineno].text; chtype *oldLine = curscr->_line[lineno].text; -int k, n; -int attrchanged = 0; +int n; +bool attrchanged = FALSE; - T(("IDcTransformLine(%d) called", lineno)); + T(("TransformLine(%d) called", lineno)); if(ceol_standout_glitch && clr_eol) { firstChar = 0; while(firstChar < screen_columns) { if(AttrOf(newLine[firstChar]) != AttrOf(oldLine[firstChar])) - attrchanged = 1; + attrchanged = TRUE; firstChar++; } } firstChar = 0; - if (attrchanged) { + if (attrchanged) { /* we may have to disregard the whole line */ GoTo(lineno, firstChar); - ClrToEOL(); - for( k = 0 ; k <= (screen_columns-1) ; k++ ) - PutChar(newLine[k]); + ClrToEOL(ClrBlank(curscr)); + PutRange(oldLine, newLine, lineno, 0, (screen_columns-1)); } else { + chtype blank; + + /* find the first differing character */ while (firstChar < screen_columns && newLine[firstChar] == oldLine[firstChar]) firstChar++; + /* if there wasn't one, we're done */ if (firstChar >= screen_columns) return; - if (clr_bol) + /* it may be cheap to clear leading whitespace with clr_bol */ + if (clr_bol && can_clear_with(blank=newLine[0])) { int oFirstChar, nFirstChar; for (oFirstChar = 0; oFirstChar < screen_columns; oFirstChar++) - if (oldLine[oFirstChar] != BLANK) + if (oldLine[oFirstChar] != blank) break; for (nFirstChar = 0; nFirstChar < screen_columns; nFirstChar++) - if (newLine[nFirstChar] != BLANK) + if (newLine[nFirstChar] != blank) break; - if (nFirstChar > oFirstChar + (int)strlen(clr_bol)) + if (nFirstChar > oFirstChar + SP->_el1_cost) { GoTo(lineno, nFirstChar - 1); - ClrToBOL(); + UpdateAttrs(blank); + TPUTS_TRACE("clr_bol"); + putp(clr_bol); - if(nFirstChar == screen_columns) + while (firstChar < nFirstChar) + oldLine[firstChar++] = blank; + + if (firstChar >= screen_columns) return; + } + } - if (nFirstChar > firstChar) - firstChar = nFirstChar; + blank = newLine[screen_columns-1]; + + if(!can_clear_with(blank)) + { + /* find the last differing character */ + nLastChar = screen_columns - 1; + + while (nLastChar > firstChar + && newLine[nLastChar] == oldLine[nLastChar]) + nLastChar--; + + if (nLastChar >= firstChar) { + GoTo(lineno, firstChar); + PutRange(oldLine, newLine, lineno, firstChar, nLastChar); + memcpy( oldLine + firstChar, + newLine + firstChar, + (nLastChar - firstChar + 1) * sizeof(chtype)); } + return; } + /* find last non-blank character on old line */ oLastChar = screen_columns - 1; - while (oLastChar > firstChar && oldLine[oLastChar] == BLANK) + while (oLastChar > firstChar && oldLine[oLastChar] == blank) oLastChar--; + /* find last non-blank character on new line */ nLastChar = screen_columns - 1; - while (nLastChar > firstChar && newLine[nLastChar] == BLANK) + while (nLastChar > firstChar && newLine[nLastChar] == blank) nLastChar--; if((nLastChar == firstChar) - && clr_eol - && (curscr->_attrs == A_NORMAL)) { + && (SP->_el_cost < (screen_columns - nLastChar))) { GoTo(lineno, firstChar); - ClrToEOL(); - if(newLine[firstChar] != BLANK ) + ClrToEOL(blank); + if(newLine[firstChar] != blank ) PutChar(newLine[firstChar]); - } else if( newLine[nLastChar] != oldLine[oLastChar] ) { - n = max( nLastChar , oLastChar ); - + } else if( newLine[nLastChar] != oldLine[oLastChar] + || !(_nc_idcok && has_ic()) ) { GoTo(lineno, firstChar); - for( k=firstChar ; k <= n ; k++ ) - PutChar(newLine[k]); + if ((oLastChar - nLastChar) > SP->_el_cost) { + if(PutRange(oldLine, newLine, lineno, firstChar, nLastChar)) + GoTo(lineno, nLastChar+1); + ClrToEOL(blank); + } else { + n = max( nLastChar , oLastChar ); + PutRange(oldLine, newLine, lineno, firstChar, n); + } } else { + int nLastNonblank = nLastChar; + int oLastNonblank = oLastChar; + + /* find the last characters that really differ */ while (newLine[nLastChar] == oldLine[oLastChar]) { if (nLastChar != 0 && oLastChar != 0) { @@ -690,29 +1036,48 @@ int attrchanged = 0; } n = min(oLastChar, nLastChar); - GoTo(lineno, firstChar); - - for (k=firstChar; k <= n; k++) - PutChar(newLine[k]); - - if (oLastChar < nLastChar) - InsStr(&newLine[k], nLastChar - oLastChar); - - else if (oLastChar > nLastChar ) { - /* - * The delete-char sequence will effectively - * shift in blanks from the right margin of the - * screen. Ensure that they are the right - * color by setting the video attributes from - * the last character on the row. - */ - UpdateAttrs(newLine[screen_columns-1]); - DelChar(oLastChar - nLastChar); + if (n >= firstChar) { + GoTo(lineno, firstChar); + PutRange(oldLine, newLine, lineno, firstChar, n); + } + GoTo(lineno, n+1); + + if (oLastChar < nLastChar) { + int m = max(nLastNonblank, oLastNonblank); + if (InsCharCost(nLastChar - oLastChar) + > (m - n)) { + PutRange(oldLine, newLine, lineno, n+1, m); + } else { + InsStr(&newLine[n+1], nLastChar - oLastChar); + } + } else if (oLastChar > nLastChar ) { + if (DelCharCost(oLastChar - nLastChar) + > SP->_el_cost + nLastNonblank - (n+1)) { + if(PutRange(oldLine, newLine, lineno, + n+1, nLastNonblank)) + GoTo(lineno, nLastNonblank+1); + ClrToEOL(blank); + } else { + /* + * The delete-char sequence will + * effectively shift in blanks from the + * right margin of the screen. Ensure + * that they are the right color by + * setting the video attributes from + * the last character on the row. + */ + UpdateAttrs(blank); + DelChar(oLastChar - nLastChar); + } } } } - for (k = firstChar; k < screen_columns; k++) - oldLine[k] = newLine[k]; + + /* update the code's internal representation */ + if (screen_columns > firstChar) + memcpy( oldLine + firstChar, + newLine + firstChar, + (screen_columns - firstChar) * sizeof(chtype)); } /* @@ -831,10 +1196,14 @@ static void DelChar(int count) ** Emit a string without waiting for update. */ -void _nc_outstr(char *str) +void _nc_outstr(const char *str) { FILE *ofp = SP ? SP->_ofp : stdout; (void) fputs(str, ofp); (void) fflush(ofp); + +#ifdef TRACE + _nc_outchars += strlen(str); +#endif /* TRACE */ } diff --git a/lib/libcurses/lib_endwin.c b/lib/libcurses/lib_endwin.c index bda6e1949b8..f3fce19e72a 100644 --- a/lib/libcurses/lib_endwin.c +++ b/lib/libcurses/lib_endwin.c @@ -27,31 +27,42 @@ ** */ -#include "curses.priv.h" -#include "term.h" +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: lib_endwin.c,v 1.10 1997/02/02 00:36:41 tom Exp $") int endwin(void) { - T(("endwin() called")); + T((T_CALLED("endwin()"))); SP->_endwin = TRUE; _nc_mouse_wrap(SP); - mvcur(-1, -1, screen_lines - 1, 0); + /* SP->_curs{row,col} may be used later in _nc_mvcur_wrap,save_curs */ + mvcur(-1, -1, SP->_cursrow = screen_lines - 1, SP->_curscol = 0); curs_set(1); /* set cursor to normal mode */ if (SP->_coloron == TRUE && orig_pair) putp(orig_pair); - _nc_mvcur_wrap(); /* wrap up cursor addressing */ + _nc_mvcur_wrap(); /* wrap up cursor addressing */ - if (curscr && (curscr->_attrs != A_NORMAL)) - vidattr(curscr->_attrs = A_NORMAL); + if (SP && (SP->_current_attr != A_NORMAL)) + vidattr(A_NORMAL); - fflush(SP->_ofp); + /* + * Reset terminal's tab counter. There's a long-time bug that + * if you exit a "curses" program such as vi or more, tab + * forward, and then backspace, the cursor doesn't go to the + * right place. The problem is that the kernel counts the + * escape sequences that reset things as column positions. + * Utter a \r to reset this invisibly. + */ + _nc_outch('\r'); - return(reset_shell_mode()); + returnCode(reset_shell_mode()); } diff --git a/lib/libcurses/lib_erase.c b/lib/libcurses/lib_erase.c index 1a3ee5c8841..3bdf64a4523 100644 --- a/lib/libcurses/lib_erase.c +++ b/lib/libcurses/lib_erase.c @@ -27,7 +27,9 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_erase.c,v 1.7 1997/02/01 23:18:18 tom Exp $") int werase(WINDOW *win) { @@ -35,32 +37,32 @@ int y; chtype *sp, *end, *start, *maxx = NULL; short minx; - T(("werase(%p) called", win)); + T((T_CALLED("werase(%p)"), win)); for (y = 0; y <= win->_maxy; y++) { - minx = _NOCHANGE; - start = win->_line[y].text; - end = &start[win->_maxx]; - - maxx = start; - for (sp = start; sp <= end; sp++) { - maxx = sp; - if (minx == _NOCHANGE) + minx = _NOCHANGE; + start = win->_line[y].text; + end = &start[win->_maxx]; + + maxx = start; + for (sp = start; sp <= end; sp++) { + maxx = sp; + if (minx == _NOCHANGE) minx = sp - start; - *sp = _nc_render(win, *sp, BLANK); - } + *sp = _nc_background(win); + } - if (minx != _NOCHANGE) { + if (minx != _NOCHANGE) { if (win->_line[y].firstchar > minx || - win->_line[y].firstchar == _NOCHANGE) - win->_line[y].firstchar = minx; + win->_line[y].firstchar == _NOCHANGE) + win->_line[y].firstchar = minx; if (win->_line[y].lastchar < maxx - win->_line[y].text) - win->_line[y].lastchar = maxx - win->_line[y].text; - } + win->_line[y].lastchar = maxx - win->_line[y].text; + } } win->_curx = win->_cury = 0; - win->_flags &= ~_NEED_WRAP; + win->_flags &= ~_WRAPPED; _nc_synchook(win); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_getch.c b/lib/libcurses/lib_getch.c index 12372bc0fc0..c0d0d5af203 100644 --- a/lib/libcurses/lib_getch.c +++ b/lib/libcurses/lib_getch.c @@ -26,13 +26,9 @@ ** */ -#include "curses.priv.h" -#include <sys/types.h> -#include <string.h> -#include <errno.h> -#if !HAVE_EXTERN_ERRNO -extern int errno; -#endif +#include <curses.priv.h> + +MODULE_ID("Id: lib_getch.c,v 1.24 1997/02/15 21:12:16 tom Exp $") #define head SP->_fifohead #define tail SP->_fifotail @@ -52,24 +48,24 @@ static int fifo_peek(void) } #ifdef TRACE -static __inline void fifo_dump(void) +static inline void fifo_dump(void) { int i; T(("head = %d, tail = %d, peek = %d", head, tail, peek)); for (i = 0; i < 10; i++) - T(("char %d = %s", i, _tracechar(SP->_fifo[i]))); + T(("char %d = %s", i, _trace_key(SP->_fifo[i]))); } #endif /* TRACE */ -static __inline int fifo_pull(void) +static inline int fifo_pull(void) { int ch; - ch = SP->_fifo[head]; + ch = SP->_fifo[head]; T(("pulling %d from %d", ch, head)); h_inc(); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return ch; } @@ -83,26 +79,56 @@ int ungetch(int ch) t_inc() } else h_dec(); - + SP->_fifo[head] = ch; T(("ungetch ok")); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return OK; } -static __inline int fifo_push(void) +static inline int fifo_push(void) { int n; -unsigned char ch; +unsigned int ch; if (tail == -1) return ERR; /* FALLTHRU */ -again: - n = read(SP->_ifd, &ch, 1); - if (n == -1 && errno == EINTR) +again: + errno = 0; +#if USE_GPM_SUPPORT + if ((_nc_mouse_fd() >= 0) + && (_nc_timed_wait(3, -1, (int *)0) & 2)) + { + _nc_mouse_event(SP); + ch = KEY_MOUSE; + n = 1; + } else +#endif + { + unsigned char c2; + n = read(SP->_ifd, &c2, 1); + ch = c2; + } + + /* + * Under System V curses with non-restarting signals, getch() returns + * with value ERR when a handled signal keeps it from completing. + * If signals restart system calls, OTOH, the signal is invisible + * except to its handler. + * + * We don't want this difference to show. This piece of code + * tries to make it look like we always have restarting signals. + */ + if (n <= 0 && errno == EINTR) goto again; + + if ((n == -1) || (n == 0)) + { + T(("read(%d,&ch,1)=%d", SP->_ifd, n)); + return ERR; + } T(("read %d characters", n)); SP->_fifo[tail] = ch; @@ -110,12 +136,12 @@ again: t_inc(); T(("pushed %#x at %d", ch, tail)); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return ch; } -static __inline void fifo_clear(void) +static inline void fifo_clear(void) { int i; for (i = 0; i < FIFO_SIZE; i++) @@ -133,7 +159,8 @@ void _nc_backspace(WINDOW *win) return; } - mvwaddstr(curscr, win->_begy + win->_cury, win->_begx + win->_curx, "\b \b"); + mvwaddstr(curscr, win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, "\b \b"); waddstr(win, "\b \b"); /* @@ -141,35 +168,57 @@ void _nc_backspace(WINDOW *win) * would fail on terminals with a non-backspace cursor_left * character. */ - mvcur(win->_begy + win->_cury, win->_begx + win->_curx, - win->_begy + win->_cury, win->_begx + win->_curx - 1); + mvcur(win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx - 1); _nc_outstr(" "); - mvcur(win->_begy + win->_cury, win->_begx + win->_curx, - win->_begy + win->_cury, win->_begx + win->_curx - 1); - SP->_curscol--; + mvcur(win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx - 1); + SP->_curscol--; } int wgetch(WINDOW *win) { -bool setHere = FALSE; /* cbreak mode was set here */ -int ch; +int ch; + + T((T_CALLED("wgetch(%p)"), win)); + + /* + * Handle cooked mode. Grab a string from the screen, + * stuff its contents in the FIFO queue, and pop off + * the first character to return it. + */ + if (head == -1 && !SP->_raw && !SP->_cbreak) + { + char buf[MAXCOLUMNS], *sp; + + T(("filling queue in cooked mode")); - T(("wgetch(%p) called", win)); + wgetnstr(win, buf, MAXCOLUMNS); + + for (sp = buf; *sp; sp++) + ungetch(*sp); + ungetch('\n'); + + return(fifo_pull()); + } /* this should be eliminated */ - if (! win->_scroll && (SP->_echo) && (win->_flags & _FULLWIN) - && win->_curx == win->_maxx && win->_cury == win->_maxy) - return(ERR); + if (!has_ic() + && !win->_scroll + && (SP->_echo) + && (win->_flags & _FULLWIN) + && win->_curx == win->_maxx + && win->_cury == win->_maxy) + returnCode(ERR); if ((is_wintouched(win) || (win->_flags & _HASMOVED)) && !(win->_flags & _ISPAD)) wrefresh(win); - if (SP->_echo && ! (SP->_raw || SP->_cbreak)) { - cbreak(); - setHere = TRUE; - } - if (!win->_notimeout && (win->_delay >= 0 || SP->_cbreak > 1)) { int delay; @@ -182,19 +231,13 @@ int ch; T(("delay is %d microseconds", delay)); if (head == -1) /* fifo is empty */ - if (_nc_timed_wait(SP->_ifd, delay, NULL) == 0) - return ERR; + if (!_nc_timed_wait(3, delay, (int *)0)) + returnCode(ERR); /* else go on to read data available */ } - /* - * Give the mouse interface a chance to pick up an event. - * If no mouse event, check for keyboard input. - */ - if (_nc_mouse_event(SP)) - ch = KEY_MOUSE; - else if (win->_use_keypad) { - /* + if (win->_use_keypad) { + /* * This is tricky. We only want to get special-key * events one at a time. But we want to accumulate * mouse events until either (a) the mouse logic tells @@ -203,9 +246,9 @@ int ch; * * Note: if the mouse code starts failing to compose * press/release events into clicks, you should probably - * increase _nc_max_click_interval. + * increase _nc_max_click_interval. */ - int runcount = 0; + int runcount = 0; do { ch = kgetch(win); @@ -217,7 +260,7 @@ int ch; } } while (ch == KEY_MOUSE - && (_nc_timed_wait(SP->_ifd, _nc_max_click_interval, NULL) + && (_nc_timed_wait(3, _nc_max_click_interval, (int *)0) || !_nc_mouse_parse(runcount))); if (runcount > 0 && ch != KEY_MOUSE) { @@ -231,6 +274,18 @@ int ch; ch = fifo_pull(); } + if (ch == ERR) + { + T(("wgetch returning ERR")); + returnCode(ERR); + } + + /* + * Simulate ICRNL mode + */ + if ((ch == '\r') && SP->_nl) + ch = '\n'; + /* Strip 8th-bit if so desired. We do this only for characters that * are in the range 128-255, to provide compatibility with terminals * that display only 7-bit characters. Note that 'ch' may be a @@ -240,28 +295,24 @@ int ch; if (!SP->_use_meta) ch &= 0x7f; - if (!(win->_flags & _ISPAD) && SP->_echo) { + if (!(win->_flags & _ISPAD) && SP->_echo) { /* there must be a simpler way of doing this */ if (ch == erasechar() || ch == KEY_BACKSPACE || ch == KEY_LEFT) _nc_backspace(win); else if (ch < KEY_MIN) { mvwaddch(curscr, - win->_begy + win->_cury, - win->_begx + win->_curx, - (chtype)(ch | win->_attrs)); - waddch(win, (chtype)(ch | win->_attrs)); + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + ch); + waddch(win, (chtype)ch); } else beep(); } - if (setHere) - nocbreak(); - T(("wgetch returning : 0x%x = %s", - ch, - (ch > KEY_MIN) ? keyname(ch) : unctrl(ch))); + T(("wgetch returning : %#x = %s", ch, _trace_key(ch));) - return(ch); + returnCode(ch); } @@ -278,52 +329,53 @@ int ch; */ static int -kgetch(WINDOW *win) +kgetch(WINDOW *win GCC_UNUSED) { -struct try *ptr; +struct tries *ptr; int ch = 0; int timeleft = ESCDELAY; - TR(TRACE_FIFO, ("kgetch(%p) called", win)); + TR(TRACE_IEVENT, ("kgetch(%p) called", win)); - ptr = SP->_keytry; + ptr = SP->_keytry; if (head == -1) { - ch = fifo_push(); + if ((ch = fifo_push()) == ERR) + return ERR; peek = 0; - while (ptr != NULL) { - TR(TRACE_FIFO, ("ch: %s", _tracechar((unsigned char)ch))); + while (ptr != NULL) { + TR(TRACE_IEVENT, ("ch: %s", _trace_key((unsigned char)ch))); while ((ptr != NULL) && (ptr->ch != (unsigned char)ch)) ptr = ptr->sibling; #ifdef TRACE if (ptr == NULL) - {TR(TRACE_FIFO, ("ptr is null"));} + {TR(TRACE_IEVENT, ("ptr is null"));} else - TR(TRACE_FIFO, ("ptr=%p, ch=%d, value=%d", + TR(TRACE_IEVENT, ("ptr=%p, ch=%d, value=%d", ptr, ptr->ch, ptr->value)); #endif /* TRACE */ if (ptr != NULL) - if (ptr->value != 0) { /* sequence terminated */ - TR(TRACE_FIFO, ("end of sequence")); - fifo_clear(); + if (ptr->value != 0) { /* sequence terminated */ + TR(TRACE_IEVENT, ("end of sequence")); + fifo_clear(); return(ptr->value); - } else { /* go back for another character */ + } else { /* go back for another character */ ptr = ptr->child; - TR(TRACE_FIFO, ("going back for more")); - } else + TR(TRACE_IEVENT, ("going back for more")); + } else break; - TR(TRACE_FIFO, ("waiting for rest of sequence")); - if (_nc_timed_wait(SP->_ifd, timeleft, &timeleft) < 1) { - TR(TRACE_FIFO, ("ran out of time")); + TR(TRACE_IEVENT, ("waiting for rest of sequence")); + if (!_nc_timed_wait(3, timeleft, &timeleft)) { + TR(TRACE_IEVENT, ("ran out of time")); return(fifo_pull()); - } else { - TR(TRACE_FIFO, ("got more!")); - fifo_push(); - ch = fifo_peek(); - } + } else { + TR(TRACE_IEVENT, ("got more!")); + fifo_push(); + ch = fifo_peek(); + } } - } + } return(fifo_pull()); } diff --git a/lib/libcurses/lib_getstr.c b/lib/libcurses/lib_getstr.c index 5f4dbcd2b7c..55248e20e6b 100644 --- a/lib/libcurses/lib_getstr.c +++ b/lib/libcurses/lib_getstr.c @@ -27,19 +27,49 @@ ** */ -#include "curses.priv.h" -#include "unctrl.h" -#include <string.h> +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: lib_getstr.c,v 1.11 1997/02/01 23:22:54 tom Exp $") + +/* + * This wipes out the last character, no matter whether it was a tab, control + * or other character, and handles reverse wraparound. + */ +static char *WipeOut(WINDOW *win, int y, int x, char *first, char *last, bool echoed) +{ + if (last > first) { + *--last = '\0'; + if (echoed) { + int y1 = win->_cury; + int x1 = win->_curx; + + wmove(win, y, x); + waddstr(win, first); + getyx(win, y, x); + while (win->_cury < y1 + || (win->_cury == y1 && win->_curx < x1)) + waddch(win, ' '); + + wmove(win, y, x); + } + } + return last; +} int wgetnstr(WINDOW *win, char *str, int maxlen) { +TTY buf; bool oldnl, oldecho, oldraw, oldcbreak, oldkeypad; char erasec; char killc; char *oldstr; int ch; - - T(("wgetnstr(%p,%p, %d) called", win, str, maxlen)); +int y, x; + + T((T_CALLED("wgetnstr(%p,%p, %d)"), win, str, maxlen)); + + GET_TTY(cur_term->Filedes, &buf); oldnl = SP->_nl; oldecho = SP->_echo; @@ -56,76 +86,77 @@ int ch; killc = killchar(); oldstr = str; + getyx(win, y, x); if (is_wintouched(win) || (win->_flags & _HASMOVED)) wrefresh(win); while ((ch = wgetch(win)) != ERR) { - /* + /* * Some terminals (the Wyse-50 is the most common) generate * a \n from the down-arrow key. With this logic, it's the * user's choice whether to set kcud=\n for wgetch(); * terminating *getstr() with \n should work either way. */ - if (ch == '\n' || ch == '\r' || ch == KEY_DOWN) + if (ch == '\n' + || ch == '\r' + || ch == KEY_DOWN + || ch == KEY_ENTER) break; - if (ch == erasec || ch == KEY_LEFT || ch == KEY_BACKSPACE) { + if (ch == erasec || ch == KEY_LEFT || ch == KEY_BACKSPACE) { if (str > oldstr) { - str--; - if (oldecho == TRUE) - _nc_backspace(win); + str = WipeOut(win, y, x, oldstr, str, oldecho); } - } else if (ch == killc) { + } else if (ch == killc) { while (str > oldstr) { - str--; - if (oldecho == TRUE) - _nc_backspace(win); + str = WipeOut(win, y, x, oldstr, str, oldecho); } } else if (ch >= KEY_MIN || (maxlen >= 0 && str - oldstr >= maxlen)) { - beep(); + beep(); } else { - if (oldecho == TRUE) { - char *glyph = unctrl(ch); - - mvwaddstr(curscr, win->_begy + win->_cury, - win->_begx + win->_curx, glyph); - waddstr(win, glyph); - _nc_outstr(glyph); - SP->_curscol += strlen(glyph); - } *str++ = ch; - } + if (oldecho == TRUE) { + if (waddch(win, ch) == ERR) { + /* + * We can't really use the lower-right + * corner for input, since it'll mess + * up bookkeeping for erases. + */ + win->_flags &= ~_WRAPPED; + waddch(win, ' '); + str = WipeOut(win, y, x, oldstr, str, oldecho); + continue; + } + wrefresh(win); + } + } } - win->_curx = 0; - win->_flags &= ~_NEED_WRAP; - if (win->_cury < win->_maxy) - win->_cury++; + win->_curx = 0; + win->_flags &= ~_WRAPPED; + if (win->_cury < win->_maxy) + win->_cury++; wrefresh(win); - if (oldnl == FALSE) - nonl(); + /* Restore with a single I/O call, to fix minor asymmetry between + * raw/noraw, etc. + */ + SP->_nl = oldnl; + SP->_echo = oldecho; + SP->_raw = oldraw; + SP->_cbreak = oldcbreak; - if (oldecho == TRUE) - echo(); - - if (oldraw == TRUE) - raw(); - - if (oldcbreak == FALSE) - nocbreak(); + SET_TTY(cur_term->Filedes, &buf); if (oldkeypad == FALSE) keypad(win, FALSE); - if (ch == ERR) { - *str = '\0'; - return ERR; - } *str = '\0'; + if (ch == ERR) + returnCode(ERR); - T(("wgetnstr returns \"%s\"", _nc_visbuf(oldstr))); + T(("wgetnstr returns %s", _nc_visbuf(oldstr))); - return(OK); + returnCode(OK); } diff --git a/lib/libcurses/lib_inchstr.c b/lib/libcurses/lib_inchstr.c index 2dc64bff0d6..8ed9a8725cb 100644 --- a/lib/libcurses/lib_inchstr.c +++ b/lib/libcurses/lib_inchstr.c @@ -27,17 +27,19 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_inchstr.c,v 1.5 1997/02/02 01:06:03 tom Exp $") int winchnstr(WINDOW *win, chtype *str, int n) { int i; - T(("winchnstr(%p,'%p',%d) called", win, str, n)); + T((T_CALLED("winchnstr(%p,%p,%d)"), win, str, n)); for (i = 0; (n < 0 || (i < n)) && (win->_curx + i <= win->_maxx); i++) str[i] = win->_line[win->_cury].text[win->_curx + i]; str[i] = (chtype)0; - return(i); + returnCode(i); } diff --git a/lib/libcurses/lib_initscr.c b/lib/libcurses/lib_initscr.c index b9c6fcaaad9..8b2b90562cd 100644 --- a/lib/libcurses/lib_initscr.c +++ b/lib/libcurses/lib_initscr.c @@ -26,37 +26,69 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> -#include <string.h> +#include <curses.priv.h> +#include <term.h> /* cur_term */ -WINDOW *initscr(void) +#if HAVE_SYS_TERMIO_H +#include <sys/termio.h> /* needed for ISC */ +#endif + +MODULE_ID("Id: lib_initscr.c,v 1.18 1997/03/08 14:03:59 tom Exp $") + +#ifndef ONLCR /* Allows compilation under the QNX 4.2 OS */ +#define ONLCR 0 +#endif + +/* + * SVr4/XSI Curses specify that hardware echo is turned off in initscr, and not + * restored during the curses session. The library simulates echo in software. + * (The behavior is unspecified if the application enables hardware echo). + * + * The newterm function also initializes terminal settings. + */ +int _nc_initscr(void) { -char *name = getenv("TERM"); + /* for extended XPG4 conformance requires cbreak() at this point */ + /* (SVr4 curses does this anyway) */ + cbreak(); - if (name == 0) - name = "unknown"; - if (newterm(name, stdout, stdin) == NULL) { - fprintf(stderr, "Error opening terminal: %s.\n", name); - exit(1); - } +#ifdef TERMIOS + cur_term->Nttyb.c_lflag &= ~(ECHO|ECHONL); + cur_term->Nttyb.c_iflag &= ~(ICRNL|INLCR|IGNCR); + cur_term->Nttyb.c_oflag &= ~(ONLCR); +#else + cur_term->Nttyb.sg_flags &= ~(ECHO|CRMOD); +#endif + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + return ERR; + return OK; +} - /* allow user to set maximum escape delay from the environment */ - if ((name = getenv("ESCDELAY"))) - ESCDELAY = atoi(getenv("ESCDELAY")); +WINDOW *initscr(void) +{ +static bool initialized = FALSE; +const char *name; - def_shell_mode(); + T((T_CALLED("initscr()"))); + /* Portable applications must not call initscr() more than once */ + if (!initialized) { + initialized = TRUE; - /* follow the XPG4 requirement to turn echo off at this point */ - noecho(); + if ((name = getenv("TERM")) == 0) + name = "unknown"; + if (newterm(name, stdout, stdin) == 0) { + fprintf(stderr, "Error opening terminal: %s.\n", name); + exit(EXIT_FAILURE); + } -#ifdef _XOPEN_SOURCE_EXTENDED - /* for extended XPG4 conformance requires cbreak() at this point */ - cbreak(); -#endif /* _XOPEN_SOURCE_EXTENDED */ + /* allow user to set maximum escape delay from the environment */ + if ((name = getenv("ESCDELAY")) != 0) + ESCDELAY = atoi(getenv("ESCDELAY")); - def_prog_mode(); - return(stdscr); + /* def_shell_mode - done in newterm/_nc_setupscreen */ + def_prog_mode(); + } + returnWin(stdscr); } char *termname(void) @@ -66,10 +98,10 @@ static char ret[15]; T(("termname() called")); - if (term == (char *)NULL) - return(char *)NULL; - else { + if (term != 0) { (void) strncpy(ret, term, sizeof(ret) - 1); - return(ret); + ret[sizeof(ret) - 1] = '\0'; + term = ret; } + return term; } diff --git a/lib/libcurses/lib_insch.c b/lib/libcurses/lib_insch.c index b2f13744e5b..1702208019e 100644 --- a/lib/libcurses/lib_insch.c +++ b/lib/libcurses/lib_insch.c @@ -28,14 +28,16 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_insch.c,v 1.7 1997/04/12 17:43:02 tom Exp $") int winsch(WINDOW *win, chtype c) { chtype *temp1, *temp2; chtype *end; - T(("winsch(%p,'%lx') called", win, c)); + T((T_CALLED("winsch(%p, %s)"), win, _tracechtype(c))); end = &win->_line[win->_cury].text[win->_curx]; temp1 = &win->_line[win->_cury].text[win->_maxx]; @@ -44,11 +46,11 @@ chtype *end; while (temp1 > end) *temp1-- = *temp2--; - *temp1 = _nc_render(win, c, c | win->_attrs); + *temp1 = _nc_render(win, c); win->_line[win->_cury].lastchar = win->_maxx; if (win->_line[win->_cury].firstchar == _NOCHANGE || win->_line[win->_cury].firstchar > win->_curx) win->_line[win->_cury].firstchar = win->_curx; - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_insdel.c b/lib/libcurses/lib_insdel.c index a6e6a86c78b..c367c93d5d0 100644 --- a/lib/libcurses/lib_insdel.c +++ b/lib/libcurses/lib_insdel.c @@ -19,33 +19,30 @@ * * ***************************************************************************/ - - /* ** lib_insdel.c ** ** The routine winsdelln(win, n). ** positive n insert n lines above current line -** negative n delete n lines starting from current line +** negative n delete n lines starting from current line ** */ -#include "curses.priv.h" -#include <stdlib.h> +#include <curses.priv.h> + +MODULE_ID("$Id") int winsdelln(WINDOW *win, int n) { - T(("winsdel(%p,%d) called", win, n)); + T((T_CALLED("winsdel(%p,%d)"), win, n)); if (n == 0) - return OK; + returnCode(OK); _nc_scroll_window(win, -n, win->_cury, win->_maxy); touchline(win, win->_cury, win->_maxy - win->_cury + 1); _nc_synchook(win); - return OK; + returnCode(OK); } - - diff --git a/lib/libcurses/lib_insstr.c b/lib/libcurses/lib_insstr.c index 1d1d867ecc8..c25071f76d5 100644 --- a/lib/libcurses/lib_insstr.c +++ b/lib/libcurses/lib_insstr.c @@ -28,18 +28,20 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> #include <ctype.h> +MODULE_ID("Id: lib_insstr.c,v 1.9 1997/02/15 16:09:53 tom Exp $") + int winsnstr(WINDOW *win, const char *str, int n) { short oy = win->_cury; short ox = win->_curx; -char *cp; +const char *cp; - T(("winsstr(%p,'%s',%d) called", win, str, n)); + T((T_CALLED("winsstr(%p,%s,%d)"), win, _nc_visbuf(str), n)); - for (cp = (char *)str; *cp && (n <= 0 || (cp - str) < n); cp++) { + for (cp = str; *cp && (n <= 0 || (cp - str) < n); cp++) { if (*cp == '\n' || *cp == '\r' || *cp == '\t' || *cp == '\b') _nc_waddch_nosync(win, (chtype)(*cp)); else if (is7bits(*cp) && iscntrl(*cp)) { @@ -53,9 +55,9 @@ char *cp; if (win->_curx > win->_maxx) win->_curx = win->_maxx; } - + win->_curx = ox; win->_cury = oy; _nc_synchook(win); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_instr.c b/lib/libcurses/lib_instr.c index e1ef5272fd9..d21de453a09 100644 --- a/lib/libcurses/lib_instr.c +++ b/lib/libcurses/lib_instr.c @@ -27,18 +27,30 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_instr.c,v 1.6 1997/05/03 10:51:07 juergen Exp $") int winnstr(WINDOW *win, char *str, int n) { - int i; + int i, row, col; - T(("winnstr(%p,'%p',%d) called", win, str, n)); + T((T_CALLED("winnstr(%p,%p,%d)"), win, str, n)); - for (i = 0; (n < 0 || (i < n)) && (win->_curx + i <= win->_maxx); i++) - str[i] = win->_line[win->_cury].text[win->_curx + i] & A_CHARTEXT; - str[i] = '\0'; + getyx(win, row, col); - return(i); -} + if (n < 0) + n = win->_maxx - win->_curx + 1; + for (i = 0; i < n;) { + str[i++] = TextOf(win->_line[row].text[col]); + if (++col > win->_maxx) { + col = 0; + if (++row > win->_maxy) + break; + } + } + str[i] = '\0'; /* SVr4 does not seem to count the null */ + + returnCode(i); +} diff --git a/lib/libcurses/lib_isendwin.c b/lib/libcurses/lib_isendwin.c index bfd991e3cfb..55c57c9d6ab 100644 --- a/lib/libcurses/lib_isendwin.c +++ b/lib/libcurses/lib_isendwin.c @@ -27,7 +27,9 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_isendwin.c,v 1.2 1996/07/30 22:29:50 tom Exp $") int isendwin(void) { diff --git a/lib/libcurses/lib_kernel.c b/lib/libcurses/lib_kernel.c index 622c549acea..a6d0083d076 100644 --- a/lib/libcurses/lib_kernel.c +++ b/lib/libcurses/lib_kernel.c @@ -27,52 +27,46 @@ * napms() * reset_prog_mode() * reset_shell_mode() - * baudrate() - * delay_output() * erasechar() * killchar() * flushinp() * savetty() * resetty() * - * + * The baudrate() and delay_output() functions could logically live here, + * but are in other modules to reduce the static-link size of programs + * that use only these facilities. */ -#include "curses.priv.h" -#include "term.h" /* cur_term, pad_char */ -#include <errno.h> -#if !HAVE_EXTERN_ERRNO -extern int errno; -#endif +#include <curses.priv.h> +#include <term.h> /* cur_term */ + +MODULE_ID("Id: lib_kernel.c,v 1.13 1997/02/02 00:33:14 tom Exp $") int napms(int ms) { - T(("napms(%d) called", ms)); + T((T_CALLED("napms(%d)"), ms)); usleep(1000*(unsigned)ms); - return OK; + returnCode(OK); } #ifndef EXTERN_TERMINFO int reset_prog_mode(void) { - T(("reset_prog_mode() called")); + T((T_CALLED("reset_prog_mode()"))); -#ifdef TERMIOS - tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb); -#else - stty(cur_term->Filedes, &cur_term->Nttyb); -#endif + SET_TTY(cur_term->Filedes, &cur_term->Nttyb); if (SP && stdscr && stdscr->_use_keypad) _nc_keypad(TRUE); - return OK; + returnCode(OK); } int reset_shell_mode(void) { - T(("reset_shell_mode() called")); + T((T_CALLED("reset_shell_mode()"))); if (SP) { @@ -80,42 +74,11 @@ int reset_shell_mode(void) _nc_keypad(FALSE); } -#ifdef TERMIOS - tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Ottyb); -#else - stty(cur_term->Filedes, &cur_term->Ottyb); -#endif - return OK; + SET_TTY(cur_term->Filedes, &cur_term->Ottyb); + returnCode(OK); } #endif /* EXTERN_TERMINFO */ -int delay_output(float ms) -{ - T(("delay_output(%f) called", ms)); - - if (SP == 0 || SP->_baudrate == ERR) - return(ERR); -#ifdef no_pad_char - else if (no_pad_char) - _nc_timed_wait(0, (int)ms, (int *)NULL); -#endif /* no_pad_char */ - else { - register int nullcount; - char null = '\0'; - -#ifdef pad_char - if (pad_char) - null = pad_char[0]; -#endif /* pad_char */ - - for (nullcount = ms * 1000 / SP->_baudrate; nullcount > 0; nullcount--) - putc(null, SP->_ofp); - (void) fflush(SP->_ofp); - } - - return OK; -} - /* * erasechar() * @@ -126,12 +89,12 @@ int delay_output(float ms) char erasechar(void) { - T(("erasechar() called")); + T((T_CALLED("erasechar()"))); #ifdef TERMIOS - return(cur_term->Ottyb.c_cc[VERASE]); + returnCode(cur_term->Ottyb.c_cc[VERASE]); #else - return(cur_term->Ottyb.sg_erase); + returnCode(cur_term->Ottyb.sg_erase); #endif } @@ -148,12 +111,12 @@ erasechar(void) char killchar(void) { - T(("killchar() called")); + T((T_CALLED("killchar()"))); #ifdef TERMIOS - return(cur_term->Ottyb.c_cc[VKILL]); + returnCode(cur_term->Ottyb.c_cc[VKILL]); #else - return(cur_term->Ottyb.sg_kill); + returnCode(cur_term->Ottyb.sg_kill); #endif } @@ -168,7 +131,7 @@ killchar(void) int flushinp(void) { - T(("flushinp() called")); + T((T_CALLED("flushinp()"))); #ifdef TERMIOS tcflush(cur_term->Filedes, TCIFLUSH); @@ -178,104 +141,16 @@ int flushinp(void) ioctl(cur_term->Filedes, TIOCFLUSH, 0); } while (errno == EINTR); -#endif - if (SP) { - SP->_fifohead = -1; - SP->_fifotail = 0; - SP->_fifopeek = 0; - } - return OK; - -} - - - -/* - * int - * baudrate() - * - * Returns the current terminal's baud rate. - * - */ - -struct speed { - speed_t s; - int sp; -}; - -static struct speed const speeds[] = { - {B0, 0}, - {B50, 50}, - {B75, 75}, - {B110, 110}, - {B134, 134}, - {B150, 150}, - {B200, 200}, - {B300, 300}, - {B600, 600}, - {B1200, 1200}, - {B1800, 1800}, - {B2400, 2400}, - {B4800, 4800}, - {B9600, 9600}, -#define MAX_BAUD B9600 -#ifdef B19200 -#undef MAX_BAUD -#define MAX_BAUD B19200 - {B19200, 19200}, -#else -#ifdef EXTA -#define MAX_BAUD EXTA - {EXTA, 19200}, -#endif -#endif -#ifdef B38400 -#undef MAX_BAUD -#define MAX_BAUD B38400 - {B38400, 38400}, -#else -#ifdef EXTB -#define MAX_BAUD EXTB - {EXTB, 38400}, -#endif -#endif -#ifdef B57600 -#undef MAX_BAUD -#define MAX_BAUD B57600 - {B57600, 57600}, -#endif -#ifdef B115200 -#undef MAX_BAUD -#define MAX_BAUD B115200 - {B115200, 115200}, #endif -}; - -int -baudrate(void) -{ -int i, ret; - - T(("baudrate() called")); + if (SP) { + SP->_fifohead = -1; + SP->_fifotail = 0; + SP->_fifopeek = 0; + } + returnCode(OK); -#ifdef TERMIOS - ret = cfgetospeed(&cur_term->Nttyb); -#else - ret = cur_term->Nttyb.sg_ospeed; -#endif - if(ret < 0 || ret > MAX_BAUD) - return ERR; - SP->_baudrate = ERR; - for (i = 0; i < (sizeof(speeds) / sizeof(struct speed)); i++) - if (speeds[i].s == ret) - { - SP->_baudrate = speeds[i].sp; - break; - } - return(SP->_baudrate); } - /* ** savetty() and resetty() ** @@ -285,25 +160,16 @@ static TTY buf; int savetty(void) { - T(("savetty() called")); + T((T_CALLED("savetty()"))); -#ifdef TERMIOS - tcgetattr(cur_term->Filedes, &buf); -#else - gtty(cur_term->Filedes, &buf); -#endif - return OK; + GET_TTY(cur_term->Filedes, &buf); + returnCode(OK); } int resetty(void) { - T(("resetty() called")); + T((T_CALLED("resetty()"))); -#ifdef TERMIOS - tcsetattr(cur_term->Filedes, TCSANOW, &buf); -#else - stty(cur_term->Filedes, &buf); -#endif - return OK; + SET_TTY(cur_term->Filedes, &buf); + returnCode(OK); } - diff --git a/lib/libcurses/lib_longname.c b/lib/libcurses/lib_longname.c index 12ff8b0ac93..c53da02d7d0 100644 --- a/lib/libcurses/lib_longname.c +++ b/lib/libcurses/lib_longname.c @@ -27,11 +27,12 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> #ifdef EXTERN_TERMINFO -#include <term.h> +#include <term.h> #endif -#include <string.h> + +MODULE_ID("Id: lib_longname.c,v 1.5 1996/12/21 14:24:06 tom Exp $") char * longname(void) @@ -41,7 +42,7 @@ char *ptr; T(("longname() called")); for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--) - if (*ptr == '|') + if (*ptr == '|') return(ptr + 1); return(ttytype); diff --git a/lib/libcurses/lib_mouse.c b/lib/libcurses/lib_mouse.c index e8f73f65f36..d7ddf67883d 100644 --- a/lib/libcurses/lib_mouse.c +++ b/lib/libcurses/lib_mouse.c @@ -21,7 +21,7 @@ /* * This module is intended to encapsulate ncurses's interface to pointing - * devices. + * devices. * * The first method used is xterm's internal mouse-tracking facility. * The second (not yet implemented) will be Alessandro Rubini's GPM server. @@ -51,10 +51,19 @@ * used yet, and a couple of bits open at the high end. */ -#include <curses.h> -#include <string.h> -#include "term.h" -#include "curses.priv.h" +#include <curses.priv.h> +#include <term.h> + +#if USE_GPM_SUPPORT +#ifndef LINT /* don't need this for llib-lncurses */ +#undef buttons /* term.h defines this, and gpm uses it! */ +#include <gpm.h> +#endif +#endif + +MODULE_ID("Id: lib_mouse.c,v 0.22 1997/02/15 22:33:37 tom Exp $") + +#define MY_TRACE TRACE_ICALLS|TRACE_IEVENT #define INVALID_EVENT -1 @@ -63,7 +72,13 @@ int _nc_max_click_interval = 166; /* max press/release separation */ static int mousetype; #define M_XTERM -1 /* use xterm's mouse tracking? */ #define M_NONE 0 /* no mouse device */ -#define M_GPM 1 /* use GPM (not yet implemented) */ +#define M_GPM 1 /* use GPM */ + +#if USE_GPM_SUPPORT +#ifndef LINT +static Gpm_Connect gpm_connect; +#endif +#endif static mmask_t eventmask; /* current event mask */ @@ -74,17 +89,29 @@ static MEVENT *eventp = events; /* next free slot in event queue */ #define NEXT(ep) ((ep == events + EV_MAX - 1) ? events : ep + 1) #define PREV(ep) ((ep == events) ? events + EV_MAX - 1 : ep - 1) -void _nc_mouse_init(SCREEN *sp) +#ifdef TRACE +static void _trace_slot(const char *tag) +{ + MEVENT *ep; + + _tracef(tag); + + for (ep = events; ep < events + EV_MAX; ep++) + _tracef("mouse event queue slot %d = %s", ep-events, _tracemouse(ep)); +} +#endif + +void _nc_mouse_init(SCREEN *sp GCC_UNUSED) /* initialize the mouse -- called at screen-setup time */ { int i; - T(("_nc_mouse_init() called")); + TR(MY_TRACE, ("_nc_mouse_init() called")); for (i = 0; i < EV_MAX; i++) events[i].id = INVALID_EVENT; -#ifdef EXTERN_TERMINFO +#ifdef EXTERN_TERMINFO /* we know how to recognize mouse events under xterm */ if (!strncmp(cur_term->name, "xterm", 5) && key_mouse) mousetype = M_XTERM; @@ -94,26 +121,85 @@ void _nc_mouse_init(SCREEN *sp) mousetype = M_XTERM; #endif - /* GPM: initialize connection to gpm server */ +#if USE_GPM_SUPPORT + else if (!strncmp(cur_term->type.term_names, "linux", 5)) + { + /* GPM: initialize connection to gpm server */ + gpm_connect.eventMask = GPM_DOWN|GPM_UP; + gpm_connect.defaultMask = ~gpm_connect.eventMask; + gpm_connect.minMod = 0; + gpm_connect.maxMod = ~0; + if (Gpm_Open (&gpm_connect, 0) >= 0) /* returns the file-descriptor */ + mousetype = M_GPM; + } +#endif +} + +int _nc_mouse_fd(void) +{ + if (mousetype == M_XTERM) + return -1; +#if USE_GPM_SUPPORT + else if (mousetype == M_GPM) + return gpm_fd; +#endif + return -1; } -bool _nc_mouse_event(SCREEN *sp) +bool _nc_mouse_event(SCREEN *sp GCC_UNUSED) /* query to see if there is a pending mouse event */ { - /* xterm: never have to query, mouse events are in the keyboard stream */ +#if USE_GPM_SUPPORT /* GPM: query server for event, return TRUE if we find one */ + Gpm_Event ev; + + if (gpm_fd >= 0 + && _nc_timed_wait(2, 0, (int *)0) + && Gpm_GetEvent(&ev) == 1) + { + eventp->id = 0; /* there's only one mouse... */ + + eventp->bstate = 0; + switch (ev.type & 0x0f) + { + case(GPM_DOWN): + if (ev.buttons & GPM_B_LEFT) eventp->bstate |= BUTTON1_PRESSED; + if (ev.buttons & GPM_B_MIDDLE) eventp->bstate |= BUTTON2_PRESSED; + if (ev.buttons & GPM_B_RIGHT) eventp->bstate |= BUTTON3_PRESSED; + break; + case(GPM_UP): + if (ev.buttons & GPM_B_LEFT) eventp->bstate |= BUTTON1_RELEASED; + if (ev.buttons & GPM_B_MIDDLE) eventp->bstate |= BUTTON2_RELEASED; + if (ev.buttons & GPM_B_RIGHT) eventp->bstate |= BUTTON3_RELEASED; + break; + default: + break; + } + + eventp->x = ev.x - 1; + eventp->y = ev.y - 1; + eventp->z = 0; + + /* bump the next-free pointer into the circular list */ + eventp = NEXT(eventp); + return (TRUE); + } +#endif + /* xterm: never have to query, mouse events are in the keyboard stream */ return(FALSE); /* no event waiting */ } bool _nc_mouse_inline(SCREEN *sp) /* mouse report received in the keyboard stream -- parse its info */ { - T(("_nc_mouse_inline() called")); + TR(MY_TRACE, ("_nc_mouse_inline() called")); if (mousetype == M_XTERM) { - char kbuf[4]; + unsigned char kbuf[4]; MEVENT *prev; + size_t grabbed; + int res; /* This code requires that your xterm entry contain the kmous * capability and that it be set to the \E[M documented in the @@ -140,14 +226,20 @@ bool _nc_mouse_inline(SCREEN *sp) * of the mouse event. The upper left corner is (1,1). * * (End quote) By the time we get here, we've eaten the - * key prefix. + * key prefix. FYI, the loop below is necessary because + * mouse click info isn't guaranteed to present as a + * single clist item. It always does under Linux but often + * fails to under Solaris. */ - (void) read(sp->_ifd, &kbuf, 3); + for (grabbed = 0; grabbed < 3; grabbed += res) + { + res = read(sp->_ifd, kbuf + grabbed, 3-grabbed); + if (res == -1) + break; + } kbuf[3] = '\0'; -#ifdef MOUSEDEBUG - T(("_nc_mouse_inline sees the following xterm data: '%s'", kbuf)); -#endif /* MOUSEDEBUG */ + TR(TRACE_IEVENT, ("_nc_mouse_inline sees the following xterm data: '%s'", kbuf)); eventp->id = 0; /* there's only one mouse... */ @@ -172,7 +264,7 @@ bool _nc_mouse_inline(SCREEN *sp) * Release events aren't reported for individual buttons, * just for the button set as a whole... */ - eventp->bstate = + eventp->bstate = (BUTTON1_RELEASED | BUTTON2_RELEASED | BUTTON3_RELEASED); @@ -202,9 +294,9 @@ bool _nc_mouse_inline(SCREEN *sp) eventp->bstate |= BUTTON_CTRL; } - eventp->x = (kbuf[1] - ' ') - 1; - eventp->y = (kbuf[2] - ' ') - 1; - T(("_nc_mouse_inline: primitive mouse-event %s has slot %d", _tracemouse(eventp), eventp - events)); + eventp->x = (kbuf[1] - ' ') - 1; + eventp->y = (kbuf[2] - ' ') - 1; + TR(MY_TRACE, ("_nc_mouse_inline: primitive mouse-event %s has slot %d", _tracemouse(eventp), eventp - events)); /* bump the next-free pointer into the circular list */ eventp = NEXT(eventp); @@ -244,7 +336,8 @@ bool _nc_mouse_parse(int runcount) int n; bool merge; - T(("_nc_mouse_parse() called")); + TR(MY_TRACE, ("_nc_mouse_parse(%d) called", runcount)); + /* * When we enter this routine, the event list next-free pointer * points just past a run of mouse events that we know were separated @@ -256,7 +349,7 @@ bool _nc_mouse_parse(int runcount) * pairs into click events. The second merges runs of click events into * double or triple-click events. * - * It's possible that the run may not resolve to a single event (for + * It's possible that the run may not resolve to a single event (for * example, if the user quadruple-clicks). If so, leading events * in the run are ignored. * @@ -268,9 +361,9 @@ bool _nc_mouse_parse(int runcount) */ if (runcount == 1) { - T(("_nc_mouse_parse: returning simple mouse event %s at slot %d", + TR(MY_TRACE, ("_nc_mouse_parse: returning simple mouse event %s at slot %d", _tracemouse(prev), prev-events)); - return(PREV(prev)->bstate & eventmask); + return (PREV(prev)->id >= 0) ? (PREV(prev)->bstate & eventmask) : 0; } /* find the start of the run */ @@ -278,13 +371,14 @@ bool _nc_mouse_parse(int runcount) for (n = runcount; n > 0; n--) runp = PREV(runp); -#ifdef MOUSEDEBUG - T(("before mouse press/release merge:")); - for (ep = events; ep < events + EV_MAX; ep++) - T(("mouse event queue slot %d = %s", ep-events, _tracemouse(ep))); - T(("_nc_mouse_parse: run starts at %d, ends at %d, count %d", - runp-events, ((eventp - events) + (EV_MAX - 1)) % EV_MAX, runcount)); -#endif /* MOUSEDEBUG */ +#ifdef TRACE + if (_nc_tracing & TRACE_IEVENT) + { + _trace_slot("before mouse press/release merge:"); + _tracef("_nc_mouse_parse: run starts at %d, ends at %d, count %d", + runp-events, ((eventp - events) + (EV_MAX-1)) % EV_MAX, runcount); + } +#endif /* TRACE */ /* first pass; merge press/release pairs */ do { @@ -328,16 +422,17 @@ bool _nc_mouse_parse(int runcount) } } while (merge); - -#ifdef MOUSEDEBUG - T(("before mouse click merges:")); - for (ep = events; ep < events + EV_MAX; ep++) - T(("mouse event queue slot %d = %s", ep-events, _tracemouse(ep))); - T(("_nc_mouse_parse: run starts at %d, ends at %d, count %d", - runp-events, ((eventp - events) + (EV_MAX - 1)) % EV_MAX, runcount)); -#endif /* MOUSEDEBUG */ - - /* + +#ifdef TRACE + if (_nc_tracing & TRACE_IEVENT) + { + _trace_slot("before mouse click merge:"); + _tracef("_nc_mouse_parse: run starts at %d, ends at %d, count %d", + runp-events, ((eventp - events) + (EV_MAX-1)) % EV_MAX, runcount); + } +#endif /* TRACE */ + + /* * Second pass; merge click runs. At this point, click events are * each followed by one invalid event. We merge click events * forward in the queue. @@ -370,7 +465,7 @@ bool _nc_mouse_parse(int runcount) if ((ep->bstate & (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED)) && (follower->bstate & - (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED))) + (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED))) { if ((eventmask & BUTTON1_DOUBLE_CLICKED) && (follower->bstate & BUTTON1_CLICKED)) @@ -399,11 +494,11 @@ bool _nc_mouse_parse(int runcount) /* merge double-click events forward */ if ((ep->bstate & - (BUTTON1_DOUBLE_CLICKED - | BUTTON2_DOUBLE_CLICKED + (BUTTON1_DOUBLE_CLICKED + | BUTTON2_DOUBLE_CLICKED | BUTTON3_DOUBLE_CLICKED)) && (follower->bstate & - (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED))) + (BUTTON1_CLICKED | BUTTON2_CLICKED | BUTTON3_CLICKED))) { if ((eventmask & BUTTON1_TRIPLE_CLICKED) && (follower->bstate & BUTTON1_CLICKED)) @@ -433,13 +528,14 @@ bool _nc_mouse_parse(int runcount) } while (merge); -#ifdef MOUSEDEBUG - T(("before mouse event queue compaction:")); - for (ep = events; ep < events + EV_MAX; ep++) - T(("mouse event queue slot %d = %s", ep-events, _tracemouse(ep))); - T(("_nc_mouse_parse: uncompacted run starts at %d, ends at %d, count %d", - runp-events, ((eventp - events) + (EV_MAX - 1)) % EV_MAX, runcount)); -#endif /* MOUSEDEBUG */ +#ifdef TRACE + if (_nc_tracing & TRACE_IEVENT) + { + _trace_slot("before mouse event queue compaction:"); + _tracef("_nc_mouse_parse: run starts at %d, ends at %d, count %d", + runp-events, ((eventp - events) + (EV_MAX-1)) % EV_MAX, runcount); + } +#endif /* TRACE */ /* * Now try to throw away trailing events flagged invalid, or that @@ -450,16 +546,15 @@ bool _nc_mouse_parse(int runcount) eventp = prev; #ifdef TRACE -#ifdef MOUSEDEBUG - T(("after mouse event queue compaction:")); - for (ep = events; ep < events + EV_MAX; ep++) - T(("mouse event queue slot %d = %s", ep-events, _tracemouse(ep))); - T(("_nc_mouse_parse: compacted run starts at %d, ends at %d, count %d", - runp-events, ((eventp - events) + (EV_MAX - 1)) % EV_MAX, runcount)); -#endif /* MOUSEDEBUG */ + if (_nc_tracing & TRACE_IEVENT) + { + _trace_slot("after mouse event queue compaction:"); + _tracef("_nc_mouse_parse: run starts at %d, ends at %d, count %d", + runp-events, ((eventp - events) + (EV_MAX-1)) % EV_MAX, runcount); + } for (ep = runp; ep != eventp; ep = NEXT(ep)) if (ep->id != INVALID_EVENT) - T(("_nc_mouse_parse: returning composite mouse event %s at slot %d", + TR(MY_TRACE, ("_nc_mouse_parse: returning composite mouse event %s at slot %d", _tracemouse(ep), ep-events)); #endif /* TRACE */ @@ -467,25 +562,22 @@ bool _nc_mouse_parse(int runcount) return(PREV(eventp)->id != INVALID_EVENT); } -void _nc_mouse_wrap(SCREEN *sp) +void _nc_mouse_wrap(SCREEN *sp GCC_UNUSED) /* release mouse -- called by endwin() before shellout/exit */ { - T(("_nc_mouse_wrap() called")); + TR(MY_TRACE, ("_nc_mouse_wrap() called")); /* xterm: turn off reporting */ if (mousetype == M_XTERM && eventmask) - { mouse_activate(FALSE); - eventmask = 0; - } /* GPM: pass all mouse events to next client */ } -void _nc_mouse_resume(SCREEN *sp) +void _nc_mouse_resume(SCREEN *sp GCC_UNUSED) /* re-connect to mouse -- called by doupdate() after shellout */ { - T(("_nc_mouse_resume() called")); + TR(MY_TRACE, ("_nc_mouse_resume() called")); /* xterm: re-enable reporting */ if (mousetype == M_XTERM && eventmask) @@ -503,7 +595,7 @@ void _nc_mouse_resume(SCREEN *sp) int getmouse(MEVENT *aevent) /* grab a copy of the current mouse event */ { - if (mousetype == M_XTERM) + if (aevent && (mousetype == M_XTERM || mousetype == M_GPM)) { /* compute the current-event pointer */ MEVENT *prev = PREV(eventp); @@ -511,10 +603,8 @@ int getmouse(MEVENT *aevent) /* copy the event we find there */ *aevent = *prev; -#ifdef MOUSEDEBUG - T(("getmouse: returning event %s from slot %d", + TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %d", _tracemouse(prev), prev-events)); -#endif /* MOUSEDEBUG */ prev->id = INVALID_EVENT; /* so the queue slot becomes free */ return(OK); @@ -541,14 +631,14 @@ mmask_t mousemask(mmask_t newmask, mmask_t *oldmask) if (oldmask) *oldmask = eventmask; - if (mousetype == M_XTERM) + if (mousetype == M_XTERM || mousetype == M_GPM) { eventmask = newmask & (BUTTON_ALT | BUTTON_CTRL | BUTTON_SHIFT | BUTTON1_PRESSED | BUTTON1_RELEASED | BUTTON1_CLICKED - | BUTTON1_DOUBLE_CLICKED | BUTTON1_TRIPLE_CLICKED + | BUTTON1_DOUBLE_CLICKED | BUTTON1_TRIPLE_CLICKED | BUTTON2_PRESSED | BUTTON2_RELEASED | BUTTON2_CLICKED - | BUTTON2_DOUBLE_CLICKED | BUTTON2_TRIPLE_CLICKED + | BUTTON2_DOUBLE_CLICKED | BUTTON2_TRIPLE_CLICKED | BUTTON3_PRESSED | BUTTON3_RELEASED | BUTTON3_CLICKED | BUTTON3_DOUBLE_CLICKED | BUTTON3_TRIPLE_CLICKED); @@ -563,9 +653,15 @@ mmask_t mousemask(mmask_t newmask, mmask_t *oldmask) bool wenclose(WINDOW *win, int y, int x) /* check to see if given window encloses given screen location */ { - return - (win->_begy <= y && win->_begx <= x - && win->_maxx >= x && win->_maxy >= y); + if (win) + { + y -= win->_yoffset; + return (win->_begy <= y && + win->_begx <= x && + (win->_begx + win->_maxx) >= x && + (win->_begy + win->_maxy) >= y); + } + return FALSE; } int mouseinterval(int maxclick) diff --git a/lib/libcurses/lib_move.c b/lib/libcurses/lib_move.c index 547aa1762e3..3799bb57a8a 100644 --- a/lib/libcurses/lib_move.c +++ b/lib/libcurses/lib_move.c @@ -27,12 +27,14 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_move.c,v 1.6 1997/02/02 00:00:47 tom Exp $") int wmove(WINDOW *win, int y, int x) { - T(("wmove(%p,%d,%d) called", win, y, x)); + T((T_CALLED("wmove(%p,%d,%d)"), win, y, x)); if (x >= 0 && x <= win->_maxx && y >= 0 && y <= win->_maxy) @@ -40,9 +42,9 @@ wmove(WINDOW *win, int y, int x) win->_curx = (short)x; win->_cury = (short)y; - win->_flags &= ~_NEED_WRAP; + win->_flags &= ~_WRAPPED; win->_flags |= _HASMOVED; - return(OK); + returnCode(OK); } else - return(ERR); + returnCode(ERR); } diff --git a/lib/libcurses/lib_mvcur.c b/lib/libcurses/lib_mvcur.c index 2281faf238c..a03a17338c7 100644 --- a/lib/libcurses/lib_mvcur.c +++ b/lib/libcurses/lib_mvcur.c @@ -27,13 +27,15 @@ ** ** void _nc_mvcur_init(void), mvcur_wrap(void) ** +** void _nc_mvcur_resume(void) +** ** int mvcur(int old_y, int old_x, int new_y, int new_x) ** ** void _nc_mvcur_wrap(void) ** ** int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) ** -** Comparisons with older movement optimizers: +** Comparisons with older movement optimizers: ** SVr3 curses mvcur() can't use cursor_to_ll or auto_left_margin. ** 4.4BSD curses can't use cuu/cud/cuf/cub/hpa/vpa/tab/cbt for local ** motions. It doesn't use tactics based on auto_left_margin. Weirdly @@ -54,7 +56,7 @@ ** cuf, cub, cuu1, cud1, cuf1, cub1. It may be that one or more are wrong. ** ** Note: you should expect this code to look like a resource hog in a profile. -** That's because it does a lot of I/O, through the tputs() calls. The I/O +** That's because it does a lot of I/O, through the tputs() calls. The I/O ** cost swamps the computation overhead (and as machines get faster, this ** will become even more true). Comments in the test exerciser at the end ** go into detail about tuning and how you can gauge the optimizer's @@ -128,6 +130,8 @@ * int _cuu_cost; // cost of (parm_cursor_up) * int _hpa_cost; // cost of (column_address) * int _vpa_cost; // cost of (row_address) + * int _ech_cost; // cost of (erase_chars) + * int _rep_cost; // cost of (repeat_char) * * The TABS_OK switch controls whether it is reliable to use tab/backtabs * for local motions. On many systems, it's not, due to uncertainties about @@ -135,11 +139,14 @@ * have parm_right_cursor, tab motions don't win you a lot anyhow. */ -#include "curses.priv.h" -#include "term.h" +#include <curses.priv.h> +#include <term.h> +#include <ctype.h> + +MODULE_ID("Id: lib_mvcur.c,v 1.37 1997/05/03 22:15:26 Peter.Wemm Exp $") + +#define STRLEN(s) (s != 0) ? strlen(s) : 0 -#define NLMAPPING SP->_nl /* nl() on? */ -#define RAWFLAG SP->_raw /* raw() on? */ #define CURRENT_ATTR SP->_current_attr /* current phys attribute */ #define CURRENT_ROW SP->_cursrow /* phys cursor row */ #define CURRENT_COLUMN SP->_curscol /* phys cursor column */ @@ -147,14 +154,6 @@ #define WANT_CHAR(y, x) SP->_newscr->_line[y].text[x] /* desired state */ #define BAUDRATE SP->_baudrate /* bits per second */ -#include <string.h> -#include <ctype.h> -#include <stdlib.h> - -#ifdef TRACE -bool no_optimize; /* suppress optimization */ -#endif /* TRACE */ - #ifdef MAIN #include <sys/time.h> @@ -164,13 +163,10 @@ static float diff; #define OPT_SIZE 512 -static char *address_cursor; -static int carriage_return_length; -static int cursor_home_length; -static int cursor_to_ll_length; - static void save_curs(void); static void restore_curs(void); +static int cost_of(const char *const cap, int affcnt); +static int normalized_cost(const char *const cap, int affcnt); /**************************************************************************** * @@ -178,17 +174,41 @@ static void restore_curs(void); * ****************************************************************************/ -#define INFINITY 1000000 /* too high to use */ +#ifdef TRACE +static int +trace_cost_of(const char *capname, const char *cap, int affcnt) +{ + int result = cost_of(cap,affcnt); + TR(TRACE_CHARPUT|TRACE_MOVE, ("CostOf %s %d", capname, result)); + return result; +} +#define CostOf(cap,affcnt) trace_cost_of(#cap,cap,affcnt); -static int cost(char *cap, int affcnt) +static int +trace_normalized_cost(const char *capname, const char *cap, int affcnt) +{ + int result = normalized_cost(cap,affcnt); + TR(TRACE_CHARPUT|TRACE_MOVE, ("NormalizedCost %s %d", capname, result)); + return result; +} +#define NormalizedCost(cap,affcnt) trace_normalized_cost(#cap,cap,affcnt); + +#else + +#define CostOf(cap,affcnt) cost_of(cap,affcnt); +#define NormalizedCost(cap,affcnt) normalized_cost(cap,affcnt); + +#endif + +static int cost_of(const char *const cap, int affcnt) /* compute the cost of a given operation */ { - if (cap == (char *)NULL) + if (cap == 0) return(INFINITY); else { - char *cp; - float cum_cost = 0; + const char *cp; + float cum_cost = 0; for (cp = cap; *cp; cp++) { @@ -217,29 +237,73 @@ static int cost(char *cap, int affcnt) } } -void _nc_mvcur_init(SCREEN *sp) +static int normalized_cost(const char *const cap, int affcnt) +/* compute the effective character-count for an operation (round up) */ +{ + int cost = cost_of(cap, affcnt); + if (cost != INFINITY) + cost = (cost + SP->_char_padding - 1) / SP->_char_padding; + return cost; +} + +static void reset_scroll_region(void) +/* Set the scroll-region to a known state (the default) */ +{ + if (change_scroll_region) + { + /* change_scroll_region may trash the cursor location */ + save_curs(); + TPUTS_TRACE("change_scroll_region"); + putp(tparm(change_scroll_region, 0, screen_lines - 1)); + restore_curs(); + } +} + +void _nc_mvcur_resume(void) +/* what to do at initialization time and after each shellout */ +{ + /* initialize screen for cursor access */ + if (enter_ca_mode) + { + TPUTS_TRACE("enter_ca_mode"); + putp(enter_ca_mode); + } + + /* + * Doing this here rather than in _nc_mvcur_wrap() ensures that + * ncurses programs will see a reset scroll region even if a + * program that messed with it died ungracefully. + * + * This also undoes the effects of terminal init strings that assume + * they know the screen size. This is useful when you're running + * a vt100 emulation through xterm. + */ + reset_scroll_region(); +} + +void _nc_mvcur_init(void) /* initialize the cost structure */ { /* * 9 = 7 bits + 1 parity + 1 stop. */ - if (BAUDRATE != 0) - SP->_char_padding = (9 * 1000 * 10) / BAUDRATE; - else - SP->_char_padding = 9 * 1000 * 10 / 9600; /* use some default if baudrate == 0 */ + SP->_char_padding = (9 * 1000 * 10) / (BAUDRATE > 0 ? BAUDRATE : 9600); + if (SP->_char_padding <= 0) + SP->_char_padding = 1; /* must be nonzero */ + TR(TRACE_CHARPUT|TRACE_MOVE, ("char_padding %d msecs", SP->_char_padding)); /* non-parameterized local-motion strings */ - SP->_cr_cost = cost(carriage_return, 0); - SP->_home_cost = cost(cursor_home, 0); - SP->_ll_cost = cost(cursor_to_ll, 0); + SP->_cr_cost = CostOf(carriage_return, 0); + SP->_home_cost = CostOf(cursor_home, 0); + SP->_ll_cost = CostOf(cursor_to_ll, 0); #ifdef TABS_OK - SP->_ht_cost = cost(tab, 0); - SP->_cbt_cost = cost(back_tab, 0); + SP->_ht_cost = CostOf(tab, 0); + SP->_cbt_cost = CostOf(back_tab, 0); #endif /* TABS_OK */ - SP->_cub1_cost = cost(cursor_left, 0); - SP->_cuf1_cost = cost(cursor_right, 0); - SP->_cud1_cost = cost(cursor_down, 0); - SP->_cuu1_cost = cost(cursor_up, 0); + SP->_cub1_cost = CostOf(cursor_left, 0); + SP->_cuf1_cost = CostOf(cursor_right, 0); + SP->_cud1_cost = CostOf(cursor_down, 0); + SP->_cuu1_cost = CostOf(cursor_up, 0); /* * Assumption: if the terminal has memory_relative addressing, the @@ -247,7 +311,7 @@ void _nc_mvcur_init(SCREEN *sp) * can treat it like absolute screen addressing. This seems to be true * for all cursor_mem_address terminal types in the terminfo database. */ - address_cursor = cursor_address ? cursor_address : cursor_mem_address; + SP->_address_cursor = cursor_address ? cursor_address : cursor_mem_address; /* * Parametrized local-motion strings. This static cost computation @@ -264,7 +328,7 @@ void _nc_mvcur_init(SCREEN *sp) * digits of parameters. On a 25x80 screen the average is 3.6197. * On larger screens the value gets much closer to 4. * - * (3) The average case of cub/cuf/hpa has 2 digits of parameters + * (3) The average case of cub/cuf/hpa/ech/rep has 2 digits of parameters * (strictly, (((10 * 1) + (70 * 2)) / 80) = 1.8750). * * (4) The average case of cud/cuu/vpa has 2 digits of parameters @@ -273,39 +337,47 @@ void _nc_mvcur_init(SCREEN *sp) * All these averages depend on the assumption that all parameter values * are equally probable. */ - SP->_cup_cost = cost(tparm(address_cursor, 23, 23), 1); - SP->_cub_cost = cost(tparm(parm_left_cursor, 23), 1); - SP->_cuf_cost = cost(tparm(parm_right_cursor, 23), 1); - SP->_cud_cost = cost(tparm(parm_down_cursor, 23), 1); - SP->_cuu_cost = cost(tparm(parm_up_cursor, 23), 1); - SP->_hpa_cost = cost(tparm(column_address, 23), 1); - SP->_vpa_cost = cost(tparm(row_address, 23), 1); - - /* initialize screen for cursor access */ - if (enter_ca_mode) - { - TPUTS_TRACE("enter_ca_mode"); - putp(enter_ca_mode); - } + SP->_cup_cost = CostOf(tparm(SP->_address_cursor, 23, 23), 1); + SP->_cub_cost = CostOf(tparm(parm_left_cursor, 23), 1); + SP->_cuf_cost = CostOf(tparm(parm_right_cursor, 23), 1); + SP->_cud_cost = CostOf(tparm(parm_down_cursor, 23), 1); + SP->_cuu_cost = CostOf(tparm(parm_up_cursor, 23), 1); + SP->_hpa_cost = CostOf(tparm(column_address, 23), 1); + SP->_vpa_cost = CostOf(tparm(row_address, 23), 1); + + /* non-parameterized screen-update strings */ + SP->_ed_cost = NormalizedCost(clr_eos, 1); + SP->_el_cost = NormalizedCost(clr_eol, 1); + SP->_el1_cost = NormalizedCost(clr_bol, 1); + SP->_dch1_cost = NormalizedCost(delete_character, 1); + SP->_ich1_cost = NormalizedCost(insert_character, 1); + + /* parameterized screen-update strings */ + SP->_dch_cost = NormalizedCost(tparm(parm_dch, 23), 1); + SP->_ich_cost = NormalizedCost(tparm(parm_ich, 23), 1); + SP->_ech_cost = NormalizedCost(tparm(erase_chars, 23), 1); + SP->_rep_cost = NormalizedCost(tparm(repeat_char, ' ', 23), 1); + + SP->_cup_ch_cost = NormalizedCost(tparm(SP->_address_cursor, 23, 23), 1); + SP->_hpa_ch_cost = NormalizedCost(tparm(column_address, 23), 1); /* pre-compute some capability lengths */ - carriage_return_length = carriage_return ? strlen(carriage_return) : 0; - cursor_home_length = cursor_home ? strlen(cursor_home) : 0; - cursor_to_ll_length = cursor_to_ll ? strlen(cursor_to_ll) : 0; + SP->_carriage_return_length = STRLEN(carriage_return); + SP->_cursor_home_length = STRLEN(cursor_home); + SP->_cursor_to_ll_length = STRLEN(cursor_to_ll); + + /* + * A different, possibly better way to arrange this would be to set + * SP->_endwin = TRUE at window initialization time and let this be + * called by doupdate's return-from-shellout code. + */ + _nc_mvcur_resume(); } void _nc_mvcur_wrap(void) /* wrap up cursor-addressing mode */ { - /* change_scroll_region may trash the cursor location */ - save_curs(); - if (change_scroll_region) - { - TPUTS_TRACE("change_scroll_region"); - putp(tparm(change_scroll_region, 0, screen_lines - 1)); - } - restore_curs(); - + reset_scroll_region(); if (exit_ca_mode) { TPUTS_TRACE("exit_ca_mode"); @@ -322,14 +394,12 @@ void _nc_mvcur_wrap(void) /* * Perform repeated-append, returning cost */ -static __inline int -repeated_append (int total, int num, int repeat, char *dst, char *src) +static inline int +repeated_append (int total, int num, int repeat, char *dst, const char *src) { register size_t src_len = strlen(src); - register size_t dst_len = 0; + register size_t dst_len = STRLEN(dst); - if (dst) - dst_len = strlen(dst); if ((dst_len + repeat * src_len) < OPT_SIZE-1) { total += (num * repeat); if (dst) { @@ -356,7 +426,6 @@ relative_move(char *result, int from_y,int from_x,int to_y,int to_x, bool ovw) /* move via local motions (cuu/cuu1/cud/cud1/cub1/cub/cuf1/cuf/vpa/hpa) */ { int n, vcost = 0, hcost = 0; - bool used_lf = FALSE; if (result) result[0] = '\0'; @@ -387,8 +456,6 @@ relative_move(char *result, int from_y,int from_x,int to_y,int to_x, bool ovw) { if (result) result[0] = '\0'; - if (cursor_down[0] == '\n') - used_lf = TRUE; vcost = repeated_append(vcost, SP->_cud1_cost, n, result, cursor_down); } } @@ -415,13 +482,6 @@ relative_move(char *result, int from_y,int from_x,int to_y,int to_x, bool ovw) return(INFINITY); } - /* - * It may be that we're using a cud1 capability of \n with the - * side-effect of taking the cursor to column 0. Deal with this. - */ - if (used_lf && NLMAPPING && !RAWFLAG) - from_x = 0; - if (result) result += strlen(result); @@ -473,11 +533,11 @@ relative_move(char *result, int from_y,int from_x,int to_y,int to_x, bool ovw) } #endif /* TABS_OK */ -#if defined(REAL_ATTR) && defined(WANT_CHAR) && 0 +#if defined(REAL_ATTR) && defined(WANT_CHAR) /* * If we have no attribute changes, overwrite is cheaper. * Note: must suppress this by passing in ovw = FALSE whenever - * WANT_CHAR would return invalid data. In particular, this + * WANT_CHAR would return invalid data. In particular, this * is true between the time a hardware scroll has been done * and the time the structure WANT_CHAR would access has been * updated. @@ -582,7 +642,7 @@ relative_move(char *result, int from_y,int from_x,int to_y,int to_x, bool ovw) * the simpler method below. */ -static __inline int +static inline int onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw) /* onscreen move from (yold, xold) to (ynew, xnew) */ { @@ -596,16 +656,16 @@ onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw) #endif /* MAIN */ /* tactic #0: use direct cursor addressing */ - sp = tparm(address_cursor, ynew, xnew); + sp = tparm(SP->_address_cursor, ynew, xnew); if (sp) { tactic = 0; (void) strcpy(use, sp); usecost = SP->_cup_cost; -#ifdef TRACE - if (no_optimize) - xold = yold = -1; +#if defined(TRACE) || defined(NCURSES_TEST) + if (!(_nc_optimize_enable & OPTIMIZE_MVCUR)) + goto nonlocal; #endif /* TRACE */ /* @@ -616,7 +676,7 @@ onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw) * (like, say, local-movement \n getting mapped to some obscure * character because A_ALTCHARSET is on). */ - if (yold == -1 || xold == -1 || + if (yold == -1 || xold == -1 || REAL_ATTR != A_NORMAL || NOT_LOCAL(yold, xold, ynew, xnew)) { #ifdef MAIN @@ -664,7 +724,7 @@ onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw) /* tactic #4: use home-down + local movement */ if (cursor_to_ll - && ((newcost=relative_move(NULL, screen_lines-1, 0, ynew, xnew, ovw)) != INFINITY) + && ((newcost=relative_move(NULL, screen_lines-1, 0, ynew, xnew, ovw)) != INFINITY) && SP->_ll_cost + newcost < usecost) { tactic = 4; @@ -694,19 +754,19 @@ onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw) else if (tactic == 2) { (void) strcpy(use, carriage_return); - (void) relative_move(use + carriage_return_length, + (void) relative_move(use + SP->_carriage_return_length, yold,0,ynew,xnew, ovw); } else if (tactic == 3) { (void) strcpy(use, cursor_home); - (void) relative_move(use + cursor_home_length, + (void) relative_move(use + SP->_cursor_home_length, 0, 0, ynew, xnew, ovw); } else if (tactic == 4) { (void) strcpy(use, cursor_to_ll); - (void) relative_move(use + cursor_to_ll_length, + (void) relative_move(use + SP->_cursor_to_ll_length, screen_lines-1, 0, ynew, xnew, ovw); } else /* if (tactic == 5) */ @@ -766,48 +826,42 @@ int mvcur(int yold, int xold, int ynew, int xnew) l = (xold + 1) / screen_columns; yold += l; - xold %= screen_columns; - if (!auto_right_margin) - { - while (l > 0) { + if (yold >= screen_lines) + l -= (yold - screen_lines - 1); + + while (l > 0) { if (newline) { - TPUTS_TRACE("newline"); - tputs(newline, 0, _nc_outch); + TPUTS_TRACE("newline"); + tputs(newline, 0, _nc_outch); } else - putchar('\n'); + putchar('\n'); l--; - } - xold = 0; - } - if (yold > screen_lines - 1) - { - ynew -= yold - (screen_lines - 1); - yold = screen_lines - 1; + if (xold > 0) + { + if (carriage_return) + { + TPUTS_TRACE("carriage_return"); + tputs(carriage_return, 0, _nc_outch); + } + else + putchar('\r'); + xold = 0; + } } } -#ifdef CURSES_OVERRUN /* not used, it takes us out of sync with curscr */ - /* - * The destination line is offscreen. Try to scroll the screen to - * bring it onscreen. Note: this is not a documented feature of the - * API. It's here for compatibility with archaic curses code, a - * feature no one seems to have actually used in a long time. - */ - if (ynew >= screen_lines) - { - if (mvcur_scrolln((ynew - (screen_lines - 1)), 0, screen_lines - 1, screen_lines - 1) == OK) - ynew = screen_lines - 1; - else - return(ERR); - } -#endif /* CURSES_OVERRUN */ + if (yold > screen_lines - 1) + yold = screen_lines - 1; + if (ynew > screen_lines - 1) + ynew = screen_lines - 1; /* destination location is on screen now */ return(onscreen_mvcur(yold, xold, ynew, xnew, TRUE)); } + /**************************************************************************** * * Cursor save_restore @@ -847,15 +901,11 @@ static void restore_curs(void) * ****************************************************************************/ -int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) +static int DoTheScrolling(int n, int top, int bot, int maxy) /* scroll region from top to bot by n lines */ { int i; - TR(TRACE_MOVE, ("mvcur_scrolln(%d, %d, %d, %d)", n, top, bot, maxy)); - - save_curs(); - /* * This code was adapted from Keith Bostic's hardware scrolling * support for 4.4BSD curses. I (esr) translated it to use terminfo @@ -874,32 +924,22 @@ int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) * BSD curses. BSD curses preferred pairs of il/dl operations * over scrolls, allegedly because il/dl looked faster. We, on * the other hand, prefer scrolls because (a) they're just as fast - * on modern terminals and (b) using them avoids bouncing an + * on many terminals and (b) using them avoids bouncing an * unchanged bottom section of the screen up and down, which is * visually nasty. */ if (n > 0) { /* - * Do explicit clear to end of region if it's possible that the - * terminal might hold on to stuff we push off the end. + * Explicitly clear if stuff pushed off top of region might + * be saved by the terminal. */ - if (non_dest_scroll_region || (memory_below && bot == maxy)) - { - if (bot == maxy && clr_eos) - { - mvcur(-1, -1, lines - n, 0); - TPUTS_TRACE("clr_eos"); - tputs(clr_eos, n, _nc_outch); - } - else if (clr_eol) + if (non_dest_scroll_region || (memory_above && top == 0)) { + for (i = 0; i < n; i++) { - for (i = 0; i < n; i++) - { - mvcur(-1, -1, lines - n + i, 0); - TPUTS_TRACE("clr_eol"); - tputs(clr_eol, n, _nc_outch); - } + mvcur(-1, -1, i, 0); + TPUTS_TRACE("clr_eol"); + tputs(clr_eol, n, _nc_outch); } } @@ -907,47 +947,32 @@ int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) { TPUTS_TRACE("change_scroll_region"); tputs(tparm(change_scroll_region, top, bot), 0, _nc_outch); + onscreen_mvcur(-1, -1, bot, 0, TRUE); + if (parm_index != NULL) { TPUTS_TRACE("parm_index"); tputs(tparm(parm_index, n, 0), n, _nc_outch); } else + { for (i = 0; i < n; i++) { TPUTS_TRACE("scroll_forward"); tputs(scroll_forward, 0, _nc_outch); } + } TPUTS_TRACE("change_scroll_region"); tputs(tparm(change_scroll_region, 0, maxy), 0, _nc_outch); - restore_curs(); - return(OK); } - - /* Scroll up the block. */ - if (parm_index && top == 0) + else if (parm_index && top == 0 && bot == maxy) { onscreen_mvcur(oy, ox, bot, 0, TRUE); TPUTS_TRACE("parm_index"); tputs(tparm(parm_index, n, 0), n, _nc_outch); } - else if (parm_delete_line) - { - onscreen_mvcur(oy, ox, top, 0, TRUE); - TPUTS_TRACE("parm_delete_line"); - tputs(tparm(parm_delete_line, n, 0), n, _nc_outch); - } - else if (delete_line) - { - onscreen_mvcur(oy, ox, top, 0, TRUE); - for (i = 0; i < n; i++) - { - TPUTS_TRACE("parm_index"); - tputs(delete_line, 0, _nc_outch); - } - } - else if (scroll_forward && top == 0) + else if (scroll_forward && top == 0 && bot == maxy) { onscreen_mvcur(oy, ox, bot, 0, TRUE); for (i = 0; i < n; i++) @@ -956,116 +981,167 @@ int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) tputs(scroll_forward, 0, _nc_outch); } } - else - return(ERR); - - /* Push down the bottom region. */ - if (parm_insert_line) - { - onscreen_mvcur(top, 0, bot - n + 1, 0, FALSE); - TPUTS_TRACE("parm_insert_line"); - tputs(tparm(parm_insert_line, n, 0), n, _nc_outch); - } - else if (insert_line) + else if (_nc_idlok + && (parm_delete_line || delete_line) + && (parm_insert_line || insert_line)) { + onscreen_mvcur(oy, ox, top, 0, TRUE); + + if (parm_delete_line) + { + TPUTS_TRACE("parm_delete_line"); + tputs(tparm(parm_delete_line, n, 0), n, _nc_outch); + } + else + { + for (i = 0; i < n; i++) + { + TPUTS_TRACE("parm_index"); + tputs(delete_line, 0, _nc_outch); + } + } + onscreen_mvcur(top, 0, bot - n + 1, 0, FALSE); - for (i = 0; i < n; i++) + + /* Push down the bottom region. */ + if (parm_insert_line) { - TPUTS_TRACE("insert_line"); - tputs(insert_line, 0, _nc_outch); + TPUTS_TRACE("parm_insert_line"); + tputs(tparm(parm_insert_line, n, 0), n, _nc_outch); + } + else + { + for (i = 0; i < n; i++) + { + TPUTS_TRACE("insert_line"); + tputs(insert_line, 0, _nc_outch); + } } } else return(ERR); - restore_curs(); } else /* (n < 0) */ { /* - * Explicitly clear if stuff pushed off top of region might - * be saved by the terminal. + * Do explicit clear to end of region if it's possible that the + * terminal might hold on to stuff we push off the end. */ - if (non_dest_scroll_region || (memory_above && top == 0)) - for (i = 0; i < n; i++) + if (non_dest_scroll_region || (memory_below && bot == maxy)) + { + if (bot == maxy && clr_eos) { - mvcur(-1, -1, i, 0); - TPUTS_TRACE("clr_eol"); - tputs(clr_eol, n, _nc_outch); + mvcur(-1, -1, lines + n, 0); + TPUTS_TRACE("clr_eos"); + tputs(clr_eos, n, _nc_outch); + } + else if (clr_eol) + { + for (i = 0; i < -n; i++) + { + mvcur(-1, -1, lines + n + i, 0); + TPUTS_TRACE("clr_eol"); + tputs(clr_eol, n, _nc_outch); + } } + } if (change_scroll_region && (scroll_reverse || parm_rindex)) { TPUTS_TRACE("change_scroll_region"); tputs(tparm(change_scroll_region, top, bot), 0, _nc_outch); + onscreen_mvcur(-1, -1, top, 0, TRUE); + if (parm_rindex) { TPUTS_TRACE("parm_rindex"); tputs(tparm(parm_rindex, -n, 0), -n, _nc_outch); } else + { for (i = n; i < 0; i++) { TPUTS_TRACE("scroll_reverse"); tputs(scroll_reverse, 0, _nc_outch); } + } TPUTS_TRACE("change_scroll_region"); tputs(tparm(change_scroll_region, 0, maxy), 0, _nc_outch); - restore_curs(); - return(OK); } - - /* Preserve the bottom lines. */ - onscreen_mvcur(oy, ox, bot + n + 1, 0, TRUE); - if (parm_rindex && bot == maxy) + else if (parm_rindex && top == 0 && bot == maxy) { + onscreen_mvcur(oy, ox, bot + n + 1, 0, TRUE); + TPUTS_TRACE("parm_rindex"); tputs(tparm(parm_rindex, -n, 0), -n, _nc_outch); } - else if (parm_delete_line) + else if (scroll_reverse && top == 0 && bot == maxy) { - TPUTS_TRACE("parm_delete_line"); - tputs(tparm(parm_delete_line, -n, 0), -n, _nc_outch); - } - else if (delete_line) - for (i = n; i < 0; i++) - { - TPUTS_TRACE("delete_line"); - tputs(delete_line, 0, _nc_outch); - } - else if (scroll_reverse && bot == maxy) + onscreen_mvcur(-1, -1, 0, 0, TRUE); for (i = n; i < 0; i++) { TPUTS_TRACE("scroll_reverse"); tputs(scroll_reverse, 0, _nc_outch); } - else - return(ERR); - - /* Scroll the block down. */ - if (parm_insert_line) - { - onscreen_mvcur(bot + n + 1, 0, top, 0, FALSE); - TPUTS_TRACE("parm_insert_line"); - tputs(tparm(parm_insert_line, -n, 0), -n, _nc_outch); } - else if (insert_line) + else if (_nc_idlok + && (parm_delete_line || delete_line) + && (parm_insert_line || insert_line)) { + onscreen_mvcur(oy, ox, bot + n + 1, 0, TRUE); + + if (parm_delete_line) + { + TPUTS_TRACE("parm_delete_line"); + tputs(tparm(parm_delete_line, -n, 0), -n, _nc_outch); + } + else + { + for (i = n; i < 0; i++) + { + TPUTS_TRACE("delete_line"); + tputs(delete_line, 0, _nc_outch); + } + } + onscreen_mvcur(bot + n + 1, 0, top, 0, FALSE); - for (i = n; i < 0; i++) + + /* Scroll the block down. */ + if (parm_insert_line) { - TPUTS_TRACE("insert_line"); - tputs(insert_line, 0, _nc_outch); + TPUTS_TRACE("parm_insert_line"); + tputs(tparm(parm_insert_line, -n, 0), -n, _nc_outch); + } + else + { + for (i = n; i < 0; i++) + { + TPUTS_TRACE("insert_line"); + tputs(insert_line, 0, _nc_outch); + } } } else return(ERR); - restore_curs(); } return(OK); } +int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) +/* scroll region from top to bot by n lines */ +{ + int code; + + TR(TRACE_MOVE, ("mvcur_scrolln(%d, %d, %d, %d)", n, top, bot, maxy)); + + save_curs(); + code = DoTheScrolling(n, top, bot, maxy); + restore_curs(); + return(code); +} + #ifdef MAIN /**************************************************************************** * @@ -1073,13 +1149,8 @@ int _nc_mvcur_scrolln(int n, int top, int bot, int maxy) * ****************************************************************************/ -#if HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <string.h> -#include <stdlib.h> -#include "tic.h" -#include "dump_entry.h" +#include <tic.h> +#include <dump_entry.h> char *_nc_progname = "mvcur"; @@ -1125,12 +1196,13 @@ static int roll(int n) int main(int argc, char *argv[]) { - (void) strncpy(tname, getenv("TERM"), sizeof tname-1); + (void) strncpy(tname, getenv("TERM"), sizeof(tname) - 1); + tname[sizeof(tname) - 1] = '\0'; load_term(); - _nc_setupscreen(lines, columns); + _nc_setupscreen(lines, columns, stdout); baudrate(); - _nc_mvcur_init(SP); + _nc_mvcur_init(); #if HAVE_SETVBUF || HAVE_SETBUFFER /* * Undo the effects of our optimization hack, otherwise our interactive @@ -1164,8 +1236,6 @@ int main(int argc, char *argv[]) (void) printf("r[eload] -- reload terminal info for %s\n", getenv("TERM")); (void) puts("l[oad] <term> -- load terminal info for type <term>"); -(void) puts("nl -- assume NL -> CR/LF when computing (default)"); -(void) puts("nonl -- don't assume NL -> CR/LF when computing"); (void) puts("d[elete] <cap> -- delete named capability"); (void) puts("i[nspect] -- display terminal capabilities"); (void) puts("c[ost] -- dump cursor-optimization cost table"); @@ -1201,23 +1271,14 @@ int main(int argc, char *argv[]) } else if (buf[0] == 'r') { - (void) strncpy(tname, getenv("TERM"), sizeof tname-1); + (void) strncpy(tname, getenv("TERM"), sizeof(tname) - 1); + tname[sizeof(tname) - 1] = '\0'; load_term(); } else if (sscanf(buf, "l %s", tname) == 1) { load_term(); } - else if (strncmp(buf, "nl", 2) == 0) - { - NLMAPPING = TRUE; - (void) puts("NL -> CR/LF will be assumed."); - } - else if (strncmp(buf, "nonl", 4) == 0) - { - NLMAPPING = FALSE; - (void) puts("NL -> CR/LF will not be assumed."); - } else if (sscanf(buf, "d %s", capname) == 1) { struct name_table_entry const *np = _nc_find_entry(capname, @@ -1257,18 +1318,18 @@ int main(int argc, char *argv[]) } else if (buf[0] == 'o') { - if (no_optimize) + if (_nc_optime_enable & OPTIMIZE_MVCUR) { - no_optimize = FALSE; - (void) puts("Optimization is now on."); + _nc_optimize_enable &=~ OPTIMIZE_MVCUR; + (void) puts("Optimization is now off."); } else { - no_optimize = TRUE; - (void) puts("Optimization is now off."); + _nc_optimize_enable |= OPTIMIZE_MVCUR; + (void) puts("Optimization is now on."); } } - /* + /* * You can use the `t' test to profile and tune the movement * optimizer. Use iteration values in three digits or more. * At above 5000 iterations the profile timing averages are stable @@ -1297,7 +1358,7 @@ int main(int argc, char *argv[]) xmits = 0; for (i = 0; i < n; i++) { - /* + /* * This does a move test between two random locations, * Random moves probably short-change the optimizer, * which will work better on the short moves probably @@ -1326,13 +1387,13 @@ int main(int argc, char *argv[]) */ perchar = cumtime / n; - (void) printf("%d moves (%ld chars) in %d msec, %f msec each:\n", + (void) printf("%d moves (%ld chars) in %d msec, %f msec each:\n", n, xmits, (int)cumtime, perchar); for (i = 0; speeds[i]; i++) { /* - * Total estimated time for the moves, computation and + * Total estimated time for the moves, computation and * transmission both. Transmission time is an estimate * assuming 9 bits/char, 8 bits + 1 stop bit. */ diff --git a/lib/libcurses/lib_mvwin.c b/lib/libcurses/lib_mvwin.c index f84f6941239..22bdb4a2604 100644 --- a/lib/libcurses/lib_mvwin.c +++ b/lib/libcurses/lib_mvwin.c @@ -28,20 +28,22 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_mvwin.c,v 1.3 1997/02/02 00:20:41 tom Exp $") int mvwin(WINDOW *win, int by, int bx) { - T(("mvwin(%p,%d,%d) called", win, by, bx)); + T((T_CALLED("mvwin(%p,%d,%d)"), win, by, bx)); if (win->_flags & _SUBWIN) - return(ERR); + returnCode(ERR); if (by + win->_maxy > screen_lines - 1 || bx + win->_maxx > screen_columns - 1 || by < 0 || bx < 0) - return(ERR); + returnCode(ERR); /* * Whether or not the window is moved, touch the window's contents so @@ -51,5 +53,5 @@ int mvwin(WINDOW *win, int by, int bx) */ win->_begy = by; win->_begx = bx; - return touchwin(win); + returnCode(touchwin(win)); } diff --git a/lib/libcurses/lib_newterm.c b/lib/libcurses/lib_newterm.c index b2551b56764..06cf4fd668e 100644 --- a/lib/libcurses/lib_newterm.c +++ b/lib/libcurses/lib_newterm.c @@ -24,16 +24,22 @@ /* ** lib_newterm.c ** -** The newterm() function. +** The newterm() function. ** */ -#include "curses.priv.h" -#include <stdlib.h> -#include "term.h" /* clear_screen, cup & friends, cur_term */ +#include <curses.priv.h> -/* This should moved to TERMINAL */ -static filter_mode = FALSE; +#ifdef SVR4_TERMIO +#define _POSIX_SOURCE +#endif + +#include <term.h> /* clear_screen, cup & friends, cur_term */ + +MODULE_ID("Id: lib_newterm.c,v 1.23 1997/03/30 01:42:01 tom Exp $") + +/* This should be moved to TERMINAL */ +static int filter_mode = FALSE; void filter(void) { @@ -47,115 +53,82 @@ int errret; char *t = getenv("NCURSES_TRACE"); if (t) - trace(strtol(t, 0, 0)); + trace((unsigned) strtol(t, 0, 0)); #endif - T(("newterm(\"%s\",%p,%p) called", term, ofp, ifp)); + T((T_CALLED("newterm(\"%s\",%p,%p)"), term, ofp, ifp)); /* this loads the capability entry, then sets LINES and COLS */ - if (setupterm(term, fileno(ofp), &errret) != 1) - return NULL; - - /* optional optimization hack -- do before any output to ofp */ -#if HAVE_SETVBUF || HAVE_SETBUFFER - { - /* - * If the output file descriptor is connected to a tty - * (the typical case) it will probably be line-buffered. - * Keith Bostic pointed out that we don't want this; it - * hoses people running over networks by forcing out a - * bunch of small packets instead of one big one, so - * screen updates on ptys look jerky. Restore block - * buffering to prevent this minor lossage. - * - * The buffer size is a compromise. Ideally we'd like a - * buffer that can hold the maximum possible update size - * (the whole screen plus cup commands to change lines as - * it's painted). On a modern 66-line xterm this can - * become excessive. So we min it with the amount of data - * we think we can get through two Ethernet packets - * (maximum packet size - 100 for TCP/IP overhead). - * - * Why two ethernet packets? It used to be one, on the theory - * that said packets define the maximum size of atomic update. - * But that's less than the 2000 chars on a 25 x 80 screen, and - * we don't want local updates to flicker either. Two packet - * lengths will handle up to a 35 x 80 screen. - * - * The magic '6' is the estimated length of the end-of-line - * cup sequence to go to the next line. It's generous. We - * used to mess with the buffering in init_mvcur() after cost - * computation, but that lost the sequences emitted by init_acs() - * in setupscreen(). - * - * "The setvbuf function may be used only after the stream pointed - * to by stream as been associated with an open file and before any - * other operation is performed on the stream." (ISO 7.9.5.6.) - * - * Grrrr... - */ - unsigned int bufsiz = min(LINES * (COLS + 6), 2800); - -#if HAVE_SETVBUF - /* - * If your code core-dumps here, you are probably running - * some bastard offspring of an SVR3 on which the setvbuffer(3) - * arguments are reversed. Autoconf has a test macro for this - * but I have too much else to do to figure out how it works. - * Send us a patch if you care. - */ - (void) setvbuf(ofp, malloc(bufsiz), _IOFBF, bufsiz); -#elif HAVE_SETBUFFER - (void) setbuffer(ofp, malloc(bufsiz), (int)bufsiz); -#endif + if (setupterm(term, fileno(ofp), &errret) == ERR) + return NULL; + + /* + * Check for mismatched graphic-rendition capabilities. Most SVr4 + * terminfo tree contain entries that have rmul or rmso equated to sgr0 + * (Solaris curses copes with those entries). We do this only for + * curses, since many termcap applications assume that smso/rmso and + * smul/rmul are paired, and will not function properly if we remove + * rmso or rmul. Curses applications shouldn't be looking at this + * detail. + */ + if (exit_attribute_mode) { +#define SGR0_FIX(mode) if (mode != 0 && !strcmp(mode, exit_attribute_mode)) \ + mode = 0 + SGR0_FIX(exit_underline_mode); + SGR0_FIX(exit_standout_mode); } -#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */ /* implement filter mode */ if (filter_mode) { - LINES = 1; + LINES = 1; #ifdef init_tabs - if (init_tabs != -1) - TABSIZE = init_tabs; - else + if (init_tabs != -1) + TABSIZE = init_tabs; + else #endif /* init_tabs */ - TABSIZE = 8; + TABSIZE = 8; - T(("TABSIZE = %d", TABSIZE)); + T(("TABSIZE = %d", TABSIZE)); #ifdef clear_screen - clear_screen = (char *)NULL; - cursor_down = parm_down_cursor = (char *)NULL; - cursor_address = (char *)NULL; - cursor_up = parm_up_cursor = (char *)NULL; - row_address = (char *)NULL; - - cursor_home = carriage_return; + clear_screen = (char *)NULL; + cursor_down = parm_down_cursor = (char *)NULL; + cursor_address = (char *)NULL; + cursor_up = parm_up_cursor = (char *)NULL; + row_address = (char *)NULL; + + cursor_home = carriage_return; #endif /* clear_screen */ } - /* if we must simulate soft labels, grab off the line to be used */ + /* If we must simulate soft labels, grab off the line to be used. + We assume that we must simulate, if it is none of the standard + formats (4-4 or 3-2-3) for which there may be some hardware + support. */ #ifdef num_labels - if (num_labels <= 0) + if (num_labels <= 0 || !SLK_STDFMT) #endif /* num_labels */ - if (_slk_init) - ripoffline(-1, slk_initialize); - - /* this actually allocates the screen structure */ - if (_nc_setupscreen(LINES, COLS) == ERR) - return NULL; + if (_nc_slk_format) + { + if (ERR==_nc_ripoffline(-SLK_LINES, _nc_slk_initialize)) + return NULL; + } + /* this actually allocates the screen structure, and saves the + * original terminal settings. + */ + if (_nc_setupscreen(LINES, COLS, ofp) == ERR) + return NULL; #ifdef num_labels /* if the terminal type has real soft labels, set those up */ - if (_slk_init && num_labels > 0) - slk_initialize(stdscr, COLS); + if (_nc_slk_format && num_labels > 0 && SLK_STDFMT) + _nc_slk_initialize(stdscr, COLS); #endif /* num_labels */ SP->_ifd = fileno(ifp); SP->_checkfd = fileno(ifp); typeahead(fileno(ifp)); - SP->_ofp = ofp; #ifdef TERMIOS SP->_use_meta = ((cur_term->Ottyb.c_cflag & CSIZE) == CS8 && !(cur_term->Ottyb.c_iflag & ISTRIP)); @@ -167,23 +140,16 @@ char *t = getenv("NCURSES_TRACE"); baudrate(); /* sets a field in the SP structure */ /* compute movement costs so we can do better move optimization */ - _nc_mvcur_init(SP); - -#if 0 - /* initialize soft labels */ - if (_slk_init) - if (num_labels <= 0) - ripoffline(-1, slk_initialize); - else - slk_initialize(stdscr, COLS); -#endif + _nc_mvcur_init(); + _nc_signal_handler(TRUE); /* open a connection to the screen's associated mouse, if any */ _nc_mouse_init(SP); - T(("newterm returns %p", SP)); + /* Initialize the terminal line settings. */ + _nc_initscr(); + T((T_RETURN("%p"), SP)); return(SP); } - diff --git a/lib/libcurses/lib_newwin.c b/lib/libcurses/lib_newwin.c index 0fd8d16db36..66269e31638 100644 --- a/lib/libcurses/lib_newwin.c +++ b/lib/libcurses/lib_newwin.c @@ -28,63 +28,94 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_newwin.c,v 1.17 1997/02/15 21:46:05 tom Exp $") + +void _nc_freewin(WINDOW *win) +{ +WINDOWLIST *p, *q; +int i; + + if (win != 0) { + for (p = _nc_windows, q = 0; p != 0; q = p, p = p->next) { + if (p->win == win) { + if (q == 0) + _nc_windows = p->next; + else + q->next = p->next; + free(p); + + if (! (win->_flags & _SUBWIN)) { + for (i = 0; i <= win->_maxy && win->_line[i].text; i++) + free(win->_line[i].text); + } + free(win->_line); + free(win); + + if (win == curscr) curscr = 0; + if (win == stdscr) stdscr = 0; + if (win == newscr) newscr = 0; + + T(("...deleted win=%p", win)); + break; + } + } + } +} WINDOW * newwin(int num_lines, int num_columns, int begy, int begx) { WINDOW *win; chtype *ptr; -int i, j; +int i; + + T((T_CALLED("newwin(%d,%d,%d,%d)"), num_lines, num_columns, begy, begx)); - T(("newwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx)); + if (begy < 0 || begx < 0 || num_lines < 0 || num_columns < 0) + returnWin(0); if (num_lines == 0) - num_lines = screen_lines - begy; + num_lines = SP->_lines_avail - begy; if (num_columns == 0) num_columns = screen_columns - begx; - if (num_columns + begx > SP->_columns || num_lines + begy > SP->_lines) - return NULL; + if (num_columns + begx > SP->_columns || num_lines + begy > SP->_lines_avail) + returnWin(0); - if ((win = _nc_makenew(num_lines, num_columns, begy, begx)) == NULL) - return NULL; + if ((win = _nc_makenew(num_lines, num_columns, begy, begx, 0)) == 0) + returnWin(0); for (i = 0; i < num_lines; i++) { - if ((win->_line[i].text = (chtype *) calloc((unsigned)num_columns, sizeof(chtype))) == NULL) { - for (j = 0; j < i; j++) - free(win->_line[j].text); - - free(win->_line); - free(win); - - return NULL; + if ((win->_line[i].text = typeCalloc(chtype, (unsigned)num_columns)) == 0) { + _nc_freewin(win); + returnWin(0); } - else - for (ptr = win->_line[i].text; ptr < win->_line[i].text + num_columns; ) - *ptr++ = ' '; + for (ptr = win->_line[i].text; ptr < win->_line[i].text + num_columns; ) + *ptr++ = ' '; } T(("newwin: returned window is %p", win)); - return(win); + returnWin(win); } WINDOW * derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx) { WINDOW *win; int i; +int flags = _SUBWIN; - T(("derwin(%p, %d,%d,%d,%d) called", orig, num_lines, num_columns, begy, begx)); + T((T_CALLED("derwin(%p,%d,%d,%d,%d)"), orig, num_lines, num_columns, begy, begx)); /* ** make sure window fits inside the original one */ - if ( begy < 0 || begx < 0) - return NULL; + if ( begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0) + returnWin(0); if ( begy + num_lines > orig->_maxy + 1 || begx + num_columns > orig->_maxx + 1) - return NULL; + returnWin(0); if (num_lines == 0) num_lines = orig->_maxy - begy; @@ -92,8 +123,11 @@ int i; if (num_columns == 0) num_columns = orig->_maxx - begx; - if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, orig->_begx + begx)) == NULL) - return NULL; + if (orig->_flags & _ISPAD) + flags |= _ISPAD; + + if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy, orig->_begx + begx, flags)) == 0) + returnWin(0); win->_pary = begy; win->_parx = begx; @@ -103,40 +137,44 @@ int i; for (i = 0; i < num_lines; i++) win->_line[i].text = &orig->_line[begy++].text[begx]; - win->_flags = _SUBWIN; win->_parent = orig; T(("derwin: returned window is %p", win)); - return(win); + returnWin(win); } WINDOW *subwin(WINDOW *w, int l, int c, int y, int x) { - T(("subwin(%p, %d, %d, %d, %d) called", w, l, c, y, x)); + T((T_CALLED("subwin(%p, %d, %d, %d, %d)"), w, l, c, y, x)); T(("parent has begy = %d, begx = %d", w->_begy, w->_begx)); - return derwin(w, l, c, y - w->_begy, x - w->_begx); + returnWin(derwin(w, l, c, y - w->_begy, x - w->_begx)); } WINDOW * -_nc_makenew(int num_lines, int num_columns, int begy, int begx) +_nc_makenew(int num_lines, int num_columns, int begy, int begx, int flags) { int i; +WINDOWLIST *wp; WINDOW *win; +bool is_pad = (flags & _ISPAD); T(("_nc_makenew(%d,%d,%d,%d)", num_lines, num_columns, begy, begx)); if (num_lines <= 0 || num_columns <= 0) - return NULL; + return 0; - if ((win = (WINDOW *) calloc(1, sizeof(WINDOW))) == NULL) - return NULL; + if ((wp = typeCalloc(WINDOWLIST, 1)) == 0) + return 0; - if ((win->_line = (struct ldat *) calloc((unsigned)num_lines, sizeof (struct ldat))) == NULL) { + if ((win = typeCalloc(WINDOW, 1)) == 0) + return 0; + + if ((win->_line = typeCalloc(struct ldat, ((unsigned)num_lines))) == 0) { free(win); - return NULL; + return 0; } win->_curx = 0; @@ -145,23 +183,24 @@ WINDOW *win; win->_maxx = num_columns - 1; win->_begy = begy; win->_begx = begx; + win->_yoffset = SP->_topstolen; - win->_flags = 0; + win->_flags = flags; win->_attrs = A_NORMAL; - win->_bkgd = A_NORMAL; + win->_bkgd = BLANK; - win->_clear = (num_lines == screen_lines && num_columns == screen_columns); + win->_clear = is_pad ? FALSE : (num_lines == screen_lines && num_columns == screen_columns); win->_idlok = FALSE; win->_idcok = TRUE; win->_scroll = FALSE; win->_leaveok = FALSE; win->_use_keypad = FALSE; - win->_delay = -1; - win->_immed = FALSE; - win->_sync = 0; - win->_parx = -1; - win->_pary = -1; - win->_parent = (WINDOW *)NULL; + win->_delay = -1; + win->_immed = FALSE; + win->_sync = 0; + win->_parx = -1; + win->_pary = -1; + win->_parent = 0; win->_regtop = 0; win->_regbottom = num_lines - 1; @@ -175,11 +214,32 @@ WINDOW *win; for (i = 0; i < num_lines; i++) { - win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE; + /* + * This used to do + * + * win->_line[i].firstchar = win->_line[i].lastchar = _NOCHANGE; + * + * which marks the whole window unchanged. That's how + * SVr1 curses did it, but SVr4 curses marks the whole new + * window changed. + * + * With the old SVr1-like code, say you have stdscr full of + * characters, then create a new window with newwin(), + * then do a printw(win, "foo ");, the trailing spaces are + * completely ignored by the following refreshes. So, you + * get "foojunkjunk" on the screen instead of "foo " as + * you actually intended. + * + * SVr4 doesn't do this. Instead the spaces are actually written. + * So that's how we want ncurses to behave. + */ + win->_line[i].firstchar = 0; + win->_line[i].lastchar = num_columns-1; + win->_line[i].oldindex = i; } - if (begx + num_columns == screen_columns) { + if (!is_pad && (begx + num_columns == screen_columns)) { win->_flags |= _ENDLINE; if (begx == 0 && num_lines == screen_lines && begy == 0) @@ -189,5 +249,11 @@ WINDOW *win; win->_flags |= _SCROLLWIN; } + wp->next = _nc_windows; + wp->win = win; + _nc_windows = wp; + + T((T_CREATE("window %p"), win)); + return(win); } diff --git a/lib/libcurses/lib_options.c b/lib/libcurses/lib_options.c index c2a73db8a7d..be33dd2e446 100644 --- a/lib/libcurses/lib_options.c +++ b/lib/libcurses/lib_options.c @@ -27,121 +27,122 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> -#include "term.h" /* keypad_xmit, keypad_local, meta_on, meta_off */ +#include <curses.priv.h> + +#include <term.h> /* keypad_xmit, keypad_local, meta_on, meta_off */ /* cursor_visible,cursor_normal,cursor_invisible */ +MODULE_ID("Id: lib_options.c,v 1.22 1997/05/01 23:46:18 Alexander.V.Lukyanov Exp $") + int has_ic(void) { - T(("has_ic() called")); - return (insert_character || parm_ich) - && (delete_character || parm_dch); + T((T_CALLED("has_ic()"))); + returnCode((insert_character || parm_ich + || (enter_insert_mode && exit_insert_mode)) + && (delete_character || parm_dch)); } int has_il(void) { - T(("has_il() called")); - return (insert_line || parm_insert_line) - && (delete_line || parm_delete_line); + T((T_CALLED("has_il()"))); + returnCode((insert_line || parm_insert_line) + && (delete_line || parm_delete_line)); } int idlok(WINDOW *win, bool flag) { - T(("idlok(%p,%d) called", win, flag)); + T((T_CALLED("idlok(%p,%d)"), win, flag)); - win->_idlok = flag && (has_il() || change_scroll_region); - return OK; + _nc_idlok = win->_idlok = flag && (has_il() || change_scroll_region); + returnCode(OK); } -int idcok(WINDOW *win, bool flag) +void idcok(WINDOW *win, bool flag) { - T(("idcok(%p,%d) called", win, flag)); + T((T_CALLED("idcok(%p,%d)"), win, flag)); - win->_idcok = flag && has_ic(); + _nc_idcok = win->_idcok = flag && has_ic(); - return OK; + returnVoid; } int clearok(WINDOW *win, bool flag) { - T(("clearok(%p,%d) called", win, flag)); + T((T_CALLED("clearok(%p,%d)"), win, flag)); - if (win == curscr) - newscr->_clear = flag; - else - win->_clear = flag; - return OK; + win->_clear = flag; + returnCode(OK); } -int immedok(WINDOW *win, bool flag) +void immedok(WINDOW *win, bool flag) { - T(("immedok(%p,%d) called", win, flag)); + T((T_CALLED("immedok(%p,%d)"), win, flag)); - win->_immed = flag; - return OK; + win->_immed = flag; + + returnVoid; } int leaveok(WINDOW *win, bool flag) { - T(("leaveok(%p,%d) called", win, flag)); - - win->_leaveok = flag; - if (flag == TRUE) - curs_set(0); - else - curs_set(1); - return OK; + T((T_CALLED("leaveok(%p,%d)"), win, flag)); + + win->_leaveok = flag; + if (flag == TRUE) + curs_set(0); + else + curs_set(1); + returnCode(OK); } int scrollok(WINDOW *win, bool flag) { - T(("scrollok(%p,%d) called", win, flag)); + T((T_CALLED("scrollok(%p,%d)"), win, flag)); - win->_scroll = flag; - return OK; + win->_scroll = flag; + returnCode(OK); } int halfdelay(int t) { - T(("halfdelay(%d) called", t)); + T((T_CALLED("halfdelay(%d)"), t)); if (t < 1 || t > 255) - return ERR; + returnCode(ERR); cbreak(); SP->_cbreak = t+1; - return OK; + returnCode(OK); } int nodelay(WINDOW *win, bool flag) { - T(("nodelay(%p,%d) called", win, flag)); + T((T_CALLED("nodelay(%p,%d)"), win, flag)); - if (flag == TRUE) + if (flag == TRUE) win->_delay = 0; else win->_delay = -1; - return OK; + returnCode(OK); } int notimeout(WINDOW *win, bool f) { - T(("notimout(%p,%d) called", win, f)); + T((T_CALLED("notimout(%p,%d)"), win, f)); win->_notimeout = f; - return OK; + returnCode(OK); } int wtimeout(WINDOW *win, int delay) { - T(("wtimeout(%p,%d) called", win, delay)); + T((T_CALLED("wtimeout(%p,%d)"), win, delay)); win->_delay = delay; - return OK; + returnCode(OK); } static void init_keytry(void); @@ -168,24 +169,24 @@ int _nc_keypad(bool flag) putp(keypad_local); (void) fflush(SP->_ofp); } - + if (SP->_keytry == UNINITIALISED) init_keytry(); - return OK; + return(OK); } int keypad(WINDOW *win, bool flag) { - T(("keypad(%p,%d) called", win, flag)); + T((T_CALLED("keypad(%p,%d)"), win, flag)); - win->_use_keypad = flag; - return (_nc_keypad(flag)); + win->_use_keypad = flag; + returnCode(_nc_keypad(flag)); } -int meta(WINDOW *win, bool flag) +int meta(WINDOW *win GCC_UNUSED, bool flag) { - T(("meta(%p,%d) called", win, flag)); + T((T_CALLED("meta(%p,%d)"), win, flag)); SP->_use_meta = flag; @@ -199,7 +200,7 @@ int meta(WINDOW *win, bool flag) TPUTS_TRACE("meta_off"); putp(meta_off); } - return OK; + returnCode(OK); } /* curs_set() moved here to narrow the kernel interface */ @@ -208,10 +209,13 @@ int curs_set(int vis) { int cursor = SP->_cursor; - T(("curs_set(%d)", vis)); + T((T_CALLED("curs_set(%d)"), vis)); if (vis < 0 || vis > 2) - return ERR; + returnCode(ERR); + + if (vis == cursor) + returnCode(cursor); switch(vis) { case 2: @@ -220,6 +224,8 @@ int cursor = SP->_cursor; TPUTS_TRACE("cursor_visible"); putp(cursor_visible); } + else + returnCode(ERR); break; case 1: if (cursor_normal) @@ -227,6 +233,8 @@ int cursor = SP->_cursor; TPUTS_TRACE("cursor_normal"); putp(cursor_normal); } + else + returnCode(ERR); break; case 0: if (cursor_invisible) @@ -234,10 +242,14 @@ int cursor = SP->_cursor; TPUTS_TRACE("cursor_invisible"); putp(cursor_invisible); } + else + returnCode(ERR); break; } SP->_cursor = vis; - return cursor; + (void) fflush(SP->_ofp); + + returnCode(cursor==-1 ? 1 : cursor); } /* @@ -248,13 +260,17 @@ int cursor = SP->_cursor; */ -static struct try *newtry; +static struct tries *newtry; static void init_keytry(void) { - newtry = NULL; - -#include "keys.tries" + newtry = 0; + +/* LINT_PREPRO +#if 0*/ +#include <keys.tries> +/* LINT_PREPRO +#endif*/ SP->_keytry = newtry; } @@ -263,102 +279,122 @@ static void init_keytry(void) static void add_to_try(char *str, short code) { static bool out_of_memory = FALSE; -struct try *ptr, *savedptr; +struct tries *ptr, *savedptr; if (! str || out_of_memory) - return; + return; + + if (newtry != 0) { + ptr = savedptr = newtry; + + for (;;) { + while (ptr->ch != (unsigned char) *str + && ptr->sibling != 0) + ptr = ptr->sibling; - if (newtry != NULL) { - ptr = savedptr = newtry; - - for (;;) { - while (ptr->ch != (unsigned char) *str - && ptr->sibling != NULL) - ptr = ptr->sibling; - - if (ptr->ch == (unsigned char) *str) { - if (*(++str)) { - if (ptr->child != NULL) - ptr = ptr->child; - else - break; - } else { - ptr->value = code; + if (ptr->ch == (unsigned char) *str) { + if (*(++str)) { + if (ptr->child != 0) + ptr = ptr->child; + else + break; + } else { + ptr->value = code; return; - } + } } else { - if ((ptr->sibling = (struct try *) malloc(sizeof *ptr)) == NULL) { - out_of_memory = TRUE; + if ((ptr->sibling = typeCalloc(struct tries,1)) == 0) { + out_of_memory = TRUE; return; - } - - savedptr = ptr = ptr->sibling; - ptr->child = ptr->sibling = NULL; - if (*str == '\200') - ptr->ch = '\0'; - else - ptr->ch = (unsigned char) *str; - str++; - ptr->value = (short) NULL; - - break; - } - } /* end for (;;) */ - } else { /* newtry == NULL :: First sequence to be added */ - savedptr = ptr = newtry = (struct try *) malloc(sizeof *ptr); - - if (ptr == NULL) { - out_of_memory = TRUE; + } + + savedptr = ptr = ptr->sibling; + if (*str == '\200') + ptr->ch = '\0'; + else + ptr->ch = (unsigned char) *str; + str++; + ptr->value = 0; + + break; + } + } /* end for (;;) */ + } else { /* newtry == 0 :: First sequence to be added */ + savedptr = ptr = newtry = typeCalloc(struct tries,1); + + if (ptr == 0) { + out_of_memory = TRUE; return; - } - - ptr->child = ptr->sibling = NULL; + } + if (*str == '\200') ptr->ch = '\0'; else - ptr->ch = (unsigned char) *str; - str++; - ptr->value = (short) NULL; + ptr->ch = (unsigned char) *str; + str++; + ptr->value = 0; } - - /* at this point, we are adding to the try. ptr->child == NULL */ - + + /* at this point, we are adding to the try. ptr->child == 0 */ + while (*str) { - ptr->child = (struct try *) malloc(sizeof *ptr); - - ptr = ptr->child; - - if (ptr == NULL) { - out_of_memory = TRUE; - + ptr->child = typeCalloc(struct tries,1); + + ptr = ptr->child; + + if (ptr == 0) { + out_of_memory = TRUE; + ptr = savedptr; - while (ptr != NULL) { - savedptr = ptr->child; - free(ptr); - ptr = savedptr; + while (ptr != 0) { + savedptr = ptr->child; + free(ptr); + ptr = savedptr; } - + return; } - - ptr->child = ptr->sibling = NULL; + if (*str == '\200') ptr->ch = '\0'; else - ptr->ch = (unsigned char) *str; - str++; - ptr->value = (short) NULL; + ptr->ch = (unsigned char) *str; + str++; + ptr->value = 0; } - + ptr->value = code; return; } int typeahead(int fd) { - - T(("typeahead(%d) called", fd)); + T((T_CALLED("typeahead(%d)"), fd)); SP->_checkfd = fd; - return OK; + returnCode(OK); } +/* +** has_key() +** +** Return TRUE if the current terminal has the given key +** +*/ + + +static int has_key_internal(int keycode, struct tries *tp) +{ + if (!tp) + return(FALSE); + else if (tp->value == keycode) + return(TRUE); + else + return(has_key_internal(keycode, tp->child) + || has_key_internal(keycode, tp->sibling)); +} + +int has_key(int keycode) +{ + T((T_CALLED("has_key(%d)"), keycode)); + returnCode(has_key_internal(keycode, SP->_keytry)); +} diff --git a/lib/libcurses/lib_overlay.c b/lib/libcurses/lib_overlay.c index 867c2e178d5..a3ce2d6c771 100644 --- a/lib/libcurses/lib_overlay.c +++ b/lib/libcurses/lib_overlay.c @@ -27,14 +27,16 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> -static void overlap(const WINDOW *const s, WINDOW *const d, int const flag) -{ +MODULE_ID("Id: lib_overlay.c,v 1.8 1997/04/24 10:34:38 tom Exp $") + +static int overlap(const WINDOW *const s, WINDOW *const d, int const flag) +{ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; T(("overlap : sby %d, sbx %d, smy %d, smx %d, dby %d, dbx %d, dmy %d, dmx %d", - s->_begy, s->_begx, s->_maxy, s->_maxx, + s->_begy, s->_begx, s->_maxy, s->_maxx, d->_begy, d->_begx, d->_maxy, d->_maxx)); sminrow = max(s->_begy, d->_begy) - s->_begy; smincol = max(s->_begx, d->_begx) - s->_begx; @@ -43,7 +45,9 @@ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; dmaxrow = min(s->_maxy+s->_begy, d->_maxy+d->_begy) - d->_begy; dmaxcol = min(s->_maxx+s->_begx, d->_maxx+d->_begx) - d->_begx; - copywin(s, d, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, flag); + return(copywin(s, d, + sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, + flag)); } /* @@ -58,8 +62,8 @@ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol; int overlay(const WINDOW *win1, WINDOW *win2) { - overlap(win1, win2, TRUE); - return OK; + T((T_CALLED("overlay(%p,%p)"), win1, win2)); + returnCode(overlap(win1, win2, TRUE)); } /* @@ -74,54 +78,54 @@ int overlay(const WINDOW *win1, WINDOW *win2) int overwrite(const WINDOW *win1, WINDOW *win2) { - overlap(win1, win2, FALSE); - return OK; + T((T_CALLED("overwrite(%p,%p)"), win1, win2)); + returnCode(overlap(win1, win2, FALSE)); } -int copywin(const WINDOW *src, WINDOW *dst, +int copywin(const WINDOW *src, WINDOW *dst, int sminrow, int smincol, - int dminrow, int dmincol, int dmaxrow, int dmaxcol, + int dminrow, int dmincol, int dmaxrow, int dmaxcol, int over) { int sx, sy, dx, dy; -int touched; +bool touched; + + T((T_CALLED("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)"), + src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); - T(("copywin(%p, %p, %d, %d, %d, %d, %d, %d, %d)", - src, dst, sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, over)); - /* make sure rectangle exists in source */ if ((sminrow + dmaxrow - dminrow) > (src->_maxy + 1) || (smincol + dmaxcol - dmincol) > (src->_maxx + 1)) { - return ERR; + returnCode(ERR); } T(("rectangle exists in source")); /* make sure rectangle fits in destination */ if (dmaxrow > dst->_maxy || dmaxcol > dst->_maxx) { - return ERR; + returnCode(ERR); } T(("rectangle fits in destination")); for (dy = dminrow, sy = sminrow; dy <= dmaxrow; sy++, dy++) { - touched=0; + touched = FALSE; for(dx=dmincol, sx=smincol; dx <= dmaxcol; sx++, dx++) { if (over) { - if (((src->_line[sy].text[sx] & A_CHARTEXT)!=' ') && + if ((TextOf(src->_line[sy].text[sx]) != ' ') && (dst->_line[dy].text[dx]!=src->_line[sy].text[sx])) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; - touched=1; + touched = TRUE; } } else { if (dst->_line[dy].text[dx] != src->_line[sy].text[sx]) { dst->_line[dy].text[dx] = src->_line[sy].text[sx]; - touched=1; + touched = TRUE; } } } @@ -131,5 +135,5 @@ int touched; } } T(("finished copywin")); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_pad.c b/lib/libcurses/lib_pad.c index 392305f658d..1d2a6339d39 100644 --- a/lib/libcurses/lib_pad.c +++ b/lib/libcurses/lib_pad.c @@ -27,78 +27,58 @@ * pechochar -- add a char to a pad and refresh */ -#include "curses.priv.h" +#include <curses.priv.h> -#include <stdlib.h> -#include <errno.h> - -#if !HAVE_EXTERN_ERRNO -extern int errno; -#endif +MODULE_ID("Id: lib_pad.c,v 1.18 1997/04/12 17:42:52 tom Exp $") WINDOW *newpad(int l, int c) { WINDOW *win; chtype *ptr; -int i, j; +int i; - T(("newpad(%d, %d) called", l, c)); + T((T_CALLED("newpad(%d, %d)"), l, c)); if (l <= 0 || c <= 0) - return NULL; - - if ((win = _nc_makenew(l,c,0,0)) == NULL) - return NULL; + returnWin(0); - win->_flags |= _ISPAD; + if ((win = _nc_makenew(l,c,0,0,_ISPAD)) == NULL) + returnWin(0); for (i = 0; i < l; i++) { win->_line[i].oldindex = _NEWINDEX; - if ((win->_line[i].text = (chtype *) calloc((size_t)c, sizeof(chtype))) == NULL) { - for (j = 0; j < i; j++) - free(win->_line[j].text); - - free(win->_line); - free(win); - - errno = ENOMEM; - return NULL; + if ((win->_line[i].text = typeCalloc(chtype, ((size_t)c))) == 0) { + _nc_freewin(win); + returnWin(0); } - else - for (ptr = win->_line[i].text; ptr < win->_line[i].text + c; ) - *ptr++ = ' '; + for (ptr = win->_line[i].text; ptr < win->_line[i].text + c; ) + *ptr++ = ' '; } - T(("newpad: returned window is %p", win)); - - return(win); + returnWin(win); } WINDOW *subpad(WINDOW *orig, int l, int c, int begy, int begx) { WINDOW *win; - T(("subpad(%d, %d) called", l, c)); - - if ((win = derwin(orig, l, c, begy, begx)) == NULL) - return NULL; - - win->_flags |= _ISPAD; + T((T_CALLED("subpad(%d, %d)"), l, c)); - T(("subpad: returned window is %p", win)); + if (!(orig->_flags & _ISPAD) || ((win = derwin(orig, l, c, begy, begx)) == NULL)) + returnWin(0); - return(win); + returnWin(win); } int prefresh(WINDOW *win, int pminrow, int pmincol, int sminrow, int smincol, int smaxrow, int smaxcol) { - T(("prefresh() called")); + T((T_CALLED("prefresh()"))); if (pnoutrefresh(win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol) != ERR && doupdate() != ERR) { - return OK; + returnCode(OK); } - return ERR; + returnCode(ERR); } int pnoutrefresh(WINDOW *win, int pminrow, int pmincol, @@ -111,14 +91,14 @@ short pmaxcol; short displaced; bool wide; - T(("pnoutrefresh(%p, %d, %d, %d, %d, %d, %d) called", + T((T_CALLED("pnoutrefresh(%p, %d, %d, %d, %d, %d, %d)"), win, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol)); if (win == 0) - return ERR; + returnCode(ERR); if (!(win->_flags & _ISPAD)) - return ERR; + returnCode(ERR); /* negative values are interpreted as zero */ if (pminrow < 0) pminrow = 0; @@ -126,20 +106,29 @@ bool wide; if (sminrow < 0) sminrow = 0; if (smincol < 0) smincol = 0; - if (smaxrow > screen_lines - || smaxcol > screen_columns - || sminrow > smaxrow - || smincol > smaxcol) - return ERR; - pmaxrow = pminrow + smaxrow - sminrow; pmaxcol = pmincol + smaxcol - smincol; T((" pminrow + smaxrow - sminrow %d, win->_maxy %d", pmaxrow, win->_maxy)); T((" pmincol + smaxcol - smincol %d, win->_maxx %d", pmaxcol, win->_maxx)); - if ((pmaxrow > win->_maxy) - || (pmaxcol > win->_maxx)) - return ERR; + + /* + * Trim the caller's screen size back to the actual limits. + */ + if (pmaxrow > win->_maxy) { + smaxrow -= (pmaxrow - win->_maxy); + pmaxrow = pminrow + smaxrow - sminrow; + } + if (pmaxcol > win->_maxx) { + smaxcol -= (pmaxcol - win->_maxx); + pmaxcol = pmincol + smaxcol - smincol; + } + + if (smaxrow > screen_lines + || smaxcol > screen_columns + || sminrow > smaxrow + || smincol > smaxcol) + returnCode(ERR); T(("pad being refreshed")); @@ -166,47 +155,49 @@ bool wide; */ wide = (sminrow <= 1 && win->_maxx >= (newscr->_maxx - 1)); - for (i = pminrow, m = sminrow; i <= pmaxrow; i++, m++) { + for (i = pminrow, m = sminrow + win->_yoffset; + i <= pmaxrow && m <= newscr->_maxy; + i++, m++) { register struct ldat *nline = &newscr->_line[m]; register struct ldat *oline = &win->_line[i]; for (j = pmincol, n = smincol; j <= pmaxcol; j++, n++) { - if (oline->text[j] != nline->text[n]) { + if (oline->text[j] != nline->text[n]) { nline->text[n] = oline->text[j]; if (nline->firstchar == _NOCHANGE) - nline->firstchar = nline->lastchar = n; + nline->firstchar = nline->lastchar = n; else if (n < nline->firstchar) - nline->firstchar = n; + nline->firstchar = n; else if (n > nline->lastchar) - nline->lastchar = n; + nline->lastchar = n; } } - if (wide) { - int nind = m + displaced; - if (oline->oldindex < 0 - || nind < sminrow - || nind > smaxrow) - nind = _NEWINDEX; - - nline->oldindex = nind; - } + if (wide) { + int nind = m + displaced; + if (oline->oldindex < 0 + || nind < sminrow + || nind > smaxrow) + nind = _NEWINDEX; + + nline->oldindex = nind; + } oline->firstchar = oline->lastchar = _NOCHANGE; oline->oldindex = i; } - /* - * Clean up debris from scrolling or resizing the pad, so we do not - * accidentally pick up the index value during the next call to this - * procedure. The only rows that should have an index value are those - * that are displayed during this cycle. - */ - for (i = pminrow-1; (i >= 0) && (win->_line[i].oldindex >= 0); i--) - win->_line[i].oldindex = _NEWINDEX; - for (i = pmaxrow+1; (i <= win->_maxy) && (win->_line[i].oldindex >= 0); i++) - win->_line[i].oldindex = _NEWINDEX; - + /* + * Clean up debris from scrolling or resizing the pad, so we do not + * accidentally pick up the index value during the next call to this + * procedure. The only rows that should have an index value are those + * that are displayed during this cycle. + */ + for (i = pminrow-1; (i >= 0) && (win->_line[i].oldindex >= 0); i--) + win->_line[i].oldindex = _NEWINDEX; + for (i = pmaxrow+1; (i <= win->_maxy) && (win->_line[i].oldindex >= 0); i++) + win->_line[i].oldindex = _NEWINDEX; + win->_begx = smincol; win->_begy = sminrow; @@ -224,13 +215,13 @@ bool wide; && win->_curx >= pmincol && win->_cury <= pmaxrow && win->_curx <= pmaxcol) { - newscr->_cury = win->_cury - pminrow + win->_begy; + newscr->_cury = win->_cury - pminrow + win->_begy + win->_yoffset; newscr->_curx = win->_curx - pmincol + win->_begx; } win->_flags &= ~_HASMOVED; /* - * Update our cache of the line-numbers that we displayed from the pad. + * Update our cache of the line-numbers that we displayed from the pad. * We will use this on subsequent calls to this function to derive * values to stuff into 'oldindex[]' -- for scrolling optimization. */ @@ -241,18 +232,17 @@ bool wide; win->_pad._pad_bottom = smaxrow; win->_pad._pad_right = smaxcol; - return OK; + returnCode(OK); } int pechochar(WINDOW *pad, chtype ch) { - T(("echochar(%p, %lx)", pad, ch)); + T((T_CALLED("pechochar(%p, %s)"), pad, _tracechtype(ch))); if (pad->_flags & _ISPAD) - return ERR; + returnCode(ERR); waddch(curscr, ch); doupdate(); - return OK; + returnCode(OK); } - diff --git a/lib/libcurses/lib_print.c b/lib/libcurses/lib_print.c new file mode 100644 index 00000000000..31c10ade575 --- /dev/null +++ b/lib/libcurses/lib_print.c @@ -0,0 +1,84 @@ + +/*************************************************************************** +* COPYRIGHT NOTICE * +**************************************************************************** +* ncurses is copyright (C) 1992-1995 * +* Zeyd M. Ben-Halim * +* zmbenhal@netcom.com * +* Eric S. Raymond * +* esr@snark.thyrsus.com * +* * +* Permission is hereby granted to reproduce and distribute ncurses * +* by any means and for any fee, whether alone or as part of a * +* larger distribution, in source or in binary form, PROVIDED * +* this notice is included with any such distribution, and is not * +* removed from any of its header files. Mention of ncurses in any * +* applications linked with it is highly appreciated. * +* * +* ncurses comes AS IS with no warranty, implied or expressed. * +* * +***************************************************************************/ + + +#include <curses.priv.h> + +#include <term.h> + +MODULE_ID("Id: lib_print.c,v 1.8 1996/12/21 14:24:06 tom Exp $") + +int mcprint(char *data, int len) +/* ship binary character data to the printer via mc4/mc5/mc5p */ +{ + char *mybuf, *switchon; + size_t onsize, offsize, res; + + errno = 0; + if (!prtr_non && (!prtr_on || !prtr_off)) + { + errno = ENODEV; + return(ERR); + } + + if (prtr_non) + { + switchon = tparm(prtr_non, len); + onsize = strlen(switchon); + offsize = 0; + } + else + { + switchon = prtr_on; + onsize = strlen(prtr_on); + offsize = strlen(prtr_off); + } + + if ((mybuf = malloc(onsize + len + offsize + 1)) == (char *)NULL) + { + errno = ENOMEM; + return(ERR); + } + + (void) strcpy(mybuf, switchon); + memcpy(mybuf + onsize, data, len); + if (offsize) + (void) strcpy(mybuf + onsize + len, prtr_off); + + /* + * We're relying on the atomicity of UNIX writes here. The + * danger is that output from a refresh() might get interspersed + * with the printer data after the write call returns but before the + * data has actually been shipped to the terminal. If the write(2) + * operation is truly atomic we're protected from this. + */ + res = write(cur_term->Filedes, mybuf, onsize + len + offsize); + + /* + * By giving up our scheduler slot here we increase the odds that the + * kernel will ship the contiguous clist items from the last write + * immediately. + */ + (void) sleep(0); + + free(mybuf); + return(res); +} diff --git a/lib/libcurses/lib_printw.c b/lib/libcurses/lib_printw.c index 22ad9c7cd8b..71bda665d80 100644 --- a/lib/libcurses/lib_printw.c +++ b/lib/libcurses/lib_printw.c @@ -28,14 +28,16 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_printw.c,v 1.3 1997/02/16 00:07:23 tom Exp $") int printw(const char *fmt, ...) { va_list argp; char buf[BUFSIZ]; - T(("printw(\"%s\",...) called", fmt)); + T(("printw(%s,...) called", _nc_visbuf(fmt))); va_start(argp, fmt); vsprintf(buf, fmt, argp); @@ -50,7 +52,7 @@ int wprintw(WINDOW *win, const char *fmt, ...) va_list argp; char buf[BUFSIZ]; - T(("wprintw(%p,\"%s\",...) called", win, fmt)); + T(("wprintw(%p,%s,...) called", win, _nc_visbuf(fmt))); va_start(argp, fmt); vsprintf(buf, fmt, argp); diff --git a/lib/libcurses/lib_raw.c b/lib/libcurses/lib_raw.c index 1971f9651bf..4cd1b953678 100644 --- a/lib/libcurses/lib_raw.c +++ b/lib/libcurses/lib_raw.c @@ -38,136 +38,274 @@ * */ -#include "curses.priv.h" -#include "term.h" /* cur_term */ +#include <curses.priv.h> +#include <term.h> /* cur_term */ -/* - * COOKED_INPUT defines the collection of input mode bits to be - * cleared when entering raw mode, then re-set by noraw(). - * - * We used to clear ISTRIP and INPCK when going to raw mode. Keith - * Bostic says that's wrong, because those are hardware bits that the - * user has to get right in his/her initial environment -- he says - * curses can't do any good by clearing these, and may do harm. In - * 1995's world of 8N1 connections over error-correcting modems, all - * the parity-check stuff is pretty nearly irrelevant anyway. - * - * What's supposed to happen when noraw() executes has never been very - * well-defined. Yes, it should reset ISIG/ICANON/OPOST (historical - * practice is for it to attempt to take the driver back to cooked - * mode, rather going to some half-baked cbreak-like intermediate - * level). - * - * We make a design choice here to turn off CR/LF translation a la BSD - * when raw() is enabled, on the theory that a programmer requesting - * raw() ideally wants an 8-bit data stream that's been messed with as - * little as possible. The man pages document this. - * - * We originally opted for the simplest way to handle noraw(); just set all - * the flags we cleared. Unfortunately, having noraw() set IGNCR - * turned out to be too painful. So raw() now clears the COOKED_INPUT - * flags, but also clears (ICRNL|INLCR|IGNCR) which noraw() doesn't - * restore. - * - * Unfortunately, this means noraw() may still force some COOKED_INPUT - * flags on that the user had initially cleared via stty. It'll all - * come out in the wash when endwin() restores the user's original - * input bits (we hope...) - * - */ -#define COOKED_INPUT (IXON|IGNBRK|BRKINT|PARMRK) +MODULE_ID("Id: lib_raw.c,v 1.16 1997/02/02 00:02:32 tom Exp $") + +#ifdef SVR4_TERMIO +#define _POSIX_SOURCE +#endif + +#if HAVE_SYS_TERMIO_H +#include <sys/termio.h> /* needed for ISC */ +#endif + +/* may be undefined if we're using termio.h */ +#ifndef TOSTOP +#define TOSTOP 0 +#endif +#ifndef IEXTEN +#define IEXTEN 0 +#endif + +#define COOKED_INPUT (IXON|BRKINT|PARMRK) + +#ifdef TRACE +char *_tracebits(void) +/* describe the state of the terminal control bits exactly */ +{ +static char buf[BUFSIZ]; +static const struct {unsigned int val; const char *name;} + +#ifdef TERMIOS +iflags[] = + { + {BRKINT, "BRKINT"}, + {IGNBRK, "IGNBRK"}, + {IGNPAR, "IGNPAR"}, + {PARMRK, "PARMRK"}, + {INPCK, "INPCK"}, + {ISTRIP, "ISTRIP"}, + {INLCR, "INLCR"}, + {IGNCR, "IGNC"}, + {ICRNL, "ICRNL"}, + {IXON, "IXON"}, + {IXOFF, "IXOFF"}, + {0, NULL} +#define ALLIN (BRKINT|IGNBRK|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF) + }, +oflags[] = + { + {OPOST, "OPOST"}, + {0, NULL} +#define ALLOUT (OPOST) + }, +cflags[] = + { + {CLOCAL, "CLOCAL"}, + {CREAD, "CREAD"}, + {CSIZE, "CSIZE"}, + {CSTOPB, "CSTOPB"}, + {HUPCL, "HUPCL"}, + {PARENB, "PARENB"}, + {PARODD|PARENB, "PARODD"}, /* concession to readability */ + {0, NULL} +#define ALLCTRL (CLOCAL|CREAD|CSIZE|CSTOPB|HUPCL|PARENB|PARODD) + }, +lflags[] = + { + {ECHO, "ECHO"}, + {ECHOE|ECHO, "ECHOE"}, /* concession to readability */ + {ECHOK|ECHO, "ECHOK"}, /* concession to readability */ + {ECHONL, "ECHONL"}, + {ICANON, "ICANON"}, + {ISIG, "ISIG"}, + {NOFLSH, "NOFLSH"}, +#if TOSTOP != 0 + {TOSTOP, "TOSTOP"}, +#endif +#if IEXTEN != 0 + {IEXTEN, "IEXTEN"}, +#endif + {0, NULL} +#define ALLLOCAL (ECHO|ECHONL|ICANON|ISIG|NOFLSH|TOSTOP|IEXTEN) + }, + *sp; + + if (cur_term->Nttyb.c_iflag & ALLIN) + { + (void) strcpy(buf, "iflags: {"); + for (sp = iflags; sp->val; sp++) + if ((cur_term->Nttyb.c_iflag & sp->val) == sp->val) + { + (void) strcat(buf, sp->name); + (void) strcat(buf, ", "); + } + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; + (void) strcat(buf,"} "); + } + + if (cur_term->Nttyb.c_oflag & ALLOUT) + { + (void) strcat(buf, "oflags: {"); + for (sp = oflags; sp->val; sp++) + if ((cur_term->Nttyb.c_oflag & sp->val) == sp->val) + { + (void) strcat(buf, sp->name); + (void) strcat(buf, ", "); + } + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; + (void) strcat(buf,"} "); + } + + if (cur_term->Nttyb.c_cflag & ALLCTRL) + { + (void) strcat(buf, "cflags: {"); + for (sp = cflags; sp->val; sp++) + if ((cur_term->Nttyb.c_cflag & sp->val) == sp->val) + { + (void) strcat(buf, sp->name); + (void) strcat(buf, ", "); + } + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; + (void) strcat(buf,"} "); + } + + if (cur_term->Nttyb.c_lflag & ALLLOCAL) + { + (void) strcat(buf, "lflags: {"); + for (sp = lflags; sp->val; sp++) + if ((cur_term->Nttyb.c_lflag & sp->val) == sp->val) + { + (void) strcat(buf, sp->name); + (void) strcat(buf, ", "); + } + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; + (void) strcat(buf,"} "); + } + +#else + /* reference: ttcompat(4M) on SunOS 4.1 */ +#ifndef EVENP +#define EVENP 0 +#endif +#ifndef LCASE +#define LCASE 0 +#endif +#ifndef LLITOUT +#define LLITOUT 0 +#endif +#ifndef ODDP +#define ODDP 0 +#endif +#ifndef TANDEM +#define TANDEM 0 +#endif + +cflags[] = + { + {CBREAK, "CBREAK"}, + {CRMOD, "CRMOD"}, + {ECHO, "ECHO"}, + {EVENP, "EVENP"}, + {LCASE, "LCASE"}, + {LLITOUT, "LLITOUT"}, + {ODDP, "ODDP"}, + {RAW, "RAW"}, + {TANDEM, "TANDEM"}, + {XTABS, "XTABS"}, + {0, NULL} +#define ALLCTRL (CBREAK|CRMOD|ECHO|EVENP|LCASE|LLITOUT|ODDP|RAW|TANDEM|XTABS) + }, + *sp; + + if (cur_term->Nttyb.sg_flags & ALLCTRL) + { + (void) strcat(buf, "cflags: {"); + for (sp = cflags; sp->val; sp++) + if ((cur_term->Nttyb.sg_flags & sp->val) == sp->val) + { + (void) strcat(buf, sp->name); + (void) strcat(buf, ", "); + } + if (buf[strlen(buf) - 2] == ',') + buf[strlen(buf) - 2] = '\0'; + (void) strcat(buf,"} "); + } + +#endif + return(buf); +} + +#define BEFORE(N) if (_nc_tracing&TRACE_BITS) _tracef("%s before bits: %s", N, _tracebits()) +#define AFTER(N) if (_nc_tracing&TRACE_BITS) _tracef("%s after bits: %s", N, _tracebits()) +#else +#define BEFORE(s) +#define AFTER(s) +#endif /* TRACE */ int raw(void) { - T(("raw() called")); + T((T_CALLED("raw()"))); SP->_raw = TRUE; SP->_cbreak = TRUE; #ifdef TERMIOS - cur_term->Nttyb.c_lflag &= ~(ICANON|ISIG|IEXTEN); - cur_term->Nttyb.c_iflag &= ~(COOKED_INPUT|ICRNL|INLCR|IGNCR); - cur_term->Nttyb.c_oflag &= ~(OPOST); + BEFORE("raw"); + cur_term->Nttyb.c_lflag &= ~(ICANON|ISIG); + cur_term->Nttyb.c_iflag &= ~(COOKED_INPUT); cur_term->Nttyb.c_cc[VMIN] = 1; cur_term->Nttyb.c_cc[VTIME] = 0; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; + AFTER("raw"); #else cur_term->Nttyb.sg_flags |= RAW; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; #endif + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); + returnCode(OK); } int cbreak(void) { - T(("cbreak() called")); + T((T_CALLED("cbreak()"))); SP->_cbreak = TRUE; #ifdef TERMIOS - cur_term->Nttyb.c_lflag &= ~ICANON; + BEFORE("cbreak"); + cur_term->Nttyb.c_lflag &= ~ICANON; + cur_term->Nttyb.c_iflag &= ~ICRNL; cur_term->Nttyb.c_lflag |= ISIG; cur_term->Nttyb.c_cc[VMIN] = 1; cur_term->Nttyb.c_cc[VTIME] = 0; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; + AFTER("cbreak"); #else cur_term->Nttyb.sg_flags |= CBREAK; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; #endif + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); + returnCode(OK); } int echo(void) { - T(("echo() called")); + T((T_CALLED("echo()"))); SP->_echo = TRUE; - -#ifdef TERMIOS - cur_term->Nttyb.c_lflag |= ECHO; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; -#else - cur_term->Nttyb.sg_flags |= ECHO; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; -#endif + + returnCode(OK); } int nl(void) { - T(("nl() called")); + T((T_CALLED("nl()"))); SP->_nl = TRUE; -#ifdef TERMIOS - /* the code used to set IXON|IXOFF here, Ghod knows why... */ - cur_term->Nttyb.c_iflag |= ICRNL; - cur_term->Nttyb.c_oflag |= OPOST|ONLCR; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; -#else - cur_term->Nttyb.sg_flags |= CRMOD; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; -#endif + returnCode(OK); } int qiflush(void) { - T(("qiflush() called")); + T((T_CALLED("qiflush()"))); /* * Note: this implementation may be wrong. See the comment under @@ -175,107 +313,79 @@ int qiflush(void) */ #ifdef TERMIOS + BEFORE("qiflush"); cur_term->Nttyb.c_lflag &= ~(NOFLSH); - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; + AFTER("qiflush"); + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); else - return OK; + returnCode(OK); #else - return ERR; + returnCode(ERR); #endif } int noraw(void) { - T(("noraw() called")); + T((T_CALLED("noraw()"))); SP->_raw = FALSE; SP->_cbreak = FALSE; #ifdef TERMIOS - cur_term->Nttyb.c_lflag |= ISIG|ICANON|IEXTEN; + BEFORE("noraw"); + cur_term->Nttyb.c_lflag |= ISIG|ICANON; cur_term->Nttyb.c_iflag |= COOKED_INPUT; - cur_term->Nttyb.c_oflag |= OPOST; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; + AFTER("noraw"); #else cur_term->Nttyb.sg_flags &= ~(RAW|CBREAK); - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; #endif - + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); + returnCode(OK); } int nocbreak(void) { - T(("nocbreak() called")); + T((T_CALLED("nocbreak()"))); SP->_cbreak = 0; - + #ifdef TERMIOS + BEFORE("nocbreak"); cur_term->Nttyb.c_lflag |= ICANON; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; -#else + cur_term->Nttyb.c_iflag |= ICRNL; + AFTER("nocbreak"); +#else cur_term->Nttyb.sg_flags &= ~CBREAK; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; #endif + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); + returnCode(OK); } int noecho(void) { - T(("noecho() called")); - + T((T_CALLED("noecho()"))); SP->_echo = FALSE; - -#ifdef TERMIOS - /* - * Turn off ECHONL to avoid having \n still be echoed when - * cooked mode is in effect (that is, ICANON is on). - */ - cur_term->Nttyb.c_lflag &= ~(ECHO|ECHONL); - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; -#else - cur_term->Nttyb.sg_flags &= ~ECHO; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; -#endif + returnCode(OK); } int nonl(void) { - T(("nonl() called")); + T((T_CALLED("nonl()"))); SP->_nl = FALSE; - -#ifdef TERMIOS - cur_term->Nttyb.c_iflag &= ~ICRNL; - cur_term->Nttyb.c_oflag &= ~ONLCR; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; - else - return OK; -#else - cur_term->Nttyb.sg_flags &= ~CRMOD; - stty(cur_term->Filedes, &cur_term->Nttyb); - return OK; -#endif + + returnCode(OK); } int noqiflush(void) { - T(("noqiflush() called")); + T((T_CALLED("noqiflush()"))); /* * Note: this implementation may be wrong. See the comment under @@ -283,19 +393,21 @@ int noqiflush(void) */ #ifdef TERMIOS + BEFORE("noqiflush"); cur_term->Nttyb.c_lflag |= NOFLSH; - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; + AFTER("noqiflush"); + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); else - return OK; + returnCode(OK); #else - return ERR; + returnCode(ERR); #endif } -int intrflush(WINDOW *win, bool flag) +int intrflush(WINDOW *win GCC_UNUSED, bool flag) { - T(("intrflush() called")); + T((T_CALLED("intrflush(%d)"), flag)); /* * This call does the same thing as the qiflush()/noqiflush() @@ -307,16 +419,17 @@ int intrflush(WINDOW *win, bool flag) */ #ifdef TERMIOS + BEFORE("intrflush"); if (flag) cur_term->Nttyb.c_lflag &= ~(NOFLSH); else cur_term->Nttyb.c_lflag |= (NOFLSH); - if((tcsetattr(cur_term->Filedes, TCSANOW, &cur_term->Nttyb)) == -1) - return ERR; + AFTER("intrflush"); + if ((SET_TTY(cur_term->Filedes, &cur_term->Nttyb)) == -1) + returnCode(ERR); else - return OK; + returnCode(OK); #else - return ERR; + returnCode(ERR); #endif } - diff --git a/lib/libcurses/lib_refresh.c b/lib/libcurses/lib_refresh.c index 1dfa1a94355..d2d3c1e008d 100644 --- a/lib/libcurses/lib_refresh.c +++ b/lib/libcurses/lib_refresh.c @@ -28,25 +28,40 @@ * */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_refresh.c,v 1.14 1997/02/02 01:05:26 tom Exp $") int wredrawln(WINDOW *win, int beg, int num) { - T(("wredrawln(%p,%d,%d) called", win, beg, num)); + T((T_CALLED("wredrawln(%p,%d,%d)"), win, beg, num)); touchline(win, beg, num); wrefresh(win); - return OK; + returnCode(OK); } int wrefresh(WINDOW *win) { - T(("wrefresh(%p) called", win)); - - if (win == curscr) - curscr->_clear = TRUE; - else - wnoutrefresh(win); - return(doupdate()); +int code; + + T((T_CALLED("wrefresh(%p)"), win)); + + if (win == curscr) { + curscr->_clear = TRUE; + code = doupdate(); + } else if ((code = wnoutrefresh(win)) == OK) { + if (win->_clear) + newscr->_clear = TRUE; + code = doupdate(); + /* + * Reset the clearok() flag in case it was set for the special + * case in hardscroll.c (if we don't reset it here, we'll get 2 + * refreshes because the flag is copied from stdscr to newscr). + * Resetting the flag shouldn't do any harm, anyway. + */ + win->_clear = FALSE; + } + returnCode(code); } int wnoutrefresh(WINDOW *win) @@ -57,7 +72,18 @@ short begy = win->_begy; short m, n; bool wide; - T(("wnoutrefresh(%p) called", win)); + T((T_CALLED("wnoutrefresh(%p)"), win)); +#ifdef TRACE + if (_nc_tracing & TRACE_UPDATE) + _tracedump("...win", win); +#endif /* TRACE */ + + /* + * This function will break badly if we try to refresh a pad. + */ + if ((win == 0) + || (win->_flags & _ISPAD)) + returnCode(ERR); /* * If 'newscr' has a different background than the window that we're @@ -67,6 +93,7 @@ bool wide; touchwin(win); newscr->_bkgd = win->_bkgd; } + newscr->_attrs = win->_attrs; /* merge in change information from all subwindows of this window */ wsyncdown(win); @@ -95,23 +122,33 @@ bool wide; * common-subexpression chunking to make it really tense, * so we'll force the issue. */ - for (i = 0, m = begy; i <= win->_maxy && m <= newscr->_maxy; i++, m++) { + for (i = 0, m = begy + win->_yoffset; + i <= win->_maxy && m <= newscr->_maxy; + i++, m++) { register struct ldat *nline = &newscr->_line[m]; register struct ldat *oline = &win->_line[i]; if (oline->firstchar != _NOCHANGE) { + int last = oline->lastchar; + + /* limit(j) */ + if (last > win->_maxx) + last = win->_maxx; + /* limit(n) */ + if (last > newscr->_maxx - begx) + last = newscr->_maxx - begx; - for (j = oline->firstchar, n = j + begx; j <= oline->lastchar; j++, n++) { - if (oline->text[j] != nline->text[n]) { + for (j = oline->firstchar, n = j + begx; j <= last; j++, n++) { + if (oline->text[j] != nline->text[n]) { nline->text[n] = oline->text[j]; if (nline->firstchar == _NOCHANGE) - nline->firstchar = nline->lastchar = n; + nline->firstchar = nline->lastchar = n; else if (n < nline->firstchar) - nline->firstchar = n; + nline->firstchar = n; else if (n > nline->lastchar) - nline->lastchar = n; - } + nline->lastchar = n; + } } } @@ -119,7 +156,7 @@ bool wide; if (wide) { int oind = oline->oldindex; - nline->oldindex = (oind == _NEWINDEX) ? _NEWINDEX : begy + oind; + nline->oldindex = (oind == _NEWINDEX) ? _NEWINDEX : begy + oind + win->_yoffset; } oline->firstchar = oline->lastchar = _NOCHANGE; @@ -127,15 +164,17 @@ bool wide; } if (win->_clear) { - win->_clear = FALSE; -#if 0 - newscr->_clear = TRUE; -#endif + win->_clear = FALSE; + newscr->_clear = TRUE; } if (! win->_leaveok) { - newscr->_cury = win->_cury + win->_begy; - newscr->_curx = win->_curx + win->_begx; + newscr->_cury = win->_cury + win->_begy + win->_yoffset; + newscr->_curx = win->_curx + win->_begx; } - return(OK); +#ifdef TRACE + if (_nc_tracing & TRACE_UPDATE) + _tracedump("newscr", newscr); +#endif /* TRACE */ + returnCode(OK); } diff --git a/lib/libcurses/lib_resize.c b/lib/libcurses/lib_resize.c index b1052f042d4..be2f199d78b 100644 --- a/lib/libcurses/lib_resize.c +++ b/lib/libcurses/lib_resize.c @@ -23,7 +23,7 @@ * Note: This code is not part of the SVr4/XSI Curses API! */ -#include "curses.priv.h" +#include <curses.priv.h> #include <stdlib.h> int wresize(WINDOW *win, int new_lines, int new_cols) diff --git a/lib/libcurses/lib_scanw.c b/lib/libcurses/lib_scanw.c index 02d1814ba63..2d61dfeab01 100644 --- a/lib/libcurses/lib_scanw.c +++ b/lib/libcurses/lib_scanw.c @@ -28,8 +28,9 @@ ** */ -#include "curses.priv.h" -#include <stdio.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_scanw.c,v 1.4 1997/02/08 14:45:51 tom Exp $") #if !HAVE_VSSCANF extern int vsscanf(const char *str, const char *format, ...); @@ -41,48 +42,54 @@ char buf[BUFSIZ]; if (wgetstr(win, buf) == ERR) return(ERR); - + return(vsscanf(buf, fmt, argp)); } int scanw(const char *fmt, ...) { +int code; va_list ap; T(("scanw(\"%s\",...) called", fmt)); va_start(ap, fmt); - return(vwscanw(stdscr, fmt, ap)); + code = vwscanw(stdscr, fmt, ap); + va_end(ap); + return (code); } int wscanw(WINDOW *win, const char *fmt, ...) { +int code; va_list ap; T(("wscanw(%p,\"%s\",...) called", win, fmt)); va_start(ap, fmt); - return(vwscanw(win, fmt, ap)); + code = vwscanw(win, fmt, ap); + va_end(ap); + return (code); } - - int mvscanw(int y, int x, const char *fmt, ...) { +int code; va_list ap; va_start(ap, fmt); - return(move(y, x) == OK ? vwscanw(stdscr, fmt, ap) : ERR); + code = (move(y, x) == OK) ? vwscanw(stdscr, fmt, ap) : ERR; + va_end(ap); + return (code); } - - int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...) { +int code; va_list ap; va_start(ap, fmt); - return(wmove(win, y, x) == OK ? vwscanw(win, fmt, ap) : ERR); + code = (wmove(win, y, x) == OK) ? vwscanw(win, fmt, ap) : ERR; + va_end(ap); + return (code); } - - diff --git a/lib/libcurses/lib_screen.c b/lib/libcurses/lib_screen.c index 73b4e63b14e..c99bb4849cc 100644 --- a/lib/libcurses/lib_screen.c +++ b/lib/libcurses/lib_screen.c @@ -20,13 +20,13 @@ ***************************************************************************/ -#include "curses.priv.h" +#include <curses.priv.h> -#include <stdio.h> -#include <sys/types.h> #include <sys/stat.h> #include <time.h> -#include "term.h" /* exit_ca_mode, non_rev_rmcup */ +#include <term.h> /* exit_ca_mode, non_rev_rmcup */ + +MODULE_ID("Id: lib_screen.c,v 1.7 1997/02/02 00:41:10 tom Exp $") static time_t dumptime; @@ -35,12 +35,14 @@ WINDOW *getwin(FILE *filep) WINDOW try, *nwin; int n; + T((T_CALLED("getwin(%p)"), filep)); + (void) fread(&try, sizeof(WINDOW), 1, filep); if (ferror(filep)) - return (WINDOW *)NULL; + returnWin(0); - if ((nwin = newwin(try._maxy+1, try._maxx+1, 0, 0)) == (WINDOW *)NULL) - return (WINDOW *)NULL; + if ((nwin = newwin(try._maxy+1, try._maxx+1, 0, 0)) == 0) + returnWin(0); /* * We deliberately do not restore the _parx, _pary, or _parent @@ -50,21 +52,22 @@ WINDOW *getwin(FILE *filep) nwin->_curx = try._curx; nwin->_cury = try._cury; nwin->_maxy = try._maxy; - nwin->_maxx = try._maxx; + nwin->_maxx = try._maxx; nwin->_begy = try._begy; nwin->_begx = try._begx; - nwin->_flags = try._flags; + nwin->_yoffset = try._yoffset; + nwin->_flags = try._flags & ~(_SUBWIN|_ISPAD); nwin->_attrs = try._attrs; - nwin->_bkgd = try._bkgd; + nwin->_bkgd = try._bkgd; nwin->_clear = try._clear; nwin->_scroll = try._scroll; nwin->_leaveok = try._leaveok; nwin->_use_keypad = try._use_keypad; - nwin->_delay = try._delay; - nwin->_immed = try._immed; - nwin->_sync = try._sync; + nwin->_delay = try._delay; + nwin->_immed = try._immed; + nwin->_sync = try._sync; nwin->_regtop = try._regtop; nwin->_regbottom = try._regbottom; @@ -76,45 +79,49 @@ WINDOW *getwin(FILE *filep) if (ferror(filep)) { delwin(nwin); - return((WINDOW *)NULL); + returnWin(0); } } touchwin(nwin); - return nwin; + returnWin(nwin); } int putwin(WINDOW *win, FILE *filep) { int n; + T((T_CALLED("putwin(%p,%p)"), win, filep)); + (void) fwrite(win, sizeof(WINDOW), 1, filep); if (ferror(filep)) - return ERR; + returnCode(ERR); for (n = 0; n < win->_maxy + 1; n++) { (void) fwrite(win->_line[n].text, sizeof(chtype), (size_t)(win->_maxx + 1), filep); if (ferror(filep)) - return(ERR); + returnCode(ERR); } - return(OK); + returnCode(OK); } int scr_restore(const char *file) { FILE *fp; - if ((fp = fopen(file, "r")) == (FILE *)NULL) - return ERR; + T((T_CALLED("scr_restore(%s)"), _nc_visbuf(file))); + + if ((fp = fopen(file, "r")) == 0) + returnCode(ERR); else { delwin(newscr); newscr = getwin(fp); (void) fclose(fp); - return OK; + returnCode(OK); } } @@ -122,14 +129,16 @@ int scr_dump(const char *file) { FILE *fp; - if ((fp = fopen(file, "w")) == (FILE *)NULL) - return ERR; + T((T_CALLED("scr_dump(%s)"), _nc_visbuf(file))); + + if ((fp = fopen(file, "w")) == 0) + returnCode(ERR); else { (void) putwin(newscr, fp); (void) fclose(fp); dumptime = time((time_t *)0); - return OK; + returnCode(OK); } } @@ -138,34 +147,36 @@ int scr_init(const char *file) FILE *fp; struct stat stb; + T((T_CALLED("scr_init(%s)"), _nc_visbuf(file))); + #ifdef exit_ca_mode if (exit_ca_mode && non_rev_rmcup) - return(ERR); + returnCode(ERR); #endif /* exit_ca_mode */ - if ((fp = fopen(file, "r")) == (FILE *)NULL) - return ERR; + if ((fp = fopen(file, "r")) == 0) + returnCode(ERR); else if (fstat(STDOUT_FILENO, &stb) || stb.st_mtime > dumptime) - return ERR; + returnCode(ERR); else { delwin(curscr); curscr = getwin(fp); (void) fclose(fp); - return OK; + returnCode(OK); } } int scr_set(const char *file) { + T((T_CALLED("scr_set(%s)"), _nc_visbuf(file))); + if (scr_init(file) == ERR) - return(ERR); + returnCode(ERR); else { delwin(newscr); newscr = dupwin(curscr); - return(OK); + returnCode(OK); } } - - diff --git a/lib/libcurses/lib_scroll.c b/lib/libcurses/lib_scroll.c index d8350a38344..4b58bf3468e 100644 --- a/lib/libcurses/lib_scroll.c +++ b/lib/libcurses/lib_scroll.c @@ -30,14 +30,15 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> -#include <string.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_scroll.c,v 1.11 1997/02/01 23:22:54 tom Exp $") void _nc_scroll_window(WINDOW *win, int const n, short const top, short const bottom) { int line, j; -chtype blank = _nc_render(win, ' ', BLANK); +chtype blank = _nc_background(win); +size_t to_copy = (size_t)(sizeof(chtype) * (win->_maxx + 1)); TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %d, %d)", win, n, top,bottom)); @@ -57,7 +58,7 @@ chtype blank = _nc_render(win, ' ', BLANK); for (line = bottom; line >= top-n; line--) { memcpy(win->_line[line].text, win->_line[line+n].text, - (size_t)(sizeof(chtype) * (win->_maxx+1))); + to_copy); win->_line[line].oldindex = win->_line[line+n].oldindex; } for (line = top; line < top-n; line++) { @@ -74,7 +75,7 @@ chtype blank = _nc_render(win, ' ', BLANK); for (line = top; line <= bottom-n; line++) { memcpy(win->_line[line].text, win->_line[line+n].text, - (size_t)(sizeof(chtype) * (win->_maxx+1))); + to_copy); win->_line[line].oldindex = win->_line[line+n].oldindex; } for (line = bottom; line > bottom-n; line--) { @@ -90,21 +91,21 @@ chtype blank = _nc_render(win, ' ', BLANK); int wscrl(WINDOW *win, int n) { - T(("wscrl(%p,%d) called", win, n)); + T((T_CALLED("wscrl(%p,%d)"), win, n)); if (! win->_scroll) - return ERR; + returnCode(ERR); if (n == 0) - return OK; + returnCode(OK); if ((n > (win->_regbottom - win->_regtop)) || (-n > (win->_regbottom - win->_regtop))) - return ERR; + returnCode(ERR); _nc_scroll_window(win, n, win->_regtop, win->_regbottom); touchline(win, win->_regtop, (int)(win->_regbottom - win->_regtop + 1)); _nc_synchook(win); - return OK; + returnCode(OK); } diff --git a/lib/libcurses/lib_scrreg.c b/lib/libcurses/lib_scrreg.c index 6a741304dbe..2c2c3e50a24 100644 --- a/lib/libcurses/lib_scrreg.c +++ b/lib/libcurses/lib_scrreg.c @@ -28,20 +28,22 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_scrreg.c,v 1.5 1997/02/01 23:22:54 tom Exp $") int wsetscrreg(WINDOW *win, int top, int bottom) { - T(("wsetscrreg(%p,%d,%d) called", win, top, bottom)); + T((T_CALLED("wsetscrreg(%p,%d,%d)"), win, top, bottom)); - if (top >= 0 && top <= win->_maxy && + if (top >= 0 && top <= win->_maxy && bottom >= 0 && bottom <= win->_maxy && bottom > top) { - win->_regtop = (short)top; - win->_regbottom = (short)bottom; + win->_regtop = (short)top; + win->_regbottom = (short)bottom; - return(OK); + returnCode(OK); } else - return(ERR); + returnCode(ERR); } diff --git a/lib/libcurses/lib_set_term.c b/lib/libcurses/lib_set_term.c index 6df38903072..a79021906ba 100644 --- a/lib/libcurses/lib_set_term.c +++ b/lib/libcurses/lib_set_term.c @@ -28,73 +28,180 @@ ** */ -#include "curses.priv.h" -#include <stdlib.h> -#include "term.h" /* cur_term */ +#include <curses.priv.h> -struct screen * set_term(struct screen *screen) +#include <term.h> /* cur_term */ + +MODULE_ID("Id: lib_set_term.c,v 1.17 1997/05/01 23:46:18 Alexander.V.Lukyanov Exp $") + +/* + * If the output file descriptor is connected to a tty (the typical case) it + * will probably be line-buffered. Keith Bostic pointed out that we don't want + * this; it hoses people running over networks by forcing out a bunch of small + * packets instead of one big one, so screen updates on ptys look jerky. + * Restore block buffering to prevent this minor lossage. + * + * The buffer size is a compromise. Ideally we'd like a buffer that can hold + * the maximum possible update size (the whole screen plus cup commands to + * change lines as it's painted). On a 66-line xterm this can become + * excessive. So we min it with the amount of data we think we can get through + * two Ethernet packets (maximum packet size - 100 for TCP/IP overhead). + * + * Why two ethernet packets? It used to be one, on the theory that said + * packets define the maximum size of atomic update. But that's less than the + * 2000 chars on a 25 x 80 screen, and we don't want local updates to flicker + * either. Two packet lengths will handle up to a 35 x 80 screen. + * + * The magic '6' is the estimated length of the end-of-line cup sequence to go + * to the next line. It's generous. We used to mess with the buffering in + * init_mvcur() after cost computation, but that lost the sequences emitted by + * init_acs() in setupscreen(). + * + * "The setvbuf function may be used only after the stream pointed to by stream + * has been associated with an open file and before any other operation is + * performed on the stream." (ISO 7.9.5.6.) + * + * Grrrr... + */ +void _nc_set_buffer(FILE *ofp, bool buffered) +{ + /* optional optimization hack -- do before any output to ofp */ +#if HAVE_SETVBUF || HAVE_SETBUFFER + unsigned buf_len; + char *buf_ptr; + + if (buffered) { + buf_len = min(LINES * (COLS + 6), 2800); + buf_ptr = malloc(buf_len); + } else { + buf_len = 0; + buf_ptr = 0; + } + +#if HAVE_SETVBUF +#ifdef SETVBUF_REVERSED /* pre-svr3? */ + (void) setvbuf(ofp, buf_ptr, buf_len, buf_len ? _IOFBF : _IONBF); +#else + (void) setvbuf(ofp, buf_ptr, buf_len ? _IOFBF : _IONBF, buf_len); +#endif +#elif HAVE_SETBUFFER + (void) setbuffer(ofp, buf_ptr, (int)buf_len); +#endif + + if (!buffered) { + FreeIfNeeded(SP->_setbuf); + } + SP->_setbuf = buf_ptr; + +#endif /* HAVE_SETVBUF || HAVE_SETBUFFER */ +} + +SCREEN * set_term(SCREEN *screen) { -struct screen *oldSP; +SCREEN *oldSP; - T(("set_term(%p) called", screen)); + T((T_CALLED("set_term(%p)"), screen)); oldSP = SP; _nc_set_screen(screen); - cur_term = SP->_term; - curscr = SP->_curscr; - newscr = SP->_newscr; - stdscr = SP->_stdscr; + cur_term = SP->_term; + curscr = SP->_curscr; + newscr = SP->_newscr; + stdscr = SP->_stdscr; + COLORS = SP->_color_count; + COLOR_PAIRS = SP->_pair_count; + T((T_RETURN("%p"), oldSP)); return(oldSP); } -void delscreen(SCREEN *sp) +static void _nc_free_keytry(struct tries *kt) { - free(sp); + if (kt != 0) { + _nc_free_keytry(kt->child); + _nc_free_keytry(kt->sibling); + free(kt); + } } -struct ripoff_t +/* + * Free the storage associated with the given SCREEN sp. + */ +void delscreen(SCREEN *sp) { - int line; - int (*hook)(WINDOW *, int); + T((T_CALLED("delscreen(%p)"), sp)); + + _nc_freewin(sp->_curscr); + _nc_freewin(sp->_newscr); + _nc_freewin(sp->_stdscr); + _nc_free_keytry(sp->_keytry); + + FreeIfNeeded(sp->_color_table); + FreeIfNeeded(sp->_color_pairs); + + free(sp); + + /* + * If this was the current screen, reset everything that the + * application might try to use (except cur_term, which may have + * multiple references in different screens). + */ + if (sp == SP) { + curscr = 0; + newscr = 0; + stdscr = 0; + COLORS = 0; + COLOR_PAIRS = 0; + _nc_set_screen(0); + } + returnVoid; } -rippedoff[5], *rsp = rippedoff; -int _nc_setupscreen(short slines, short const scolumns) +ripoff_t rippedoff[5], *rsp = rippedoff; +#define N_RIPS (int)(sizeof(rippedoff)/sizeof(rippedoff[0])) + +int _nc_setupscreen(short slines, short const scolumns, FILE *output) /* OS-independent screen initializations */ { -int stolen, topstolen; +int bottom_stolen = 0, i; if (!_nc_alloc_screen()) - return ERR; - - SP->_term = cur_term; - SP->_lines = slines; - SP->_columns = scolumns; - SP->_cursrow = -1; - SP->_curscol = -1; - SP->_keytry = UNINITIALISED; - SP->_nl = TRUE; - SP->_raw = FALSE; - SP->_cbreak = FALSE; - SP->_echo = TRUE; - SP->_fifohead = -1; - SP->_fifotail = 0; - SP->_fifopeek = 0; - SP->_endwin = TRUE; - SP->_ofp = stdout; /* (may be overridden later) */ - SP->_coloron = 0; - - init_acs(); + return ERR; + + _nc_set_buffer(output, TRUE); + SP->_term = cur_term; + SP->_lines = slines; + SP->_lines_avail = slines; + SP->_columns = scolumns; + SP->_cursrow = -1; + SP->_curscol = -1; + SP->_keytry = UNINITIALISED; + SP->_nl = TRUE; + SP->_raw = FALSE; + SP->_cbreak = FALSE; + SP->_echo = FALSE; + SP->_fifohead = -1; + SP->_fifotail = 0; + SP->_fifopeek = 0; + SP->_endwin = TRUE; + SP->_ofp = output; + SP->_coloron = 0; + SP->_curscr = 0; + SP->_newscr = 0; + SP->_stdscr = 0; + SP->_topstolen = 0; + SP->_cursor = -1; /* cannot know real cursor shape */ + + init_acs(); T(("creating newscr")); - if ((newscr = newwin(slines, scolumns, 0, 0)) == (WINDOW *)NULL) - return ERR; + if ((newscr = newwin(slines, scolumns, 0, 0)) == 0) + return ERR; T(("creating curscr")); - if ((curscr = newwin(slines, scolumns, 0, 0)) == (WINDOW *)NULL) - return ERR; + if ((curscr = newwin(slines, scolumns, 0, 0)) == 0) + return ERR; SP->_newscr = newscr; SP->_curscr = curscr; @@ -102,19 +209,37 @@ int stolen, topstolen; newscr->_clear = TRUE; curscr->_clear = FALSE; - stolen = topstolen = 0; - for (rsp = rippedoff; rsp->line; rsp++) { - if (rsp->hook) - if (rsp->line < 0) - rsp->hook(newwin(1,scolumns, slines-1,0), scolumns); - else - rsp->hook(newwin(1,scolumns, topstolen++,0), scolumns); - --slines; - stolen++; + for (i=0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) { + if (rsp->hook) { + WINDOW *w; + int count = (rsp->line < 0) ? -rsp->line : rsp->line; + + if (rsp->line < 0) { + w = newwin(count,scolumns,SP->_lines_avail - count,0); + if (w) { + rsp->w = w; + rsp->hook(w, scolumns); + bottom_stolen += count; + } + else + return ERR; + } else { + w = newwin(count,scolumns, 0, 0); + if (w) { + rsp->w = w; + rsp->hook(w, scolumns); + SP->_topstolen += count; + } + else + return ERR; + } + SP->_lines_avail -= count; + } } T(("creating stdscr")); - if ((stdscr = newwin(LINES = slines, scolumns, topstolen, 0)) == NULL) + assert ((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines); + if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0) return ERR; SP->_stdscr = stdscr; @@ -124,18 +249,33 @@ int stolen, topstolen; return OK; } +/* The internal implementation interprets line as the number of + lines to rip off from the top or bottom. + */ int -ripoffline(int line, int (*init)(WINDOW *, int)) +_nc_ripoffline(int line, int (*init)(WINDOW *,int)) { if (line == 0) return(OK); - if (rsp >= rippedoff + sizeof(rippedoff)/sizeof(rippedoff[0])) + if (rsp >= rippedoff + N_RIPS) return(ERR); rsp->line = line; rsp->hook = init; + rsp->w = 0; rsp++; return(OK); } + +int +ripoffline(int line, int (*init)(WINDOW *, int)) +{ + T((T_CALLED("ripoffline(%d,%p)"), line, init)); + + if (line == 0) + returnCode(OK); + + returnCode(_nc_ripoffline ((line<0) ? -1 : 1, init)); +} diff --git a/lib/libcurses/lib_slk.c b/lib/libcurses/lib_slk.c index 973a3ab6ae3..6d9869ae2e6 100644 --- a/lib/libcurses/lib_slk.c +++ b/lib/libcurses/lib_slk.c @@ -24,24 +24,29 @@ * Soft key routines. */ -#include "curses.priv.h" -#include <string.h> -#include <stdlib.h> -#include "term.h" /* num_labels, label_*, plab_norm */ +#include <curses.priv.h> -#define MAX_SKEY 8 /* count of soft keys */ -#define MAX_SKEY_LEN 8 /* max length of soft key text */ +#include <ctype.h> +#include <term.h> /* num_labels, label_*, plab_norm */ +MODULE_ID("Id: lib_slk.c,v 1.11 1997/01/18 23:06:32 tom Exp $") + +#define MAX_SKEY_OLD 8 /* count of soft keys */ +#define MAX_SKEY_LEN_OLD 8 /* max length of soft key text */ +#define MAX_SKEY_PC 12 /* This is what most PC's have */ +#define MAX_SKEY_LEN_PC 5 + +#define MAX_SKEY (SLK_STDFMT ? MAX_SKEY_OLD : MAX_SKEY_PC) +#define MAX_SKEY_LEN (SLK_STDFMT ? MAX_SKEY_LEN_OLD : MAX_SKEY_LEN_PC) /* * We'd like to move these into the screen context structure, but cannot, * because slk_init() is called before initscr()/newterm(). */ -int _slk_init; /* TRUE if slk_init() called */ +int _nc_slk_format; /* one more than format specified in slk_init() */ -static int _slk_format; /* format specified in slk_init() */ static chtype _slk_attr = A_STANDOUT; /* soft label attribute */ -static int maxlab; /* number of labels */ -static int maxlen; /* maximum length of label */ +static SLK *_slk; +static void slk_paint_info(WINDOW *win); /* * Fetch the label text. @@ -52,7 +57,7 @@ slk_label(int n) { T(("slk_label(%d)", n)); - if (SP->_slk == NULL || n < 1 || n > MAX_SKEY) + if (SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt) return NULL; return(SP->_slk->ent[n-1].text); } @@ -65,22 +70,27 @@ static void slk_intern_refresh(SLK *slk) { int i; - for (i = 0; i < MAX_SKEY; i++) { + for (i = 0; i < slk->labcnt; i++) { if (slk->dirty || slk->ent[i].dirty) { if (slk->ent[i].visible) { #ifdef num_labels - if (num_labels > 0) + if (num_labels > 0 && SLK_STDFMT) { - TPUTS_TRACE("plab_norm"); - putp(tparm(plab_norm, i, slk->win,slk->ent[i].form_text)); + if (i < num_labels) { + TPUTS_TRACE("plab_norm"); + putp(tparm(plab_norm, i, slk->win,slk->ent[i].form_text)); + } } else #endif /* num_labels */ { - wmove(slk->win,0,slk->ent[i].x); + wmove(slk->win,SLK_LINES-1,slk->ent[i].x); wattrset(slk->win,_slk_attr); - waddstr(slk->win,slk->ent[i].form_text); - wattrset(slk->win,A_NORMAL); + waddnstr(slk->win,slk->ent[i].form_text, MAX_SKEY_LEN); + /* if we simulate SLK's, it's looking much more + natural to use the current ATTRIBUTE also + for the label window */ + wattrset(slk->win,stdscr->_attrs); } } slk->ent[i].dirty = FALSE; @@ -111,7 +121,7 @@ int slk_noutrefresh(void) { T(("slk_noutrefresh()")); - + if (SP->_slk == NULL) return(ERR); if (SP->_slk->hidden) @@ -128,7 +138,7 @@ int slk_refresh(void) { T(("slk_refresh()")); - + if (SP->_slk == NULL) return(ERR); if (SP->_slk->hidden) @@ -145,11 +155,13 @@ int slk_restore(void) { T(("slk_restore()")); - + if (SP->_slk == NULL) return(ERR); SP->_slk->hidden = FALSE; SP->_slk->dirty = TRUE; + /* we have to repaint info line eventually */ + slk_paint_info(SP->_slk->win); return slk_refresh(); } @@ -163,19 +175,31 @@ slk_set(int i, const char *astr, int format) SLK *slk = SP->_slk; size_t len; const char *str = astr; +const char *p; T(("slk_set(%d, \"%s\", %d)", i, str, format)); - if (slk == NULL || i < 1 || i > maxlab || format < 0 || format > 2) + if (slk == NULL || i < 1 || i > slk->labcnt || format < 0 || format > 2) return(ERR); if (str == NULL) str = ""; - --i; - (void) strncpy(slk->ent[i].text, str, (unsigned)maxlen); - memset(slk->ent[i].form_text,' ', (unsigned)maxlen); - slk->ent[i].text[maxlen] = 0; - slk->ent[i].form_text[maxlen] = 0; - len = strlen(slk->ent[i].text); + + while (isspace(*str)) str++; /* skip over leading spaces */ + p = str; + while (isprint(*p)) p++; /* The first non-print stops */ + + --i; /* Adjust numbering of labels */ + + len = (size_t)(p - str); + if (len > (unsigned)slk->maxlen) + len = slk->maxlen; + if (len==0) + slk->ent[i].text[0] = 0; + else + (void) strncpy(slk->ent[i].text, str, len); + memset(slk->ent[i].form_text,' ', (unsigned)slk->maxlen); + slk->ent[i].text[slk->maxlen] = 0; + /* len = strlen(slk->ent[i].text); */ switch(format) { case 0: /* left-justified */ @@ -184,16 +208,17 @@ const char *str = astr; len); break; case 1: /* centered */ - memcpy(slk->ent[i].form_text+(MAX_SKEY_LEN-len)/2, + memcpy(slk->ent[i].form_text+(slk->maxlen - len)/2, slk->ent[i].text, len); break; case 2: /* right-justified */ - memcpy(slk->ent[i].form_text+MAX_SKEY_LEN-len, + memcpy(slk->ent[i].form_text+ slk->maxlen - len, slk->ent[i].text, len); break; } + slk->ent[i].form_text[slk->maxlen] = 0; slk->ent[i].dirty = TRUE; return(OK); } @@ -206,7 +231,7 @@ int slk_touch(void) { T(("slk_touch()")); - + if (SP->_slk == NULL) return(ERR); SP->_slk->dirty = TRUE; @@ -221,69 +246,155 @@ int slk_clear(void) { T(("slk_clear()")); - + if (SP->_slk == NULL) return(ERR); SP->_slk->hidden = TRUE; + /* For simulated SLK's it's looks much more natural to + inherit those attributes from the standard screen */ + SP->_slk->win->_bkgd = stdscr->_bkgd; + SP->_slk->win->_attrs = stdscr->_attrs; werase(SP->_slk->win); return wrefresh(SP->_slk->win); } /* + * Paint the info line for the PC style SLK emulation. + * + */ + +static void +slk_paint_info(WINDOW *win) +{ + if (win && _nc_slk_format==4) + { + int i; + + mvwhline (win,0,0,0,getmaxx(win)); + wmove (win,0,0); + + for (i = 0; i < _slk->maxlab; i++) { + if (win && _nc_slk_format==4) + { + mvwaddch(win,0,_slk->ent[i].x,'F'); + if (i<9) + waddch(win,'1'+i); + else + { + waddch(win,'1'); + waddch(win,'0' + (i-9)); + } + } + } + } +} + +/* * Initialize soft labels. * Called from newterm() */ int -slk_initialize(WINDOW *stwin, int cols) +_nc_slk_initialize(WINDOW *stwin, int cols) { -SLK *slk; int i, x; +char *p; T(("slk_initialize()")); - if ((SP->_slk = slk = (SLK*) calloc(1,sizeof(SLK))) == NULL) - return(OK); + if (_slk) + { /* we did this already, so simply return */ + SP->_slk = _slk; + return(OK); + } + else + if ((SP->_slk = _slk = typeCalloc(SLK, 1)) == 0) + return(ERR); + + _slk->ent = NULL; + _slk->buffer = NULL; #ifdef num_labels - maxlab = (num_labels > 0) ? num_labels : MAX_SKEY; - maxlen = (num_labels > 0) ? label_width * label_height : MAX_SKEY_LEN; + _slk->maxlab = (num_labels > 0) ? num_labels : MAX_SKEY; + _slk->maxlen = (num_labels > 0) ? label_width * label_height : MAX_SKEY_LEN; + _slk->labcnt = (_slk->maxlab < MAX_SKEY) ? MAX_SKEY : _slk->maxlab; #else - maxlab = MAX_SKEY; - maxlen = MAX_SKEY_LEN; + _slk->labcnt = _slk->maxlab = MAX_SKEY; + _slk->maxlen = MAX_SKEY_LEN; #endif /* num_labels */ - for (i = 0; i < MAX_SKEY; i++) { - memset(slk->ent[i].form_text, ' ', (unsigned)maxlen); - slk->ent[i].visible = i < maxlab; + _slk->ent = typeCalloc(slk_ent, _slk->labcnt); + if (_slk->ent == NULL) + goto exception; + + p = _slk->buffer = (char*) calloc(2*_slk->labcnt,(1+_slk->maxlen)); + if (_slk->buffer == NULL) + goto exception; + + for (i = 0; i < _slk->labcnt; i++) { + _slk->ent[i].text = p; + p += (1 + _slk->maxlen); + _slk->ent[i].form_text = p; + p += (1 + _slk->maxlen); + memset(_slk->ent[i].form_text, ' ', (unsigned)_slk->maxlen); + _slk->ent[i].visible = (i < _slk->maxlab); } - if (_slk_format == 1) { /* 4-4 */ - int gap = cols - (MAX_SKEY * MAX_SKEY_LEN) - 6; + if (_nc_slk_format >= 3) /* PC style */ + { + int gap = (cols - 3 * (3 + 4*_slk->maxlen))/2; - if (gap < 1) + if (gap < 1) + gap = 1; + + for (i = x = 0; i < _slk->maxlab; i++) { + _slk->ent[i].x = x; + x += _slk->maxlen; + x += (i==3 || i==7) ? gap : 1; + } + if (_nc_slk_format == 4) + slk_paint_info (stwin); + } + else { + if (_nc_slk_format == 2) { /* 4-4 */ + int gap = cols - (_slk->maxlab * _slk->maxlen) - 6; + + if (gap < 1) gap = 1; - for (i = x = 0; i < MAX_SKEY; i++) { - slk->ent[i].x = x; - x += MAX_SKEY_LEN; - x += (i == 3) ? gap : 1; - } - } - else { /* 0 -> 3-2-3 */ - int gap = (cols - (MAX_SKEY * MAX_SKEY_LEN) - 5) / 2; + for (i = x = 0; i < _slk->maxlab; i++) { + _slk->ent[i].x = x; + x += _slk->maxlen; + x += (i == 3) ? gap : 1; + } + } + else + { + if (_nc_slk_format == 1) { /* 1 -> 3-2-3 */ + int gap = (cols - (_slk->maxlab * _slk->maxlen) - 5) / 2; if (gap < 1) - gap = 1; - for (i = x = 0; i < MAX_SKEY; i++) { - slk->ent[i].x = x; - x += MAX_SKEY_LEN; - x += (i == 2 || i == 4) ? gap : 1; + gap = 1; + for (i = x = 0; i < _slk->maxlab; i++) { + _slk->ent[i].x = x; + x += _slk->maxlen; + x += (i == 2 || i == 4) ? gap : 1; } + } + else + goto exception; + } } - slk->dirty = TRUE; - if ((slk->win = stwin) == NULL) + _slk->dirty = TRUE; + if ((_slk->win = stwin) == NULL) { - free(slk); - return(ERR); + exception: + if (_slk) + { + FreeIfNeeded(_slk->buffer); + FreeIfNeeded(_slk->ent); + free(_slk); + SP->_slk = _slk = (SLK*)0; + return(ERR); + } } return(OK); @@ -296,33 +407,37 @@ int i, x; int slk_init(int format) { - if (format < 0 || format > 1) + if (format < 0 || format > 3) return(ERR); - _slk_format = format; - _slk_init = TRUE; + _nc_slk_format = 1 + format; return(OK); } /* Functions to manipulate the soft-label attribute */ -int -slk_attrset(attr_t attr) +int +slk_attrset(const attr_t attr) { _slk_attr = attr; return(OK); } -int -slk_attron(attr_t attr) +int +slk_attron(const attr_t attr) { - _slk_attr |= attr; + toggle_attr_on(_slk_attr,attr); return(OK); } -int -slk_attroff(attr_t attr) +int +slk_attroff(const attr_t attr) { - _slk_attr &=~ attr; + toggle_attr_off(_slk_attr,attr); return(OK); } +attr_t +slk_attr(void) +{ + return _slk_attr; +} diff --git a/lib/libcurses/lib_touch.c b/lib/libcurses/lib_touch.c index b2b29ac5859..3d21449edc8 100644 --- a/lib/libcurses/lib_touch.c +++ b/lib/libcurses/lib_touch.c @@ -29,36 +29,42 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> + +MODULE_ID("Id: lib_touch.c,v 1.3 1997/02/02 00:26:15 tom Exp $") int is_linetouched(WINDOW *win, int line) { + T((T_CALLED("is_linetouched(%p,%d)"), win, line)); + + /* XSI doesn't define any error */ if (line > win->_maxy || line < 0) - return ERR; - if (win->_line[line].firstchar != _NOCHANGE) return TRUE; - return FALSE; + returnCode(ERR); + + returnCode(win->_line[line].firstchar != _NOCHANGE ? TRUE : FALSE); } int is_wintouched(WINDOW *win) { int i; + T((T_CALLED("is_wintouched(%p)"), win)); + for (i = 0; i <= win->_maxy; i++) if (win->_line[i].firstchar != _NOCHANGE) - return TRUE; - return FALSE; + returnCode(TRUE); + returnCode(FALSE); } int wtouchln(WINDOW *win, int y, int n, int changed) { int i; - T(("wtouchln(%p,%d,%d,%d)", win, y, n, changed)); + T((T_CALLED("wtouchln(%p,%d,%d,%d)"), win, y, n, changed)); for (i = y; i < y+n; i++) { win->_line[i].firstchar = changed ? 0 : _NOCHANGE; win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE; } - return OK; + returnCode(OK); } - diff --git a/lib/libcurses/lib_tstp.c b/lib/libcurses/lib_tstp.c index 73be68af51c..abee316c0e0 100644 --- a/lib/libcurses/lib_tstp.c +++ b/lib/libcurses/lib_tstp.c @@ -27,23 +27,26 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> #include <signal.h> -#include <stdlib.h> #if HAVE_SIGACTION #if !HAVE_TYPE_SIGACTION typedef struct sigaction sigaction_t; #endif -#else -#include "SigAction.h" +#else /* !HAVE_SIGACTION */ +#if HAVE_SIGVEC +#include <SigAction.h> +#endif #endif #ifdef SVR4_ACTION #define _POSIX_SOURCE #endif +MODULE_ID("Id: lib_tstp.c,v 1.8 1996/11/17 00:11:41 tom Exp $") + /* * Note: This code is fragile! Its problem is that different OSs * handle restart of system calls interrupted by signals differently. @@ -88,7 +91,7 @@ typedef struct sigaction sigaction_t; */ #ifdef SIGTSTP -static void tstp(int dummy) +static void tstp(int dummy GCC_UNUSED) { sigset_t mask, omask; sigaction_t act, oact; @@ -123,7 +126,7 @@ static void tstp(int dummy) (void)sigaddset(&mask, SIGTSTP); (void)sigprocmask(SIG_UNBLOCK, &mask, NULL); - /* Now we want to resend SIGSTP to this process and suspend it */ + /* Now we want to resend SIGSTP to this process and suspend it */ act.sa_handler = SIG_DFL; sigemptyset(&act.sa_mask); act.sa_flags = 0; @@ -146,7 +149,7 @@ static void tstp(int dummy) def_shell_mode(); /* - * This relies on the fact that doupdate() will restore the + * This relies on the fact that doupdate() will restore the * program-mode tty state, and issue enter_ca_mode if need be. */ doupdate(); @@ -165,6 +168,7 @@ static void cleanup(int sig) */ if (sig == SIGINT || sig == SIGQUIT) { +#if HAVE_SIGACTION || HAVE_SIGVEC sigaction_t act; sigemptyset(&act.sa_mask); act.sa_flags = 0; @@ -172,14 +176,20 @@ static void cleanup(int sig) if (sigaction(sig, &act, (sigaction_t *)0) == 0) { endwin(); } +#else + if (signal(sig, SIG_IGN) != SIG_ERR) { + endwin(); + } +#endif } - exit(1); + exit(EXIT_FAILURE); } /* * If the given signal is still in its default state, set it to the given * handler. */ +#if HAVE_SIGACTION || HAVE_SIGVEC static int CatchIfDefault(int sig, sigaction_t *act) { sigaction_t old_act; @@ -194,6 +204,21 @@ static int CatchIfDefault(int sig, sigaction_t *act) } return FALSE; } +#else +static int CatchIfDefault(int sig, RETSIGTYPE (*handler)()) +{ + void (*ohandler)(); + + ohandler = signal(sig, SIG_IGN); + if (ohandler == SIG_DFL) { + signal(sig, handler); + return TRUE; + } else { + signal(sig, ohandler); + return FALSE; + } +} +#endif /* * This is invoked once at the beginning (e.g., from 'initscr()'), to @@ -243,10 +268,15 @@ static int ignore; #else if (enable) { +#if HAVE_SIGACTION || HAVE_SIGVEC static sigaction_t act; act.sa_handler = cleanup; CatchIfDefault(SIGINT, &act); CatchIfDefault(SIGTERM, &act); +#else + CatchIfDefault(SIGINT, cleanup); + CatchIfDefault(SIGTERM, cleanup); +#endif } #endif } diff --git a/lib/libcurses/lib_twait.c b/lib/libcurses/lib_twait.c index c9dee4e07be..92f29b8b748 100644 --- a/lib/libcurses/lib_twait.c +++ b/lib/libcurses/lib_twait.c @@ -26,93 +26,242 @@ ** */ -#include "curses.priv.h" +#include <curses.priv.h> -#include <sys/types.h> /* some systems can't live without this */ -#include <string.h> - -#if HAVE_SYS_TIME_H && ! SYSTEM_LOOKS_LIKE_SCO +#if USE_FUNC_POLL +#include <stropts.h> +#include <poll.h> +#if HAVE_SYS_TIME_H #include <sys/time.h> #endif - -#if HAVE_UNISTD_H -#include <unistd.h> +#elif HAVE_SELECT +/* on SCO, <sys/time.h> conflicts with <sys/select.h> */ +#if HAVE_SYS_TIME_H && ! SYSTEM_LOOKS_LIKE_SCO +#include <sys/time.h> #endif - #if HAVE_SYS_SELECT_H #include <sys/select.h> #endif +#endif + +MODULE_ID("Id: lib_twait.c,v 1.18 1997/02/15 18:27:51 tom Exp $") /* - * We want to define GOOD_SELECT if the last argument of select(2) is + * We want to define GOOD_SELECT if the last argument of select(2) is * modified to indicate time left. The code will deal gracefully with * the other case, this is just an optimization to reduce the number * of system calls per input event. * - * In general, expect System-V-like UNIXes to have this behavior and BSD-like + * In general, expect System-V-like UNIXes to have this behavior and BSD-like * ones to not have it. Check your manual page. If it doesn't explicitly * say the last argument is modified, assume it's not. - * + * * (We'd really like configure to autodetect this, but writing a proper test * turns out to be hard.) */ -#if defined(linux) -#define GOOD_SELECT + +#if HAVE_GETTIMEOFDAY +#if (defined(TRACE) && !HAVE_USLEEP) || ! GOOD_SELECT +static void _nc_gettime(struct timeval *tp) +{ + gettimeofday(tp, (struct timezone *)0); + T(("time: %ld.%06ld", tp->tv_sec, tp->tv_usec)); +} +#endif #endif #if !HAVE_USLEEP -int usleep(unsigned int usec) +int _nc_usleep(unsigned int usec) { +int code; struct timeval tval; +#if defined(TRACE) && HAVE_GETTIMEOFDAY + _nc_gettime(&tval); +#endif +#if USE_FUNC_POLL + { + struct pollfd fds[1]; + code = poll(fds, 0, usec / 1000); + } +#elif HAVE_SELECT tval.tv_sec = usec / 1000000; tval.tv_usec = usec % 1000000; - select(0, NULL, NULL, NULL, &tval); + code = select(0, NULL, NULL, NULL, &tval); +#endif -} +#if defined(TRACE) && HAVE_GETTIMEOFDAY + _nc_gettime(&tval); #endif + return code; +} +#endif /* !HAVE_USLEEP */ -int _nc_timed_wait(int fd, int wait, int *timeleft) +/* + * Wait a specified number of milliseconds, returning true if the timer + * didn't expire before there is activity on the specified file descriptors. + * The file-descriptors are specified by the mode: + * 0 - none (absolute time) + * 1 - ncurses' normal input-descriptor + * 2 - mouse descriptor, if any + * 3 - either input or mouse. + * + * If the milliseconds given are -1, the wait blocks until activity on the + * descriptors. + */ +int _nc_timed_wait(int mode, int milliseconds, int *timeleft) { -int result; +int fd; +int count = 0; +long whole_secs = milliseconds / 1000; +long micro_secs = (milliseconds % 1000) * 1000; + +int result = 0; struct timeval ntimeout; + +#if USE_FUNC_POLL +struct pollfd fds[2]; +#elif HAVE_SELECT static fd_set set; -#if !defined(GOOD_SELECT) && HAVE_GETTIMEOFDAY +#endif + +#if !GOOD_SELECT && HAVE_GETTIMEOFDAY struct timeval starttime, returntime; +long delta; - gettimeofday(&starttime, NULL); + _nc_gettime(&starttime); #endif - FD_ZERO(&set); - FD_SET(fd, &set); + if (milliseconds >= 0) { + ntimeout.tv_sec = whole_secs; + ntimeout.tv_usec = micro_secs; + } else { + ntimeout.tv_sec = 0; + ntimeout.tv_usec = 0; + } + + T(("start twait: %lu.%06lu secs", (long) ntimeout.tv_sec, (long) ntimeout.tv_usec)); - /* the units of wait are milliseconds */ - ntimeout.tv_sec = wait / 1000; - ntimeout.tv_usec = (wait % 1000) * 1000; + /* + * The do loop tries to make it look like we have restarting signals, + * even if we don't. + */ + do { + count = 0; +#if USE_FUNC_POLL - T(("start twait: sec = %ld, usec = %ld", ntimeout.tv_sec, ntimeout.tv_usec)); + if (mode & 1) { + fds[count].fd = SP->_ifd; + fds[count].events = POLLIN; + count++; + } + if ((mode & 2) + && (fd = _nc_mouse_fd()) >= 0) { + fds[count].fd = fd; + fds[count].events = POLLIN; + count++; + } - result = select(fd+1, &set, NULL, NULL, &ntimeout); + result = poll(fds, count, milliseconds); +#elif HAVE_SELECT + /* + * Some systems modify the fd_set arguments; do this in the + * loop. + */ + FD_ZERO(&set); -#if !defined(GOOD_SELECT) && HAVE_GETTIMEOFDAY - gettimeofday(&returntime, NULL); - ntimeout.tv_sec -= (returntime.tv_sec - starttime.tv_sec); - ntimeout.tv_usec -= (returntime.tv_usec - starttime.tv_usec); - if (ntimeout.tv_usec < 0 && ntimeout.tv_sec > 0) { - ntimeout.tv_sec--; - ntimeout.tv_usec += 1000000; - } - if (ntimeout.tv_sec < 0) - ntimeout.tv_sec = ntimeout.tv_usec = 0; + if (mode & 1) { + FD_SET(SP->_ifd, &set); + count = SP->_ifd + 1; + } + if ((mode & 2) + && (fd = _nc_mouse_fd()) >= 0) { + FD_SET(fd, &set); + count = max(fd, count) + 1; + } + + errno = 0; + result = select(count, &set, NULL, NULL, milliseconds >= 0 ? &ntimeout : 0); #endif - /* return approximate time left on the ntimeout, in milliseconds */ - if (timeleft) +#if !GOOD_SELECT && HAVE_GETTIMEOFDAY + _nc_gettime(&returntime); + + /* The contents of ntimeout aren't guaranteed after return from + * 'select()', so we disregard its contents. Also, note that + * on some systems, tv_sec and tv_usec are unsigned. + */ + ntimeout.tv_sec = whole_secs; + ntimeout.tv_usec = micro_secs; + +#define DELTA(f) (long)ntimeout.f - (long)returntime.f + (long)starttime.f + + delta = DELTA(tv_sec); + if (delta < 0) + delta = 0; + ntimeout.tv_sec = delta; + + delta = DELTA(tv_usec); + while (delta < 0 && ntimeout.tv_sec != 0) { + ntimeout.tv_sec--; + delta += 1000000; + } + ntimeout.tv_usec = delta; + if (delta < 0) + ntimeout.tv_sec = ntimeout.tv_usec = 0; + + /* + * If the timeout hasn't expired, and we've gotten no data, + * this is probably a system where 'select()' needs to be left + * alone so that it can complete. Make this process sleep, + * then come back for more. + */ + if (result == 0 + && (ntimeout.tv_sec != 0 || ntimeout.tv_usec > 100000)) { + napms(100); + continue; + } +#endif + } while (result == -1 && errno == EINTR); + + /* return approximate time left on the ntimeout, in milliseconds */ + if (timeleft) *timeleft = (ntimeout.tv_sec * 1000) + (ntimeout.tv_usec / 1000); - T(("end twait: returned %d, sec = %ld, usec = %ld (%d msec)", - result, ntimeout.tv_sec, ntimeout.tv_usec, - timeleft ? *timeleft : -1)); + T(("end twait: returned %d, remaining time %lu.%06lu secs (%d msec)", + result, (long) ntimeout.tv_sec, (long) ntimeout.tv_usec, + timeleft ? *timeleft : -1)); + + /* + * Both 'poll()' and 'select()' return the number of file descriptors + * that are active. Translate this back to the mask that denotes which + * file-descriptors, so that we don't need all of this system-specific + * code everywhere. + */ + if (result != 0) { + if (result > 0) { + result = 0; +#if USE_FUNC_POLL + for (count = 0; count < 2; count++) { + if ((mode & (1 << count)) + && (fds[count].revents & POLLIN)) { + result |= (1 << count); + count++; + } + } +#elif HAVE_SELECT + if ((mode & 2) + && (fd = _nc_mouse_fd()) >= 0 + && FD_ISSET(fd, &set)) + result |= 2; + if ((mode & 1) + && FD_ISSET(SP->_ifd, &set)) + result |= 1; +#endif + } + else + result = 0; + } - return(result); + return (result); } diff --git a/lib/libcurses/lib_vidattr.c b/lib/libcurses/lib_vidattr.c index 8c6ffc8a35a..fe5041d2c6c 100644 --- a/lib/libcurses/lib_vidattr.c +++ b/lib/libcurses/lib_vidattr.c @@ -23,7 +23,7 @@ * vidputs(newmode, outc) * * newmode is taken to be the logical 'or' of the symbols in curses.h - * representing graphic renditions. The teminal is set to be in all of + * representing graphic renditions. The terminal is set to be in all of * the given modes, if possible. * * if the new attribute is normal @@ -43,49 +43,71 @@ * NOTE that this algorithm won't achieve the desired mix of attributes * in some cases, but those are probably just those cases in which it is * actually impossible, anyway, so... + * + * NOTE that we cannot assume that there's no interaction between color + * and other attribute resets. So each time we reset color (or other + * attributes) we'll have to be prepared to restore the other. */ -#include "curses.priv.h" -#include <string.h> -#include "term.h" +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: lib_vidattr.c,v 1.14 1997/05/06 16:02:43 tom Exp $") + +#define doPut(mode) TPUTS_TRACE(#mode); tputs(mode, 1, outc) + +#define TurnOn(mask,mode) \ + if ((turn_on & mask) && mode) { doPut(mode); } + +#define TurnOff(mask,mode) \ + if ((turn_off & mask) && mode) { doPut(mode); turn_off &= ~mask; } int vidputs(attr_t newmode, int (*outc)(int)) { -static attr_t previous_attr; +static attr_t previous_attr = A_NORMAL; attr_t turn_on, turn_off; +int pair, current_pair; - T(("vidputs(%lx) called %s", newmode, _traceattr(newmode))); + T((T_CALLED("vidputs(%s)"), _traceattr(newmode))); - /* this allows us to go on whether or not newterm() has been called */ + /* this allows us to go on whether or not newterm() has been called */ if (SP) previous_attr = SP->_current_attr; T(("previous attribute was %s", _traceattr(previous_attr))); - turn_off = (~newmode & previous_attr) & (chtype)(~A_COLOR); - turn_on = (newmode & ~previous_attr) & (chtype)(~A_COLOR); - if (newmode == previous_attr) - return OK; + returnCode(OK); + + turn_off = (~newmode & previous_attr) & ALL_BUT_COLOR; + turn_on = (newmode & ~previous_attr) & ALL_BUT_COLOR; + + pair = PAIR_NUMBER(newmode); + current_pair = PAIR_NUMBER(previous_attr); + + /* if there is no current screen, assume we *can* do color */ + if ((!SP || SP->_coloron) && pair == 0) { + T(("old pair = %d -- new pair = %d", current_pair, pair)); + if (pair != current_pair) { + _nc_do_color(pair, outc); + previous_attr &= ~A_COLOR; + } + } + if (newmode == A_NORMAL) { if((previous_attr & A_ALTCHARSET) && exit_alt_charset_mode) { - TPUTS_TRACE("exit_alt_charset_mode"); - tputs(exit_alt_charset_mode, 1, outc); - previous_attr &= ~A_ALTCHARSET; - } - if (previous_attr & A_COLOR) { - TPUTS_TRACE("orig_pair"); - tputs(orig_pair, 1, outc); + doPut(exit_alt_charset_mode); + previous_attr &= ~A_ALTCHARSET; } - if (previous_attr) { - TPUTS_TRACE("exit_attribute_mode"); - tputs(exit_attribute_mode, 1, outc); + if (previous_attr) { + doPut(exit_attribute_mode); + previous_attr &= ~A_COLOR; } - + } else if (set_attributes) { if (turn_on || turn_off) { TPUTS_TRACE("set_attributes"); - tputs(tparm(set_attributes, + tputs(tparm(set_attributes, (newmode & A_STANDOUT) != 0, (newmode & A_UNDERLINE) != 0, (newmode & A_REVERSE) != 0, @@ -95,145 +117,67 @@ attr_t turn_on, turn_off; (newmode & A_INVIS) != 0, (newmode & A_PROTECT) != 0, (newmode & A_ALTCHARSET) != 0), 1, outc); - /* - * Setting attributes in this way tends to unset the - * ones (such as color) that weren't specified. - */ - turn_off |= A_COLOR; + previous_attr &= ~A_COLOR; } } else { T(("turning %s off", _traceattr(turn_off))); - if ((turn_off & A_ALTCHARSET) && exit_alt_charset_mode) { - TPUTS_TRACE("exit_alt_charset_mode"); - tputs(exit_alt_charset_mode, 1, outc); - turn_off &= ~A_ALTCHARSET; - } - - if ((turn_off & A_UNDERLINE) && exit_underline_mode) { - TPUTS_TRACE("exit_underline_mode"); - tputs(exit_underline_mode, 1, outc); - turn_off &= ~A_UNDERLINE; - } - - if ((turn_off & A_STANDOUT) && exit_standout_mode) { - TPUTS_TRACE("exit_standout_mode"); - tputs(exit_standout_mode, 1, outc); - turn_off &= ~A_STANDOUT; - } + TurnOff(A_ALTCHARSET, exit_alt_charset_mode); + TurnOff(A_UNDERLINE, exit_underline_mode); + TurnOff(A_STANDOUT, exit_standout_mode); if (turn_off && exit_attribute_mode) { - TPUTS_TRACE("exit_attribute_mode"); - tputs(exit_attribute_mode, 1, outc); + doPut(exit_attribute_mode); turn_on |= (newmode & (chtype)(~A_COLOR)); - turn_off |= A_COLOR; + previous_attr &= ~A_COLOR; } T(("turning %s on", _traceattr(turn_on))); - if ((turn_on & A_ALTCHARSET) && enter_alt_charset_mode) { - TPUTS_TRACE("enter_alt_charset_mode"); - tputs(enter_alt_charset_mode, 1, outc); - } - - if ((turn_on & A_BLINK) && enter_blink_mode) { - TPUTS_TRACE("enter_blink_mode"); - tputs(enter_blink_mode, 1, outc); - } - - if ((turn_on & A_BOLD) && enter_bold_mode) { - TPUTS_TRACE("enter_bold_mode"); - tputs(enter_bold_mode, 1, outc); - } - - if ((turn_on & A_DIM) && enter_dim_mode) { - TPUTS_TRACE("enter_dim_mode"); - tputs(enter_dim_mode, 1, outc); - } - - if ((turn_on & A_REVERSE) && enter_reverse_mode) { - TPUTS_TRACE("enter_reverse_mode"); - tputs(enter_reverse_mode, 1, outc); - } - - if ((turn_on & A_STANDOUT) && enter_standout_mode) { - TPUTS_TRACE("enter_standout_mode"); - tputs(enter_standout_mode, 1, outc); - } - - if ((turn_on & A_PROTECT) && enter_protected_mode) { - TPUTS_TRACE("enter_protected_mode"); - tputs(enter_protected_mode, 1, outc); - } - - if ((turn_on & A_INVIS) && enter_secure_mode) { - TPUTS_TRACE("enter_secure_mode"); - tputs(enter_secure_mode, 1, outc); - } - - if ((turn_on & A_UNDERLINE) && enter_underline_mode) { - TPUTS_TRACE("enter_underline_mode"); - tputs(enter_underline_mode, 1, outc); - } - - if ((turn_on & A_HORIZONTAL) && enter_horizontal_hl_mode) { - TPUTS_TRACE("enter_horizontal_hl_mode"); - tputs(enter_horizontal_hl_mode, 1, outc); - } - - if ((turn_on & A_LEFT) && enter_left_hl_mode) { - TPUTS_TRACE("enter_left_hl_mode"); - tputs(enter_left_hl_mode, 1, outc); - } - - if ((turn_on & A_LOW) && enter_low_hl_mode) { - TPUTS_TRACE("enter_low_hl_mode"); - tputs(enter_low_hl_mode, 1, outc); - } - - if ((turn_on & A_RIGHT) && enter_right_hl_mode) { - TPUTS_TRACE("enter_right_hl_mode"); - tputs(enter_right_hl_mode, 1, outc); - } - - if ((turn_on & A_TOP) && enter_top_hl_mode) { - TPUTS_TRACE("enter_top_hl_mode"); - tputs(enter_top_hl_mode, 1, outc); - } - - if ((turn_on & A_VERTICAL) && enter_vertical_hl_mode) { - TPUTS_TRACE("enter_vertical_hl_mode"); - tputs(enter_vertical_hl_mode, 1, outc); - } + TurnOn (A_ALTCHARSET, enter_alt_charset_mode); + TurnOn (A_BLINK, enter_blink_mode); + TurnOn (A_BOLD, enter_bold_mode); + TurnOn (A_DIM, enter_dim_mode); + TurnOn (A_REVERSE, enter_reverse_mode); + TurnOn (A_STANDOUT, enter_standout_mode); + TurnOn (A_PROTECT, enter_protected_mode); + TurnOn (A_INVIS, enter_secure_mode); + TurnOn (A_UNDERLINE, enter_underline_mode); + TurnOn (A_HORIZONTAL, enter_horizontal_hl_mode); + TurnOn (A_LEFT, enter_left_hl_mode); + TurnOn (A_LOW, enter_low_hl_mode); + TurnOn (A_RIGHT, enter_right_hl_mode); + TurnOn (A_TOP, enter_top_hl_mode); + TurnOn (A_VERTICAL, enter_vertical_hl_mode); } - /* if there is no crrent screen, assume we *can* do color */ - if (!SP || SP->_coloron) { - int pair = PAIR_NUMBER(newmode); - int current_pair = PAIR_NUMBER(previous_attr); - - T(("old pair = %d -- new pair = %d", current_pair, pair)); - if (pair != current_pair || (turn_off && pair)) { + /* if there is no current screen, assume we *can* do color */ + if ((!SP || SP->_coloron) && pair != 0) { + current_pair = PAIR_NUMBER(previous_attr); + T(("old pair = %d -- new pair = %d", current_pair, pair)); + if (pair != current_pair) { _nc_do_color(pair, outc); } - } + } if (SP) SP->_current_attr = newmode; + else + previous_attr = newmode; - T(("vidputs finished")); - return OK; + returnCode(OK); } +#ifdef EXTERN_TERMINFO #undef vidattr +#endif int vidattr(attr_t newmode) { + T((T_CALLED("vidattr(%s)"), _traceattr(newmode))); - T(("vidattr(%lx) called", newmode)); - - return(vidputs(newmode, _nc_outch)); + returnCode(vidputs(newmode, _nc_outch)); } attr_t termattrs(void) diff --git a/lib/libcurses/lib_window.c b/lib/libcurses/lib_window.c index 3e9f58af704..aa4d1206893 100644 --- a/lib/libcurses/lib_window.c +++ b/lib/libcurses/lib_window.c @@ -25,8 +25,9 @@ ** */ -#include "curses.priv.h" -#include <string.h> +#include <curses.priv.h> + +MODULE_ID("Id: lib_window.c,v 1.8 1997/02/02 01:14:43 tom Exp $") void _nc_synchook(WINDOW *win) /* hook to be called after each window change */ @@ -41,77 +42,125 @@ int mvderwin(WINDOW *win, int y, int x) WINDOW *orig = win->_parent; int i; + T((T_CALLED("mvderwin(%p,%d,%d)"), win, y, x)); + if (orig) { if (win->_parx==x && win->_pary==y) - return OK; + returnCode(OK); if (x<0 || y<0) - return ERR; + returnCode(ERR); if ( (x+getmaxx(win) > getmaxx(orig)) || (y+getmaxy(win) > getmaxy(orig)) ) - return ERR; + returnCode(ERR); } else - return ERR; + returnCode(ERR); wsyncup(win); win->_parx = x; win->_pary = y; for(i=0;i<getmaxy(win);i++) win->_line[i].text = &(orig->_line[y++].text[x]); - return OK; + returnCode(OK); } int syncok(WINDOW *win, bool bf) /* enable/disable automatic wsyncup() on each change to window */ { + T((T_CALLED("syncok(%p,%d)"), win, bf)); + if (win) { win->_sync = bf; - return(OK); + returnCode(OK); } else - return(ERR); + returnCode(ERR); } void wsyncup(WINDOW *win) /* mark changed every cell in win's ancestors that is changed in win */ +/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ { WINDOW *wp; - if (win->_parent) + if (win && win->_parent) for (wp = win; wp->_parent; wp = wp->_parent) - { - int i; - WINDOW *pp = wp->_parent; - - for (i = 0; i <= wp->_maxy; i++) { - if (pp->_line[wp->_pary + i].firstchar >= 0 - && pp->_line[wp->_pary + i].firstchar < wp->_line[i].firstchar) - wp->_line[i].firstchar = pp->_line[wp->_pary + i].firstchar; - if (pp->_line[wp->_pary + i].lastchar > wp->_line[i].lastchar) - wp->_line[i].lastchar = pp->_line[wp->_pary + i].lastchar; + int y; + WINDOW *pp = wp->_parent; + + assert((wp->_pary <= pp->_maxy) && + ((wp->_pary+wp->_maxy) <= pp->_maxy)); + + for (y = 0; y <= wp->_maxy; y++) + { + int left = wp->_line[y].firstchar; + if (left >= 0) /* line is touched */ + { + /* left & right character in parent window coordinates */ + int right = wp->_line[y].lastchar + wp->_parx; + left += wp->_parx; + + if (pp->_line[wp->_pary + y].firstchar == _NOCHANGE) + { + pp->_line[wp->_pary + y].firstchar = left; + pp->_line[wp->_pary + y].lastchar = right; + } + else + { + if (left < pp->_line[wp->_pary + y].firstchar) + pp->_line[wp->_pary + y].firstchar = left; + if (pp->_line[wp->_pary + y].lastchar < right) + pp->_line[wp->_pary + y].lastchar = right; + } + } + } } - } } void wsyncdown(WINDOW *win) -/* mark changed every cell in win that is changed in any of its ancestors */ +/* mark changed every cell in win that is changed in any of its ancestors */ +/* Rewritten by J. Pfeifer, 1-Apr-96 (don't even think that...) */ { - WINDOW *wp; - - if (win->_parent) - for (wp = win; wp->_parent; wp = wp->_parent) + if (win && win->_parent) { - int i; - WINDOW *pp = wp->_parent; - - for (i = 0; i <= wp->_maxy; i++) - { - if (wp->_line[i].firstchar >= 0 - && wp->_line[i].firstchar < pp->_line[wp->_pary + i].firstchar) - pp->_line[wp->_pary + i].firstchar = wp->_line[i].firstchar; - if (wp->_line[i].lastchar > pp->_line[wp->_pary + i].lastchar) - pp->_line[wp->_pary + i].lastchar = wp->_line[i].lastchar; - } + WINDOW *pp = win->_parent; + int y; + + /* This recursion guarantees, that the changes are propagated down- + wards from the root to our direct parent. */ + wsyncdown(pp); + + /* and now we only have to propagate the changes from our direct + parent, if there are any. */ + assert((win->_pary <= pp->_maxy) && + ((win->_pary + win->_maxy) <= pp->_maxy)); + + for (y = 0; y <= win->_maxy; y++) + { + if (pp->_line[win->_pary + y].firstchar >= 0) /* parent changed */ + { + /* left and right character in child coordinates */ + int left = pp->_line[win->_pary + y].firstchar - win->_parx; + int right = pp->_line[win->_pary + y].lastchar - win->_parx; + /* The change maybe outside the childs range */ + if (left<0) + left = 0; + if (right > win->_maxx) + right = win->_maxx; + if (win->_line[y].firstchar == _NOCHANGE) + { + win->_line[y].firstchar = left; + win->_line[y].lastchar = right; + } + else + { + if (left < win->_line[y].firstchar) + win->_line[y].firstchar = left; + if (win->_line[y].lastchar < right) + win->_line[y].lastchar = right; + } + } + } } } @@ -121,7 +170,7 @@ void wcursyncup(WINDOW *win) WINDOW *wp; for( wp = win; wp && wp->_parent; wp = wp->_parent ) { wmove( wp->_parent, wp->_pary + wp->_cury, wp->_parx + wp->_curx ); - } + } } WINDOW *dupwin(WINDOW *win) @@ -131,34 +180,35 @@ WINDOW *nwin; size_t linesize; int i; - T(("dupwin(%p) called", win)); + T((T_CALLED("dupwin(%p)"), win)); if ((nwin = newwin(win->_maxy + 1, win->_maxx + 1, win->_begy, win->_begx)) == NULL) - return NULL; - - nwin->_curx = win->_curx; - nwin->_cury = win->_cury; - nwin->_maxy = win->_maxy; - nwin->_maxx = win->_maxx; - nwin->_begy = win->_begy; - nwin->_begx = win->_begx; - - nwin->_flags = win->_flags; - nwin->_attrs = win->_attrs; - nwin->_bkgd = win->_bkgd; - - nwin->_clear = win->_clear; - nwin->_scroll = win->_scroll; - nwin->_leaveok = win->_leaveok; + returnWin(0); + + nwin->_curx = win->_curx; + nwin->_cury = win->_cury; + nwin->_maxy = win->_maxy; + nwin->_maxx = win->_maxx; + nwin->_begy = win->_begy; + nwin->_begx = win->_begx; + nwin->_yoffset = win->_yoffset; + + nwin->_flags = win->_flags; + nwin->_attrs = win->_attrs; + nwin->_bkgd = win->_bkgd; + + nwin->_clear = win->_clear; + nwin->_scroll = win->_scroll; + nwin->_leaveok = win->_leaveok; nwin->_use_keypad = win->_use_keypad; - nwin->_delay = win->_delay; - nwin->_immed = win->_immed; - nwin->_sync = win->_sync; - nwin->_parx = win->_parx; - nwin->_pary = win->_pary; - nwin->_parent = win->_parent; - - nwin->_regtop = win->_regtop; + nwin->_delay = win->_delay; + nwin->_immed = win->_immed; + nwin->_sync = win->_sync; + nwin->_parx = win->_parx; + nwin->_pary = win->_pary; + nwin->_parent = win->_parent; + + nwin->_regtop = win->_regtop; nwin->_regbottom = win->_regbottom; linesize = (win->_maxx + 1) * sizeof(chtype); @@ -168,6 +218,5 @@ int i; nwin->_line[i].lastchar = win->_line[i].lastchar; } - return nwin; + returnWin(nwin); } - diff --git a/lib/libcurses/nc_alloc.h b/lib/libcurses/nc_alloc.h new file mode 100644 index 00000000000..489dca19308 --- /dev/null +++ b/lib/libcurses/nc_alloc.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * Copyright 1996,1997 by Thomas E. Dickey <dickey@clark.net> * + * All Rights Reserved. * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose and without fee is hereby granted, provided * + * that the above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the above listed copyright holder(s) * + * not be used in advertising or publicity pertaining to distribution of the * + * software without specific, written prior permission. THE ABOVE LISTED * + * COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * + * EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ******************************************************************************/ +/* Id: nc_alloc.h,v 1.4 1997/02/15 18:51:39 tom Exp $ */ + +#ifndef NC_ALLOC_included +#define NC_ALLOC_included 1 + +#if HAVE_LIBDMALLOC +#include <dmalloc.h> /* Gray Watson's library */ +#else +#undef HAVE_LIBDMALLOC +#define HAVE_LIBDMALLOC 0 +#endif + +#if HAVE_LIBDBMALLOC +#include <dbmalloc.h> /* Conor Cahill's library */ +#else +#undef HAVE_LIBDBMALLOC +#define HAVE_LIBDBMALLOC 0 +#endif + +#ifndef NO_LEAKS +#define NO_LEAKS 0 +#endif + +#ifndef HAVE_NC_FREEALL +#define HAVE_NC_FREEALL 0 +#endif + +#if HAVE_LIBDBMALLOC || HAVE_LIBDMALLOC || NO_LEAKS || HAVE_NC_FREEALL +struct termtype; +extern void _nc_free_and_exit(int) GCC_NORETURN; +extern void _nc_free_tparm(void); +extern void _nc_leaks_dump_entry(void); +extern void _nc_free_termtype(struct termtype *, int); +#define ExitProgram(code) _nc_free_and_exit(code) +#endif + +#ifndef ExitProgram +#define ExitProgram(code) return code +#endif + +#endif /* NC_ALLOC_included */ diff --git a/lib/libcurses/ncurses_cfg.h b/lib/libcurses/ncurses_cfg.h new file mode 100644 index 00000000000..e465257d066 --- /dev/null +++ b/lib/libcurses/ncurses_cfg.h @@ -0,0 +1,65 @@ +/* generated by configure-script + * On host: OpenBSD xerxes.courtesan.com 2.2 XERXES#13 i386 + */ +#ifndef NC_CONFIG_H +#define NC_CONFIG_H + +#define CC_HAS_INLINE_FUNCS 1 +#define GCC_NORETURN __attribute__((noreturn)) +#define GCC_PRINTF 1 +#define GCC_SCANF 1 +#define GCC_UNUSED __attribute__((unused)) +#define HAVE_BUILTIN_H 1 +#define HAVE_DIRENT_H 1 +#define HAVE_EXTERN_ERRNO 1 +#define HAVE_EXTERN_SYS_ERRLIST 1 +#define HAVE_FCNTL_H 1 +#define HAVE_FORM_H 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_GETTTYNAM 1 +#define HAVE_LIMITS_H 1 +#define HAVE_LOCALE_H 1 +#define HAVE_MEMCCPY 1 +#define HAVE_MENU_H 1 +#define HAVE_NC_ALLOC_H 1 +#define HAVE_PANEL_H 1 +#define HAVE_POLL 1 +#define HAVE_POLL_H 1 +#define HAVE_REGEX_H 1 +#define HAVE_SELECT 1 +#define HAVE_SETBUF 1 +#define HAVE_SETBUFFER 1 +#define HAVE_SETVBUF 1 +#define HAVE_SIGACTION 1 +#define HAVE_SIGVEC 1 +#define HAVE_STRDUP 1 +#define HAVE_SYS_IOCTL_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_SYS_TIMES_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_TCGETATTR 1 +#define HAVE_TERMIOS_H 1 +#define HAVE_TIMES 1 +#define HAVE_TTYENT_H 1 +#define HAVE_TYPEINFO 1 +#define HAVE_UNISTD_H 1 +#define HAVE_USLEEP 1 +#define HAVE_VSSCANF 1 +#define PURE_TERMINFO 1 +#define RETSIGTYPE void +#define STDC_HEADERS 1 +#define SYSTEM_NAME "OpenBSD 2.2" + + /* The C compiler may not treat these properly, but C++ has to */ +#ifdef __cplusplus +#undef const +#undef inline +#else +#if defined(lint) || defined(TRACE) +#undef inline +#define inline /* nothing */ +#endif +#endif + +#endif /* NC_CONFIG_H */ diff --git a/lib/libcurses/resizeterm.c b/lib/libcurses/resizeterm.c new file mode 100644 index 00000000000..760ce6f296d --- /dev/null +++ b/lib/libcurses/resizeterm.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * Copyright 1996,1997 by Thomas E. Dickey <dickey@clark.net> * + * All Rights Reserved. * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose and without fee is hereby granted, provided * + * that the above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the above listed copyright holder(s) * + * not be used in advertising or publicity pertaining to distribution of the * + * software without specific, written prior permission. THE ABOVE LISTED * + * COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * + * EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ******************************************************************************/ + +/* + * This is an extension to the curses library. It provides callers with a hook + * into the NCURSES data to resize windows, primarily for use by programs + * running in an X Window terminal (e.g., xterm). I abstracted this module + * from my application library for NCURSES because it must be compiled with + * the private data structures -- T.Dickey 1995/7/4. + */ + +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: resizeterm.c,v 1.3 1997/02/02 01:03:06 tom Exp $") + +/* + * This function reallocates NCURSES window structures. It is invoked in + * response to a SIGWINCH interrupt. Other user-defined windows may also need + * to be reallocated. + * + * Because this performs memory allocation, it should not (in general) be + * invoked directly from the signal handler. + */ +int +resizeterm(int ToLines, int ToCols) +{ + int stolen = screen_lines - SP->_lines_avail; + int bottom = screen_lines + SP->_topstolen - stolen; + + T((T_CALLED("resizeterm(%d,%d) old(%d,%d)"), + ToLines, ToCols, + screen_lines, screen_columns)); + + if (ToLines != screen_lines + || ToCols != screen_columns) { + WINDOWLIST *wp; + + for (wp = _nc_windows; wp != 0; wp = wp->next) { + WINDOW *win = wp->win; + int myLines = win->_maxy + 1; + int myCols = win->_maxx + 1; + + /* pads aren't treated this way */ + if (win->_flags & _ISPAD) + continue; + + if (win->_begy >= bottom) { + win->_begy += (ToLines - screen_lines); + } else { + if (myLines == screen_lines - stolen + && ToLines != screen_lines) + myLines = ToLines - stolen; + else + if (myLines == screen_lines + && ToLines != screen_lines) + myLines = ToLines; + } + + if (myCols == screen_columns + && ToCols != screen_columns) + myCols = ToCols; + + if (wresize(win, myLines, myCols) != OK) + returnCode(ERR); + } + + screen_lines = lines = ToLines; + screen_columns = columns = ToCols; + + SP->_lines_avail = lines - stolen; + } + + /* + * Always update LINES, to allow for call from lib_doupdate.c which + * needs to have the count adjusted by the stolen (ripped off) lines. + */ + LINES = ToLines - stolen; + COLS = ToCols; + + returnCode(OK); +} diff --git a/lib/libcurses/shlib_version b/lib/libcurses/shlib_version index 3f0196ebf4a..d9961ea9fef 100644 --- a/lib/libcurses/shlib_version +++ b/lib/libcurses/shlib_version @@ -1,2 +1,2 @@ -major=3 -minor=1 +major=4 +minor=0 diff --git a/lib/libcurses/unctrl.c b/lib/libcurses/unctrl.c new file mode 100644 index 00000000000..93ca24252c4 --- /dev/null +++ b/lib/libcurses/unctrl.c @@ -0,0 +1,43 @@ +/* generated by MKunctrl.awk */ + +#include <curses.priv.h> + +NCURSES_CONST char *unctrl(register chtype ch) +{ +static const char* const table[] = { + "^\100", "^\101", "^\102", "^\103", "^\104", "^\105", "^\106", "^\107", + "^\110", "^\111", "^\112", "^\113", "^\114", "^\115", "^\116", "^\117", + "^\120", "^\121", "^\122", "^\123", "^\124", "^\125", "^\126", "^\127", + "^\130", "^\131", "^\132", "^\133", "^\134", "^\135", "^\136", "^\137", + "\040", "\041", "\042", "\043", "\044", "\045", "\046", "\047", + "\050", "\051", "\052", "\053", "\054", "\055", "\056", "\057", + "\060", "\061", "\062", "\063", "\064", "\065", "\066", "\067", + "\070", "\071", "\072", "\073", "\074", "\075", "\076", "\077", + "\100", "\101", "\102", "\103", "\104", "\105", "\106", "\107", + "\110", "\111", "\112", "\113", "\114", "\115", "\116", "\117", + "\120", "\121", "\122", "\123", "\124", "\125", "\126", "\127", + "\130", "\131", "\132", "\133", "\134", "\135", "\136", "\137", + "\140", "\141", "\142", "\143", "\144", "\145", "\146", "\147", + "\150", "\151", "\152", "\153", "\154", "\155", "\156", "\157", + "\160", "\161", "\162", "\163", "\164", "\165", "\166", "\167", + "\170", "\171", "\172", "\173", "\174", "\175", "\176", "^?", + "\200", "\201", "\202", "\203", "\204", "\205", "\206", "\207", + "\210", "\211", "\212", "\213", "\214", "\215", "\216", "\217", + "\220", "\221", "\222", "\223", "\224", "\225", "\226", "\227", + "\230", "\231", "\232", "\233", "\234", "\235", "\236", "\237", + "\240", "\241", "\242", "\243", "\244", "\245", "\246", "\247", + "\250", "\251", "\252", "\253", "\254", "\255", "\256", "\257", + "\260", "\261", "\262", "\263", "\264", "\265", "\266", "\267", + "\270", "\271", "\272", "\273", "\274", "\275", "\276", "\277", + "\300", "\301", "\302", "\303", "\304", "\305", "\306", "\307", + "\310", "\311", "\312", "\313", "\314", "\315", "\316", "\317", + "\320", "\321", "\322", "\323", "\324", "\325", "\326", "\327", + "\330", "\331", "\332", "\333", "\334", "\335", "\336", "\337", + "\340", "\341", "\342", "\343", "\344", "\345", "\346", "\347", + "\350", "\351", "\352", "\353", "\354", "\355", "\356", "\357", + "\360", "\361", "\362", "\363", "\364", "\365", "\366", "\367", + "\370", "\371", "\372", "\373", "\374", "\375", "\376", "\377" +}; + + return (NCURSES_CONST char *)table[TextOf(ch)]; +} diff --git a/lib/libcurses/unctrl.h b/lib/libcurses/unctrl.h index a503aa76a8f..32554512eb9 100644 --- a/lib/libcurses/unctrl.h +++ b/lib/libcurses/unctrl.h @@ -1,4 +1,3 @@ - /*************************************************************************** * COPYRIGHT NOTICE * **************************************************************************** @@ -31,15 +30,25 @@ * before calling unctrl() again. * */ + +/* Id: unctrl.h.in,v 1.5 1997/04/26 23:04:09 tom Exp $ */ + #ifndef _UNCTRL_H #define _UNCTRL_H 1 -#define NCURSES_VERSION "1.9.9e" -#ifndef _CHTYPE_T_ -#define _CHTYPE_T_ unsigned long -typedef _CHTYPE_T_ chtype; +#undef NCURSES_VERSION +#define NCURSES_VERSION "4.1" + +#ifdef __cplusplus +extern "C" { #endif -extern char *unctrl(chtype); +#include <curses.h> + +extern NCURSES_CONST char *unctrl(chtype); + +#ifdef __cplusplus +} +#endif #endif /* _UNCTRL_H */ diff --git a/lib/libcurses/wresize.3 b/lib/libcurses/wresize.3 new file mode 100644 index 00000000000..f95fbb733d5 --- /dev/null +++ b/lib/libcurses/wresize.3 @@ -0,0 +1,60 @@ +.\"***************************************************************************** +.\" Copyright 1996 by Thomas E. Dickey <dickey@clark.net> * +.\" All Rights Reserved. * +.\" * +.\" Permission to use, copy, modify, and distribute this software and its * +.\" documentation for any purpose and without fee is hereby granted, provided * +.\" that the above copyright notice appear in all copies and that both that * +.\" copyright notice and this permission notice appear in supporting * +.\" documentation, and that the name of the above listed copyright holder(s) * +.\" not be used in advertising or publicity pertaining to distribution of the * +.\" software without specific, written prior permission. THE ABOVE LISTED * +.\" COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * +.\" EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * +.\" SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * +.\" RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * +.\" CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * +.\" CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * +.\"***************************************************************************** +.\" Id: wresize.3x,v 1.2 1996/09/07 14:51:04 tom Exp $ +.TH wresize 3X "" +. +.SH NAME +\fBwresize\fR - resize a curses window +. +.SH SYNOPSIS +\fB#include <curses.h>\fR + +\fBint wresize(WINDOW *win, int lines, int columns);\fR +. +.SH DESCRIPTION +The \fBwresize\fR function reallocates storage for an \fBcurses\fR +window to adjust its dimensions to the specified values. +If either dimension is larger than the current values, the +window's data is filled with blanks that have the current background rendition +(as set by \fBwbkgndset\fR) merged into them. +. +.SH RETURN VALUE +The function returns the integer \fBERR\fR upon failure and \fBOK\fR on success. +It will fail if either of the dimensions less than or equal to zero, +or if an error occurs while (re)allocating memory for the window. +. +.SH NOTES +The only restriction placed on the dimensions is that they be greater than zero. +The dimensions are not compared to \fBcurses\fR screen dimensions to +simplify the logic of \fBresizeterm\fR. +The caller must ensure that the window's dimensions fit within the +actual screen dimensions. +. +.SH SEE ALSO +\fBresizeterm\fR(3x). +. +.SH AUTHOR +Thomas Dickey (from an equivalent function written in 1988 for BSD curses). +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/lib/libcurses/wresize.c b/lib/libcurses/wresize.c new file mode 100644 index 00000000000..3d5c1f8c4d1 --- /dev/null +++ b/lib/libcurses/wresize.c @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright 1996,1997 by Thomas E. Dickey <dickey@clark.net> * + * All Rights Reserved. * + * * + * Permission to use, copy, modify, and distribute this software and its * + * documentation for any purpose and without fee is hereby granted, provided * + * that the above copyright notice appear in all copies and that both that * + * copyright notice and this permission notice appear in supporting * + * documentation, and that the name of the above listed copyright holder(s) * + * not be used in advertising or publicity pertaining to distribution of the * + * software without specific, written prior permission. THE ABOVE LISTED * + * COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * + * EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY * + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ******************************************************************************/ + +#include <curses.priv.h> +#include <term.h> + +MODULE_ID("Id: wresize.c,v 1.5 1997/02/01 23:22:54 tom Exp $") + +/* + * Reallocate a curses WINDOW struct to either shrink or grow to the specified + * new lines/columns. If it grows, the new character cells are filled with + * blanks. The application is responsible for repainting the blank area. + */ + +static void *doalloc(void *p, size_t n) +{ + if (p == 0) + p = malloc(n); + else + p = realloc(p, n); + return p; +} + +#define DOALLOC(p,t,n) (t *)doalloc(p, sizeof(t)*(n)) +#define ld_ALLOC(p,n) DOALLOC(p,struct ldat,n) +#define c_ALLOC(p,n) DOALLOC(p,chtype,n) + +int +wresize(WINDOW *win, int ToLines, int ToCols) +{ + register int row; + int size_x, size_y; + struct ldat *pline = (win->_flags & _SUBWIN) ? win->_parent->_line : 0; + +#ifdef TRACE + T((T_CALLED("wresize(%p,%d,%d)"), win, ToLines, ToCols)); + TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)", + win->_begy, win->_begx, + win->_maxy, win->_maxx, + win->_regtop, win->_regbottom)); + if (_nc_tracing & TRACE_UPDATE) + _tracedump("...before", win); +#endif + + if (--ToLines < 0 || --ToCols < 0) + returnCode(ERR); + + size_x = win->_maxx; + size_y = win->_maxy; + + if (ToLines == size_y + && ToCols == size_x) + returnCode(OK); + + /* + * If the number of lines has changed, adjust the size of the overall + * vector: + */ + if (ToLines != size_y) { + if (! (win->_flags & _SUBWIN)) { + for (row = ToLines+1; row <= size_y; row++) + free((char *)(win->_line[row].text)); + } + + win->_line = ld_ALLOC(win->_line, ToLines+1); + if (win->_line == 0) + returnCode(ERR); + + for (row = size_y+1; row <= ToLines; row++) { + win->_line[row].text = 0; + win->_line[row].firstchar = 0; + win->_line[row].lastchar = ToCols; + if ((win->_flags & _SUBWIN)) { + win->_line[row].text = + &pline[win->_begy + row].text[win->_begx]; + } + } + } + + /* + * Adjust the width of the columns: + */ + for (row = 0; row <= ToLines; row++) { + chtype *s = win->_line[row].text; + int begin = (s == 0) ? 0 : size_x + 1; + int end = ToCols; + chtype blank = _nc_background(win); + + win->_line[row].oldindex = row; + + if (ToCols != size_x || s == 0) { + if (! (win->_flags & _SUBWIN)) { + win->_line[row].text = s = c_ALLOC(s, ToCols+1); + if (win->_line[row].text == 0) + returnCode(ERR); + } else if (s == 0) { + win->_line[row].text = s = + &pline[win->_begy + row].text[win->_begx]; + } + + if (end >= begin) { /* growing */ + if (win->_line[row].firstchar < begin) + win->_line[row].firstchar = begin; + win->_line[row].lastchar = ToCols; + do { + s[end] = blank; + } while (--end >= begin); + } else { /* shrinking */ + win->_line[row].firstchar = 0; + win->_line[row].lastchar = ToCols; + } + } + } + + /* + * Finally, adjust the parameters showing screen size and cursor + * position: + */ + win->_maxx = ToCols; + win->_maxy = ToLines; + + if (win->_regtop > win->_maxy) + win->_regtop = win->_maxy; + if (win->_regbottom > win->_maxy + || win->_regbottom == size_y) + win->_regbottom = win->_maxy; + + if (win->_curx > win->_maxx) + win->_curx = win->_maxx; + if (win->_cury > win->_maxy) + win->_cury = win->_maxy; + +#ifdef TRACE + TR(TRACE_UPDATE, ("...beg (%d, %d), max(%d,%d), reg(%d,%d)", + win->_begy, win->_begx, + win->_maxy, win->_maxx, + win->_regtop, win->_regbottom)); + if (_nc_tracing & TRACE_UPDATE) + _tracedump("...after:", win); +#endif + returnCode(OK); +} |