diff options
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 03e71368f734..5dd55d673455 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;  }  | 
