diff --git a/ChangeLog b/ChangeLog index 634123b7a..1b13776de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-08-21 Yoshinori K. Okuji + + * util/console.c (grub_ncurses_putchar): If C is greater than + 0x7f, set C to a question mark. + (grub_ncurses_getcharwidth): New function. + (grub_ncurses_term): Specify grub_ncurses_getcharwidth as + getcharwidth. + + * normal/menu.c (print_entry): Made aware of Unicode. First, + convert TITLE to UCS-4, and predict the cursor position by + grub_getcharwidth. + + * include/grub/misc.h (grub_utf8_to_ucs4): Specify the qualifier + const to SRC. + * kern/misc.c (grub_utf16_to_utf8): Likewise. + 2005-08-20 Yoshinori K. Okuji * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Specify diff --git a/include/grub/misc.h b/include/grub/misc.h index b549c3e2f..051fbe001 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -73,7 +73,7 @@ grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest, grub_uint16_t *src, grub_size_t size); grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, - grub_uint8_t *src, + const grub_uint8_t *src, grub_size_t size); grub_err_t EXPORT_FUNC(grub_split_cmdline) (const char *str, diff --git a/kern/misc.c b/kern/misc.c index 255ebb250..df5efa6a6 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -809,7 +809,8 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, characters (when the input is unknown). If an invalid sequence is found, return -1. */ grub_ssize_t -grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_uint8_t *src, grub_size_t size) +grub_utf8_to_ucs4 (grub_uint32_t *dest, const grub_uint8_t *src, + grub_size_t size) { grub_uint32_t *p = dest; int count = 0; diff --git a/normal/menu.c b/normal/menu.c index 8fc755c63..dd7fd1bd9 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,11 +41,13 @@ draw_border (void) { grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1); grub_putcode (GRUB_TERM_DISP_VLINE); - grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1, GRUB_TERM_TOP_BORDER_Y + i + 1); + grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1, + GRUB_TERM_TOP_BORDER_Y + i + 1); grub_putcode (GRUB_TERM_DISP_VLINE); } - grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1); + grub_gotoxy (GRUB_TERM_MARGIN, + GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1); grub_putcode (GRUB_TERM_DISP_LL); for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++) grub_putcode (GRUB_TERM_DISP_HLINE); @@ -53,7 +55,9 @@ draw_border (void) grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + GRUB_TERM_MARGIN + 1); + grub_gotoxy (GRUB_TERM_MARGIN, + (GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + + GRUB_TERM_MARGIN + 1)); } static void @@ -97,8 +101,23 @@ print_entry (int y, int highlight, grub_menu_entry_t entry) { int x; const char *title; - + grub_ssize_t len; + grub_uint32_t *unicode_title; + grub_ssize_t i; + title = entry ? entry->title : ""; + unicode_title = grub_malloc (grub_strlen (title) * sizeof (*unicode_title)); + if (! unicode_title) + /* XXX How to show this error? */ + return; + + len = grub_utf8_to_ucs4 (unicode_title, title, grub_strlen (title)); + if (len < 0) + { + /* It is an invalid sequence. */ + grub_free (unicode_title); + return; + } grub_setcolorstate (highlight ? GRUB_TERM_COLOR_HIGHLIGHT @@ -106,23 +125,36 @@ print_entry (int y, int highlight, grub_menu_entry_t entry) grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y); - for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1; + for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0; x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN; - x++) + i++) { - if (*title && x <= GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN - 1) + if (i < len + && x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH + - GRUB_TERM_MARGIN - 1)) { - if (x == GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN - 1) + grub_ssize_t width; + + width = grub_getcharwidth (unicode_title[i]); + + if (x + width > (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH + - GRUB_TERM_MARGIN - 1)) grub_putcode (GRUB_TERM_DISP_RIGHT); else - grub_putchar (*title++); + grub_putcode (unicode_title[i]); + + x += width; } else - grub_putchar (' '); + { + grub_putchar (' '); + x++; + } } grub_gotoxy (GRUB_TERM_CURSOR_X, y); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + grub_free (unicode_title); } static void diff --git a/util/console.c b/util/console.c index ec3c855fc..3af2cbe62 100644 --- a/util/console.c +++ b/util/console.c @@ -80,12 +80,21 @@ grub_ncurses_putchar (grub_uint32_t c) break; default: + /* ncurses does not support Unicode. */ + if (c > 0x7f) + c = '?'; break; } addch (c | grub_console_attr); } +static grub_ssize_t +grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused))) +{ + return 1; +} + static void grub_ncurses_setcolorstate (grub_term_color_state state) { @@ -283,6 +292,7 @@ static struct grub_term grub_ncurses_term = .init = grub_ncurses_init, .fini = grub_ncurses_fini, .putchar = grub_ncurses_putchar, + .getcharwidth = grub_ncurses_getcharwidth, .checkkey = grub_ncurses_checkkey, .getkey = grub_ncurses_getkey, .getxy = grub_ncurses_getxy,