TERM set to xterm by default (which broke a lot of stuff), better escape handling (title), and a little clean up.
This commit is contained in:
		
							
								
								
									
										157
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								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,33 +356,21 @@ 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++) {
 | 
					 | 
				
			||||||
	case '[': /* CSI */
 | 
					 | 
				
			||||||
	if(*p == '?')
 | 
						if(*p == '?')
 | 
				
			||||||
		escseq.priv = 1, 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;
 | 
				
			||||||
@ -406,11 +378,6 @@ escparse(void) {
 | 
				
			|||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case '(':
 | 
					 | 
				
			||||||
		/* XXX: graphic character set */
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -625,16 +592,12 @@ tsetscroll(int t, int b) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
eschandle(void) {
 | 
					csihandle(void) {
 | 
				
			||||||
	switch(escseq.pre) {
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		goto unknown_seq;
 | 
					 | 
				
			||||||
	case '[':
 | 
					 | 
				
			||||||
	switch(escseq.mode) {
 | 
						switch(escseq.mode) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		unknown_seq:
 | 
					 | 
				
			||||||
		fprintf(stderr, "erresc: unknown sequence\n");
 | 
							fprintf(stderr, "erresc: unknown sequence\n");
 | 
				
			||||||
			escdump();
 | 
							csidump();
 | 
				
			||||||
 | 
							/* die(""); */
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '@': /* Insert <n> blank char */
 | 
						case '@': /* Insert <n> blank char */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(escseq.arg[0], 1);
 | 
				
			||||||
@ -703,6 +666,7 @@ eschandle(void) {
 | 
				
			|||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case 'S':
 | 
				
			||||||
	case 'L': /* Insert <n> blank lines */
 | 
						case 'L': /* Insert <n> blank lines */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(escseq.arg[0], 1);
 | 
				
			||||||
		tinsertblankline(escseq.arg[0]);
 | 
							tinsertblankline(escseq.arg[0]);
 | 
				
			||||||
@ -715,6 +679,7 @@ eschandle(void) {
 | 
				
			|||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(escseq.arg[0], 1);
 | 
				
			||||||
		tdeleteline(escseq.arg[0]);
 | 
							tdeleteline(escseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case 'X':
 | 
				
			||||||
	case 'P': /* Delete <n> char */
 | 
						case 'P': /* Delete <n> char */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(escseq.arg[0], 1);
 | 
				
			||||||
		tdeletechar(escseq.arg[0]);
 | 
							tdeletechar(escseq.arg[0]);
 | 
				
			||||||
@ -746,25 +711,22 @@ eschandle(void) {
 | 
				
			|||||||
		tcpos(CSload);
 | 
							tcpos(CSload);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		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;
 | 
				
			||||||
 | 
									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;
 | 
									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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user