summaryrefslogtreecommitdiff
path: root/src/gui/curses
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2006-05-08 13:26:08 +0000
committerSebastien Helleu <flashcode@flashtux.org>2006-05-08 13:26:08 +0000
commit93e69f5b3efec9ddc9198e7bb4d5f06af19bad28 (patch)
treea08da159aaad979702e350a5dae21c77683437a7 /src/gui/curses
parentbeb846884c0699220009cde0749f4e2f7590de3e (diff)
downloadweechat-93e69f5b3efec9ddc9198e7bb4d5f06af19bad28.zip
Fixed UTF-8 display bug with chars using more than one cell on screen (bug #16356)
Diffstat (limited to 'src/gui/curses')
-rw-r--r--src/gui/curses/gui-curses-chat.c40
-rw-r--r--src/gui/curses/gui-curses-input.c40
2 files changed, 57 insertions, 23 deletions
diff --git a/src/gui/curses/gui-curses-chat.c b/src/gui/curses/gui-curses-chat.c
index 45f73bfc8..e1d8d3e94 100644
--- a/src/gui/curses/gui-curses-chat.c
+++ b/src/gui/curses/gui-curses-chat.c
@@ -246,10 +246,14 @@ gui_chat_display_new_line (t_gui_window *window, int num_lines, int count,
*/
char *
-gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string, int apply_style)
+gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string,
+ int apply_style, int *width_screen)
{
- char str_fg[3], str_bg[3];
- int fg, bg, weechat_color;
+ char str_fg[3], str_bg[3], utf_char[16];
+ int fg, bg, weechat_color, char_size;
+
+ if (width_screen)
+ *width_screen = 0;
while (string[0])
{
@@ -399,7 +403,16 @@ gui_chat_word_get_next_char (t_gui_window *window, unsigned char *string, int ap
if (string[0] < 32)
string++;
else
- return utf8_next_char ((char *)string);
+ {
+ char_size = utf8_char_size ((char *) string);
+ if (width_screen)
+ {
+ memcpy (utf_char, string, char_size);
+ utf_char[char_size] = '\0';
+ *width_screen = utf8_width_screen (utf_char);
+ }
+ return (char *)string + char_size;
+ }
}
}
@@ -424,7 +437,7 @@ gui_chat_display_word_raw (t_gui_window *window, char *string)
while (string && string[0])
{
- next_char = gui_chat_word_get_next_char (window, (unsigned char *)string, 1);
+ next_char = gui_chat_word_get_next_char (window, (unsigned char *)string, 1, NULL);
if (!next_char)
return;
@@ -447,10 +460,10 @@ gui_chat_display_word_raw (t_gui_window *window, char *string)
void
gui_chat_display_word (t_gui_window *window,
- t_gui_line *line,
- char *data,
- char *end_offset,
- int num_lines, int count, int *lines_displayed, int simulate)
+ t_gui_line *line,
+ char *data,
+ char *end_offset,
+ int num_lines, int count, int *lines_displayed, int simulate)
{
char *end_line, saved_char_end, saved_char;
int pos_saved_char, chars_to_display, num_displayed;
@@ -557,7 +570,7 @@ gui_chat_get_word_info (t_gui_window *window,
leading_spaces = 1;
while (data && data[0])
{
- next_char = gui_chat_word_get_next_char (window, (unsigned char *)data, 0);
+ next_char = gui_chat_word_get_next_char (window, (unsigned char *)data, 0, NULL);
if (next_char)
{
prev_char = utf8_prev_char (data, next_char);
@@ -676,7 +689,9 @@ gui_chat_display_line (t_gui_window *window, t_gui_line *line, int count,
saved_char = ptr_data[word_start_offset];
ptr_data[word_start_offset] = '\0';
ptr_style = ptr_data;
- while ((ptr_style = gui_chat_word_get_next_char (window, (unsigned char *)ptr_style, 1)) != NULL)
+ while ((ptr_style = gui_chat_word_get_next_char (window,
+ (unsigned char *)ptr_style,
+ 1, NULL)) != NULL)
{
/* loop until no style/char available */
}
@@ -705,7 +720,8 @@ gui_chat_display_line (t_gui_window *window, t_gui_line *line, int count,
while (ptr_data && (ptr_data[0] == ' '))
{
next_char = gui_chat_word_get_next_char (window,
- (unsigned char *)ptr_data, 0);
+ (unsigned char *)ptr_data,
+ 0, NULL);
if (!next_char)
break;
prev_char = utf8_prev_char (ptr_data, next_char);
diff --git a/src/gui/curses/gui-curses-input.c b/src/gui/curses/gui-curses-input.c
index f6ed316f1..54aaa4c2b 100644
--- a/src/gui/curses/gui-curses-input.c
+++ b/src/gui/curses/gui-curses-input.c
@@ -67,14 +67,14 @@ gui_input_set_color (t_gui_window *window, int irc_color)
}
/*
- * gui_input_get_prompt_length: return input prompt length
+ * gui_input_get_prompt_length: return input prompt length (displayed on screen)
*/
int
gui_input_get_prompt_length (t_gui_window *window, char *nick)
{
- char *pos, *modes;
- int length, mode_found;
+ char *pos, saved_char, *modes;
+ int char_size, length, mode_found;
length = 0;
pos = cfg_look_input_format;
@@ -134,8 +134,12 @@ gui_input_get_prompt_length (t_gui_window *window, char *nick)
}
break;
default:
- length++;
- pos += utf8_char_size (pos);
+ char_size = utf8_char_size (pos);
+ saved_char = pos[char_size];
+ pos[char_size] = '\0';
+ length += utf8_width_screen (pos);
+ pos[char_size] = saved_char;
+ pos += char_size;
break;
}
}
@@ -144,6 +148,8 @@ gui_input_get_prompt_length (t_gui_window *window, char *nick)
/*
* gui_input_draw_prompt: display input prompt
+ * return: # chars displayed on screen (one UTF-8 char
+ * may be displayed on more than 1 char on screen)
*/
void
@@ -250,18 +256,23 @@ gui_input_draw_prompt (t_gui_window *window, char *nick)
/*
* gui_input_draw_text: display text in input buffer, according to color mask
+ * return: offset for cursor position on screen (one UTF-8
+ * char may be displayed on more than 1 char on screen)
*/
-void
+int
gui_input_draw_text (t_gui_window *window, int input_width)
{
char *ptr_start, *ptr_next, saved_char;
- int pos_mask, size, last_color, color;
+ int pos_mask, size, last_color, color, count_cursor, offset_cursor;
ptr_start = utf8_add_offset (window->buffer->input_buffer,
window->buffer->input_buffer_1st_display);
pos_mask = ptr_start - window->buffer->input_buffer;
last_color = -1;
+ count_cursor = window->buffer->input_buffer_pos -
+ window->buffer->input_buffer_1st_display;
+ offset_cursor = 0;
while ((input_width > 0) && ptr_start && ptr_start[0])
{
ptr_next = utf8_next_char (ptr_start);
@@ -283,6 +294,11 @@ gui_input_draw_text (t_gui_window *window, int input_width)
}
last_color = color;
wprintw (GUI_CURSES(window)->win_input, "%s", ptr_start);
+ if (count_cursor > 0)
+ {
+ offset_cursor += utf8_width_screen (ptr_start);
+ count_cursor--;
+ }
ptr_next[0] = saved_char;
ptr_start = ptr_next;
pos_mask += size;
@@ -291,6 +307,7 @@ gui_input_draw_text (t_gui_window *window, int input_width)
ptr_start = NULL;
input_width--;
}
+ return offset_cursor;
}
/*
@@ -303,7 +320,7 @@ gui_input_draw (t_gui_buffer *buffer, int erase)
t_gui_window *ptr_win;
char format[32];
char *ptr_nickname;
- int prompt_length, display_prompt;
+ int prompt_length, display_prompt, offset_cursor;
t_irc_dcc *dcc_selected;
if (!gui_ok)
@@ -368,13 +385,14 @@ gui_input_draw (t_gui_buffer *buffer, int erase)
gui_window_set_weechat_color (GUI_CURSES(ptr_win)->win_input, COLOR_WIN_INPUT);
snprintf (format, 32, "%%-%ds", ptr_win->win_width - prompt_length);
+ offset_cursor = 0;
if (ptr_win == gui_current_window)
- gui_input_draw_text (ptr_win, ptr_win->win_width - prompt_length);
+ offset_cursor = gui_input_draw_text (ptr_win,
+ ptr_win->win_width - prompt_length);
else
wprintw (GUI_CURSES(ptr_win)->win_input, format, "");
wclrtoeol (GUI_CURSES(ptr_win)->win_input);
- ptr_win->win_input_x = prompt_length +
- (buffer->input_buffer_pos - buffer->input_buffer_1st_display);
+ ptr_win->win_input_x = prompt_length + offset_cursor;
if (ptr_win == gui_current_window)
move (ptr_win->win_y + ptr_win->win_height - 1,
ptr_win->win_x + ptr_win->win_input_x);