Improve support for non-colour displays by adding a mask of attributes to
[u/mdw/putty] / terminal.c
index 8b48a3c..5950072 100644 (file)
@@ -336,6 +336,7 @@ Terminal *term_init(Config *mycfg, void *frontend)
     term->nbeeps = 0;
     term->lastbeep = FALSE;
     term->beep_overloaded = FALSE;
+    term->attr_mask = 0xffffffff;
     term->resize_fn = NULL;
     term->resize_ctx = NULL;
 
@@ -592,11 +593,13 @@ static void check_selection(Terminal *term, pos from, pos to)
 static void scroll(Terminal *term, int topline, int botline, int lines, int sb)
 {
     unsigned long *line, *line2;
-    int i, seltop;
+    int i, seltop, olddisptop, shift;
 
     if (topline != 0 || term->alt_which != 0)
        sb = FALSE;
 
+    olddisptop = term->disptop;
+    shift = lines;
     if (lines < 0) {
        while (lines < 0) {
            line = delpos234(term->screen, botline);
@@ -705,6 +708,11 @@ static void scroll(Terminal *term, int topline, int botline, int lines, int sb)
            lines--;
        }
     }
+#ifdef OPTIMISE_SCROLL
+    shift += term->disptop - olddisptop;
+    if (shift < term->rows && shift > -term->rows && shift != 0)
+       scroll_display(term, topline, botline, shift);
+#endif /* OPTIMISE_SCROLL */
 }
 
 #ifdef OPTIMISE_SCROLL
@@ -722,10 +730,15 @@ static void scroll_display(Terminal *term, int topline, int botline, int lines)
     size = end - start - distance;
     if (lines > 0) {
        memmove(start, start + distance, size * TSIZE);
+       if (term->dispcurs >= start + distance &&
+           term->dispcurs <= start + distance + size)
+           term->dispcurs -= distance;
        for (i = 0; i < distance; i++)
            (start + size)[i] |= ATTR_INVALID;
     } else {
        memmove(start + distance, start, size * TSIZE);
+       if (term->dispcurs >= start && term->dispcurs <= start + size)
+           term->dispcurs += distance;
        for (i = 0; i < distance; i++)
            start[i] |= ATTR_INVALID;
     }
@@ -3027,7 +3040,8 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
            if ((term->disptext[idx] ^ tattr) & ATTR_WIDE)
                dirty_line = TRUE;
 
-           break_run = (tattr != attr || j - start >= sizeof(ch));
+           break_run = (((tattr ^ attr) & term->attr_mask) ||
+               j - start >= sizeof(ch));
 
            /* Special hack for VT100 Linedraw glyphs */
            if ((attr & CSET_MASK) == 0x2300 && tchar >= 0xBA