=== modified file 'ChangeLog' --- ChangeLog 2009-12-12 00:43:32 +0000 +++ ChangeLog 2009-12-13 00:44:09 +0000 @@ -1,3 +1,10 @@ +2009-12-13 Carles Pina i Estany + + * normal/menu_text.c (utf8_to_ucs4): New definition. + (print_message_indented): Use `utf8_to_ucs'. + (print_timeout): Prints the whole string so avoid problems with + multi-byte and multi-width characters. + 2009-12-12 Robert Millan * gendistlist.sh (EXTRA_DISTFILES): Add `genvideolist.sh'. === modified file 'normal/menu_text.c' --- normal/menu_text.c 2009-12-08 00:08:52 +0000 +++ normal/menu_text.c 2009-12-13 01:26:09 +0000 @@ -77,35 +77,50 @@ getstringwidth (grub_uint32_t * str, con return width; } +static int +utf8_to_ucs4 (const char *msg, grub_uint32_t **unicode_msg, + grub_uint32_t **last_position) +{ + grub_ssize_t msg_len = grub_strlen (msg); + + *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t)); + + if (!*unicode_msg) + { + grub_printf ("utf8_to_ucs4 ERROR1: %s", msg); + return -1; + } + + msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len, + (grub_uint8_t *) msg, -1, 0); + + *last_position = *unicode_msg + msg_len; + + if (msg_len < 0) + { + grub_printf ("utf8_to_ucs4 ERROR2: %s", msg); + grub_free (*unicode_msg); + } + return msg_len; +} + static void print_message_indented (const char *msg) { const int line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') * 15; grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; - grub_ssize_t msg_len = grub_strlen (msg); - - unicode_msg = grub_malloc (msg_len * sizeof (*unicode_msg)); + int msg_len; - msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len, - (grub_uint8_t *) msg, -1, 0); - - if (!unicode_msg) - { - grub_printf ("print_message_indented ERROR1: %s", msg); - return; - } + msg_len = utf8_to_ucs4 (msg, &unicode_msg, &last_position); if (msg_len < 0) { - grub_printf ("print_message_indented ERROR2: %s", msg); - grub_free (unicode_msg); return; } - const grub_uint32_t *last_position = unicode_msg + msg_len; - grub_uint32_t *current_position = unicode_msg; grub_uint32_t *next_new_line = unicode_msg; @@ -368,22 +383,39 @@ get_entry_number (const char *name) } static void -print_timeout (int timeout, int offset, int second_stage) +print_timeout (int timeout, int offset, + int second_stage __attribute__ ((unused))) { const char *msg = _("The highlighted entry will be booted automatically in %ds."); - const int msg_localized_len = grub_strlen (msg); - const int number_spaces = GRUB_TERM_WIDTH - msg_localized_len - 3; - char *msg_end = grub_strchr (msg, '%'); + char *msg_formatted = grub_malloc (sizeof (char) * + (grub_strlen (msg) + 1 + 6)); + /* 5: max string length that `timeout' can have. */ + + grub_sprintf (msg_formatted, msg, timeout); + + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + + int msg_len = utf8_to_ucs4 (msg_formatted, &unicode_msg, &last_position); + if (msg_len < 0) + { + return; + } - grub_gotoxy (second_stage ? (msg_end - msg + 3) : 3, GRUB_TERM_HEIGHT - 3); - grub_printf (second_stage ? msg_end : msg, timeout); - print_spaces (second_stage ? number_spaces : 0); + grub_gotoxy (3, GRUB_TERM_HEIGHT - 3); + grub_print_ucs4 (unicode_msg, last_position); + + int strwidth = getstringwidth (unicode_msg, last_position); + + print_spaces (GRUB_TERM_WIDTH - strwidth - 3); + + grub_free(unicode_msg); grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); grub_refresh (); -}; +} /* Show the menu and handle menu entry selection. Returns the menu entry index that should be executed or -1 if no entry should be executed (e.g.,