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/Xutil.h> | ||||
| 
 | ||||
| #define TNAME "st" | ||||
| #define TNAME "xterm" | ||||
| 
 | ||||
| /* Arbitrary sizes */ | ||||
| #define TITLESIZ 256 | ||||
| #define ESCSIZ 256 | ||||
| #define ESCARG 16 | ||||
| #define ESCARGSIZ 16 | ||||
| #define MAXDRAWBUF 1024 | ||||
| 
 | ||||
| #define SERRNO strerror(errno) | ||||
| @ -40,7 +41,8 @@ | ||||
| enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; | ||||
| enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload }; | ||||
| 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 }; | ||||
| 
 | ||||
| typedef int Color; | ||||
| @ -62,17 +64,16 @@ typedef struct { | ||||
| 	int y; | ||||
| } TCursor; | ||||
| 
 | ||||
| /* Escape sequence structs */ | ||||
| /* ESC <pre> [[ [<priv>] <arg> [;]] <mode>] */ | ||||
| /* CSI Escape sequence structs */ | ||||
| /* ESC '[' [[ [<priv>] <arg> [;]] <mode>] */ | ||||
| typedef struct { | ||||
| 	char buf[ESCSIZ+1]; /* raw string */ | ||||
| 	char buf[ESCSIZ]; /* raw string */ | ||||
| 	int len;            /* raw string length */ | ||||
| 	char pre;            | ||||
| 	char priv; | ||||
| 	int arg[ESCARG+1]; | ||||
| 	int arg[ESCARGSIZ]; | ||||
| 	int narg;           /* nb of args */ | ||||
| 	char mode; | ||||
| } Escseq; | ||||
| } CSIEscape; | ||||
| 
 | ||||
