Sorry, I ran into two more issues that I fixed today. New patch is
attached.

1. I added support for set origin to relative/absolute (ESC[?6h, ESC[?6l)
2. Recognize set/clear graphmode with ESC(0, ESC(B

I also put in a clear screen at the end of the creation process. You
probably don't notice the issue if you use a black background, but I
prefer black on white terminals so this was bugging me.

Thanks! -Ross


On 12/07/2010 09:34 AM, Ross Mohn wrote:
> Hi,
>
> I’m no terminal expert, and I’m reluctant to add more code to the
> madtty.c source, but I hope these changes will be considered. They
> certainly work for me!
>
> The existing ESC ] s (CUPSV) and ESC ] u (CUPRS) are for save/restore
> cursor position. I use at least one program that uses ESC 7 (DECSC)
> and ESC 8 (DECRC) to save/restore state, both cursor position and
> character attributes, so I’ve implemented them. To do this, I created
> reusable functions for save_curs(), restore_curs(), save_attrs(), and
> restore_attrs() because they are used more than once now.
>
> I also have some programs that were displaying weird reverse video
> backgrounds, only in dvtm. To fix this I added code at the beginning
> and end of the interpret_csi_ED() ‘erase display’ function so that the
> display is always erased with A_NORMAL character attributes.
>
> Thanks! –Ross
>
--- madtty000.c 2010-10-08 12:06:05.000000000 -0400
+++ madtty.c    2010-12-07 16:26:11.000000000 -0500
@@ -101,11 +102,12 @@
      unsigned curshid    : 1;
      unsigned curskeymode: 1;
      unsigned bell       : 1;
+     unsigned relposmode : 1;
  
      /* geometry */
      int rows, cols, maxcols;
-     unsigned curattrs;
-     short curfg, curbg;
+     unsigned curattrs, scurattrs;
+     short curfg, curbg, scurfg, scurbg;
  
      /* scrollback buffer */
      struct t_row_t *scroll_buf;
@@ -246,6 +248,33 @@
      }
  }
  
