diff options
author | Rong-En Fan <rafan@FreeBSD.org> | 2008-11-09 09:06:04 +0000 |
---|---|---|
committer | Rong-En Fan <rafan@FreeBSD.org> | 2008-11-09 09:06:04 +0000 |
commit | a388f199193767bacbb38b172ab89cb84369736c (patch) | |
tree | a1816f5667d2280b970ca44e407bac8cc4496c0a /contrib/ncurses/ncurses/tty | |
parent | aa59d4d4c5dda7e1c6f9dc0cc6edc58992a525c7 (diff) | |
download | src-a388f199193767bacbb38b172ab89cb84369736c.tar.gz src-a388f199193767bacbb38b172ab89cb84369736c.zip |
- Flatten the vendor area
Notes
Notes:
svn path=/vendor/ncurses/dist/; revision=184786
Diffstat (limited to 'contrib/ncurses/ncurses/tty')
-rwxr-xr-x | contrib/ncurses/ncurses/tty/MKexpanded.sh | 99 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/hardscroll.c | 325 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/hashmap.c | 549 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/lib_mvcur.c | 1245 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/lib_tstp.c | 389 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/lib_twait.c | 444 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/lib_vidattr.c | 338 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/tty_display.h | 140 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/tty_input.h | 61 | ||||
-rw-r--r-- | contrib/ncurses/ncurses/tty/tty_update.c | 1972 |
10 files changed, 0 insertions, 5562 deletions
diff --git a/contrib/ncurses/ncurses/tty/MKexpanded.sh b/contrib/ncurses/ncurses/tty/MKexpanded.sh deleted file mode 100755 index bf9acf21aa43..000000000000 --- a/contrib/ncurses/ncurses/tty/MKexpanded.sh +++ /dev/null @@ -1,99 +0,0 @@ -#! /bin/sh -############################################################################## -# Copyright (c) 1998-2000,2005 Free Software Foundation, Inc. # -# # -# Permission is hereby granted, free of charge, to any person obtaining a # -# copy of this software and associated documentation files (the "Software"), # -# to deal in the Software without restriction, including without limitation # -# the rights to use, copy, modify, merge, publish, distribute, distribute # -# with modifications, sublicense, and/or sell copies of the Software, and to # -# permit persons to whom the Software is furnished to do so, subject to the # -# following conditions: # -# # -# The above copyright notice and this permission notice shall be included in # -# all copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # -# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # -# DEALINGS IN THE SOFTWARE. # -# # -# Except as contained in this notice, the name(s) of the above copyright # -# holders shall not be used in advertising or otherwise to promote the sale, # -# use or other dealings in this Software without prior written # -# authorization. # -############################################################################## -# -# Author: Thomas E. Dickey <dickey@clark.net> 1997 -# -# $Id: MKexpanded.sh,v 1.11 2005/01/02 01:06:40 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 <<EOF -/* generated by MKexpanded.sh */ -#include <curses.priv.h> -#include <term.h> -#if 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 -NCURSES_EXPORT(void) _nc_toggle_attr_on (attr_t *S, attr_t at) -{ - toggle_attr_on(*S,at); -} -NCURSES_EXPORT(void) _nc_toggle_attr_off (attr_t *S, attr_t at) -{ - toggle_attr_off(*S,at); -} -NCURSES_EXPORT(int) _nc_DelCharCost (int count) -{ - return DelCharCost(count); -} -NCURSES_EXPORT(int) _nc_InsCharCost (int count) -{ - return InsCharCost(count); -} -NCURSES_EXPORT(void) _nc_UpdateAttrs (NCURSES_CH_T c) -{ - UpdateAttrs(c); -} -EOF - -$preprocessor $TMP 2>/dev/null | sed -e '1,/^IGNORE$/d' - -cat <<EOF -#else /* ! NCURSES_EXPANDED */ -NCURSES_EXPORT(void) _nc_expanded (void) { } -#endif /* NCURSES_EXPANDED */ -EOF diff --git a/contrib/ncurses/ncurses/tty/hardscroll.c b/contrib/ncurses/ncurses/tty/hardscroll.c deleted file mode 100644 index 7d8979a4f51b..000000000000 --- a/contrib/ncurses/ncurses/tty/hardscroll.c +++ /dev/null @@ -1,325 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - ****************************************************************************/ - -/****************************************************************************** - -NAME - hardscroll.c -- hardware-scrolling optimization for ncurses - -SYNOPSIS - void _nc_scroll_optimize(void) - -DESCRIPTION - OVERVIEW - -This algorithm for computes optimum hardware scrolling to transform an -old screen (curscr) into a new screen (newscr) via vertical line moves. - -Because the screen has a `grain' (there are insert/delete/scroll line -operations but no insert/delete/scroll column operations), it is efficient -break the update algorithm into two pieces: a first stage that does only line -moves, optimizing the end product of user-invoked insertions, deletions, and -scrolls; and a second phase (corresponding to the present doupdate code in -ncurses) that does only line transformations. - -The common case we want hardware scrolling for is to handle line insertions -and deletions in screen-oriented text-editors. This two-stage approach will -accomplish that at a low computation and code-size cost. - - LINE-MOVE COMPUTATION - -Now, to a discussion of the line-move computation. - -For expository purposes, consider the screen lines to be represented by -integers 0..23 (with the understanding that the value of 23 may vary). -Let a new line introduced by insertion, scrolling, or at the bottom of -the screen following a line delete be given the index -1. - -Assume that the real screen starts with lines 0..23. Now, we have -the following possible line-oriented operations on the screen: - -Insertion: inserts a line at a given screen row, forcing all lines below -to scroll forward. The last screen line is lost. For example, an insertion -at line 5 would produce: 0..4 -1 5..23. - -Deletion: deletes a line at a given screen row, forcing all lines below -to scroll forward. The last screen line is made new. For example, a deletion -at line 7 would produce: 0..6 8..23 -1. - -Scroll up: move a range of lines up 1. The bottom line of the range -becomes new. For example, scrolling up the region from 9 to 14 will -produce 0..8 10..14 -1 15..23. - -Scroll down: move a range of lines down 1. The top line of the range -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. - -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 -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. - -Note that the move computation does not need to have the full generality -of a diff algorithm (which it superficially resembles) because lines cannot -be moved out of order. - - THE ALGORITHM - -The scrolling is done in two passes. The first pass is from top to bottom -scroling hunks UP. The second one is from bottom to top scrolling hunks DOWN. -Obviously enough, no lines to be scrolled will be destroyed. (lav) - -HOW TO TEST THIS: - -Use the following production: - -hardscroll: hardscroll.c - $(CC) -g -DSCROLLDEBUG hardscroll.c -o hardscroll - -Then just type scramble vectors and watch. The following test loads are -a representative sample of cases: - ------------------------------ CUT HERE ------------------------------------ -# No lines moved - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 -# -# A scroll up - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 -1 -# -# A scroll down --1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 -# -# An insertion (after line 12) - 0 1 2 3 4 5 6 7 8 9 10 11 12 -1 13 14 15 16 17 18 19 20 21 22 -# -# A simple deletion (line 10) - 0 1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 -1 -# -# A more complex case --1 -1 -1 -1 -1 3 4 5 6 7 -1 -1 8 9 10 11 12 13 14 15 16 17 -1 -1 ------------------------------ CUT HERE ------------------------------------ - -AUTHOR - Eric S. Raymond <esr@snark.thyrsus.com>, November 1994 - New algorithm by Alexander V. Lukyanov <lav@yars.free.net>, Aug 1997 - -*****************************************************************************/ - -#include <curses.priv.h> - -MODULE_ID("$Id: hardscroll.c,v 1.41 2007/09/29 21:48:36 tom Exp $") - -#if defined(SCROLLDEBUG) || defined(HASHDEBUG) - -# undef screen_lines -# define screen_lines MAXLINES -NCURSES_EXPORT_VAR(int) -oldnums[MAXLINES]; -# define OLDNUM(n) oldnums[n] -# define _tracef printf -# undef TR -# define TR(n, a) if (_nc_tracing & (n)) { _tracef a ; putchar('\n'); } - -extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing; - -#else /* no debug */ - -/* OLDNUM(n) indicates which line will be shifted to the position n. - if OLDNUM(n) == _NEWINDEX, then the line n in new, not shifted from - somewhere. */ -NCURSES_EXPORT_VAR(int *) -_nc_oldnums = 0; /* obsolete: keep for ABI compat */ - -# if USE_HASHMAP -# define oldnums SP->_oldnum_list -# define OLDNUM(n) oldnums[n] -# else /* !USE_HASHMAP */ -# define OLDNUM(n) newscr->_line[n].oldindex -# endif /* !USE_HASHMAP */ - -#define OLDNUM_SIZE SP->_oldnum_size - -#endif /* defined(SCROLLDEBUG) || defined(HASHDEBUG) */ - -NCURSES_EXPORT(void) -_nc_scroll_optimize(void) -/* scroll optimization to transform curscr to newscr */ -{ - int i; - int start, end, shift; - - TR(TRACE_ICALLS, (T_CALLED("_nc_scroll_optimize"))); - -#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) -#if USE_HASHMAP - /* get enough storage */ - if (OLDNUM_SIZE < screen_lines) { - int *new_oldnums = typeRealloc(int, screen_lines, oldnums); - if (!new_oldnums) - return; - oldnums = new_oldnums; - OLDNUM_SIZE = screen_lines; - } - /* calculate the indices */ - _nc_hash_map(); -#endif -#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ - -#ifdef TRACE - if (USE_TRACEF(TRACE_UPDATE | TRACE_MOVE)) { - _nc_linedump(); - _nc_unlock_global(tracef); - } -#endif /* TRACE */ - - /* pass 1 - from top to bottom scrolling up */ - for (i = 0; i < screen_lines;) { - while (i < screen_lines && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) <= i)) - i++; - if (i >= screen_lines) - break; - - shift = OLDNUM(i) - i; /* shift > 0 */ - start = i; - - i++; - while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i - == shift) - i++; - end = i - 1 + shift; - - TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift)); -#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) - if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) { - TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll")); - continue; - } -#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ - } - - /* pass 2 - from bottom to top scrolling down */ - for (i = screen_lines - 1; i >= 0;) { - while (i >= 0 && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) >= i)) - i--; - if (i < 0) - break; - - shift = OLDNUM(i) - i; /* shift < 0 */ - end = i; - - i--; - while (i >= 0 && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i == shift) - i--; - start = i + 1 - (-shift); - - TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift)); -#if !defined(SCROLLDEBUG) && !defined(HASHDEBUG) - if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) { - TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll")); - continue; - } -#endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */ - } - TR(TRACE_ICALLS, (T_RETURN(""))); -} - -#if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG) -NCURSES_EXPORT(void) -_nc_linedump(void) -/* dump the state of the real and virtual oldnum fields */ -{ - int n; - char *buf = 0; - size_t want = (screen_lines + 1) * 4; - - buf = typeMalloc(char, want); - - (void) strcpy(buf, "virt"); - for (n = 0; n < screen_lines; n++) - (void) sprintf(buf + strlen(buf), " %02d", OLDNUM(n)); - TR(TRACE_UPDATE | TRACE_MOVE, (buf)); - free(buf); -} -#endif /* defined(TRACE) || defined(SCROLLDEBUG) */ - -#ifdef SCROLLDEBUG - -int -main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) -{ - char line[BUFSIZ], *st; - -#ifdef TRACE - _nc_tracing = TRACE_MOVE; -#endif - for (;;) { - int n; - - for (n = 0; n < screen_lines; n++) - oldnums[n] = _NEWINDEX; - - /* grab the test vector */ - if (fgets(line, sizeof(line), stdin) == (char *) NULL) - exit(EXIT_SUCCESS); - - /* parse it */ - n = 0; - if (line[0] == '#') { - (void) fputs(line, stderr); - continue; - } - st = strtok(line, " "); - do { - oldnums[n++] = atoi(st); - } while - ((st = strtok((char *) NULL, " ")) != 0); - - /* display it */ - (void) fputs("Initial input:\n", stderr); - _nc_linedump(); - - _nc_scroll_optimize(); - } -} - -#endif /* SCROLLDEBUG */ - -/* hardscroll.c ends here */ diff --git a/contrib/ncurses/ncurses/tty/hashmap.c b/contrib/ncurses/ncurses/tty/hashmap.c deleted file mode 100644 index 9b60df62d5cf..000000000000 --- a/contrib/ncurses/ncurses/tty/hashmap.c +++ /dev/null @@ -1,549 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - ****************************************************************************/ - -/****************************************************************************** - -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. Then if the lines just before or after the pair -are the same or similar, they are a pair too. - - 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 - Bug fixes and improvements by Alexander V. Lukyanov <lav@yars.free.net>, 1997 - -*****************************************************************************/ - -#include <curses.priv.h> -#include <term.h> /* for back_color_erase */ - -MODULE_ID("$Id: hashmap.c,v 1.56 2007/10/13 18:47:25 Miroslav.Lichvar Exp $") - -#ifdef HASHDEBUG - -# define _tracef printf -# undef TR -# define TR(n, a) if (_nc_tracing & (n)) { _tracef a ; putchar('\n'); } -# undef screen_lines -# define screen_lines MAXLINES -# define TEXTWIDTH 1 -int oldnums[MAXLINES], reallines[MAXLINES]; -static NCURSES_CH_T oldtext[MAXLINES][TEXTWIDTH]; -static NCURSES_CH_T newtext[MAXLINES][TEXTWIDTH]; -# define OLDNUM(n) oldnums[n] -# define OLDTEXT(n) oldtext[n] -# define NEWTEXT(m) newtext[m] -# define PENDING(n) 1 - -#else /* !HASHDEBUG */ - -# define OLDNUM(n) SP->_oldnum_list[n] -# define OLDTEXT(n) curscr->_line[n].text -# define NEWTEXT(m) newscr->_line[m].text -# define TEXTWIDTH (curscr->_maxx+1) -# define PENDING(n) (newscr->_line[n].firstchar != _NOCHANGE) - -#endif /* !HASHDEBUG */ - -#define oldhash (SP->oldhash) -#define newhash (SP->newhash) -#define hashtab (SP->hashtab) -#define lines_alloc (SP->hashtab_len) - -#if USE_WIDEC_SUPPORT -#define HASH_VAL(ch) (ch.chars[0]) -#else -#define HASH_VAL(ch) (ch) -#endif - -static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT); - -static NCURSES_INLINE unsigned long -hash(NCURSES_CH_T * text) -{ - int i; - NCURSES_CH_T ch; - unsigned long result = 0; - for (i = TEXTWIDTH; i > 0; i--) { - ch = *text++; - result += (result << 5) + HASH_VAL(ch); - } - return result; -} - -/* approximate update cost */ -static int -update_cost(NCURSES_CH_T * from, NCURSES_CH_T * to) -{ - int cost = 0; - int i; - - for (i = TEXTWIDTH; i > 0; i--, from++, to++) - if (!(CharEq(*from, *to))) - cost++; - - return cost; -} - -static int -update_cost_from_blank(NCURSES_CH_T * to) -{ - int cost = 0; - int i; - NCURSES_CH_T blank = blankchar; - - if (back_color_erase) - SetPair(blank, GetPair(stdscr->_nc_bkgd)); - - for (i = TEXTWIDTH; i > 0; i--, to++) - if (!(CharEq(blank, *to))) - cost++; - - return cost; -} - -/* - * Returns true when moving line 'from' to line 'to' seems to be cost - * effective. 'blank' indicates whether the line 'to' would become blank. - */ -static NCURSES_INLINE bool -cost_effective(const int from, const int to, const bool blank) -{ - int new_from; - - if (from == to) - return FALSE; - - new_from = OLDNUM(from); - if (new_from == _NEWINDEX) - new_from = from; - - /* - * On the left side of >= is the cost before moving; - * on the right side -- cost after moving. - */ - return (((blank ? update_cost_from_blank(NEWTEXT(to)) - : update_cost(OLDTEXT(to), NEWTEXT(to))) - + update_cost(OLDTEXT(new_from), NEWTEXT(from))) - >= ((new_from == from ? update_cost_from_blank(NEWTEXT(from)) - : update_cost(OLDTEXT(new_from), NEWTEXT(from))) - + update_cost(OLDTEXT(from), NEWTEXT(to)))) ? TRUE : FALSE; -} - -static void -grow_hunks(void) -{ - int start, end, shift; - int back_limit, forward_limit; /* limits for cells to fill */ - int back_ref_limit, forward_ref_limit; /* limits for refrences */ - int i; - int next_hunk; - - /* - * This is tricky part. We have unique pairs to use as anchors. - * Use these to deduce the presence of spans of identical lines. - */ - back_limit = 0; - back_ref_limit = 0; - - i = 0; - while (i < screen_lines && OLDNUM(i) == _NEWINDEX) - i++; - for (; i < screen_lines; i = next_hunk) { - start = i; - shift = OLDNUM(i) - i; - - /* get forward limit */ - i = start + 1; - while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i - == shift) - i++; - end = i; - while (i < screen_lines && OLDNUM(i) == _NEWINDEX) - i++; - next_hunk = i; - forward_limit = i; - if (i >= screen_lines || OLDNUM(i) >= i) - forward_ref_limit = i; - else - forward_ref_limit = OLDNUM(i); - - i = start - 1; - /* grow back */ - if (shift < 0) - back_limit = back_ref_limit + (-shift); - while (i >= back_limit) { - if (newhash[i] == oldhash[i + shift] - || cost_effective(i + shift, i, shift < 0)) { - OLDNUM(i) = i + shift; - TR(TRACE_UPDATE | TRACE_MOVE, - ("connected new line %d to old line %d (backward continuation)", - i, i + shift)); - } else { - TR(TRACE_UPDATE | TRACE_MOVE, - ("not connecting new line %d to old line %d (backward continuation)", - i, i + shift)); - break; - } - i--; - } - - i = end; - /* grow forward */ - if (shift > 0) - forward_limit = forward_ref_limit - shift; - while (i < forward_limit) { - if (newhash[i] == oldhash[i + shift] - || cost_effective(i + shift, i, shift > 0)) { - OLDNUM(i) = i + shift; - TR(TRACE_UPDATE | TRACE_MOVE, - ("connected new line %d to old line %d (forward continuation)", - i, i + shift)); - } else { - TR(TRACE_UPDATE | TRACE_MOVE, - ("not connecting new line %d to old line %d (forward continuation)", - i, i + shift)); - break; - } - i++; - } - - back_ref_limit = back_limit = i; - if (shift > 0) - back_ref_limit += shift; - } -} - -NCURSES_EXPORT(void) -_nc_hash_map(void) -{ - HASHMAP *sp; - register int i; - int start, shift, size; - - if (screen_lines > lines_alloc) { - if (hashtab) - free(hashtab); - hashtab = typeMalloc(HASHMAP, (screen_lines + 1) * 2); - if (!hashtab) { - if (oldhash) { - FreeAndNull(oldhash); - } - lines_alloc = 0; - return; - } - lines_alloc = screen_lines; - } - - if (oldhash && newhash) { - /* re-hash only changed lines */ - for (i = 0; i < screen_lines; i++) { - if (PENDING(i)) - newhash[i] = hash(NEWTEXT(i)); - } - } else { - /* re-hash all */ - if (oldhash == 0) - oldhash = typeCalloc(unsigned long, (unsigned) screen_lines); - if (newhash == 0) - newhash = typeCalloc(unsigned long, (unsigned) screen_lines); - if (!oldhash || !newhash) - return; /* malloc failure */ - for (i = 0; i < screen_lines; i++) { - newhash[i] = hash(NEWTEXT(i)); - oldhash[i] = hash(OLDTEXT(i)); - } - } - -#ifdef HASH_VERIFY - for (i = 0; i < screen_lines; i++) { - if (newhash[i] != hash(NEWTEXT(i))) - fprintf(stderr, "error in newhash[%d]\n", i); - if (oldhash[i] != hash(OLDTEXT(i))) - fprintf(stderr, "error in oldhash[%d]\n", i); - } -#endif - - /* - * Set up and count line-hash values. - */ - memset(hashtab, '\0', sizeof(*hashtab) * (screen_lines + 1) * 2); - for (i = 0; i < screen_lines; i++) { - unsigned long hashval = oldhash[i]; - - for (sp = hashtab; sp->hashval; sp++) - if (sp->hashval == hashval) - break; - sp->hashval = hashval; /* in case this is a new entry */ - sp->oldcount++; - sp->oldindex = i; - } - for (i = 0; i < screen_lines; i++) { - unsigned long hashval = newhash[i]; - - for (sp = hashtab; sp->hashval; sp++) - if (sp->hashval == hashval) - break; - sp->hashval = hashval; /* in case this is a new entry */ - sp->newcount++; - sp->newindex = i; - - OLDNUM(i) = _NEWINDEX; /* initialize old indices array */ - } - - /* - * Mark line pairs corresponding to unique hash pairs. - * - * We don't mark lines with offset 0, because it can make fail - * extending hunks by cost_effective. Otherwise, it does not - * have any side effects. - */ - for (sp = hashtab; sp->hashval; sp++) - if (sp->oldcount == 1 && sp->newcount == 1 - && sp->oldindex != sp->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; - } - - grow_hunks(); - - /* - * Eliminate bad or impossible shifts -- this includes removing - * those hunks which could not grow because of conflicts, as well - * those which are to be moved too far, they are likely to destroy - * more than carry. - */ - for (i = 0; i < screen_lines;) { - while (i < screen_lines && OLDNUM(i) == _NEWINDEX) - i++; - if (i >= screen_lines) - break; - start = i; - shift = OLDNUM(i) - i; - i++; - while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i - == shift) - i++; - size = i - start; - if (size < 3 || size + min(size / 8, 2) < abs(shift)) { - while (start < i) { - OLDNUM(start) = _NEWINDEX; - start++; - } - } - } - - /* After clearing invalid hunks, try grow the rest. */ - grow_hunks(); -} - -NCURSES_EXPORT(void) -_nc_make_oldhash(int i) -{ - if (oldhash) - oldhash[i] = hash(OLDTEXT(i)); -} - -NCURSES_EXPORT(void) -_nc_scroll_oldhash(int n, int top, int bot) -{ - size_t size; - int i; - - if (!oldhash) - return; - - size = sizeof(*oldhash) * (bot - top + 1 - abs(n)); - if (n > 0) { - memmove(oldhash + top, oldhash + top + n, size); - for (i = bot; i > bot - n; i--) - oldhash[i] = hash(OLDTEXT(i)); - } else { - memmove(oldhash + top - n, oldhash + top, size); - for (i = top; i < top - n; i++) - oldhash[i] = hash(OLDTEXT(i)); - } -} - -#ifdef HASHDEBUG -static void -usage(void) -{ - static const char *table[] = - { - "hashmap test-driver", - "", - "# comment", - "l get initial line number vector", - "n use following letters as text of new lines", - "o use following letters as text of old lines", - "d dump state of test arrays", - "h apply hash mapper and see scroll optimization", - "? this message" - }; - size_t n; - for (n = 0; n < sizeof(table) / sizeof(table[0]); n++) - fprintf(stderr, "%s\n", table[n]); -} - -int -main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) -{ - char line[BUFSIZ], *st; - int n; - - if (setupterm(NULL, fileno(stdout), (int *) 0) == ERR) - return EXIT_FAILURE; - (void) _nc_alloc_screen(); - - for (n = 0; n < screen_lines; n++) { - reallines[n] = n; - oldnums[n] = _NEWINDEX; - CharOf(oldtext[n][0]) = CharOf(newtext[n][0]) = '.'; - } - - if (isatty(fileno(stdin))) - usage(); - -#ifdef TRACE - _nc_tracing = TRACE_MOVE; -#endif - for (;;) { - /* grab a test command */ - if (fgets(line, sizeof(line), stdin) == (char *) NULL) - break; - - switch (line[0]) { - case '#': /* comment */ - (void) fputs(line, stderr); - break; - - case 'l': /* get initial line number vector */ - for (n = 0; n < screen_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 < screen_lines; n++) - CharOf(newtext[n][0]) = '.'; - for (n = 0; n < screen_lines; n++) - if (line[n + 1] == '\n') - break; - else - CharOf(newtext[n][0]) = line[n + 1]; - break; - - case 'o': /* use following letters as text of old lines */ - for (n = 0; n < screen_lines; n++) - CharOf(oldtext[n][0]) = '.'; - for (n = 0; n < screen_lines; n++) - if (line[n + 1] == '\n') - break; - else - CharOf(oldtext[n][0]) = line[n + 1]; - break; - - case 'd': /* dump state of test arrays */ -#ifdef TRACE - _nc_linedump(); -#endif - (void) fputs("Old lines: [", stdout); - for (n = 0; n < screen_lines; n++) - putchar(CharOf(oldtext[n][0])); - putchar(']'); - putchar('\n'); - (void) fputs("New lines: [", stdout); - for (n = 0; n < screen_lines; n++) - putchar(CharOf(newtext[n][0])); - putchar(']'); - putchar('\n'); - break; - - case 'h': /* apply hash mapper and see scroll optimization */ - _nc_hash_map(); - (void) fputs("Result:\n", stderr); -#ifdef TRACE - _nc_linedump(); -#endif - _nc_scroll_optimize(); - (void) fputs("Done.\n", stderr); - break; - default: - case '?': - usage(); - break; - } - } -#if NO_LEAKS - _nc_free_and_exit(EXIT_SUCCESS); -#else - return EXIT_SUCCESS; -#endif -} - -#endif /* HASHDEBUG */ - -/* hashmap.c ends here */ diff --git a/contrib/ncurses/ncurses/tty/lib_mvcur.c b/contrib/ncurses/ncurses/tty/lib_mvcur.c deleted file mode 100644 index 19984c92333e..000000000000 --- a/contrib/ncurses/ncurses/tty/lib_mvcur.c +++ /dev/null @@ -1,1245 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/* -** lib_mvcur.c -** -** The routines for moving the physical cursor and scrolling: -** -** void _nc_mvcur_init(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) -** -** 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 -** enough, it doesn't use its own hardware-scrolling routine to scroll up -** destination lines for out-of-bounds addresses! -** old ncurses optimizer: less accurate cost computations (in fact, -** it was broken and had to be commented out!). -** -** Compile with -DMAIN to build an interactive tester/timer for the movement -** optimizer. You can use it to investigate the optimizer's behavior. -** You can also use it for tuning the formulas used to determine whether -** or not full optimization is attempted. -** -** This code has a nasty tendency to find bugs in terminfo entries, because it -** exercises the non-cup movement capabilities heavily. If you think you've -** found a bug, try deleting subsets of the following capabilities (arranged -** in decreasing order of suspiciousness): it, tab, cbt, hpa, vpa, cuu, cud, -** 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 -** 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 -** effectiveness. -**/ - -/**************************************************************************** - * - * Constants and macros for optimizer tuning. - * - ****************************************************************************/ - -/* - * The average overhead of a full optimization computation in character - * transmission times. If it's too high, the algorithm will be a bit - * over-biased toward using cup rather than local motions; if it's too - * low, the algorithm may spend more time than is strictly optimal - * looking for non-cup motions. Profile the optimizer using the `t' - * command of the exerciser (see below), and round to the nearest integer. - * - * Yes, I (esr) thought about computing expected overhead dynamically, say - * by derivation from a running average of optimizer times. But the - * whole point of this optimization is to *decrease* the frequency of - * system calls. :-) - */ -#define COMPUTE_OVERHEAD 1 /* I use a 90MHz Pentium @ 9.6Kbps */ - -/* - * LONG_DIST is the distance we consider to be just as costly to move over as a - * cup sequence is to emit. In other words, it's the length of a cup sequence - * adjusted for average computation overhead. The magic number is the length - * of "\033[yy;xxH", the typical cup sequence these days. - */ -#define LONG_DIST (8 - COMPUTE_OVERHEAD) - -/* - * Tell whether a motion is optimizable by local motions. Needs to be cheap to - * compute. In general, all the fast moves go to either the right or left edge - * of the screen. So any motion to a location that is (a) further away than - * LONG_DIST and (b) further inward from the right or left edge than LONG_DIST, - * we'll consider nonlocal. - */ -#define NOT_LOCAL(fy, fx, ty, tx) ((tx > LONG_DIST) \ - && (tx < screen_columns - 1 - LONG_DIST) \ - && (abs(ty-fy) + abs(tx-fx) > LONG_DIST)) - -/**************************************************************************** - * - * External interfaces - * - ****************************************************************************/ - -/* - * For this code to work OK, the following components must live in the - * screen structure: - * - * 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) - *#if USE_HARD_TABS - * int _ht_cost; // cost of (tab) - * int _cbt_cost; // cost of (back_tab) - *#endif USE_HARD_TABS - * 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) - * int _ech_cost; // cost of (erase_chars) - * int _rep_cost; // cost of (repeat_char) - * - * The USE_HARD_TABS switch controls whether it is reliable to use tab/backtabs - * for local motions. On many systems, it's not, due to uncertainties about - * tab delays and whether or not tabs will be expanded in raw mode. If you - * have parm_right_cursor, tab motions don't win you a lot anyhow. - */ - -#include <curses.priv.h> -#include <term.h> -#include <ctype.h> - -MODULE_ID("$Id: lib_mvcur.c,v 1.110 2007/08/11 16:15:57 tom Exp $") - -#define WANT_CHAR(y, x) SP->_newscr->_line[y].text[x] /* desired state */ -#define BAUDRATE cur_term->_baudrate /* bits per second */ - -#if defined(MAIN) || defined(NCURSES_TEST) -#include <sys/time.h> - -static bool profiling = FALSE; -static float diff; -#endif /* MAIN */ - -#define OPT_SIZE 512 - -static int normalized_cost(const char *const cap, int affcnt); - -/**************************************************************************** - * - * Initialization/wrapup (including cost pre-computation) - * - ****************************************************************************/ - -#ifdef TRACE -static int -trace_cost_of(const char *capname, const char *cap, int affcnt) -{ - int result = _nc_msec_cost(cap, affcnt); - TR(TRACE_CHARPUT | TRACE_MOVE, - ("CostOf %s %d %s", capname, result, _nc_visbuf(cap))); - return result; -} -#define CostOf(cap,affcnt) trace_cost_of(#cap,cap,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 %s", capname, result, _nc_visbuf(cap))); - return result; -} -#define NormalizedCost(cap,affcnt) trace_normalized_cost(#cap,cap,affcnt); - -#else - -#define CostOf(cap,affcnt) _nc_msec_cost(cap,affcnt); -#define NormalizedCost(cap,affcnt) normalized_cost(cap,affcnt); - -#endif - -NCURSES_EXPORT(int) -_nc_msec_cost(const char *const cap, int affcnt) -/* compute the cost of a given operation */ -{ - if (cap == 0) - return (INFINITY); - else { - const char *cp; - float cum_cost = 0.0; - - for (cp = cap; *cp; cp++) { - /* extract padding, either mandatory or required */ - if (cp[0] == '$' && cp[1] == '<' && strchr(cp, '>')) { - float number = 0.0; - - for (cp += 2; *cp != '>'; cp++) { - if (isdigit(UChar(*cp))) - number = number * 10 + (*cp - '0'); - else if (*cp == '*') - number *= affcnt; - else if (*cp == '.' && (*++cp != '>') && isdigit(UChar(*cp))) - number += (*cp - '0') / 10.0; - } - -#if NCURSES_NO_PADDING - if (!(SP->_no_padding)) -#endif - cum_cost += number * 10; - } else - cum_cost += SP->_char_padding; - } - - return ((int) cum_cost); - } -} - -static int -normalized_cost(const char *const cap, int affcnt) -/* compute the effective character-count for an operation (round up) */ -{ - int cost = _nc_msec_cost(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) { - TPUTS_TRACE("change_scroll_region"); - putp(TPARM_2(change_scroll_region, 0, screen_lines - 1)); - } -} - -NCURSES_EXPORT(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(); - SP->_cursrow = SP->_curscol = -1; - - /* restore cursor shape */ - if (SP->_cursor != -1) { - int cursor = SP->_cursor; - SP->_cursor = -1; - curs_set(cursor); - } -} - -NCURSES_EXPORT(void) -_nc_mvcur_init(void) -/* initialize the cost structure */ -{ - if (isatty(fileno(SP->_ofp))) - SP->_char_padding = ((BAUDBYTE * 1000 * 10) - / (BAUDRATE > 0 ? BAUDRATE : 9600)); - else - SP->_char_padding = 1; /* must be nonzero */ - 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 = CostOf(carriage_return, 0); - SP->_home_cost = CostOf(cursor_home, 0); - SP->_ll_cost = CostOf(cursor_to_ll, 0); -#if USE_HARD_TABS - if (getenv("NCURSES_NO_HARD_TABS") == 0) { - SP->_ht_cost = CostOf(tab, 0); - SP->_cbt_cost = CostOf(back_tab, 0); - } else { - SP->_ht_cost = INFINITY; - SP->_cbt_cost = INFINITY; - } -#endif /* USE_HARD_TABS */ - 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); - - SP->_smir_cost = CostOf(enter_insert_mode, 0); - SP->_rmir_cost = CostOf(exit_insert_mode, 0); - SP->_ip_cost = 0; - if (insert_padding) { - SP->_ip_cost = CostOf(insert_padding, 0); - } - - /* - * Assumption: if the terminal has memory_relative addressing, the - * initialization strings or smcup will set single-page mode so we - * can treat it like absolute screen addressing. This seems to be true - * for all cursor_mem_address terminal types in the terminfo database. - */ - SP->_address_cursor = cursor_address ? cursor_address : cursor_mem_address; - - /* - * Parametrized local-motion strings. This static cost computation - * depends on the following assumptions: - * - * (1) They never have * padding. In the entire master terminfo database - * as of March 1995, only the obsolete Zenith Z-100 pc violates this. - * (Proportional padding is found mainly in insert, delete and scroll - * capabilities). - * - * (2) The average case of cup has two two-digit parameters. Strictly, - * the average case for a 24 * 80 screen has ((10*10*(1 + 1)) + - * (14*10*(1 + 2)) + (10*70*(2 + 1)) + (14*70*4)) / (24*80) = 3.458 - * 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/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 - * (strictly, (((10 * 1) + (14 * 2)) / 24) = 1.5833). - * - * All these averages depend on the assumption that all parameter values - * are equally probable. - */ - SP->_cup_cost = CostOf(TPARM_2(SP->_address_cursor, 23, 23), 1); - SP->_cub_cost = CostOf(TPARM_1(parm_left_cursor, 23), 1); - SP->_cuf_cost = CostOf(TPARM_1(parm_right_cursor, 23), 1); - SP->_cud_cost = CostOf(TPARM_1(parm_down_cursor, 23), 1); - SP->_cuu_cost = CostOf(TPARM_1(parm_up_cursor, 23), 1); - SP->_hpa_cost = CostOf(TPARM_1(column_address, 23), 1); - SP->_vpa_cost = CostOf(TPARM_1(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); - - /* - * If this is a bce-terminal, we want to bias the choice so we use clr_eol - * rather than spaces at the end of a line. - */ - if (back_color_erase) - SP->_el_cost = 0; - - /* parameterized screen-update strings */ - SP->_dch_cost = NormalizedCost(TPARM_1(parm_dch, 23), 1); - SP->_ich_cost = NormalizedCost(TPARM_1(parm_ich, 23), 1); - SP->_ech_cost = NormalizedCost(TPARM_1(erase_chars, 23), 1); - SP->_rep_cost = NormalizedCost(TPARM_2(repeat_char, ' ', 23), 1); - - SP->_cup_ch_cost = NormalizedCost(TPARM_2(SP->_address_cursor, 23, 23), 1); - SP->_hpa_ch_cost = NormalizedCost(TPARM_1(column_address, 23), 1); - SP->_cuf_ch_cost = NormalizedCost(TPARM_1(parm_right_cursor, 23), 1); - SP->_inline_cost = min(SP->_cup_ch_cost, - min(SP->_hpa_ch_cost, - SP->_cuf_ch_cost)); - - /* - * If save_cursor is used within enter_ca_mode, we should not use it for - * scrolling optimization, since the corresponding restore_cursor is not - * nested on the various terminals (vt100, xterm, etc.) which use this - * feature. - */ - if (save_cursor != 0 - && enter_ca_mode != 0 - && strstr(enter_ca_mode, save_cursor) != 0) { - T(("...suppressed sc/rc capability due to conflict with smcup/rmcup")); - save_cursor = 0; - restore_cursor = 0; - } - - /* - * 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(); -} - -NCURSES_EXPORT(void) -_nc_mvcur_wrap(void) -/* wrap up cursor-addressing mode */ -{ - /* leave cursor at screen bottom */ - mvcur(-1, -1, screen_lines - 1, 0); - - /* set cursor to normal mode */ - if (SP->_cursor != -1) - curs_set(1); - - if (exit_ca_mode) { - TPUTS_TRACE("exit_ca_mode"); - putp(exit_ca_mode); - } - /* - * 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'); -} - -/**************************************************************************** - * - * Optimized cursor movement - * - ****************************************************************************/ - -/* - * Perform repeated-append, returning cost - */ -static NCURSES_INLINE int -repeated_append(string_desc * target, int total, int num, int repeat, const char *src) -{ - size_t need = repeat * strlen(src); - - if (need < target->s_size) { - while (repeat-- > 0) { - if (_nc_safe_strcat(target, src)) { - total += num; - } else { - total = INFINITY; - break; - } - } - } else { - total = INFINITY; - } - return total; -} - -#ifndef NO_OPTIMIZE -#define NEXTTAB(fr) (fr + init_tabs - (fr % init_tabs)) - -/* - * Assume back_tab (CBT) does not wrap backwards at the left margin, return - * a negative value at that point to simplify the loop. - */ -#define LASTTAB(fr) ((fr > 0) ? ((fr - 1) / init_tabs) * init_tabs : -1) - -static int -relative_move(string_desc * target, 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) */ -{ - string_desc save; - int n, vcost = 0, hcost = 0; - - (void) _nc_str_copy(&save, target); - - if (to_y != from_y) { - vcost = INFINITY; - - if (row_address != 0 - && _nc_safe_strcat(target, TPARM_1(row_address, to_y))) { - vcost = SP->_vpa_cost; - } - - if (to_y > from_y) { - n = (to_y - from_y); - - if (parm_down_cursor - && SP->_cud_cost < vcost - && _nc_safe_strcat(_nc_str_copy(target, &save), - TPARM_1(parm_down_cursor, n))) { - vcost = SP->_cud_cost; - } - - if (cursor_down - && (*cursor_down != '\n' || SP->_nl) - && (n * SP->_cud1_cost < vcost)) { - vcost = repeated_append(_nc_str_copy(target, &save), 0, - SP->_cud1_cost, n, cursor_down); - } - } else { /* (to_y < from_y) */ - n = (from_y - to_y); - - if (parm_up_cursor - && SP->_cuu_cost < vcost - && _nc_safe_strcat(_nc_str_copy(target, &save), - TPARM_1(parm_up_cursor, n))) { - vcost = SP->_cuu_cost; - } - - if (cursor_up && (n * SP->_cuu1_cost < vcost)) { - vcost = repeated_append(_nc_str_copy(target, &save), 0, - SP->_cuu1_cost, n, cursor_up); - } - } - - if (vcost == INFINITY) - return (INFINITY); - } - - save = *target; - - if (to_x != from_x) { - char str[OPT_SIZE]; - string_desc check; - - hcost = INFINITY; - - if (column_address - && _nc_safe_strcat(_nc_str_copy(target, &save), - TPARM_1(column_address, to_x))) { - hcost = SP->_hpa_cost; - } - - if (to_x > from_x) { - n = to_x - from_x; - - if (parm_right_cursor - && SP->_cuf_cost < hcost - && _nc_safe_strcat(_nc_str_copy(target, &save), - TPARM_1(parm_right_cursor, n))) { - hcost = SP->_cuf_cost; - } - - if (cursor_right) { - int lhcost = 0; - - (void) _nc_str_init(&check, str, sizeof(str)); - -#if USE_HARD_TABS - /* use hard tabs, if we have them, to do as much as possible */ - if (init_tabs > 0 && tab) { - int nxt, fr; - - for (fr = from_x; (nxt = NEXTTAB(fr)) <= to_x; fr = nxt) { - lhcost = repeated_append(&check, lhcost, - SP->_ht_cost, 1, tab); - if (lhcost == INFINITY) - break; - } - - n = to_x - fr; - from_x = fr; - } -#endif /* USE_HARD_TABS */ - - if (n <= 0 || n >= (int) check.s_size) - ovw = FALSE; -#if BSD_TPUTS - /* - * If we're allowing BSD-style padding in tputs, don't generate - * a string with a leading digit. Otherwise, that will be - * interpreted as a padding value rather than sent to the - * screen. - */ - if (ovw - && n > 0 - && n < (int) check.s_size - && vcost == 0 - && str[0] == '\0') { - int wanted = CharOf(WANT_CHAR(to_y, from_x)); - if (is8bits(wanted) && isdigit(wanted)) - ovw = FALSE; - } -#endif - /* - * 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 - * is true between the time a hardware scroll has been done - * and the time the structure WANT_CHAR would access has been - * updated. - */ - if (ovw) { - int i; - - for (i = 0; i < n; i++) { - NCURSES_CH_T ch = WANT_CHAR(to_y, from_x + i); - if (!SameAttrOf(ch, SCREEN_ATTRS(SP)) -#if USE_WIDEC_SUPPORT - || !Charable(ch) -#endif - ) { - ovw = FALSE; - break; - } - } - } - if (ovw) { - int i; - - for (i = 0; i < n; i++) - *check.s_tail++ = CharOf(WANT_CHAR(to_y, from_x + i)); - *check.s_tail = '\0'; - check.s_size -= n; - lhcost += n * SP->_char_padding; - } else { - lhcost = repeated_append(&check, lhcost, SP->_cuf1_cost, - n, cursor_right); - } - - if (lhcost < hcost - && _nc_safe_strcat(_nc_str_copy(target, &save), str)) { - hcost = lhcost; - } - } - } else { /* (to_x < from_x) */ - n = from_x - to_x; - - if (parm_left_cursor - && SP->_cub_cost < hcost - && _nc_safe_strcat(_nc_str_copy(target, &save), - TPARM_1(parm_left_cursor, n))) { - hcost = SP->_cub_cost; - } - - if (cursor_left) { - int lhcost = 0; - - (void) _nc_str_init(&check, str, sizeof(str)); - -#if USE_HARD_TABS - if (init_tabs > 0 && back_tab) { - int nxt, fr; - - for (fr = from_x; (nxt = LASTTAB(fr)) >= to_x; fr = nxt) { - lhcost = repeated_append(&check, lhcost, - SP->_cbt_cost, 1, back_tab); - if (lhcost == INFINITY) - break; - } - - n = fr - to_x; - } -#endif /* USE_HARD_TABS */ - - lhcost = repeated_append(&check, lhcost, SP->_cub1_cost, n, cursor_left); - - if (lhcost < hcost - && _nc_safe_strcat(_nc_str_copy(target, &save), str)) { - hcost = lhcost; - } - } - } - - if (hcost == INFINITY) - return (INFINITY); - } - - return (vcost + hcost); -} -#endif /* !NO_OPTIMIZE */ - -/* - * With the machinery set up above, it's conceivable that - * onscreen_mvcur could be modified into a recursive function that does - * an alpha-beta search of motion space, as though it were a chess - * move tree, with the weight function being boolean and the search - * depth equated to length of string. However, this would jack up the - * computation cost a lot, especially on terminals without a cup - * capability constraining the search tree depth. So we settle for - * the simpler method below. - */ - -static NCURSES_INLINE int -onscreen_mvcur(int yold, int xold, int ynew, int xnew, bool ovw) -/* onscreen move from (yold, xold) to (ynew, xnew) */ -{ - string_desc result; - char buffer[OPT_SIZE]; - int tactic = 0, newcost, usecost = INFINITY; - int t5_cr_cost; - -#if defined(MAIN) || defined(NCURSES_TEST) - struct timeval before, after; - - gettimeofday(&before, NULL); -#endif /* MAIN */ - -#define NullResult _nc_str_null(&result, sizeof(buffer)) -#define InitResult _nc_str_init(&result, buffer, sizeof(buffer)) - - /* tactic #0: use direct cursor addressing */ - if (_nc_safe_strcpy(InitResult, TPARM_2(SP->_address_cursor, ynew, xnew))) { - tactic = 0; - usecost = SP->_cup_cost; - -#if defined(TRACE) || defined(NCURSES_TEST) - if (!(_nc_optimize_enable & OPTIMIZE_MVCUR)) - goto nonlocal; -#endif /* TRACE */ - - /* - * We may be able to tell in advance that the full optimization - * will probably not be worth its overhead. Also, don't try to - * use local movement if the current attribute is anything but - * A_NORMAL...there are just too many ways this can screw up - * (like, say, local-movement \n getting mapped to some obscure - * character because A_ALTCHARSET is on). - */ - if (yold == -1 || xold == -1 || NOT_LOCAL(yold, xold, ynew, xnew)) { -#if defined(MAIN) || defined(NCURSES_TEST) - if (!profiling) { - (void) fputs("nonlocal\n", stderr); - goto nonlocal; /* always run the optimizer if profiling */ - } -#else - goto nonlocal; -#endif /* MAIN */ - } - } -#ifndef NO_OPTIMIZE - /* tactic #1: use local movement */ - if (yold != -1 && xold != -1 - && ((newcost = relative_move(NullResult, yold, xold, ynew, xnew, - ovw)) != INFINITY) - && newcost < usecost) { - tactic = 1; - usecost = newcost; - } - - /* tactic #2: use carriage-return + local movement */ - if (yold != -1 && carriage_return - && ((newcost = relative_move(NullResult, yold, 0, ynew, xnew, ovw)) - != INFINITY) - && SP->_cr_cost + newcost < usecost) { - tactic = 2; - usecost = SP->_cr_cost + newcost; - } - - /* tactic #3: use home-cursor + local movement */ - if (cursor_home - && ((newcost = relative_move(NullResult, 0, 0, ynew, xnew, ovw)) != INFINITY) - && SP->_home_cost + newcost < usecost) { - tactic = 3; - usecost = SP->_home_cost + newcost; - } - - /* tactic #4: use home-down + local movement */ - if (cursor_to_ll - && ((newcost = relative_move(NullResult, screen_lines - 1, 0, ynew, - xnew, ovw)) != INFINITY) - && SP->_ll_cost + newcost < usecost) { - tactic = 4; - usecost = SP->_ll_cost + newcost; - } - - /* - * tactic #5: use left margin for wrap to right-hand side, - * unless strange wrap behavior indicated by xenl might hose us. - */ - t5_cr_cost = (xold > 0 ? SP->_cr_cost : 0); - if (auto_left_margin && !eat_newline_glitch - && yold > 0 && cursor_left - && ((newcost = relative_move(NullResult, yold - 1, screen_columns - - 1, ynew, xnew, ovw)) != INFINITY) - && t5_cr_cost + SP->_cub1_cost + newcost < usecost) { - tactic = 5; - usecost = t5_cr_cost + SP->_cub1_cost + newcost; - } - - /* - * These cases are ordered by estimated relative frequency. - */ - if (tactic) - InitResult; - switch (tactic) { - case 1: - (void) relative_move(&result, yold, xold, ynew, xnew, ovw); - break; - case 2: - (void) _nc_safe_strcpy(&result, carriage_return); - (void) relative_move(&result, yold, 0, ynew, xnew, ovw); - break; - case 3: - (void) _nc_safe_strcpy(&result, cursor_home); - (void) relative_move(&result, 0, 0, ynew, xnew, ovw); - break; - case 4: - (void) _nc_safe_strcpy(&result, cursor_to_ll); - (void) relative_move(&result, screen_lines - 1, 0, ynew, xnew, ovw); - break; - case 5: - if (xold > 0) - (void) _nc_safe_strcat(&result, carriage_return); - (void) _nc_safe_strcat(&result, cursor_left); - (void) relative_move(&result, yold - 1, screen_columns - 1, ynew, - xnew, ovw); - break; - } -#endif /* !NO_OPTIMIZE */ - - nonlocal: -#if defined(MAIN) || defined(NCURSES_TEST) - gettimeofday(&after, NULL); - diff = after.tv_usec - before.tv_usec - + (after.tv_sec - before.tv_sec) * 1000000; - if (!profiling) - (void) fprintf(stderr, - "onscreen: %d microsec, %f 28.8Kbps char-equivalents\n", - (int) diff, diff / 288); -#endif /* MAIN */ - - if (usecost != INFINITY) { - TPUTS_TRACE("mvcur"); - tputs(buffer, 1, _nc_outch); - SP->_cursrow = ynew; - SP->_curscol = xnew; - return (OK); - } else - return (ERR); -} - -NCURSES_EXPORT(int) -mvcur(int yold, int xold, int ynew, int xnew) -/* optimized cursor move from (yold, xold) to (ynew, xnew) */ -{ - NCURSES_CH_T oldattr; - int code; - - TR(TRACE_CALLS | TRACE_MOVE, (T_CALLED("mvcur(%d,%d,%d,%d)"), - yold, xold, ynew, xnew)); - - if (SP == 0) { - code = ERR; - } else if (yold == ynew && xold == xnew) { - code = OK; - } else { - - /* - * Most work here is rounding for terminal boundaries getting the - * column position implied by wraparound or the lack thereof and - * rolling up the screen to get ynew on the screen. - */ - if (xnew >= screen_columns) { - ynew += xnew / screen_columns; - xnew %= screen_columns; - } - - /* - * Force restore even if msgr is on when we're in an alternate - * character set -- these have a strong tendency to screw up the CR & - * LF used for local character motions! - */ - oldattr = SCREEN_ATTRS(SP); - if ((AttrOf(oldattr) & A_ALTCHARSET) - || (AttrOf(oldattr) && !move_standout_mode)) { - TR(TRACE_CHARPUT, ("turning off (%#lx) %s before move", - (unsigned long) AttrOf(oldattr), - _traceattr(AttrOf(oldattr)))); - (void) VIDATTR(A_NORMAL, 0); - } - - if (xold >= screen_columns) { - int l; - - if (SP->_nl) { - l = (xold + 1) / screen_columns; - yold += l; - if (yold >= screen_lines) - l -= (yold - screen_lines - 1); - - if (l > 0) { - if (carriage_return) { - TPUTS_TRACE("carriage_return"); - putp(carriage_return); - } else - _nc_outch('\r'); - xold = 0; - - while (l > 0) { - if (newline) { - TPUTS_TRACE("newline"); - putp(newline); - } else - _nc_outch('\n'); - l--; - } - } - } else { - /* - * If caller set nonl(), we cannot really use newlines to - * position to the next row. - */ - xold = -1; - yold = -1; - } - } - - if (yold > screen_lines - 1) - yold = screen_lines - 1; - if (ynew > screen_lines - 1) - ynew = screen_lines - 1; - - /* destination location is on screen now */ - code = onscreen_mvcur(yold, xold, ynew, xnew, TRUE); - - /* - * Restore attributes if we disabled them before moving. - */ - if (!SameAttrOf(oldattr, SCREEN_ATTRS(SP))) { - TR(TRACE_CHARPUT, ("turning on (%#lx) %s after move", - (unsigned long) AttrOf(oldattr), - _traceattr(AttrOf(oldattr)))); - (void) VIDATTR(AttrOf(oldattr), GetPair(oldattr)); - } - } - returnCode(code); -} - -#if defined(TRACE) || defined(NCURSES_TEST) -NCURSES_EXPORT_VAR(int) _nc_optimize_enable = OPTIMIZE_ALL; -#endif - -#if defined(MAIN) || defined(NCURSES_TEST) -/**************************************************************************** - * - * Movement optimizer test code - * - ****************************************************************************/ - -#include <tic.h> -#include <dump_entry.h> -#include <time.h> - -NCURSES_EXPORT_VAR(const char *) _nc_progname = "mvcur"; - -static unsigned long xmits; - -/* these override lib_tputs.c */ -NCURSES_EXPORT(int) -tputs(const char *string, int affcnt GCC_UNUSED, int (*outc) (int) GCC_UNUSED) -/* stub tputs() that dumps sequences in a visible form */ -{ - if (profiling) - xmits += strlen(string); - else - (void) fputs(_nc_visbuf(string), stdout); - return (OK); -} - -NCURSES_EXPORT(int) -putp(const char *string) -{ - return (tputs(string, 1, _nc_outch)); -} - -NCURSES_EXPORT(int) -_nc_outch(int ch) -{ - putc(ch, stdout); - return OK; -} - -NCURSES_EXPORT(int) -delay_output(int ms GCC_UNUSED) -{ - return OK; -} - -static char tname[PATH_MAX]; - -static void -load_term(void) -{ - (void) setupterm(tname, STDOUT_FILENO, NULL); -} - -static int -roll(int n) -{ - int i, j; - - i = (RAND_MAX / n) * n; - while ((j = rand()) >= i) - continue; - return (j % n); -} - -int -main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) -{ - strcpy(tname, getenv("TERM")); - load_term(); - _nc_setupscreen(lines, columns, stdout, FALSE, 0); - baudrate(); - - _nc_mvcur_init(); - NC_BUFFERED(FALSE); - - (void) puts("The mvcur tester. Type ? for help"); - - fputs("smcup:", stdout); - putchar('\n'); - - for (;;) { - int fy, fx, ty, tx, n, i; - char buf[BUFSIZ], capname[BUFSIZ]; - - (void) fputs("> ", stdout); - (void) fgets(buf, sizeof(buf), stdin); - - if (buf[0] == '?') { - (void) puts("? -- display this help message"); - (void) - puts("fy fx ty tx -- (4 numbers) display (fy,fx)->(ty,tx) move"); - (void) puts("s[croll] n t b m -- display scrolling sequence"); - (void) - printf("r[eload] -- reload terminal info for %s\n", - termname()); - (void) - puts("l[oad] <term> -- load terminal info for type <term>"); - (void) puts("d[elete] <cap> -- delete named capability"); - (void) puts("i[nspect] -- display terminal capabilities"); - (void) - puts("c[ost] -- dump cursor-optimization cost table"); - (void) puts("o[optimize] -- toggle movement optimization"); - (void) - puts("t[orture] <num> -- torture-test with <num> random moves"); - (void) puts("q[uit] -- quit the program"); - } else if (sscanf(buf, "%d %d %d %d", &fy, &fx, &ty, &tx) == 4) { - struct timeval before, after; - - putchar('"'); - - gettimeofday(&before, NULL); - mvcur(fy, fx, ty, tx); - gettimeofday(&after, NULL); - - printf("\" (%ld msec)\n", - (long) (after.tv_usec - before.tv_usec - + (after.tv_sec - before.tv_sec) - * 1000000)); - } else if (sscanf(buf, "s %d %d %d %d", &fy, &fx, &ty, &tx) == 4) { - struct timeval before, after; - - putchar('"'); - - gettimeofday(&before, NULL); - _nc_scrolln(fy, fx, ty, tx); - gettimeofday(&after, NULL); - - printf("\" (%ld msec)\n", - (long) (after.tv_usec - before.tv_usec + (after.tv_sec - - before.tv_sec) - * 1000000)); - } else if (buf[0] == 'r') { - (void) strcpy(tname, termname()); - load_term(); - } else if (sscanf(buf, "l %s", tname) == 1) { - load_term(); - } else if (sscanf(buf, "d %s", capname) == 1) { - struct name_table_entry const *np = _nc_find_entry(capname, - _nc_get_hash_table(FALSE)); - - if (np == NULL) - (void) printf("No such capability as \"%s\"\n", capname); - else { - switch (np->nte_type) { - case BOOLEAN: - cur_term->type.Booleans[np->nte_index] = FALSE; - (void) - printf("Boolean capability `%s' (%d) turned off.\n", - np->nte_name, np->nte_index); - break; - - case NUMBER: - cur_term->type.Numbers[np->nte_index] = ABSENT_NUMERIC; - (void) printf("Number capability `%s' (%d) set to -1.\n", - np->nte_name, np->nte_index); - break; - - case STRING: - cur_term->type.Strings[np->nte_index] = ABSENT_STRING; - (void) printf("String capability `%s' (%d) deleted.\n", - np->nte_name, np->nte_index); - break; - } - } - } else if (buf[0] == 'i') { - dump_init((char *) NULL, F_TERMINFO, S_TERMINFO, 70, 0, FALSE); - dump_entry(&cur_term->type, FALSE, TRUE, 0, 0); - putchar('\n'); - } else if (buf[0] == 'o') { - if (_nc_optimize_enable & OPTIMIZE_MVCUR) { - _nc_optimize_enable &= ~OPTIMIZE_MVCUR; - (void) puts("Optimization is now off."); - } else { - _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 - * to within a millisecond or three. - * - * The `overhead' field of the report will help you pick a - * COMPUTE_OVERHEAD figure appropriate for your processor and - * expected line speed. The `total estimated time' is - * computation time plus a character-transmission time - * estimate computed from the number of transmits and the baud - * rate. - * - * Use this together with the `o' command to get a read on the - * optimizer's effectiveness. Compare the total estimated times - * for `t' runs of the same length in both optimized and un-optimized - * modes. As long as the optimized times are less, the optimizer - * is winning. - */ - else if (sscanf(buf, "t %d", &n) == 1) { - float cumtime = 0.0, perchar; - int speeds[] = - {2400, 9600, 14400, 19200, 28800, 38400, 0}; - - srand((unsigned) (getpid() + time((time_t *) 0))); - profiling = TRUE; - 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 - * typical of doupdate()'s usage pattern. Still, - * until we have better data... - */ -#ifdef FIND_COREDUMP - int from_y = roll(lines); - int to_y = roll(lines); - int from_x = roll(columns); - int to_x = roll(columns); - - printf("(%d,%d) -> (%d,%d)\n", from_y, from_x, to_y, to_x); - mvcur(from_y, from_x, to_y, to_x); -#else - mvcur(roll(lines), roll(columns), roll(lines), roll(columns)); -#endif /* FIND_COREDUMP */ - if (diff) - cumtime += diff; - } - profiling = FALSE; - - /* - * Average milliseconds per character optimization time. - * This is the key figure to watch when tuning the optimizer. - */ - perchar = cumtime / 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 - * transmission both. Transmission time is an estimate - * assuming 9 bits/char, 8 bits + 1 stop bit. - */ - float totalest = cumtime + xmits * 9 * 1e6 / speeds[i]; - - /* - * Per-character optimization overhead in character transmits - * at the current speed. Round this to the nearest integer - * to figure COMPUTE_OVERHEAD for the speed. - */ - float overhead = speeds[i] * perchar / 1e6; - - (void) - printf("%6d bps: %3.2f char-xmits overhead; total estimated time %15.2f\n", - speeds[i], overhead, totalest); - } - } else if (buf[0] == 'c') { - (void) printf("char padding: %d\n", SP->_char_padding); - (void) printf("cr cost: %d\n", SP->_cr_cost); - (void) printf("cup cost: %d\n", SP->_cup_cost); - (void) printf("home cost: %d\n", SP->_home_cost); - (void) printf("ll cost: %d\n", SP->_ll_cost); -#if USE_HARD_TABS - (void) printf("ht cost: %d\n", SP->_ht_cost); - (void) printf("cbt cost: %d\n", SP->_cbt_cost); -#endif /* USE_HARD_TABS */ - (void) printf("cub1 cost: %d\n", SP->_cub1_cost); - (void) printf("cuf1 cost: %d\n", SP->_cuf1_cost); - (void) printf("cud1 cost: %d\n", SP->_cud1_cost); - (void) printf("cuu1 cost: %d\n", SP->_cuu1_cost); - (void) printf("cub cost: %d\n", SP->_cub_cost); - (void) printf("cuf cost: %d\n", SP->_cuf_cost); - (void) printf("cud cost: %d\n", SP->_cud_cost); - (void) printf("cuu cost: %d\n", SP->_cuu_cost); - (void) printf("hpa cost: %d\n", SP->_hpa_cost); - (void) printf("vpa cost: %d\n", SP->_vpa_cost); - } else if (buf[0] == 'x' || buf[0] == 'q') - break; - else - (void) puts("Invalid command."); - } - - (void) fputs("rmcup:", stdout); - _nc_mvcur_wrap(); - putchar('\n'); - - return (0); -} - -#endif /* MAIN */ - -/* lib_mvcur.c ends here */ diff --git a/contrib/ncurses/ncurses/tty/lib_tstp.c b/contrib/ncurses/ncurses/tty/lib_tstp.c deleted file mode 100644 index 06c8411caa4d..000000000000 --- a/contrib/ncurses/ncurses/tty/lib_tstp.c +++ /dev/null @@ -1,389 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1995-on * - ****************************************************************************/ - -/* -** lib_tstp.c -** -** The routine _nc_signal_handler(). -** -*/ -#include <curses.priv.h> - -#include <SigAction.h> - -#if SVR4_ACTION && !defined(_POSIX_SOURCE) -#define _POSIX_SOURCE -#endif - -MODULE_ID("$Id: lib_tstp.c,v 1.37 2008/05/03 16:24:56 tom Exp $") - -#if defined(SIGTSTP) && (HAVE_SIGACTION || HAVE_SIGVEC) -#define USE_SIGTSTP 1 -#else -#define USE_SIGTSTP 0 -#endif - -#ifdef TRACE -static const char * -signal_name(int sig) -{ - switch (sig) { - case SIGALRM: - return "SIGALRM"; -#ifdef SIGCONT - case SIGCONT: - return "SIGCONT"; -#endif - case SIGINT: - return "SIGINT"; - case SIGQUIT: - return "SIGQUIT"; - case SIGTERM: - return "SIGTERM"; -#ifdef SIGTSTP - case SIGTSTP: - return "SIGTSTP"; -#endif -#ifdef SIGTTOU - case SIGTTOU: - return "SIGTTOU"; -#endif -#ifdef SIGWINCH - case SIGWINCH: - return "SIGWINCH"; -#endif - default: - return "unknown signal"; - } -} -#endif - -/* - * Note: This code is fragile! Its problem is that different OSs - * handle restart of system calls interrupted by signals differently. - * The ncurses code needs signal-call restart to happen -- otherwise, - * interrupted wgetch() calls will return FAIL, probably making the - * application think the input stream has ended and it should - * terminate. In particular, you know you have this problem if, when - * you suspend an ncurses-using lynx with ^Z and resume, it dies - * immediately. - * - * Default behavior of POSIX sigaction(2) is not to restart - * interrupted system calls, but Linux's sigaction does it anyway (at - * least, on and after the 1.1.47 I (esr) use). Thus this code works - * OK under Linux. The 4.4BSD sigaction(2) supports a (non-portable) - * SA_RESTART flag that forces the right behavior. Thus, this code - * should work OK under BSD/OS, NetBSD, and FreeBSD (let us know if it - * does not). - * - * Stock System Vs (and anything else using a strict-POSIX - * sigaction(2) without SA_RESTART) may have a problem. Possible - * solutions: - * - * sigvec restarts by default (SV_INTERRUPT flag to not restart) - * signal restarts by default in SVr4 (assuming you link with -lucb) - * and BSD, but not SVr3. - * sigset restarts, but is only available under SVr4/Solaris. - * - * The signal(3) call is mandated by the ANSI standard, and its - * interaction with sigaction(2) is described in the POSIX standard - * (3.3.4.2, page 72,line 934). According to section 8.1, page 191, - * however, signal(3) itself is not required by POSIX.1. And POSIX is - * silent on whether it is required to restart signals. - * - * So. The present situation is, we use sigaction(2) with no - * guarantee of restart anywhere but on Linux and BSD. We could - * switch to signal(3) and collar Linux, BSD, and SVr4. Any way - * we slice it, System V UNIXes older than SVr4 will probably lose - * (this may include XENIX). - * - * This implementation will probably be changed to use signal(3) in - * the future. If nothing else, it's simpler... - */ - -#if USE_SIGTSTP -static void -tstp(int dummy GCC_UNUSED) -{ - sigset_t mask, omask; - sigaction_t act, oact; - -#ifdef SIGTTOU - int sigttou_blocked; -#endif - - T(("tstp() called")); - - /* - * The user may have changed the prog_mode tty bits, so save them. - * - * But first try to detect whether we still are in the foreground - * process group - if not, an interactive shell may already have - * taken ownership of the tty and modified the settings when our - * parent was stopped before us, and we would likely pick up the - * settings already modified by the shell. - */ - if (SP != 0 && !SP->_endwin) /* don't do this if we're not in curses */ -#if HAVE_TCGETPGRP - if (tcgetpgrp(STDIN_FILENO) == getpgrp()) -#endif - def_prog_mode(); - - /* - * Block window change and timer signals. The latter - * is because applications use timers to decide when - * to repaint the screen. - */ - (void) sigemptyset(&mask); - (void) sigaddset(&mask, SIGALRM); -#if USE_SIGWINCH - (void) sigaddset(&mask, SIGWINCH); -#endif - (void) sigprocmask(SIG_BLOCK, &mask, &omask); - -#ifdef SIGTTOU - sigttou_blocked = sigismember(&omask, SIGTTOU); - if (!sigttou_blocked) { - (void) sigemptyset(&mask); - (void) sigaddset(&mask, SIGTTOU); - (void) sigprocmask(SIG_BLOCK, &mask, NULL); - } -#endif - - /* - * End window mode, which also resets the terminal state to the - * original (pre-curses) modes. - */ - endwin(); - - /* Unblock SIGTSTP. */ - (void) sigemptyset(&mask); - (void) sigaddset(&mask, SIGTSTP); -#ifdef SIGTTOU - if (!sigttou_blocked) { - /* Unblock this too if it wasn't blocked on entry */ - (void) sigaddset(&mask, SIGTTOU); - } -#endif - (void) sigprocmask(SIG_UNBLOCK, &mask, NULL); - - /* 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; -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; -#endif /* SA_RESTART */ - sigaction(SIGTSTP, &act, &oact); - kill(getpid(), SIGTSTP); - - /* Process gets suspended...time passes...process resumes */ - - T(("SIGCONT received")); - sigaction(SIGTSTP, &oact, NULL); - flushinp(); - - /* - * If the user modified the tty state while suspended, he wants - * those changes to stick. So save the new "default" terminal state. - */ - def_shell_mode(); - - /* - * This relies on the fact that doupdate() will restore the - * program-mode tty state, and issue enter_ca_mode if need be. - */ - doupdate(); - - /* Reset the signals. */ - (void) sigprocmask(SIG_SETMASK, &omask, NULL); -} -#endif /* USE_SIGTSTP */ - -static void -cleanup(int sig) -{ - /* - * Actually, doing any sort of I/O from within an signal handler is - * "unsafe". But we'll _try_ to clean up the screen and terminal - * settings on the way out. - */ - if (!_nc_globals.cleanup_nested++ - && (sig == SIGINT - || sig == SIGQUIT)) { -#if HAVE_SIGACTION || HAVE_SIGVEC - sigaction_t act; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - act.sa_handler = SIG_IGN; - if (sigaction(sig, &act, NULL) == 0) -#else - if (signal(sig, SIG_IGN) != SIG_ERR) -#endif - { - SCREEN *scan; - for (each_screen(scan)) { - if (scan->_ofp != 0 - && isatty(fileno(scan->_ofp))) { - scan->_cleanup = TRUE; - scan->_outch = _nc_outch; - } - set_term(scan); - endwin(); - if (SP) - SP->_endwin = FALSE; /* in case we have an atexit! */ - } - } - } - exit(EXIT_FAILURE); -} - -#if USE_SIGWINCH -static void -sigwinch(int sig GCC_UNUSED) -{ - _nc_globals.have_sigwinch = 1; -} -#endif /* USE_SIGWINCH */ - -/* - * If the given signal is still in its default state, set it to the given - * handler. - */ -static int -CatchIfDefault(int sig, RETSIGTYPE (*handler) (int)) -{ - int result; -#if HAVE_SIGACTION || HAVE_SIGVEC - sigaction_t old_act; - sigaction_t new_act; - - memset(&new_act, 0, sizeof(new_act)); - sigemptyset(&new_act.sa_mask); -#ifdef SA_RESTART -#ifdef SIGWINCH - if (sig != SIGWINCH) -#endif - new_act.sa_flags |= SA_RESTART; -#endif /* SA_RESTART */ - new_act.sa_handler = handler; - - if (sigaction(sig, NULL, &old_act) == 0 - && (old_act.sa_handler == SIG_DFL - || old_act.sa_handler == handler -#if USE_SIGWINCH - || (sig == SIGWINCH && old_act.sa_handler == SIG_IGN) -#endif - )) { - (void) sigaction(sig, &new_act, NULL); - result = TRUE; - } else { - result = FALSE; - } -#else /* !HAVE_SIGACTION */ - RETSIGTYPE (*ohandler) (int); - - ohandler = signal(sig, SIG_IGN); - if (ohandler == SIG_DFL - || ohandler == handler -#if USE_SIGWINCH - || (sig == SIGWINCH && ohandler == SIG_IGN) -#endif - ) { - signal(sig, handler); - result = TRUE; - } else { - signal(sig, ohandler); - result = FALSE; - } -#endif - T(("CatchIfDefault - will %scatch %s", - result ? "" : "not ", signal_name(sig))); - return result; -} - -/* - * This is invoked once at the beginning (e.g., from 'initscr()'), to - * initialize the signal catchers, and thereafter when spawning a shell (and - * returning) to disable/enable the SIGTSTP (i.e., ^Z) catcher. - * - * If the application has already set one of the signals, we'll not modify it - * (during initialization). - * - * The XSI document implies that we shouldn't keep the SIGTSTP handler if - * the caller later changes its mind, but that doesn't seem correct. - */ -NCURSES_EXPORT(void) -_nc_signal_handler(bool enable) -{ - T((T_CALLED("_nc_signal_handler(%d)"), enable)); -#if USE_SIGTSTP /* Xenix 2.x doesn't have SIGTSTP, for example */ - { - static bool ignore_tstp = FALSE; - - if (!ignore_tstp) { - static sigaction_t new_sigaction, old_sigaction; - - if (!enable) { - new_sigaction.sa_handler = SIG_IGN; - sigaction(SIGTSTP, &new_sigaction, &old_sigaction); - } else if (new_sigaction.sa_handler != SIG_DFL) { - sigaction(SIGTSTP, &old_sigaction, NULL); - } else if (sigaction(SIGTSTP, NULL, &old_sigaction) == 0 - && (old_sigaction.sa_handler == SIG_DFL)) { - sigemptyset(&new_sigaction.sa_mask); -#ifdef SA_RESTART - new_sigaction.sa_flags |= SA_RESTART; -#endif /* SA_RESTART */ - new_sigaction.sa_handler = tstp; - (void) sigaction(SIGTSTP, &new_sigaction, NULL); - } else { - ignore_tstp = TRUE; - } - } - } -#endif /* !USE_SIGTSTP */ - - if (!_nc_globals.init_signals) { - if (enable) { - CatchIfDefault(SIGINT, cleanup); - CatchIfDefault(SIGTERM, cleanup); -#if USE_SIGWINCH - CatchIfDefault(SIGWINCH, sigwinch); -#endif - _nc_globals.init_signals = TRUE; - } - } - returnVoid; -} diff --git a/contrib/ncurses/ncurses/tty/lib_twait.c b/contrib/ncurses/ncurses/tty/lib_twait.c deleted file mode 100644 index 6d46081862fd..000000000000 --- a/contrib/ncurses/ncurses/tty/lib_twait.c +++ /dev/null @@ -1,444 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/* -** lib_twait.c -** -** The routine _nc_timed_wait(). -** -** (This file was originally written by Eric Raymond; however except for -** comments, none of the original code remains - T.Dickey). -*/ - -#include <curses.priv.h> - -#ifdef __BEOS__ -#undef false -#undef true -#include <OS.h> -#endif - -#if USE_FUNC_POLL -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# endif -#elif HAVE_SELECT -# if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT -# include <sys/time.h> -# endif -# if HAVE_SYS_SELECT_H -# include <sys/select.h> -# endif -#endif - -MODULE_ID("$Id: lib_twait.c,v 1.57 2008/05/03 21:35:57 tom Exp $") - -static long -_nc_gettime(TimeType * t0, bool first) -{ - long res; - -#if PRECISE_GETTIME - TimeType t1; - gettimeofday(&t1, (struct timezone *) 0); - if (first) { - *t0 = t1; - res = 0; - } else { - /* .tv_sec and .tv_usec are unsigned, be careful when subtracting */ - if (t0->tv_usec > t1.tv_usec) { - t1.tv_usec += 1000000; /* Convert 1s in 1e6 microsecs */ - t1.tv_sec--; - } - res = (t1.tv_sec - t0->tv_sec) * 1000 - + (t1.tv_usec - t0->tv_usec) / 1000; - } -#else - time_t t1 = time((time_t *) 0); - if (first) { - *t0 = t1; - } - res = (t1 - *t0) * 1000; -#endif - TR(TRACE_IEVENT, ("%s time: %ld msec", first ? "get" : "elapsed", res)); - return res; -} - -#ifdef NCURSES_WGETCH_EVENTS -NCURSES_EXPORT(int) -_nc_eventlist_timeout(_nc_eventlist * evl) -{ - int event_delay = -1; - int n; - - if (evl != 0) { - - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_TIMEOUT_MSEC) { - event_delay = ev->data.timeout_msec; - if (event_delay < 0) - event_delay = INT_MAX; /* FIXME Is this defined? */ - } - } - } - return event_delay; -} -#endif /* NCURSES_WGETCH_EVENTS */ - -/* - * Wait a specified number of milliseconds, returning nonzero 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. - * - * Experimental: if NCURSES_WGETCH_EVENTS is defined, (mode & 4) determines - * whether to pay attention to evl argument. If set, the smallest of - * millisecond and of timeout of evl is taken. - * - * We return a mask that corresponds to the mode (e.g., 2 for mouse activity). - * - * If the milliseconds given are -1, the wait blocks until activity on the - * descriptors. - */ -NCURSES_EXPORT(int) -_nc_timed_wait(SCREEN *sp, - int mode, - int milliseconds, - int *timeleft - EVENTLIST_2nd(_nc_eventlist * evl)) -{ - int fd; - int count; - int result = 0; - TimeType t0; - -#ifdef NCURSES_WGETCH_EVENTS - int timeout_is_event = 0; - int n; -#endif - -#if USE_FUNC_POLL -#define MIN_FDS 2 - struct pollfd fd_list[MIN_FDS]; - struct pollfd *fds = fd_list; -#elif defined(__BEOS__) -#elif HAVE_SELECT - fd_set set; -#endif - - long starttime, returntime; - - TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d", - milliseconds, mode)); - -#ifdef NCURSES_WGETCH_EVENTS - if (mode & 4) { - int event_delay = _nc_eventlist_timeout(evl); - - if (event_delay >= 0 - && (milliseconds >= event_delay || milliseconds < 0)) { - milliseconds = event_delay; - timeout_is_event = 1; - } - } -#endif - -#if PRECISE_GETTIME && HAVE_NANOSLEEP - retry: -#endif - starttime = _nc_gettime(&t0, TRUE); - - count = 0; - -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) - evl->result_flags = 0; -#endif - -#if USE_FUNC_POLL - memset(fd_list, 0, sizeof(fd_list)); - -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) - fds = typeMalloc(struct pollfd, MIN_FDS + evl->count); -#endif - - if (mode & 1) { - fds[count].fd = sp->_ifd; - fds[count].events = POLLIN; - count++; - } - if ((mode & 2) - && (fd = sp->_mouse_fd) >= 0) { - fds[count].fd = fd; - fds[count].events = POLLIN; - count++; - } -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) { - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_FILE - && (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) { - fds[count].fd = ev->data.fev.fd; - fds[count].events = POLLIN; - count++; - } - } - } -#endif - - result = poll(fds, (unsigned) count, milliseconds); - -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) { - int c; - - if (!result) - count = 0; - - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_FILE - && (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) { - ev->data.fev.result = 0; - for (c = 0; c < count; c++) - if (fds[c].fd == ev->data.fev.fd - && fds[c].revents & POLLIN) { - ev->data.fev.result |= _NC_EVENT_FILE_READABLE; - evl->result_flags |= _NC_EVENT_FILE_READABLE; - } - } else if (ev->type == _NC_EVENT_TIMEOUT_MSEC - && !result && timeout_is_event) { - evl->result_flags |= _NC_EVENT_TIMEOUT_MSEC; - } - } - } - - if (fds != fd_list) - free((char *) fds); - -#endif - -#elif defined(__BEOS__) - /* - * BeOS's select() is declared in socket.h, so the configure script does - * not see it. That's just as well, since that function works only for - * sockets. This (using snooze and ioctl) was distilled from Be's patch - * for ncurses which uses a separate thread to simulate select(). - * - * FIXME: the return values from the ioctl aren't very clear if we get - * interrupted. - * - * FIXME: this assumes mode&1 if milliseconds < 0 (see lib_getch.c). - */ - result = 0; - if (mode & 1) { - int step = (milliseconds < 0) ? 0 : 5000; - bigtime_t d; - bigtime_t useconds = milliseconds * 1000; - int n, howmany; - - if (useconds <= 0) /* we're here to go _through_ the loop */ - useconds = 1; - - for (d = 0; d < useconds; d += step) { - n = 0; - howmany = ioctl(0, 'ichr', &n); - if (howmany >= 0 && n > 0) { - result = 1; - break; - } - if (useconds > 1 && step > 0) { - snooze(step); - milliseconds -= (step / 1000); - if (milliseconds <= 0) { - milliseconds = 0; - break; - } - } - } - } else if (milliseconds > 0) { - snooze(milliseconds * 1000); - milliseconds = 0; - } -#elif HAVE_SELECT - /* - * select() modifies the fd_set arguments; do this in the - * loop. - */ - FD_ZERO(&set); - - if (mode & 1) { - FD_SET(sp->_ifd, &set); - count = sp->_ifd + 1; - } - if ((mode & 2) - && (fd = sp->_mouse_fd) >= 0) { - FD_SET(fd, &set); - count = max(fd, count) + 1; - } -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) { - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_FILE - && (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) { - FD_SET(ev->data.fev.fd, &set); - count = max(ev->data.fev.fd + 1, count); - } - } - } -#endif - - if (milliseconds >= 0) { - struct timeval ntimeout; - ntimeout.tv_sec = milliseconds / 1000; - ntimeout.tv_usec = (milliseconds % 1000) * 1000; - result = select(count, &set, NULL, NULL, &ntimeout); - } else { - result = select(count, &set, NULL, NULL, NULL); - } - -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl) { - evl->result_flags = 0; - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_FILE - && (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) { - ev->data.fev.result = 0; - if (FD_ISSET(ev->data.fev.fd, &set)) { - ev->data.fev.result |= _NC_EVENT_FILE_READABLE; - evl->result_flags |= _NC_EVENT_FILE_READABLE; - } - } else if (ev->type == _NC_EVENT_TIMEOUT_MSEC - && !result && timeout_is_event) - evl->result_flags |= _NC_EVENT_TIMEOUT_MSEC; - } - } -#endif - -#endif /* USE_FUNC_POLL, etc */ - - returntime = _nc_gettime(&t0, FALSE); - - if (milliseconds >= 0) - milliseconds -= (returntime - starttime); - -#ifdef NCURSES_WGETCH_EVENTS - if (evl) { - evl->result_flags = 0; - for (n = 0; n < evl->count; ++n) { - _nc_event *ev = evl->events[n]; - - if (ev->type == _NC_EVENT_TIMEOUT_MSEC) { - long diff = (returntime - starttime); - if (ev->data.timeout_msec <= diff) - ev->data.timeout_msec = 0; - else - ev->data.timeout_msec -= diff; - } - - } - } -#endif - -#if PRECISE_GETTIME && HAVE_NANOSLEEP - /* - * 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 && milliseconds > 100) { - napms(100); /* FIXME: this won't be right if I recur! */ - milliseconds -= 100; - goto retry; - } -#endif - - /* return approximate time left in milliseconds */ - if (timeleft) - *timeleft = milliseconds; - - TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec", - result, errno, milliseconds)); - - /* - * 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 < MIN_FDS; count++) { - if ((mode & (1 << count)) - && (fds[count].revents & POLLIN)) { - result |= (1 << count); - } - } -#elif defined(__BEOS__) - result = 1; /* redundant, but simple */ -#elif HAVE_SELECT - if ((mode & 2) - && (fd = sp->_mouse_fd) >= 0 - && FD_ISSET(fd, &set)) - result |= 2; - if ((mode & 1) - && FD_ISSET(sp->_ifd, &set)) - result |= 1; -#endif - } else - result = 0; - } -#ifdef NCURSES_WGETCH_EVENTS - if ((mode & 4) && evl && evl->result_flags) - result |= 4; -#endif - - return (result); -} diff --git a/contrib/ncurses/ncurses/tty/lib_vidattr.c b/contrib/ncurses/ncurses/tty/lib_vidattr.c deleted file mode 100644 index ac2a74f08e01..000000000000 --- a/contrib/ncurses/ncurses/tty/lib_vidattr.c +++ /dev/null @@ -1,338 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1996 on * - ****************************************************************************/ - -/* - * vidputs(newmode, outc) - * - * newmode is taken to be the logical 'or' of the symbols in curses.h - * representing graphic renditions. The terminal is set to be in all of - * the given modes, if possible. - * - * if the new attribute is normal - * if exit-alt-char-set exists - * emit it - * emit exit-attribute-mode - * else if set-attributes exists - * use it to set exactly what you want - * else - * if exit-attribute-mode exists - * turn off everything - * else - * turn off those which can be turned off and aren't in - * newmode. - * turn on each mode which should be on and isn't, one by one - * - * 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 <term.h> - -MODULE_ID("$Id: lib_vidattr.c,v 1.49 2007/06/30 21:58:04 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; } - - /* if there is no current screen, assume we *can* do color */ -#define SetColorsIf(why,old_attr) \ - if (can_color && (why)) { \ - int old_pair = PAIR_NUMBER(old_attr); \ - TR(TRACE_ATTRS, ("old pair = %d -- new pair = %d", old_pair, pair)); \ - if ((pair != old_pair) \ - || (fix_pair0 && (pair == 0)) \ - || (reverse ^ ((old_attr & A_REVERSE) != 0))) { \ - _nc_do_color(old_pair, pair, reverse, outc); \ - } \ - } - -#define PreviousAttr _nc_prescreen.previous_attr - -NCURSES_EXPORT(int) -vidputs(chtype newmode, int (*outc) (int)) -{ - attr_t turn_on, turn_off; - int pair; - bool reverse = FALSE; - bool can_color = (SP == 0 || SP->_coloron); -#if NCURSES_EXT_FUNCS - bool fix_pair0 = (SP != 0 && SP->_coloron && !SP->_default_color); -#else -#define fix_pair0 FALSE -#endif - - newmode &= A_ATTRIBUTES; - T((T_CALLED("vidputs(%s)"), _traceattr(newmode))); - - /* this allows us to go on whether or not newterm() has been called */ - if (SP) - PreviousAttr = AttrOf(SCREEN_ATTRS(SP)); - - TR(TRACE_ATTRS, ("previous attribute was %s", _traceattr(PreviousAttr))); - - if ((SP != 0) - && (magic_cookie_glitch > 0)) { -#if USE_XMC_SUPPORT - static const chtype table[] = - { - A_STANDOUT, - A_UNDERLINE, - A_REVERSE, - A_BLINK, - A_DIM, - A_BOLD, - A_INVIS, - A_PROTECT, - }; - unsigned n; - int used = 0; - int limit = (max_attributes <= 0) ? 1 : max_attributes; - chtype retain = 0; - - /* - * Limit the number of attribute bits set in the newmode according to - * the terminfo max_attributes value. - */ - for (n = 0; n < SIZEOF(table); ++n) { - if ((table[n] & SP->_ok_attributes) == 0) { - newmode &= ~table[n]; - } else if ((table[n] & newmode) != 0) { - if (used++ >= limit) { - newmode &= ~table[n]; - if (newmode == retain) - break; - } else { - retain = newmode; - } - } - } -#else - newmode &= ~(SP->_xmc_suppress); -#endif - TR(TRACE_ATTRS, ("suppressed attribute is %s", _traceattr(newmode))); - } - - /* - * If we have a terminal that cannot combine color with video - * attributes, use the colors in preference. - */ - if (((newmode & A_COLOR) != 0 - || fix_pair0) - && (no_color_video > 0)) { - /* - * If we had chosen the A_xxx definitions to correspond to the - * no_color_video mask, we could simply shift it up and mask off the - * attributes. But we did not (actually copied Solaris' definitions). - * However, this is still simpler/faster than a lookup table. - * - * The 63 corresponds to A_STANDOUT, A_UNDERLINE, A_REVERSE, A_BLINK, - * A_DIM, A_BOLD which are 1:1 with no_color_video. The bits that - * correspond to A_INVIS, A_PROTECT (192) must be shifted up 1 and - * A_ALTCHARSET (256) down 2 to line up. We use the NCURSES_BITS - * macro so this will work properly for the wide-character layout. - */ - unsigned value = no_color_video; - attr_t mask = NCURSES_BITS((value & 63) - | ((value & 192) << 1) - | ((value & 256) >> 2), 8); - - if ((mask & A_REVERSE) != 0 - && (newmode & A_REVERSE) != 0) { - reverse = TRUE; - mask &= ~A_REVERSE; - } - newmode &= ~mask; - } - - if (newmode == PreviousAttr) - returnCode(OK); - - pair = PAIR_NUMBER(newmode); - - if (reverse) { - newmode &= ~A_REVERSE; - } - - turn_off = (~newmode & PreviousAttr) & ALL_BUT_COLOR; - turn_on = (newmode & ~PreviousAttr) & ALL_BUT_COLOR; - - SetColorsIf(((pair == 0) && !fix_pair0), PreviousAttr); - - if (newmode == A_NORMAL) { - if ((PreviousAttr & A_ALTCHARSET) && exit_alt_charset_mode) { - doPut(exit_alt_charset_mode); - PreviousAttr &= ~A_ALTCHARSET; - } - if (PreviousAttr) { - if (exit_attribute_mode) { - doPut(exit_attribute_mode); - } else { - if (!SP || SP->_use_rmul) { - TurnOff(A_UNDERLINE, exit_underline_mode); - } - if (!SP || SP->_use_rmso) { - TurnOff(A_STANDOUT, exit_standout_mode); - } - } - PreviousAttr &= ALL_BUT_COLOR; - } - - SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); - } else if (set_attributes) { - if (turn_on || turn_off) { - TPUTS_TRACE("set_attributes"); - tputs(tparm(set_attributes, - (newmode & A_STANDOUT) != 0, - (newmode & A_UNDERLINE) != 0, - (newmode & A_REVERSE) != 0, - (newmode & A_BLINK) != 0, - (newmode & A_DIM) != 0, - (newmode & A_BOLD) != 0, - (newmode & A_INVIS) != 0, - (newmode & A_PROTECT) != 0, - (newmode & A_ALTCHARSET) != 0), 1, outc); - PreviousAttr &= ALL_BUT_COLOR; - } - SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); - } else { - - TR(TRACE_ATTRS, ("turning %s off", _traceattr(turn_off))); - - TurnOff(A_ALTCHARSET, exit_alt_charset_mode); - - if (!SP || SP->_use_rmul) { - TurnOff(A_UNDERLINE, exit_underline_mode); - } - - if (!SP || SP->_use_rmso) { - TurnOff(A_STANDOUT, exit_standout_mode); - } - - if (turn_off && exit_attribute_mode) { - doPut(exit_attribute_mode); - turn_on |= (newmode & ALL_BUT_COLOR); - PreviousAttr &= ALL_BUT_COLOR; - } - SetColorsIf((pair != 0) || fix_pair0, PreviousAttr); - - TR(TRACE_ATTRS, ("turning %s on", _traceattr(turn_on))); - /* *INDENT-OFF* */ - 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); -#if USE_WIDEC_SUPPORT - 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); -#endif - /* *INDENT-ON* */ - - } - - if (reverse) - newmode |= A_REVERSE; - - if (SP) - SetAttr(SCREEN_ATTRS(SP), newmode); - else - PreviousAttr = newmode; - - returnCode(OK); -} - -NCURSES_EXPORT(int) -vidattr(chtype newmode) -{ - T((T_CALLED("vidattr(%s)"), _traceattr(newmode))); - - returnCode(vidputs(newmode, _nc_outch)); -} - -NCURSES_EXPORT(chtype) -termattrs(void) -{ - chtype attrs = A_NORMAL; - - T((T_CALLED("termattrs()"))); - if (enter_alt_charset_mode) - attrs |= A_ALTCHARSET; - - if (enter_blink_mode) - attrs |= A_BLINK; - - if (enter_bold_mode) - attrs |= A_BOLD; - - if (enter_dim_mode) - attrs |= A_DIM; - - if (enter_reverse_mode) - attrs |= A_REVERSE; - - if (enter_standout_mode) - attrs |= A_STANDOUT; - - if (enter_protected_mode) - attrs |= A_PROTECT; - - if (enter_secure_mode) - attrs |= A_INVIS; - - if (enter_underline_mode) - attrs |= A_UNDERLINE; - - if (SP->_coloron) - attrs |= A_COLOR; - - returnChar(attrs); -} diff --git a/contrib/ncurses/ncurses/tty/tty_display.h b/contrib/ncurses/ncurses/tty/tty_display.h deleted file mode 100644 index 4c45a08450ed..000000000000 --- a/contrib/ncurses/ncurses/tty/tty_display.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2003,2004 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ************************************************************************** */ - -#ifndef TTY_DISPLAY_H -#define TTY_DISPLAY_H 1 - -/* - * $Id: tty_display.h,v 1.6 2005/01/01 23:41:12 tom Exp $ - */ -extern NCURSES_EXPORT(bool) _nc_tty_beep (void); -extern NCURSES_EXPORT(bool) _nc_tty_check_resize (void); -extern NCURSES_EXPORT(bool) _nc_tty_cursor (int); -extern NCURSES_EXPORT(bool) _nc_tty_flash (void); -extern NCURSES_EXPORT(bool) _nc_tty_init_color (int,int,int,int); -extern NCURSES_EXPORT(bool) _nc_tty_init_pair (int,int,int); -extern NCURSES_EXPORT(bool) _nc_tty_slk_hide (bool); -extern NCURSES_EXPORT(bool) _nc_tty_slk_update (int,const char *); -extern NCURSES_EXPORT(bool) _nc_tty_start_color (void); -extern NCURSES_EXPORT(void) _nc_tty_display_resume (void); -extern NCURSES_EXPORT(void) _nc_tty_display_suspend (void); -extern NCURSES_EXPORT(void) _nc_tty_dispose (void); /* frees SP->_term */ -extern NCURSES_EXPORT(void) _nc_tty_switch_to (void); -extern NCURSES_EXPORT(void) _nc_tty_update (void); - -struct tty_display_data { - int _fifohold; /* set if breakout marked */ - unsigned long _current_attr; /* terminal attribute current set */ - int _cursrow; /* physical cursor row (-1=unknown) */ - int _curscol; /* physical cursor column */ - - /* 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) */ -#if USE_HARD_TABS - int _ht_cost; /* cost of (tab) */ - int _cbt_cost; /* cost of (backtab) */ -#endif /* USE_HARD_TABS */ - 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) */ - int _smir_cost; /* cost of (enter_insert_mode) */ - int _rmir_cost; /* cost of (exit_insert_mode) */ - int _ip_cost; /* cost of (insert_padding) */ - /* used in lib_mvcur.c */ - char * _address_cursor; - int _carriage_return_length; - int _cursor_home_length; - int _cursor_to_ll_length; - - chtype _xmc_suppress; /* attributes to suppress if xmc */ - chtype _xmc_triggers; /* attributes to process if xmc */ - - bool _sig_winch; -}; - - -#define DelCharCost(count) \ - ((parm_dch != 0) \ - ? D->_dch_cost \ - : ((delete_character != 0) \ - ? (D->_dch1_cost * count) \ - : INFINITY)) - -#define InsCharCost(count) \ - ((parm_ich != 0) \ - ? D->_ich_cost \ - : ((enter_insert_mode && exit_insert_mode) \ - ? D->_smir_cost + D->_rmir_cost + (D->_ip_cost * count) \ - : ((insert_character != 0) \ - ? ((D->_ich1_cost + D->_ip_cost) * count) \ - : INFINITY))) - -#if USE_XMC_SUPPORT -#define UpdateAttrs(c) if (!SameAttrOf(D->_current_attr, AttrOf(c))) { \ - attr_t chg = D->_current_attr; \ - vidattr(AttrOf(c)); \ - if (magic_cookie_glitch > 0 \ - && XMC_CHANGES((chg ^ D->_current_attr))) { \ - T(("%s @%d before glitch %d,%d", \ - __FILE__, __LINE__, \ - D->_cursrow, \ - D->_curscol)); \ - _nc_do_xmc_glitch(chg); \ - } \ - } -#else -#define UpdateAttrs(c) if (!SameAttrOf(D->_current_attr, AttrOf(c))) \ - vidattr(AttrOf(c)); -#endif - -#define XMC_CHANGES(c) ((c) & D->_xmc_suppress) - -#endif /* TTY_DISPLAY_H */ diff --git a/contrib/ncurses/ncurses/tty/tty_input.h b/contrib/ncurses/ncurses/tty/tty_input.h deleted file mode 100644 index e520793eea64..000000000000 --- a/contrib/ncurses/ncurses/tty/tty_input.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998,2000 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/* - * $Id: tty_input.h,v 1.2 2000/12/10 02:26:51 tom Exp $ - */ - -#ifndef TTY_INPUT_H -#define TTY_INPUT_H 1 - -extern NCURSES_EXPORT(bool) _nc_tty_mouse_mask (mmask_t); -extern NCURSES_EXPORT(bool) _nc_tty_pending (void); -extern NCURSES_EXPORT(int) _nc_tty_next_event (int); -extern NCURSES_EXPORT(void) _nc_tty_flags_changed (void); -extern NCURSES_EXPORT(void) _nc_tty_flush (void); -extern NCURSES_EXPORT(void) _nc_tty_input_resume (void); -extern NCURSES_EXPORT(void) _nc_tty_input_suspend (void); - -struct tty_input_data { - int _ifd; /* input file ptr for screen */ - int _keypad_xmit; /* current terminal state */ - int _meta_on; /* current terminal state */ - - /* - * These are the data that support the mouse interface. - */ - bool (*_mouse_event) (SCREEN *); - bool (*_mouse_inline)(SCREEN *); - bool (*_mouse_parse) (int); - void (*_mouse_resume)(SCREEN *); - void (*_mouse_wrap) (SCREEN *); - int _mouse_fd; /* file-descriptor, if any */ - int mousetype; -}; - -#endif /* TTY_INPUT_H */ diff --git a/contrib/ncurses/ncurses/tty/tty_update.c b/contrib/ncurses/ncurses/tty/tty_update.c deleted file mode 100644 index 16fc17d27236..000000000000 --- a/contrib/ncurses/ncurses/tty/tty_update.c +++ /dev/null @@ -1,1972 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/*----------------------------------------------------------------- - * - * lib_doupdate.c - * - * The routine doupdate() and its dependents. - * All physical output is concentrated here (except _nc_outch() - * in lib_tputs.c). - * - *-----------------------------------------------------------------*/ - -#include <curses.priv.h> - -#ifdef __BEOS__ -#undef false -#undef true -#include <OS.h> -#endif - -#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 && HAVE_SYS_TIME_SELECT -#include <sys/time.h> -#endif - -#if USE_TRACE_TIMES -#include <sys/times.h> -#endif - -#if USE_FUNC_POLL -#elif HAVE_SELECT -#if HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif -#endif - -#include <ctype.h> -#include <term.h> - -MODULE_ID("$Id: tty_update.c,v 1.245 2008/05/03 22:43:04 tom Exp $") - -/* - * This define controls the line-breakout optimization. Every once in a - * while during screen refresh, we want to check for input and abort the - * update if there's some waiting. CHECK_INTERVAL controls the number of - * changed lines to be emitted between input checks. - * - * Note: Input-check-and-abort is no longer done if the screen is being - * updated from scratch. This is a feature, not a bug. - */ -#define CHECK_INTERVAL 5 - -#define FILL_BCE() (SP->_coloron && !SP->_default_color && !back_color_erase) - -static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT); -static NCURSES_CH_T normal = NewChar(BLANK_TEXT); - -/* - * Enable checking to see if doupdate and friends are tracking the true - * cursor position correctly. NOTE: this is a debugging hack which will - * work ONLY on ANSI-compatible terminals! - */ -/* #define POSITION_DEBUG */ - -static NCURSES_INLINE NCURSES_CH_T ClrBlank(WINDOW *win); -static int ClrBottom(int total); -static void ClearScreen(NCURSES_CH_T blank); -static void ClrUpdate(void); -static void DelChar(int count); -static void InsStr(NCURSES_CH_T * line, int count); -static void TransformLine(int const lineno); - -#ifdef POSITION_DEBUG -/**************************************************************************** - * - * Debugging code. Only works on ANSI-standard terminals. - * - ****************************************************************************/ - -static void -position_check(int expected_y, int expected_x, char *legend) -/* check to see if the real cursor position matches the virtual */ -{ - char buf[20]; - char *s; - int y, x; - - if (!_nc_tracing || (expected_y < 0 && expected_x < 0)) - return; - - _nc_flush(); - memset(buf, '\0', sizeof(buf)); - putp("\033[6n"); /* only works on ANSI-compatibles */ - _nc_flush(); - *(s = buf) = 0; - do { - int ask = sizeof(buf) - 1 - (s - buf); - int got = read(0, s, ask); - if (got == 0) - break; - s += got; - } while (strchr(buf, 'R') == 0); - _tracef("probe returned %s", _nc_visbuf(buf)); - - /* try to interpret as a position report */ - if (sscanf(buf, "\033[%d;%dR", &y, &x) != 2) { - _tracef("position probe failed in %s", legend); - } else { - if (expected_x < 0) - expected_x = x - 1; - if (expected_y < 0) - expected_y = y - 1; - if (y - 1 != expected_y || x - 1 != expected_x) { - beep(); - tputs(tparm("\033[%d;%dH", expected_y + 1, expected_x + 1), 1, _nc_outch); - _tracef("position seen (%d, %d) doesn't match expected one (%d, %d) in %s", - y - 1, x - 1, expected_y, expected_x, legend); - } else { - _tracef("position matches OK in %s", legend); - } - } -} -#else -#define position_check(expected_y, expected_x, legend) /* nothing */ -#endif /* POSITION_DEBUG */ - -/**************************************************************************** - * - * Optimized update code - * - ****************************************************************************/ - -static NCURSES_INLINE void -GoTo(int const row, int const col) -{ - TR(TRACE_MOVE, ("GoTo(%d, %d) from (%d, %d)", - row, col, SP->_cursrow, SP->_curscol)); - - position_check(SP->_cursrow, SP->_curscol, "GoTo"); - - mvcur(SP->_cursrow, SP->_curscol, row, col); - position_check(SP->_cursrow, SP->_curscol, "GoTo2"); -} - -static NCURSES_INLINE void -PutAttrChar(CARG_CH_T ch) -{ - int chlen = 1; - NCURSES_CH_T my_ch; - PUTC_DATA; - NCURSES_CH_T tilde; - NCURSES_CH_T attr = CHDEREF(ch); - - TR(TRACE_CHARPUT, ("PutAttrChar(%s) at (%d, %d)", - _tracech_t(ch), - SP->_cursrow, SP->_curscol)); -#if USE_WIDEC_SUPPORT - /* - * If this is not a valid character, there is nothing more to do. - */ - if (isWidecExt(CHDEREF(ch))) { - TR(TRACE_CHARPUT, ("...skip")); - return; - } - /* - * Determine the number of character cells which the 'ch' value will use - * on the screen. It should be at least one. - */ - if ((chlen = wcwidth(CharOf(CHDEREF(ch)))) <= 0) { - static const NCURSES_CH_T blank = NewChar(BLANK_TEXT); - - /* - * If the character falls into any of these special cases, do - * not force the result to a blank: - * - * a) it is printable (this works around a bug in wcwidth()). - * b) use_legacy_coding() has been called to modify the treatment - * of codes 128-255. - * c) the acs_map[] has been initialized to allow codes 0-31 - * to be rendered. This supports Linux console's "PC" - * characters. Codes 128-255 are allowed though this is - * not checked. - */ - if (is8bits(CharOf(CHDEREF(ch))) - && (isprint(CharOf(CHDEREF(ch))) - || (SP->_legacy_coding > 0 && CharOf(CHDEREF(ch)) >= 160) - || (SP->_legacy_coding > 1 && CharOf(CHDEREF(ch)) >= 128) - || (AttrOf(attr) & A_ALTCHARSET - && ((CharOfD(ch) < ACS_LEN - && SP->_acs_map != 0 - && SP->_acs_map[CharOfD(ch)] != 0) - || (CharOfD(ch) >= 128))))) { - ; - } else { - ch = CHREF(blank); - TR(TRACE_CHARPUT, ("forced to blank")); - } - chlen = 1; - } -#endif - - if ((AttrOf(attr) & A_ALTCHARSET) - && SP->_acs_map != 0 - && CharOfD(ch) < ACS_LEN) { - my_ch = CHDEREF(ch); /* work around const param */ -#if USE_WIDEC_SUPPORT - /* - * This is crude & ugly, but works most of the time. It checks if the - * acs_chars string specified that we have a mapping for this - * character, and uses the wide-character mapping when we expect the - * normal one to be broken (by mis-design ;-). - */ - if (SP->_screen_acs_fix - && SP->_screen_acs_map[CharOf(my_ch)]) { - RemAttr(attr, A_ALTCHARSET); - my_ch = _nc_wacs[CharOf(my_ch)]; - } -#endif - /* - * If we (still) have alternate character set, it is the normal 8bit - * flavor. The _screen_acs_map[] array tells if the character was - * really in acs_chars, needed because of the way wide/normal line - * drawing flavors are integrated. - */ - if (AttrOf(attr) & A_ALTCHARSET) { - int j = CharOfD(ch); - chtype temp = UChar(SP->_acs_map[j]); - - if (!(SP->_screen_acs_map[j])) { - RemAttr(attr, A_ALTCHARSET); - if (temp == 0) - temp = ' '; - } - if (temp != 0) - SetChar(my_ch, temp, AttrOf(attr)); - } - ch = CHREF(my_ch); - } - if (tilde_glitch && (CharOfD(ch) == L('~'))) { - SetChar(tilde, L('`'), AttrOf(attr)); - ch = CHREF(tilde); - } - - UpdateAttrs(attr); -#if !USE_WIDEC_SUPPORT - /* FIXME - we do this special case for signal handling, should see how to - * make it work for wide characters. - */ - if (SP->_outch != 0) { - SP->_outch(UChar(ch)); - } else -#endif - { - PUTC(CHDEREF(ch), SP->_ofp); /* macro's fastest... */ - COUNT_OUTCHARS(1); - } - SP->_curscol += chlen; - if (char_padding) { - TPUTS_TRACE("char_padding"); - putp(char_padding); - } -} - -static bool -check_pending(void) -/* check for pending input */ -{ - bool have_pending = FALSE; - - /* - * Only carry out this check when the flag is zero, otherwise we'll - * have the refreshing slow down drastically (or stop) if there's an - * unread character available. - */ - if (SP->_fifohold != 0) - return FALSE; - - if (SP->_checkfd >= 0) { -#if USE_FUNC_POLL - struct pollfd fds[1]; - fds[0].fd = SP->_checkfd; - fds[0].events = POLLIN; - if (poll(fds, 1, 0) > 0) { - have_pending = TRUE; - } -#elif defined(__BEOS__) - /* - * BeOS's select() is declared in socket.h, so the configure script does - * not see it. That's just as well, since that function works only for - * sockets. This (using snooze and ioctl) was distilled from Be's patch - * for ncurses which uses a separate thread to simulate select(). - * - * FIXME: the return values from the ioctl aren't very clear if we get - * interrupted. - */ - int n = 0; - int howmany = ioctl(0, 'ichr', &n); - if (howmany >= 0 && n > 0) { - have_pending = 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) { - have_pending = TRUE; - } -#endif - } - if (have_pending) { - SP->_fifohold = 5; - _nc_flush(); - } - return FALSE; -} - -/* put char at lower right corner */ -static void -PutCharLR(const ARG_CH_T ch) -{ - if (!auto_right_margin) { - /* we can put the char directly */ - PutAttrChar(ch); - } else if (enter_am_mode && exit_am_mode) { - /* we can suppress automargin */ - TPUTS_TRACE("exit_am_mode"); - putp(exit_am_mode); - - PutAttrChar(ch); - SP->_curscol--; - position_check(SP->_cursrow, SP->_curscol, "exit_am_mode"); - - TPUTS_TRACE("enter_am_mode"); - putp(enter_am_mode); - } else if ((enter_insert_mode && exit_insert_mode) - || insert_character || parm_ich) { - GoTo(screen_lines - 1, screen_columns - 2); - PutAttrChar(ch); - GoTo(screen_lines - 1, screen_columns - 2); - InsStr(newscr->_line[screen_lines - 1].text + screen_columns - 2, 1); - } -} - -/* - * Wrap the cursor position, i.e., advance to the beginning of the next line. - */ -static void -wrap_cursor(void) -{ - if (eat_newline_glitch) { - /* - * xenl can manifest two different ways. The vt100 way is that, when - * you'd expect the cursor to wrap, it stays hung at the right margin - * (on top of the character just emitted) and doesn't wrap until the - * *next* graphic char is emitted. The c100 way is to ignore LF - * received just after an am wrap. - * - * An aggressive way to handle this would be to emit CR/LF after the - * char and then assume the wrap is done, you're on the first position - * of the next line, and the terminal out of its weird state. Here - * it's safe to just tell the code that the cursor is in hyperspace and - * let the next mvcur() call straighten things out. - */ - SP->_curscol = -1; - SP->_cursrow = -1; - } else if (auto_right_margin) { - SP->_curscol = 0; - SP->_cursrow++; - /* - * We've actually moved - but may have to work around problems with - * video attributes not working. - */ - if (!move_standout_mode && AttrOf(SCREEN_ATTRS(SP))) { - TR(TRACE_CHARPUT, ("turning off (%#lx) %s before wrapping", - (unsigned long) AttrOf(SCREEN_ATTRS(SP)), - _traceattr(AttrOf(SCREEN_ATTRS(SP))))); - (void) VIDATTR(A_NORMAL, 0); - } - } else { - SP->_curscol--; - } - position_check(SP->_cursrow, SP->_curscol, "wrap_cursor"); -} - -static NCURSES_INLINE void -PutChar(const ARG_CH_T ch) -/* insert character, handling automargin stuff */ -{ - if (SP->_cursrow == screen_lines - 1 && SP->_curscol == screen_columns - 1) - PutCharLR(ch); - else - PutAttrChar(ch); - - if (SP->_curscol >= screen_columns) - wrap_cursor(); - - position_check(SP->_cursrow, SP->_curscol, "PutChar"); -} - -/* - * 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. - */ -static NCURSES_INLINE bool -can_clear_with(ARG_CH_T ch) -{ - if (!back_color_erase && SP->_coloron) { -#if NCURSES_EXT_FUNCS - int pair; - - if (!SP->_default_color) - return FALSE; - if (SP->_default_fg != C_MASK || SP->_default_bg != C_MASK) - return FALSE; - if ((pair = GetPair(CHDEREF(ch))) != 0) { - short fg, bg; - pair_content(pair, &fg, &bg); - if (fg != C_MASK || bg != C_MASK) - return FALSE; - } -#else - if (AttrOfD(ch) & A_COLOR) - return FALSE; -#endif - } - return (ISBLANK(CHDEREF(ch)) && - (AttrOfD(ch) & ~(NONBLANK_ATTR | A_COLOR)) == BLANK_ATTR); -} - -/* - * 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 int -EmitRange(const NCURSES_CH_T * ntext, int num) -{ - int i; - - TR(TRACE_CHARPUT, ("EmitRange %d:%s", num, _nc_viscbuf(ntext, num))); - - if (erase_chars || repeat_char) { - while (num > 0) { - int runcount; - NCURSES_CH_T ntext0; - - while (num > 1 && !CharEq(ntext[0], ntext[1])) { - PutChar(CHREF(ntext[0])); - ntext++; - num--; - } - ntext0 = ntext[0]; - if (num == 1) { - PutChar(CHREF(ntext0)); - return 0; - } - runcount = 2; - - while (runcount < num && CharEq(ntext[runcount], ntext0)) - runcount++; - - /* - * The cost expression in the middle isn't exactly right. - * _cup_ch_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_ch_cost - && can_clear_with(CHREF(ntext0))) { - UpdateAttrs(ntext0); - putp(TPARM_1(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); - tputs(TPARM_2(repeat_char, CharOf(ntext0), rep_count), - rep_count, _nc_outch); - SP->_curscol += rep_count; - - if (wrap_possible) - PutChar(CHREF(ntext0)); - } else { - for (i = 0; i < runcount; i++) - PutChar(CHREF(ntext[i])); - } - ntext += runcount; - num -= runcount; - } - return 0; - } - - for (i = 0; i < num; i++) - PutChar(CHREF(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 NCURSES_CH_T * otext, - const NCURSES_CH_T * ntext, - int row, - int first, int last) -{ - int i, j, same; - - TR(TRACE_CHARPUT, ("PutRange(%p, %p, %d, %d, %d)", - otext, ntext, row, first, last)); - - if (otext != ntext - && (last - first + 1) > SP->_inline_cost) { - for (j = first, same = 0; j <= last; j++) { - if (!same && isWidecExt(otext[j])) - continue; - if (CharEq(otext[j], ntext[j])) { - same++; - } else { - if (same > SP->_inline_cost) { - EmitRange(ntext + first, j - same - first); - GoTo(row, first = j); - } - same = 0; - } - } - i = EmitRange(ntext + first, j - same - first); - /* - * Always return 1 for the next GoTo() after a PutRange() if we found - * identical characters at end of interval - */ - return (same == 0 ? i : 1); - } - return EmitRange(ntext + first, last - first + 1); -} - -/* leave unbracketed here so 'indent' works */ -#define MARK_NOCHANGE(win,row) \ - win->_line[row].firstchar = _NOCHANGE; \ - win->_line[row].lastchar = _NOCHANGE; \ - if_USE_SCROLL_HINTS(win->_line[row].oldindex = row) - -NCURSES_EXPORT(int) -doupdate(void) -{ - int i; - int nonempty; -#if USE_TRACE_TIMES - struct tms before, after; -#endif /* USE_TRACE_TIMES */ - - T((T_CALLED("doupdate()"))); - - if (curscr == 0 - || newscr == 0) - returnCode(ERR); - -#ifdef TRACE - if (USE_TRACEF(TRACE_UPDATE)) { - if (curscr->_clear) - _tracef("curscr is clear"); - else - _tracedump("curscr", curscr); - _tracedump("newscr", newscr); - _nc_unlock_global(tracef); - } -#endif /* TRACE */ - - _nc_signal_handler(FALSE); - - if (SP->_fifohold) - SP->_fifohold--; - -#if USE_SIZECHANGE - if (SP->_endwin || _nc_handle_sigwinch(SP)) { - /* - * 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. - */ - _nc_update_screensize(SP); - } -#endif - - if (SP->_endwin) { - - T(("coming back from shell mode")); - reset_prog_mode(); - - _nc_mvcur_resume(); - _nc_screen_resume(); - SP->_mouse_resume(SP); - - SP->_endwin = FALSE; - } -#if USE_TRACE_TIMES - /* zero the metering machinery */ - RESET_OUTCHARS(); - (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 USE_XMC_SUPPORT - 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; - NCURSES_CH_T *thisline = newscr->_line[i].text; - attr_t thisattr = AttrOf(thisline[j]) & SP->_xmc_triggers; - attr_t turnon = thisattr & ~rattr; - - /* is an attribute turned on here? */ - if (turnon == 0) { - rattr = thisattr; - continue; - } - - TR(TRACE_ATTRS, ("At (%d, %d): from %s...", i, j, _traceattr(rattr))); - TR(TRACE_ATTRS, ("...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) & SP->_xmc_triggers)) - if (ISBLANK(thisline[j]) && SAFE(turnon)) { - RemAttr(thisline[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 - || !ISBLANK(thisline[j - k]) - || !SAFE(AttrOf(thisline[j - k]))) { - failed = TRUE; - TR(TRACE_ATTRS, ("No room at start in %d,%d%s%s", - i, j - k, - (ISBLANK(thisline[j - k]) - ? "" - : ":nonblank"), - (SAFE(AttrOf(thisline[j - k])) - ? "" - : ":unsafe"))); - break; - } - } - if (!failed) { - bool end_onscreen = FALSE; - int m, n = j; - - /* find end of span, if it's onscreen */ - for (m = i; m < screen_lines; m++) { - for (; n < screen_columns; n++) { - attr_t testattr = AttrOf(newscr->_line[m].text[n]); - if ((testattr & SP->_xmc_triggers) == rattr) { - end_onscreen = TRUE; - TR(TRACE_ATTRS, - ("Range attributed with %s ends at (%d, %d)", - _traceattr(turnon), m, n)); - goto foundit; - } - } - n = 0; - } - TR(TRACE_ATTRS, - ("Range attributed with %s ends offscreen", - _traceattr(turnon))); - foundit:; - - if (end_onscreen) { - NCURSES_CH_T *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 - && ISBLANK(lastline[n]) - && SAFE(AttrOf(lastline[n]))) { - RemAttr(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 - || !ISBLANK(lastline[n + k]) - || !SAFE(AttrOf(lastline[n + k]))) { - failed = TRUE; - TR(TRACE_ATTRS, - ("No room at end in %d,%d%s%s", - i, j - k, - (ISBLANK(lastline[n + k]) - ? "" - : ":nonblank"), - (SAFE(AttrOf(lastline[n + k])) - ? "" - : ":unsafe"))); - break; - } - } - } - } - - if (failed) { - int p, q = j; - - TR(TRACE_ATTRS, - ("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 < screen_columns; q++) { - attr_t testattr = AttrOf(newscr->_line[p].text[q]); - if ((testattr & SP->_xmc_triggers) == rattr) - goto foundend; - RemAttr(newscr->_line[p].text[q], turnon); - } - q = 0; - } - foundend:; - } else { - TR(TRACE_ATTRS, - ("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++) - AddAttr(thisline[j - k], turnon); - } - - rattr = thisattr; - } - } - -#ifdef TRACE - /* show altered highlights after magic-cookie check */ - if (USE_TRACEF(TRACE_UPDATE)) { - _tracef("After magic-cookie check..."); - _tracedump("newscr", newscr); - _nc_unlock_global(tracef); - } -#endif /* TRACE */ - } -#endif /* USE_XMC_SUPPORT */ - - nonempty = 0; - if (curscr->_clear || newscr->_clear) { /* force refresh ? */ - ClrUpdate(); - curscr->_clear = FALSE; /* reset flag */ - newscr->_clear = FALSE; /* reset flag */ - } else { - int changedlines = CHECK_INTERVAL; - - if (check_pending()) - goto cleanup; - - nonempty = min(screen_lines, newscr->_maxy + 1); - - if (SP->_scrolling) { - _nc_scroll_optimize(); - } - - nonempty = ClrBottom(nonempty); - - TR(TRACE_UPDATE, ("Transforming lines, nonempty %d", nonempty)); - for (i = 0; i < nonempty; i++) { - /* - * Here is our line-breakout optimization. - */ - if (changedlines == CHECK_INTERVAL) { - if (check_pending()) - goto cleanup; - changedlines = 0; - } - - /* - * 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) { - MARK_NOCHANGE(newscr, i); - } - if (i <= curscr->_maxy) { - MARK_NOCHANGE(curscr, 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); - } - - if (!newscr->_leaveok) { - curscr->_curx = newscr->_curx; - curscr->_cury = newscr->_cury; - - GoTo(curscr->_cury, curscr->_curx); - } - - cleanup: - /* - * We would like to keep the physical screen in normal mode in case we get - * other processes writing to the screen. This goal cannot be met for - * magic cookies since it interferes with attributes that may propagate - * past the current position. - */ -#if USE_XMC_SUPPORT - if (magic_cookie_glitch != 0) -#endif - UpdateAttrs(normal); - - _nc_flush(); - WINDOW_ATTRS(curscr) = WINDOW_ATTRS(newscr); - -#if USE_TRACE_TIMES - (void) times(&after); - TR(TRACE_TIMES, - ("Update cost: %ld chars, %ld clocks system time, %ld clocks user time", - _nc_outchars, - (long) (after.tms_stime - before.tms_stime), - (long) (after.tms_utime - before.tms_utime))); -#endif /* USE_TRACE_TIMES */ - - _nc_signal_handler(TRUE); - - 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. - * - * 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))->_nc_bkgd) - -static NCURSES_INLINE NCURSES_CH_T -ClrBlank(WINDOW *win) -{ - NCURSES_CH_T blank = blankchar; - if (back_color_erase) - AddAttr(blank, (AttrOf(BCE_BKGD(win)) & BCE_ATTRS)); - return blank; -} - -/* -** ClrUpdate() -** -** Update by clearing and redrawing the entire screen. -** -*/ - -static void -ClrUpdate(void) -{ - int i; - NCURSES_CH_T blank = ClrBlank(stdscr); - int nonempty = min(screen_lines, newscr->_maxy + 1); - - TR(TRACE_UPDATE, (T_CALLED("ClrUpdate"))); - - ClearScreen(blank); - - TR(TRACE_UPDATE, ("updating screen from scratch")); - - nonempty = ClrBottom(nonempty); - - for (i = 0; i < nonempty; i++) - TransformLine(i); - - TR(TRACE_UPDATE, (T_RETURN(""))); -} - -/* -** ClrToEOL(blank) -** -** Clear to end of current line, starting at the cursor position -*/ - -static void -ClrToEOL(NCURSES_CH_T blank, bool needclear) -{ - int j; - - if (curscr != 0 - && SP->_cursrow >= 0) { - for (j = SP->_curscol; j < screen_columns; j++) { - if (j >= 0) { - NCURSES_CH_T *cp = &(curscr->_line[SP->_cursrow].text[j]); - - if (!CharEq(*cp, blank)) { - *cp = blank; - needclear = TRUE; - } - } - } - } else { - needclear = TRUE; - } - - if (needclear) { - UpdateAttrs(blank); - TPUTS_TRACE("clr_eol"); - if (clr_eol && SP->_el_cost <= (screen_columns - SP->_curscol)) { - putp(clr_eol); - } else { - int count = (screen_columns - SP->_curscol); - while (count-- > 0) - PutChar(CHREF(blank)); - } - } -} - -/* -** ClrToEOS(blank) -** -** Clear to end of screen, starting at the cursor position -*/ - -static void -ClrToEOS(NCURSES_CH_T blank) -{ - int row, col; - - row = SP->_cursrow; - col = SP->_curscol; - - UpdateAttrs(blank); - TPUTS_TRACE("clr_eos"); - tputs(clr_eos, screen_lines - row, _nc_outch); - - while (col < screen_columns) - curscr->_line[row].text[col++] = blank; - - for (row++; row < screen_lines; row++) { - for (col = 0; col < screen_columns; col++) - curscr->_line[row].text[col] = blank; - } -} - -/* - * 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 row; - int col; - int top = total; - int last = min(screen_columns, newscr->_maxx + 1); - NCURSES_CH_T blank = newscr->_line[total - 1].text[last - 1]; - bool ok; - - if (clr_eos && can_clear_with(CHREF(blank))) { - - for (row = total - 1; row >= 0; row--) { - for (col = 0, ok = TRUE; ok && col < last; col++) { - ok = (CharEq(newscr->_line[row].text[col], blank)); - } - if (!ok) - break; - - for (col = 0; ok && col < last; col++) { - ok = (CharEq(curscr->_line[row].text[col], blank)); - } - if (!ok) - top = row; - } - - /* don't use clr_eos for just one line if clr_eol available */ - if (top < total) { - GoTo(top, 0); - ClrToEOS(blank); - if (SP->oldhash && SP->newhash) { - for (row = top; row < screen_lines; row++) - SP->oldhash[row] = SP->newhash[row]; - } - } - } - return top; -} - -#if USE_XMC_SUPPORT -#if USE_WIDEC_SUPPORT -#define check_xmc_transition(a, b) \ - ((((a)->attr ^ (b)->attr) & ~((a)->attr) & SP->_xmc_triggers) != 0) -#define xmc_turn_on(a,b) check_xmc_transition(&(a), &(b)) -#else -#define xmc_turn_on(a,b) ((((a)^(b)) & ~(a) & SP->_xmc_triggers) != 0) -#endif - -#define xmc_new(r,c) newscr->_line[r].text[c] -#define xmc_turn_off(a,b) xmc_turn_on(b,a) -#endif /* USE_XMC_SUPPORT */ - -/* -** TransformLine(lineno) -** -** Transform the given line in curscr to the one in newscr, using -** 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 -** nLastChar = position of last different character in new line -** -** move to firstChar -** overwrite chars up to min(oLastChar, nLastChar) -** if oLastChar < nLastChar -** insert newLine[oLastChar+1..nLastChar] -** else -** delete oLastChar - nLastChar spaces -*/ - -static void -TransformLine(int const lineno) -{ - int firstChar, oLastChar, nLastChar; - NCURSES_CH_T *newLine = newscr->_line[lineno].text; - NCURSES_CH_T *oldLine = curscr->_line[lineno].text; - int n; - bool attrchanged = FALSE; - - TR(TRACE_UPDATE, (T_CALLED("TransformLine(%d)"), lineno)); - - /* copy new hash value to old one */ - if (SP->oldhash && SP->newhash) - SP->oldhash[lineno] = SP->newhash[lineno]; - - /* - * If we have colors, there is the possibility of having two color pairs - * that display as the same colors. For instance, Lynx does this. Check - * for this case, and update the old line with the new line's colors when - * they are equivalent. - */ - if (SP->_coloron) { - int oldPair; - int newPair; - - for (n = 0; n < screen_columns; n++) { - if (!CharEq(newLine[n], oldLine[n])) { - oldPair = GetPair(oldLine[n]); - newPair = GetPair(newLine[n]); - if (oldPair != newPair - && unColor(oldLine[n]) == unColor(newLine[n])) { - if (oldPair < COLOR_PAIRS - && newPair < COLOR_PAIRS - && SP->_color_pairs[oldPair] == SP->_color_pairs[newPair]) { - SetPair(oldLine[n], GetPair(newLine[n])); - } - } - } - } - } - - if (ceol_standout_glitch && clr_eol) { - firstChar = 0; - while (firstChar < screen_columns) { - if (!SameAttrOf(newLine[firstChar], oldLine[firstChar])) { - attrchanged = TRUE; - break; - } - firstChar++; - } - } - - firstChar = 0; - - if (attrchanged) { /* we may have to disregard the whole line */ - GoTo(lineno, firstChar); - ClrToEOL(ClrBlank(curscr), FALSE); - PutRange(oldLine, newLine, lineno, 0, (screen_columns - 1)); -#if USE_XMC_SUPPORT - - /* - * This is a very simple loop to paint characters which may have the - * magic cookie glitch embedded. It doesn't know much about video - * attributes which are continued from one line to the next. It - * assumes that we have filtered out requests for attribute changes - * that do not get mapped to blank positions. - * - * FIXME: we are not keeping track of where we put the cookies, so this - * will work properly only once, since we may overwrite a cookie in a - * following operation. - */ - } else if (magic_cookie_glitch > 0) { - GoTo(lineno, firstChar); - for (n = 0; n < screen_columns; n++) { - int m = n + magic_cookie_glitch; - - /* check for turn-on: - * If we are writing an attributed blank, where the - * previous cell is not attributed. - */ - if (ISBLANK(newLine[n]) - && ((n > 0 - && xmc_turn_on(newLine[n - 1], newLine[n])) - || (n == 0 - && lineno > 0 - && xmc_turn_on(xmc_new(lineno - 1, screen_columns - 1), - newLine[n])))) { - n = m; - } - - PutChar(CHREF(newLine[n])); - - /* check for turn-off: - * If we are writing an attributed non-blank, where the - * next cell is blank, and not attributed. - */ - if (!ISBLANK(newLine[n]) - && ((n + 1 < screen_columns - && xmc_turn_off(newLine[n], newLine[n + 1])) - || (n + 1 >= screen_columns - && lineno + 1 < screen_lines - && xmc_turn_off(newLine[n], xmc_new(lineno + 1, 0))))) { - n = m; - } - - } -#endif - } else { - NCURSES_CH_T blank; - - /* it may be cheap to clear leading whitespace with clr_bol */ - blank = newLine[0]; - if (clr_bol && can_clear_with(CHREF(blank))) { - int oFirstChar, nFirstChar; - - for (oFirstChar = 0; oFirstChar < screen_columns; oFirstChar++) - if (!CharEq(oldLine[oFirstChar], blank)) - break; - for (nFirstChar = 0; nFirstChar < screen_columns; nFirstChar++) - if (!CharEq(newLine[nFirstChar], blank)) - break; - - if (nFirstChar == oFirstChar) { - firstChar = nFirstChar; - /* find the first differing character */ - while (firstChar < screen_columns - && CharEq(newLine[firstChar], oldLine[firstChar])) - firstChar++; - } else if (oFirstChar > nFirstChar) { - firstChar = nFirstChar; - } else { /* oFirstChar < nFirstChar */ - firstChar = oFirstChar; - if (SP->_el1_cost < nFirstChar - oFirstChar) { - if (nFirstChar >= screen_columns - && SP->_el_cost <= SP->_el1_cost) { - GoTo(lineno, 0); - UpdateAttrs(blank); - TPUTS_TRACE("clr_eol"); - putp(clr_eol); - } else { - GoTo(lineno, nFirstChar - 1); - UpdateAttrs(blank); - TPUTS_TRACE("clr_bol"); - putp(clr_bol); - } - - while (firstChar < nFirstChar) - oldLine[firstChar++] = blank; - } - } - } else { - /* find the first differing character */ - while (firstChar < screen_columns - && CharEq(newLine[firstChar], oldLine[firstChar])) - firstChar++; - } - /* if there wasn't one, we're done */ - if (firstChar >= screen_columns) { - TR(TRACE_UPDATE, (T_RETURN(""))); - return; - } - - blank = newLine[screen_columns - 1]; - - if (!can_clear_with(CHREF(blank))) { - /* find the last differing character */ - nLastChar = screen_columns - 1; - - while (nLastChar > firstChar - && CharEq(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(NCURSES_CH_T)); - } - TR(TRACE_UPDATE, (T_RETURN(""))); - return; - } - - /* find last non-blank character on old line */ - oLastChar = screen_columns - 1; - while (oLastChar > firstChar && CharEq(oldLine[oLastChar], blank)) - oLastChar--; - - /* find last non-blank character on new line */ - nLastChar = screen_columns - 1; - while (nLastChar > firstChar && CharEq(newLine[nLastChar], blank)) - nLastChar--; - - if ((nLastChar == firstChar) - && (SP->_el_cost < (oLastChar - nLastChar))) { - GoTo(lineno, firstChar); - if (!CharEq(newLine[firstChar], blank)) - PutChar(CHREF(newLine[firstChar])); - ClrToEOL(blank, FALSE); - } else if ((nLastChar != oLastChar) - && (!CharEq(newLine[nLastChar], oldLine[oLastChar]) - || !(_nc_idcok && has_ic()))) { - GoTo(lineno, firstChar); - if ((oLastChar - nLastChar) > SP->_el_cost) { - if (PutRange(oldLine, newLine, lineno, firstChar, nLastChar)) - GoTo(lineno, nLastChar + 1); - ClrToEOL(blank, FALSE); - } 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 */ - /* can be -1 if no characters differ */ - while (CharEq(newLine[nLastChar], oldLine[oLastChar])) { - /* don't split a wide char */ - if (isWidecExt(newLine[nLastChar]) && - !CharEq(newLine[nLastChar - 1], oldLine[oLastChar - 1])) - break; - nLastChar--; - oLastChar--; - if (nLastChar == -1 || oLastChar == -1) - break; - } - - n = min(oLastChar, nLastChar); - if (n >= firstChar) { - GoTo(lineno, firstChar); - PutRange(oldLine, newLine, lineno, firstChar, n); - } - - if (oLastChar < nLastChar) { - int m = max(nLastNonblank, oLastNonblank); -#if USE_WIDEC_SUPPORT - while (isWidecExt(newLine[n + 1]) && n) { - --n; - --oLastChar; - } -#endif - GoTo(lineno, n + 1); - if ((nLastChar < nLastNonblank) - || InsCharCost(nLastChar - oLastChar) > (m - n)) { - PutRange(oldLine, newLine, lineno, n + 1, m); - } else { - InsStr(&newLine[n + 1], nLastChar - oLastChar); - } - } else if (oLastChar > nLastChar) { - GoTo(lineno, n + 1); - if (DelCharCost(oLastChar - nLastChar) - > SP->_el_cost + nLastNonblank - (n + 1)) { - if (PutRange(oldLine, newLine, lineno, - n + 1, nLastNonblank)) - GoTo(lineno, nLastNonblank + 1); - ClrToEOL(blank, FALSE); - } 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); - } - } - } - } - - /* update the code's internal representation */ - if (screen_columns > firstChar) - memcpy(oldLine + firstChar, - newLine + firstChar, - (screen_columns - firstChar) * sizeof(NCURSES_CH_T)); - TR(TRACE_UPDATE, (T_RETURN(""))); - return; -} - -/* -** ClearScreen(blank) -** -** Clear the physical screen and put cursor at home -** -*/ - -static void -ClearScreen(NCURSES_CH_T blank) -{ - int i, j; - bool fast_clear = (clear_screen || clr_eos || clr_eol); - - TR(TRACE_UPDATE, ("ClearScreen() called")); - -#if NCURSES_EXT_FUNCS - if (SP->_coloron - && !SP->_default_color) { - _nc_do_color(GET_SCREEN_PAIR(SP), 0, FALSE, _nc_outch); - if (!back_color_erase) { - fast_clear = FALSE; - } - } -#endif - - if (fast_clear) { - if (clear_screen) { - UpdateAttrs(blank); - TPUTS_TRACE("clear_screen"); - putp(clear_screen); - SP->_cursrow = SP->_curscol = 0; - position_check(SP->_cursrow, SP->_curscol, "ClearScreen"); - } else if (clr_eos) { - SP->_cursrow = SP->_curscol = -1; - GoTo(0, 0); - - UpdateAttrs(blank); - TPUTS_TRACE("clr_eos"); - tputs(clr_eos, screen_lines, _nc_outch); - } else if (clr_eol) { - SP->_cursrow = SP->_curscol = -1; - - UpdateAttrs(blank); - for (i = 0; i < screen_lines; i++) { - GoTo(i, 0); - TPUTS_TRACE("clr_eol"); - putp(clr_eol); - } - GoTo(0, 0); - } - } else { - UpdateAttrs(blank); - for (i = 0; i < screen_lines; i++) { - GoTo(i, 0); - for (j = 0; j < screen_columns; j++) - PutChar(CHREF(blank)); - } - GoTo(0, 0); - } - - for (i = 0; i < screen_lines; i++) { - for (j = 0; j < screen_columns; j++) - curscr->_line[i].text[j] = blank; - } - - TR(TRACE_UPDATE, ("screen cleared")); -} - -/* -** InsStr(line, count) -** -** Insert the count characters pointed to by line. -** -*/ - -static void -InsStr(NCURSES_CH_T * line, int count) -{ - TR(TRACE_UPDATE, ("InsStr(%p,%d) called", line, count)); - - /* Prefer parm_ich as it has the smallest cost - no need to shift - * the whole line on each character. */ - /* The order must match that of InsCharCost. */ - if (parm_ich) { - TPUTS_TRACE("parm_ich"); - tputs(TPARM_1(parm_ich, count), count, _nc_outch); - while (count) { - PutAttrChar(CHREF(*line)); - line++; - count--; - } - } else if (enter_insert_mode && exit_insert_mode) { - TPUTS_TRACE("enter_insert_mode"); - putp(enter_insert_mode); - while (count) { - PutAttrChar(CHREF(*line)); - if (insert_padding) { - TPUTS_TRACE("insert_padding"); - putp(insert_padding); - } - line++; - count--; - } - TPUTS_TRACE("exit_insert_mode"); - putp(exit_insert_mode); - } else { - while (count) { - TPUTS_TRACE("insert_character"); - putp(insert_character); - PutAttrChar(CHREF(*line)); - if (insert_padding) { - TPUTS_TRACE("insert_padding"); - putp(insert_padding); - } - line++; - count--; - } - } - position_check(SP->_cursrow, SP->_curscol, "InsStr"); -} - -/* -** DelChar(count) -** -** Delete count characters at current position -** -*/ - -static void -DelChar(int count) -{ - int n; - - TR(TRACE_UPDATE, ("DelChar(%d) called, position = (%ld,%ld)", - count, - (long) newscr->_cury, - (long) newscr->_curx)); - - if (parm_dch) { - TPUTS_TRACE("parm_dch"); - tputs(TPARM_1(parm_dch, count), count, _nc_outch); - } else { - for (n = 0; n < count; n++) { - TPUTS_TRACE("delete_character"); - putp(delete_character); - } - } -} - -/* - * Physical-scrolling support - * - * This code was adapted from Keith Bostic's hardware scrolling - * support for 4.4BSD curses. I (esr) translated it to use terminfo - * capabilities, narrowed the call interface slightly, and cleaned - * up some convoluted tests. I also added support for the memory_above - * memory_below, and non_dest_scroll_region capabilities. - * - * For this code to work, we must have either - * change_scroll_region and scroll forward/reverse commands, or - * insert and delete line capabilities. - * When the scrolling region has been set, the cursor has to - * be at the last line of the region to make the scroll up - * happen, or on the first line of region to scroll down. - * - * This code makes one aesthetic decision in the opposite way from - * 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 many terminals and (b) using them avoids bouncing an - * unchanged bottom section of the screen up and down, which is - * visually nasty. - * - * (lav): added more cases, used dl/il when bot==maxy and in csr case. - * - * I used assumption that capabilities il/il1/dl/dl1 work inside - * changed scroll region not shifting screen contents outside of it. - * If there are any terminals behaving different way, it would be - * necessary to add some conditions to scroll_csr_forward/backward. - */ - -/* Try to scroll up assuming given csr (miny, maxy). Returns ERR on failure */ -static int -scroll_csr_forward(int n, int top, int bot, int miny, int maxy, NCURSES_CH_T blank) -{ - int i; - - if (n == 1 && scroll_forward && top == miny && bot == maxy) { - GoTo(bot, 0); - UpdateAttrs(blank); - TPUTS_TRACE("scroll_forward"); - putp(scroll_forward); - } else if (n == 1 && delete_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("delete_line"); - putp(delete_line); - } else if (parm_index && top == miny && bot == maxy) { - GoTo(bot, 0); - UpdateAttrs(blank); - TPUTS_TRACE("parm_index"); - tputs(TPARM_2(parm_index, n, 0), n, _nc_outch); - } else if (parm_delete_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("parm_delete_line"); - tputs(TPARM_2(parm_delete_line, n, 0), n, _nc_outch); - } else if (scroll_forward && top == miny && bot == maxy) { - GoTo(bot, 0); - UpdateAttrs(blank); - for (i = 0; i < n; i++) { - TPUTS_TRACE("scroll_forward"); - putp(scroll_forward); - } - } else if (delete_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - for (i = 0; i < n; i++) { - TPUTS_TRACE("delete_line"); - putp(delete_line); - } - } else - return ERR; - -#if NCURSES_EXT_FUNCS - if (FILL_BCE()) { - int j; - for (i = 0; i < n; i++) { - GoTo(bot - i, 0); - for (j = 0; j < screen_columns; j++) - PutChar(CHREF(blank)); - } - } -#endif - return OK; -} - -/* Try to scroll down assuming given csr (miny, maxy). Returns ERR on failure */ -/* n > 0 */ -static int -scroll_csr_backward(int n, int top, int bot, int miny, int maxy, - NCURSES_CH_T blank) -{ - int i; - - if (n == 1 && scroll_reverse && top == miny && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("scroll_reverse"); - putp(scroll_reverse); - } else if (n == 1 && insert_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("insert_line"); - putp(insert_line); - } else if (parm_rindex && top == miny && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("parm_rindex"); - tputs(TPARM_2(parm_rindex, n, 0), n, _nc_outch); - } else if (parm_insert_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - TPUTS_TRACE("parm_insert_line"); - tputs(TPARM_2(parm_insert_line, n, 0), n, _nc_outch); - } else if (scroll_reverse && top == miny && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - for (i = 0; i < n; i++) { - TPUTS_TRACE("scroll_reverse"); - putp(scroll_reverse); - } - } else if (insert_line && bot == maxy) { - GoTo(top, 0); - UpdateAttrs(blank); - for (i = 0; i < n; i++) { - TPUTS_TRACE("insert_line"); - putp(insert_line); - } - } else - return ERR; - -#if NCURSES_EXT_FUNCS - if (FILL_BCE()) { - int j; - for (i = 0; i < n; i++) { - GoTo(top + i, 0); - for (j = 0; j < screen_columns; j++) - PutChar(CHREF(blank)); - } - } -#endif - return OK; -} - -/* scroll by using delete_line at del and insert_line at ins */ -/* n > 0 */ -static int -scroll_idl(int n, int del, int ins, NCURSES_CH_T blank) -{ - int i; - - if (!((parm_delete_line || delete_line) && (parm_insert_line || insert_line))) - return ERR; - - GoTo(del, 0); - UpdateAttrs(blank); - if (n == 1 && delete_line) { - TPUTS_TRACE("delete_line"); - putp(delete_line); - } else if (parm_delete_line) { - TPUTS_TRACE("parm_delete_line"); - tputs(TPARM_2(parm_delete_line, n, 0), n, _nc_outch); - } else { /* if (delete_line) */ - for (i = 0; i < n; i++) { - TPUTS_TRACE("delete_line"); - putp(delete_line); - } - } - - GoTo(ins, 0); - UpdateAttrs(blank); - if (n == 1 && insert_line) { - TPUTS_TRACE("insert_line"); - putp(insert_line); - } else if (parm_insert_line) { - TPUTS_TRACE("parm_insert_line"); - tputs(TPARM_2(parm_insert_line, n, 0), n, _nc_outch); - } else { /* if (insert_line) */ - for (i = 0; i < n; i++) { - TPUTS_TRACE("insert_line"); - putp(insert_line); - } - } - - return OK; -} - -/* - * Note: some terminals require the cursor to be within the scrolling margins - * before setting them. Generally, the cursor must be at the appropriate end - * of the scrolling margins when issuing an indexing operation (it is not - * apparent whether it must also be at the left margin; we do this just to be - * safe). To make the related cursor movement a little faster, we use the - * save/restore cursor capabilities if the terminal has them. - */ -NCURSES_EXPORT(int) -_nc_scrolln(int n, int top, int bot, int maxy) -/* scroll region from top to bot by n lines */ -{ - NCURSES_CH_T blank = ClrBlank(stdscr); - int i; - bool cursor_saved = FALSE; - int res; - - TR(TRACE_MOVE, ("mvcur_scrolln(%d, %d, %d, %d)", n, top, bot, maxy)); - -#if USE_XMC_SUPPORT - /* - * If we scroll, we might remove a cookie. - */ - if (magic_cookie_glitch > 0) { - return (ERR); - } -#endif - - if (n > 0) { /* scroll up (forward) */ - /* - * Explicitly clear if stuff pushed off top of region might - * be saved by the terminal. - */ - res = scroll_csr_forward(n, top, bot, 0, maxy, blank); - - if (res == ERR && change_scroll_region) { - if ((((n == 1 && scroll_forward) || parm_index) - && (SP->_cursrow == bot || SP->_cursrow == bot - 1)) - && save_cursor && restore_cursor) { - cursor_saved = TRUE; - TPUTS_TRACE("save_cursor"); - putp(save_cursor); - } - TPUTS_TRACE("change_scroll_region"); - putp(TPARM_2(change_scroll_region, top, bot)); - if (cursor_saved) { - TPUTS_TRACE("restore_cursor"); - putp(restore_cursor); - } else { - SP->_cursrow = SP->_curscol = -1; - } - - res = scroll_csr_forward(n, top, bot, top, bot, blank); - - TPUTS_TRACE("change_scroll_region"); - putp(TPARM_2(change_scroll_region, 0, maxy)); - SP->_cursrow = SP->_curscol = -1; - } - - if (res == ERR && _nc_idlok) - res = scroll_idl(n, top, bot - n + 1, blank); - - /* - * Clear the newly shifted-in text. - */ - if (res != ERR - && (non_dest_scroll_region || (memory_below && bot == maxy))) { - static const NCURSES_CH_T blank2 = NewChar(BLANK_TEXT); - if (bot == maxy && clr_eos) { - GoTo(bot - n + 1, 0); - ClrToEOS(blank2); - } else { - for (i = 0; i < n; i++) { - GoTo(bot - i, 0); - ClrToEOL(blank2, FALSE); - } - } - } - - } else { /* (n < 0) - scroll down (backward) */ - res = scroll_csr_backward(-n, top, bot, 0, maxy, blank); - - if (res == ERR && change_scroll_region) { - if (top != 0 && (SP->_cursrow == top || SP->_cursrow == top - 1) - && save_cursor && restore_cursor) { - cursor_saved = TRUE; - TPUTS_TRACE("save_cursor"); - putp(save_cursor); - } - TPUTS_TRACE("change_scroll_region"); - putp(TPARM_2(change_scroll_region, top, bot)); - if (cursor_saved) { - TPUTS_TRACE("restore_cursor"); - putp(restore_cursor); - } else { - SP->_cursrow = SP->_curscol = -1; - } - - res = scroll_csr_backward(-n, top, bot, top, bot, blank); - - TPUTS_TRACE("change_scroll_region"); - putp(TPARM_2(change_scroll_region, 0, maxy)); - SP->_cursrow = SP->_curscol = -1; - } - - if (res == ERR && _nc_idlok) - res = scroll_idl(-n, bot + n + 1, top, blank); - - /* - * Clear the newly shifted-in text. - */ - if (res != ERR - && (non_dest_scroll_region || (memory_above && top == 0))) { - static const NCURSES_CH_T blank2 = NewChar(BLANK_TEXT); - for (i = 0; i < -n; i++) { - GoTo(i + top, 0); - ClrToEOL(blank2, FALSE); - } - } - } - - if (res == ERR) - return (ERR); - - _nc_scroll_window(curscr, n, top, bot, blank); - - /* shift hash values too - they can be reused */ - _nc_scroll_oldhash(n, top, bot); - - return (OK); -} - -NCURSES_EXPORT(void) -_nc_screen_resume(void) -{ - /* make sure terminal is in a sane known state */ - SetAttr(SCREEN_ATTRS(SP), A_NORMAL); - newscr->_clear = TRUE; - - /* reset color pairs and definitions */ - if (SP->_coloron || SP->_color_defs) - _nc_reset_colors(); - - /* restore user-defined colors, if any */ - if (SP->_color_defs < 0) { - int n; - SP->_color_defs = -(SP->_color_defs); - for (n = 0; n < SP->_color_defs; ++n) { - if (SP->_color_table[n].init) { - init_color(n, - SP->_color_table[n].r, - SP->_color_table[n].g, - SP->_color_table[n].b); - } - } - } - - if (exit_attribute_mode) - putp(exit_attribute_mode); - else { - /* turn off attributes */ - if (exit_alt_charset_mode) - putp(exit_alt_charset_mode); - if (exit_standout_mode) - putp(exit_standout_mode); - if (exit_underline_mode) - putp(exit_underline_mode); - } - if (exit_insert_mode) - putp(exit_insert_mode); - if (enter_am_mode && exit_am_mode) - putp(auto_right_margin ? enter_am_mode : exit_am_mode); -} - -NCURSES_EXPORT(void) -_nc_screen_init(void) -{ - _nc_screen_resume(); -} - -/* wrap up screen handling */ -NCURSES_EXPORT(void) -_nc_screen_wrap(void) -{ - UpdateAttrs(normal); -#if NCURSES_EXT_FUNCS - if (SP->_coloron - && !SP->_default_color) { - static const NCURSES_CH_T blank = NewChar(BLANK_TEXT); - SP->_default_color = TRUE; - _nc_do_color(-1, 0, FALSE, _nc_outch); - SP->_default_color = FALSE; - - mvcur(SP->_cursrow, SP->_curscol, screen_lines - 1, 0); - - ClrToEOL(blank, TRUE); - } -#endif - if (SP->_color_defs) { - _nc_reset_colors(); - } -} - -#if USE_XMC_SUPPORT -NCURSES_EXPORT(void) -_nc_do_xmc_glitch(attr_t previous) -{ - attr_t chg = XMC_CHANGES(previous ^ AttrOf(SCREEN_ATTRS(SP))); - - while (chg != 0) { - if (chg & 1) { - SP->_curscol += magic_cookie_glitch; - if (SP->_curscol >= SP->_columns) - wrap_cursor(); - TR(TRACE_UPDATE, ("bumped to %d,%d after cookie", SP->_cursrow, SP->_curscol)); - } - chg >>= 1; - } -} -#endif /* USE_XMC_SUPPORT */ |