TERM set to xterm by default (which broke a lot of stuff), better escape handling (title), and a little clean up.
parent
f2dff29a16
commit
0981437524
395
st.c
395
st.c
|
@ -20,11 +20,12 @@
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
#define TNAME "st"
|
#define TNAME "xterm"
|
||||||
|
|
||||||
/* Arbitrary sizes */
|
/* Arbitrary sizes */
|
||||||
|
#define TITLESIZ 256
|
||||||
#define ESCSIZ 256
|
#define ESCSIZ 256
|
||||||
#define ESCARG 16
|
#define ESCARGSIZ 16
|
||||||
#define MAXDRAWBUF 1024
|
#define MAXDRAWBUF 1024
|
||||||
|
|
||||||
#define SERRNO strerror(errno)
|
#define SERRNO strerror(errno)
|
||||||
|
@ -40,7 +41,8 @@
|
||||||
enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 };
|
enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 };
|
||||||
enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload };
|
enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload };
|
||||||
enum { CRset=1, CRupdate=2 };
|
enum { CRset=1, CRupdate=2 };
|
||||||
enum { TMwrap=1, TMinsert=2 };
|
enum { TMwrap=1, TMinsert=2, TMtitle=4 };
|
||||||
|
enum { ESCin = 1, ESCcsi = 2, ESCosc = 4, ESCtitle = 8 };
|
||||||
enum { SCupdate, SCredraw };
|
enum { SCupdate, SCredraw };
|
||||||
|
|
||||||
typedef int Color;
|
typedef int Color;
|
||||||
|
@ -62,17 +64,16 @@ typedef struct {
|
||||||
int y;
|
int y;
|
||||||
} TCursor;
|
} TCursor;
|
||||||
|
|
||||||
/* Escape sequence structs */
|
/* CSI Escape sequence structs */
|
||||||
/* ESC <pre> [[ [<priv>] <arg> [;]] <mode>] */
|
/* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char buf[ESCSIZ+1]; /* raw string */
|
char buf[ESCSIZ]; /* raw string */
|
||||||
int len; /* raw string length */
|
int len; /* raw string length */
|
||||||
char pre;
|
|
||||||
char priv;
|
char priv;
|
||||||
int arg[ESCARG+1];
|
int arg[ESCARGSIZ];
|
||||||
int narg; /* nb of args */
|
int narg; /* nb of args */
|
||||||
char mode;
|
char mode;
|
||||||
} Escseq;
|
} CSIEscape;
|
||||||
|
|
||||||
/* Internal representation of the screen */
|
/* Internal representation of the screen */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -83,6 +84,9 @@ typedef struct {
|
||||||
int top; /* top scroll limit */
|
int top; /* top scroll limit */
|
||||||
int bot; /* bottom scroll limit */
|
int bot; /* bottom scroll limit */
|
||||||
int mode; /* terminal mode */
|
int mode; /* terminal mode */
|
||||||
|
int esc;
|
||||||
|
char title[TITLESIZ];
|
||||||
|
int titlelen;
|
||||||
} Term;
|
} Term;
|
||||||
|
|
||||||
/* Purely graphic info */
|
/* Purely graphic info */
|
||||||
|
@ -116,12 +120,10 @@ static void execsh(void);
|
||||||
static void sigchld(int);
|
static void sigchld(int);
|
||||||
static void run(void);
|
static void run(void);
|
||||||
|
|
||||||
static int escaddc(char);
|
static void csidump(void);
|
||||||
static int escfinal(char);
|
static void csihandle(void);
|
||||||
static void escdump(void);
|
static void csiparse(void);
|
||||||
static void eschandle(void);
|
static void csireset(void);
|
||||||
static void escparse(void);
|
|
||||||
static void escreset(void);
|
|
||||||
|
|
||||||
static void tclearregion(int, int, int, int);
|
static void tclearregion(int, int, int, int);
|
||||||
static void tcpos(int);
|
static void tcpos(int);
|
||||||
|
@ -168,7 +170,7 @@ static void (*handler[LASTEvent])(XEvent *) = {
|
||||||
static DC dc;
|
static DC dc;
|
||||||
static XWindow xw;
|
static XWindow xw;
|
||||||
static Term term;
|
static Term term;
|
||||||
static Escseq escseq;
|
static CSIEscape escseq;
|
||||||
static int cmdfd;
|
static int cmdfd;
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
static int running;
|
static int running;
|
||||||
|
@ -269,7 +271,7 @@ ttynew(void) {
|
||||||
void
|
void
|
||||||
dump(char c) {
|
dump(char c) {
|
||||||
static int col;
|
static int col;
|
||||||
fprintf(stderr, " %02x %c ", c, isprint(c)?c:'.');
|
fprintf(stderr, " %02x '%c' ", c, isprint(c)?c:'.');
|
||||||
if(++col % 10 == 0)
|
if(++col % 10 == 0)
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
@ -305,24 +307,6 @@ ttyresize(int x, int y) {
|
||||||
fprintf(stderr, "Couldn't set window size: %s\n", SERRNO);
|
fprintf(stderr, "Couldn't set window size: %s\n", SERRNO);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
escfinal(char c) {
|
|
||||||
if(escseq.len == 1)
|
|
||||||
switch(c) {
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '(':
|
|
||||||
return 0;
|
|
||||||
case '=':
|
|
||||||
case '>':
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if(BETWEEN(c, 0x40, 0x7E))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tcpos(int mode) {
|
tcpos(int mode) {
|
||||||
static int x = 0;
|
static int x = 0;
|
||||||
|
@ -372,44 +356,27 @@ tnewline(void) {
|
||||||
tmoveto(0, y);
|
tmoveto(0, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
escaddc(char c) {
|
|
||||||
escseq.buf[escseq.len++] = c;
|
|
||||||
if(escfinal(c) || escseq.len >= ESCSIZ) {
|
|
||||||
escparse(), eschandle();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
escparse(void) {
|
csiparse(void) {
|
||||||
/* int noarg = 1; */
|
/* int noarg = 1; */
|
||||||
char *p = escseq.buf;
|
char *p = escseq.buf;
|
||||||
|
|
||||||
escseq.narg = 0;
|
escseq.narg = 0;
|
||||||
switch(escseq.pre = *p++) {
|
if(*p == '?')
|
||||||
case '[': /* CSI */
|
escseq.priv = 1, p++;
|
||||||
if(*p == '?')
|
|
||||||
escseq.priv = 1, p++;
|
|
||||||
|
|
||||||
while(p < escseq.buf+escseq.len) {
|
while(p < escseq.buf+escseq.len) {
|
||||||
while(isdigit(*p)) {
|
while(isdigit(*p)) {
|
||||||
escseq.arg[escseq.narg] *= 10;
|
escseq.arg[escseq.narg] *= 10;
|
||||||
escseq.arg[escseq.narg] += *(p++) - '0'/*, noarg = 0 */;
|
escseq.arg[escseq.narg] += *p++ - '0'/*, noarg = 0 */;
|
||||||
}
|
}
|
||||||
if(*p == ';')
|
if(*p == ';' && escseq.narg+1 < ESCARGSIZ)
|
||||||
escseq.narg++, p++;
|
escseq.narg++, p++;
|
||||||
else {
|
else {
|
||||||
escseq.mode = *p;
|
escseq.mode = *p;
|
||||||
escseq.narg++;
|
escseq.narg++;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case '(':
|
|
||||||
/* XXX: graphic character set */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,146 +592,141 @@ tsetscroll(int t, int b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eschandle(void) {
|
csihandle(void) {
|
||||||
switch(escseq.pre) {
|
switch(escseq.mode) {
|
||||||
default:
|
default:
|
||||||
goto unknown_seq;
|
fprintf(stderr, "erresc: unknown sequence\n");
|
||||||
case '[':
|
csidump();
|
||||||
switch(escseq.mode) {
|
/* die(""); */
|
||||||
default:
|
break;
|
||||||
unknown_seq:
|
case '@': /* Insert <n> blank char */
|
||||||
fprintf(stderr, "erresc: unknown sequence\n");
|
DEFAULT(escseq.arg[0], 1);
|
||||||
escdump();
|
tinsertblank(escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'A': /* Cursor <n> Up */
|
||||||
|
case 'e':
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(term.c.x, term.c.y-escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'B': /* Cursor <n> Down */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(term.c.x, term.c.y+escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'C': /* Cursor <n> Forward */
|
||||||
|
case 'a':
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(term.c.x+escseq.arg[0], term.c.y);
|
||||||
|
break;
|
||||||
|
case 'D': /* Cursor <n> Backward */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(term.c.x-escseq.arg[0], term.c.y);
|
||||||
|
break;
|
||||||
|
case 'E': /* Cursor <n> Down and first col */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(0, term.c.y+escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'F': /* Cursor <n> Up and first col */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(0, term.c.y-escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'G': /* Move to <col> */
|
||||||
|
case '`':
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(escseq.arg[0]-1, term.c.y);
|
||||||
|
break;
|
||||||
|
case 'H': /* Move to <row> <col> */
|
||||||
|
case 'f':
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
DEFAULT(escseq.arg[1], 1);
|
||||||
|
tmoveto(escseq.arg[1]-1, escseq.arg[0]-1);
|
||||||
|
break;
|
||||||
|
case 'J': /* Clear screen */
|
||||||
|
switch(escseq.arg[0]) {
|
||||||
|
case 0: /* below */
|
||||||
|
tclearregion(term.c.x, term.c.y, term.col-1, term.row-1);
|
||||||
break;
|
break;
|
||||||
case '@': /* Insert <n> blank char */
|
case 1: /* above */
|
||||||
DEFAULT(escseq.arg[0], 1);
|
tclearregion(0, 0, term.c.x, term.c.y);
|
||||||
tinsertblank(escseq.arg[0]);
|
|
||||||
break;
|
break;
|
||||||
case 'A': /* Cursor <n> Up */
|
case 2: /* all */
|
||||||
case 'e':
|
tclearregion(0, 0, term.col-1, term.row-1);
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(term.c.x, term.c.y-escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'B': /* Cursor <n> Down */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(term.c.x, term.c.y+escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'C': /* Cursor <n> Forward */
|
|
||||||
case 'a':
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(term.c.x+escseq.arg[0], term.c.y);
|
|
||||||
break;
|
|
||||||
case 'D': /* Cursor <n> Backward */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(term.c.x-escseq.arg[0], term.c.y);
|
|
||||||
break;
|
|
||||||
case 'E': /* Cursor <n> Down and first col */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(0, term.c.y+escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'F': /* Cursor <n> Up and first col */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(0, term.c.y-escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'G': /* Move to <col> */
|
|
||||||
case '`':
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(escseq.arg[0]-1, term.c.y);
|
|
||||||
break;
|
|
||||||
case 'H': /* Move to <row> <col> */
|
|
||||||
case 'f':
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
DEFAULT(escseq.arg[1], 1);
|
|
||||||
tmoveto(escseq.arg[1]-1, escseq.arg[0]-1);
|
|
||||||
break;
|
|
||||||
case 'J': /* Clear screen */
|
|
||||||
switch(escseq.arg[0]) {
|
|
||||||
case 0: /* below */
|
|
||||||
tclearregion(term.c.x, term.c.y, term.col-1, term.row-1);
|
|
||||||
break;
|
|
||||||
case 1: /* above */
|
|
||||||
tclearregion(0, 0, term.c.x, term.c.y);
|
|
||||||
break;
|
|
||||||
case 2: /* all */
|
|
||||||
tclearregion(0, 0, term.col-1, term.row-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'K': /* Clear line */
|
|
||||||
switch(escseq.arg[0]) {
|
|
||||||
case 0: /* right */
|
|
||||||
tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
|
|
||||||
break;
|
|
||||||
case 1: /* left */
|
|
||||||
tclearregion(0, term.c.y, term.c.x, term.c.y);
|
|
||||||
break;
|
|
||||||
case 2: /* all */
|
|
||||||
tclearregion(0, term.c.y, term.col-1, term.c.y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'L': /* Insert <n> blank lines */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tinsertblankline(escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
if(escseq.priv && escseq.arg[0] == 25)
|
|
||||||
term.c.hidden = 1;
|
|
||||||
break;
|
|
||||||
case 'M': /* Delete <n> lines */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tdeleteline(escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'P': /* Delete <n> char */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tdeletechar(escseq.arg[0]);
|
|
||||||
break;
|
|
||||||
case 'd': /* Move to <row> */
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
tmoveto(term.c.x, escseq.arg[0]-1);
|
|
||||||
break;
|
|
||||||
case 'h': /* Set terminal mode */
|
|
||||||
if(escseq.priv && escseq.arg[0] == 25)
|
|
||||||
term.c.hidden = 0;
|
|
||||||
break;
|
|
||||||
case 'm': /* Terminal attribute (color) */
|
|
||||||
tsetattr(escseq.arg, escseq.narg);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
if(escseq.priv)
|
|
||||||
;
|
|
||||||
else {
|
|
||||||
DEFAULT(escseq.arg[0], 1);
|
|
||||||
DEFAULT(escseq.arg[1], term.row);
|
|
||||||
tsetscroll(escseq.arg[0]-1, escseq.arg[1]-1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's': /* Save cursor position */
|
|
||||||
tcpos(CSsave);
|
|
||||||
break;
|
|
||||||
case 'u': /* Load cursor position */
|
|
||||||
tcpos(CSload);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'K': /* Clear line */
|
||||||
|
switch(escseq.arg[0]) {
|
||||||
|
case 0: /* right */
|
||||||
|
tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
|
||||||
|
break;
|
||||||
|
case 1: /* left */
|
||||||
|
tclearregion(0, term.c.y, term.c.x, term.c.y);
|
||||||
|
break;
|
||||||
|
case 2: /* all */
|
||||||
|
tclearregion(0, term.c.y, term.col-1, term.c.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
case 'L': /* Insert <n> blank lines */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tinsertblankline(escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if(escseq.priv && escseq.arg[0] == 25)
|
||||||
|
term.c.hidden = 1;
|
||||||
|
break;
|
||||||
|
case 'M': /* Delete <n> lines */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tdeleteline(escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
case 'P': /* Delete <n> char */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tdeletechar(escseq.arg[0]);
|
||||||
|
break;
|
||||||
|
case 'd': /* Move to <row> */
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
tmoveto(term.c.x, escseq.arg[0]-1);
|
||||||
|
break;
|
||||||
|
case 'h': /* Set terminal mode */
|
||||||
|
if(escseq.priv && escseq.arg[0] == 25)
|
||||||
|
term.c.hidden = 0;
|
||||||
|
break;
|
||||||
|
case 'm': /* Terminal attribute (color) */
|
||||||
|
tsetattr(escseq.arg, escseq.narg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
if(escseq.priv)
|
||||||
|
;
|
||||||
|
else {
|
||||||
|
DEFAULT(escseq.arg[0], 1);
|
||||||
|
DEFAULT(escseq.arg[1], term.row);
|
||||||
|
tsetscroll(escseq.arg[0]-1, escseq.arg[1]-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's': /* Save cursor position */
|
||||||
|
tcpos(CSsave);
|
||||||
|
break;
|
||||||
|
case 'u': /* Load cursor position */
|
||||||
|
tcpos(CSload);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
escdump(void) {
|
csidump(void) {
|
||||||
int i;
|
int i;
|
||||||
printf("rawbuf : %s\n", escseq.buf);
|
printf("ESC [ %s", escseq.priv ? "? " : "");
|
||||||
printf("prechar : %c\n", escseq.pre);
|
|
||||||
printf("private : %c\n", escseq.priv ? '?' : ' ');
|
|
||||||
printf("narg : %d\n", escseq.narg);
|
|
||||||
if(escseq.narg)
|
if(escseq.narg)
|
||||||
for(i = 0; i < escseq.narg; i++)
|
for(i = 0; i < escseq.narg; i++)
|
||||||
printf("\targ %d = %d\n", i, escseq.arg[i]);
|
printf("%d ", escseq.arg[i]);
|
||||||
printf("mode : %c\n", escseq.mode);
|
if(escseq.mode)
|
||||||
|
putchar(escseq.mode);
|
||||||
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
escreset(void) {
|
csireset(void) {
|
||||||
memset(&escseq, 0, sizeof(escseq));
|
memset(&escseq, 0, sizeof(escseq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,21 +743,41 @@ tputtab(void) {
|
||||||
|
|
||||||
void
|
void
|
||||||
tputc(char c) {
|
tputc(char c) {
|
||||||
static int inesc = 0;
|
|
||||||
#if 0
|
#if 0
|
||||||
dump(c);
|
dump(c);
|
||||||
#endif
|
#endif
|
||||||
/* start of escseq */
|
if(term.esc & ESCin) {
|
||||||
if(c == '\033')
|
if(term.esc & ESCcsi) {
|
||||||
escreset(), inesc = 1;
|
escseq.buf[escseq.len++] = c;
|
||||||
else if(inesc) {
|
if(BETWEEN(c, 0x40, 0x7E) || escseq.len >= ESCSIZ) {
|
||||||
inesc = escaddc(c);
|
term.esc = 0;
|
||||||
} /* normal char */
|
csiparse(), csihandle();
|
||||||
else switch(c) {
|
}
|
||||||
default:
|
} else if (term.esc & ESCosc) {
|
||||||
tsetchar(c);
|
if(c == ';') {
|
||||||
tcursor(CSright);
|
term.titlelen = 0;
|
||||||
break;
|
term.esc = ESCin | ESCtitle;
|
||||||
|
}
|
||||||
|
} else if(term.esc & ESCtitle) {
|
||||||
|
if(c == '\a' || term.titlelen+1 >= TITLESIZ) {
|
||||||
|
term.esc = 0;
|
||||||
|
term.title[term.titlelen] = '\0';
|
||||||
|
XStoreName(xw.dis, xw.win, term.title);
|
||||||
|
} else {
|
||||||
|
term.title[term.titlelen++] = c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(c) {
|
||||||
|
case '[':
|
||||||
|
term.esc |= ESCcsi;
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
term.esc |= ESCosc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch(c) {
|
||||||
case '\t':
|
case '\t':
|
||||||
tputtab();
|
tputtab();
|
||||||
break;
|
break;
|
||||||
|
@ -811,6 +793,15 @@ tputc(char c) {
|
||||||
case '\a':
|
case '\a':
|
||||||
xbell();
|
xbell();
|
||||||
break;
|
break;
|
||||||
|
case '\033':
|
||||||
|
csireset();
|
||||||
|
term.esc = ESCin;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tsetchar(c);
|
||||||
|
tcursor(CSright);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue