1  | 
     | 
     | 
    /*	$OpenBSD: hardscroll.c,v 1.7 2010/01/12 23:22:07 nicm Exp $	*/  | 
    
    
    2  | 
     | 
     | 
     | 
    
    
    3  | 
     | 
     | 
    /****************************************************************************  | 
    
    
    4  | 
     | 
     | 
     * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *  | 
    
    
    5  | 
     | 
     | 
     *                                                                          *  | 
    
    
    6  | 
     | 
     | 
     * Permission is hereby granted, free of charge, to any person obtaining a  *  | 
    
    
    7  | 
     | 
     | 
     * copy of this software and associated documentation files (the            *  | 
    
    
    8  | 
     | 
     | 
     * "Software"), to deal in the Software without restriction, including      *  | 
    
    
    9  | 
     | 
     | 
     * without limitation the rights to use, copy, modify, merge, publish,      *  | 
    
    
    10  | 
     | 
     | 
     * distribute, distribute with modifications, sublicense, and/or sell       *  | 
    
    
    11  | 
     | 
     | 
     * copies of the Software, and to permit persons to whom the Software is    *  | 
    
    
    12  | 
     | 
     | 
     * furnished to do so, subject to the following conditions:                 *  | 
    
    
    13  | 
     | 
     | 
     *                                                                          *  | 
    
    
    14  | 
     | 
     | 
     * The above copyright notice and this permission notice shall be included  *  | 
    
    
    15  | 
     | 
     | 
     * in all copies or substantial portions of the Software.                   *  | 
    
    
    16  | 
     | 
     | 
     *                                                                          *  | 
    
    
    17  | 
     | 
     | 
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *  | 
    
    
    18  | 
     | 
     | 
     * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *  | 
    
    
    19  | 
     | 
     | 
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *  | 
    
    
    20  | 
     | 
     | 
     * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *  | 
    
    
    21  | 
     | 
     | 
     * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *  | 
    
    
    22  | 
     | 
     | 
     * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *  | 
    
    
    23  | 
     | 
     | 
     * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *  | 
    
    
    24  | 
     | 
     | 
     *                                                                          *  | 
    
    
    25  | 
     | 
     | 
     * Except as contained in this notice, the name(s) of the above copyright   *  | 
    
    
    26  | 
     | 
     | 
     * holders shall not be used in advertising or otherwise to promote the     *  | 
    
    
    27  | 
     | 
     | 
     * sale, use or other dealings in this Software without prior written       *  | 
    
    
    28  | 
     | 
     | 
     * authorization.                                                           *  | 
    
    
    29  | 
     | 
     | 
     ****************************************************************************/  | 
    
    
    30  | 
     | 
     | 
     | 
    
    
    31  | 
     | 
     | 
    /****************************************************************************  | 
    
    
    32  | 
     | 
     | 
     *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *  | 
    
    
    33  | 
     | 
     | 
     *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *  | 
    
    
    34  | 
     | 
     | 
     *     and: Thomas E. Dickey                        1996-on                 *  | 
    
    
    35  | 
     | 
     | 
     *     and: Alexander V Lukyanov                    1997-1998               *  | 
    
    
    36  | 
     | 
     | 
     ****************************************************************************/  | 
    
    
    37  | 
     | 
     | 
     | 
    
    
    38  | 
     | 
     | 
    /******************************************************************************  | 
    
    
    39  | 
     | 
     | 
     | 
    
    
    40  | 
     | 
     | 
    NAME  | 
    
    
    41  | 
     | 
     | 
       hardscroll.c -- hardware-scrolling optimization for ncurses  | 
    
    
    42  | 
     | 
     | 
     | 
    
    
    43  | 
     | 
     | 
    SYNOPSIS  | 
    
    
    44  | 
     | 
     | 
       void _nc_scroll_optimize(void)  | 
    
    
    45  | 
     | 
     | 
     | 
    
    
    46  | 
     | 
     | 
    DESCRIPTION  | 
    
    
    47  | 
     | 
     | 
    			OVERVIEW  | 
    
    
    48  | 
     | 
     | 
     | 
    
    
    49  | 
     | 
     | 
    This algorithm for computes optimum hardware scrolling to transform an  | 
    
    
    50  | 
     | 
     | 
    old screen (curscr) into a new screen (newscr) via vertical line moves.  | 
    
    
    51  | 
     | 
     | 
     | 
    
    
    52  | 
     | 
     | 
    Because the screen has a `grain' (there are insert/delete/scroll line  | 
    
    
    53  | 
     | 
     | 
    operations but no insert/delete/scroll column operations), it is efficient  | 
    
    
    54  | 
     | 
     | 
    break the update algorithm into two pieces: a first stage that does only line  | 
    
    
    55  | 
     | 
     | 
    moves, optimizing the end product of user-invoked insertions, deletions, and  | 
    
    
    56  | 
     | 
     | 
    scrolls; and a second phase (corresponding to the present doupdate code in  | 
    
    
    57  | 
     | 
     | 
    ncurses) that does only line transformations.  | 
    
    
    58  | 
     | 
     | 
     | 
    
    
    59  | 
     | 
     | 
    The common case we want hardware scrolling for is to handle line insertions  | 
    
    
    60  | 
     | 
     | 
    and deletions in screen-oriented text-editors.  This two-stage approach will  | 
    
    
    61  | 
     | 
     | 
    accomplish that at a low computation and code-size cost.  | 
    
    
    62  | 
     | 
     | 
     | 
    
    
    63  | 
     | 
     | 
    			LINE-MOVE COMPUTATION  | 
    
    
    64  | 
     | 
     | 
     | 
    
    
    65  | 
     | 
     | 
    Now, to a discussion of the line-move computation.  | 
    
    
    66  | 
     | 
     | 
     | 
    
    
    67  | 
     | 
     | 
    For expository purposes, consider the screen lines to be represented by  | 
    
    
    68  | 
     | 
     | 
    integers 0..23 (with the understanding that the value of 23 may vary).  | 
    
    
    69  | 
     | 
     | 
    Let a new line introduced by insertion, scrolling, or at the bottom of  | 
    
    
    70  | 
     | 
     | 
    the screen following a line delete be given the index -1.  | 
    
    
    71  | 
     | 
     | 
     | 
    
    
    72  | 
     | 
     | 
    Assume that the real screen starts with lines 0..23.  Now, we have  | 
    
    
    73  | 
     | 
     | 
    the following possible line-oriented operations on the screen:  | 
    
    
    74  | 
     | 
     | 
     | 
    
    
    75  | 
     | 
     | 
    Insertion: inserts a line at a given screen row, forcing all lines below  | 
    
    
    76  | 
     | 
     | 
    to scroll forward.  The last screen line is lost.  For example, an insertion  | 
    
    
    77  | 
     | 
     | 
    at line 5 would produce: 0..4 -1 5..23.  | 
    
    
    78  | 
     | 
     | 
     | 
    
    
    79  | 
     | 
     | 
    Deletion: deletes a line at a given screen row, forcing all lines below  | 
    
    
    80  | 
     | 
     | 
    to scroll forward.  The last screen line is made new.  For example, a deletion  | 
    
    
    81  | 
     | 
     | 
    at line 7 would produce: 0..6 8..23 -1.  | 
    
    
    82  | 
     | 
     | 
     | 
    
    
    83  | 
     | 
     | 
    Scroll up: move a range of lines up 1.  The bottom line of the range  | 
    
    
    84  | 
     | 
     | 
    becomes new.  For example, scrolling up the region from 9 to 14 will  | 
    
    
    85  | 
     | 
     | 
    produce 0..8 10..14 -1 15..23.  | 
    
    
    86  | 
     | 
     | 
     | 
    
    
    87  | 
     | 
     | 
    Scroll down: move a range of lines down 1.  The top line of the range  | 
    
    
    88  | 
     | 
     | 
    becomes new.  For example, scrolling down the region from 12 to 16 will produce  | 
    
    
    89  | 
     | 
     | 
    0..11 -1 12..15 17..23.  | 
    
    
    90  | 
     | 
     | 
     | 
    
    
    91  | 
     | 
     | 
    Now, an obvious property of all these operations is that they preserve the  | 
    
    
    92  | 
     | 
     | 
    order of old lines, though not their position in the sequence.  | 
    
    
    93  | 
     | 
     | 
     | 
    
    
    94  | 
     | 
     | 
    The key trick of this algorithm is that the original line indices described  | 
    
    
    95  | 
     | 
     | 
    above are actually maintained as _line[].oldindex fields in the window  | 
    
    
    96  | 
     | 
     | 
    structure, and stick to each line through scroll and insert/delete operations.  | 
    
    
    97  | 
     | 
     | 
     | 
    
    
    98  | 
     | 
     | 
    Thus, it is possible at update time to look at the oldnum fields and compute  | 
    
    
    99  | 
     | 
     | 
    an optimal set of il/dl/scroll operations that will take the real screen  | 
    
    
    100  | 
     | 
     | 
    lines to the virtual screen lines.  Once these vertical moves have been done,  | 
    
    
    101  | 
     | 
     | 
    we can hand off to the second stage of the update algorithm, which does line  | 
    
    
    102  | 
     | 
     | 
    transformations.  | 
    
    
    103  | 
     | 
     | 
     | 
    
    
    104  | 
     | 
     | 
    Note that the move computation does not need to have the full generality  | 
    
    
    105  | 
     | 
     | 
    of a diff algorithm (which it superficially resembles) because lines cannot  | 
    
    
    106  | 
     | 
     | 
    be moved out of order.  | 
    
    
    107  | 
     | 
     | 
     | 
    
    
    108  | 
     | 
     | 
    			THE ALGORITHM  | 
    
    
    109  | 
     | 
     | 
     | 
    
    
    110  | 
     | 
     | 
    The scrolling is done in two passes. The first pass is from top to bottom  | 
    
    
    111  | 
     | 
     | 
    scroling hunks UP. The second one is from bottom to top scrolling hunks DOWN.  | 
    
    
    112  | 
     | 
     | 
    Obviously enough, no lines to be scrolled will be destroyed. (lav)  | 
    
    
    113  | 
     | 
     | 
     | 
    
    
    114  | 
     | 
     | 
    HOW TO TEST THIS:  | 
    
    
    115  | 
     | 
     | 
     | 
    
    
    116  | 
     | 
     | 
    Use the following production:  | 
    
    
    117  | 
     | 
     | 
     | 
    
    
    118  | 
     | 
     | 
    hardscroll: hardscroll.c  | 
    
    
    119  | 
     | 
     | 
    	$(CC) -g -DSCROLLDEBUG hardscroll.c -o hardscroll  | 
    
    
    120  | 
     | 
     | 
     | 
    
    
    121  | 
     | 
     | 
    Then just type scramble vectors and watch.  The following test loads are  | 
    
    
    122  | 
     | 
     | 
    a representative sample of cases:  | 
    
    
    123  | 
     | 
     | 
     | 
    
    
    124  | 
     | 
     | 
    -----------------------------  CUT HERE ------------------------------------  | 
    
    
    125  | 
     | 
     | 
    # No lines moved  | 
    
    
    126  | 
     | 
     | 
     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | 
    
    
    127  | 
     | 
     | 
    #  | 
    
    
    128  | 
     | 
     | 
    # A scroll up  | 
    
    
    129  | 
     | 
     | 
     1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 -1  | 
    
    
    130  | 
     | 
     | 
    #  | 
    
    
    131  | 
     | 
     | 
    # A scroll down  | 
    
    
    132  | 
     | 
     | 
    -1  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22  | 
    
    
    133  | 
     | 
     | 
    #  | 
    
    
    134  | 
     | 
     | 
    # An insertion (after line 12)  | 
    
    
    135  | 
     | 
     | 
     0  1  2  3  4  5  6  7  8  9 10 11 12 -1 13 14 15 16 17 18 19 20 21 22  | 
    
    
    136  | 
     | 
     | 
    #  | 
    
    
    137  | 
     | 
     | 
    # A simple deletion (line 10)  | 
    
    
    138  | 
     | 
     | 
     0  1  2  3  4  5  6  7  8  9  11 12 13 14 15 16 17 18 19 20 21 22 23 -1  | 
    
    
    139  | 
     | 
     | 
    #  | 
    
    
    140  | 
     | 
     | 
    # A more complex case  | 
    
    
    141  | 
     | 
     | 
    -1 -1 -1 -1 -1  3  4  5  6  7  -1 -1  8  9 10 11 12 13 14 15 16 17 -1 -1  | 
    
    
    142  | 
     | 
     | 
    -----------------------------  CUT HERE ------------------------------------  | 
    
    
    143  | 
     | 
     | 
     | 
    
    
    144  | 
     | 
     | 
    AUTHOR  | 
    
    
    145  | 
     | 
     | 
        Eric S. Raymond <esr@snark.thyrsus.com>, November 1994  | 
    
    
    146  | 
     | 
     | 
        New algorithm by Alexander V. Lukyanov <lav@yars.free.net>, Aug 1997  | 
    
    
    147  | 
     | 
     | 
     | 
    
    
    148  | 
     | 
     | 
    *****************************************************************************/  | 
    
    
    149  | 
     | 
     | 
     | 
    
    
    150  | 
     | 
     | 
    #include <curses.priv.h>  | 
    
    
    151  | 
     | 
     | 
     | 
    
    
    152  | 
     | 
     | 
    MODULE_ID("$Id: hardscroll.c,v 1.7 2010/01/12 23:22:07 nicm Exp $") | 
    
    
    153  | 
     | 
     | 
     | 
    
    
    154  | 
     | 
     | 
    #if defined(SCROLLDEBUG) || defined(HASHDEBUG)  | 
    
    
    155  | 
     | 
     | 
     | 
    
    
    156  | 
     | 
     | 
    # undef screen_lines  | 
    
    
    157  | 
     | 
     | 
    # define screen_lines MAXLINES  | 
    
    
    158  | 
     | 
     | 
    NCURSES_EXPORT_VAR(int)  | 
    
    
    159  | 
     | 
     | 
    oldnums[MAXLINES];  | 
    
    
    160  | 
     | 
     | 
    # define OLDNUM(n)	oldnums[n]  | 
    
    
    161  | 
     | 
     | 
    # define _tracef	printf  | 
    
    
    162  | 
     | 
     | 
    # undef TR  | 
    
    
    163  | 
     | 
     | 
    # define TR(n, a)	if (_nc_tracing & (n)) { _tracef a ; putchar('\n'); } | 
    
    
    164  | 
     | 
     | 
     | 
    
    
    165  | 
     | 
     | 
    extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing;  | 
    
    
    166  | 
     | 
     | 
     | 
    
    
    167  | 
     | 
     | 
    #else /* no debug */  | 
    
    
    168  | 
     | 
     | 
     | 
    
    
    169  | 
     | 
     | 
    /* OLDNUM(n) indicates which line will be shifted to the position n.  | 
    
    
    170  | 
     | 
     | 
       if OLDNUM(n) == _NEWINDEX, then the line n in new, not shifted from  | 
    
    
    171  | 
     | 
     | 
       somewhere. */  | 
    
    
    172  | 
     | 
     | 
    NCURSES_EXPORT_VAR(int *)  | 
    
    
    173  | 
     | 
     | 
    _nc_oldnums = 0;		/* obsolete: keep for ABI compat */  | 
    
    
    174  | 
     | 
     | 
     | 
    
    
    175  | 
     | 
     | 
    # if USE_HASHMAP  | 
    
    
    176  | 
     | 
     | 
    #  define oldnums       SP->_oldnum_list  | 
    
    
    177  | 
     | 
     | 
    #  define OLDNUM(n)	oldnums[n]  | 
    
    
    178  | 
     | 
     | 
    # else				/* !USE_HASHMAP */  | 
    
    
    179  | 
     | 
     | 
    #  define OLDNUM(n)	newscr->_line[n].oldindex  | 
    
    
    180  | 
     | 
     | 
    # endif				/* !USE_HASHMAP */  | 
    
    
    181  | 
     | 
     | 
     | 
    
    
    182  | 
     | 
     | 
    #define OLDNUM_SIZE     SP->_oldnum_size  | 
    
    
    183  | 
     | 
     | 
     | 
    
    
    184  | 
     | 
     | 
    #endif /* defined(SCROLLDEBUG) || defined(HASHDEBUG) */  | 
    
    
    185  | 
     | 
     | 
     | 
    
    
    186  | 
     | 
     | 
    NCURSES_EXPORT(void)  | 
    
    
    187  | 
     | 
     | 
    _nc_scroll_optimize(void)  | 
    
    
    188  | 
     | 
     | 
    /* scroll optimization to transform curscr to newscr */  | 
    
    
    189  | 
     | 
     | 
    { | 
    
    
    190  | 
     | 
     | 
        int i;  | 
    
    
    191  | 
     | 
     | 
        int start, end, shift;  | 
    
    
    192  | 
     | 
     | 
     | 
    
    
    193  | 
     | 
     | 
        TR(TRACE_ICALLS, (T_CALLED("_nc_scroll_optimize"))); | 
    
    
    194  | 
     | 
     | 
     | 
    
    
    195  | 
     | 
     | 
    #if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)  | 
    
    
    196  | 
     | 
     | 
    #if USE_HASHMAP  | 
    
    
    197  | 
     | 
     | 
        /* get enough storage */  | 
    
    
    198  | 
     | 
     | 
        if (OLDNUM_SIZE < screen_lines) { | 
    
    
    199  | 
     | 
     | 
    	int *new_oldnums = typeRealloc(int, screen_lines, oldnums);  | 
    
    
    200  | 
     | 
     | 
    	if (!new_oldnums)  | 
    
    
    201  | 
     | 
     | 
    	    return;  | 
    
    
    202  | 
     | 
     | 
    	oldnums = new_oldnums;  | 
    
    
    203  | 
     | 
     | 
    	OLDNUM_SIZE = screen_lines;  | 
    
    
    204  | 
     | 
     | 
        }  | 
    
    
    205  | 
     | 
     | 
        /* calculate the indices */  | 
    
    
    206  | 
     | 
     | 
        _nc_hash_map();  | 
    
    
    207  | 
     | 
     | 
    #endif  | 
    
    
    208  | 
     | 
     | 
    #endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */  | 
    
    
    209  | 
     | 
     | 
     | 
    
    
    210  | 
     | 
     | 
    #ifdef TRACE  | 
    
    
    211  | 
     | 
     | 
        if (USE_TRACEF(TRACE_UPDATE | TRACE_MOVE)) { | 
    
    
    212  | 
     | 
     | 
    	_nc_linedump();  | 
    
    
    213  | 
     | 
     | 
    	_nc_unlock_global(tracef);  | 
    
    
    214  | 
     | 
     | 
        }  | 
    
    
    215  | 
     | 
     | 
    #endif /* TRACE */  | 
    
    
    216  | 
     | 
     | 
     | 
    
    
    217  | 
     | 
     | 
        /* pass 1 - from top to bottom scrolling up */  | 
    
    
    218  | 
     | 
     | 
        for (i = 0; i < screen_lines;) { | 
    
    
    219  | 
     | 
     | 
    	while (i < screen_lines && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) <= i))  | 
    
    
    220  | 
     | 
     | 
    	    i++;  | 
    
    
    221  | 
     | 
     | 
    	if (i >= screen_lines)  | 
    
    
    222  | 
     | 
     | 
    	    break;  | 
    
    
    223  | 
     | 
     | 
     | 
    
    
    224  | 
     | 
     | 
    	shift = OLDNUM(i) - i;	/* shift > 0 */  | 
    
    
    225  | 
     | 
     | 
    	start = i;  | 
    
    
    226  | 
     | 
     | 
     | 
    
    
    227  | 
     | 
     | 
    	i++;  | 
    
    
    228  | 
     | 
     | 
    	while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i  | 
    
    
    229  | 
     | 
     | 
    	       == shift)  | 
    
    
    230  | 
     | 
     | 
    	    i++;  | 
    
    
    231  | 
     | 
     | 
    	end = i - 1 + shift;  | 
    
    
    232  | 
     | 
     | 
     | 
    
    
    233  | 
     | 
     | 
    	TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift)); | 
    
    
    234  | 
     | 
     | 
    #if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)  | 
    
    
    235  | 
     | 
     | 
    	if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) { | 
    
    
    236  | 
     | 
     | 
    	    TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll")); | 
    
    
    237  | 
     | 
     | 
    	    continue;  | 
    
    
    238  | 
     | 
     | 
    	}  | 
    
    
    239  | 
     | 
     | 
    #endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */  | 
    
    
    240  | 
     | 
     | 
        }  | 
    
    
    241  | 
     | 
     | 
     | 
    
    
    242  | 
     | 
     | 
        /* pass 2 - from bottom to top scrolling down */  | 
    
    
    243  | 
     | 
     | 
        for (i = screen_lines - 1; i >= 0;) { | 
    
    
    244  | 
     | 
     | 
    	while (i >= 0 && (OLDNUM(i) == _NEWINDEX || OLDNUM(i) >= i))  | 
    
    
    245  | 
     | 
     | 
    	    i--;  | 
    
    
    246  | 
     | 
     | 
    	if (i < 0)  | 
    
    
    247  | 
     | 
     | 
    	    break;  | 
    
    
    248  | 
     | 
     | 
     | 
    
    
    249  | 
     | 
     | 
    	shift = OLDNUM(i) - i;	/* shift < 0 */  | 
    
    
    250  | 
     | 
     | 
    	end = i;  | 
    
    
    251  | 
     | 
     | 
     | 
    
    
    252  | 
     | 
     | 
    	i--;  | 
    
    
    253  | 
     | 
     | 
    	while (i >= 0 && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i == shift)  | 
    
    
    254  | 
     | 
     | 
    	    i--;  | 
    
    
    255  | 
     | 
     | 
    	start = i + 1 - (-shift);  | 
    
    
    256  | 
     | 
     | 
     | 
    
    
    257  | 
     | 
     | 
    	TR(TRACE_UPDATE | TRACE_MOVE, ("scroll [%d, %d] by %d", start, end, shift)); | 
    
    
    258  | 
     | 
     | 
    #if !defined(SCROLLDEBUG) && !defined(HASHDEBUG)  | 
    
    
    259  | 
     | 
     | 
    	if (_nc_scrolln(shift, start, end, screen_lines - 1) == ERR) { | 
    
    
    260  | 
     | 
     | 
    	    TR(TRACE_UPDATE | TRACE_MOVE, ("unable to scroll")); | 
    
    
    261  | 
     | 
     | 
    	    continue;  | 
    
    
    262  | 
     | 
     | 
    	}  | 
    
    
    263  | 
     | 
     | 
    #endif /* !defined(SCROLLDEBUG) && !defined(HASHDEBUG) */  | 
    
    
    264  | 
     | 
     | 
        }  | 
    
    
    265  | 
     | 
     | 
        TR(TRACE_ICALLS, (T_RETURN(""))); | 
    
    
    266  | 
     | 
     | 
    }  | 
    
    
    267  | 
     | 
     | 
     | 
    
    
    268  | 
     | 
     | 
    #if defined(TRACE) || defined(SCROLLDEBUG) || defined(HASHDEBUG)  | 
    
    
    269  | 
     | 
     | 
    NCURSES_EXPORT(void)  | 
    
    
    270  | 
     | 
     | 
    _nc_linedump(void)  | 
    
    
    271  | 
     | 
     | 
    /* dump the state of the real and virtual oldnum fields */  | 
    
    
    272  | 
     | 
     | 
    { | 
    
    
    273  | 
     | 
     | 
        int n;  | 
    
    
    274  | 
     | 
     | 
        char *buf = 0;  | 
    
    
    275  | 
     | 
     | 
        size_t want = (screen_lines + 1) * 4;  | 
    
    
    276  | 
     | 
     | 
     | 
    
    
    277  | 
     | 
     | 
        if ((buf = typeMalloc(char, want)) != 0) { | 
    
    
    278  | 
     | 
     | 
     | 
    
    
    279  | 
     | 
     | 
    	(void) strlcpy(buf, "virt", want);  | 
    
    
    280  | 
     | 
     | 
    	for (n = 0; n < screen_lines; n++)  | 
    
    
    281  | 
     | 
     | 
    		(void) snprintf(buf + strlen(buf), want - strlen(buf), " %02d", OLDNUM(n));  | 
    
    
    282  | 
     | 
     | 
    	TR(TRACE_UPDATE | TRACE_MOVE, (buf));  | 
    
    
    283  | 
     | 
     | 
    	free(buf);  | 
    
    
    284  | 
     | 
     | 
        }  | 
    
    
    285  | 
     | 
     | 
    }  | 
    
    
    286  | 
     | 
     | 
    #endif /* defined(TRACE) || defined(SCROLLDEBUG) */  | 
    
    
    287  | 
     | 
     | 
     | 
    
    
    288  | 
     | 
     | 
    #ifdef SCROLLDEBUG  | 
    
    
    289  | 
     | 
     | 
     | 
    
    
    290  | 
     | 
     | 
    int  | 
    
    
    291  | 
     | 
     | 
    main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)  | 
    
    
    292  | 
     | 
     | 
    { | 
    
    
    293  | 
     | 
     | 
        char line[BUFSIZ], *st, *last;  | 
    
    
    294  | 
     | 
     | 
     | 
    
    
    295  | 
     | 
     | 
    #ifdef TRACE  | 
    
    
    296  | 
     | 
     | 
        _nc_tracing = TRACE_MOVE;  | 
    
    
    297  | 
     | 
     | 
    #endif  | 
    
    
    298  | 
     | 
     | 
        for (;;) { | 
    
    
    299  | 
     | 
     | 
    	int n;  | 
    
    
    300  | 
     | 
     | 
     | 
    
    
    301  | 
     | 
     | 
    	for (n = 0; n < screen_lines; n++)  | 
    
    
    302  | 
     | 
     | 
    	    oldnums[n] = _NEWINDEX;  | 
    
    
    303  | 
     | 
     | 
     | 
    
    
    304  | 
     | 
     | 
    	/* grab the test vector */  | 
    
    
    305  | 
     | 
     | 
    	if (fgets(line, sizeof(line), stdin) == (char *) NULL)  | 
    
    
    306  | 
     | 
     | 
    	    exit(EXIT_SUCCESS);  | 
    
    
    307  | 
     | 
     | 
     | 
    
    
    308  | 
     | 
     | 
    	/* parse it */  | 
    
    
    309  | 
     | 
     | 
    	n = 0;  | 
    
    
    310  | 
     | 
     | 
    	if (line[0] == '#') { | 
    
    
    311  | 
     | 
     | 
    	    (void) fputs(line, stderr);  | 
    
    
    312  | 
     | 
     | 
    	    continue;  | 
    
    
    313  | 
     | 
     | 
    	}  | 
    
    
    314  | 
     | 
     | 
    	st = strtok_r(line, " ", &last);  | 
    
    
    315  | 
     | 
     | 
    	do { | 
    
    
    316  | 
     | 
     | 
    	    oldnums[n++] = atoi(st);  | 
    
    
    317  | 
     | 
     | 
    	} while  | 
    
    
    318  | 
     | 
     | 
    	    ((st = strtok_r((char *) NULL, " ", &last)) != 0);  | 
    
    
    319  | 
     | 
     | 
     | 
    
    
    320  | 
     | 
     | 
    	/* display it */  | 
    
    
    321  | 
     | 
     | 
    	(void) fputs("Initial input:\n", stderr); | 
    
    
    322  | 
     | 
     | 
    	_nc_linedump();  | 
    
    
    323  | 
     | 
     | 
     | 
    
    
    324  | 
     | 
     | 
    	_nc_scroll_optimize();  | 
    
    
    325  | 
     | 
     | 
        }  | 
    
    
    326  | 
     | 
     | 
    }  | 
    
    
    327  | 
     | 
     | 
     | 
    
    
    328  | 
     | 
     | 
    #endif /* SCROLLDEBUG */  | 
    
    
    329  | 
     | 
     | 
     | 
    
    
    330  | 
     | 
     | 
    /* hardscroll.c ends here */  |