jcs
/subtext
/amendments
/36
ansi: Add VT52 support
jcs made amendment 36 over 2 years ago
--- ansi.c Wed Dec 15 14:24:54 2021
+++ ansi.c Thu Dec 23 20:57:33 2021
@@ -26,7 +26,7 @@
* We may be outputting a bunch of ansi()s in a string, so they can't all
* return the same buffer. Rotate between a few on each iteration.
*/
-static char ansi_buf[6][32];
+static char ansi_buf[10][32];
static short last_ansi_buf = 0;
char *
@@ -35,9 +35,9 @@ ansi(struct session *s, ...)
char ansi_tmp[10];
char *ansi_out;
va_list ap;
- short attr, val, len;
+ short attr, val, val2, len, n;
- if (!s->ansi)
+ if (!s->vt100 && !s->vt52)
return "";
ansi_out = (char *)&ansi_buf[last_ansi_buf];
@@ -51,71 +51,139 @@ ansi(struct session *s, ...)
len = 0;
switch (attr) {
case ANSI_RESET:
- len = strlcat(ansi_out, "\33[0m", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[0m", sizeof(ansi_buf[0]));
break;
case ANSI_BOLD:
- len = strlcat(ansi_out, "\33[1m", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[1m", sizeof(ansi_buf[0]));
break;
case ANSI_UNDERLINE:
- len = strlcat(ansi_out, "\33[4m", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[4m", sizeof(ansi_buf[0]));
break;
case ANSI_REVERSE:
- len = strlcat(ansi_out, "\33[7m", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[7m", sizeof(ansi_buf[0]));
break;
case ANSI_CLEAR_SCREEN:
- len = strlcat(ansi_out, "\33[2J", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[2J", sizeof(ansi_buf[0]));
+ else if (s->vt52)
+ /* XXX: changes cursor position */
+ len = strlcat(ansi_out, "\33H\33J", sizeof(ansi_buf[0]));
break;
-
case ANSI_ERASE_LINE:
- /* XXX: this doesn't work on windows command-line telnet */
- len = strlcat(ansi_out, "\33[2K", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ /* XXX: this doesn't work on windows command-line telnet */
+ len = strlcat(ansi_out, "\33[2K", sizeof(ansi_buf[0]));
+ else if (s->vt52)
+ /* XXX: changes cursor position */
+ len = strlcat(ansi_out, "\r\33K", sizeof(ansi_buf[0]));
break;
- case ANSI_INSERT_LINE:
- len = strlcat(ansi_out, "\33[L", sizeof(ansi_buf[0]));
- break;
- case ANSI_DELETE_LINE:
- len = strlcat(ansi_out, "\33[M", sizeof(ansi_buf[0]));
- break;
-
case ANSI_BACKSPACE:
- len = strlcat(ansi_out, "\33[D \33[D", sizeof(ansi_buf[0]));
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[D \33[D", sizeof(ansi_buf[0]));
+ else if (s->vt52)
+ len = strlcat(ansi_out, "\33D \33D", sizeof(ansi_buf[0]));
break;
- case ANSI_BACK:
- len = strlcat(ansi_out, "\33[D", sizeof(ansi_buf[0]));
- break;
- case ANSI_UP:
- len = strlcat(ansi_out, "\33[A", sizeof(ansi_buf[0]));
- break;
- case ANSI_DOWN:
- len = strlcat(ansi_out, "\33[B", sizeof(ansi_buf[0]));
- break;
/* these require N args */
+ case ANSI_UP_N:
+ if (s->vt100) {
+ sprintf(ansi_tmp, "\33[%dF", va_arg(ap, short));
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ val = va_arg(ap, short);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, "\33A", sizeof(ansi_buf[0]));
+ }
+ break;
+ case ANSI_DOWN_N:
+ if (s->vt100) {
+ sprintf(ansi_tmp, "\33[%dB", va_arg(ap, short));
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ val = va_arg(ap, short);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, "\33B", sizeof(ansi_buf[0]));
+ }
+ break;
case ANSI_BACK_N:
- sprintf(ansi_tmp, "\33[%dB", va_arg(ap, short));
- len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ if (s->vt100) {
+ sprintf(ansi_tmp, "\33[%dD", va_arg(ap, short));
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ val = va_arg(ap, short);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, "\33D", sizeof(ansi_buf[0]));
+ }
break;
- case ANSI_CURSOR_N_N:
- sprintf(ansi_tmp, "\33[%d;%dH", va_arg(ap, short),
- va_arg(ap, short));
- len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ case ANSI_INSERT_LINES_N:
+ if (s->vt100) {
+ sprintf(ansi_tmp, "\33[%dL", va_arg(ap, short));
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ val = va_arg(ap, short);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, "\33L", sizeof(ansi_buf[0]));
+ }
break;
+ case ANSI_DELETE_LINES_N:
+ if (s->vt100) {
+ sprintf(ansi_tmp, "\33[%dM", va_arg(ap, short));
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ val = va_arg(ap, short);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, "\33M", sizeof(ansi_buf[0]));
+ }
+ break;
case ANSI_COL_N:
- /* \e[xG not supported on windows telnet, fake it */
val = va_arg(ap, short);
if (val == 1)
len = strlcat(ansi_out, "\r", sizeof(ansi_buf[0]));
else {
- sprintf(ansi_tmp, "\r\33[%dC", val);
- len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ if (s->vt100) {
+ /* \e[xG not supported on windows telnet, fake it */
+ sprintf(ansi_tmp, "\r\33[%dC", val);
+ len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
+ } else if (s->vt52) {
+ /* go to beginning of line, then move right N times */
+ strlcat(ansi_out, "\r", sizeof(ansi_buf[0]));
+ sprintf(ansi_tmp, "\33C", val);
+ for (n = 0; n < val; n++)
+ len = strlcat(ansi_out, ansi_tmp,
+ sizeof(ansi_buf[0]));
+ }
}
break;
- case ANSI_ROW_N:
- sprintf(ansi_tmp, "\33[%dH", va_arg(ap, short));
+ case ANSI_CURSOR_ROW_COL:
+ val = va_arg(ap, short);
+ val2 = va_arg(ap, short);
+ if (s->vt100)
+ /* row, column */
+ sprintf(ansi_tmp, "\33[%d;%dH", val, val2);
+ else if (s->vt52)
+ /* column, row as chr(col)+31,chr(row)+31 */
+ sprintf(ansi_tmp, "\33Y%c%c", val2 + 31, val + 31);
len = strlcat(ansi_out, ansi_tmp, sizeof(ansi_buf[0]));
break;
+ case ANSI_SAVE_CURSOR:
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[s", sizeof(ansi_buf[0]));
+ else if (s->vt52)
+ len = strlcat(ansi_out, "\337", sizeof(ansi_buf[0]));
+ break;
+ case ANSI_RESTORE_SAVED_CURSOR:
+ if (s->vt100)
+ len = strlcat(ansi_out, "\33[u", sizeof(ansi_buf[0]));
+ else if (s->vt52)
+ len = strlcat(ansi_out, "\338", sizeof(ansi_buf[0]));
+ break;
+
default:
panic("ansi: Unknown ANSI attribute %d", attr);
}
--- ansi.h Wed Dec 15 14:06:45 2021
+++ ansi.h Thu Dec 23 20:57:41 2021
@@ -24,23 +24,22 @@ enum {
ANSI_REVERSE,
ANSI_CLEAR_SCREEN,
-
ANSI_ERASE_LINE,
- ANSI_INSERT_LINE,
- ANSI_DELETE_LINE,
-
ANSI_BACKSPACE,
- ANSI_BACK,
- ANSI_UP,
- ANSI_DOWN,
+ ANSI_SAVE_CURSOR,
+ ANSI_RESTORE_SAVED_CURSOR,
+
/* these require N args */
+ ANSI_UP_N,
+ ANSI_DOWN_N,
ANSI_BACK_N,
- ANSI_CURSOR_N_N,
ANSI_COL_N,
- ANSI_ROW_N,
+ ANSI_CURSOR_ROW_COL,
+ ANSI_INSERT_LINES_N,
+ ANSI_DELETE_LINES_N,
- ANSI_NULL
+ ANSI_NULL = -1
};
char *ansi(struct session *s, ...);