Add OSC, DSC, PM, APC and settitle.
This commit is contained in:
		
							parent
							
								
									ff040e9894
								
							
						
					
					
						commit
						6696ef8563
					
				
							
								
								
									
										1
									
								
								TODO
								
								
								
								
							
							
						
						
									
										1
									
								
								TODO
								
								
								
								
							| 
						 | 
					@ -20,6 +20,7 @@ bugs
 | 
				
			||||||
* fix shift up/down (shift selection in emacs)
 | 
					* fix shift up/down (shift selection in emacs)
 | 
				
			||||||
* fix selection click
 | 
					* fix selection click
 | 
				
			||||||
* fix selection paste for xatom STRING
 | 
					* fix selection paste for xatom STRING
 | 
				
			||||||
 | 
					* fix umlaut handling in settitle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
misc
 | 
					misc
 | 
				
			||||||
----
 | 
					----
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										279
									
								
								st.c
								
								
								
								
							
							
						
						
									
										279
									
								
								st.c
								
								
								
								
							| 
						 | 
					@ -43,9 +43,10 @@
 | 
				
			||||||
#define XEMBED_FOCUS_OUT 5
 | 
					#define XEMBED_FOCUS_OUT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Arbitrary sizes */
 | 
					/* Arbitrary sizes */
 | 
				
			||||||
#define ESC_TITLE_SIZ 256
 | 
					 | 
				
			||||||
#define ESC_BUF_SIZ   256
 | 
					#define ESC_BUF_SIZ   256
 | 
				
			||||||
#define ESC_ARG_SIZ   16
 | 
					#define ESC_ARG_SIZ   16
 | 
				
			||||||
 | 
					#define STR_BUF_SIZ   256
 | 
				
			||||||
 | 
					#define STR_ARG_SIZ   16
 | 
				
			||||||
#define DRAW_BUF_SIZ  1024
 | 
					#define DRAW_BUF_SIZ  1024
 | 
				
			||||||
#define UTF_SIZ       4
 | 
					#define UTF_SIZ       4
 | 
				
			||||||
#define XK_NO_MOD     UINT_MAX
 | 
					#define XK_NO_MOD     UINT_MAX
 | 
				
			||||||
