+2005-08-20 Yoshinori K. Okuji <okuji@enbug.org>
+
+ * kern/term.c (grub_putchar): Use grub_utf8_to_ucs4 for the
+ conversion.
+ (grub_getcharwidth): New function.
+
+ * kern/misc.c (grub_utf8_to_ucs4): New function.
+
+ * include/grub/term.h (struct grub_term): Added a new member
+ "getcharwidth".
+ (grub_getcharwidth): New prototype.
+
+ * include/grub/misc.h (grub_utf8_to_ucs4): New prototype.
+
+ * term/i386/pc/console.c (map_char): New function. Segregated from
+ grub_console_putchar.
+ (grub_console_putchar): Use map_char.
+ (grub_console_getcharwidth): New function.
+ (grub_console_term): Specified grub_console_getcharwidth as
+ getcharwidth.
+
+ * term/i386/pc/vga.c (grub_vga_getcharwidth): New function.
+ (grub_vga_term): Specified grub_vga_getcharwidth as getcharwidth.
+
+ * term/i386/pc/vesafb.c (grub_virtual_screen_setup): Return
+ GRUB_ERRNO.
+ (grub_vesafb_init): Do not use RC. Instead, use GRUB_ERRNO. Rely
+ on grub_strtoul completely.
+ (write_char): Declare local variables in the beginning of the
+ function.
+ (grub_vesafb_getcharwidth): New function.
+ (grub_vesafb_term): Specified grub_vesafb_getcharwidth as
+ getcharwidth.
+
2005-08-19 Yoshinori K. Okuji <okuji@enbug.org>
* DISTLIST: Replace commands/i386/pc/vbe_list_modes.c and
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,
+ grub_size_t size);
grub_err_t EXPORT_FUNC(grub_split_cmdline) (const char *str,
grub_err_t (* getline) (char **),
/* Put a character. C is encoded in Unicode. */
void (*putchar) (grub_uint32_t c);
+
+ /* Get the number of columns occupied by a given character C. C is
+ encoded in Unicode. */
+ grub_ssize_t (*getcharwidth) (grub_uint32_t c);
/* Check if any input character is available. */
int (*checkkey) (void);
void EXPORT_FUNC(grub_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
+grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void);
grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
return ret;
}
-/* Convert UTF-16 to UTF8. */
+/* Convert UTF-16 to UTF-8. */
grub_uint8_t *
grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
grub_size_t size)
return dest;
}
+/* Convert an UTF-8 string to an UCS-4 string. Return the number of
+ characters converted. DEST must be able to hold at least SIZE
+ 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_uint32_t *p = dest;
+ int count = 0;
+ grub_uint32_t code = 0;
+
+ while (size--)
+ {
+ grub_uint32_t c = *src++;
+
+ if (count)
+ {
+ if ((c & 0xc0) != 0x80)
+ {
+ /* invalid */
+ return -1;
+ }
+ else
+ {
+ code <<= 6;
+ code |= (c & 0x3f);
+ count--;
+ }
+ }
+ else
+ {
+ if ((c & 0x80) == 0x00)
+ code = c;
+ else if ((c & 0xe0) == 0xc0)
+ {
+ count = 1;
+ code = c & 0x1f;
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ count = 2;
+ code = c & 0x0f;
+ }
+ else if ((c & 0xf8) == 0xf0)
+ {
+ count = 3;
+ code = c & 0x07;
+ }
+ else if ((c & 0xfc) == 0xf8)
+ {
+ count = 4;
+ code = c & 0x03;
+ }
+ else if ((c & 0xfe) == 0xfc)
+ {
+ count = 5;
+ code = c & 0x01;
+ }
+ else
+ /* invalid */
+ return -1;
+ }
+
+ if (count == 0)
+ *p++ = code;
+ }
+
+ return p - dest;
+}
+
grub_err_t
-grub_split_cmdline (const char *cmdline, grub_err_t (* getline) (char **), int *argc, char ***argv)
+grub_split_cmdline (const char *cmdline, grub_err_t (*getline) (char **),
+ int *argc, char ***argv)
{
/* XXX: Fixed size buffer, perhaps this buffer should be dynamically
allocated. */
void
grub_putchar (int c)
{
- static grub_uint32_t code = 0;
- static int count = 0;
+ static grub_size_t size = 0;
+ static grub_uint8_t buf[6];
+ grub_uint32_t code;
+ grub_ssize_t ret;
- if (count)
+ buf[size++] = c;
+ ret = grub_utf8_to_ucs4 (&code, buf, size);
+
+ if (ret > 0)
{
- if ((c & 0xc0) != 0x80)
- {
- /* invalid */
- code = '@';
- count = 0;
- }
- else
- {
- code <<= 6;
- code |= (c & 0x3f);
- count--;
- }
+ size = 0;
+ grub_putcode (code);
}
- else
+ else if (ret < 0)
{
- if ((c & 0x80) == 0x00)
- code = c;
- else if ((c & 0xe0) == 0xc0)
- {
- count = 1;
- code = c & 0x1f;
- }
- else if ((c & 0xf0) == 0xe0)
- {
- count = 2;
- code = c & 0x0f;
- }
- else if ((c & 0xf8) == 0xf0)
- {
- count = 3;
- code = c & 0x07;
- }
- else if ((c & 0xfc) == 0xf8)
- {
- count = 4;
- code = c & 0x03;
- }
- else if ((c & 0xfe) == 0xfc)
- {
- count = 5;
- code = c & 0x01;
- }
- else
- /* invalid */
- code = '?';
- }
-
- if (count)
- /* Not finished yet. */
- return;
+ size = 0;
+ grub_putcode ('?');
+ }
+}
- grub_putcode (code);
+/* Return the number of columns occupied by the character code CODE. */
+grub_ssize_t
+grub_getcharwidth (grub_uint32_t code)
+{
+ return (grub_cur_term->getcharwidth) (code);
}
int
static grub_uint8_t grub_console_normal_color = 0x7;
static grub_uint8_t grub_console_highlight_color = 0x70;
-static void
-grub_console_putchar (grub_uint32_t c)
+static grub_uint32_t
+map_char (grub_uint32_t c)
{
if (c > 0x7f)
{
}
}
- grub_console_real_putchar (c);
+ return c;
+}
+
+static void
+grub_console_putchar (grub_uint32_t c)
+{
+ grub_console_real_putchar (map_char (c));
+}
+
+static grub_ssize_t
+grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
+{
+ /* For now, every printable character has the width 1. */
+ return 1;
}
static grub_uint16_t
.init = 0,
.fini = 0,
.putchar = grub_console_putchar,
+ .getcharwidth = grub_console_getcharwidth,
.checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
.getwh = grub_console_getwh,
{
/* If virtual screen has been allocated, free it. */
if (virtual_screen.text_buffer != 0)
- {
- grub_free (virtual_screen.text_buffer);
- }
+ grub_free (virtual_screen.text_buffer);
/* Reset virtual screen data. */
- grub_memset (&virtual_screen, 0, sizeof(virtual_screen));
+ grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
}
static grub_err_t
/* Allocate memory for text buffer. */
virtual_screen.text_buffer =
- (struct grub_colored_char *)grub_malloc (virtual_screen.columns
- * virtual_screen.rows
- * sizeof(struct grub_colored_char));
- if (virtual_screen.text_buffer == 0)
- {
- return GRUB_ERR_OUT_OF_MEMORY;
- }
+ (struct grub_colored_char *) grub_malloc (virtual_screen.columns
+ * virtual_screen.rows
+ * sizeof (*virtual_screen.text_buffer));
- return GRUB_ERR_NONE;
+ return grub_errno;
}
static grub_err_t
grub_vesafb_init (void)
{
- grub_uint32_t rc;
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
struct grub_vbe_info_block controller_info;
char *modevar;
vga_font = grub_vga_get_font ();
/* Check if we have VESA BIOS installed. */
- rc = grub_vbe_probe (&controller_info);
- if (rc != GRUB_ERR_NONE)
- {
- return rc;
- }
+ if (grub_vbe_probe (&controller_info) != GRUB_ERR_NONE)
+ return grub_errno;
/* Check existence of vbe_mode environment variable. */
modevar = grub_env_get ("vbe_mode");
if (modevar != 0)
{
- unsigned long value = 0;
+ unsigned long value;
- if ((grub_strncmp (modevar, "0x", 2) == 0) ||
- (grub_strncmp (modevar, "0X", 2) == 0))
- {
- /* Convert HEX mode number. */
- value = grub_strtoul (modevar + 2, 0, 16);
- }
- else
- {
- /* Convert DEC mode number. */
- value = grub_strtoul (modevar, 0, 10);
- }
-
- if (value != 0)
- {
- use_mode = value;
- }
+ value = grub_strtoul (modevar, 0, 0);
+ if (grub_errno == GRUB_ERR_NONE)
+ use_mode = value;
}
/* Store initial video mode. */
- rc = grub_vbe_get_video_mode (&old_mode);
+ if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE)
+ return grub_errno;
/* Setup desired graphics mode. */
- rc = grub_vbe_set_video_mode (use_mode, &mode_info);
- if (rc != GRUB_ERR_NONE)
- {
- return rc;
- }
+ if (grub_vbe_set_video_mode (use_mode, &mode_info) != GRUB_ERR_NONE)
+ return grub_errno;
/* Determine framebuffer and bytes per scan line. */
- framebuffer = (grub_uint8_t *)mode_info.phys_base_addr;
+ framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
if (controller_info.version >= 0x300)
- {
- bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
- }
+ bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
else
- {
- bytes_per_scan_line = mode_info.bytes_per_scan_line;
- }
+ bytes_per_scan_line = mode_info.bytes_per_scan_line;
/* Create virtual screen. */
- rc = grub_virtual_screen_setup (mode_info.x_resolution,
- mode_info.y_resolution);
- if (rc != GRUB_ERR_NONE)
+ if (grub_virtual_screen_setup (mode_info.x_resolution,
+ mode_info.y_resolution) != GRUB_ERR_NONE)
{
grub_vbe_set_video_mode (old_mode, 0);
- return rc;
+ return grub_errno;
}
/* Make sure frame buffer is black. */
struct grub_colored_char *p;
unsigned char bitmap[32];
unsigned width;
+ unsigned y;
+ unsigned offset;
p = (virtual_screen.text_buffer
+ virtual_screen.cursor_x
width = 0;
}
- unsigned y;
- unsigned offset;
-
for (y = 0, offset = 0;
y < virtual_screen.char_height;
y++, offset++)
{
unsigned char color;
- if (bitmap[offset] & (1<<(8-i)))
+ if (bitmap[offset] & (1 << (8-i)))
{
color = p->fg_color;
}
/* Scroll text buffer with one line to up. */
grub_memmove (virtual_screen.text_buffer,
virtual_screen.text_buffer + virtual_screen.columns,
- sizeof (struct grub_colored_char)
+ sizeof (*virtual_screen.text_buffer)
* virtual_screen.columns
* (virtual_screen.rows - 1));
if (virtual_screen.cursor_x + width > virtual_screen.columns)
grub_putchar ('\n');
- p = virtual_screen.text_buffer +
- virtual_screen.cursor_x +
- virtual_screen.cursor_y * virtual_screen.columns;
+ p = (virtual_screen.text_buffer +
+ virtual_screen.cursor_x +
+ virtual_screen.cursor_y * virtual_screen.columns);
p->code = c;
p->fg_color = virtual_screen.fg_color;
p->bg_color = virtual_screen.bg_color;
}
}
+static grub_ssize_t
+grub_vesafb_getcharwidth (grub_uint32_t c)
+{
+ unsigned width;
+
+ if (! grub_virtual_screen_get_glyph (c, 0, &width))
+ return 0;
+
+ return width;
+}
+
static grub_uint16_t
grub_virtual_screen_getwh (void)
{
.init = grub_vesafb_init,
.fini = grub_vesafb_fini,
.putchar = grub_vesafb_putchar,
+ .getcharwidth = grub_vesafb_getcharwidth,
.checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
.getwh = grub_virtual_screen_getwh,
#endif
}
+static grub_ssize_t
+grub_vga_getcharwidth (grub_uint32_t c)
+{
+ unsigned width;
+
+ if (! get_vga_glyph (c, 0, &width))
+ return 0;
+
+ return width;
+}
+
static grub_uint16_t
grub_vga_getwh (void)
{
.init = grub_vga_init,
.fini = grub_vga_fini,
.putchar = grub_vga_putchar,
+ .getcharwidth = grub_vga_getcharwidth,
.checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
.getwh = grub_vga_getwh,