lib_scroll.c revision 262685
1/**************************************************************************** 2 * Copyright (c) 1998-2010,2011 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-2003 * 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.29 2011/10/22 16:34:50 tom Exp $") 47 48NCURSES_EXPORT(void) 49_nc_scroll_window(WINDOW *win, 50 int const n, 51 int const top, 52 int const bottom, 53 NCURSES_CH_T blank) 54{ 55 int limit; 56 int line; 57 int j; 58 size_t to_copy = (sizeof(NCURSES_CH_T) * (size_t) (win->_maxx + 1)); 59 60 TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %ld, %ld)", 61 (void *) win, n, (long) top, (long) bottom)); 62 63 if (top < 0 64 || bottom < top 65 || bottom > win->_maxy) { 66 TR(TRACE_MOVE, ("nothing to scroll")); 67 return; 68 } 69 70 /* 71 * This used to do a line-text pointer-shuffle instead of text copies. 72 * That (a) doesn't work when the window is derived and doesn't have 73 * its own storage, (b) doesn't save you a lot on modern machines 74 * anyway. Your typical memcpy implementations are coded in 75 * assembler using a tight BLT loop; for the size of copies we're 76 * talking here, the total execution time is dominated by the one-time 77 * setup cost. So there is no point in trying to be excessively 78 * clever -- esr. 79 */ 80 81 /* shift n lines downwards */ 82 if (n < 0) { 83 limit = top - n; 84 for (line = bottom; line >= limit && line >= 0; line--) { 85 TR(TRACE_MOVE, ("...copying %d to %d", line + n, line)); 86 memcpy(win->_line[line].text, 87 win->_line[line + n].text, 88 to_copy); 89 if_USE_SCROLL_HINTS(win->_line[line].oldindex = 90 win->_line[line + n].oldindex); 91 } 92 for (line = top; line < limit && line <= win->_maxy; line++) { 93 TR(TRACE_MOVE, ("...filling %d", line)); 94 for (j = 0; j <= win->_maxx; j++) 95 win->_line[line].text[j] = blank; 96 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 97 } 98 } 99 100 /* shift n lines upwards */ 101 if (n > 0) { 102 limit = bottom - n; 103 for (line = top; line <= limit && line <= win->_maxy; line++) { 104 memcpy(win->_line[line].text, 105 win->_line[line + n].text, 106 to_copy); 107 if_USE_SCROLL_HINTS(win->_line[line].oldindex = 108 win->_line[line + n].oldindex); 109 } 110 for (line = bottom; line > limit && line >= 0; line--) { 111 for (j = 0; j <= win->_maxx; j++) 112 win->_line[line].text[j] = blank; 113 if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 114 } 115 } 116 touchline(win, top, bottom - top + 1); 117 118 if_WIDEC({ 119 if (WINDOW_EXT(win, addch_used) != 0) { 120 int next = WINDOW_EXT(win, addch_y) + n; 121 if (next < 0 || next > win->_maxy) { 122 TR(TRACE_VIRTPUT, 123 ("Alert discarded multibyte on scroll")); 124 WINDOW_EXT(win, addch_y) = 0; 125 } else { 126 TR(TRACE_VIRTPUT, ("scrolled working position to %d,%d", 127 WINDOW_EXT(win, addch_y), 128 WINDOW_EXT(win, addch_x))); 129 WINDOW_EXT(win, addch_y) = next; 130 } 131 } 132 }) 133} 134 135NCURSES_EXPORT(int) 136wscrl(WINDOW *win, int n) 137{ 138 T((T_CALLED("wscrl(%p,%d)"), (void *) 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 _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd); 147 _nc_synchook(win); 148 } 149 returnCode(OK); 150} 151