| 
						 | 
					@ -110,9 +111,9 @@ enum term_mode {
 | 
				
			||||||
enum escape_state {
 | 
					enum escape_state {
 | 
				
			||||||
	ESC_START      = 1,
 | 
						ESC_START      = 1,
 | 
				
			||||||
	ESC_CSI        = 2,
 | 
						ESC_CSI        = 2,
 | 
				
			||||||
	ESC_OSC        = 4,
 | 
						ESC_STR        = 4, /* DSC, OSC, PM, APC */
 | 
				
			||||||
	ESC_TITLE      = 8,
 | 
						ESC_ALTCHARSET = 8,
 | 
				
			||||||
	ESC_ALTCHARSET = 16
 | 
						ESC_STR_END    = 16, /* a final string was encountered */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum window_state {
 | 
					enum window_state {
 | 
				
			||||||
| 
						 | 
					@ -158,6 +159,16 @@ typedef struct {
 | 
				
			||||||
	char mode;
 | 
						char mode;
 | 
				
			||||||
} CSIEscape;
 | 
					} CSIEscape;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* STR Escape sequence structs */
 | 
				
			||||||
 | 
					/* ESC type [[ [<priv>] <arg> [;]] <mode>] ESC '\' */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						char type;             /* ESC type ... */
 | 
				
			||||||
 | 
						char buf[STR_BUF_SIZ]; /* raw string */
 | 
				
			||||||
 | 
						int len;               /* raw string length */
 | 
				
			||||||
 | 
						char *args[STR_ARG_SIZ];
 | 
				
			||||||
 | 
						int narg;              /* nb of args */
 | 
				
			||||||
 | 
					} STREscape;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Internal representation of the screen */
 | 
					/* Internal representation of the screen */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	int row;	/* nb row */
 | 
						int row;	/* nb row */
 | 
				
			||||||
| 
						 | 
					@ -170,8 +181,6 @@ typedef struct {
 | 
				
			||||||
	int bot;	/* bottom scroll limit */
 | 
						int bot;	/* bottom scroll limit */
 | 
				
			||||||
	int mode;	/* terminal mode flags */
 | 
						int mode;	/* terminal mode flags */
 | 
				
			||||||
	int esc;	/* escape state flags */
 | 
						int esc;	/* escape state flags */
 | 
				
			||||||
	char title[ESC_TITLE_SIZ];
 | 
					 | 
				
			||||||
	int titlelen;
 | 
					 | 
				
			||||||
	bool *tabs;
 | 
						bool *tabs;
 | 
				
			||||||
} Term;
 | 
					} Term;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,6 +248,10 @@ static void csidump(void);
 | 
				
			||||||
static void csihandle(void);
 | 
					static void csihandle(void);
 | 
				
			||||||
static void csiparse(void);
 | 
					static void csiparse(void);
 | 
				
			||||||
static void csireset(void);
 | 
					static void csireset(void);
 | 
				
			||||||
 | 
					static void strdump(void);
 | 
				
			||||||
 | 
					static void strhandle(void);
 | 
				
			||||||
 | 
					static void strparse(void);
 | 
				
			||||||
 | 
					static void strreset(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tclearregion(int, int, int, int);
 | 
					static void tclearregion(int, int, int, int);
 | 
				
			||||||
static void tcursor(int);
 | 
					static void tcursor(int);
 | 
				
			||||||
| 
						 | 
					@ -323,7 +336,8 @@ static void (*handler[LASTEvent])(XEvent *) = {
 | 
				
			||||||
static DC dc;
 | 
					static DC dc;
 | 
				
			||||||
static XWindow xw;
 | 
					static XWindow xw;
 | 
				
			||||||
static Term term;
 | 
					static Term term;
 | 
				
			||||||
static CSIEscape escseq;
 | 
					static CSIEscape csiescseq;
 | 
				
			||||||
 | 
					static STREscape strescseq;
 | 
				
			||||||
static int cmdfd;
 | 
					static int cmdfd;
 | 
				
			||||||
static pid_t pid;
 | 
					static pid_t pid;
 | 
				
			||||||
static Selection sel;
 | 
					static Selection sel;
 | 
				
			||||||
| 
						 | 
					@ -968,22 +982,22 @@ tnewline(int first_col) {
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
csiparse(void) {
 | 
					csiparse(void) {
 | 
				
			||||||
	/* int noarg = 1; */
 | 
						/* int noarg = 1; */
 | 
				
			||||||
	char *p = escseq.buf;
 | 
						char *p = csiescseq.buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	escseq.narg = 0;
 | 
						csiescseq.narg = 0;
 | 
				
			||||||
	if(*p == '?')
 | 
						if(*p == '?')
 | 
				
			||||||
		escseq.priv = 1, p++;
 | 
							csiescseq.priv = 1, p++;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	while(p < escseq.buf+escseq.len) {
 | 
						while(p < csiescseq.buf+csiescseq.len) {
 | 
				
			||||||
		while(isdigit(*p)) {
 | 
							while(isdigit(*p)) {
 | 
				
			||||||
			escseq.arg[escseq.narg] *= 10;
 | 
								csiescseq.arg[csiescseq.narg] *= 10;
 | 
				
			||||||
			escseq.arg[escseq.narg] += *p++ - '0'/*, noarg = 0 */;
 | 
								csiescseq.arg[csiescseq.narg] += *p++ - '0'/*, noarg = 0 */;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if(*p == ';' && escseq.narg+1 < ESC_ARG_SIZ)
 | 
							if(*p == ';' && csiescseq.narg+1 < ESC_ARG_SIZ)
 | 
				
			||||||
			escseq.narg++, p++;
 | 
								csiescseq.narg++, p++;
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			escseq.mode = *p;
 | 
								csiescseq.mode = *p;
 | 
				
			||||||
			escseq.narg++;
 | 
								csiescseq.narg++;
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1166,7 +1180,7 @@ tsetscroll(int t, int b) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
csihandle(void) {
 | 
					csihandle(void) {
 | 
				
			||||||
	switch(escseq.mode) {
 | 
						switch(csiescseq.mode) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
	unknown:
 | 
						unknown:
 | 
				
			||||||
		fprintf(stderr, "erresc: unknown csi ");
 | 
							fprintf(stderr, "erresc: unknown csi ");
 | 
				
			||||||
| 
						 | 
					@ -1174,37 +1188,37 @@ csihandle(void) {
 | 
				
			||||||
		/* die(""); */
 | 
							/* die(""); */
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case '@': /* ICH -- Insert <n> blank char */
 | 
						case '@': /* ICH -- Insert <n> blank char */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tinsertblank(escseq.arg[0]);
 | 
							tinsertblank(csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'A': /* CUU -- Cursor <n> Up */
 | 
						case 'A': /* CUU -- Cursor <n> Up */
 | 
				
			||||||
	case 'e':
 | 
						case 'e':
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(term.c.x, term.c.y-escseq.arg[0]);
 | 
							tmoveto(term.c.x, term.c.y-csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'B': /* CUD -- Cursor <n> Down */
 | 
						case 'B': /* CUD -- Cursor <n> Down */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(term.c.x, term.c.y+escseq.arg[0]);
 | 
							tmoveto(term.c.x, term.c.y+csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'C': /* CUF -- Cursor <n> Forward */
 | 
						case 'C': /* CUF -- Cursor <n> Forward */
 | 
				
			||||||
	case 'a':
 | 
						case 'a':
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(term.c.x+escseq.arg[0], term.c.y);
 | 
							tmoveto(term.c.x+csiescseq.arg[0], term.c.y);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'D': /* CUB -- Cursor <n> Backward */
 | 
						case 'D': /* CUB -- Cursor <n> Backward */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(term.c.x-escseq.arg[0], term.c.y);
 | 
							tmoveto(term.c.x-csiescseq.arg[0], term.c.y);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'E': /* CNL -- Cursor <n> Down and first col */
 | 
						case 'E': /* CNL -- Cursor <n> Down and first col */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(0, term.c.y+escseq.arg[0]);
 | 
							tmoveto(0, term.c.y+csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'F': /* CPL -- Cursor <n> Up and first col */
 | 
						case 'F': /* CPL -- Cursor <n> Up and first col */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(0, term.c.y-escseq.arg[0]);
 | 
							tmoveto(0, term.c.y-csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'g': /* TBC -- Tabulation clear */
 | 
						case 'g': /* TBC -- Tabulation clear */
 | 
				
			||||||
		switch (escseq.arg[0]) {
 | 
							switch (csiescseq.arg[0]) {
 | 
				
			||||||
		case 0: /* clear current tab stop */
 | 
							case 0: /* clear current tab stop */
 | 
				
			||||||
			term.tabs[term.c.x] = 0;
 | 
								term.tabs[term.c.x] = 0;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -1217,23 +1231,23 @@ csihandle(void) {
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'G': /* CHA -- Move to <col> */
 | 
						case 'G': /* CHA -- Move to <col> */
 | 
				
			||||||
	case '`': /* XXX: HPA -- same? */
 | 
						case '`': /* XXX: HPA -- same? */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(escseq.arg[0]-1, term.c.y);
 | 
							tmoveto(csiescseq.arg[0]-1, term.c.y);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'H': /* CUP -- Move to <row> <col> */
 | 
						case 'H': /* CUP -- Move to <row> <col> */
 | 
				
			||||||
	case 'f': /* XXX: HVP -- same? */
 | 
						case 'f': /* XXX: HVP -- same? */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		DEFAULT(escseq.arg[1], 1);
 | 
							DEFAULT(csiescseq.arg[1], 1);
 | 
				
			||||||
		tmoveto(escseq.arg[1]-1, escseq.arg[0]-1);
 | 
							tmoveto(csiescseq.arg[1]-1, csiescseq.arg[0]-1);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
 | 
						case 'I': /* CHT -- Cursor Forward Tabulation <n> tab stops */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		while (escseq.arg[0]--)
 | 
							while (csiescseq.arg[0]--)
 | 
				
			||||||
			tputtab();
 | 
								tputtab();
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'J': /* ED -- Clear screen */
 | 
						case 'J': /* ED -- Clear screen */
 | 
				
			||||||
		sel.bx = -1;
 | 
							sel.bx = -1;
 | 
				
			||||||
		switch(escseq.arg[0]) {
 | 
							switch(csiescseq.arg[0]) {
 | 
				
			||||||
		case 0: /* below */
 | 
							case 0: /* below */
 | 
				
			||||||
			tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
 | 
								tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
 | 
				
			||||||
			if(term.c.y < term.row-1)
 | 
								if(term.c.y < term.row-1)
 | 
				
			||||||
| 
						 | 
					@ -1252,7 +1266,7 @@ csihandle(void) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'K': /* EL -- Clear line */
 | 
						case 'K': /* EL -- Clear line */
 | 
				
			||||||
		switch(escseq.arg[0]) {
 | 
							switch(csiescseq.arg[0]) {
 | 
				
			||||||
		case 0: /* right */
 | 
							case 0: /* right */
 | 
				
			||||||
			tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
 | 
								tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -1265,20 +1279,20 @@ csihandle(void) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'S': /* SU -- Scroll <n> line up */
 | 
						case 'S': /* SU -- Scroll <n> line up */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tscrollup(term.top, escseq.arg[0]);
 | 
							tscrollup(term.top, csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'T': /* SD -- Scroll <n> line down */
 | 
						case 'T': /* SD -- Scroll <n> line down */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tscrolldown(term.top, escseq.arg[0]);
 | 
							tscrolldown(term.top, csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'L': /* IL -- Insert <n> blank lines */
 | 
						case 'L': /* IL -- Insert <n> blank lines */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tinsertblankline(escseq.arg[0]);
 | 
							tinsertblankline(csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'l': /* RM -- Reset Mode */
 | 
						case 'l': /* RM -- Reset Mode */
 | 
				
			||||||
		if(escseq.priv) {
 | 
							if(csiescseq.priv) {
 | 
				
			||||||
			switch(escseq.arg[0]) {
 | 
								switch(csiescseq.arg[0]) {
 | 
				
			||||||
			case 1:
 | 
								case 1:
 | 
				
			||||||
				term.mode &= ~MODE_APPKEYPAD;
 | 
									term.mode &= ~MODE_APPKEYPAD;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -1312,7 +1326,7 @@ csihandle(void) {
 | 
				
			||||||
					tclearregion(0, 0, term.col-1, term.row-1);
 | 
										tclearregion(0, 0, term.col-1, term.row-1);
 | 
				
			||||||
					tswapscreen();
 | 
										tswapscreen();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if(escseq.arg[0] != 1049)
 | 
									if(csiescseq.arg[0] != 1049)
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			case 1048:
 | 
								case 1048:
 | 
				
			||||||
				tcursor(CURSOR_LOAD);
 | 
									tcursor(CURSOR_LOAD);
 | 
				
			||||||
| 
						 | 
					@ -1321,7 +1335,7 @@ csihandle(void) {
 | 
				
			||||||
				goto unknown;
 | 
									goto unknown;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			switch(escseq.arg[0]) {
 | 
								switch(csiescseq.arg[0]) {
 | 
				
			||||||
			case 4:
 | 
								case 4:
 | 
				
			||||||
				term.mode &= ~MODE_INSERT;
 | 
									term.mode &= ~MODE_INSERT;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -1331,25 +1345,25 @@ csihandle(void) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'M': /* DL -- Delete <n> lines */
 | 
						case 'M': /* DL -- Delete <n> lines */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tdeleteline(escseq.arg[0]);
 | 
							tdeleteline(csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'X': /* ECH -- Erase <n> char */
 | 
						case 'X': /* ECH -- Erase <n> char */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tclearregion(term.c.x, term.c.y, term.c.x + escseq.arg[0], term.c.y);
 | 
							tclearregion(term.c.x, term.c.y, term.c.x + csiescseq.arg[0], term.c.y);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'P': /* DCH -- Delete <n> char */
 | 
						case 'P': /* DCH -- Delete <n> char */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tdeletechar(escseq.arg[0]);
 | 
							tdeletechar(csiescseq.arg[0]);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	/* XXX: (CSI n Z) CBT -- Cursor Backward Tabulation <n> tab stops */
 | 
						/* XXX: (CSI n Z) CBT -- Cursor Backward Tabulation <n> tab stops */
 | 
				
			||||||
	case 'd': /* VPA -- Move to <row> */
 | 
						case 'd': /* VPA -- Move to <row> */
 | 
				
			||||||
		DEFAULT(escseq.arg[0], 1);
 | 
							DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
		tmoveto(term.c.x, escseq.arg[0]-1);
 | 
							tmoveto(term.c.x, csiescseq.arg[0]-1);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'h': /* SM -- Set terminal mode */
 | 
						case 'h': /* SM -- Set terminal mode */
 | 
				
			||||||
		if(escseq.priv) {
 | 
							if(csiescseq.priv) {
 | 
				
			||||||
			switch(escseq.arg[0]) {
 | 
								switch(csiescseq.arg[0]) {
 | 
				
			||||||
			case 1:
 | 
								case 1:
 | 
				
			||||||
				term.mode |= MODE_APPKEYPAD;
 | 
									term.mode |= MODE_APPKEYPAD;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -1367,7 +1381,7 @@ csihandle(void) {
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case 12: /* att610 -- Start blinking cursor (IGNORED) */
 | 
								case 12: /* att610 -- Start blinking cursor (IGNORED) */
 | 
				
			||||||
				 /* fallthrough for xterm cvvis = CSI [ ? 12 ; 25 h */
 | 
									 /* fallthrough for xterm cvvis = CSI [ ? 12 ; 25 h */
 | 
				
			||||||
				if(escseq.narg > 1 && escseq.arg[1] != 25)
 | 
									if(csiescseq.narg > 1 && csiescseq.arg[1] != 25)
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			case 25:
 | 
								case 25:
 | 
				
			||||||
				term.c.state &= ~CURSOR_HIDE;
 | 
									term.c.state &= ~CURSOR_HIDE;
 | 
				
			||||||
| 
						 | 
					@ -1385,7 +1399,7 @@ csihandle(void) {
 | 
				
			||||||
					tclearregion(0, 0, term.col-1, term.row-1);
 | 
										tclearregion(0, 0, term.col-1, term.row-1);
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					tswapscreen();
 | 
										tswapscreen();
 | 
				
			||||||
				if(escseq.arg[0] != 1049)
 | 
									if(csiescseq.arg[0] != 1049)
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
			case 1048:
 | 
								case 1048:
 | 
				
			||||||
				tcursor(CURSOR_SAVE);
 | 
									tcursor(CURSOR_SAVE);
 | 
				
			||||||
| 
						 | 
					@ -1393,7 +1407,7 @@ csihandle(void) {
 | 
				
			||||||
			default: goto unknown;
 | 
								default: goto unknown;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			switch(escseq.arg[0]) {
 | 
								switch(csiescseq.arg[0]) {
 | 
				
			||||||
			case 4:
 | 
								case 4:
 | 
				
			||||||
				term.mode |= MODE_INSERT;
 | 
									term.mode |= MODE_INSERT;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -1402,15 +1416,15 @@ csihandle(void) {
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'm': /* SGR -- Terminal attribute (color) */
 | 
						case 'm': /* SGR -- Terminal attribute (color) */
 | 
				
			||||||
		tsetattr(escseq.arg, escseq.narg);
 | 
							tsetattr(csiescseq.arg, csiescseq.narg);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 'r': /* DECSTBM -- Set Scrolling Region */
 | 
						case 'r': /* DECSTBM -- Set Scrolling Region */
 | 
				
			||||||
		if(escseq.priv)
 | 
							if(csiescseq.priv)
 | 
				
			||||||
			goto unknown;
 | 
								goto unknown;
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			DEFAULT(escseq.arg[0], 1);
 | 
								DEFAULT(csiescseq.arg[0], 1);
 | 
				
			||||||
			DEFAULT(escseq.arg[1], term.row);
 | 
								DEFAULT(csiescseq.arg[1], term.row);
 | 
				
			||||||
			tsetscroll(escseq.arg[0]-1, escseq.arg[1]-1);
 | 
								tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1);
 | 
				
			||||||
			tmoveto(0, 0);
 | 
								tmoveto(0, 0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -1427,8 +1441,8 @@ void
 | 
				
			||||||
csidump(void) {
 | 
					csidump(void) {
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	printf("ESC[");
 | 
						printf("ESC[");
 | 
				
			||||||
	for(i = 0; i < escseq.len; i++) {
 | 
						for(i = 0; i < csiescseq.len; i++) {
 | 
				
			||||||
		uint c = escseq.buf[i] & 0xff;
 | 
							uint c = csiescseq.buf[i] & 0xff;
 | 
				
			||||||
		if(isprint(c)) putchar(c);
 | 
							if(isprint(c)) putchar(c);
 | 
				
			||||||
		else if(c == '\n') printf("(\\n)");
 | 
							else if(c == '\n') printf("(\\n)");
 | 
				
			||||||
		else if(c == '\r') printf("(\\r)");
 | 
							else if(c == '\r') printf("(\\r)");
 | 
				
			||||||
| 
						 | 
					@ -1440,7 +1454,80 @@ csidump(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
csireset(void) {
 | 
					csireset(void) {
 | 
				
			||||||
	memset(&escseq, 0, sizeof(escseq));
 | 
						memset(&csiescseq, 0, sizeof(csiescseq));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					strhandle(void) {
 | 
				
			||||||
 | 
						char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = strescseq.buf; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch(strescseq.type) {
 | 
				
			||||||
 | 
						case ']': /* OSC -- Operating System Command */
 | 
				
			||||||
 | 
							switch(p[0]) {
 | 
				
			||||||
 | 
							case '0':
 | 
				
			||||||
 | 
							case '2':
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * TODO: Handle special chars in string, like umlauts.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if(p[1] == ';') {
 | 
				
			||||||
 | 
									if(!strncmp(strescseq.buf, "settitle ", 9)) {
 | 
				
			||||||
 | 
										XStoreName(xw.dpy, xw.win, strescseq.buf+11);	
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										XStoreName(xw.dpy, xw.win, strescseq.buf+2);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case ';':
 | 
				
			||||||
 | 
								XStoreName(xw.dpy, xw.win, strescseq.buf+1);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '4': /* TODO: Set color (arg0) to "rgb:%hexr/$hexg/$hexb" (arg1) */
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								fprintf(stderr, "erresc: unknown str ");
 | 
				
			||||||
 | 
								strdump();
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'P': /* DSC -- Device Control String */
 | 
				
			||||||
 | 
						case '_': /* APC -- Application Program Command */
 | 
				
			||||||
 | 
						case '^': /* PM -- Privacy Message */
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							fprintf(stderr, "erresc: unknown str ");
 | 
				
			||||||
 | 
							strdump();
 | 
				
			||||||
 | 
							/* die(""); */
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					strparse(void) {
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * TODO: Implement parsing like for CSI when required.
 | 
				
			||||||
 | 
						 * Format: ESC type cmd ';' arg0 [';' argn] ESC \
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					strdump(void) {
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						printf("ESC%c", strescseq.type);
 | 
				
			||||||
 | 
						for(i = 0; i < strescseq.len; i++) {
 | 
				
			||||||
 | 
							uint c = strescseq.buf[i] & 0xff;
 | 
				
			||||||
 | 
							if(isprint(c)) putchar(c);
 | 
				
			||||||
 | 
							else if(c == '\n') printf("(\\n)");
 | 
				
			||||||
 | 
							else if(c == '\r') printf("(\\r)");
 | 
				
			||||||
 | 
							else if(c == 0x1b) printf("(\\e)");
 | 
				
			||||||
 | 
							else printf("(%02x)", c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("ESC\\\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					strreset(void) {
 | 
				
			||||||
 | 
						memset(&strescseq, 0, sizeof(strescseq));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -1457,25 +1544,31 @@ tputc(char *c) {
 | 
				
			||||||
	char ascii = *c;
 | 
						char ascii = *c;
 | 
				
			||||||
	if(term.esc & ESC_START) {
 | 
						if(term.esc & ESC_START) {
 | 
				
			||||||
		if(term.esc & ESC_CSI) {
 | 
							if(term.esc & ESC_CSI) {
 | 
				
			||||||
			escseq.buf[escseq.len++] = ascii;
 | 
								csiescseq.buf[csiescseq.len++] = ascii;
 | 
				
			||||||
			if(BETWEEN(ascii, 0x40, 0x7E) || escseq.len >= ESC_BUF_SIZ) {
 | 
								if(BETWEEN(ascii, 0x40, 0x7E) || csiescseq.len >= ESC_BUF_SIZ) {
 | 
				
			||||||
				term.esc = 0;
 | 
									term.esc = 0;
 | 
				
			||||||
				csiparse(), csihandle();
 | 
									csiparse(), csihandle();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			/* TODO: handle other OSC */
 | 
							} else if(term.esc & ESC_STR) {
 | 
				
			||||||
		} else if(term.esc & ESC_OSC) {
 | 
								switch(ascii) {
 | 
				
			||||||
			if(ascii == ';') {
 | 
								case '\033':
 | 
				
			||||||
				term.titlelen = 0;
 | 
									term.esc = ESC_START | ESC_STR_END;
 | 
				
			||||||
				term.esc = ESC_START | ESC_TITLE;
 | 
									break;
 | 
				
			||||||
			}
 | 
								case '\a': /* backwards compatibility to xterm */
 | 
				
			||||||
		} else if(term.esc & ESC_TITLE) {
 | 
					 | 
				
			||||||
			if(ascii == '\a' || term.titlelen+1 >= ESC_TITLE_SIZ) {
 | 
					 | 
				
			||||||
				term.esc = 0;
 | 
									term.esc = 0;
 | 
				
			||||||
				term.title[term.titlelen] = '\0';
 | 
									strhandle();
 | 
				
			||||||
				XStoreName(xw.dpy, xw.win, term.title);
 | 
									break;
 | 
				
			||||||
			} else {
 | 
								default:
 | 
				
			||||||
				term.title[term.titlelen++] = ascii;
 | 
									strescseq.buf[strescseq.len++] = ascii;
 | 
				
			||||||
 | 
									if (strescseq.len+1 >= STR_BUF_SIZ) {
 | 
				
			||||||
 | 
										term.esc = 0;
 | 
				
			||||||
 | 
										strhandle();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else if(term.esc & ESC_STR_END) {
 | 
				
			||||||
 | 
								term.esc = 0;
 | 
				
			||||||
 | 
								if(ascii == '\\')
 | 
				
			||||||
 | 
									strhandle();
 | 
				
			||||||
		} else if(term.esc & ESC_ALTCHARSET) {
 | 
							} else if(term.esc & ESC_ALTCHARSET) {
 | 
				
			||||||
			switch(ascii) {
 | 
								switch(ascii) {
 | 
				
			||||||
			case '0': /* Line drawing crap */
 | 
								case '0': /* Line drawing crap */
 | 
				
			||||||
| 
						 | 
					@ -1493,8 +1586,13 @@ tputc(char *c) {
 | 
				
			||||||
			case '[':
 | 
								case '[':
 | 
				
			||||||
				term.esc |= ESC_CSI;
 | 
									term.esc |= ESC_CSI;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case ']':
 | 
								case 'P': /* DCS -- Device Control String */
 | 
				
			||||||
				term.esc |= ESC_OSC;
 | 
								case '_': /* APC -- Application Program Command */
 | 
				
			||||||
 | 
								case '^': /* PM -- Privacy Message */
 | 
				
			||||||
 | 
								case ']': /* OSC -- Operating System Command */
 | 
				
			||||||
 | 
									strreset();
 | 
				
			||||||
 | 
									strescseq.type = ascii;
 | 
				
			||||||
 | 
									term.esc |= ESC_STR;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case '(':
 | 
								case '(':
 | 
				
			||||||
				term.esc |= ESC_ALTCHARSET;
 | 
									term.esc |= ESC_ALTCHARSET;
 | 
				
			||||||
| 
						 | 
					@ -1541,6 +1639,9 @@ tputc(char *c) {
 | 
				
			||||||
				tcursor(CURSOR_LOAD);
 | 
									tcursor(CURSOR_LOAD);
 | 
				
			||||||
				term.esc = 0;
 | 
									term.esc = 0;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
								case '\\': /* ST -- Stop */
 | 
				
			||||||
 | 
									term.esc = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
 | 
									fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n",
 | 
				
			||||||
				    (uchar) ascii, isprint(ascii)?ascii:'.');
 | 
									    (uchar) ascii, isprint(ascii)?ascii:'.');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue