improvements to wide/multibyte character input and output, using wide
curses functions where applicable
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2182 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
diff --git a/src/winio.c b/src/winio.c
index c3b0ec9..18cfd93 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -122,7 +122,7 @@
* default keystroke buffer is empty. */
void get_buffer(WINDOW *win)
{
- int input;
+ int input, input_key_code;
/* If the keystroke buffer isn't empty, get out. */
if (key_buffer != NULL)
@@ -134,19 +134,36 @@
#ifndef NANO_SMALL
allow_pending_sigwinch(TRUE);
#endif
- input = wgetch(win);
+
+#ifdef NANO_WIDE
+ if (!ISSET(NO_UTF8)) {
+ wint_t tmp;
+
+ input_key_code = wget_wch(win, &tmp);
+ input = (int)tmp;
+ } else {
+#endif
+ input = wgetch(win);
+ input_key_code = !is_byte_char(input);
+#ifdef NANO_WIDE
+ }
+#endif
+
#ifndef NANO_SMALL
allow_pending_sigwinch(FALSE);
#endif
/* Increment the length of the keystroke buffer, save the value of
* the keystroke in key, and set key_code to TRUE if the keystroke
- * is an extended keypad value and hence shouldn't be treated as a
- * multibyte character. */
+ * is an extended keypad value or FALSE if it isn't. */
key_buffer_len++;
key_buffer = (buffer *)nmalloc(sizeof(buffer));
key_buffer[0].key = input;
- key_buffer[0].key_code = !is_byte_char(input);
+ key_buffer[0].key_code =
+#ifdef NANO_WIDE
+ !ISSET(NO_UTF8) ? (input_key_code == KEY_CODE_YES) :
+#endif
+ input_key_code;
/* Read in the remaining characters using non-blocking input. */
nodelay(win, TRUE);
@@ -155,73 +172,49 @@
#ifndef NANO_SMALL
allow_pending_sigwinch(TRUE);
#endif
- input = wgetch(win);
-#ifndef NANO_SMALL
- allow_pending_sigwinch(FALSE);
-#endif
+#ifdef NANO_WIDE
+ if (!ISSET(NO_UTF8)) {
+ wint_t tmp;
+
+ input_key_code = wget_wch(win, &tmp);
+ input = (int)tmp;
+ } else {
+#endif
+ input = wgetch(win);
+ input_key_code = !is_byte_char(input);
+#ifdef NANO_WIDE
+ }
+#endif
/* If there aren't any more characters, stop reading. */
- if (input == ERR)
+ if (
+#ifdef NANO_WIDE
+ (!ISSET(NO_UTF8) && input_key_code == ERR) ||
+#endif
+ input == ERR)
break;
/* Otherwise, increment the length of the keystroke buffer, save
* the value of the keystroke in key, and set key_code to TRUE
- * if the keystroke is an extended keypad value and hence
- * shouldn't be treated as a multibyte character. */
+ * if the keystroke is an extended keypad value or FALSE if it
+ * isn't. */
key_buffer_len++;
key_buffer = (buffer *)nrealloc(key_buffer, key_buffer_len *
sizeof(buffer));
key_buffer[key_buffer_len - 1].key = input;
- key_buffer[key_buffer_len - 1].key_code = !is_byte_char(input);
+ key_buffer[key_buffer_len - 1].key_code =
+#ifdef NANO_WIDE
+ !ISSET(NO_UTF8) ? (input_key_code == KEY_CODE_YES) :
+#endif
+ input_key_code;
+
+#ifndef NANO_SMALL
+ allow_pending_sigwinch(FALSE);
+#endif
}
/* Switch back to non-blocking input. */
nodelay(win, FALSE);
-
-#ifdef NANO_WIDE
- if (!ISSET(NO_UTF8)) {
- size_t i;
- buffer *clean_key_buffer = NULL;
- size_t clean_key_buffer_len = 0;
-
- mbtowc(NULL, NULL, 0);
-
- /* Change all complete and valid multibyte keystrokes to
- * their wide character values, discarding the others. */
- for (i = 0; i < key_buffer_len; i++) {
- wchar_t wide_key;
- int wide_key_len;
-
- if (key_buffer[i].key_code) {
- mbtowc(NULL, NULL, 0);
-
- wide_key_len = 1;
- wide_key = key_buffer[i].key;
- } else
- wide_key_len = mbtowc(&wide_key,
- (const char *)&key_buffer[i].key, 1);
-
- if (wide_key_len != -1) {
- clean_key_buffer_len++;
- clean_key_buffer = (buffer *)nrealloc(clean_key_buffer,
- clean_key_buffer_len * sizeof(buffer));
-
- clean_key_buffer[clean_key_buffer_len - 1].key =
- (int)wide_key;
- clean_key_buffer[clean_key_buffer_len - 1].key_code =
- key_buffer[i].key_code;
- }
- }
-
- mbtowc(NULL, NULL, 0);
-
- /* Replace the default keystroke buffer with the non-(-1)
- * keystroke buffer. */
- key_buffer_len = clean_key_buffer_len;
- free(key_buffer);
- key_buffer = clean_key_buffer;
- }
-#endif
}
/* Return the length of the default keystroke buffer. */
@@ -258,12 +251,10 @@
#ifdef NANO_WIDE
if (!ISSET(NO_UTF8)) {
size_t i;
-
- wctomb(NULL, 0);
+ char *key = charalloc(MB_CUR_MAX);
/* Keep all valid wide keystrokes, discarding the others. */
for (i = 0; i < input_len; i++) {
- char key[MB_LEN_MAX];
int key_len = input[i].key_code ? 1 :
wctomb(key, (wchar_t)input[i].key);
@@ -278,8 +269,7 @@
}
}
- wctomb(NULL, 0);
-
+ free(key);
} else {
#endif
clean_input = input;