+ static void save_curs(madtty_t *t)
+ {
+     t->curs_srow = t->curs_row - t->lines;
+     t->curs_scol = t->curs_col;
+ }
+ 
+ static void restore_curs(madtty_t *t)
+ {
+     t->curs_row = t->lines + t->curs_srow;
+     t->curs_col = t->curs_scol;
+     clamp_cursor_to_bounds(t);
+ }
+ 
+ static void save_attrs(madtty_t *t)
+ {
+     t->scurattrs = t->curattrs;
+     t->scurfg = t->curfg;
+     t->scurbg = t->curbg;
+ }
+ 
+ static void restore_attrs(madtty_t *t)
+ {
+     t->curattrs = t->scurattrs;
+     t->curfg = t->scurfg;
+     t->curbg = t->scurbg;
+ }
+ 
  static void fill_scroll_buf(madtty_t *t, int s)
  {
      /* work in screenfuls */
@@ -393,6 +422,10 @@
  {
      t_row_t *row, *start, *end;
  
+     save_attrs(t);
+     t->curattrs = A_NORMAL;
+     t->curfg = t->curbg = -1;
+ 
      /* decide range */
      if (pcount && param[0] == 2) {
          start = t->lines;
@@ -412,6 +445,8 @@
      for (row = start; row < end; row++) {
          t_row_set(row, 0, t->cols, t);
      }
+ 
+     restore_attrs(t);
  }
  
  /* interprets a 'move cursor' (CUP) escape sequence */
@@ -419,15 +454,17 @@
  {
      if (pcount == 0) {
          /* special case */
-         t->curs_row = t->lines;
+         t->curs_row = (t->relposmode ? t->scroll_top : t->lines);
          t->curs_col = 0;
          return;
      } else
-     if (pcount < 2) {
-         return;  /* malformed */
+     if (pcount == 1) {
+         t->curs_row = (t->relposmode ? t->scroll_top : t->lines) + param[0] - 
1;
+         t->curs_col = 0;
+         return;  /* shorthand for beginning of row param[0] ??? */
      }
  
-     t->curs_row = t->lines + param[0] - 1;
+     t->curs_row = (t->relposmode ? t->scroll_top : t->lines) + param[0] - 1;
      t->curs_col = param[1] - 1;
  
      clamp_cursor_to_bounds(t);
@@ -631,6 +668,8 @@
                  t->curshid = true;
              if (csiparam[0] == 1) /* DECCKM: reset ANSI cursor (normal) key 
mode */
                  t->curskeymode = 0;
+             if (csiparam[0] == 6) /* DECOM: set origin to absolute */
+                 t->relposmode = false;
              if (csiparam[0] == 47) {
                  /* use normal screen buffer */
                  t->curattrs = A_NORMAL;
@@ -643,6 +682,8 @@
                  t->curshid = false;
              if (csiparam[0] == 1) /* DECCKM: set ANSI cursor (application) 
key mode */
                  t->curskeymode = 1;
+             if (csiparam[0] == 6) /* DECOM: set origin to relative */
+                 t->relposmode = true;
              if (csiparam[0] == 47) {
                  /* use alternate screen buffer */
                  t->curattrs = A_NORMAL;
@@ -687,19 +728,25 @@
        case 'r': /* set scrolling region */
          interpret_csi_DECSTBM(t, csiparam, param_count); break;
        case 's': /* save cursor location */
-         t->curs_srow = t->curs_row - t->lines;
-         t->curs_scol = t->curs_col;
-         break;
+         save_curs(t); break;
        case 'u': /* restore cursor location */
-         t->curs_row = t->lines + t->curs_srow;
-         t->curs_col = t->curs_scol;
-         clamp_cursor_to_bounds(t);
-         break;
+         restore_curs(t); break;
        default:
          break;
      }
  }
  
+ static void interpret_char_set(madtty_t *t)
+ {
+     char lastchar  = t->ebuf[t->elen-1];
+ 
+     if (*t->ebuf == '(' && lastchar == '0')
+         t->graphmode = true;
+     else if (*t->ebuf == '(' && lastchar == 'B')
+         t->graphmode = false;
+     /* else ignore for now */
+ }
+ 
  static void try_interpret_escape_seq(madtty_t *t)
  {
      char lastchar  = t->ebuf[t->elen-1];
@@ -723,8 +770,12 @@
  
        case '(':
        case ')':
-         if (t->elen == 2)
-             goto cancel;
+       case '#':
+         if (t->elen == 2) {
+             interpret_char_set(t);
+             cancel_escape_sequence(t);
+             return;
+         }
          break;
  
        case ']': /* xterm thing */
@@ -742,6 +793,18 @@
              return;
          }
          break;
+ 
+       case '7': /* save cursor and attrs */
+         save_attrs(t);
+         save_curs(t);
+         cancel_escape_sequence(t);
+         return;
+ 
+       case '8': /* restore cursor and attrs */
+         restore_attrs(t);
+         restore_curs(t);
+         cancel_escape_sequence(t);
+         return;
      }
  
      if (t->elen + 1 >= (int)sizeof(t->ebuf)) {
@@ -1033,6 +1096,12 @@
      }
      t->scroll_buf_ptr = t->scroll_buf_len = 0;
      t->scroll_amount = 0;
+ 
+     /* clear the screen */
+     t_row_set(t->curs_row, t->curs_col, t->cols - t->curs_col, t);
+     for (t_row_t *row = t->curs_row + 1; row < t->lines + t->rows; row++)
+         t_row_set(row, 0, t->cols, t);
+ 
      return t;
  }
  
@@ -1224,7 +1293,7 @@
  
          maxfd = sysconf(_SC_OPEN_MAX);
          for (fd = 3; fd < maxfd; fd++)
-             if (close(fd) == EBADF)
+             if (close(fd) == -1 && errno == EBADF)
                  break;
  
          while (envp && envp[0]) {

Reply via email to