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.
This commit is contained in:
parent
1f0a95e481
commit
ef0954341c
8 changed files with 205 additions and 117 deletions
34
ChangeLog
34
ChangeLog
|
@ -1,3 +1,37 @@
|
|||
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
|
||||
|
|
|
@ -72,6 +72,9 @@ void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn));
|
|||
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 **),
|
||||
|
|
|
@ -136,6 +136,10 @@ struct grub_term
|
|||
/* 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);
|
||||
|
||||
|
@ -184,6 +188,7 @@ grub_term_t EXPORT_FUNC(grub_term_get_current) (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);
|
||||
|
|
75
kern/misc.c
75
kern/misc.c
|
@ -742,7 +742,7 @@ grub_sprintf (char *str, const char *fmt, ...)
|
|||
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)
|
||||
|
@ -804,8 +804,79 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
|
|||
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. */
|
||||
|
|
70
kern/term.c
70
kern/term.c
|
@ -143,63 +143,31 @@ grub_putcode (grub_uint32_t code)
|
|||
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 = '?';
|
||||
size = 0;
|
||||
grub_putcode ('?');
|
||||
}
|
||||
}
|
||||
|
||||
if (count)
|
||||
/* Not finished yet. */
|
||||
return;
|
||||
|
||||
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
|
||||
|
|
|
@ -26,8 +26,8 @@ static grub_uint8_t grub_console_standard_color = 0x7;
|
|||
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)
|
||||
{
|
||||
|
@ -71,7 +71,20 @@ grub_console_putchar (grub_uint32_t c)
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -111,6 +124,7 @@ static struct grub_term grub_console_term =
|
|||
.init = 0,
|
||||
.fini = 0,
|
||||
.putchar = grub_console_putchar,
|
||||
.getcharwidth = grub_console_getcharwidth,
|
||||
.checkkey = grub_console_checkkey,
|
||||
.getkey = grub_console_getkey,
|
||||
.getwh = grub_console_getwh,
|
||||
|
|
|
@ -102,12 +102,10 @@ grub_virtual_screen_free (void)
|
|||
{
|
||||
/* 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
|
||||
|
@ -136,21 +134,16 @@ grub_virtual_screen_setup (grub_uint32_t width,
|
|||
|
||||
/* 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;
|
||||
|
@ -159,66 +152,43 @@ grub_vesafb_init (void)
|
|||
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. */
|
||||
|
@ -319,6 +289,8 @@ write_char (void)
|
|||
struct grub_colored_char *p;
|
||||
unsigned char bitmap[32];
|
||||
unsigned width;
|
||||
unsigned y;
|
||||
unsigned offset;
|
||||
|
||||
p = (virtual_screen.text_buffer
|
||||
+ virtual_screen.cursor_x
|
||||
|
@ -332,9 +304,6 @@ write_char (void)
|
|||
width = 0;
|
||||
}
|
||||
|
||||
unsigned y;
|
||||
unsigned offset;
|
||||
|
||||
for (y = 0, offset = 0;
|
||||
y < virtual_screen.char_height;
|
||||
y++, offset++)
|
||||
|
@ -347,7 +316,7 @@ write_char (void)
|
|||
{
|
||||
unsigned char color;
|
||||
|
||||
if (bitmap[offset] & (1<<(8-i)))
|
||||
if (bitmap[offset] & (1 << (8-i)))
|
||||
{
|
||||
color = p->fg_color;
|
||||
}
|
||||
|
@ -392,7 +361,7 @@ scroll_up (void)
|
|||
/* 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));
|
||||
|
||||
|
@ -468,9 +437,9 @@ grub_vesafb_putchar (grub_uint32_t c)
|
|||
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;
|
||||
|
@ -507,6 +476,17 @@ grub_vesafb_putchar (grub_uint32_t c)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -612,6 +592,7 @@ static struct grub_term grub_vesafb_term =
|
|||
.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,
|
||||
|
|
|
@ -472,6 +472,17 @@ grub_vga_putchar (grub_uint32_t c)
|
|||
#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)
|
||||
{
|
||||
|
@ -570,6 +581,7 @@ static struct grub_term grub_vga_term =
|
|||
.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,
|
||||
|
|
Loading…
Reference in a new issue