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