diff options
author | ache <ache@FreeBSD.org> | 1998-01-02 04:36:51 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1998-01-02 04:36:51 +0000 |
commit | 533db3b201ab193b971a34bcef090d11bb0f4d15 (patch) | |
tree | 26b32e41615afb10ff19f8aaa642de47134ce56a /lib/libncurses/lib_scroll.c | |
parent | 8a719f4f6a5228ee1a499af703c7b6cdfa493c59 (diff) | |
download | FreeBSD-src-533db3b201ab193b971a34bcef090d11bb0f4d15.zip FreeBSD-src-533db3b201ab193b971a34bcef090d11bb0f4d15.tar.gz |
1) Redo internal interface to be more latest ncurses-like
2) Fix winsdel called in last line of the window (nothing happens in
old variant)
3) Add range checks to wscrl() and internal soft scroll function
Diffstat (limited to 'lib/libncurses/lib_scroll.c')
-rw-r--r-- | lib/libncurses/lib_scroll.c | 118 |
1 files changed, 73 insertions, 45 deletions
diff --git a/lib/libncurses/lib_scroll.c b/lib/libncurses/lib_scroll.c index 03e7136..5dd55d6 100644 --- a/lib/libncurses/lib_scroll.c +++ b/lib/libncurses/lib_scroll.c @@ -16,30 +16,30 @@ #include "curses.priv.h" #include "terminfo.h" -void scroll_window(WINDOW *win, int n, int regtop, int regbottom) +void _nc_soft_scroll_window(WINDOW *win, int const n, short const top, short const bottom, chtype blank) { int line, i; chtype *ptr, *temp; chtype **saved; -chtype blank = _nc_background(win); - saved = (chtype **)malloc(sizeof(chtype *) * abs(n)); + saved = (chtype **)calloc(abs(n), sizeof(chtype *)); if (n < 0) { /* save overwritten lines */ - for (i = 0; i < -n; i++) - saved[i] = win->_line[regbottom-i]; + for (i = 0; i < -n && bottom-i >= 0; i++) + saved[i] = win->_line[bottom-i]; /* shift n lines */ - for (line = regbottom; line >= regtop-n; line--) + for (line = bottom; line >= top-n && line >= 0; line--) win->_line[line] = win->_line[line+n]; /* restore saved lines and blank them */ - for (i = 0, line = regtop; line < regtop-n; line++, i++) { - win->_line[line] = saved[i]; + for (i = 0, line = top; line < top-n && line <= win->_maxy; line++, i++) { + if (saved[i]) + win->_line[line] = saved[i]; temp = win->_line[line]; for (ptr = temp; ptr - temp <= win->_maxx; ptr++) *ptr = blank; @@ -47,47 +47,56 @@ chtype blank = _nc_background(win); } else { /* save overwritten lines */ - for (i = 0; i < n; i++) - saved[i] = win->_line[regtop+i]; + for (i = 0; i < n && top+i <= win->_maxy; i++) + saved[i] = win->_line[top+i]; /* shift n lines */ - for (line = regtop; line <= regbottom-n; line++) + for (line = top; line <= bottom-n && line+n <= win->_maxy; line++) win->_line[line] = win->_line[line+n]; /* restore saved lines and blank them */ - for (i = 0, line = regbottom; line > regbottom - n; line--, i++) { - win->_line[line] = saved[i]; + for (i = 0, line = bottom; line > bottom - n && line >= 0; line--, i++) { + if (saved[i]) + win->_line[line] = saved[i]; temp = win->_line[line]; for (ptr = temp; ptr - temp <= win->_maxx; ptr++) *ptr = blank; } } - + /* touchline(win, top, bottom-top+1); */ /* not yet */ free(saved); } -int -wscrl(WINDOW *win, int n) +void _nc_scroll_window(WINDOW *win, int n, short const top, short const bottom, chtype blank) { int physical = FALSE; int i; - T(("wscrl(%x,%d) called", win, n)); + if (top == bottom) { + int sy, sx; - if (! win->_scroll) - return ERR; + getyx(win, sy, sx); + win->_curx = 0; + win->_cury = top; + wclrtoeol(win); + win->_curx = sx; + win->_cury = sy; + return; + } - if (n == 0) - return OK; + if (n > lines) + n = lines; + else if (-n > lines) + n = -lines; /* as an optimization, if the scrolling region is the entire screen scroll the physical screen */ if ( win->_begx == 0 && win->_maxx == columns - 1 && !memory_above && !memory_below - && ((((win->_begy+win->_regtop == 0 && win->_begy+win->_regbottom == lines - 1) + && ((((win->_begy+top == 0 && win->_begy+bottom == lines - 1) || change_scroll_region) && ( (n < 0 && (parm_rindex || scroll_reverse)) || (n > 0 && (parm_index || scroll_forward)) @@ -97,28 +106,28 @@ int i; ) ) ) - physical = TRUE; + physical = TRUE; if (physical == TRUE) { wrefresh(win); - scroll_window(curscr, n, win->_begy+win->_regtop, win->_begy+win->_regbottom); - scroll_window(newscr, n, win->_begy+win->_regtop, win->_begy+win->_regbottom); + _nc_soft_scroll_window(curscr, n, win->_begy+top, win->_begy+bottom, blank); + _nc_soft_scroll_window(newscr, n, win->_begy+top, win->_begy+bottom, blank); } - scroll_window(win, n, win->_regtop, win->_regbottom); + _nc_soft_scroll_window(win, n, top, bottom, blank); if (physical == TRUE) { if (n < 0) { - if ( (( win->_begy+win->_regtop == 0 - && win->_begy+win->_regbottom == lines - 1) + if ( (( win->_begy+top == 0 + && win->_begy+bottom == lines - 1) || change_scroll_region) && (parm_rindex || scroll_reverse) ) { if (change_scroll_region && - (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) + (win->_begy+top != 0 || win->_begy+bottom != lines - 1) ) - putp(tparm(change_scroll_region, win->_begy+win->_regtop, win->_begy+win->_regbottom)); + putp(tparm(change_scroll_region, win->_begy+top, win->_begy+bottom)); i = abs(n); - mvcur(-1, -1, win->_begy+win->_regtop, 0); + mvcur(-1, -1, win->_begy+top, 0); if (parm_rindex) { putp(tparm(parm_rindex, i)); } else if (scroll_reverse) { @@ -126,13 +135,13 @@ int i; putp(scroll_reverse); } if (change_scroll_region && - (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) + (win->_begy+top != 0 || win->_begy+bottom != lines - 1) ) putp(tparm(change_scroll_region, 0, lines-1)); } else { i = abs(n); - if (win->_begy+win->_regbottom < lines - 1) { - mvcur(-1, -1, win->_begy+win->_regbottom, 0); + if (win->_begy+bottom < lines - 1) { + mvcur(-1, -1, win->_begy+bottom, 0); if (parm_delete_line) { putp(tparm(parm_delete_line, i)); } else if (delete_line) { @@ -141,7 +150,7 @@ int i; i = abs(n); } } - mvcur(-1, -1, win->_begy+win->_regtop, 0); + mvcur(-1, -1, win->_begy+top, 0); if (parm_insert_line) { putp(tparm(parm_insert_line, i)); } else if (insert_line) { @@ -150,16 +159,16 @@ int i; } } } else { - if ( (( win->_begy+win->_regtop == 0 - && win->_begy+win->_regbottom == lines - 1) + if ( (( win->_begy+top == 0 + && win->_begy+bottom == lines - 1) || change_scroll_region) && (parm_index || scroll_forward) ) { if (change_scroll_region && - (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) + (win->_begy+top != 0 || win->_begy+bottom != lines - 1) ) - putp(tparm(change_scroll_region, win->_begy+win->_regtop, win->_begy+win->_regbottom)); - mvcur(-1, -1, win->_begy+win->_regbottom, 0); + putp(tparm(change_scroll_region, win->_begy+top, win->_begy+bottom)); + mvcur(-1, -1, win->_begy+bottom, 0); if (parm_index) { putp(tparm(parm_index, n)); } else if (scroll_forward) { @@ -168,11 +177,11 @@ int i; putp(scroll_forward); } if (change_scroll_region && - (win->_begy+win->_regtop != 0 || win->_begy+win->_regbottom != lines - 1) + (win->_begy+top != 0 || win->_begy+bottom != lines - 1) ) putp(tparm(change_scroll_region, 0, lines-1)); } else { - mvcur(-1, -1, win->_begy+win->_regtop, 0); + mvcur(-1, -1, win->_begy+top, 0); if (parm_delete_line) { putp(tparm(parm_delete_line, n)); } else if (delete_line) { @@ -180,8 +189,8 @@ int i; while (i--) putp(delete_line); } - if (win->_begy+win->_regbottom < lines - 1) { - mvcur(win->_begy+win->_regtop, 0, win->_begy+win->_regbottom, 0); + if (win->_begy+bottom < lines - 1) { + mvcur(win->_begy+top, 0, win->_begy+bottom, 0); if (parm_insert_line) { putp(tparm(parm_insert_line, n)); } else if (insert_line) { @@ -195,7 +204,26 @@ int i; mvcur(-1, -1, win->_begy+win->_cury, win->_begx+win->_curx); } else - touchline(win, win->_regtop, win->_regbottom - win->_regtop + 1); + touchline(win, top, bottom - top + 1); +} + + +int +wscrl(WINDOW *win, int n) +{ + T(("wscrl(%x,%d) called", win, n)); + + if (!win || !win->_scroll) + return ERR; + + if (n == 0) + return OK; + + if ((n > (win->_regbottom - win->_regtop)) || + (-n > (win->_regbottom - win->_regtop))) + return ERR; + + _nc_scroll_window(win, n, win->_regtop, win->_regbottom, _nc_background(win)); return OK; } |