summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-08-18 17:30:18 +0200
committerSebastien Helleu <flashcode@flashtux.org>2011-08-18 17:30:18 +0200
commit27afc1e7d25b9e260b5d03ef19576397fb63204d (patch)
tree87fa42316071077f8b6e4f3b268a1ebc6d1208c4
parent223e7f845261d8b33f0d4b37a0b518f8674d2eb7 (diff)
downloadweechat-27afc1e7d25b9e260b5d03ef19576397fb63204d.zip
core: fix input of wide UTF-8 chars under Cygwin (bug #34061)
-rw-r--r--ChangeLog3
-rw-r--r--src/gui/curses/gui-curses-key.c247
2 files changed, 119 insertions, 131 deletions
diff --git a/ChangeLog b/ChangeLog
index 10628a57a..f215202fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,13 @@
WeeChat ChangeLog
=================
Sébastien Helleu <flashcode@flashtux.org>
-v0.3.6-dev, 2011-08-17
+v0.3.6-dev, 2011-08-18
Version 0.3.6 (under dev!)
--------------------------
+* core: fix input of wide UTF-8 chars under Cygwin (bug #34061)
* core: allow name of buffer for command /buffer clear (task #11269)
* core: add new command /repeat (execute a command several times)
* core: save and restore layout for buffers and windows on /upgrade
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c
index 9a96275b0..7c21b1f7f 100644
--- a/src/gui/curses/gui-curses-key.c
+++ b/src/gui/curses/gui-curses-key.c
@@ -287,7 +287,10 @@ void
gui_key_flush ()
{
int i, key, insert_ok;
- char key_str[32], *key_utf, *input_old;
+ static char key_str[64] = { '\0' };
+ static int length_key_str = 0;
+ char key_temp[2], *key_utf, *input_old, *ptr_char, *next_char, *ptr_error;
+ char utf_partial_char[16];
/*
* if there's no paste pending, then we use buffer and do actions
@@ -301,164 +304,148 @@ gui_key_flush ()
for (i = 0; i < gui_key_buffer_size; i++)
{
key = gui_key_buffer[i];
-
insert_ok = 1;
+ utf_partial_char[0] = '\0';
- if (gui_mouse_event_pending)
- {
- insert_ok = 0;
- key_str[0] = (char) key;
- key_str[1] = '\0';
- }
- else if (key < 32)
+ if (gui_mouse_event_pending || (key < 32) || (key == 127))
{
- insert_ok = 0;
- key_str[0] = '\x01';
- key_str[1] = (char) key + '@';
- key_str[2] = '\0';
- }
- else if (key == 127)
- {
- key_str[0] = '\x01';
- key_str[1] = '?';
- key_str[2] = '\0';
+ if (gui_mouse_event_pending)
+ {
+ insert_ok = 0;
+ key_str[0] = (char)key;
+ key_str[1] = '\0';
+ length_key_str = 1;
+ }
+ else if (key < 32)
+ {
+ insert_ok = 0;
+ key_str[0] = '\x01';
+ key_str[1] = (char)key + '@';
+ key_str[2] = '\0';
+ length_key_str = 2;
+ }
+ else if (key == 127)
+ {
+ key_str[0] = '\x01';
+ key_str[1] = '?';
+ key_str[2] = '\0';
+ length_key_str = 2;
+ }
}
else
{
if (local_utf8)
{
- /* 1 char: 0vvvvvvv */
- if (key < 0x80)
- {
- key_str[0] = (char) key;
- key_str[1] = '\0';
- }
- /* 2 chars: 110vvvvv 10vvvvvv */
- else if ((key & 0xE0) == 0xC0)
- {
- key_str[0] = (char) key;
- if (i < gui_key_buffer_size - 1)
- {
- key_str[1] = (char) (gui_key_buffer[++i]);
- key_str[2] = '\0';
- }
- else
- key_str[1] = '\0';
- }
- /* 3 chars: 1110vvvv 10vvvvvv 10vvvvvv */
- else if ((key & 0xF0) == 0xE0)
+ key_str[length_key_str] = (char)key;
+ key_str[length_key_str + 1] = '\0';
+ length_key_str++;
+
+ /*
+ * replace invalid chars by "?", but NOT last char of
+ * string, if it is incomplete UTF-8 char (another char
+ * will be added to the string on next iteration)
+ */
+ ptr_char = key_str;
+ while (ptr_char && ptr_char[0])
{
- key_str[0] = (char) key;
- if (i < gui_key_buffer_size - 1)
+ (void) utf8_is_valid (ptr_char, &ptr_error);
+ if (!ptr_error)
+ break;
+ next_char = utf8_next_char (ptr_error);
+ if (next_char && next_char[0])
{
- key_str[1] = (char) (gui_key_buffer[++i]);
- if (i < gui_key_buffer_size - 1)
+ ptr_char = ptr_error;
+ while (ptr_char < next_char)
{
- key_str[2] = (char) (gui_key_buffer[++i]);
- key_str[3] = '\0';
+ ptr_char[0] = '?';
+ ptr_char++;
}
- else
- key_str[2] = '\0';
}
else
- key_str[1] = '\0';
- }
- /* 4 chars: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */
- else if ((key & 0xF8) == 0xF0)
- {
- key_str[0] = (char) key;
- if (i < gui_key_buffer_size - 1)
{
- key_str[1] = (char) (gui_key_buffer[++i]);
- if (i < gui_key_buffer_size - 1)
- {
- key_str[2] = (char) (gui_key_buffer[++i]);
- if (i < gui_key_buffer_size - 1)
- {
- key_str[3] = (char) (gui_key_buffer[++i]);
- key_str[4] = '\0';
- }
- else
- key_str[3] = '\0';
- }
- else
- key_str[2] = '\0';
+ strcpy (utf_partial_char, ptr_char);
+ ptr_char[0] = '\0';
+ break;
}
- else
- key_str[1] = '\0';
+ ptr_char = next_char;
}
}
else
{
- key_str[0] = (char) key;
- key_str[1] = '\0';
-
- /* convert input to UTF-8 is user is not using UTF-8 as locale */
- if (!local_utf8)
- {
- key_utf = string_iconv_to_internal (NULL, key_str);
- strncpy (key_str, key_utf, sizeof (key_str));
- key_str[sizeof (key_str) - 1] = '\0';
- }
+ /* convert input to UTF-8 */
+ key_temp[0] = (char) key;
+ key_temp[1] = '\0';
+ key_utf = string_iconv_to_internal (NULL, key_temp);
+ strcat (key_str, key_utf);
}
}
-
- hook_signal_send ("key_pressed",
- WEECHAT_HOOK_SIGNAL_STRING, key_str);
-
- if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
- input_old = (gui_current_window->buffer->input_buffer) ?
- strdup (gui_current_window->buffer->input_buffer) : strdup ("");
- else
- input_old = NULL;
-
- if ((gui_key_pressed (key_str) != 0) && (insert_ok)
- && (!gui_cursor_mode))
- {
- gui_buffer_undo_snap (gui_current_window->buffer);
- gui_input_insert_string (gui_current_window->buffer,
- key_str, -1);
- if (gui_current_window->buffer->completion)
- gui_completion_stop (gui_current_window->buffer->completion, 0);
- gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1);
- }
-
- /* incremental text search in buffer */
- if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
- && ((input_old == NULL)
- || (gui_current_window->buffer->input_buffer == NULL)
- || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0)))
+
+ if (key_str[0])
{
- /*
- * if current input is longer than old input, and that
- * beginning of current input is exactly equal to old input,
- * then do nothing (search will not find any result and can
- * take some time on buffer with many lines..)
- */
- if (!gui_current_window->buffer->text_search_found
- && (input_old != NULL)
- && (input_old[0])
- && (gui_current_window->buffer->input_buffer != NULL)
- && (gui_current_window->buffer->input_buffer[0])
- && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old))
- && (strncmp (gui_current_window->buffer->input_buffer, input_old,
- strlen (input_old)) == 0))
+ hook_signal_send ("key_pressed",
+ WEECHAT_HOOK_SIGNAL_STRING, key_str);
+
+ if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
+ input_old = (gui_current_window->buffer->input_buffer) ?
+ strdup (gui_current_window->buffer->input_buffer) : strdup ("");
+ else
+ input_old = NULL;
+
+ if ((gui_key_pressed (key_str) != 0) && (insert_ok)
+ && (!gui_cursor_mode))
{
- /*
- * do not search text in buffer, just alert about text not
- * found
- */
- if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert))
- printf ("\a");
+ gui_buffer_undo_snap (gui_current_window->buffer);
+ gui_input_insert_string (gui_current_window->buffer,
+ key_str, -1);
+ if (gui_current_window->buffer->completion)
+ gui_completion_stop (gui_current_window->buffer->completion, 0);
+ gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1);
}
- else
+
+ /* incremental text search in buffer */
+ if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
+ && ((input_old == NULL)
+ || (gui_current_window->buffer->input_buffer == NULL)
+ || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0)))
{
- gui_window_search_restart (gui_current_window);
+ /*
+ * if current input is longer than old input, and that
+ * beginning of current input is exactly equal to old input,
+ * then do nothing (search will not find any result and can
+ * take some time on buffer with many lines..)
+ */
+ if (!gui_current_window->buffer->text_search_found
+ && (input_old != NULL)
+ && (input_old[0])
+ && (gui_current_window->buffer->input_buffer != NULL)
+ && (gui_current_window->buffer->input_buffer[0])
+ && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old))
+ && (strncmp (gui_current_window->buffer->input_buffer, input_old,
+ strlen (input_old)) == 0))
+ {
+ /*
+ * do not search text in buffer, just alert about text not
+ * found
+ */
+ if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert))
+ printf ("\a");
+ }
+ else
+ {
+ gui_window_search_restart (gui_current_window);
+ }
}
+
+ if (input_old)
+ free (input_old);
}
- if (input_old)
- free (input_old);
+ /* prepare incomplete UTF-8 char for next iteration */
+ if (utf_partial_char[0])
+ strcpy (key_str, utf_partial_char);
+ else
+ key_str[0] = '\0';
+ length_key_str = strlen (key_str);
}
gui_key_buffer_reset ();