diff options
author | ache <ache@FreeBSD.org> | 1994-10-07 08:58:58 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1994-10-07 08:58:58 +0000 |
commit | a80c0624fbd8bd1c784b0b5b7a0fd20b09d317b9 (patch) | |
tree | 4a94ca97fb2fc2fdc1fcdd522a66e39c6e763138 /lib/libncurses/lib_scroll.c | |
download | FreeBSD-src-a80c0624fbd8bd1c784b0b5b7a0fd20b09d317b9.zip FreeBSD-src-a80c0624fbd8bd1c784b0b5b7a0fd20b09d317b9.tar.gz |
Moved from ports with several enhancements
Diffstat (limited to 'lib/libncurses/lib_scroll.c')
-rw-r--r-- | lib/libncurses/lib_scroll.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/libncurses/lib_scroll.c b/lib/libncurses/lib_scroll.c new file mode 100644 index 0000000..a1f2a09 --- /dev/null +++ b/lib/libncurses/lib_scroll.c @@ -0,0 +1,120 @@ + +/* This work is copyrighted. See COPYRIGHT.OLD & COPYRIGHT.NEW for * +* details. If they are missing then this copy is in violation of * +* the copyright conditions. */ + +/* +** lib_scroll.c +** +** The routine wscrl(win, n). +** positive n scroll the window up (ie. move lines down) +** negative n scroll the window down (ie. move lines up) +** +*/ + +#include <stdlib.h> +#include "curses.priv.h" +#include <nterm.h> + +int +wscrl(WINDOW *win, int n) +{ +int line, i; +chtype *ptr, *temp; +chtype **saved; +chtype blank = ' '; + + T(("wscrl(%x,%d) called", win, n)); + + if (! win->_scroll) + return ERR; + + if (n == 0) + return OK; + + /* test for scrolling region == entire screen */ + + saved = (chtype **)malloc(sizeof(chtype *) * abs(n)); + + if (n < 0) { + /* save overwritten lines */ + + for (i = 0; i < -n; i++) + saved[i] = win->_line[win->_regbottom-i]; + + /* shift n lines */ + + for (line = win->_regbottom; line > win->_regtop+n; line--) + win->_line[line] = win->_line[line+n]; + + /* restore saved lines and blank them */ + + for (i = 0, line = win->_regtop; line < win->_regtop-n; line++, i++) { + win->_line[line] = saved[i]; + temp = win->_line[line]; + for (ptr = temp; ptr - temp <= win->_maxx; ptr++) + *ptr = blank; + } + } + + if (n > 0) { + /* save overwritten lines */ + + for (i = 0; i < n; i++) + saved[i] = win->_line[win->_regtop+i]; + + /* shift n lines */ + + for (line = win->_regtop; line < win->_regbottom; line++) + win->_line[line] = win->_line[line+n]; + + /* restore saved lines and blank them */ + + for (i = 0, line = win->_regbottom; line > win->_regbottom - n; line--, i++) { + win->_line[line] = saved[i]; + temp = win->_line[line]; + for (ptr = temp; ptr - temp <= win->_maxx; ptr++) + *ptr = blank; + } + } + + free(saved); + + /* as an optimization, if the scrolling region is the entire screen + scroll the physical screen */ + /* should we extend this to include smaller scrolling ranges by using + change_scroll_region? */ + + if (win->_maxx == columns && win->_regtop == 0 && win->_regbottom == lines) { + + /* at the moment this relies on scroll_reverse and scroll_forward + or parm_rindex and parm_index. + we should add idl support as an alternative */ + + if (n > 0) { + mvcur(-1, -1, win->_regtop, 0); + if (parm_rindex) { + putp(tparm(parm_rindex, n)); + } else if (scroll_reverse) { + while (n--) + putp(scroll_reverse); + } + } + + if (n < 0) { + mvcur(-1, -1, win->_regbottom, columns); + n = abs(n); + if (parm_index) { + putp(tparm(parm_index, n)); + } else if (scroll_forward) { + while (n--) + putp(scroll_forward); + } + } + + mvcur(-1, -1, win->_cury, win->_curx); + } else + touchline(win, win->_regtop, win->_regbottom - win->_regtop + 1); + + return OK; +} |