diff --git a/ChangeLog b/ChangeLog
index 39a4f04fae6996e2f5fa2ab090ee9e0750106d56..6fc29c9d2e5964611f6a20d7056d61be1819830f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,21 +34,20 @@ CVS code -
 	  properly again. (DLR, found by Arthur Ivanov)
 	- Massively overhaul the input and output routines to support
 	  buffered input and output, the first steps toward
-	  wide/multibyte character input and output, and
-	  double-Escape/verbatim input of double-byte Unicode characters
-	  instead of single-byte ASCII characters.  New functions
-	  is_byte_char(), get_buffer(), get_buffer_len(),
-	  buffer_to_keys(), unget_input(), get_input(), parse_kbinput(),
-	  and parse_verbatim_kbinput(); new macro charcpy(); changes to
-	  do_char() (renamed to do_output()), get_edit_input() (renamed
-	  to do_input() and moved to nano.c), get_edit_mouse() (renamed
-	  do_mouse() and moved to nano.c), do_verbatim_input(),
-	  do_tab(), main(), and get_ascii_kbinput() (renamed to
-	  get_word_kbinput()).  The wide version of ncurses is required
-	  in order for wide/multibyte input and output to work properly.
-	  (DLR; buffered input/output based on ideas from mutt 1.4.2.1;
-	  double-Escape input of Unicode characters suggested by Michael
-	  Piefel)
+	  wide/multibyte character input and output, and verbatim input
+	  of double-byte Unicode characters instead of single-byte ASCII
+	  characters.  New functions is_byte_char(), get_buffer(),
+	  get_buffer_len(), buffer_to_keys(), unget_input(),
+	  get_input(), parse_kbinput(), and parse_verbatim_kbinput();
+	  new macro charcpy(); changes to do_char() (renamed to
+	  do_output()), get_edit_input() (renamed to do_input() and
+	  moved to nano.c), get_edit_mouse() (renamed do_mouse() and
+	  moved to nano.c), do_verbatim_input(), do_tab(), main(), and
+	  get_ascii_kbinput() (renamed to get_word_kbinput()).  The wide
+	  version of ncurses is required in order for wide/multibyte
+	  input and output to work properly. (DLR; buffered input/output
+	  based on ideas from mutt 1.4.2.1; input of Unicode characters
+	  in hexadecimal suggested by Michael Piefel)
 	- More steps toward wide character/multibyte character support.
 	  Movement and cursor display in the edit window should now work
 	  properly with files containing multibyte characters, and text
@@ -190,7 +189,8 @@ CVS code -
 	- Typo fixes. (DLR)
 - doc/faq.html:
 	- Remove now-inaccurate note about verbatim input's not working
-	  at prompts. (DLR)
+	  at prompts, and update its description to mention that it
+	  handles hexadecimal values now. (DLR)
 - doc/nanorc.sample:
 	- Add return to the "c-file" regexes. (DLR)
 
diff --git a/doc/faq.html b/doc/faq.html
index fa7a55db4f4cfd77f2004f85f349359db9623a2f..906f6bd84c1a9238c90df2a86f8746164ed2156a 100644
--- a/doc/faq.html
+++ b/doc/faq.html
@@ -166,7 +166,7 @@
   <p>You can move between the buffers you have open with the <b>Meta-&lt;</b> and <b>Meta-&gt;</b> keys, or more easily with <b>Meta-,</b> and <b>Meta-.</b> (clear as mud, right? =-). When you have more than one file buffer open, the ^X shortcut will say &quot;Close&quot;, instead of the normal &quot;Exit&quot; when only one buffer is open.</p></blockquote>
 <h2><a name="3.8"></a>3.8. Tell me more about this verbatim input stuff!</h2>
 <blockquote><p>To use verbatim input, you must be using nano 1.3.1 or newer. When you want to insert a literal character into the file you're editing, such as a control character that nano usually treats as a command, first press <b>Meta-V</b>. (If you're not at a prompt, you'll get the message &quot;Verbatim input&quot;.) Then press the key(s) that generate the character you want.</p>
