diff -p -u old/menu_entry.c new/menu_entry.c --- old/menu_entry.c 2009-11-29 00:56:42.020701488 +0000 +++ new/menu_entry.c 2009-11-29 00:56:06.748700757 +0000 @@ -833,7 +833,9 @@ store_completion (const char *item, grub } grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - grub_printf (" Possible %s are:\n ", what); + grub_printf (" "); + grub_printf (_("Possible %s are:"), what); + grub_printf ("\n "); } /* Make sure that the completion buffer has enough room. */ @@ -994,7 +996,9 @@ run (struct screen *screen) } grub_cls (); - grub_printf (_(" Booting a command list\n\n")); + grub_printf (" "); + grub_printf (_("Booting a command list")); + grub_printf ("\n\n"); /* Execute the script, line for line. */ @@ -1174,6 +1178,7 @@ fail: grub_cls (); grub_print_error (); grub_errno = GRUB_ERR_NONE; - grub_printf (_("\nPress any key to continue...")); + grub_putchar ('\n'); + grub_printf (_("Press any key to continue...")); (void) grub_getkey (); } diff -p -u old/menu_text.c new/menu_text.c --- old/menu_text.c 2009-11-29 00:56:33.700701575 +0000 +++ new/menu_text.c 2009-11-29 00:56:09.736702258 +0000 @@ -39,7 +39,8 @@ static grub_uint8_t grub_color_menu_high void grub_wait_after_message (void) { - grub_printf ("\nPress any key to continue..."); + grub_putchar ('\n'); + grub_printf (_("Press any key to continue...")); (void) grub_getkey (); grub_putchar ('\n'); } @@ -81,27 +82,130 @@ draw_border (void) } static void +print_spaces (int number_spaces) +{ + int i; + for (i = 0; i < number_spaces; i++) + grub_putchar (' '); +} + +static void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position) +{ + while (str < last_position) + { + grub_putcode (*str); + str++; + } +} + +static grub_ssize_t +getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position) +{ + grub_ssize_t width = 0; + + while (str < last_position) + { + width += grub_getcharwidth (*str); + str++; + } + return width; +} + +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_ssize_t msg_len = grub_strlen (msg); + + unicode_msg = grub_malloc (msg_len * sizeof (*unicode_msg)); + + 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; + } + + 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; + + while (current_position < last_position) + { + next_new_line = (grub_uint32_t *) last_position; + + while (getstringwidth (current_position, next_new_line) > line_len + || (*next_new_line != ' ' && next_new_line > current_position && + next_new_line != last_position)) + { + next_new_line--; + } + + if (next_new_line == current_position) + { + next_new_line = (next_new_line + line_len > last_position) ? + (grub_uint32_t *) last_position : next_new_line + line_len; + } + + print_spaces (6); + grub_print_ucs4 (current_position, next_new_line); + grub_putchar ('\n'); + + next_new_line++; + current_position = next_new_line; + } + grub_free (unicode_msg); +} + +static void print_message (int nested, int edit) { grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + grub_putchar ('\n'); if (edit) { - grub_printf ("\n\ - Minimum Emacs-like screen editing is supported. TAB lists\n\ - completions. Press Ctrl-x to boot, Ctrl-c for a command-line\n\ - or ESC to return menu."); + print_message_indented (_("Minimum Emacs-like screen editing is \ +supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \ +command-line or ESC to return menu.")); } else { - grub_printf (_("\n\ - Use the %C and %C keys to select which entry is highlighted.\n"), (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN); - grub_printf ("\ - Press enter to boot the selected OS, \'e\' to edit the\n\ - commands before booting or \'c\' for a command-line."); + const char *msg = _("Use the %C and %C keys to select which \ +entry is highlighted."); + char *msg_translated = + grub_malloc (sizeof (char) * grub_strlen (msg) + 1); + + grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP, + (grub_uint32_t) GRUB_TERM_DISP_DOWN); + print_message_indented (msg_translated); + + grub_free (msg_translated); + + print_message_indented (_("Press enter to boot the selected OS, \ +\'e\' to edit the commands before booting or \'c\' for a command-line.")); + if (nested) - grub_printf ("\n\ - ESC to return previous menu."); + { + grub_printf ("\n "); + grub_printf (_("ESC to return previous menu.")); + } } } @@ -266,14 +370,17 @@ get_entry_number (const char *name) static void print_timeout (int timeout, int offset, int second_stage) { - /* NOTE: Do not remove the trailing space characters. - They are required to clear the line. */ - char *msg = - " The highlighted entry will be booted automatically in %ds. "; + 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, '%'); - grub_gotoxy (second_stage ? (msg_end - msg) : 0, GRUB_TERM_HEIGHT - 3); + 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 (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); grub_refresh (); }; @@ -362,8 +469,7 @@ refresh: if (timeout >= 0) { grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - grub_printf ("\ - "); + print_spaces (GRUB_TERM_WIDTH - 1); grub_env_unset ("timeout"); grub_env_unset ("fallback"); grub_gotoxy (GRUB_TERM_CURSOR_X, @@ -523,7 +629,9 @@ static void notify_booting (grub_menu_entry_t entry, void *userdata __attribute__ ((unused))) { - grub_printf (" Booting \'%s\'\n\n", entry->title); + grub_printf (" "); + grub_printf (_("Booting \'%s\'"), entry->title); + grub_printf ("\n\n"); } /* Callback invoked when a default menu entry executed because of a timeout @@ -533,7 +641,9 @@ static void notify_fallback (grub_menu_entry_t entry, void *userdata __attribute__ ((unused))) { - grub_printf ("\n Falling back to \'%s\'\n\n", entry->title); + grub_printf ("\n "); + grub_printf (_("Falling back to \'%s\'"), entry->title); + grub_printf ("\n\n"); grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS); } @@ -547,7 +657,9 @@ notify_execution_failure (void *userdata grub_print_error (); grub_errno = GRUB_ERR_NONE; } - grub_printf ("\n Failed to boot default entries.\n"); + grub_printf ("\n "); + grub_printf (_("Failed to boot default entries.")); + grub_putchar ('\n'); grub_wait_after_message (); }