+#if 0
+int
+ansi_scroll_up (ANSI * a, CRT_Pos s, CRT_Pos e)
+{
+ char buf[16];
+ int i;
+ if (s.x)
+ return -1;
+ if (e.x != (CRT_COLS - 1))
+ return -1;
+ if (s.y)
+ return -1;
+ if (s.y >= a->size.y)
+ return -1;
+
+ ansi_showhide_cursor (a, 1);
+ i = sprintf (buf, "\033[%d;%dr", s.y + 1, e.y + 1);
+ a->terminal->xmit (a->terminal, buf, i);
+ i = sprintf (buf, "\033[%d;%dH", e.y + 1, 0);
+ a->terminal->xmit (a->terminal, buf, i);
+ a->terminal->xmit (a->terminal, "\033D", 2);
+ a->terminal->xmit (a->terminal, "\033[r", 3);
+
+ s.y = e.y;
+ crt_erase (&a->crt, s, e, 1);
+
+ a->pos.x = ANSI_INVAL;
+
+ return 0;
+}
+
+
+void
+ansi_spot_scroll_up (ANSI * a, CRT * c)
+{
+ int l, n, p;
+
+ l = c->sh.e.x - c->sh.s.x;
+ l++;
+ l *= sizeof (CRT_CA);
+
+ n = c->sh.e.y - c->sh.s.y;
+ p = CRT_ADDR_POS (&c->sh.s);
+
+ while (n--)
+ {
+ if (memcmp (&c->screen[p], &a->crt.screen[p + CRT_COLS], l))
+ return;
+ p += CRT_COLS;
+ }
+
+ if (ansi_scroll_up (a, c->sh.s, c->sh.e))
+ return;
+
+ n = c->sh.e.y - c->sh.s.y;
+ p = CRT_ADDR_POS (&c->sh.s);
+
+ while (n--)
+ {
+ memcpy (&a->crt.screen[p], &a->crt.screen[p + CRT_COLS], l);
+ p += CRT_COLS;
+ }
+
+ c->sh.dir = 0; //FIXME: horrid hack
+
+}
+
+void
+ansi_spot_scroll (ANSI * a, CRT * c)
+{
+
+ switch (c->sh.dir)
+ {
+ case -1:
+/*we only care about up for the moment */
+ ansi_spot_scroll_up (a, c);
+ break;
+ }
+
+ return;
+}
+
+#endif
+
+
+void
+ansi_draw_line (ANSI * a, CRT_CA * cap, int y)
+{
+ CRT_Pos p = { 0, y };
+ CRT_CA *acap = &a->crt.screen[CRT_ADDR_POS (&p)];
+
+ for (p.x = 0; p.x < CRT_COLS; ++p.x)
+ {
+ if (p.x >= a->size.x)
+ continue;
+
+ if (crt_ca_cmp (*acap, *cap))
+ {
+ ansi_showhide_cursor (a, 1);
+ *acap = *cap;
+
+ ansi_move (a, p);
+ ansi_render (a, *acap);
+ }
+
+ acap++;
+ cap++;
+ }
+}
+
+void
+ansi_resize_check (ANSI * a)
+{
+
+ if (!crt_pos_cmp (a->terminal->size, a->size))
+ return;
+
+ terminal_getsize (a->terminal);
+
+ a->size = a->terminal->size;
+
+ a->pos.x = ANSI_INVAL;
+ a->hide_cursor = ANSI_INVAL;
+
+ crt_reset (&a->crt);
+
+// FIXME: -- echos back crap?
+// a->terminal->xmit (a->terminal, "\033[c", 3);
+
+ ansi_cls (a);
+ a->terminal->xmit (a->terminal, "\033=", 2);
+ a->terminal->xmit (a->terminal, "\033[?6l", 5);
+ a->terminal->xmit (a->terminal, "\033[r", 3);
+
+}
+
+#define HISTORY_GUESS_SCROLL 24 /*guess all 24 lines usually scroll */
+/*if they haven't then ansi_draw will patch it up*/
+
+void
+ansi_history (ANSI * a, History * h)
+{
+ char buf[32];
+ int i;
+/*Do we need to catch up on history?*/
+
+ if (a->history_ptr == h->wptr)
+ return;
+ ansi_resize_check (a);
+
+ if ((a->size.x < CRT_COLS) || (a->size.y < CRT_ROWS))
+ return;
+
+ ansi_force_attr_normal (a);
+ ansi_set_color (a, CRT_COLOR_NORMAL);
+
+ i = sprintf (buf, "\033[%d;%dr", 1, HISTORY_GUESS_SCROLL);
+ a->terminal->xmit (a->terminal, buf, i);
+
+
+ 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 */
+ ansi_draw_line (a, e->line, 0);
+
+
+ /*Roll HISTORY_GUESS_SCROLL lines up putting the top line into the xterm's history */
+
+
+ ansi_showhide_cursor (a, 1);
+ i = sprintf (buf, "\033[%d;%dH", HISTORY_GUESS_SCROLL, 1);
+ a->terminal->xmit (a->terminal, buf, i);
+ a->terminal->xmit (a->terminal, "\033D", 2);
+ 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 < HISTORY_GUESS_SCROLL; s.y++, e.y++)
+ {
+ memcpy (&a->crt.screen[CRT_ADDR_POS (&e)],
+ &a->crt.screen[CRT_ADDR_POS (&s)],
+ sizeof (CRT_CA) * CRT_COLS);
+ }
+
+ /* erase new line */
+ s.y = e.y;
+ e.x = CRT_COLS - 1;
+ crt_erase (&a->crt, s, e, 1);
+ }
+
+ }
+/*reset margins*/
+ a->terminal->xmit (a->terminal, "\033[r", 3);
+ a->pos.x = ANSI_INVAL;
+
+}
+
+
+