aboutsummaryrefslogtreecommitdiffstats
path: root/src/ansi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansi.c')
-rw-r--r--src/ansi.c207
1 files changed, 173 insertions, 34 deletions
diff --git a/src/ansi.c b/src/ansi.c
index 12a0563..7f44957 100644
--- a/src/ansi.c
+++ b/src/ansi.c
@@ -10,6 +10,9 @@ static char rcsid[] = "$Id$";
/*
* $Log$
+ * Revision 1.19 2008/02/13 16:57:29 james
+ * *** empty log message ***
+ *
* Revision 1.18 2008/02/13 09:12:21 james
* *** empty log message ***
*
@@ -316,7 +319,7 @@ ansi_cls (ANSI * a)
crt_cls (&a->crt);
- ansi_force_attr_normal (a);
+ ansi_set_attr (a, CRT_ATTR_NORMAL);
ansi_set_color (a, CRT_COLOR_NORMAL);
ansi_move (a, p);
a->terminal->xmit (a->terminal, "\033[2J", 4);
@@ -410,67 +413,173 @@ ansi_spot_scroll (ANSI * a, CRT * c)
void
-ansi_draw (ANSI * a, CRT * c)
+ansi_draw_line (ANSI * a, CRT_CA * cap, int y)
{
- CRT_Pos p;
- int o;
- int hidden_cursor = 0;
+ CRT_Pos p = { 0, y };
+ CRT_CA *acap = &a->crt.screen[CRT_ADDR_POS (&p)];
- if (crt_pos_cmp (a->terminal->size, a->size))
+ for (p.x = 0; p.x < CRT_COLS; ++p.x)
{
- terminal_getsize (a->terminal);
+ if (p.x >= a->size.x)
+ continue;
- a->size = a->terminal->size;
+ if (crt_ca_cmp (*acap, *cap))
+ {
+ ansi_showhide_cursor (a, 1);
+ *acap = *cap;
- a->pos.x = ANSI_INVAL;
- a->hide_cursor = ANSI_INVAL;
+ ansi_move (a, p);
+ ansi_render (a, *acap);
+ }
- crt_reset (&a->crt);
+ 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);
+ 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;
+
+}
+
+
+
+
+void
+ansi_draw (ANSI * a, CRT * c)
+{
+ CRT_Pos p;
+ int o;
+ int hidden_cursor = 0;
+
+ ansi_resize_check (a);
+
for (p.y = 0; p.y < CRT_ROWS; ++p.y)
{
if (p.y >= a->size.y)
continue;
- o = CRT_ADDR (p.y, 0);
- for (p.x = 0; p.x < CRT_COLS; ++p.x, ++o)
- {
- if (p.x >= a->size.x)
- continue;
- if (crt_ca_cmp (a->crt.screen[o], c->screen[o]))
- {
- ansi_showhide_cursor (a, 1);
- a->crt.screen[o] = c->screen[o];
- ansi_move (a, p);
- ansi_render (a, a->crt.screen[o]);
- }
- }
+ ansi_draw_line (a, &c->screen[CRT_ADDR (p.y, 0)], p.y);
+
}
if ((CRT_COLS > a->size.x) || (CRT_ROWS > a->size.y))
{
- char msg[] = "Window is too small";
+ char msg[1024]; // = "Window is too small";
+ int i;
p.x = 0;
p.y = 0;
+ i =
+ sprintf (msg, "Window too small (%dx%d need %dx%d)", a->size.x,
+ a->size.y, CRT_COLS, CRT_ROWS);
+
ansi_showhide_cursor (a, 1);
ansi_set_attr (a, CRT_ATTR_REVERSE);
ansi_set_color (a, CRT_MAKE_COLOR (CRT_COLOR_WHITE, CRT_COLOR_RED));
ansi_move (a, p);
- a->terminal->xmit (a->terminal, msg, sizeof (msg));
+ a->terminal->xmit (a->terminal, msg, i);
a->pos.x = ANSI_INVAL;
}
@@ -489,10 +598,19 @@ ansi_draw (ANSI * a, CRT * c)
}
void
-ansi_reset (ANSI * a)
+ansi_reset (ANSI * a, CRT * c)
{
a->size.x = -1;
- ansi_draw (a, &a->crt);
+ ansi_draw (a, c ? c : &a->crt);
+}
+
+void
+ansi_terminal_reset (ANSI * a)
+{
+ CRT_Pos p = { 0, CRT_ROWS };
+ ansi_force_attr_normal (a);
+
+ ansi_move (a, p);
}
void
@@ -682,6 +800,10 @@ ansi_dispatch (ANSI * a, Context * c)
ansi_check_escape (a, c);
+
+ if (!a->terminal)
+ return;
+
red = a->terminal->recv (a->terminal, buf, sizeof (buf));
if (red <= 0)
return red;
@@ -691,9 +813,18 @@ ansi_dispatch (ANSI * a, Context * c)
return -1;
#endif
-#if 0
+#if 1
if (*buf == 1)
- return 1;
+ {
+ ansi_reset (a, NULL);
+ return 0;
+ }
+ if (*buf == 2)
+ {
+ a->history_ptr = c->h->wptr;
+ HISTORY_INC (c->h, a->history_ptr);
+ return 0;
+ }
#endif
@@ -701,3 +832,11 @@ ansi_dispatch (ANSI * a, Context * c)
return 0;
}
+
+
+void
+ansi_update (ANSI * a, Context * c)
+{
+ ansi_history (a, c->h);
+ ansi_draw (a, &c->v->crt);
+}