+ err += ansi_set_attr (a, CRT_ATTR_NORMAL);
+ err += ansi_set_color (a, CRT_COLOR_NORMAL);
+ err += ansi_move (a, p);
+ if (a->terminal->xmit (a->terminal, "\033[2J", 4) != 4)
+ err++;
+ /* different emulators leave cursor in different places after cls
+ differently */
+ a->pos.x = ANSI_INVAL;
+
+ return err;
+}
+
+static int
+ansi_draw_line (ANSI * a, CRT_CA * cap, int y)
+{
+ int err = 0;
+
+ CRT_Pos p = { 0, y };
+ CRT_CA *acap = &a->crt.screen[CRT_ADDR_POS (&p)];
+
+ for (p.x = 0; p.x < a->crt.size.x; ++p.x) {
+ if (p.x >= a->size.x)
+ continue;
+
+ if (crt_ca_cmp (*acap, *cap)) {
+ err += ansi_showhide_cursor (a, 1);
+
+ *acap = *cap;
+
+ err += ansi_move (a, p);
+ err += ansi_render (a, *acap);
+ }
+
+ acap++;
+ cap++;
+ }
+
+ return err;
+}
+
+static int
+ansi_resize_check (ANSI * a, CRT_Pos * size)
+{
+ int err = 0;
+
+ if ((size && crt_pos_cmp (a->crt.size, *size))
+ || crt_pos_cmp (a->terminal->size, a->size)) {
+
+ terminal_getsize (a->terminal);
+
+ a->size = a->terminal->size;
+
+ a->pos.x = ANSI_INVAL;
+ a->hide_cursor = ANSI_INVAL;
+
+ crt_reset (&a->crt);
+
+ if (size)
+ a->crt.size = *size;
+
+ // a->terminal->xmit (a->terminal, "\033c", 3);
+ // maybe - issue 132 column command if we're 132?
+
+ ansi_cls (a);
+ if (a->terminal->xmit (a->terminal, "\033=", 2) != 2)
+ err++;
+ if (a->terminal->xmit (a->terminal, "\033[?6l", 5) != 5)
+ err++;
+ if (a->terminal->xmit (a->terminal, "\033[r", 3) != 3)
+ err++;
+ if (a->utf8) {
+ if (a->terminal->xmit (a->terminal, "\033%G", 3) != 3)
+ err++;
+ } else {
+ if (a->terminal->xmit (a->terminal, "\033(B", 3) != 3)
+ err++;
+ if (a->terminal->xmit (a->terminal, "\033)0", 3) != 3)
+ err++;
+ if (a->terminal->xmit (a->terminal, "\017", 1) != 3)
+ err++;
+ }
+
+ }
+ return err;
+}
+
+
+static int
+ansi_history (ANSI * a, History * h)
+{
+ char buf[32];
+ int i;
+ int guess_scroll;
+ int err = 0;
+ /* Do we need to catch up on history? */
+
+ if (a->history_ptr == h->wptr)
+ return err;
+
+ err += ansi_resize_check (a, NULL);
+
+ if ((a->size.x < a->crt.size.x) || (a->size.y < a->crt.size.y))
+ return err;
+
+ guess_scroll = a->crt.size.y - 1; /* Bototm line should be a status line */
+
+
+ err += ansi_force_attr_normal (a);
+ err += ansi_set_color (a, CRT_COLOR_NORMAL);
+
+ i = sprintf (buf, "\033[%d;%dr", 1, guess_scroll);
+ if (a->terminal->xmit (a->terminal, buf, i) != i)
+ err++;
+
+
+ while (a->history_ptr != h->wptr) {
+
+ History_ent *e = &h->lines[a->history_ptr];
+
+ HISTORY_INC (h, a->history_ptr);
+
+ if (!e->valid)
+ continue;
+
+ /* If so write the line ot the top of the screen */
+ err += ansi_draw_line (a, e->line, 0);
+
+
+ /* Roll guess_scroll lines up putting the top line into the xterm's
+ history */
+
+
+ /* Make extra lines a predictable colour */
+ err += ansi_set_color (a, CRT_COLOR_NORMAL);
+
+ err += ansi_showhide_cursor (a, 1);
+
+ i = sprintf (buf, "\033[%d;%dH", guess_scroll, 1);
+ if (a->terminal->xmit (a->terminal, buf, i) != i)
+ err++;
+
+ if (a->terminal->xmit (a->terminal, "\033D", 2) != 2)
+ err++;
+
+ a->pos.x = ANSI_INVAL;
+
+ /* now do the same in our image of the screen */
+
+ {
+ CRT_Pos s = { 0 }
+ , e = {
+ 0};
+
+ /* scroll lines up */
+ for (s.y++; s.y < guess_scroll; s.y++, e.y++) {
+ memcpy (&a->crt.screen[CRT_ADDR_POS (&e)],
+ &a->crt.screen[CRT_ADDR_POS (&s)],
+ sizeof (CRT_CA) * a->crt.size.x);
+ }
+
+ /* erase new line */
+ s.y = e.y;
+ e.x = CRT_COLS - 1;
+ crt_erase (&a->crt, s, e, 1, CRT_COLOR_NORMAL);
+ }
+
+ }
+ /* reset margins */
+ if (a->terminal->xmit (a->terminal, "\033[r", 3) != 3)
+ err++;
+