Bring in some of my scroll-optimisation stuff from the old Mac port.
authorben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 23 Nov 2002 13:07:29 +0000 (13:07 +0000)
committerben <ben@cda61777-01e9-0310-a592-d414129be87e>
Sat, 23 Nov 2002 13:07:29 +0000 (13:07 +0000)
This introduces a new front-end function, do_scroll(), which is expected to
scroll a part of the physical display and cause repaint events for any
areas that couldn't be scrolled (e.g. because they were hidden).
scroll_display() is a wrapper around this which also updates disptext to
match.

Currently, scroll_display is only used in response to user scrollback requests
(via term_scroll()), but extending scroll() to use it as well should be
easy.

All of this is conditional on the front end's defining OPTIMISE_SCROLL, since
only the Mac front end currently implements do_scroll().

git-svn-id: svn://svn.tartarus.org/sgt/putty@2242 cda61777-01e9-0310-a592-d414129be87e

mac/macstuff.h
putty.h
terminal.c

index e8a8fac..cc3aabe 100644 (file)
@@ -23,6 +23,8 @@ typedef void *Context; /* FIXME */
 #define WCHAR wchar_t
 #define BYTE unsigned char
 
+#define OPTIMISE_SCROLL
+
 /* To make it compile */
 
 #include <stdarg.h>
diff --git a/putty.h b/putty.h
index af9c13e..5809ccc 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -405,6 +405,9 @@ void request_resize(void *frontend, int, int);
 void do_text(Context, int, int, char *, int, unsigned long, int);
 void do_cursor(Context, int, int, char *, int, unsigned long, int);
 int char_width(Context ctx, int uc);
+#ifdef OPTIMISE_SCROLL
+void do_scroll(void *, int, int, int);
+#endif
 void set_title(void *frontend, char *);
 void set_icon(void *frontend, char *);
 void set_sbar(void *frontend, int, int, int);
index 37c75d7..410d8bb 100644 (file)
@@ -68,6 +68,9 @@ static void swap_screen(Terminal *, int, int, int);
 static void update_sbar(Terminal *);
 static void deselect(Terminal *);
 static void term_print_finish(Terminal *);
+#ifdef OPTIMISE_SCROLL
+static void scroll_display(Terminal *, int, int, int);
+#endif /* OPTIMISE_SCROLL */
 
 /*
  * Resize a line to make it `cols' columns wide.
@@ -703,6 +706,32 @@ static void scroll(Terminal *term, int topline, int botline, int lines, int sb)
     }
 }
 
+#ifdef OPTIMISE_SCROLL
+/*
+ * Scroll the physical display, and our conception of it in disptext.
+ */
+static void scroll_display(Terminal *term, int topline, int botline, int lines)
+{
+    unsigned long *start, *end;
+    int distance, size, i;
+
+    start = term->disptext + topline * (term->cols + 1);
+    end = term->disptext + (botline + 1) * (term->cols + 1);
+    distance = (lines > 0 ? lines : -lines) * (term->cols + 1);
+    size = end - start - distance;
+    if (lines > 0) {
+       memmove(start, start + distance, size * TSIZE);
+       for (i = 0; i < distance; i++)
+           (start + size)[i] |= ATTR_INVALID;
+    } else {
+       memmove(start + distance, start, size * TSIZE);
+       for (i = 0; i < distance; i++)
+           start[i] |= ATTR_INVALID;
+    }
+    do_scroll(term->frontend, topline, botline, lines);
+}
+#endif /* OPTIMISE_SCROLL */
+
 /*
  * Move the cursor to a given position, clipping at boundaries. We
  * may or may not want to clip at the scroll margin: marg_clip is 0
@@ -3143,6 +3172,10 @@ void term_paint(Terminal *term, Context ctx,
 void term_scroll(Terminal *term, int rel, int where)
 {
     int sbtop = -count234(term->scrollback);
+#ifdef OPTIMISE_SCROLL
+    int olddisptop = term->disptop;
+    int shift;
+#endif /* OPTIMISE_SCROLL */
 
     term->disptop = (rel < 0 ? 0 : rel > 0 ? sbtop : term->disptop) + where;
     if (term->disptop < sbtop)
@@ -3150,6 +3183,11 @@ void term_scroll(Terminal *term, int rel, int where)
     if (term->disptop > 0)
        term->disptop = 0;
     update_sbar(term);
+#ifdef OPTIMISE_SCROLL
+    shift = (term->disptop - olddisptop);
+    if (shift < term->rows && shift > -term->rows)
+       scroll_display(term, 0, term->rows - 1, shift);
+#endif /* OPTIMISE_SCROLL */
     term_update(term);
 }