diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/mdb/common/mdb/mdb_termio.c | 79 | 
1 files changed, 69 insertions, 10 deletions
| diff --git a/usr/src/cmd/mdb/common/mdb/mdb_termio.c b/usr/src/cmd/mdb/common/mdb/mdb_termio.c index 5e36cda7ad..5818150e6b 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_termio.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_termio.c @@ -26,7 +26,7 @@  /*   * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Copyright 2015 Joyent, Inc.   */  /* @@ -93,8 +93,23 @@  #define	KEY_ESC	(0x01b)			/* Escape key code */  #define	KEY_DEL (0x07f)			/* ASCII DEL key code */ -#define	META(c)	((c) | 0x080)		/* Convert 'x' to 'M-x' */ -#define	KPAD(c) ((c) | 0x100)		/* Convert 'x' to 'ESC-[-x' */ +/* + * These macros support the use of various ranges within the "tio_keymap" + * member of "termio_data_t" objects.  This array maps from an input byte, or + * special control code, to the appropriate terminal handling callback.  The + * array has KEY_MAX (0x1ff) entries, partitioned as follows: + * + *     0 -  7f		7-bit ASCII byte + *    80 -  ff	META()	ASCII byte with Meta key modifier + *   100 - 119	KPAD()	Alphabetic character received as part of a single-byte + *			cursor control sequence, e.g. ESC [ A + *   11a - 123	FKEY()	Numeric character received as part of a function key + *			control sequence, e.g. ESC [ 4 ~ + *   124 - 1ff		Unused + */ +#define	META(c)		(((c) & 0x7f) | 0x80) +#define	KPAD(c)		(((c) < 'A' || (c) > 'Z') ? 0 : ((c) - 'A' + 0x100)) +#define	FKEY(c)		(((c) < '0' || (c) > '9') ? 0 : ((c) - '0' + 0x11a))  /*   * These macros allow for composition of control sequences for xterm and other @@ -202,7 +217,7 @@ typedef struct termio_data {  	mdb_iob_t *tio_out;		/* I/o buffer for terminal output */  	mdb_iob_t *tio_in;		/* I/o buffer for terminal input */  	mdb_iob_t *tio_link;		/* I/o buffer to resize on WINCH */ -	keycb_t tio_keymap[KEY_MAX];	/* Keymap (callback functions) */ +	keycb_t tio_keymap[KEY_MAX];	/* Keymap (see comments atop file) */  	mdb_cmdbuf_t tio_cmdbuf;	/* Editable command-line buffer */  	struct termios tio_ptios;	/* Parent terminal settings */  	struct termios tio_ctios;	/* Child terminal settings */ @@ -385,7 +400,7 @@ termio_read(mdb_io_t *io, void *buf, size_t nbytes)  	mdb_bool_t esc = FALSE, pad = FALSE;  	ssize_t rlen = 0; -	int c; +	int c, fkey = 0;  	const char *s;  	size_t len; @@ -471,8 +486,42 @@ char_loop:  		}  		if (pad) { -			c = KPAD(CTRL(c));  			pad = FALSE; + +			if ((fkey = FKEY(c)) != 0) { +				/* +				 * Some terminals send a multibyte control +				 * sequence for particular function keys. +				 * These sequences are of the form: +				 * +				 *	ESC [ n ~ +				 * +				 * where "n" is a numeric character from +				 * '0' to '9'. +				 */ +				goto char_loop; +			} + +			if ((c = KPAD(c)) == 0) { +				/* +				 * This was not a valid keypad control +				 * sequence. +				 */ +				goto char_loop; +			} +		} + +		if (fkey != 0) { +			if (c == '~') { +				/* +				 * This is a valid special function key +				 * sequence.  Use the value we stashed +				 * earlier. +				 */ +				c = fkey; +			} + +			fkey = 0;  		}  		len = td->tio_cmdbuf.cmd_buflen + td->tio_promptlen; @@ -1486,10 +1535,20 @@ mdb_termio_create(const char *name, mdb_io_t *rio, mdb_io_t *wio)  	td->tio_keymap[CTRL('d')] = termio_delchar;  	td->tio_keymap[CTRL('?')] = termio_widescreen; -	td->tio_keymap[KPAD(CTRL('A'))] = termio_prevhist; -	td->tio_keymap[KPAD(CTRL('B'))] = termio_nexthist; -	td->tio_keymap[KPAD(CTRL('C'))] = termio_fwdchar; -	td->tio_keymap[KPAD(CTRL('D'))] = termio_backchar; +	td->tio_keymap[KPAD('A')] = termio_prevhist; +	td->tio_keymap[KPAD('B')] = termio_nexthist; +	td->tio_keymap[KPAD('C')] = termio_fwdchar; +	td->tio_keymap[KPAD('D')] = termio_backchar; + +	/* +	 * Many modern terminal emulators treat the "Home" and "End" keys on a +	 * PC keyboard as cursor keys.  Some others use a multibyte function +	 * key control sequence.  We handle both styles here: +	 */ +	td->tio_keymap[KPAD('H')] = termio_home; +	td->tio_keymap[FKEY('1')] = termio_home; +	td->tio_keymap[KPAD('F')] = termio_end; +	td->tio_keymap[FKEY('4')] = termio_end;  	/*  	 * We default both ASCII BS and DEL to termio_backspace for safety.  We | 