-  <p>Alternatively, you can press <b>Meta-V</b> and then type a three-digit ASCII code from 000 to 255, and the character with that ASCII code will be inserted instead.</p></blockquote>
+  <p>Alternatively, you can press <b>Meta-V</b> and then type a four-digit hexadecimal code from 0000 to ffff (case-insensitive), and the character with the corresponding value will be inserted instead.</p></blockquote>
 <h2><a name="3.9"></a>3.9. How do I make a .nanorc file that nano will read when I start it?</h2>
 <blockquote><p>It's not hard at all! But, your version of nano must have been compiled with <b>--enable-nanorc</b>, and again must be version 1.1.12 or newer (use nano -V to check your version and compiled features). Then simply copy the <b>nanorc.sample</b> that came with the nano source or your nano package (most likely in /usr/doc/nano) to .nanorc in your home directory. If you didn't get one, the syntax is simple. Flags are turned on and off by using the word <b>set</b> and the getopt_long flag for the feature, for example &quot;set nowrap&quot; or &quot;set suspend&quot;.</p></blockquote>
 <hr width="100%">
@@ -244,7 +244,7 @@
 <h2><a name="8"></a>8. ChangeLog</h2>
 <blockquote>
 <p>
-2005/01/02 - Remove now-inaccurate note about verbatim input's not working at prompts. (DLR)
+2005/01/03 - Remove now-inaccurate note about verbatim input's not working at prompts, and update its description to mention that it handles hexadecimal values now. (DLR)
 2004/11/21 - List sh as an example of a Bourne shell. (DLR)
 2004/11/05 - Fixed inaccuracy: Pico compatibility mode was made the default in nano 1.1.99pre1, not 1.2.2. Also added question about how to type F13-F16 on terminals lacking keys past F12 (suggested by Chris), question about how to select text for the clipboard in X terminals with nano's mouse support turned on (answer found by Joseph Birthisel), and misc. fixes and link updates. (DLR)<br>
 2004/04/07 - Removed NumLock glitch question, as it's no longer needed. (DLR)<br>
diff --git a/src/nano.c b/src/nano.c
index 866e7ecf61247c215a8f38b7677ddcaa304b6464..021d3097abc4e0278fd78f13d46afbc6dabd9fc7 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -372,9 +372,9 @@ void help_init(void)
 	  "(M) symbol and can be entered using either the Esc, Alt or "
 	  "Meta key depending on your keyboard setup.  Also, pressing Esc "
 	  "twice and then typing a three-digit number from 000 to 255 "
-	  "will enter the character with the corresponding ASCII code.  "
-	  "The following keystrokes are available in the main editor "
-	  "window.  Alternative keys are shown in parentheses:\n\n");
+	  "will enter the character with the corresponding value.  The "
+	  "following keystrokes are available in the main editor window.  "
+	  "Alternative keys are shown in parentheses:\n\n");
 
     htx = _(htx);
 
diff --git a/src/proto.h b/src/proto.h
index bd6fd72abba10f5739af697cd98ec8ea432f561b..6801d0a6c935b7f1a0d9a1815c9022abd1a3e82b 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -555,6 +555,11 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 int get_escape_seq_kbinput(const int *sequence, size_t seq_len, bool
 	*ignore_seq);
 int get_escape_seq_abcd(int kbinput);