| /* Internal representation of the screen */ | ||||
| typedef struct { | ||||
| @ -83,6 +84,9 @@ typedef struct { | ||||
| 	int top;    /* top    scroll limit */ | ||||
| 	int bot;    /* bottom scroll limit */ | ||||
| 	int mode;   /* terminal mode */ | ||||
| 	int esc; | ||||
| 	char title[TITLESIZ]; | ||||
| 	int titlelen; | ||||
| } Term; | ||||
| 
 | ||||
| /* Purely graphic info */ | ||||
| @ -116,12 +120,10 @@ static void execsh(void); | ||||
| static void sigchld(int); | ||||
| static void run(void); | ||||
| 
 | ||||
| static int escaddc(char); | ||||
| static int escfinal(char); | ||||
| static void escdump(void); | ||||
| static void eschandle(void); | ||||
| static void escparse(void); | ||||
| static void escreset(void); | ||||
| static void csidump(void); | ||||
| static void csihandle(void); | ||||
| static void csiparse(void); | ||||
| static void csireset(void); | ||||
| 
 | ||||
| static void tclearregion(int, int, int, int); | ||||
| static void tcpos(int); | ||||
| @ -168,7 +170,7 @@ static void (*handler[LASTEvent])(XEvent *) = { | ||||
| static DC dc; | ||||
| static XWindow xw; | ||||
| static Term term; | ||||
| static Escseq escseq; | ||||
| static CSIEscape escseq; | ||||
| static int cmdfd; | ||||
| static pid_t pid; | ||||
| static int running; | ||||
| @ -269,7 +271,7 @@ ttynew(void) { | ||||
| void | ||||
| dump(char c) { | ||||
| 	static int col; | ||||
| 	fprintf(stderr, " %02x %c ", c, isprint(c)?c:'.'); | ||||
| 	fprintf(stderr, " %02x '%c' ", c, isprint(c)?c:'.'); | ||||
| 	if(++col % 10 == 0) | ||||
| 		fprintf(stderr, "\n"); | ||||
| } | ||||
| @ -305,24 +307,6 @@ ttyresize(int x, int y) { | ||||
| 		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 | ||||
| tcpos(int mode) { | ||||
| 	static int x = 0; | ||||
| @ -372,33 +356,21 @@ tnewline(void) { | ||||
| 	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 | ||||
| escparse(void) { | ||||
| csiparse(void) { | ||||
| 	/* int noarg = 1; */ | ||||
| 	char *p = escseq.buf; | ||||
| 
 | ||||
| 	escseq.narg = 0; | ||||
| 	switch(escseq.pre = *p++) { | ||||
| 	case '[': /* CSI */ | ||||
| 	if(*p == '?') | ||||
| 		escseq.priv = 1, p++; | ||||
| 	 | ||||
| 	while(p < escseq.buf+escseq.len) { | ||||
| 		while(isdigit(*p)) { | ||||
| 			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++; | ||||
| 		else { | ||||
| 			escseq.mode = *p; | ||||
| @ -406,11 +378,6 @@ escparse(void) { | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 		break; | ||||
| 	case '(': | ||||
| 		/* XXX: graphic character set */ | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| @ -625,16 +592,12 @@ tsetscroll(int t, int b) { | ||||
| } | ||||
| 
 | ||||
| void | ||||
| eschandle(void) { | ||||
| 	switch(escseq.pre) { | ||||
| 	default: | ||||
| 		goto unknown_seq; | ||||
| 	case '[': | ||||
| csihandle(void) { | ||||
| 	switch(escseq.mode) { | ||||
| 	default: | ||||
| 		unknown_seq: | ||||
| 		fprintf(stderr, "erresc: unknown sequence\n"); | ||||
| 			escdump(); | ||||
| 		csidump(); | ||||
| 		/* die(""); */ | ||||
| 		break; | ||||
| 	case '@': /* Insert <n> blank char */ | ||||
| 		DEFAULT(escseq.arg[0], 1); | ||||
| @ -703,6 +666,7 @@ eschandle(void) { | ||||
| 			break; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 'S': | ||||
| 	case 'L': /* Insert <n> blank lines */ | ||||
| 		DEFAULT(escseq.arg[0], 1); | ||||
| 		tinsertblankline(escseq.arg[0]); | ||||
| @ -715,6 +679,7 @@ eschandle(void) { | ||||
| 		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]); | ||||
| @ -746,25 +711,22 @@ eschandle(void) { | ||||
| 		tcpos(CSload); | ||||
| 		break; | ||||
| 	} | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| escdump(void) {  | ||||
| csidump(void) {  | ||||
| 	int i; | ||||
| 	printf("rawbuf	: %s\n", escseq.buf); | ||||
| 	printf("prechar : %c\n", escseq.pre); | ||||
| 	printf("private : %c\n", escseq.priv ? '?' : ' '); | ||||
| 	printf("narg	: %d\n", escseq.narg); | ||||
| 	printf("ESC [ %s", escseq.priv ? "? " : ""); | ||||
| 	if(escseq.narg) | ||||
| 		for(i = 0; i < escseq.narg; i++) | ||||
| 			printf("\targ %d = %d\n", i, escseq.arg[i]); | ||||
| 	printf("mode	: %c\n", escseq.mode); | ||||
| 			printf("%d ", escseq.arg[i]); | ||||
| 	if(escseq.mode) | ||||
| 		putchar(escseq.mode); | ||||
| 	putchar('\n'); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| escreset(void) { | ||||
| csireset(void) { | ||||
| 	memset(&escseq, 0, sizeof(escseq)); | ||||
| } | ||||
| 
 | ||||
| @ -781,21 +743,41 @@ tputtab(void) { | ||||
| 
 | ||||
| void | ||||
| tputc(char c) { | ||||
| 	static int inesc = 0; | ||||
| #if 0 | ||||
| 	dump(c); | ||||
| #endif	 | ||||
| 	/* start of escseq */ | ||||
| 	if(c == '\033') | ||||
| 		escreset(), inesc = 1; | ||||
| 	else if(inesc) { | ||||
| 		inesc = escaddc(c); | ||||
| 	} /* normal char */  | ||||
| 	else switch(c) {  | ||||
| 		default: | ||||
| 			tsetchar(c); | ||||
| 			tcursor(CSright); | ||||
| 	if(term.esc & ESCin) { | ||||
| 		if(term.esc & ESCcsi) { | ||||
| 			escseq.buf[escseq.len++] = c; | ||||
| 			if(BETWEEN(c, 0x40, 0x7E) || escseq.len >= ESCSIZ) { | ||||
| 				term.esc = 0; | ||||
| 				csiparse(), csihandle(); | ||||
| 			} | ||||
| 		} else if (term.esc & ESCosc) { | ||||
| 			if(c == ';') { | ||||
| 				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; | ||||
| 			case ']': | ||||
| 				term.esc |= ESCosc; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		switch(c) { | ||||
| 		case '\t': | ||||
| 			tputtab(); | ||||
| 			break; | ||||
| @ -811,6 +793,15 @@ tputc(char c) { | ||||
| 		case '\a': | ||||
| 			xbell(); | ||||
| 			break; | ||||
| 		case '\033': | ||||
| 			csireset(); | ||||
| 			term.esc = ESCin; | ||||
| 			break; | ||||
| 		default: | ||||
| 			tsetchar(c); | ||||
| 			tcursor(CSright); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user