mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	New input parser via state machine.
This commit is contained in:
		
							
								
								
									
										12
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -1,4 +1,14 @@ | ||||
| 28 September 2007 | ||||
|  | ||||
| * (nicm) Major rewrite of input parser: | ||||
| 	- Lose the old weirdness in favour of a state machine. | ||||
| 	- Merge in parsing from screen.c. | ||||
| 	- Split key parsing off into a separate file. | ||||
|   This is step one towards hopefully allowing a status line. It requires | ||||
|   that we output data as if the terminal had one line less than it really does - | ||||
|   a serious problem when it comes to things like scrolling. This change  | ||||
|   consolidates all the range checking and limiting together which should make | ||||
|   it easier. | ||||
| * (mxey) Added window remaming, like "tmux rename [-s session] [-i index] name" | ||||
|      | ||||
| 27 September 2007 | ||||
| @@ -58,5 +68,5 @@ | ||||
|   (including mutt, emacs). No status bar yet and no key remapping or other | ||||
|   customisation. | ||||
|  | ||||
| $Id: CHANGES,v 1.12 2007-09-28 21:41:51 mxey Exp $ | ||||
| $Id: CHANGES,v 1.13 2007-09-28 22:47:21 nicm Exp $ | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| # $Id: Makefile,v 1.6 2007-09-26 18:32:16 nicm Exp $ | ||||
| # $Id: Makefile,v 1.7 2007-09-28 22:47:21 nicm Exp $ | ||||
|  | ||||
| .SUFFIXES: .c .o .y .h | ||||
| .PHONY: clean | ||||
| @@ -17,8 +17,8 @@ DEBUG= | ||||
| META?= \002 # C-b | ||||
|  | ||||
| SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c \ | ||||
|       xmalloc.c xmalloc-debug.c input.c screen.c window.c session.c local.c \ | ||||
|       log.c client.c client-msg.c client-cmd.c op.c op-list.c | ||||
|       xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c window.c \ | ||||
|       session.c local.c log.c client.c client-msg.c client-cmd.c op.c op-list.c | ||||
|  | ||||
| YACC= yacc -d | ||||
|  | ||||
|   | ||||
							
								
								
									
										78
									
								
								input-keys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								input-keys.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| /* $Id: input-keys.c,v 1.1 2007-09-28 22:47:21 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
|  * copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | ||||
|  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | ||||
|  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "tmux.h" | ||||
|  | ||||
| struct { | ||||
| 	int		 key; | ||||
| 	const char	*data; | ||||
| } input_keys[] = { | ||||
| /*	{ KEYC_BACKSPACE, "\010" }, */ | ||||
| 	{ KEYC_DC,     "\e[3~" }, | ||||
| 	{ KEYC_DOWN,   "\eOB" }, | ||||
| 	{ KEYC_F1,     "\eOP" }, | ||||
| 	{ KEYC_F10,    "\e[21~" }, | ||||
| 	{ KEYC_F11,    "\e[23~" }, | ||||
| 	{ KEYC_F12,    "\e[24~" }, | ||||
| 	{ KEYC_F2,     "\eOQ" }, | ||||
| 	{ KEYC_F3,     "\eOR" }, | ||||
| 	{ KEYC_F4,     "\eOS" }, | ||||
| 	{ KEYC_F5,     "\e[15~" }, | ||||
| 	{ KEYC_F6,     "\e[17~" }, | ||||
| 	{ KEYC_F7,     "\e[18~" }, | ||||
| 	{ KEYC_F8,     "\e[19~" }, | ||||
| 	{ KEYC_F9,     "\e[20~" }, | ||||
| 	{ KEYC_HOME,   "\e[1~" }, | ||||
| 	{ KEYC_IC,     "\e[2~" }, | ||||
| 	{ KEYC_LEFT,   "\eOD" }, | ||||
| 	{ KEYC_LL,     "\e[4~" }, | ||||
| 	{ KEYC_NPAGE,  "\e[6~" }, | ||||
| 	{ KEYC_PPAGE,  "\e[5~" }, | ||||
| 	{ KEYC_RIGHT,  "\eOC" }, | ||||
| 	{ KEYC_UP,     "\eOA" } | ||||
| }; | ||||
| #define NINPUTKEYS (sizeof input_keys / sizeof input_keys[0]) | ||||
|  | ||||
| /* Translate a key code from client into an output key sequence. */ | ||||
| void | ||||
| input_translate_key(struct buffer *b, int key) | ||||
| { | ||||
| 	u_int	i; | ||||
|  | ||||
| 	log_debug2("writing key %d", key); | ||||
| 	if (key != KEYC_NONE && key >= 0) { | ||||
| 		input_store8(b, key); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < NINPUTKEYS; i++) { | ||||
| 		if (input_keys[i].key == key) { | ||||
| 			log_debug2( | ||||
| 			    "found key %d: \"%s\"", key, input_keys[i].data); | ||||
| 			buffer_write( | ||||
| 			    b, input_keys[i].data, strlen(input_keys[i].data)); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										32
									
								
								local.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								local.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* $Id: local.c,v 1.7 2007-09-21 19:24:37 nicm Exp $ */ | ||||
| /* $Id: local.c,v 1.8 2007-09-28 22:47:21 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -310,7 +310,7 @@ local_putc(int c) | ||||
| 	if (c < 0 || c > (int) UCHAR_MAX) | ||||
| 		fatalx("invalid character"); | ||||
|  | ||||
| 	if (debug_level > 1) { | ||||
| 	if (debug_level > 2) { | ||||
| 		f = fopen("tmux-out.log", "a+"); | ||||
| 		fprintf(f, "%c", ch); | ||||
| 		fclose(f); | ||||
| @@ -416,7 +416,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 		switch (ch) { | ||||
| 		case CODE_CURSORUP: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_CURSORUP underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_up_cursor == NULL) { | ||||
| @@ -427,7 +427,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_CURSORDOWN: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_CURSORDOWN underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_down_cursor == NULL) { | ||||
| @@ -438,7 +438,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_CURSORRIGHT: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_CURSORRIGHT underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_right_cursor == NULL) { | ||||
| @@ -449,7 +449,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_CURSORLEFT: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_CURSORLEFT underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_left_cursor == NULL) { | ||||
| @@ -460,7 +460,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_CURSORMOVE: | ||||
| 			if (size < 4) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_CURSORMOVE underflow"); | ||||
| 			size -= 4; | ||||
| 			ua = input_extract16(b); | ||||
| 			ub = input_extract16(b); | ||||
| @@ -507,7 +507,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_INSERTLINE: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_INSERTLINE underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_insert_line == NULL) { | ||||
| @@ -518,7 +518,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_DELETELINE: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_DELETELINE underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_delete_line == NULL) { | ||||
| @@ -529,7 +529,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_INSERTCHARACTER: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_INSERTCHARACTER underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_ich == NULL) { | ||||
| @@ -540,7 +540,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_DELETECHARACTER: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_DELETECHARACTER underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
| 			if (parm_dch == NULL) { | ||||
| @@ -572,7 +572,7 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_SCROLLREGION: | ||||
| 			if (size < 4) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_SCROLLREGION underflow"); | ||||
| 			size -= 4; | ||||
| 			ua = input_extract16(b); | ||||
| 			ub = input_extract16(b); | ||||
| @@ -630,18 +630,18 @@ local_output(struct buffer *b, size_t size) | ||||
| 			break; | ||||
| 		case CODE_TITLE: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_TITLE underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
|  | ||||
| 			if (size < ua) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_TITLE underflow"); | ||||
| 			size -= ua; | ||||
| 			buffer_remove(b, ua); | ||||
| 			break; | ||||
| 		case CODE_ATTRIBUTES: | ||||
| 			if (size < 2) | ||||
| 				fatalx("underflow"); | ||||
| 				fatalx("CODE_ATTRIBUTES underflow"); | ||||
| 			size -= 2; | ||||
| 			ua = input_extract16(b); | ||||
|  | ||||
| @@ -656,7 +656,7 @@ local_output(struct buffer *b, size_t size) | ||||
|  | ||||
| 			while (ua-- != 0) { | ||||
| 				if (size < 2) | ||||
| 					fatalx("underflow"); | ||||
| 					fatalx("CODE_ATTRIBUTES underflow"); | ||||
| 				size -= 2; | ||||
| 				ub = input_extract16(b); | ||||
|  | ||||
|   | ||||
							
								
								
									
										266
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										266
									
								
								screen.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* $Id: screen.c,v 1.11 2007-09-21 19:24:37 nicm Exp $ */ | ||||
| /* $Id: screen.c,v 1.12 2007-09-28 22:47:21 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -35,30 +35,6 @@ void	 screen_make_lines(struct screen *, u_int, u_int); | ||||
| void	 screen_move_lines(struct screen *, u_int, u_int, u_int); | ||||
| void	 screen_fill_lines( | ||||
| 	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| uint16_t screen_extract(u_char *); | ||||
| void	 screen_write_character(struct screen *, u_char); | ||||
| void	 screen_cursor_up_scroll(struct screen *); | ||||
| void	 screen_cursor_down_scroll(struct screen *); | ||||
| void	 screen_scroll_region_up(struct screen *); | ||||
| void	 screen_scroll_region_down(struct screen *); | ||||
| void	 screen_scroll_up(struct screen *, u_int); | ||||
| void	 screen_scroll_down(struct screen *, u_int); | ||||
| void	 screen_fill_screen(struct screen *, u_char, u_char, u_char); | ||||
| void	 screen_fill_line(struct screen *, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_end_of_screen( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_end_of_line( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_start_of_line( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| void	 screen_insert_lines(struct screen *, u_int, u_int); | ||||
| void	 screen_delete_lines(struct screen *, u_int, u_int); | ||||
| void	 screen_insert_characters(struct screen *, u_int, u_int, u_int); | ||||
| void	 screen_delete_characters(struct screen *, u_int, u_int, u_int); | ||||
|  | ||||
| #define SCREEN_DEFDATA ' ' | ||||
| #define SCREEN_DEFATTR 0 | ||||
| #define SCREEN_DEFCOLR 0x88 | ||||
|  | ||||
| #define screen_last_y(s) ((s)->sy - 1) | ||||
| #define screen_last_x(s) ((s)->sx - 1) | ||||
| @@ -380,246 +356,6 @@ screen_fill_lines( | ||||
| 		screen_fill_line(s, i, data, attr, colr); | ||||
| } | ||||
|  | ||||
| /* Update screen with character. */ | ||||
| void | ||||
| screen_character(struct screen *s, u_char ch) | ||||
| { | ||||
| 	switch (ch) { | ||||
| 	case '\n':	/* LF */ | ||||
| 		screen_cursor_down_scroll(s); | ||||
| 		break; | ||||
| 	case '\r':	/* CR */ | ||||
| 		s->cx = 0; | ||||
| 		break; | ||||
| 	case '\010':	/* BS */ | ||||
| 		if (s->cx > 0) | ||||
| 			s->cx--; | ||||
| 		break; | ||||
| 	case '\177':	/* DC */ | ||||
| 		/* XXX */ | ||||
| 		break; | ||||
| 	default: | ||||
| 		if (ch < ' ') | ||||
| 			fatalx("bad control"); | ||||
| 		screen_write_character(s, ch); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Extract 16-bit value from pointer. */ | ||||
| uint16_t | ||||
| screen_extract(u_char *ptr) | ||||
| { | ||||
| 	uint16_t	n; | ||||
|  | ||||
| 	memcpy(&n, ptr, sizeof n); | ||||
| 	return (n); | ||||
| } | ||||
|  | ||||
| /* Update screen with escape sequence. */ | ||||
| void | ||||
| screen_sequence(struct screen *s, u_char *ptr) | ||||
| { | ||||
| 	uint16_t	ua, ub; | ||||
|  | ||||
| 	ptr++; | ||||
| 	log_debug("processing code %hhu", *ptr); | ||||
| 	switch (*ptr++) { | ||||
| 	case CODE_CURSORUP: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		if (ua > s->cy) | ||||
| 			ua = s->cy; | ||||
| 		s->cy -= ua; | ||||
| 		break; | ||||
| 	case CODE_CURSORDOWN: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		if (s->cy + ua > screen_last_y(s)) | ||||
| 			ua = screen_last_y(s) - s->cy; | ||||
| 		s->cy += ua; | ||||
| 		break; | ||||
| 	case CODE_CURSORLEFT: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		if (ua > s->cx) | ||||
| 			ua = s->cx; | ||||
| 		s->cx -= ua; | ||||
| 		break; | ||||
| 	case CODE_CURSORRIGHT: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		if (s->cx + ua > screen_last_x(s)) | ||||
| 			ua = screen_last_x(s) - s->cx; | ||||
| 		s->cx += ua; | ||||
| 		break; | ||||
| 	case CODE_CURSORMOVE: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		ptr += 2; | ||||
| 		ub = screen_extract(ptr); | ||||
| 		if (ub > s->sx) | ||||
| 			ub = s->sx; | ||||
| 		s->cx = ub - 1; | ||||
| 		if (ua > s->sy) | ||||
| 			ua = s->sy; | ||||
| 		s->cy = ua - 1; | ||||
| 		break; | ||||
| 	case CODE_CLEARENDOFSCREEN: | ||||
| 		screen_fill_end_of_screen( | ||||
| 		    s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr); | ||||
| 		break; | ||||
| 	case CODE_CLEARSCREEN: | ||||
| 		screen_fill_screen(s, SCREEN_DEFDATA, s->attr, s->colr); | ||||
| 		break; | ||||
| 	case CODE_CLEARENDOFLINE: | ||||
| 		screen_fill_end_of_line( | ||||
| 		    s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr); | ||||
| 		break; | ||||
| 	case CODE_CLEARSTARTOFLINE: | ||||
| 		screen_fill_start_of_line( | ||||
| 		    s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr); | ||||
| 		break; | ||||
| 	case CODE_CLEARLINE: | ||||
| 		screen_fill_line(s, s->cy, SCREEN_DEFDATA, s->attr, s->colr); | ||||
| 		break; | ||||
| 	case CODE_INSERTLINE: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		screen_insert_lines(s, s->cy, ua); | ||||
| 		break; | ||||
| 	case CODE_DELETELINE: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		screen_delete_lines(s, s->cy, ua); | ||||
| 		break; | ||||
| 	case CODE_INSERTCHARACTER: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		screen_insert_characters(s, s->cx, s->cy, ua); | ||||
| 		break; | ||||
| 	case CODE_DELETECHARACTER: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		screen_delete_characters(s, s->cx, s->cy, ua); | ||||
| 		break; | ||||
| 	case CODE_CURSORON: | ||||
| 		s->mode |= MODE_CURSOR; | ||||
| 		break; | ||||
| 	case CODE_CURSOROFF: | ||||
| 		s->mode &= ~MODE_CURSOR; | ||||
| 		break; | ||||
| 	case CODE_REVERSEINDEX: | ||||
| 		screen_cursor_up_scroll(s); | ||||
| 		break; | ||||
| 	case CODE_SCROLLREGION: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		ptr += 2; | ||||
| 		ub = screen_extract(ptr); | ||||
| 		if (ua > s->sy) | ||||
| 			ua = s->sy; | ||||
| 		s->ry_upper = ua - 1; | ||||
| 		if (ub > s->sy) | ||||
| 			ub = s->sy; | ||||
| 		s->ry_lower = ub - 1; | ||||
| 		break; | ||||
| 	case CODE_INSERTOFF: | ||||
| 		s->mode &= ~MODE_INSERT; | ||||
| 		break; | ||||
| 	case CODE_INSERTON: | ||||
| 		s->mode |= MODE_INSERT; | ||||
| 		break; | ||||
| 	case CODE_KCURSOROFF: | ||||
| 		s->mode &= ~MODE_KCURSOR; | ||||
| 		break; | ||||
| 	case CODE_KCURSORON: | ||||
| 		s->mode |= MODE_KCURSOR; | ||||
| 		break; | ||||
| 	case CODE_KKEYPADOFF: | ||||
| 		s->mode &= ~MODE_KKEYPAD; | ||||
| 		break; | ||||
| 	case CODE_KKEYPADON: | ||||
| 		s->mode |= MODE_KKEYPAD; | ||||
| 		break; | ||||
| 	case CODE_TITLE: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		ptr += 2; | ||||
| 		log_debug("new title: %u:%.*s", ua, (int) ua, ptr); | ||||
| 		if (ua > (sizeof s->title) - 1) | ||||
| 			ua = (sizeof s->title) - 1; | ||||
| 		memcpy(s->title, ptr, ua); | ||||
| 		s->title[ua] = '\0'; | ||||
| 		break; | ||||
| 	case CODE_ATTRIBUTES: | ||||
| 		ua = screen_extract(ptr); | ||||
| 		if (ua == 0) { | ||||
| 			s->attr = 0; | ||||
| 			s->colr = SCREEN_DEFCOLR; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		while (ua-- > 0) { | ||||
| 			ptr += 2; | ||||
| 			ub = screen_extract(ptr); | ||||
| 			switch (ub) { | ||||
| 			case 0: | ||||
| 			case 10: | ||||
| 				s->attr = 0; | ||||
| 				s->colr = SCREEN_DEFCOLR; | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				s->attr |= ATTR_BRIGHT; | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				s->attr |= ATTR_DIM; | ||||
| 				break; | ||||
| 			case 3: | ||||
| 				s->attr |= ATTR_ITALICS; | ||||
| 				break; | ||||
| 			case 4: | ||||
| 				s->attr |= ATTR_UNDERSCORE; | ||||
| 				break; | ||||
| 			case 5: | ||||
| 				s->attr |= ATTR_BLINK; | ||||
| 				break; | ||||
| 			case 7: | ||||
| 				s->attr |= ATTR_REVERSE; | ||||
| 				break; | ||||
| 			case 8: | ||||
| 				s->attr |= ATTR_HIDDEN; | ||||
| 				break; | ||||
| 			case 23: | ||||
| 				s->attr &= ~ATTR_ITALICS; | ||||
| 				break; | ||||
| 			case 24: | ||||
| 				s->attr &= ~ATTR_UNDERSCORE; | ||||
| 				break; | ||||
| 			case 30: | ||||
| 			case 31: | ||||
| 			case 32: | ||||
| 			case 33: | ||||
| 			case 34: | ||||
| 			case 35: | ||||
| 			case 36: | ||||
| 			case 37: | ||||
| 				s->colr &= 0x0f; | ||||
| 				s->colr |= (ub - 30) << 4; | ||||
| 				break; | ||||
| 			case 39: | ||||
| 				s->colr &= 0x0f; | ||||
| 				s->colr |= 0x80; | ||||
| 				break; | ||||
| 			case 40: | ||||
| 			case 41: | ||||
| 			case 42: | ||||
| 			case 43: | ||||
| 			case 44: | ||||
| 			case 45: | ||||
| 			case 46: | ||||
| 			case 47: | ||||
| 				s->colr &= 0xf0; | ||||
| 				s->colr |= ub - 40; | ||||
| 				break; | ||||
| 			case 49: | ||||
| 				s->colr &= 0xf0; | ||||
| 				s->colr |= 0x08; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* Write a single character to the screen at the cursor and move forward. */ | ||||
| void | ||||
| screen_write_character(struct screen *s, u_char ch) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| /* $Id: server-msg.c,v 1.7 2007-09-28 21:41:52 mxey Exp $ */ | ||||
| /* $Id: server-msg.c,v 1.8 2007-09-28 22:47:21 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -390,13 +390,12 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c) | ||||
| 	struct window	       *w; | ||||
| 	struct session	       *s; | ||||
|  | ||||
|  | ||||
| 	if (hdr->size != sizeof data) | ||||
| 		fatalx("bad MSG_RENAME size"); | ||||
|  | ||||
| 	buffer_read(c->in, &data, hdr->size); | ||||
|  | ||||
| 	data.newname[sizeof data.newname] = '\0'; | ||||
| 	data.newname[(sizeof data.newname) - 1] = '\0'; | ||||
| 	 | ||||
| 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | ||||
| 		/* XXX: Send message to client */ | ||||
|   | ||||
							
								
								
									
										77
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* $Id: tmux.h,v 1.20 2007-09-28 21:41:52 mxey Exp $ */ | ||||
| /* $Id: tmux.h,v 1.21 2007-09-28 22:47:21 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -391,6 +391,50 @@ struct screen { | ||||
| 	int		 mode; | ||||
| }; | ||||
|  | ||||
| /* Screen default contents. */ | ||||
| #define SCREEN_DEFDATA ' ' | ||||
| #define SCREEN_DEFATTR 0 | ||||
| #define SCREEN_DEFCOLR 0x88 | ||||
|  | ||||
| /* Input parser sequence argument. */ | ||||
| struct input_arg { | ||||
| 	size_t		 off; | ||||
| 	size_t		 len; | ||||
| }; | ||||
|  | ||||
| /* Input character classes. */ | ||||
| enum input_class { | ||||
| 	INPUT_C0CONTROL, | ||||
| 	INPUT_SPACE, | ||||
| 	INPUT_INTERMEDIATE, | ||||
| 	INPUT_PARAMETER, | ||||
| 	INPUT_UPPERCASE, | ||||
| 	INPUT_LOWERCASE, | ||||
| 	INPUT_DELETE, | ||||
| 	INPUT_C1CONTROL, | ||||
| 	INPUT_G1DISPLAYABLE, | ||||
| 	INPUT_SPECIAL | ||||
| }; | ||||
|  | ||||
| /* Input parser context. */ | ||||
| struct input_ctx { | ||||
| 	u_char		*buf; | ||||
| 	size_t		 len; | ||||
| 	size_t		 off; | ||||
|  | ||||
| 	struct buffer	*b; | ||||
| 	struct screen	*s; | ||||
|  | ||||
| 	void 		*(*state)(u_char, enum input_class, struct input_ctx *); | ||||
|  | ||||
| 	size_t		 intoff; | ||||
| 	size_t		 intlen; | ||||
|  | ||||
| 	size_t		 saved; | ||||
| 	u_char		 private; | ||||
| 	ARRAY_DECL(, struct input_arg) args; | ||||
| }; | ||||
|  | ||||
| /* Window structure. */ | ||||
| struct window { | ||||
| 	char		 name[MAXNAMELEN]; | ||||
| @@ -401,6 +445,8 @@ struct window { | ||||
|  | ||||
| 	u_int		 references; | ||||
|  | ||||
| 	struct input_ctx ictx; | ||||
|  | ||||
| 	struct screen	 screen; | ||||
| }; | ||||
| ARRAY_DECL(windows, struct window *); | ||||
| @@ -492,8 +538,9 @@ void	 server_window_changed(struct client *); | ||||
| void	 server_draw_client(struct client *, u_int, u_int); | ||||
|  | ||||
| /* input.c */ | ||||
| void	 input_key(struct buffer *, int); | ||||
| size_t	 input_parse(u_char *, size_t, struct buffer *, struct screen *); | ||||
| void	 input_init(struct input_ctx *, struct screen *); | ||||
| void	 input_free(struct input_ctx *); | ||||
| size_t	 input_parse(struct input_ctx *, u_char *, size_t, struct buffer *); | ||||
| uint8_t  input_extract8(struct buffer *); | ||||
| uint16_t input_extract16(struct buffer *); | ||||
| void	 input_store8(struct buffer *, uint8_t); | ||||
| @@ -502,12 +549,32 @@ void	 input_store_zero(struct buffer *, u_char); | ||||
| void	 input_store_one(struct buffer *, u_char, uint16_t); | ||||
| void	 input_store_two(struct buffer *, u_char, uint16_t, uint16_t); | ||||
|  | ||||
| /* input-key.c */ | ||||
| void	 input_translate_key(struct buffer *, int); | ||||
|  | ||||
| /* screen.c */ | ||||
| void	 screen_create(struct screen *, u_int, u_int); | ||||
| void	 screen_resize(struct screen *, u_int, u_int); | ||||
| void	 screen_draw(struct screen *, struct buffer *, u_int, u_int); | ||||
| void	 screen_character(struct screen *, u_char); | ||||
| void 	 screen_sequence(struct screen *, u_char *); | ||||
| void	 screen_write_character(struct screen *, u_char); | ||||
| void	 screen_insert_lines(struct screen *, u_int, u_int); | ||||
| void	 screen_delete_lines(struct screen *, u_int, u_int); | ||||
| void	 screen_insert_characters(struct screen *, u_int, u_int, u_int); | ||||
| void	 screen_delete_characters(struct screen *, u_int, u_int, u_int); | ||||
| void	 screen_cursor_up_scroll(struct screen *); | ||||
| void	 screen_cursor_down_scroll(struct screen *); | ||||
| void	 screen_scroll_region_up(struct screen *); | ||||
| void	 screen_scroll_region_down(struct screen *); | ||||
| void	 screen_scroll_up(struct screen *, u_int); | ||||
| void	 screen_scroll_down(struct screen *, u_int); | ||||
| void	 screen_fill_screen(struct screen *, u_char, u_char, u_char); | ||||
| void	 screen_fill_line(struct screen *, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_end_of_screen( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_end_of_line( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
| void	 screen_fill_start_of_line( | ||||
|     	     struct screen *, u_int, u_int, u_char, u_char, u_char); | ||||
|  | ||||
| /* local.c */ | ||||
| int	 local_init(struct buffer **, struct buffer **); | ||||
|   | ||||
							
								
								
									
										10
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								window.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| /* $Id: window.c,v 1.11 2007-09-27 09:15:58 nicm Exp $ */ | ||||
| /* $Id: window.c,v 1.12 2007-09-28 22:47:22 nicm Exp $ */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||
| @@ -102,6 +102,7 @@ window_create(const char *cmd, const char **environ, u_int sx, u_int sy) | ||||
| 	w->in = buffer_create(BUFSIZ); | ||||
| 	w->out = buffer_create(BUFSIZ); | ||||
| 	screen_create(&w->screen, sx, sy); | ||||
| 	input_init(&w->ictx, &w->screen); | ||||
|  | ||||
| 	name = xstrdup(cmd); | ||||
| 	if ((ptr = strchr(name, ' ')) != NULL) { | ||||
| @@ -175,6 +176,8 @@ window_destroy(struct window *w) | ||||
| { | ||||
| 	close(w->fd); | ||||
|  | ||||
| 	input_free(&w->ictx); | ||||
|  | ||||
| 	buffer_destroy(w->in); | ||||
| 	buffer_destroy(w->out); | ||||
| 	xfree(w); | ||||
| @@ -300,7 +303,7 @@ window_input(struct window *w, struct buffer *b, size_t size) | ||||
| 			size -= 2; | ||||
| 			key = (int16_t) input_extract16(b); | ||||
| 		} | ||||
| 		input_key(w->out, key); | ||||
| 		input_translate_key(w->out, key); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -313,8 +316,7 @@ window_output(struct window *w, struct buffer *b) | ||||
| { | ||||
| 	size_t	used; | ||||
|  | ||||
| 	used = input_parse( | ||||
| 	    BUFFER_OUT(w->in), BUFFER_USED(w->in), b, &w->screen); | ||||
| 	used = input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b); | ||||
| 	if (used != 0) | ||||
| 		buffer_remove(w->in, used); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott