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:
		
							parent
							
								
									f2dff29a16
								
							
						
					
					
						commit
						0981437524
					
				
							
								
								
									
										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; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user