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 | |
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
-rw-r--r-- | lib/libncurses/curses.priv.h | 1 | ||||
-rw-r--r-- | lib/libncurses/lib_insdel.c | 36 | ||||
-rw-r--r-- | lib/libncurses/lib_scroll.c | 118 |
3 files changed, 82 insertions, 73 deletions
diff --git a/lib/libncurses/curses.priv.h b/lib/libncurses/curses.priv.h index 85f54b7..73e3d7d 100644 --- a/lib/libncurses/curses.priv.h +++ b/lib/libncurses/curses.priv.h @@ -64,6 +64,7 @@ extern WINDOW *makenew(int, int, int, int); extern int timed_wait(int fd, int wait, int *timeleft); extern chtype _nc_background(WINDOW *); extern chtype _nc_render(WINDOW *, chtype); +extern void _nc_scroll_window(WINDOW *, int, short const, short const, chtype); struct try { struct try *child; /* ptr to child. NULL if none */ diff --git a/lib/libncurses/lib_insdel.c b/lib/libncurses/lib_insdel.c index eb30f20..8729efe 100644 --- a/lib/libncurses/lib_insdel.c +++ b/lib/libncurses/lib_insdel.c @@ -12,40 +12,20 @@ ** */ -#include <stdlib.h> #include "curses.priv.h" -#include "terminfo.h" int winsdelln(WINDOW *win, int n) { - int ret, sscroll, stop, sbot; +int code = ERR; T(("winsdel(%x,%d) called", win, n)); - if (n == 0) - return OK; - if (win->_cury == win->_maxy && abs(n) == 1) - return wclrtoeol(win); - if (n < 0 && win->_cury - n > win->_maxy) - /* request to delete too many lines */ - /* should we truncate to an appropriate number? */ - return ERR; - - sscroll = win->_scroll; - stop = win->_regtop; - sbot = win->_regbottom; - - win->_scroll = TRUE; - win->_regtop = win->_cury; - if (win->_regtop > win->_regbottom) - win->_regbottom = win->_maxy; - - ret = wscrl(win, -n); - - win->_scroll = sscroll; - win->_regtop = stop; - win->_regbottom = sbot; - - return ret; + if (win) { + if (n != 0) { + _nc_scroll_window(win, -n, win->_cury, win->_maxy, _nc_background(win)); + } + code = OK; + } + return code; } 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; } |