core: fix input of wide UTF-8 chars under Cygwin (bug #34061)

This commit is contained in:
Sebastien Helleu 2011-08-18 17:30:18 +02:00
parent 223e7f8452
commit 27afc1e7d2
2 changed files with 119 additions and 131 deletions

View File

@ -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

View File

@ -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)
if (gui_mouse_event_pending || (key < 32) || (key == 127))
{
insert_ok = 0;
key_str[0] = (char) key;
key_str[1] = '\0';
}
else if (key < 32)
{
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[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;
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)
(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]);
key_str[2] = '\0';
}
else
key_str[1] = '\0';
}
/* 3 chars: 1110vvvv 10vvvvvv 10vvvvvv */
else if ((key & 0xF0) == 0xE0)
{
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)
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))
if (key_str[0])
{
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);
}
hook_signal_send ("key_pressed",
WEECHAT_HOOK_SIGNAL_STRING, key_str);
/* 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 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))
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)))
{
/*
* do not search text in buffer, just alert about text not
* found
* 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 (CONFIG_BOOLEAN(config_look_search_text_not_found_alert))
printf ("\a");
}
else
{
gui_window_search_restart (gui_current_window);
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 ();