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:
		
							
								
								
									
										14
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -1,5 +1,15 @@ | |||||||
| 28 September 2007 | 28 September 2007 | ||||||
|  * (mxey) Added window remaming, like "tmux rename [-s session] [-i index] name" |  | ||||||
|  | * (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 | 27 September 2007 | ||||||
|  |  | ||||||
| @@ -58,5 +68,5 @@ | |||||||
|   (including mutt, emacs). No status bar yet and no key remapping or other |   (including mutt, emacs). No status bar yet and no key remapping or other | ||||||
|   customisation. |   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 | .SUFFIXES: .c .o .y .h | ||||||
| .PHONY: clean | .PHONY: clean | ||||||
| @@ -17,8 +17,8 @@ DEBUG= | |||||||
| META?= \002 # C-b | META?= \002 # C-b | ||||||
|  |  | ||||||
| SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c \ | 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 \ |       xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c window.c \ | ||||||
|       log.c client.c client-msg.c client-cmd.c op.c op-list.c |       session.c local.c log.c client.c client-msg.c client-cmd.c op.c op-list.c | ||||||
|  |  | ||||||
| YACC= yacc -d | 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> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -310,7 +310,7 @@ local_putc(int c) | |||||||
| 	if (c < 0 || c > (int) UCHAR_MAX) | 	if (c < 0 || c > (int) UCHAR_MAX) | ||||||
| 		fatalx("invalid character"); | 		fatalx("invalid character"); | ||||||
|  |  | ||||||
| 	if (debug_level > 1) { | 	if (debug_level > 2) { | ||||||
| 		f = fopen("tmux-out.log", "a+"); | 		f = fopen("tmux-out.log", "a+"); | ||||||
| 		fprintf(f, "%c", ch); | 		fprintf(f, "%c", ch); | ||||||
| 		fclose(f); | 		fclose(f); | ||||||
| @@ -416,7 +416,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 		switch (ch) { | 		switch (ch) { | ||||||
| 		case CODE_CURSORUP: | 		case CODE_CURSORUP: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_CURSORUP underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_up_cursor == NULL) { | 			if (parm_up_cursor == NULL) { | ||||||
| @@ -427,7 +427,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_CURSORDOWN: | 		case CODE_CURSORDOWN: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_CURSORDOWN underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_down_cursor == NULL) { | 			if (parm_down_cursor == NULL) { | ||||||
| @@ -438,7 +438,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_CURSORRIGHT: | 		case CODE_CURSORRIGHT: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_CURSORRIGHT underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_right_cursor == NULL) { | 			if (parm_right_cursor == NULL) { | ||||||
| @@ -449,7 +449,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_CURSORLEFT: | 		case CODE_CURSORLEFT: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_CURSORLEFT underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_left_cursor == NULL) { | 			if (parm_left_cursor == NULL) { | ||||||
| @@ -460,7 +460,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_CURSORMOVE: | 		case CODE_CURSORMOVE: | ||||||
| 			if (size < 4) | 			if (size < 4) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_CURSORMOVE underflow"); | ||||||
| 			size -= 4; | 			size -= 4; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			ub = input_extract16(b); | 			ub = input_extract16(b); | ||||||
| @@ -507,7 +507,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_INSERTLINE: | 		case CODE_INSERTLINE: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_INSERTLINE underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_insert_line == NULL) { | 			if (parm_insert_line == NULL) { | ||||||
| @@ -518,7 +518,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_DELETELINE: | 		case CODE_DELETELINE: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_DELETELINE underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_delete_line == NULL) { | 			if (parm_delete_line == NULL) { | ||||||
| @@ -529,7 +529,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_INSERTCHARACTER: | 		case CODE_INSERTCHARACTER: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_INSERTCHARACTER underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_ich == NULL) { | 			if (parm_ich == NULL) { | ||||||
| @@ -540,7 +540,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_DELETECHARACTER: | 		case CODE_DELETECHARACTER: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_DELETECHARACTER underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			if (parm_dch == NULL) { | 			if (parm_dch == NULL) { | ||||||
| @@ -572,7 +572,7 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_SCROLLREGION: | 		case CODE_SCROLLREGION: | ||||||
| 			if (size < 4) | 			if (size < 4) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_SCROLLREGION underflow"); | ||||||
| 			size -= 4; | 			size -= 4; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
| 			ub = input_extract16(b); | 			ub = input_extract16(b); | ||||||
| @@ -630,18 +630,18 @@ local_output(struct buffer *b, size_t size) | |||||||
| 			break; | 			break; | ||||||
| 		case CODE_TITLE: | 		case CODE_TITLE: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_TITLE underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
|  |  | ||||||
| 			if (size < ua) | 			if (size < ua) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_TITLE underflow"); | ||||||
| 			size -= ua; | 			size -= ua; | ||||||
| 			buffer_remove(b, ua); | 			buffer_remove(b, ua); | ||||||
| 			break; | 			break; | ||||||
| 		case CODE_ATTRIBUTES: | 		case CODE_ATTRIBUTES: | ||||||
| 			if (size < 2) | 			if (size < 2) | ||||||
| 				fatalx("underflow"); | 				fatalx("CODE_ATTRIBUTES underflow"); | ||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			ua = input_extract16(b); | 			ua = input_extract16(b); | ||||||
|  |  | ||||||
| @@ -656,7 +656,7 @@ local_output(struct buffer *b, size_t size) | |||||||
|  |  | ||||||
| 			while (ua-- != 0) { | 			while (ua-- != 0) { | ||||||
| 				if (size < 2) | 				if (size < 2) | ||||||
| 					fatalx("underflow"); | 					fatalx("CODE_ATTRIBUTES underflow"); | ||||||
| 				size -= 2; | 				size -= 2; | ||||||
| 				ub = input_extract16(b); | 				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> |  * 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_move_lines(struct screen *, u_int, u_int, u_int); | ||||||
| void	 screen_fill_lines( | void	 screen_fill_lines( | ||||||
| 	     struct screen *, u_int, u_int, u_char, u_char, u_char); | 	     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_y(s) ((s)->sy - 1) | ||||||
| #define screen_last_x(s) ((s)->sx - 1) | #define screen_last_x(s) ((s)->sx - 1) | ||||||
| @@ -380,246 +356,6 @@ screen_fill_lines( | |||||||
| 		screen_fill_line(s, i, data, attr, colr); | 		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. */ | /* Write a single character to the screen at the cursor and move forward. */ | ||||||
| void | void | ||||||
| screen_write_character(struct screen *s, u_char ch) | 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> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -389,14 +389,13 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c) | |||||||
| 	char                   *cause; | 	char                   *cause; | ||||||
| 	struct window	       *w; | 	struct window	       *w; | ||||||
| 	struct session	       *s; | 	struct session	       *s; | ||||||
| 	 |  | ||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_RENAME size"); | 		fatalx("bad MSG_RENAME size"); | ||||||
|  |  | ||||||
| 	buffer_read(c->in, &data, hdr->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) { | 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | ||||||
| 		/* XXX: Send message to client */ | 		/* 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> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -391,6 +391,50 @@ struct screen { | |||||||
| 	int		 mode; | 	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. */ | /* Window structure. */ | ||||||
| struct window { | struct window { | ||||||
| 	char		 name[MAXNAMELEN]; | 	char		 name[MAXNAMELEN]; | ||||||
| @@ -401,6 +445,8 @@ struct window { | |||||||
|  |  | ||||||
| 	u_int		 references; | 	u_int		 references; | ||||||
|  |  | ||||||
|  | 	struct input_ctx ictx; | ||||||
|  |  | ||||||
| 	struct screen	 screen; | 	struct screen	 screen; | ||||||
| }; | }; | ||||||
| ARRAY_DECL(windows, struct window *); | 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); | void	 server_draw_client(struct client *, u_int, u_int); | ||||||
|  |  | ||||||
| /* input.c */ | /* input.c */ | ||||||
| void	 input_key(struct buffer *, int); | void	 input_init(struct input_ctx *, struct screen *); | ||||||
| size_t	 input_parse(u_char *, size_t, struct buffer *, 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 *); | uint8_t  input_extract8(struct buffer *); | ||||||
| uint16_t input_extract16(struct buffer *); | uint16_t input_extract16(struct buffer *); | ||||||
| void	 input_store8(struct buffer *, uint8_t); | 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_one(struct buffer *, u_char, uint16_t); | ||||||
| void	 input_store_two(struct buffer *, u_char, uint16_t, 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 */ | /* screen.c */ | ||||||
| void	 screen_create(struct screen *, u_int, u_int); | void	 screen_create(struct screen *, u_int, u_int); | ||||||
| void	 screen_resize(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_draw(struct screen *, struct buffer *, u_int, u_int); | ||||||
| void	 screen_character(struct screen *, u_char); | void	 screen_write_character(struct screen *, u_char); | ||||||
| void 	 screen_sequence(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 */ | /* local.c */ | ||||||
| int	 local_init(struct buffer **, struct buffer **); | 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> |  * 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->in = buffer_create(BUFSIZ); | ||||||
| 	w->out = buffer_create(BUFSIZ); | 	w->out = buffer_create(BUFSIZ); | ||||||
| 	screen_create(&w->screen, sx, sy); | 	screen_create(&w->screen, sx, sy); | ||||||
|  | 	input_init(&w->ictx, &w->screen); | ||||||
|  |  | ||||||
| 	name = xstrdup(cmd); | 	name = xstrdup(cmd); | ||||||
| 	if ((ptr = strchr(name, ' ')) != NULL) { | 	if ((ptr = strchr(name, ' ')) != NULL) { | ||||||
| @@ -175,6 +176,8 @@ window_destroy(struct window *w) | |||||||
| { | { | ||||||
| 	close(w->fd); | 	close(w->fd); | ||||||
|  |  | ||||||
|  | 	input_free(&w->ictx); | ||||||
|  |  | ||||||
| 	buffer_destroy(w->in); | 	buffer_destroy(w->in); | ||||||
| 	buffer_destroy(w->out); | 	buffer_destroy(w->out); | ||||||
| 	xfree(w); | 	xfree(w); | ||||||
| @@ -300,7 +303,7 @@ window_input(struct window *w, struct buffer *b, size_t size) | |||||||
| 			size -= 2; | 			size -= 2; | ||||||
| 			key = (int16_t) input_extract16(b); | 			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; | 	size_t	used; | ||||||
|  |  | ||||||
| 	used = input_parse( | 	used = input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b); | ||||||
| 	    BUFFER_OUT(w->in), BUFFER_USED(w->in), b, &w->screen); |  | ||||||
| 	if (used != 0) | 	if (used != 0) | ||||||
| 		buffer_remove(w->in, used); | 		buffer_remove(w->in, used); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott