ncurses 4.1
[ncurses.git] / ncurses / lib_scroll.c
1
2 /***************************************************************************
3 *                            COPYRIGHT NOTICE                              *
4 ****************************************************************************
5 *                ncurses is copyright (C) 1992-1995                        *
6 *                          Zeyd M. Ben-Halim                               *
7 *                          zmbenhal@netcom.com                             *
8 *                          Eric S. Raymond                                 *
9 *                          esr@snark.thyrsus.com                           *
10 *                                                                          *
11 *        Permission is hereby granted to reproduce and distribute ncurses  *
12 *        by any means and for any fee, whether alone or as part of a       *
13 *        larger distribution, in source or in binary form, PROVIDED        *
14 *        this notice is included with any such distribution, and is not    *
15 *        removed from any of its header files. Mention of ncurses in any   *
16 *        applications linked with it is highly appreciated.                *
17 *                                                                          *
18 *        ncurses comes AS IS with no warranty, implied or expressed.       *
19 *                                                                          *
20 ***************************************************************************/
21
22
23
24 /*
25 **      lib_scroll.c
26 **
27 **      The routine wscrl(win, n).
28 **  positive n scroll the window up (ie. move lines down)
29 **  negative n scroll the window down (ie. move lines up)
30 **
31 */
32
33 #include <curses.priv.h>
34
35 MODULE_ID("$Id: lib_scroll.c,v 1.11 1997/02/01 23:22:54 tom Exp $")
36
37 void _nc_scroll_window(WINDOW *win, int const n, short const top, short const bottom)
38 {
39 int     line, j;
40 chtype  blank = _nc_background(win);
41 size_t  to_copy = (size_t)(sizeof(chtype) * (win->_maxx + 1));
42
43         TR(TRACE_MOVE, ("_nc_scroll_window(%p, %d, %d, %d)", win, n, top,bottom)); 
44
45         /*
46          * This used to do a line-text pointer-shuffle instead of text copies.
47          * That (a) doesn't work when the window is derived and doesn't have
48          * its own storage, (b) doesn't save you a lot on modern machines
49          * anyway.  Your typical memcpy implementations are coded in
50          * assembler using a tight BLT loop; for the size of copies we're
51          * talking here, the total execution time is dominated by the one-time
52          * setup cost.  So there is no point in trying to be excessively
53          * clever -- esr.
54          */
55
56         /* shift n lines downwards */
57         if (n < 0) {
58                 for (line = bottom; line >= top-n; line--) {
59                         memcpy(win->_line[line].text,
60                                win->_line[line+n].text,
61                                to_copy);
62                         win->_line[line].oldindex = win->_line[line+n].oldindex;
63                 }
64                 for (line = top; line < top-n; line++) {
65                         for (j = 0; j <= win->_maxx; j ++)
66                                 win->_line[line].text[j] = blank;
67                         win->_line[line].oldindex = _NEWINDEX;
68                         win->_line[line].firstchar = 0;
69                         win->_line[line].lastchar = win->_maxx;
70                 }
71         }
72
73         /* shift n lines upwards */
74         if (n > 0) {
75                 for (line = top; line <= bottom-n; line++) {
76                         memcpy(win->_line[line].text,
77                                win->_line[line+n].text,
78                                to_copy);
79                         win->_line[line].oldindex = win->_line[line+n].oldindex;
80                 }
81                 for (line = bottom; line > bottom-n; line--) {
82                         for (j = 0; j <= win->_maxx; j ++)
83                                 win->_line[line].text[j] = blank;
84                         win->_line[line].oldindex = _NEWINDEX;
85                         win->_line[line].firstchar = 0;
86                         win->_line[line].lastchar = win->_maxx;
87                 }
88         }
89 }
90
91 int
92 wscrl(WINDOW *win, int n)
93 {
94         T((T_CALLED("wscrl(%p,%d)"), win, n));
95
96         if (! win->_scroll)
97                 returnCode(ERR);
98
99         if (n == 0)
100                 returnCode(OK);
101
102         if ((n > (win->_regbottom - win->_regtop)) || 
103             (-n > (win->_regbottom - win->_regtop)))
104             returnCode(ERR);
105
106         _nc_scroll_window(win, n, win->_regtop, win->_regbottom);
107         touchline(win, win->_regtop, (int)(win->_regbottom - win->_regtop + 1));
108
109         _nc_synchook(win);
110         returnCode(OK);
111 }