summaryrefslogtreecommitdiffstats
path: root/lib/libncurses/lib_scroll.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1998-01-02 04:36:51 +0000
committerache <ache@FreeBSD.org>1998-01-02 04:36:51 +0000
commit533db3b201ab193b971a34bcef090d11bb0f4d15 (patch)
tree26b32e41615afb10ff19f8aaa642de47134ce56a /lib/libncurses/lib_scroll.c
parent8a719f4f6a5228ee1a499af703c7b6cdfa493c59 (diff)
downloadFreeBSD-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.c118
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;
}
OpenPOWER on IntegriCloud