lib_scroll.c revision 97049
1/**************************************************************************** 2 * Copyright (c) 1998,2000,2001 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29/**************************************************************************** 30 * Author: Thomas E. Dickey 1996-2001 * 31 * and: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 32 * and: Eric S. Raymond <esr@snark.thyrsus.com> * 33 ****************************************************************************/ 34 35/* 36** lib_scroll.c 37** 38** The routine wscrl(win, n). 39** positive n scroll the window up (ie. move lines down) 40** negative n scroll the window down (ie. move lines up) 41** 42*/ 43 44#include <curses.priv.h> 45 46MODULE_ID("$Id: lib_scroll.c,v 1.23 2001/12/19 01:06:55 tom Exp $") 47 48NCURSES_EXPORT(void) 49_nc_scroll_window(WINDOW *win, int const n, NCURSES_SIZE_T const top, 50 NCURSES_SIZE_T const bottom, NCURSES_CH_T blank) 51{ 52 int limit; 53 int line; 54 int j; 55 size_t to_copy = (size_t) (sizeof(NCURSES_CH_T) * (win->_maxx + 1)); 56 57 TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %d, %d)", win, n, top, bottom)); 58 59 if (top < 0 60 || bottom < top 61 || bottom > win->_maxy) { 62 TR(TRACE_MOVE, ("nothing to scroll")); 63 return; 64 } 65 66 /* 67 * This used to do a line-text pointer-shuffle instead of text copies. 68 * That (a) doesn't work when the window is derived and doesn't have 69 * its own storage, (b) doesn't save you a lot on modern machines 70 * anyway. Your typical memcpy implementations are coded in 71 * assembler using a tight BLT loop; for the size of copies we're 72 * talking here, the total execution time is dominated by the one-time 73 * setup cost. So there is no point in trying to be excessively 74 * clever -- esr. 75 */ 76 77 /* shift n lines downwards */ 78 if (n < 0) { 79 limit = top - n; 80 if (limit > win->_maxy) 81 limit = win->_maxy; 82 for (line = bottom; line >= limit; line--) { 83 if (line + n >= 0) { 84 TR(TRACE_MOVE, ("...copying %d to %d", line + n, line)); 85 memcpy(win->_line[line].text, 86 win->_line[line + n].text, 87 to_copy); 88 if_USE_SCROLL_HINTS(win->_line[line].oldindex = 89 win->_line[line + n].oldindex); 90 } else { 91 TR(TRACE_MOVE, ("...filling %d", line)); 92 for (j = 0; j <= win->_maxx; j++) 93 win->_line[line].text[j] = blank; 94 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 95 } 96 } 97 for (line = top; line < limit; line++) { 98 TR(TRACE_MOVE, ("...filling %d", line)); 99 for (j = 0; j <= win->_maxx; j++) 100 win->_line[line].text[j] = blank; 101 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 102 } 103 } 104 105 /* shift n lines upwards */ 106 if (n > 0) { 107 limit = bottom - n; 108 if (limit < 0) 109 limit = 0; 110 for (line = top; line <= limit; line++) { 111 if (line + n <= win->_maxy) { 112 TR(TRACE_MOVE, ("...copying %d to %d", line + n, line)); 113 memcpy(win->_line[line].text, 114 win->_line[line + n].text, 115 to_copy); 116 if_USE_SCROLL_HINTS(win->_line[line].oldindex = 117 win->_line[line + n].oldindex); 118 } else { 119 TR(TRACE_MOVE, ("...filling %d", line)); 120 for (j = 0; j <= win->_maxx; j++) 121 win->_line[line].text[j] = blank; 122 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 123 } 124 } 125 for (line = bottom; line > limit; line--) { 126 TR(TRACE_MOVE, ("...filling %d", line)); 127 for (j = 0; j <= win->_maxx; j++) 128 win->_line[line].text[j] = blank; 129 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 130 } 131 } 132 touchline(win, top, bottom - top + 1); 133} 134 135NCURSES_EXPORT(int) 136wscrl(WINDOW *win, int n) 137{ 138 T((T_CALLED("wscrl(%p,%d)"), win, n)); 139 140 if (!win || !win->_scroll) { 141 TR(TRACE_MOVE, ("...scrollok is false")); 142 returnCode(ERR); 143 } 144 145 if (n == 0) 146 returnCode(OK); 147 148 _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd); 149 150 _nc_synchook(win); 151 returnCode(OK); 152} 153