150276Speter/**************************************************************************** 2262685Sdelphij * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 30166124Srafan * Author: Thomas E. Dickey 1996-2003 * 3197049Speter * and: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 3250276Speter * and: Eric S. Raymond <esr@snark.thyrsus.com> * 3350276Speter ****************************************************************************/ 3450276Speter 3550276Speter/* 3650276Speter** lib_scroll.c 3750276Speter** 3850276Speter** The routine wscrl(win, n). 3950276Speter** positive n scroll the window up (ie. move lines down) 4050276Speter** negative n scroll the window down (ie. move lines up) 4150276Speter** 4250276Speter*/ 4350276Speter 4450276Speter#include <curses.priv.h> 4550276Speter 46262685SdelphijMODULE_ID("$Id: lib_scroll.c,v 1.29 2011/10/22 16:34:50 tom Exp $") 4750276Speter 4876726SpeterNCURSES_EXPORT(void) 49166124Srafan_nc_scroll_window(WINDOW *win, 50166124Srafan int const n, 51262685Sdelphij int const top, 52262685Sdelphij int const bottom, 53166124Srafan NCURSES_CH_T blank) 5450276Speter{ 5597049Speter int limit; 5697049Speter int line; 5797049Speter int j; 58262629Sdelphij size_t to_copy = (sizeof(NCURSES_CH_T) * (size_t) (win->_maxx + 1)); 5950276Speter 60166124Srafan TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %ld, %ld)", 61262629Sdelphij (void *) win, n, (long) top, (long) bottom)); 6250276Speter 6397049Speter if (top < 0 6497049Speter || bottom < top 6597049Speter || bottom > win->_maxy) { 6697049Speter TR(TRACE_MOVE, ("nothing to scroll")); 6797049Speter return; 6897049Speter } 6997049Speter 7062449Speter /* 7162449Speter * This used to do a line-text pointer-shuffle instead of text copies. 7262449Speter * That (a) doesn't work when the window is derived and doesn't have 7362449Speter * its own storage, (b) doesn't save you a lot on modern machines 7462449Speter * anyway. Your typical memcpy implementations are coded in 7562449Speter * assembler using a tight BLT loop; for the size of copies we're 7662449Speter * talking here, the total execution time is dominated by the one-time 7762449Speter * setup cost. So there is no point in trying to be excessively 7862449Speter * clever -- esr. 7962449Speter */ 8050276Speter 8162449Speter /* shift n lines downwards */ 8262449Speter if (n < 0) { 8397049Speter limit = top - n; 84166124Srafan for (line = bottom; line >= limit && line >= 0; line--) { 85166124Srafan TR(TRACE_MOVE, ("...copying %d to %d", line + n, line)); 86166124Srafan memcpy(win->_line[line].text, 87166124Srafan win->_line[line + n].text, 88166124Srafan to_copy); 89166124Srafan if_USE_SCROLL_HINTS(win->_line[line].oldindex = 90166124Srafan win->_line[line + n].oldindex); 9162449Speter } 92166124Srafan for (line = top; line < limit && line <= win->_maxy; line++) { 9397049Speter TR(TRACE_MOVE, ("...filling %d", line)); 9462449Speter for (j = 0; j <= win->_maxx; j++) 9562449Speter win->_line[line].text[j] = blank; 9662449Speter if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 9762449Speter } 9862449Speter } 9950276Speter 10062449Speter /* shift n lines upwards */ 10162449Speter if (n > 0) { 10297049Speter limit = bottom - n; 103166124Srafan for (line = top; line <= limit && line <= win->_maxy; line++) { 104166124Srafan memcpy(win->_line[line].text, 105166124Srafan win->_line[line + n].text, 106166124Srafan to_copy); 107166124Srafan if_USE_SCROLL_HINTS(win->_line[line].oldindex = 108166124Srafan win->_line[line + n].oldindex); 10950276Speter } 110166124Srafan for (line = bottom; line > limit && line >= 0; line--) { 11162449Speter for (j = 0; j <= win->_maxx; j++) 11262449Speter win->_line[line].text[j] = blank; 11362449Speter if_USE_SCROLL_HINTS(win->_line[line].oldindex = _NEWINDEX); 11462449Speter } 11562449Speter } 11662449Speter touchline(win, top, bottom - top + 1); 117166124Srafan 118166124Srafan if_WIDEC({ 119166124Srafan if (WINDOW_EXT(win, addch_used) != 0) { 120166124Srafan int next = WINDOW_EXT(win, addch_y) + n; 121166124Srafan if (next < 0 || next > win->_maxy) { 122166124Srafan TR(TRACE_VIRTPUT, 123166124Srafan ("Alert discarded multibyte on scroll")); 124166124Srafan WINDOW_EXT(win, addch_y) = 0; 125166124Srafan } else { 126166124Srafan TR(TRACE_VIRTPUT, ("scrolled working position to %d,%d", 127166124Srafan WINDOW_EXT(win, addch_y), 128166124Srafan WINDOW_EXT(win, addch_x))); 129166124Srafan WINDOW_EXT(win, addch_y) = next; 130166124Srafan } 131166124Srafan } 132166124Srafan }) 13350276Speter} 13450276Speter 13576726SpeterNCURSES_EXPORT(int) 13650276Speterwscrl(WINDOW *win, int n) 13750276Speter{ 138262629Sdelphij T((T_CALLED("wscrl(%p,%d)"), (void *) win, n)); 13950276Speter 14097049Speter if (!win || !win->_scroll) { 14197049Speter TR(TRACE_MOVE, ("...scrollok is false")); 14262449Speter returnCode(ERR); 14397049Speter } 14450276Speter 145166124Srafan if (n != 0) { 146166124Srafan _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd); 147166124Srafan _nc_synchook(win); 148166124Srafan } 14962449Speter returnCode(OK); 15050276Speter} 151