summaryrefslogtreecommitdiffstats
path: root/lib/libncurses/lib_scroll.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libncurses/lib_scroll.c')
-rw-r--r--lib/libncurses/lib_scroll.c218
1 files changed, 218 insertions, 0 deletions
diff --git a/lib/libncurses/lib_scroll.c b/lib/libncurses/lib_scroll.c
new file mode 100644
index 0000000..3a60836
--- /dev/null
+++ b/lib/libncurses/lib_scroll.c
@@ -0,0 +1,218 @@
+
+/* 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 "terminfo.h"
+
+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;
+
+ saved = (chtype **)calloc(abs(n), sizeof(chtype *));
+
+ if (n < 0) {
+ /* save overwritten lines */
+
+ for (i = 0; i < -n && bottom-i >= 0; i++)
+ saved[i] = win->_line[bottom-i];
+
+ /* shift n lines */
+
+ 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 = 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;
+ }
+ } else {
+ /* save overwritten lines */
+
+ for (i = 0; i < n && top+i <= win->_maxy; i++)
+ saved[i] = win->_line[top+i];
+
+ /* shift n lines */
+
+ 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 = 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);
+}
+
+void _nc_scroll_window(WINDOW *win, int n, short const top, short const bottom, chtype blank)
+{
+int physical = FALSE;
+int i;
+
+ 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 ( top != bottom
+ && win->_begx == 0 && win->_maxx == columns - 1
+ && !memory_above && !memory_below
+ && ((((win->_begy+top == 0 && win->_begy+bottom == lines - 1)
+ || change_scroll_region)
+ && ( (n < 0 && (parm_rindex || scroll_reverse))
+ || (n > 0 && (parm_index || scroll_forward))
+ )
+ ) || (win->_idlok && (parm_insert_line || insert_line)
+ && (parm_delete_line || delete_line)
+ )
+ )
+ )
+ physical = TRUE;
+
+ if (physical == TRUE) {
+ wrefresh(win);
+ _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);
+ }
+ _nc_soft_scroll_window(win, n, top, bottom, blank);
+
+ if (physical == TRUE) {
+ if (n < 0) {
+ if ( (( win->_begy+top == 0
+ && win->_begy+bottom == lines - 1)
+ || change_scroll_region)
+ && (parm_rindex || scroll_reverse)
+ ) {
+ if (change_scroll_region &&
+ (win->_begy+top != 0 || win->_begy+bottom != lines - 1)
+ )
+ putp(tparm(change_scroll_region, win->_begy+top, win->_begy+bottom));
+ i = abs(n);
+ mvcur(-1, -1, win->_begy+top, 0);
+ if (parm_rindex) {
+ putp(tparm(parm_rindex, i));
+ } else if (scroll_reverse) {
+ while (i--)
+ putp(scroll_reverse);
+ }
+ if (change_scroll_region &&
+ (win->_begy+top != 0 || win->_begy+bottom != lines - 1)
+ )
+ putp(tparm(change_scroll_region, 0, lines-1));
+ } else {
+ i = abs(n);
+ 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) {
+ while (i--)
+ putp(delete_line);
+ i = abs(n);
+ }
+ }
+ mvcur(-1, -1, win->_begy+top, 0);
+ if (parm_insert_line) {
+ putp(tparm(parm_insert_line, i));
+ } else if (insert_line) {
+ while (i--)
+ putp(insert_line);
+ }
+ }
+ } else {
+ if ( (( win->_begy+top == 0
+ && win->_begy+bottom == lines - 1)
+ || change_scroll_region)
+ && (parm_index || scroll_forward)
+ ) {
+ if (change_scroll_region &&
+ (win->_begy+top != 0 || win->_begy+bottom != lines - 1)
+ )
+ 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) {
+ i = n;
+ while (i--)
+ putp(scroll_forward);
+ }
+ if (change_scroll_region &&
+ (win->_begy+top != 0 || win->_begy+bottom != lines - 1)
+ )
+ putp(tparm(change_scroll_region, 0, lines-1));
+ } else {
+ mvcur(-1, -1, win->_begy+top, 0);
+ if (parm_delete_line) {
+ putp(tparm(parm_delete_line, n));
+ } else if (delete_line) {
+ i = n;
+ while (i--)
+ putp(delete_line);
+ }
+ 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) {
+ i = n;
+ while (i--)
+ putp(insert_line);
+ }
+ }
+ }
+ }
+
+ mvcur(-1, -1, win->_begy+win->_cury, win->_begx+win->_curx);
+ } else
+ 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