+int get_byte_kbinput(int kbinput
+#ifndef NANO_SMALL
+	, bool reset
+#endif
+	);
 int get_word_kbinput(int kbinput
 #ifndef NANO_SMALL
 	, bool reset
diff --git a/src/winio.c b/src/winio.c
index 79e2f16e0b96f422c843e5572b35832e10d82b35..a4df2577cc29cc2a67ec68b767491c2425bd5fb3 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -121,6 +121,7 @@ static bool resetstatuspos = FALSE;
 void reset_kbinput(void)
 {
     parse_kbinput(NULL, NULL, NULL, TRUE);
+    get_byte_kbinput(0, TRUE);
     get_word_kbinput(0, TRUE);
 }
 #endif
@@ -439,14 +440,14 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 	)
 
 {
-    static int escapes = 0, word_digits = 0;
+    static int escapes = 0, byte_digits = 0;
     buffer *kbinput;
     int retval = ERR;
 
 #ifndef NANO_SMALL
     if (reset) {
 	escapes = 0;
-	word_digits = 0;
+	byte_digits = 0;
 	return ERR;
     }
 #endif
@@ -646,48 +647,47 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 			break;
 		    case 2:
 			/* Two escapes followed by one or more decimal
-			 * digits: word sequence mode.  If the word
-			 * sequence's range is limited to 6XXXX (the
-			 * first digit is in the '0' to '6' range and
-			 * it's the first digit, or it's in the '0' to
-			 * '9' range and it's not the first digit),
-			 * increment the word sequence counter and
-			 * interpret the digit.  If the word sequence's
-			 * range is not limited to 6XXXX, fall
-			 * through. */
+			 * digits: byte sequence mode.  If the word
+			 * sequence's range is limited to 2XX (the first
+			 * digit is in the '0' to '2' range and it's the
+			 * first digit, or it's in the '0' to '9' range
+			 * and it's not the first digit), increment the
+			 * byte sequence counter and interpret the
+			 * digit.  If the byte sequence's range is not
+			 * limited to 2XX, fall through. */
 			if (('0' <= kbinput->key && kbinput->key <= '6'
-				&& word_digits == 0) ||
+				&& byte_digits == 0) ||
 				('0' <= kbinput->key && kbinput->key <= '9'
-				&& word_digits > 0)) {
-			    int word_kbinput;
+				&& byte_digits > 0)) {
+			    int byte_kbinput;
 
-			    word_digits++;
-			    word_kbinput = get_word_kbinput(kbinput->key
+			    byte_digits++;
+			    byte_kbinput = get_byte_kbinput(kbinput->key
 #ifndef NANO_SMALL
 				, FALSE
 #endif
 				);
 
-			    if (word_kbinput != ERR) {
-				/* If we've read in a complete word
-				 * sequence, reset the word sequence
+			    if (byte_kbinput != ERR) {
+				/* If we've read in a complete byte
+				 * sequence, reset the byte sequence
 				 * counter and the escape counter,
-				 * and put back the corresponding word
+				 * and put back the corresponding byte
 				 * value. */
-				word_digits = 0;
+				byte_digits = 0;
 				escapes = 0;
-				unget_kbinput(word_kbinput, FALSE,
+				unget_kbinput(byte_kbinput, FALSE,
 					FALSE);
 			    }
 			} else {
 			    /* Reset the escape counter. */
 			    escapes = 0;
-			    if (word_digits == 0)
+			    if (byte_digits == 0)
 				/* Two escapes followed by a non-decimal
 				 * digit or a decimal digit that would
-				 * create a word sequence greater than
-				 * 6XXXX, and we're not in the middle of
-				 * a word sequence: control character
+				 * create a byte sequence greater than
+				 * 2XX, and we're not in the middle of a
+				 * byte sequence: control character
 				 * sequence mode.  Interpret the control
 				 * sequence and save the corresponding
 				 * control character as the result. */
@@ -697,7 +697,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 				 * sequence, reset the word sequence
 				 * counter and save the character we got
 				 * as the result. */
-				word_digits = 0;
+				byte_digits = 0;
 				retval = kbinput->key;
 			    }
 			}
@@ -715,7 +715,7 @@ int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key
 	retval = kbinput->key;
 
 #ifdef DEBUG
-    fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, word_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, word_digits, retval);
+    fprintf(stderr, "parse_kbinput(): kbinput->key = %d, meta_key = %d, func_key = %d, escapes = %d, byte_digits = %d, retval = %d\n", kbinput->key, (int)*meta_key, (int)*func_key, escapes, byte_digits, retval);
 #endif
 
     /* Return the result. */
@@ -1250,98 +1250,174 @@ int get_escape_seq_abcd(int kbinput)
     }
 }
 
