merge with mainline
This commit is contained in:
commit
297f0c2b6e
218 changed files with 35637 additions and 4957 deletions
|
@ -236,7 +236,7 @@ grub_at_keyboard_getkey_noblock (void)
|
|||
}
|
||||
|
||||
static int
|
||||
grub_at_keyboard_checkkey (void)
|
||||
grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
if (pending_key != -1)
|
||||
return 1;
|
||||
|
@ -250,7 +250,7 @@ grub_at_keyboard_checkkey (void)
|
|||
}
|
||||
|
||||
static int
|
||||
grub_at_keyboard_getkey (void)
|
||||
grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
int key;
|
||||
if (pending_key != -1)
|
||||
|
@ -267,7 +267,7 @@ grub_at_keyboard_getkey (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_keyboard_controller_init (void)
|
||||
grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
pending_key = -1;
|
||||
at_keyboard_status = 0;
|
||||
|
@ -277,7 +277,7 @@ grub_keyboard_controller_init (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_keyboard_controller_fini (void)
|
||||
grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_keyboard_controller_write (grub_keyboard_controller_orig);
|
||||
return GRUB_ERR_NONE;
|
||||
|
|
|
@ -24,97 +24,84 @@
|
|||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/console.h>
|
||||
|
||||
static grub_uint8_t
|
||||
static const grub_uint8_t
|
||||
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
|
||||
GRUB_EFI_BACKGROUND_BLACK);
|
||||
static grub_uint8_t
|
||||
grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
|
||||
GRUB_EFI_BACKGROUND_BLACK);
|
||||
static grub_uint8_t
|
||||
grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
|
||||
GRUB_EFI_BACKGROUND_LIGHTGRAY);
|
||||
|
||||
static int read_key = -1;
|
||||
|
||||
static grub_uint32_t
|
||||
map_char (grub_uint32_t c)
|
||||
{
|
||||
if (c > 0x7f)
|
||||
/* Map some unicode characters to the EFI character. */
|
||||
switch (c)
|
||||
{
|
||||
/* Map some unicode characters to the EFI character. */
|
||||
switch (c)
|
||||
{
|
||||
case 0x2190: /* left arrow */
|
||||
c = 0x25c4;
|
||||
break;
|
||||
case 0x2191: /* up arrow */
|
||||
c = 0x25b2;
|
||||
break;
|
||||
case 0x2192: /* right arrow */
|
||||
c = 0x25ba;
|
||||
break;
|
||||
case 0x2193: /* down arrow */
|
||||
c = 0x25bc;
|
||||
break;
|
||||
case 0x2501: /* horizontal line */
|
||||
c = 0x2500;
|
||||
break;
|
||||
case 0x2503: /* vertical line */
|
||||
c = 0x2502;
|
||||
break;
|
||||
case 0x250F: /* upper-left corner */
|
||||
c = 0x250c;
|
||||
break;
|
||||
case 0x2513: /* upper-right corner */
|
||||
c = 0x2510;
|
||||
break;
|
||||
case 0x2517: /* lower-left corner */
|
||||
c = 0x2514;
|
||||
break;
|
||||
case 0x251B: /* lower-right corner */
|
||||
c = 0x2518;
|
||||
break;
|
||||
|
||||
default:
|
||||
c = '?';
|
||||
break;
|
||||
}
|
||||
case GRUB_UNICODE_LEFTARROW:
|
||||
c = GRUB_UNICODE_BLACK_LEFT_TRIANGLE;
|
||||
break;
|
||||
case GRUB_UNICODE_UPARROW:
|
||||
c = GRUB_UNICODE_BLACK_UP_TRIANGLE;
|
||||
break;
|
||||
case GRUB_UNICODE_RIGHTARROW:
|
||||
c = GRUB_UNICODE_BLACK_RIGHT_TRIANGLE;
|
||||
break;
|
||||
case GRUB_UNICODE_DOWNARROW:
|
||||
c = GRUB_UNICODE_BLACK_DOWN_TRIANGLE;
|
||||
break;
|
||||
case GRUB_UNICODE_HLINE:
|
||||
c = GRUB_UNICODE_LIGHT_HLINE;
|
||||
break;
|
||||
case GRUB_UNICODE_VLINE:
|
||||
c = GRUB_UNICODE_LIGHT_VLINE;
|
||||
break;
|
||||
case GRUB_UNICODE_CORNER_UL:
|
||||
c = GRUB_UNICODE_LIGHT_CORNER_UL;
|
||||
break;
|
||||
case GRUB_UNICODE_CORNER_UR:
|
||||
c = GRUB_UNICODE_LIGHT_CORNER_UR;
|
||||
break;
|
||||
case GRUB_UNICODE_CORNER_LL:
|
||||
c = GRUB_UNICODE_LIGHT_CORNER_LL;
|
||||
break;
|
||||
case GRUB_UNICODE_CORNER_LR:
|
||||
c = GRUB_UNICODE_LIGHT_CORNER_LR;
|
||||
break;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_putchar (grub_uint32_t c)
|
||||
grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
grub_efi_char16_t str[2];
|
||||
grub_efi_char16_t str[2 + c->ncomb];
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
unsigned i, j;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
|
||||
/* For now, do not try to use a surrogate pair. */
|
||||
if (c > 0xffff)
|
||||
c = '?';
|
||||
|
||||
str[0] = (grub_efi_char16_t) map_char (c & 0xffff);
|
||||
str[1] = 0;
|
||||
if (c->base > 0xffff)
|
||||
str[0] = '?';
|
||||
else
|
||||
str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff);
|
||||
j = 1;
|
||||
for (i = 0; i < c->ncomb; i++)
|
||||
if (c->base < 0xffff)
|
||||
str[j++] = c->combining[i].code;
|
||||
str[j] = 0;
|
||||
|
||||
/* Should this test be cached? */
|
||||
if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
|
||||
if ((c->base > 0x7f || c->ncomb)
|
||||
&& efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
|
||||
return;
|
||||
|
||||
efi_call_2 (o->output_string, o, str);
|
||||
}
|
||||
|
||||
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 int
|
||||
grub_console_checkkey (void)
|
||||
grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_simple_input_interface_t *i;
|
||||
grub_efi_input_key_t key;
|
||||
|
@ -209,7 +196,7 @@ grub_console_checkkey (void)
|
|||
}
|
||||
|
||||
static int
|
||||
grub_console_getkey (void)
|
||||
grub_console_getkey (struct grub_term_input *term)
|
||||
{
|
||||
grub_efi_simple_input_interface_t *i;
|
||||
grub_efi_boot_services_t *b;
|
||||
|
@ -233,7 +220,7 @@ grub_console_getkey (void)
|
|||
if (status != GRUB_EFI_SUCCESS)
|
||||
return -1;
|
||||
|
||||
grub_console_checkkey ();
|
||||
grub_console_checkkey (term);
|
||||
}
|
||||
while (read_key < 0);
|
||||
|
||||
|
@ -243,7 +230,7 @@ grub_console_getkey (void)
|
|||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_console_getwh (void)
|
||||
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
grub_efi_uintn_t columns, rows;
|
||||
|
@ -260,7 +247,7 @@ grub_console_getwh (void)
|
|||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_console_getxy (void)
|
||||
grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
|
@ -269,7 +256,8 @@ grub_console_getxy (void)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
||||
grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
|
@ -278,7 +266,7 @@ grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_console_cls (void)
|
||||
grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
grub_efi_int32_t orig_attr;
|
||||
|
@ -291,7 +279,8 @@ grub_console_cls (void)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_console_setcolorstate (grub_term_color_state state)
|
||||
grub_console_setcolorstate (struct grub_term_output *term,
|
||||
grub_term_color_state state)
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
|
@ -302,10 +291,10 @@ grub_console_setcolorstate (grub_term_color_state state)
|
|||
efi_call_2 (o->set_attributes, o, grub_console_standard_color);
|
||||
break;
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
efi_call_2 (o->set_attributes, o, grub_console_normal_color);
|
||||
efi_call_2 (o->set_attributes, o, term->normal_color);
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
efi_call_2 (o->set_attributes, o, grub_console_highlight_color);
|
||||
efi_call_2 (o->set_attributes, o, term->highlight_color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -313,21 +302,8 @@ grub_console_setcolorstate (grub_term_color_state state)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
|
||||
{
|
||||
grub_console_normal_color = normal_color;
|
||||
grub_console_highlight_color = highlight_color;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
|
||||
{
|
||||
*normal_color = grub_console_normal_color;
|
||||
*highlight_color = grub_console_highlight_color;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_console_setcursor (int on)
|
||||
grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
int on)
|
||||
{
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
|
||||
|
@ -346,15 +322,17 @@ static struct grub_term_output grub_console_term_output =
|
|||
{
|
||||
.name = "console",
|
||||
.putchar = grub_console_putchar,
|
||||
.getcharwidth = grub_console_getcharwidth,
|
||||
.getwh = grub_console_getwh,
|
||||
.getxy = grub_console_getxy,
|
||||
.gotoxy = grub_console_gotoxy,
|
||||
.cls = grub_console_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcolor = grub_console_setcolor,
|
||||
.getcolor = grub_console_getcolor,
|
||||
.setcursor = grub_console_setcursor
|
||||
.setcursor = grub_console_setcursor,
|
||||
.normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY,
|
||||
GRUB_EFI_BACKGROUND_BLACK),
|
||||
.highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK,
|
||||
GRUB_EFI_BACKGROUND_LIGHTGRAY),
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#define DEFAULT_BORDER_WIDTH 10
|
||||
|
||||
#define DEFAULT_STANDARD_COLOR 0x07
|
||||
#define DEFAULT_NORMAL_COLOR 0x07
|
||||
#define DEFAULT_HIGHLIGHT_COLOR 0x70
|
||||
|
||||
struct grub_dirty_region
|
||||
{
|
||||
|
@ -49,7 +47,7 @@ struct grub_dirty_region
|
|||
struct grub_colored_char
|
||||
{
|
||||
/* An Unicode codepoint. */
|
||||
grub_uint32_t code;
|
||||
struct grub_unicode_glyph *code;
|
||||
|
||||
/* Color values. */
|
||||
grub_video_color_t fg_color;
|
||||
|
@ -92,8 +90,6 @@ struct grub_virtual_screen
|
|||
|
||||
/* Terminal color settings. */
|
||||
grub_uint8_t standard_color_setting;
|
||||
grub_uint8_t normal_color_setting;
|
||||
grub_uint8_t highlight_color_setting;
|
||||
grub_uint8_t term_color;
|
||||
|
||||
/* Color settings. */
|
||||
|
@ -122,8 +118,8 @@ void (*grub_gfxterm_decorator_hook) (void) = NULL;
|
|||
static struct grub_gfxterm_window window;
|
||||
static struct grub_virtual_screen virtual_screen;
|
||||
static grub_gfxterm_repaint_callback_t repaint_callback;
|
||||
static int repaint_schedulded = 0;
|
||||
static int repaint_was_schedulded = 0;
|
||||
static int repaint_scheduled = 0;
|
||||
static int repaint_was_scheduled = 0;
|
||||
|
||||
static void destroy_window (void);
|
||||
|
||||
|
@ -146,7 +142,11 @@ static unsigned int calculate_normal_character_width (grub_font_t font);
|
|||
|
||||
static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
|
||||
|
||||
static void grub_gfxterm_refresh (void);
|
||||
static void grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused)));
|
||||
|
||||
static grub_ssize_t
|
||||
grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)),
|
||||
const struct grub_unicode_glyph *c);
|
||||
|
||||
static void
|
||||
set_term_color (grub_uint8_t term_color)
|
||||
|
@ -177,7 +177,10 @@ set_term_color (grub_uint8_t term_color)
|
|||
static void
|
||||
clear_char (struct grub_colored_char *c)
|
||||
{
|
||||
c->code = ' ';
|
||||
grub_free (c->code);
|
||||
c->code = grub_unicode_glyph_from_code (' ');
|
||||
if (!c->code)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
c->fg_color = virtual_screen.fg_color;
|
||||
c->bg_color = virtual_screen.bg_color;
|
||||
c->width = 0;
|
||||
|
@ -253,10 +256,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
|
|||
grub_video_set_active_render_target (text_layer);
|
||||
|
||||
virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
|
||||
virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
|
||||
virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
|
||||
|
||||
virtual_screen.term_color = virtual_screen.normal_color_setting;
|
||||
virtual_screen.term_color = GRUB_TERM_DEFAULT_NORMAL_COLOR;
|
||||
|
||||
set_term_color (virtual_screen.term_color);
|
||||
|
||||
|
@ -266,7 +267,10 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
|
|||
|
||||
/* Clear out text buffer. */
|
||||
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
{
|
||||
virtual_screen.text_buffer[i].code = 0;
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
}
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
@ -274,7 +278,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
|
|||
void
|
||||
grub_gfxterm_schedule_repaint (void)
|
||||
{
|
||||
repaint_schedulded = 1;
|
||||
repaint_scheduled = 1;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
|
@ -355,7 +359,7 @@ grub_gfxterm_fullscreen (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_gfxterm_term_init (void)
|
||||
grub_gfxterm_term_init (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
char *tmp;
|
||||
grub_err_t err;
|
||||
|
@ -399,7 +403,7 @@ destroy_window (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_gfxterm_term_fini (void)
|
||||
grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
destroy_window ();
|
||||
grub_video_restore ();
|
||||
|
@ -506,7 +510,7 @@ dirty_region_reset (void)
|
|||
dirty_region.top_left_y = -1;
|
||||
dirty_region.bottom_right_x = -1;
|
||||
dirty_region.bottom_right_y = -1;
|
||||
repaint_was_schedulded = 0;
|
||||
repaint_was_scheduled = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -526,14 +530,14 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height)
|
|||
if ((width == 0) || (height == 0))
|
||||
return;
|
||||
|
||||
if (repaint_schedulded)
|
||||
if (repaint_scheduled)
|
||||
{
|
||||
x = virtual_screen.offset_x;
|
||||
y = virtual_screen.offset_y;
|
||||
width = virtual_screen.width;
|
||||
height = virtual_screen.height;
|
||||
repaint_schedulded = 0;
|
||||
repaint_was_schedulded = 1;
|
||||
repaint_scheduled = 0;
|
||||
repaint_was_scheduled = 1;
|
||||
}
|
||||
|
||||
if (dirty_region_is_empty ())
|
||||
|
@ -582,7 +586,7 @@ dirty_region_redraw (void)
|
|||
width = dirty_region.bottom_right_x - x + 1;
|
||||
height = dirty_region.bottom_right_y - y + 1;
|
||||
|
||||
if (repaint_was_schedulded && grub_gfxterm_decorator_hook)
|
||||
if (repaint_was_scheduled && grub_gfxterm_decorator_hook)
|
||||
grub_gfxterm_decorator_hook ();
|
||||
|
||||
redraw_screen_rect (x, y, width, height);
|
||||
|
@ -611,7 +615,12 @@ paint_char (unsigned cx, unsigned cy)
|
|||
p -= p->index;
|
||||
|
||||
/* Get glyph for character. */
|
||||
glyph = grub_font_get_glyph (virtual_screen.font, p->code);
|
||||
glyph = grub_font_construct_glyph (virtual_screen.font, p->code);
|
||||
if (!glyph)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
ascent = grub_font_get_ascent (virtual_screen.font);
|
||||
|
||||
width = virtual_screen.normal_char_width * calculate_character_width(glyph);
|
||||
|
@ -632,6 +641,7 @@ paint_char (unsigned cx, unsigned cy)
|
|||
/* Mark character to be drawn. */
|
||||
dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
|
||||
width, height);
|
||||
grub_free (glyph);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -782,6 +792,15 @@ scroll_up (void)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Clear first line in text buffer. */
|
||||
for (i = 0;
|
||||
i < virtual_screen.columns;
|
||||
i++)
|
||||
{
|
||||
virtual_screen.text_buffer[i].code = 0;
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
}
|
||||
|
||||
/* Scroll text buffer with one line to up. */
|
||||
grub_memmove (virtual_screen.text_buffer,
|
||||
virtual_screen.text_buffer + virtual_screen.columns,
|
||||
|
@ -793,15 +812,19 @@ scroll_up (void)
|
|||
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
|
||||
i < virtual_screen.columns * virtual_screen.rows;
|
||||
i++)
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
{
|
||||
virtual_screen.text_buffer[i].code = 0;
|
||||
clear_char (&(virtual_screen.text_buffer[i]));
|
||||
}
|
||||
|
||||
virtual_screen.total_scroll++;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_putchar (grub_uint32_t c)
|
||||
grub_gfxterm_putchar (struct grub_term_output *term,
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
if (c == '\a')
|
||||
if (c->base == '\a')
|
||||
/* FIXME */
|
||||
return;
|
||||
|
||||
|
@ -809,9 +832,9 @@ grub_gfxterm_putchar (grub_uint32_t c)
|
|||
if (virtual_screen.cursor_state)
|
||||
draw_cursor (0);
|
||||
|
||||
if (c == '\b' || c == '\n' || c == '\r')
|
||||
if (c->base == '\b' || c->base == '\n' || c->base == '\r')
|
||||
{
|
||||
switch (c)
|
||||
switch (c->base)
|
||||
{
|
||||
case '\b':
|
||||
if (virtual_screen.cursor_x > 0)
|
||||
|
@ -832,26 +855,30 @@ grub_gfxterm_putchar (grub_uint32_t c)
|
|||
}
|
||||
else
|
||||
{
|
||||
struct grub_font_glyph *glyph;
|
||||
struct grub_colored_char *p;
|
||||
unsigned char char_width;
|
||||
|
||||
/* Get properties of the character. */
|
||||
glyph = grub_font_get_glyph (virtual_screen.font, c);
|
||||
|
||||
/* Calculate actual character width for glyph. This is number of
|
||||
times of normal_font_width. */
|
||||
char_width = calculate_character_width(glyph);
|
||||
char_width = grub_gfxterm_getcharwidth (term, c);
|
||||
|
||||
/* If we are about to exceed line length, wrap to next line. */
|
||||
if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
|
||||
grub_putchar ('\n');
|
||||
{
|
||||
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
|
||||
scroll_up ();
|
||||
else
|
||||
virtual_screen.cursor_y++;
|
||||
}
|
||||
|
||||
/* Find position on virtual screen, and fill information. */
|
||||
p = (virtual_screen.text_buffer +
|
||||
virtual_screen.cursor_x +
|
||||
virtual_screen.cursor_y * virtual_screen.columns);
|
||||
p->code = c;
|
||||
grub_free (p->code);
|
||||
p->code = grub_unicode_glyph_dup (c);
|
||||
if (!p->code)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
p->fg_color = virtual_screen.fg_color;
|
||||
p->bg_color = virtual_screen.bg_color;
|
||||
p->width = char_width - 1;
|
||||
|
@ -864,7 +891,10 @@ grub_gfxterm_putchar (grub_uint32_t c)
|
|||
|
||||
for (i = 1; i < char_width; i++)
|
||||
{
|
||||
p[i].code = ' ';
|
||||
grub_free (p[i].code);
|
||||
p[i].code = grub_unicode_glyph_from_code (' ');
|
||||
if (!p[i].code)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
p[i].width = char_width - 1;
|
||||
p[i].index = i;
|
||||
}
|
||||
|
@ -929,34 +959,34 @@ calculate_character_width (struct grub_font_glyph *glyph)
|
|||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_gfxterm_getcharwidth (grub_uint32_t c)
|
||||
grub_gfxterm_getcharwidth (struct grub_term_output *term __attribute__ ((unused)),
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
struct grub_font_glyph *glyph;
|
||||
unsigned char char_width;
|
||||
int dev_width;
|
||||
dev_width = grub_font_get_constructed_device_width (virtual_screen.font, c);
|
||||
|
||||
/* Get properties of the character. */
|
||||
glyph = grub_font_get_glyph (virtual_screen.font, c);
|
||||
if (dev_width == 0)
|
||||
return 1;
|
||||
|
||||
/* Calculate actual character width for glyph. */
|
||||
char_width = calculate_character_width (glyph);
|
||||
|
||||
return char_width;
|
||||
return (dev_width + (virtual_screen.normal_char_width - 1))
|
||||
/ virtual_screen.normal_char_width;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_virtual_screen_getwh (void)
|
||||
grub_virtual_screen_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
return (virtual_screen.columns << 8) | virtual_screen.rows;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_virtual_screen_getxy (void)
|
||||
grub_virtual_screen_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
grub_gfxterm_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
||||
grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
if (x >= virtual_screen.columns)
|
||||
x = virtual_screen.columns - 1;
|
||||
|
@ -977,7 +1007,7 @@ grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_cls (void)
|
||||
grub_virtual_screen_cls (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint32_t i;
|
||||
|
||||
|
@ -988,12 +1018,12 @@ grub_virtual_screen_cls (void)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_cls (void)
|
||||
grub_gfxterm_cls (struct grub_term_output *term)
|
||||
{
|
||||
grub_video_color_t color;
|
||||
|
||||
/* Clear virtual screen. */
|
||||
grub_virtual_screen_cls ();
|
||||
grub_virtual_screen_cls (term);
|
||||
|
||||
/* Clear text layer. */
|
||||
grub_video_set_active_render_target (text_layer);
|
||||
|
@ -1005,11 +1035,12 @@ grub_gfxterm_cls (void)
|
|||
/* Mark virtual screen to be redrawn. */
|
||||
dirty_region_add_virtualscreen ();
|
||||
|
||||
grub_gfxterm_refresh ();
|
||||
grub_gfxterm_refresh (term);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_setcolorstate (grub_term_color_state state)
|
||||
grub_virtual_screen_setcolorstate (struct grub_term_output *term,
|
||||
grub_term_color_state state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
|
@ -1018,11 +1049,11 @@ grub_virtual_screen_setcolorstate (grub_term_color_state state)
|
|||
break;
|
||||
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
virtual_screen.term_color = virtual_screen.normal_color_setting;
|
||||
virtual_screen.term_color = term->normal_color;
|
||||
break;
|
||||
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
virtual_screen.term_color = virtual_screen.highlight_color_setting;
|
||||
virtual_screen.term_color = term->highlight_color;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1034,23 +1065,8 @@ grub_virtual_screen_setcolorstate (grub_term_color_state state)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_setcolor (grub_uint8_t normal_color,
|
||||
grub_uint8_t highlight_color)
|
||||
{
|
||||
virtual_screen.normal_color_setting = normal_color;
|
||||
virtual_screen.highlight_color_setting = highlight_color;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_virtual_screen_getcolor (grub_uint8_t *normal_color,
|
||||
grub_uint8_t *highlight_color)
|
||||
{
|
||||
*normal_color = virtual_screen.normal_color_setting;
|
||||
*highlight_color = virtual_screen.highlight_color_setting;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_setcursor (int on)
|
||||
grub_gfxterm_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
int on)
|
||||
{
|
||||
if (virtual_screen.cursor_state != on)
|
||||
{
|
||||
|
@ -1064,7 +1080,7 @@ grub_gfxterm_setcursor (int on)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_gfxterm_refresh (void)
|
||||
grub_gfxterm_refresh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
real_scroll ();
|
||||
|
||||
|
@ -1118,44 +1134,44 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)),
|
|||
/* If filename was provided, try to load that. */
|
||||
if (argc >= 1)
|
||||
{
|
||||
/* Try to load new one. */
|
||||
grub_video_bitmap_load (&bitmap, args[0]);
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
return grub_errno;
|
||||
/* Try to load new one. */
|
||||
grub_video_bitmap_load (&bitmap, args[0]);
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
return grub_errno;
|
||||
|
||||
/* Determine if the bitmap should be scaled to fit the screen. */
|
||||
if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set
|
||||
|| grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg,
|
||||
"stretch") == 0)
|
||||
/* Determine if the bitmap should be scaled to fit the screen. */
|
||||
if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set
|
||||
|| grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg,
|
||||
"stretch") == 0)
|
||||
{
|
||||
if (window.width != grub_video_bitmap_get_width (bitmap)
|
||||
|| window.height != grub_video_bitmap_get_height (bitmap))
|
||||
{
|
||||
struct grub_video_bitmap *scaled_bitmap;
|
||||
grub_video_bitmap_create_scaled (&scaled_bitmap,
|
||||
window.width,
|
||||
window.height,
|
||||
bitmap,
|
||||
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
/* Replace the original bitmap with the scaled one. */
|
||||
grub_video_bitmap_destroy (bitmap);
|
||||
bitmap = scaled_bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If bitmap was loaded correctly, display it. */
|
||||
if (bitmap)
|
||||
{
|
||||
if (window.width != grub_video_bitmap_get_width (bitmap)
|
||||
|| window.height != grub_video_bitmap_get_height (bitmap))
|
||||
{
|
||||
struct grub_video_bitmap *scaled_bitmap;
|
||||
grub_video_bitmap_create_scaled (&scaled_bitmap,
|
||||
window.width,
|
||||
window.height,
|
||||
bitmap,
|
||||
GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
/* Replace the original bitmap with the scaled one. */
|
||||
grub_video_bitmap_destroy (bitmap);
|
||||
bitmap = scaled_bitmap;
|
||||
}
|
||||
}
|
||||
/* Determine bitmap dimensions. */
|
||||
bitmap_width = grub_video_bitmap_get_width (bitmap);
|
||||
bitmap_height = grub_video_bitmap_get_height (bitmap);
|
||||
|
||||
/* Mark whole screen as dirty. */
|
||||
dirty_region_add (0, 0, window.width, window.height);
|
||||
}
|
||||
|
||||
/* If bitmap was loaded correctly, display it. */
|
||||
if (bitmap)
|
||||
{
|
||||
/* Determine bitmap dimensions. */
|
||||
bitmap_width = grub_video_bitmap_get_width (bitmap);
|
||||
bitmap_height = grub_video_bitmap_get_height (bitmap);
|
||||
|
||||
/* Mark whole screen as dirty. */
|
||||
dirty_region_add (0, 0, window.width, window.height);
|
||||
}
|
||||
}
|
||||
|
||||
/* All was ok. */
|
||||
|
@ -1175,11 +1191,11 @@ static struct grub_term_output grub_video_term =
|
|||
.gotoxy = grub_gfxterm_gotoxy,
|
||||
.cls = grub_gfxterm_cls,
|
||||
.setcolorstate = grub_virtual_screen_setcolorstate,
|
||||
.setcolor = grub_virtual_screen_setcolor,
|
||||
.getcolor = grub_virtual_screen_getcolor,
|
||||
.setcursor = grub_gfxterm_setcursor,
|
||||
.refresh = grub_gfxterm_refresh,
|
||||
.flags = 0,
|
||||
.flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS,
|
||||
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
|
||||
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ static const struct grub_machine_bios_data_area *bios_data_area =
|
|||
#define KEYBOARD_ALT (1 << 3)
|
||||
|
||||
static int
|
||||
grub_console_getkeystatus (void)
|
||||
grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint8_t status = bios_data_area->keyboard_flag_lower;
|
||||
int mods = 0;
|
||||
|
@ -57,15 +57,15 @@ static struct grub_term_output grub_console_term_output =
|
|||
{
|
||||
.name = "console",
|
||||
.putchar = grub_console_putchar,
|
||||
.getcharwidth = grub_console_getcharwidth,
|
||||
.getwh = grub_console_getwh,
|
||||
.getxy = grub_console_getxy,
|
||||
.gotoxy = grub_console_gotoxy,
|
||||
.cls = grub_console_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcolor = grub_console_setcolor,
|
||||
.getcolor = grub_console_getcolor,
|
||||
.setcursor = grub_console_setcursor
|
||||
.setcursor = grub_console_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_CP437,
|
||||
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
|
||||
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <grub/i386/vga_common.h>
|
||||
#include <grub/i386/io.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/vga.h>
|
||||
|
||||
#define COLS 80
|
||||
#define ROWS 25
|
||||
|
@ -28,15 +29,6 @@ static int grub_curr_x, grub_curr_y;
|
|||
|
||||
#define VGA_TEXT_SCREEN 0xb8000
|
||||
|
||||
#define CRTC_ADDR_PORT 0x3D4
|
||||
#define CRTC_DATA_PORT 0x3D5
|
||||
|
||||
#define CRTC_CURSOR 0x0a
|
||||
#define CRTC_CURSOR_ADDR_HIGH 0x0e
|
||||
#define CRTC_CURSOR_ADDR_LOW 0x0f
|
||||
|
||||
#define CRTC_CURSOR_DISABLE (1 << 5)
|
||||
|
||||
static void
|
||||
screen_write_char (int x, int y, short c)
|
||||
{
|
||||
|
@ -53,10 +45,8 @@ static void
|
|||
update_cursor (void)
|
||||
{
|
||||
unsigned int pos = grub_curr_y * COLS + grub_curr_x;
|
||||
grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT);
|
||||
grub_outb (pos >> 8, CRTC_DATA_PORT);
|
||||
grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT);
|
||||
grub_outb (pos & 0xFF, CRTC_DATA_PORT);
|
||||
grub_vga_cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH);
|
||||
grub_vga_cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -68,9 +58,11 @@ inc_y (void)
|
|||
else
|
||||
{
|
||||
int x, y;
|
||||
for (y = 0; y < ROWS; y++)
|
||||
for (y = 0; y < ROWS - 1; y++)
|
||||
for (x = 0; x < COLS; x++)
|
||||
screen_write_char (x, y, screen_read_char (x, y + 1));
|
||||
for (x = 0; x < COLS; x++)
|
||||
screen_write_char (x, ROWS - 1, ' ' | (grub_console_cur_color << 8));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,10 +75,11 @@ inc_x (void)
|
|||
grub_curr_x++;
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_real_putchar (int c)
|
||||
static void
|
||||
grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
switch (c)
|
||||
switch (c->base)
|
||||
{
|
||||
case '\b':
|
||||
if (grub_curr_x != 0)
|
||||
|
@ -99,8 +92,8 @@ grub_console_real_putchar (int c)
|
|||
grub_curr_x = 0;
|
||||
break;
|
||||
default:
|
||||
screen_write_char (grub_curr_x,
|
||||
grub_curr_y, c | (grub_console_cur_color << 8));
|
||||
screen_write_char (grub_curr_x, grub_curr_y,
|
||||
c->base | (grub_console_cur_color << 8));
|
||||
inc_x ();
|
||||
}
|
||||
|
||||
|
@ -108,13 +101,14 @@ grub_console_real_putchar (int c)
|
|||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_vga_text_getxy (void)
|
||||
grub_vga_text_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
return (grub_curr_x << 8) | grub_curr_y;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
grub_vga_text_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
||||
grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
grub_curr_x = x;
|
||||
grub_curr_y = y;
|
||||
|
@ -122,30 +116,32 @@ grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_vga_text_cls (void)
|
||||
grub_vga_text_cls (struct grub_term_output *term)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ROWS * COLS; i++)
|
||||
((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8);
|
||||
grub_vga_text_gotoxy (0, 0);
|
||||
grub_vga_text_gotoxy (term, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_vga_text_setcursor (int on)
|
||||
grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
int on)
|
||||
{
|
||||
grub_uint8_t old;
|
||||
grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT);
|
||||
old = grub_inb (CRTC_DATA_PORT);
|
||||
old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR_START);
|
||||
if (on)
|
||||
grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
|
||||
grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE,
|
||||
GRUB_VGA_CR_CURSOR_START);
|
||||
else
|
||||
grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT);
|
||||
grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE,
|
||||
GRUB_VGA_CR_CURSOR_START);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_vga_text_init_fini (void)
|
||||
grub_vga_text_init_fini (struct grub_term_output *term)
|
||||
{
|
||||
grub_vga_text_cls ();
|
||||
grub_vga_text_cls (term);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -154,16 +150,16 @@ static struct grub_term_output grub_vga_text_term =
|
|||
.name = "vga_text",
|
||||
.init = grub_vga_text_init_fini,
|
||||
.fini = grub_vga_text_init_fini,
|
||||
.putchar = grub_console_putchar,
|
||||
.getcharwidth = grub_console_getcharwidth,
|
||||
.putchar = grub_vga_text_putchar,
|
||||
.getwh = grub_console_getwh,
|
||||
.getxy = grub_vga_text_getxy,
|
||||
.gotoxy = grub_vga_text_gotoxy,
|
||||
.cls = grub_vga_text_cls,
|
||||
.setcolorstate = grub_console_setcolorstate,
|
||||
.setcolor = grub_console_setcolor,
|
||||
.getcolor = grub_console_getcolor,
|
||||
.setcursor = grub_vga_text_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_CP437,
|
||||
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
|
||||
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(vga_text)
|
||||
|
|
|
@ -21,105 +21,28 @@
|
|||
#include <grub/types.h>
|
||||
|
||||
grub_uint8_t grub_console_cur_color = 0x7;
|
||||
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 grub_uint32_t
|
||||
map_char (grub_uint32_t c)
|
||||
{
|
||||
if (c > 0x7f)
|
||||
{
|
||||
/* Map some unicode characters to the VGA font, if possible. */
|
||||
switch (c)
|
||||
{
|
||||
case 0x2190: /* left arrow */
|
||||
c = 0x1b;
|
||||
break;
|
||||
case 0x2191: /* up arrow */
|
||||
c = 0x18;
|
||||
break;
|
||||
case 0x2192: /* right arrow */
|
||||
c = 0x1a;
|
||||
break;
|
||||
case 0x2193: /* down arrow */
|
||||
c = 0x19;
|
||||
break;
|
||||
case 0x2501: /* horizontal line */
|
||||
c = 0xc4;
|
||||
break;
|
||||
case 0x2503: /* vertical line */
|
||||
c = 0xb3;
|
||||
break;
|
||||
case 0x250F: /* upper-left corner */
|
||||
c = 0xda;
|
||||
break;
|
||||
case 0x2513: /* upper-right corner */
|
||||
c = 0xbf;
|
||||
break;
|
||||
case 0x2517: /* lower-left corner */
|
||||
c = 0xc0;
|
||||
break;
|
||||
case 0x251B: /* lower-right corner */
|
||||
c = 0xd9;
|
||||
break;
|
||||
|
||||
default:
|
||||
c = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_putchar (grub_uint32_t c)
|
||||
{
|
||||
grub_console_real_putchar (map_char (c));
|
||||
}
|
||||
|
||||
grub_ssize_t
|
||||
grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
|
||||
{
|
||||
/* For now, every printable character has the width 1. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_uint16_t
|
||||
grub_console_getwh (void)
|
||||
grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
return (80 << 8) | 25;
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_setcolorstate (grub_term_color_state state)
|
||||
grub_console_setcolorstate (struct grub_term_output *term,
|
||||
grub_term_color_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
grub_console_cur_color = grub_console_standard_color;
|
||||
grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR;
|
||||
break;
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
grub_console_cur_color = grub_console_normal_color;
|
||||
grub_console_cur_color = term->normal_color;
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
grub_console_cur_color = grub_console_highlight_color;
|
||||
grub_console_cur_color = term->highlight_color;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
|
||||
{
|
||||
grub_console_normal_color = normal_color;
|
||||
grub_console_highlight_color = highlight_color;
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
|
||||
{
|
||||
*normal_color = grub_console_normal_color;
|
||||
*highlight_color = grub_console_highlight_color;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/machine/console.h>
|
||||
#include <grub/terminfo.h>
|
||||
#include <grub/ieee1275/console.h>
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
|
||||
static grub_ieee1275_ihandle_t stdout_ihandle;
|
||||
|
@ -31,12 +32,6 @@ static grub_ieee1275_ihandle_t stdin_ihandle;
|
|||
static grub_uint8_t grub_ofconsole_width;
|
||||
static grub_uint8_t grub_ofconsole_height;
|
||||
|
||||
static int grub_curr_x;
|
||||
static int grub_curr_y;
|
||||
|
||||
static int grub_keybuf;
|
||||
static int grub_buflen;
|
||||
|
||||
struct color
|
||||
{
|
||||
int red;
|
||||
|
@ -44,292 +39,41 @@ struct color
|
|||
int blue;
|
||||
};
|
||||
|
||||
/* Use serial colors as they are default on most firmwares and some firmwares
|
||||
ignore set-color!. Additionally output may be redirected to serial. */
|
||||
static struct color colors[] =
|
||||
{
|
||||
// {R, G, B}
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0xA8}, // 1 = blue
|
||||
{0x00, 0x00, 0x00}, // 0 = black
|
||||
{0xA8, 0x00, 0x00}, // 1 = red
|
||||
{0x00, 0xA8, 0x00}, // 2 = green
|
||||
{0x00, 0xA8, 0xA8}, // 3 = cyan
|
||||
{0xA8, 0x00, 0x00}, // 4 = red
|
||||
{0xFE, 0xFE, 0x54}, // 3 = yellow
|
||||
{0x00, 0x00, 0xA8}, // 4 = blue
|
||||
{0xA8, 0x00, 0xA8}, // 5 = magenta
|
||||
{0xFE, 0xFE, 0x54}, // 6 = yellow
|
||||
{0x00, 0xA8, 0xA8}, // 6 = cyan
|
||||
{0xFE, 0xFE, 0xFE} // 7 = white
|
||||
};
|
||||
|
||||
static grub_uint8_t grub_ofconsole_normal_color = 0x7;
|
||||
static grub_uint8_t grub_ofconsole_highlight_color = 0x70;
|
||||
|
||||
/* Write control characters to the console. */
|
||||
static void
|
||||
grub_ofconsole_writeesc (const char *str)
|
||||
put (const int c)
|
||||
{
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
|
||||
return;
|
||||
char chr = c;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
char chr = *(str++);
|
||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_putchar (grub_uint32_t c)
|
||||
{
|
||||
char chr;
|
||||
|
||||
if (c > 0x7F)
|
||||
{
|
||||
/* Better than nothing. */
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_DISP_LEFT:
|
||||
c = '<';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_UP:
|
||||
c = '^';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_RIGHT:
|
||||
c = '>';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_DOWN:
|
||||
c = 'v';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_HLINE:
|
||||
c = '-';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_VLINE:
|
||||
c = '|';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_UL:
|
||||
case GRUB_TERM_DISP_UR:
|
||||
case GRUB_TERM_DISP_LL:
|
||||
case GRUB_TERM_DISP_LR:
|
||||
c = '+';
|
||||
break;
|
||||
|
||||
default:
|
||||
c = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chr = c;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
grub_curr_y++;
|
||||
grub_curr_x = 0;
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
grub_curr_x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_curr_x++;
|
||||
if (grub_curr_x >= grub_ofconsole_width)
|
||||
{
|
||||
grub_ofconsole_putchar ('\n');
|
||||
grub_ofconsole_putchar ('\r');
|
||||
grub_curr_x++;
|
||||
}
|
||||
}
|
||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_setcolorstate (grub_term_color_state state)
|
||||
{
|
||||
char setcol[256];
|
||||
int fg;
|
||||
int bg;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
fg = grub_ofconsole_normal_color & 0x0f;
|
||||
bg = grub_ofconsole_normal_color >> 4;
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
fg = grub_ofconsole_highlight_color & 0x0f;
|
||||
bg = grub_ofconsole_highlight_color >> 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
grub_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg);
|
||||
grub_ofconsole_writeesc (setcol);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_setcolor (grub_uint8_t normal_color,
|
||||
grub_uint8_t highlight_color)
|
||||
{
|
||||
/* Discard bright bit. */
|
||||
grub_ofconsole_normal_color = normal_color & 0x77;
|
||||
grub_ofconsole_highlight_color = highlight_color & 0x77;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
|
||||
{
|
||||
*normal_color = grub_ofconsole_normal_color;
|
||||
*highlight_color = grub_ofconsole_highlight_color;
|
||||
}
|
||||
|
||||
#define ANSI_C0 0x9b
|
||||
|
||||
static int
|
||||
grub_ofconsole_readkey (int *key)
|
||||
readkey (void)
|
||||
{
|
||||
grub_uint8_t c;
|
||||
grub_ssize_t actual = 0;
|
||||
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
if (actual > 0)
|
||||
switch(c)
|
||||
{
|
||||
case 0x7f:
|
||||
/* Backspace: Ctrl-h. */
|
||||
c = '\b';
|
||||
break;
|
||||
case ANSI_C0:
|
||||
case '\e':
|
||||
{
|
||||
grub_uint64_t start;
|
||||
|
||||
if (c == '\e')
|
||||
{
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
|
||||
/* On 9600 we have to wait up to 12 milliseconds. */
|
||||
start = grub_get_time_ms ();
|
||||
while (actual <= 0 && grub_get_time_ms () - start < 12)
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
|
||||
if (actual <= 0)
|
||||
{
|
||||
*key = '\e';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c != '[')
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
|
||||
/* On 9600 we have to wait up to 12 milliseconds. */
|
||||
start = grub_get_time_ms ();
|
||||
while (actual <= 0 && grub_get_time_ms () - start < 12)
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
if (actual <= 0)
|
||||
return 0;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'A':
|
||||
/* Up: Ctrl-p. */
|
||||
c = GRUB_TERM_UP;
|
||||
break;
|
||||
case 'B':
|
||||
/* Down: Ctrl-n. */
|
||||
c = GRUB_TERM_DOWN;
|
||||
break;
|
||||
case 'C':
|
||||
/* Right: Ctrl-f. */
|
||||
c = GRUB_TERM_RIGHT;
|
||||
break;
|
||||
case 'D':
|
||||
/* Left: Ctrl-b. */
|
||||
c = GRUB_TERM_LEFT;
|
||||
break;
|
||||
case '3':
|
||||
{
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
/* On 9600 we have to wait up to 12 milliseconds. */
|
||||
start = grub_get_time_ms ();
|
||||
while (actual <= 0 && grub_get_time_ms () - start < 12)
|
||||
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
|
||||
|
||||
if (actual <= 0)
|
||||
return 0;
|
||||
|
||||
/* Delete: Ctrl-d. */
|
||||
if (c == '~')
|
||||
c = GRUB_TERM_DC;
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*key = c;
|
||||
return actual > 0;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofconsole_checkkey (void)
|
||||
{
|
||||
int key;
|
||||
int read;
|
||||
|
||||
if (grub_buflen)
|
||||
return 1;
|
||||
|
||||
read = grub_ofconsole_readkey (&key);
|
||||
if (read)
|
||||
{
|
||||
grub_keybuf = key;
|
||||
grub_buflen = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return c;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofconsole_getkey (void)
|
||||
{
|
||||
int key;
|
||||
|
||||
if (grub_buflen)
|
||||
{
|
||||
grub_buflen =0;
|
||||
return grub_keybuf;
|
||||
}
|
||||
|
||||
while (! grub_ofconsole_readkey (&key));
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_ofconsole_getxy (void)
|
||||
{
|
||||
return (grub_curr_x << 8) | grub_curr_y;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_dimensions (void)
|
||||
{
|
||||
|
@ -367,50 +111,14 @@ grub_ofconsole_dimensions (void)
|
|||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_ofconsole_getwh (void)
|
||||
grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
|
||||
{
|
||||
char s[256];
|
||||
grub_curr_x = x;
|
||||
grub_curr_y = y;
|
||||
|
||||
grub_snprintf (s, sizeof (s), "\e[%d;%dH", y + 1, x + 1);
|
||||
grub_ofconsole_writeesc (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y == grub_curr_y) && (x == grub_curr_x - 1))
|
||||
{
|
||||
char chr;
|
||||
|
||||
chr = '\b';
|
||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
||||
}
|
||||
|
||||
grub_curr_x = x;
|
||||
grub_curr_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_cls (void)
|
||||
{
|
||||
/* Clear the screen. Using serial console, screen(1) only recognizes the
|
||||
* ANSI escape sequence. Using video console, Apple Open Firmware (version
|
||||
* 3.1.1) only recognizes the literal ^L. So use both. */
|
||||
grub_ofconsole_writeesc ("\e[2J");
|
||||
grub_ofconsole_gotoxy (0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_setcursor (int on)
|
||||
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||
int on)
|
||||
{
|
||||
/* Understood by the Open Firmware flavour in OLPC. */
|
||||
if (on)
|
||||
|
@ -419,14 +127,8 @@ grub_ofconsole_setcursor (int on)
|
|||
grub_ieee1275_interpret ("cursor-off", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofconsole_refresh (void)
|
||||
{
|
||||
/* Do nothing, the current console state is ok. */
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_ofconsole_init_input (void)
|
||||
grub_ofconsole_init_input (struct grub_term_input *term)
|
||||
{
|
||||
grub_ssize_t actual;
|
||||
|
||||
|
@ -435,11 +137,11 @@ grub_ofconsole_init_input (void)
|
|||
|| actual != sizeof stdin_ihandle)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
|
||||
|
||||
return 0;
|
||||
return grub_terminfo_input_init (term);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_ofconsole_init_output (void)
|
||||
grub_ofconsole_init_output (struct grub_term_output *term)
|
||||
{
|
||||
grub_ssize_t actual;
|
||||
|
||||
|
@ -462,8 +164,8 @@ grub_ofconsole_init_output (void)
|
|||
grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
|
||||
colors[col].green, colors[col].blue);
|
||||
|
||||
/* Set the right fg and bg colors. */
|
||||
grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
|
||||
/* Set the right fg and bg colors. */
|
||||
grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||
}
|
||||
|
||||
grub_ofconsole_dimensions ();
|
||||
|
@ -471,51 +173,74 @@ grub_ofconsole_init_output (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_ofconsole_fini (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
struct grub_terminfo_input_state grub_ofconsole_terminfo_input =
|
||||
{
|
||||
.readkey = readkey
|
||||
};
|
||||
|
||||
struct grub_terminfo_output_state grub_ofconsole_terminfo_output =
|
||||
{
|
||||
.put = put
|
||||
};
|
||||
|
||||
static struct grub_term_input grub_ofconsole_term_input =
|
||||
{
|
||||
.name = "ofconsole",
|
||||
.init = grub_ofconsole_init_input,
|
||||
.fini = grub_ofconsole_fini,
|
||||
.checkkey = grub_ofconsole_checkkey,
|
||||
.getkey = grub_ofconsole_getkey,
|
||||
.checkkey = grub_terminfo_checkkey,
|
||||
.getkey = grub_terminfo_getkey,
|
||||
.data = &grub_ofconsole_terminfo_input
|
||||
};
|
||||
|
||||
static struct grub_term_output grub_ofconsole_term_output =
|
||||
{
|
||||
.name = "ofconsole",
|
||||
.init = grub_ofconsole_init_output,
|
||||
.fini = grub_ofconsole_fini,
|
||||
.putchar = grub_ofconsole_putchar,
|
||||
.getcharwidth = grub_ofconsole_getcharwidth,
|
||||
.getxy = grub_ofconsole_getxy,
|
||||
.putchar = grub_terminfo_putchar,
|
||||
.getxy = grub_terminfo_getxy,
|
||||
.getwh = grub_ofconsole_getwh,
|
||||
.gotoxy = grub_ofconsole_gotoxy,
|
||||
.cls = grub_ofconsole_cls,
|
||||
.setcolorstate = grub_ofconsole_setcolorstate,
|
||||
.setcolor = grub_ofconsole_setcolor,
|
||||
.getcolor = grub_ofconsole_getcolor,
|
||||
.gotoxy = grub_terminfo_gotoxy,
|
||||
.cls = grub_terminfo_cls,
|
||||
.setcolorstate = grub_terminfo_setcolorstate,
|
||||
.setcursor = grub_ofconsole_setcursor,
|
||||
.refresh = grub_ofconsole_refresh
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_ofconsole_terminfo_output,
|
||||
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
|
||||
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
|
||||
};
|
||||
|
||||
void grub_terminfo_fini (void);
|
||||
void grub_terminfo_init (void);
|
||||
|
||||
void
|
||||
grub_console_init (void)
|
||||
grub_console_init_early (void)
|
||||
{
|
||||
grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
|
||||
grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_init_lately (void)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
|
||||
type = "dumb";
|
||||
else
|
||||
type = "ieee1275";
|
||||
|
||||
grub_terminfo_init ();
|
||||
grub_terminfo_output_register (&grub_ofconsole_term_output, type);
|
||||
}
|
||||
|
||||
void
|
||||
grub_console_fini (void)
|
||||
{
|
||||
grub_term_unregister_input (&grub_ofconsole_term_input);
|
||||
grub_term_unregister_output (&grub_ofconsole_term_output);
|
||||
grub_terminfo_output_unregister (&grub_ofconsole_term_output);
|
||||
|
||||
grub_terminfo_fini ();
|
||||
}
|
||||
|
|
|
@ -27,19 +27,8 @@
|
|||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
#define TEXT_WIDTH 80
|
||||
#define TEXT_HEIGHT 24
|
||||
|
||||
static unsigned int xpos, ypos;
|
||||
static unsigned int keep_track = 1;
|
||||
static unsigned int registered = 0;
|
||||
|
||||
/* An input buffer. */
|
||||
static char input_buf[8];
|
||||
static unsigned int npending = 0;
|
||||
|
||||
static struct grub_term_output grub_serial_term_output;
|
||||
|
||||
/* Argument options. */
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
|
@ -111,98 +100,6 @@ serial_hw_put (const int c)
|
|||
grub_outb (c, serial_settings.port + UART_TX);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_translate_key_sequence (void)
|
||||
{
|
||||
unsigned int i;
|
||||
static struct
|
||||
{
|
||||
char key;
|
||||
char ascii;
|
||||
}
|
||||
three_code_table[] =
|
||||
{
|
||||
{'A', 16},
|
||||
{'B', 14},
|
||||
{'C', 6},
|
||||
{'D', 2},
|
||||
{'F', 5},
|
||||
{'H', 1},
|
||||
{'4', 4}
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
short key;
|
||||
char ascii;
|
||||
}
|
||||
four_code_table[] =
|
||||
{
|
||||
{('1' | ('~' << 8)), 1},
|
||||
{('3' | ('~' << 8)), 4},
|
||||
{('5' | ('~' << 8)), 7},
|
||||
{('6' | ('~' << 8)), 3}
|
||||
};
|
||||
|
||||
if (npending < 3)
|
||||
return;
|
||||
|
||||
/* The buffer must start with "ESC [". */
|
||||
if (input_buf[0] != '\e' || input_buf[1] != '[')
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
|
||||
if (three_code_table[i].key == input_buf[2])
|
||||
{
|
||||
input_buf[0] = three_code_table[i].ascii;
|
||||
npending -= 2;
|
||||
grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (npending >= 4)
|
||||
{
|
||||
short key = input_buf[3] | (input_buf[4] << 8);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
|
||||
if (four_code_table[i].key == key)
|
||||
{
|
||||
input_buf[0] = four_code_table[i].ascii;
|
||||
npending -= 3;
|
||||
grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fill_input_buf (const int nowait)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = serial_hw_fetch ();
|
||||
if (c >= 0)
|
||||
{
|
||||
input_buf[npending++] = c;
|
||||
|
||||
/* Reset the counter to zero, to wait for the same interval. */
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (nowait)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Translate some key sequences. */
|
||||
serial_translate_key_sequence ();
|
||||
|
||||
return npending;
|
||||
}
|
||||
|
||||
/* Convert speed to divisor. */
|
||||
static unsigned short
|
||||
serial_get_divisor (unsigned int speed)
|
||||
|
@ -241,34 +138,6 @@ serial_get_divisor (unsigned int speed)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* The serial version of checkkey. */
|
||||
static int
|
||||
grub_serial_checkkey (void)
|
||||
{
|
||||
if (fill_input_buf (1))
|
||||
return input_buf[0];
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The serial version of getkey. */
|
||||
static int
|
||||
grub_serial_getkey (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while (! fill_input_buf (0))
|
||||
;
|
||||
|
||||
c = input_buf[0];
|
||||
if (c == 0x7f)
|
||||
c = GRUB_TERM_BACKSPACE;
|
||||
|
||||
grub_memmove (input_buf, input_buf + 1, --npending);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Initialize a serial device. PORT is the port number for a serial device.
|
||||
SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
|
||||
19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
|
||||
|
@ -300,198 +169,68 @@ serial_hw_init (void)
|
|||
/* In Yeeloong serial port has only 3 wires. */
|
||||
#ifndef GRUB_MACHINE_MIPS_YEELOONG
|
||||
/* Enable the FIFO. */
|
||||
grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR);
|
||||
grub_outb (UART_ENABLE_FIFO_TRIGGER1, serial_settings.port + UART_FCR);
|
||||
|
||||
/* Turn on DTR and RTS. */
|
||||
grub_outb (UART_ENABLE_DTRRTS, serial_settings.port + UART_MCR);
|
||||
#else
|
||||
/* Enable the FIFO. */
|
||||
grub_outb (UART_ENABLE_FIFO_TRIGGER14, serial_settings.port + UART_FCR);
|
||||
|
||||
/* Turn on DTR, RTS, and OUT2. */
|
||||
grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR);
|
||||
grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2,
|
||||
serial_settings.port + UART_MCR);
|
||||
#endif
|
||||
|
||||
/* Drain the input buffer. */
|
||||
while (grub_serial_checkkey () != -1)
|
||||
(void) grub_serial_getkey ();
|
||||
while (serial_hw_fetch () != -1);
|
||||
|
||||
/* FIXME: should check if the serial terminal was found. */
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* The serial version of putchar. */
|
||||
static void
|
||||
grub_serial_putchar (grub_uint32_t c)
|
||||
{
|
||||
/* Keep track of the cursor. */
|
||||
if (keep_track)
|
||||
{
|
||||
/* The serial terminal does not have VGA fonts. */
|
||||
if (c > 0x7F)
|
||||
{
|
||||
/* Better than nothing. */
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_DISP_LEFT:
|
||||
c = '<';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_UP:
|
||||
c = '^';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_RIGHT:
|
||||
c = '>';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_DOWN:
|
||||
c = 'v';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_HLINE:
|
||||
c = '-';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_VLINE:
|
||||
c = '|';
|
||||
break;
|
||||
|
||||
case GRUB_TERM_DISP_UL:
|
||||
case GRUB_TERM_DISP_UR:
|
||||
case GRUB_TERM_DISP_LL:
|
||||
case GRUB_TERM_DISP_LR:
|
||||
c = '+';
|
||||
break;
|
||||
|
||||
default:
|
||||
c = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\a':
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
case 127:
|
||||
if (xpos > 0)
|
||||
xpos--;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (ypos < TEXT_HEIGHT - 1)
|
||||
ypos++;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
xpos = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (xpos >= TEXT_WIDTH)
|
||||
{
|
||||
grub_putchar ('\r');
|
||||
grub_putchar ('\n');
|
||||
}
|
||||
xpos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
serial_hw_put (c);
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_serial_getwh (void)
|
||||
grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||
{
|
||||
const grub_uint8_t TEXT_WIDTH = 80;
|
||||
const grub_uint8_t TEXT_HEIGHT = 24;
|
||||
return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_serial_getxy (void)
|
||||
{
|
||||
return ((xpos << 8) | ypos);
|
||||
}
|
||||
struct grub_terminfo_input_state grub_serial_terminfo_input =
|
||||
{
|
||||
.readkey = serial_hw_fetch
|
||||
};
|
||||
|
||||
static void
|
||||
grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
keep_track = 0;
|
||||
grub_terminfo_gotoxy (x, y, &grub_serial_term_output);
|
||||
keep_track = 1;
|
||||
|
||||
xpos = x;
|
||||
ypos = y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_serial_cls (void)
|
||||
{
|
||||
keep_track = 0;
|
||||
grub_terminfo_cls (&grub_serial_term_output);
|
||||
keep_track = 1;
|
||||
|
||||
xpos = ypos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_serial_setcolorstate (const grub_term_color_state state)
|
||||
{
|
||||
keep_track = 0;
|
||||
switch (state)
|
||||
{
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
grub_terminfo_reverse_video_off (&grub_serial_term_output);
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
grub_terminfo_reverse_video_on (&grub_serial_term_output);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
keep_track = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_serial_setcursor (const int on)
|
||||
{
|
||||
if (on)
|
||||
grub_terminfo_cursor_on (&grub_serial_term_output);
|
||||
else
|
||||
grub_terminfo_cursor_off (&grub_serial_term_output);
|
||||
}
|
||||
struct grub_terminfo_output_state grub_serial_terminfo_output =
|
||||
{
|
||||
.put = serial_hw_put
|
||||
};
|
||||
|
||||
static struct grub_term_input grub_serial_term_input =
|
||||
{
|
||||
.name = "serial",
|
||||
.checkkey = grub_serial_checkkey,
|
||||
.getkey = grub_serial_getkey,
|
||||
.init = grub_terminfo_input_init,
|
||||
.checkkey = grub_terminfo_checkkey,
|
||||
.getkey = grub_terminfo_getkey,
|
||||
.data = &grub_serial_terminfo_input
|
||||
};
|
||||
|
||||
static struct grub_term_output grub_serial_term_output =
|
||||
{
|
||||
.name = "serial",
|
||||
.putchar = grub_serial_putchar,
|
||||
.getcharwidth = grub_serial_getcharwidth,
|
||||
.putchar = grub_terminfo_putchar,
|
||||
.getwh = grub_serial_getwh,
|
||||
.getxy = grub_serial_getxy,
|
||||
.gotoxy = grub_serial_gotoxy,
|
||||
.cls = grub_serial_cls,
|
||||
.setcolorstate = grub_serial_setcolorstate,
|
||||
.setcursor = grub_serial_setcursor,
|
||||
.flags = 0,
|
||||
.getxy = grub_terminfo_getxy,
|
||||
.gotoxy = grub_terminfo_gotoxy,
|
||||
.cls = grub_terminfo_cls,
|
||||
.setcolorstate = grub_terminfo_setcolorstate,
|
||||
.setcursor = grub_terminfo_setcursor,
|
||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||
.data = &grub_serial_terminfo_output,
|
||||
.normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR,
|
||||
.highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR,
|
||||
};
|
||||
|
||||
|
||||
|
@ -586,6 +325,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
|
|||
{
|
||||
grub_term_register_input ("serial", &grub_serial_term_input);
|
||||
grub_term_register_output ("serial", &grub_serial_term_output);
|
||||
grub_terminfo_output_register (&grub_serial_term_output, "vt100");
|
||||
registered = 1;
|
||||
}
|
||||
}
|
||||
|
@ -602,6 +342,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
|
|||
/* If unable to restore settings, unregister terminal. */
|
||||
grub_term_unregister_input (&grub_serial_term_input);
|
||||
grub_term_unregister_output (&grub_serial_term_output);
|
||||
grub_terminfo_output_unregister (&grub_serial_term_output);
|
||||
registered = 0;
|
||||
}
|
||||
}
|
||||
|
@ -629,6 +370,21 @@ GRUB_MOD_INIT(serial)
|
|||
serial_settings.word_len = UART_8BITS_WORD;
|
||||
serial_settings.parity = UART_NO_PARITY;
|
||||
serial_settings.stop_bits = UART_1_STOP_BIT;
|
||||
|
||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
||||
{
|
||||
grub_err_t hwiniterr;
|
||||
hwiniterr = serial_hw_init ();
|
||||
|
||||
if (hwiniterr == GRUB_ERR_NONE)
|
||||
{
|
||||
grub_term_register_input_active ("serial", &grub_serial_term_input);
|
||||
grub_term_register_output_active ("serial", &grub_serial_term_output);
|
||||
|
||||
registered = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(serial)
|
||||
|
@ -638,5 +394,6 @@ GRUB_MOD_FINI(serial)
|
|||
{
|
||||
grub_term_unregister_input (&grub_serial_term_input);
|
||||
grub_term_unregister_output (&grub_serial_term_output);
|
||||
grub_terminfo_output_unregister (&grub_serial_term_output);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,26 +32,17 @@
|
|||
#include <grub/tparm.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
|
||||
struct terminfo
|
||||
{
|
||||
char *name;
|
||||
|
||||
char *gotoxy;
|
||||
char *cls;
|
||||
char *reverse_video_on;
|
||||
char *reverse_video_off;
|
||||
char *cursor_on;
|
||||
char *cursor_off;
|
||||
};
|
||||
|
||||
static struct terminfo term;
|
||||
static struct grub_term_output *terminfo_outputs;
|
||||
|
||||
/* Get current terminfo name. */
|
||||
char *
|
||||
grub_terminfo_get_current (void)
|
||||
grub_terminfo_get_current (struct grub_term_output *term)
|
||||
{
|
||||
return term.name;
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
return data->name;
|
||||
}
|
||||
|
||||
/* Free *PTR and set *PTR to NULL, to prevent double-free. */
|
||||
|
@ -62,10 +53,29 @@ grub_terminfo_free (char **ptr)
|
|||
*ptr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_terminfo_all_free (struct grub_term_output *term)
|
||||
{
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
/* Free previously allocated memory. */
|
||||
grub_terminfo_free (&data->name);
|
||||
grub_terminfo_free (&data->gotoxy);
|
||||
grub_terminfo_free (&data->cls);
|
||||
grub_terminfo_free (&data->reverse_video_on);
|
||||
grub_terminfo_free (&data->reverse_video_off);
|
||||
grub_terminfo_free (&data->cursor_on);
|
||||
grub_terminfo_free (&data->cursor_off);
|
||||
}
|
||||
|
||||
/* Set current terminfo type. */
|
||||
grub_err_t
|
||||
grub_terminfo_set_current (const char *str)
|
||||
grub_terminfo_set_current (struct grub_term_output *term,
|
||||
const char *str)
|
||||
{
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
/* TODO
|
||||
* Lookup user specified terminfo type. If found, set term variables
|
||||
* as appropriate. Otherwise return an error.
|
||||
|
@ -83,95 +93,518 @@ grub_terminfo_set_current (const char *str)
|
|||
* d. Your idea here.
|
||||
*/
|
||||
|
||||
/* Free previously allocated memory. */
|
||||
grub_terminfo_free (&term.name);
|
||||
grub_terminfo_free (&term.gotoxy);
|
||||
grub_terminfo_free (&term.cls);
|
||||
grub_terminfo_free (&term.reverse_video_on);
|
||||
grub_terminfo_free (&term.reverse_video_off);
|
||||
grub_terminfo_free (&term.cursor_on);
|
||||
grub_terminfo_free (&term.cursor_off);
|
||||
grub_terminfo_all_free (term);
|
||||
|
||||
if (grub_strcmp ("vt100", str) == 0)
|
||||
{
|
||||
term.name = grub_strdup ("vt100");
|
||||
term.gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
||||
term.cls = grub_strdup ("\e[H\e[J");
|
||||
term.reverse_video_on = grub_strdup ("\e[7m");
|
||||
term.reverse_video_off = grub_strdup ("\e[m");
|
||||
term.cursor_on = grub_strdup ("\e[?25h");
|
||||
term.cursor_off = grub_strdup ("\e[?25l");
|
||||
data->name = grub_strdup ("vt100");
|
||||
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
||||
data->cls = grub_strdup ("\e[H\e[J");
|
||||
data->reverse_video_on = grub_strdup ("\e[7m");
|
||||
data->reverse_video_off = grub_strdup ("\e[m");
|
||||
data->cursor_on = grub_strdup ("\e[?25h");
|
||||
data->cursor_off = grub_strdup ("\e[?25l");
|
||||
data->setcolor = NULL;
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_strcmp ("vt100-color", str) == 0)
|
||||
{
|
||||
data->name = grub_strdup ("vt100-color");
|
||||
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
||||
data->cls = grub_strdup ("\e[H\e[J");
|
||||
data->reverse_video_on = grub_strdup ("\e[7m");
|
||||
data->reverse_video_off = grub_strdup ("\e[m");
|
||||
data->cursor_on = grub_strdup ("\e[?25h");
|
||||
data->cursor_off = grub_strdup ("\e[?25l");
|
||||
data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_strcmp ("ieee1275", str) == 0)
|
||||
{
|
||||
data->name = grub_strdup ("ieee1275");
|
||||
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
||||
/* Clear the screen. Using serial console, screen(1) only recognizes the
|
||||
* ANSI escape sequence. Using video console, Apple Open Firmware
|
||||
* (version 3.1.1) only recognizes the literal ^L. So use both. */
|
||||
data->cls = grub_strdup ("\e[2J");
|
||||
data->reverse_video_on = grub_strdup ("\e[7m");
|
||||
data->reverse_video_off = grub_strdup ("\e[m");
|
||||
data->cursor_on = grub_strdup ("\e[?25h");
|
||||
data->cursor_off = grub_strdup ("\e[?25l");
|
||||
data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm");
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_strcmp ("dumb", str) == 0)
|
||||
{
|
||||
data->name = grub_strdup ("dumb");
|
||||
data->gotoxy = NULL;
|
||||
data->cls = NULL;
|
||||
data->reverse_video_on = NULL;
|
||||
data->reverse_video_off = NULL;
|
||||
data->cursor_on = NULL;
|
||||
data->cursor_off = NULL;
|
||||
data->setcolor = NULL;
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
|
||||
}
|
||||
|
||||
/* Wrapper for grub_putchar to write strings. */
|
||||
static void
|
||||
putstr (const char *str, grub_term_output_t oterm)
|
||||
grub_err_t
|
||||
grub_terminfo_output_register (struct grub_term_output *term,
|
||||
const char *type)
|
||||
{
|
||||
while (*str)
|
||||
grub_putcode (*str++, oterm);
|
||||
grub_err_t err;
|
||||
struct grub_terminfo_output_state *data;
|
||||
|
||||
err = grub_terminfo_set_current (term, type);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
data = (struct grub_terminfo_output_state *) term->data;
|
||||
data->next = terminfo_outputs;
|
||||
terminfo_outputs = term;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Move the cursor to the given position starting with "0". */
|
||||
void
|
||||
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
|
||||
grub_err_t
|
||||
grub_terminfo_output_unregister (struct grub_term_output *term)
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
|
||||
struct grub_term_output **ptr;
|
||||
|
||||
for (ptr = &terminfo_outputs; *ptr;
|
||||
ptr = &((struct grub_terminfo_output_state *) (*ptr)->data)->next)
|
||||
if (*ptr == term)
|
||||
{
|
||||
grub_terminfo_all_free (term);
|
||||
*ptr = ((struct grub_terminfo_output_state *) (*ptr)->data)->next;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "terminal not found");
|
||||
}
|
||||
|
||||
/* Wrapper for grub_putchar to write strings. */
|
||||
static void
|
||||
putstr (struct grub_term_output *term, const char *str)
|
||||
{
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
while (*str)
|
||||
data->put (*str++);
|
||||
}
|
||||
|
||||
grub_uint16_t
|
||||
grub_terminfo_getxy (struct grub_term_output *term)
|
||||
{
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
return ((data->xpos << 8) | data->ypos);
|
||||
}
|
||||
|
||||
void
|
||||
grub_terminfo_gotoxy (struct grub_term_output *term,
|
||||
grub_uint8_t x, grub_uint8_t y)
|
||||
{
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
if (x > grub_term_width (term) || y > grub_term_height (term))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->gotoxy)
|
||||
putstr (term, grub_terminfo_tparm (data->gotoxy, y, x));
|
||||
else
|
||||
{
|
||||
if ((y == data->ypos) && (x == data->xpos - 1))
|
||||
data->put ('\b');
|
||||
}
|
||||
|
||||
data->xpos = x;
|
||||
data->ypos = y;
|
||||
}
|
||||
|
||||
/* Clear the screen. */
|
||||
void
|
||||
grub_terminfo_cls (grub_term_output_t oterm)
|
||||
grub_terminfo_cls (struct grub_term_output *term)
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.cls), oterm);
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
putstr (term, grub_terminfo_tparm (data->cls));
|
||||
|
||||
data->xpos = data->ypos = 0;
|
||||
}
|
||||
|
||||
/* Set reverse video mode on. */
|
||||
void
|
||||
grub_terminfo_reverse_video_on (grub_term_output_t oterm)
|
||||
grub_terminfo_setcolorstate (struct grub_term_output *term,
|
||||
const grub_term_color_state state)
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
if (data->setcolor)
|
||||
{
|
||||
int fg;
|
||||
int bg;
|
||||
/* Map from VGA to terminal colors. */
|
||||
const int colormap[8]
|
||||
= { 0, /* Black. */
|
||||
4, /* Blue. */
|
||||
2, /* Green. */
|
||||
6, /* Cyan. */
|
||||
1, /* Red. */
|
||||
5, /* Magenta. */
|
||||
3, /* Yellow. */
|
||||
7, /* White. */
|
||||
};
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
fg = term->normal_color & 0x0f;
|
||||
bg = term->normal_color >> 4;
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
fg = term->highlight_color & 0x0f;
|
||||
bg = term->highlight_color >> 4;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
putstr (term, grub_terminfo_tparm (data->setcolor, colormap[fg & 7],
|
||||
colormap[bg & 7]));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case GRUB_TERM_COLOR_STANDARD:
|
||||
case GRUB_TERM_COLOR_NORMAL:
|
||||
putstr (term, grub_terminfo_tparm (data->reverse_video_off));
|
||||
break;
|
||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||
putstr (term, grub_terminfo_tparm (data->reverse_video_on));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set reverse video mode off. */
|
||||
void
|
||||
grub_terminfo_reverse_video_off (grub_term_output_t oterm)
|
||||
grub_terminfo_setcursor (struct grub_term_output *term, const int on)
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
if (on)
|
||||
putstr (term, grub_terminfo_tparm (data->cursor_on));
|
||||
else
|
||||
putstr (term, grub_terminfo_tparm (data->cursor_off));
|
||||
}
|
||||
|
||||
/* Show cursor. */
|
||||
/* The terminfo version of putchar. */
|
||||
void
|
||||
grub_terminfo_cursor_on (grub_term_output_t oterm)
|
||||
grub_terminfo_putchar (struct grub_term_output *term,
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.cursor_on), oterm);
|
||||
struct grub_terminfo_output_state *data
|
||||
= (struct grub_terminfo_output_state *) term->data;
|
||||
|
||||
/* Keep track of the cursor. */
|
||||
switch (c->base)
|
||||
{
|
||||
case '\a':
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
case 127:
|
||||
if (data->xpos > 0)
|
||||
data->xpos--;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (data->ypos < grub_term_height (term) - 1)
|
||||
data->ypos++;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
data->xpos = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (data->xpos + c->estimated_width >= grub_term_width (term) + 1)
|
||||
{
|
||||
data->xpos = 0;
|
||||
if (data->ypos < grub_term_height (term) - 1)
|
||||
data->ypos++;
|
||||
data->put ('\r');
|
||||
data->put ('\n');
|
||||
}
|
||||
data->xpos += c->estimated_width;
|
||||
break;
|
||||
}
|
||||
|
||||
data->put (c->base);
|
||||
}
|
||||
|
||||
/* Hide cursor. */
|
||||
void
|
||||
grub_terminfo_cursor_off (grub_term_output_t oterm)
|
||||
#define ANSI_C0 0x9b
|
||||
|
||||
static void
|
||||
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
|
||||
{
|
||||
putstr (grub_terminfo_tparm (term.cursor_off), oterm);
|
||||
int c;
|
||||
|
||||
#define CONTINUE_READ \
|
||||
{ \
|
||||
grub_uint64_t start; \
|
||||
/* On 9600 we have to wait up to 12 milliseconds. */ \
|
||||
start = grub_get_time_ms (); \
|
||||
do \
|
||||
c = readkey (); \
|
||||
while (c == -1 && grub_get_time_ms () - start < 12); \
|
||||
if (c == -1) \
|
||||
return; \
|
||||
\
|
||||
keys[*len] = c; \
|
||||
(*len)++; \
|
||||
}
|
||||
|
||||
c = readkey ();
|
||||
if (c < 0)
|
||||
{
|
||||
*len = 0;
|
||||
return;
|
||||
}
|
||||
*len = 1;
|
||||
keys[0] = c;
|
||||
if (c != ANSI_C0 && c != '\e')
|
||||
{
|
||||
/* Backspace: Ctrl-h. */
|
||||
if (c == 0x7f)
|
||||
c = '\b';
|
||||
*len = 1;
|
||||
keys[0] = c;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
static struct
|
||||
{
|
||||
char key;
|
||||
char ascii;
|
||||
}
|
||||
three_code_table[] =
|
||||
{
|
||||
{'4', GRUB_TERM_DC},
|
||||
{'A', GRUB_TERM_UP},
|
||||
{'B', GRUB_TERM_DOWN},
|
||||
{'C', GRUB_TERM_RIGHT},
|
||||
{'D', GRUB_TERM_LEFT},
|
||||
{'F', GRUB_TERM_END},
|
||||
{'H', GRUB_TERM_HOME},
|
||||
{'K', GRUB_TERM_END},
|
||||
{'P', GRUB_TERM_DC},
|
||||
{'?', GRUB_TERM_PPAGE},
|
||||
{'/', GRUB_TERM_NPAGE}
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
char key;
|
||||
char ascii;
|
||||
}
|
||||
four_code_table[] =
|
||||
{
|
||||
{'1', GRUB_TERM_HOME},
|
||||
{'3', GRUB_TERM_DC},
|
||||
{'5', GRUB_TERM_PPAGE},
|
||||
{'6', GRUB_TERM_NPAGE}
|
||||
};
|
||||
unsigned i;
|
||||
|
||||
if (c == '\e')
|
||||
{
|
||||
CONTINUE_READ;
|
||||
|
||||
if (c != '[')
|
||||
return;
|
||||
}
|
||||
|
||||
CONTINUE_READ;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (three_code_table); i++)
|
||||
if (three_code_table[i].key == c)
|
||||
{
|
||||
keys[0] = three_code_table[i].ascii;
|
||||
*len = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (four_code_table); i++)
|
||||
if (four_code_table[i].key == c)
|
||||
{
|
||||
CONTINUE_READ;
|
||||
if (c != '~')
|
||||
return;
|
||||
keys[0] = three_code_table[i].ascii;
|
||||
*len = 1;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#undef CONTINUE_READ
|
||||
}
|
||||
|
||||
/* The terminfo version of checkkey. */
|
||||
int
|
||||
grub_terminfo_checkkey (struct grub_term_input *termi)
|
||||
{
|
||||
struct grub_terminfo_input_state *data
|
||||
= (struct grub_terminfo_input_state *) (termi->data);
|
||||
if (data->npending)
|
||||
return data->input_buf[0];
|
||||
|
||||
grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
|
||||
|
||||
if (data->npending)
|
||||
return data->input_buf[0];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The terminfo version of getkey. */
|
||||
int
|
||||
grub_terminfo_getkey (struct grub_term_input *termi)
|
||||
{
|
||||
struct grub_terminfo_input_state *data
|
||||
= (struct grub_terminfo_input_state *) (termi->data);
|
||||
int ret;
|
||||
while (! data->npending)
|
||||
grub_terminfo_readkey (data->input_buf, &data->npending, data->readkey);
|
||||
|
||||
ret = data->input_buf[0];
|
||||
data->npending--;
|
||||
grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
|
||||
return ret;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_terminfo_input_init (struct grub_term_input *termi)
|
||||
{
|
||||
struct grub_terminfo_input_state *data
|
||||
= (struct grub_terminfo_input_state *) (termi->data);
|
||||
data->npending = 0;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* GRUB Command. */
|
||||
|
||||
static grub_err_t
|
||||
print_terminfo (void)
|
||||
{
|
||||
const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK
|
||||
>> GRUB_TERM_CODE_TYPE_SHIFT) + 1]
|
||||
= {
|
||||
/* VGA and glyph descriptor types are just for completeness,
|
||||
they are not used on terminfo terminals.
|
||||
*/
|
||||
[GRUB_TERM_CODE_TYPE_ASCII >> GRUB_TERM_CODE_TYPE_SHIFT] = _("ASCII"),
|
||||
[GRUB_TERM_CODE_TYPE_CP437 >> GRUB_TERM_CODE_TYPE_SHIFT] = "CP-437",
|
||||
[GRUB_TERM_CODE_TYPE_UTF8_LOGICAL >> GRUB_TERM_CODE_TYPE_SHIFT]
|
||||
= _("UTF-8"),
|
||||
[GRUB_TERM_CODE_TYPE_UTF8_VISUAL >> GRUB_TERM_CODE_TYPE_SHIFT]
|
||||
= _("UTF-8 visual"),
|
||||
[GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS >> GRUB_TERM_CODE_TYPE_SHIFT]
|
||||
= "Glyph descriptors",
|
||||
_("Unknown"), _("Unknown"), _("Unknown")
|
||||
};
|
||||
struct grub_term_output *cur;
|
||||
|
||||
grub_printf ("Current terminfo types: \n");
|
||||
for (cur = terminfo_outputs; cur;
|
||||
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
|
||||
grub_printf ("%s: %s\t%s\n", cur->name,
|
||||
grub_terminfo_get_current(cur),
|
||||
encoding_names[(cur->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||
>> GRUB_TERM_CODE_TYPE_SHIFT]);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_term_output *cur;
|
||||
int encoding = GRUB_TERM_CODE_TYPE_ASCII;
|
||||
int i;
|
||||
char *name = NULL, *type = NULL;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
|
||||
else
|
||||
return grub_terminfo_set_current (args[0]);
|
||||
return print_terminfo ();
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (grub_strcmp (args[i], "-a") == 0
|
||||
|| grub_strcmp (args[i], "--ascii") == 0)
|
||||
{
|
||||
encoding = GRUB_TERM_CODE_TYPE_ASCII;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[i], "-u") == 0
|
||||
|| grub_strcmp (args[i], "--utf8") == 0)
|
||||
{
|
||||
encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL;
|
||||
continue;
|
||||
}
|
||||
if (grub_strcmp (args[i], "-v") == 0
|
||||
|| grub_strcmp (args[i], "--visual-utf8") == 0)
|
||||
{
|
||||
encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL;
|
||||
continue;
|
||||
}
|
||||
if (!name)
|
||||
{
|
||||
name = args[i];
|
||||
continue;
|
||||
}
|
||||
if (!type)
|
||||
{
|
||||
type = args[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters");
|
||||
|
||||
for (cur = terminfo_outputs; cur;
|
||||
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
|
||||
if (grub_strcmp (name, cur->name) == 0)
|
||||
{
|
||||
cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding;
|
||||
if (!type)
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
return grub_terminfo_set_current (cur, type);
|
||||
}
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"no terminal %s found or it's not handled by terminfo",
|
||||
name);
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
@ -179,8 +612,13 @@ static grub_command_t cmd;
|
|||
GRUB_MOD_INIT(terminfo)
|
||||
{
|
||||
cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
|
||||
N_("[TERM]"), N_("Set terminfo type."));
|
||||
grub_terminfo_set_current ("vt100");
|
||||
N_("[[-a|-u|-v] TERM [TYPE]]"),
|
||||
N_("Set terminfo type of TERM to TYPE.\n"
|
||||
"-a, --ascii Terminal is ASCII-only [default].\n"
|
||||
"-u, --utf8 Terminal is logical-ordered UTF-8.\n"
|
||||
"-v, --visual-utf8 Terminal is visually-ordered UTF-8.")
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(terminfo)
|
||||
|
|
|
@ -751,6 +751,9 @@ grub_terminfo_tparm (const char *string, ...)
|
|||
va_list ap;
|
||||
char *result;
|
||||
|
||||
if (!string)
|
||||
return "";
|
||||
|
||||
va_start (ap, string);
|
||||
result = tparam_internal (string, ap);
|
||||
va_end (ap);
|
||||
|
|
|
@ -119,7 +119,7 @@ grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
|
|||
|
||||
|
||||
static int
|
||||
grub_usb_keyboard_checkkey (void)
|
||||
grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint8_t data[8];
|
||||
int key;
|
||||
|
@ -188,7 +188,7 @@ typedef enum
|
|||
} grub_usb_keyboard_repeat_t;
|
||||
|
||||
static int
|
||||
grub_usb_keyboard_getkey (void)
|
||||
grub_usb_keyboard_getkey (struct grub_term_input *term)
|
||||
{
|
||||
int key;
|
||||
grub_err_t err;
|
||||
|
@ -201,7 +201,7 @@ grub_usb_keyboard_getkey (void)
|
|||
|
||||
do
|
||||
{
|
||||
key = grub_usb_keyboard_checkkey ();
|
||||
key = grub_usb_keyboard_checkkey (term);
|
||||
} while (key == -1);
|
||||
|
||||
data[2] = !0; /* Or whatever. */
|
||||
|
@ -253,7 +253,7 @@ grub_usb_keyboard_getkey (void)
|
|||
}
|
||||
|
||||
static int
|
||||
grub_usb_keyboard_getkeystatus (void)
|
||||
grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint8_t data[8];
|
||||
int mods = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue