--- 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]) {