-/* Translate a word sequence: turn a five-digit decimal number from
- * 00000 to 65535 into its corresponding word value. */
-int get_word_kbinput(int kbinput
+/* Translate a byte sequence: turn a three-digit decimal number from
+ * 000 to 255 into its corresponding byte value. */
+int get_byte_kbinput(int kbinput
 #ifndef NANO_SMALL
 	, bool reset
 #endif
 	)
 {
-    static int word_digits = 0, word_kbinput = 0;
+    static int byte_digits = 0, byte_kbinput = 0;
     int retval = ERR;
 
 #ifndef NANO_SMALL
     if (reset) {
-	word_digits = 0;
-	word_kbinput = 0;
+	byte_digits = 0;
+	byte_kbinput = 0;
 	return ERR;
     }
 #endif
 
-    /* Increment the word digit counter. */
-    word_digits++;
+    /* Increment the byte digit counter. */
+    byte_digits++;
 
-    switch (word_digits) {
+    switch (byte_digits) {
 	case 1:
-	    /* One digit: reset the word sequence holder and add the
-	     * digit we got to the 10000's position of the word sequence
+	    /* One digit: reset the byte sequence holder and add the
+	     * digit we got to the 100's position of the byte sequence
 	     * holder. */
-	    word_kbinput = 0;
-	    if ('0' <= kbinput && kbinput <= '6')
-		word_kbinput += (kbinput - '0') * 10000;
+	    byte_kbinput = 0;
+	    if ('0' <= kbinput && kbinput <= '2')
+		byte_kbinput += (kbinput - '0') * 100;
 	    else
 		/* If the character we got isn't a decimal digit, or if
-		 * it is and it would put the word sequence out of word
+		 * it is and it would put the byte sequence out of byte
 		 * range, save it as the result. */
 		retval = kbinput;
 	    break;
 	case 2:
-	    /* Two digits: add the digit we got to the 1000's position
-	     * of the word sequence holder. */
+	    /* Two digits: add the digit we got to the 10's position of
+	     * the byte sequence holder. */
 	    if (('0' <= kbinput && kbinput <= '5') ||
-		(word_kbinput < 60000 && '6' <= kbinput &&
+		(byte_kbinput < 200 && '6' <= kbinput &&
 		kbinput <= '9'))
-		word_kbinput += (kbinput - '0') * 1000;
+		byte_kbinput += (kbinput - '0') * 10;
 	    else
 		/* If the character we got isn't a decimal digit, or if
-		 * it is and it would put the word sequence out of word
+		 * it is and it would put the byte sequence out of byte
 		 * range, save it as the result. */
 		retval = kbinput;
 	    break;
 	case 3:
-	    /* Three digits: add the digit we got to the 100's position
-	     * of the word sequence holder. */
+	    /* Three digits: add the digit we got to the 1's position of
+	     * the byte sequence holder, and save the corresponding word
+	     * value as the result. */
 	    if (('0' <= kbinput && kbinput <= '5') ||
-		(word_kbinput < 65000 && '6' <= kbinput &&
-		kbinput <= '9'))
-		word_kbinput += (kbinput - '0') * 100;
-	    else
+		(byte_kbinput < 250 && '6' <= kbinput &&
+		kbinput <= '9')) {
+		byte_kbinput += (kbinput - '0');
+		retval = byte_kbinput;
+	    } else
 		/* If the character we got isn't a decimal digit, or if
 		 * it is and it would put the word sequence out of word
 		 * range, save it as the result. */
 		retval = kbinput;
 	    break;
-	case 4:
-	    /* Four digits: add the digit we got to the 10's position of
+	default:
+	    /* More than three digits: save the character we got as the
+	     * result. */
+	    retval = kbinput;
+	    break;
+    }
+
+    /* If we have a result, reset the byte digit counter and the byte
+     * sequence holder. */
+    if (retval != ERR) {
+	byte_digits = 0;
+	byte_kbinput = 0;
+    }
+
+#ifdef DEBUG
+    fprintf(stderr, "get_byte_kbinput(): kbinput = %d, byte_digits = %d, byte_kbinput = %d, retval = %d\n", kbinput, byte_digits, byte_kbinput, retval);
+#endif
+
+    return retval;
+}
+
+/* Translate a word sequence: turn a four-digit hexadecimal number from
+ * 0000 to ffff (case-insensitive) into its corresponding word value. */
+int get_word_kbinput(int kbinput
+#ifndef NANO_SMALL
+	, bool reset
+#endif
+	)
+{
+    static int word_digits = 0, word_kbinput = 0;
+    int retval = ERR;
+
+#ifndef NANO_SMALL
+    if (reset) {
+	word_digits = 0;
+	word_kbinput = 0;
+	return ERR;
+    }
+#endif
+
+    /* Increment the word digit counter. */
+    word_digits++;
+
+    switch (word_digits) {
+	case 1:
+	    /* One digit: reset the word sequence holder and add the
+	     * digit we got to the 4096's position of the word sequence
+	     * holder. */
+	    word_kbinput = 0;
+	    if ('0' <= kbinput && kbinput <= '9')
+		word_kbinput += (kbinput - '0') * 4096;
+	    else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f')
+		word_kbinput += (tolower(kbinput) + 10 - 'a') * 4096;
+	    else
+		/* If the character we got isn't a hexadecimal digit, or
+		 * if it is and it would put the word sequence out of
+		 * word range, save it as the result. */
+		retval = kbinput;
+	    break;
+	case 2:
+	    /* Two digits: add the digit we got to the 256's position of
 	     * the word sequence holder. */
-	    if (('0' <= kbinput && kbinput <= '3') ||
-		(word_kbinput < 65500 && '4' <= kbinput &&
-		kbinput <= '9'))
-		word_kbinput += (kbinput - '0') * 10;
+	    if ('0' <= kbinput && kbinput <= '9')
+		word_kbinput += (kbinput - '0') * 256;
+	    else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f')
+		word_kbinput += (tolower(kbinput) + 10 - 'a') * 256;
 	    else
-		/* If the character we got isn't a decimal digit, or if
-		 * it is and it would put the word sequence out of word
-		 * range, save it as the result. */
+		/* If the character we got isn't a hexadecimal digit, or
+		 * if it is and it would put the word sequence out of
+		 * word range, save it as the result. */
 		retval = kbinput;
 	    break;
-	case 5:
-	    /* Five digits: add the digit we got to the 1's position of
+	case 3:
+	    /* Three digits: add the digit we got to the 16's position
+	     * of the word sequence holder. */
+	    if ('0' <= kbinput && kbinput <= '9')
+		word_kbinput += (kbinput - '0') * 16;
+	    else if ('a' <= tolower(kbinput) && tolower(kbinput) <= 'f')
+		word_kbinput += (tolower(kbinput) + 10 - 'a') * 16;
+	    else
+		/* If the character we got isn't a hexadecimal digit, or
+		 * if it is and it would put the word sequence out of
+		 * word range, save it as the result. */
+		retval = kbinput;
+	    break;
+	case 4:
+	    /* Four digits: add the digit we got to the 1's position of
 	     * the word sequence holder, and save the corresponding word
 	     * value as the result. */
-	    if (('0' <= kbinput && kbinput <= '5') ||
-		(word_kbinput < 65530 && '6' <= kbinput &&
-		kbinput <= '9')) {
+	    if ('0' <= kbinput && kbinput <= '9') {
 		word_kbinput += (kbinput - '0');
 		retval = word_kbinput;
+	    } else if ('a' <= tolower(kbinput) &&
+		tolower(kbinput) <= 'f') {
+		word_kbinput += (tolower(kbinput) + 10 - 'a');
+		retval = word_kbinput;
 	    } else
-		/* If the character we got isn't a decimal digit, or if
-		 * it is and it would put the word sequence out of word
-		 * range, save it as the result. */
+		/* If the character we got isn't a hexadecimal digit, or
+		 * if it is and it would put the word sequence out of
+		 * word range, save it as the result. */
 		retval = kbinput;
 	    break;
 	default:
-	    /* More than three digits: save the character we got as the
+	    /* More than four digits: save the character we got as the
 	     * result. */
 	    retval = kbinput;
 	    break;
@@ -1444,15 +1520,15 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len)
     /* Read in the first keystroke. */
     while ((kbinput = get_input(win, 1)) == NULL);
 
-    /* Check whether the first keystroke is a decimal digit. */
+    /* Check whether the first keystroke is a hexadecimal digit. */
     word = get_word_kbinput(kbinput->key
 #ifndef NANO_SMALL
 	, FALSE
 #endif
 	);
 
-    /* If the first keystroke isn't a decimal digit, put back the first
-     * keystroke. */
+    /* If the first keystroke isn't a hexadecimal digit, put back the
+     * first keystroke. */
     if (word != ERR)
 	unget_input(kbinput, 1);
     /* Otherwise, read in keystrokes until we have a complete word