chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / ansi.c
index f70a2d55e844c7a890579f7babad27e7f5a920fa..d575f62ae2b0c5e73848d0d297a90e3954aa3876 100644 (file)
@@ -10,6 +10,9 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.15  2008/02/07 13:19:48  james
+ * *** empty log message ***
+ *
  * Revision 1.14  2008/02/07 12:21:16  james
  * *** empty log message ***
  *
@@ -347,7 +350,7 @@ ansi_render (ANSI * a, CRT_CA ca)
 /*Can't easily wrap round here as don't know size of destination screen*/
 /*so invalidate the cached cursor position*/
 
-  if (a->pos.x >= CRT_COLS)
+  if (a->pos.x >= a->size.x)
     a->pos.x = ANSI_INVAL;
 
 }
@@ -367,6 +370,77 @@ ansi_cls (ANSI * a)
   a->pos.x = ANSI_INVAL;
 }
 
+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);
+ansi_write(a,buf,i);
+i=sprintf(buf,"\033[%d;%dH",e.y+1,0);
+ansi_write(a,buf,i);
+ansi_write (a, "\033D",2);
+ansi_write(a,"\033[r", 3);
+
+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;
+}
+
+
+
 
 void
 ansi_draw (ANSI * a, CRT * c)
@@ -375,6 +449,8 @@ ansi_draw (ANSI * a, CRT * c)
   int o;
   int hidden_cursor = 0;
 
+  ansi_spot_scroll(a,c);
+
   for (p.y = 0; p.y < CRT_ROWS; ++p.y)
     {
       if (p.y >= a->size.y)
@@ -439,6 +515,8 @@ ansi_reset (ANSI * a)
 
   ansi_cls (a);
   ansi_write (a, "\033=", 2);
+  ansi_write (a, "\033[?6l", 5);
+  ansi_write (a, "\033[r", 3);
   ansi_draw (a, &a->crt);
 }