merge common serial and ofconsole code into terminfo
This commit is contained in:
parent
58664b94b7
commit
bf8733749b
9 changed files with 483 additions and 494 deletions
|
@ -22,7 +22,8 @@
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
|
|
||||||
/* Initialize the console system. */
|
/* Initialize the console system. */
|
||||||
void grub_console_init (void);
|
void grub_console_init_early (void);
|
||||||
|
void grub_console_init_lately (void);
|
||||||
|
|
||||||
/* Finish the console system. */
|
/* Finish the console system. */
|
||||||
void grub_console_fini (void);
|
void grub_console_fini (void);
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GRUB_CONSOLE_MACHINE_HEADER
|
|
||||||
#define GRUB_CONSOLE_MACHINE_HEADER 1
|
|
||||||
|
|
||||||
/* Initialize the console system. */
|
|
||||||
void grub_console_init (void);
|
|
||||||
|
|
||||||
/* Finish the console system. */
|
|
||||||
void grub_console_fini (void);
|
|
||||||
|
|
||||||
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GRUB is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GRUB_CONSOLE_MACHINE_HEADER
|
|
||||||
#define GRUB_CONSOLE_MACHINE_HEADER 1
|
|
||||||
|
|
||||||
/* Initialize the console system. */
|
|
||||||
void grub_console_init (void);
|
|
||||||
|
|
||||||
/* Finish the console system. */
|
|
||||||
void grub_console_fini (void);
|
|
||||||
|
|
||||||
#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */
|
|
|
@ -23,18 +23,64 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
|
|
||||||
char *EXPORT_FUNC(grub_terminfo_get_current) (void);
|
char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term);
|
||||||
grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (const char *);
|
grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term,
|
||||||
|
const char *);
|
||||||
void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_uint8_t x, grub_uint8_t y,
|
|
||||||
grub_term_output_t oterm);
|
|
||||||
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t oterm);
|
|
||||||
void EXPORT_FUNC(grub_terminfo_reverse_video_on) (grub_term_output_t oterm);
|
|
||||||
void EXPORT_FUNC(grub_terminfo_reverse_video_off) (grub_term_output_t oterm);
|
|
||||||
void EXPORT_FUNC(grub_terminfo_cursor_on) (grub_term_output_t oterm);
|
|
||||||
void EXPORT_FUNC(grub_terminfo_cursor_off) (grub_term_output_t oterm);
|
|
||||||
|
|
||||||
#define GRUB_TERMINFO_READKEY_MAX_LEN 4
|
#define GRUB_TERMINFO_READKEY_MAX_LEN 4
|
||||||
void EXPORT_FUNC(grub_terminfo_readkey) (int *keys, int *len, int (*readkey) (void));
|
struct grub_terminfo_input_state
|
||||||
|
{
|
||||||
|
int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
|
||||||
|
int npending;
|
||||||
|
int (*readkey) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct grub_terminfo_output_state
|
||||||
|
{
|
||||||
|
struct grub_term_output *next;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
char *gotoxy;
|
||||||
|
char *cls;
|
||||||
|
char *reverse_video_on;
|
||||||
|
char *reverse_video_off;
|
||||||
|
char *cursor_on;
|
||||||
|
char *cursor_off;
|
||||||
|
char *setcolor;
|
||||||
|
|
||||||
|
grub_uint8_t normal_color;
|
||||||
|
grub_uint8_t highlight_color;
|
||||||
|
|
||||||
|
unsigned int xpos, ypos;
|
||||||
|
|
||||||
|
void (*put) (const int c);
|
||||||
|
};
|
||||||
|
|
||||||
|
void EXPORT_FUNC(grub_terminfo_gotoxy) (grub_term_output_t term,
|
||||||
|
grub_uint8_t x, grub_uint8_t y);
|
||||||
|
void EXPORT_FUNC(grub_terminfo_cls) (grub_term_output_t term);
|
||||||
|
grub_uint16_t EXPORT_FUNC (grub_terminfo_getxy) (struct grub_term_output *term);
|
||||||
|
void EXPORT_FUNC (grub_terminfo_setcursor) (struct grub_term_output *term,
|
||||||
|
const int on);
|
||||||
|
void EXPORT_FUNC (grub_terminfo_setcolorstate) (struct grub_term_output *term,
|
||||||
|
const grub_term_color_state state);
|
||||||
|
|
||||||
|
|
||||||
|
int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term);
|
||||||
|
grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term);
|
||||||
|
int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term);
|
||||||
|
void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term,
|
||||||
|
const struct grub_unicode_glyph *c);
|
||||||
|
void EXPORT_FUNC (grub_terminfo_getcolor) (struct grub_term_output *term,
|
||||||
|
grub_uint8_t *normal_color,
|
||||||
|
grub_uint8_t *highlight_color);
|
||||||
|
void EXPORT_FUNC (grub_terminfo_setcolor) (struct grub_term_output *term,
|
||||||
|
grub_uint8_t normal_color,
|
||||||
|
grub_uint8_t highlight_color);
|
||||||
|
|
||||||
|
grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term,
|
||||||
|
const char *type);
|
||||||
|
grub_err_t EXPORT_FUNC (grub_terminfo_output_unregister) (struct grub_term_output *term);
|
||||||
|
|
||||||
#endif /* ! GRUB_TERMINFO_HEADER */
|
#endif /* ! GRUB_TERMINFO_HEADER */
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/machine/console.h>
|
#include <grub/ieee1275/console.h>
|
||||||
#include <grub/machine/kernel.h>
|
#include <grub/machine/kernel.h>
|
||||||
#include <grub/cpu/kernel.h>
|
#include <grub/cpu/kernel.h>
|
||||||
#include <grub/ieee1275/ofdisk.h>
|
#include <grub/ieee1275/ofdisk.h>
|
||||||
|
@ -225,11 +225,12 @@ grub_machine_init (void)
|
||||||
|
|
||||||
grub_ieee1275_init ();
|
grub_ieee1275_init ();
|
||||||
|
|
||||||
grub_console_init ();
|
grub_console_init_early ();
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
grub_get_extended_memory ();
|
grub_get_extended_memory ();
|
||||||
#endif
|
#endif
|
||||||
grub_claim_heap ();
|
grub_claim_heap ();
|
||||||
|
grub_console_init_lately ();
|
||||||
grub_ofdisk_init ();
|
grub_ofdisk_init ();
|
||||||
|
|
||||||
/* Process commandline. */
|
/* Process commandline. */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
#include <grub/terminfo.h>
|
#include <grub/terminfo.h>
|
||||||
#include <grub/machine/console.h>
|
#include <grub/ieee1275/console.h>
|
||||||
#include <grub/ieee1275/ieee1275.h>
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
|
|
||||||
static grub_ieee1275_ihandle_t stdout_ihandle;
|
static grub_ieee1275_ihandle_t stdout_ihandle;
|
||||||
|
@ -32,12 +32,6 @@ static grub_ieee1275_ihandle_t stdin_ihandle;
|
||||||
static grub_uint8_t grub_ofconsole_width;
|
static grub_uint8_t grub_ofconsole_width;
|
||||||
static grub_uint8_t grub_ofconsole_height;
|
static grub_uint8_t grub_ofconsole_height;
|
||||||
|
|
||||||
static int grub_curr_x;
|
|
||||||
static int grub_curr_y;
|
|
||||||
|
|
||||||
static int grub_keybuf[GRUB_TERMINFO_READKEY_MAX_LEN];
|
|
||||||
static int grub_buflen;
|
|
||||||
|
|
||||||
struct color
|
struct color
|
||||||
{
|
{
|
||||||
int red;
|
int red;
|
||||||
|
@ -58,102 +52,14 @@ static struct color colors[] =
|
||||||
{0xFE, 0xFE, 0xFE} // 7 = white
|
{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
|
static void
|
||||||
grub_ofconsole_writeesc (const char *str)
|
put (const int c)
|
||||||
{
|
{
|
||||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
|
char chr = c;
|
||||||
return;
|
|
||||||
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
char chr = *(str++);
|
|
||||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_ofconsole_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
const struct grub_unicode_glyph *c)
|
|
||||||
{
|
|
||||||
char chr;
|
|
||||||
|
|
||||||
chr = c->base;
|
|
||||||
|
|
||||||
if (chr == '\n')
|
|
||||||
{
|
|
||||||
grub_curr_y++;
|
|
||||||
grub_curr_x = 0;
|
|
||||||
}
|
|
||||||
else if (chr == '\r')
|
|
||||||
{
|
|
||||||
grub_curr_x = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_curr_x++;
|
|
||||||
if (grub_curr_x >= grub_ofconsole_width)
|
|
||||||
{
|
|
||||||
chr = '\n';
|
|
||||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
|
||||||
chr = '\r';
|
|
||||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
|
||||||
grub_curr_y++;
|
|
||||||
grub_curr_x = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
grub_ofconsole_setcolorstate (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
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 (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
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 (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
|
|
||||||
{
|
|
||||||
*normal_color = grub_ofconsole_normal_color;
|
|
||||||
*highlight_color = grub_ofconsole_highlight_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readkey (void)
|
readkey (void)
|
||||||
{
|
{
|
||||||
|
@ -166,39 +72,6 @@ readkey (void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
grub_ofconsole_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
if (grub_buflen)
|
|
||||||
return grub_keybuf[0];
|
|
||||||
|
|
||||||
grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey);
|
|
||||||
|
|
||||||
if (grub_buflen)
|
|
||||||
return grub_keybuf[0];
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
grub_ofconsole_getkey (struct grub_term_input *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
while (! grub_buflen)
|
|
||||||
grub_terminfo_readkey (grub_keybuf, &grub_buflen, readkey);
|
|
||||||
|
|
||||||
ret = grub_keybuf[0];
|
|
||||||
grub_buflen--;
|
|
||||||
grub_memmove (grub_keybuf, grub_keybuf + 1, grub_buflen);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint16_t
|
|
||||||
grub_ofconsole_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
return (grub_curr_x << 8) | grub_curr_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_ofconsole_dimensions (void)
|
grub_ofconsole_dimensions (void)
|
||||||
{
|
{
|
||||||
|
@ -241,44 +114,6 @@ grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
||||||
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
|
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
grub_ofconsole_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
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 (struct grub_term_output *term)
|
|
||||||
{
|
|
||||||
/* 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 (term, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
||||||
int on)
|
int on)
|
||||||
|
@ -290,14 +125,8 @@ grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused))
|
||||||
grub_ieee1275_interpret ("cursor-off", 0);
|
grub_ieee1275_interpret ("cursor-off", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
grub_ofconsole_refresh (struct grub_term_output *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
/* Do nothing, the current console state is ok. */
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused)))
|
grub_ofconsole_init_input (struct grub_term_input *term)
|
||||||
{
|
{
|
||||||
grub_ssize_t actual;
|
grub_ssize_t actual;
|
||||||
|
|
||||||
|
@ -306,7 +135,7 @@ grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused))
|
||||||
|| actual != sizeof stdin_ihandle)
|
|| actual != sizeof stdin_ihandle)
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin");
|
||||||
|
|
||||||
return 0;
|
return grub_terminfo_input_init (term);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -333,8 +162,8 @@ grub_ofconsole_init_output (struct grub_term_output *term)
|
||||||
grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
|
grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red,
|
||||||
colors[col].green, colors[col].blue);
|
colors[col].green, colors[col].blue);
|
||||||
|
|
||||||
/* Set the right fg and bg colors. */
|
/* Set the right fg and bg colors. */
|
||||||
grub_ofconsole_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_ofconsole_dimensions ();
|
grub_ofconsole_dimensions ();
|
||||||
|
@ -343,41 +172,73 @@ grub_ofconsole_init_output (struct grub_term_output *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 =
|
static struct grub_term_input grub_ofconsole_term_input =
|
||||||
{
|
{
|
||||||
.name = "ofconsole",
|
.name = "ofconsole",
|
||||||
.init = grub_ofconsole_init_input,
|
.init = grub_ofconsole_init_input,
|
||||||
.checkkey = grub_ofconsole_checkkey,
|
.checkkey = grub_terminfo_checkkey,
|
||||||
.getkey = grub_ofconsole_getkey,
|
.getkey = grub_terminfo_getkey,
|
||||||
|
.data = &grub_ofconsole_terminfo_input
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct grub_term_output grub_ofconsole_term_output =
|
static struct grub_term_output grub_ofconsole_term_output =
|
||||||
{
|
{
|
||||||
.name = "ofconsole",
|
.name = "ofconsole",
|
||||||
.init = grub_ofconsole_init_output,
|
.init = grub_ofconsole_init_output,
|
||||||
.putchar = grub_ofconsole_putchar,
|
.putchar = grub_terminfo_putchar,
|
||||||
.getxy = grub_ofconsole_getxy,
|
.getxy = grub_terminfo_getxy,
|
||||||
.getwh = grub_ofconsole_getwh,
|
.getwh = grub_ofconsole_getwh,
|
||||||
.gotoxy = grub_ofconsole_gotoxy,
|
.gotoxy = grub_terminfo_gotoxy,
|
||||||
.cls = grub_ofconsole_cls,
|
.cls = grub_terminfo_cls,
|
||||||
.setcolorstate = grub_ofconsole_setcolorstate,
|
.setcolorstate = grub_terminfo_setcolorstate,
|
||||||
.setcolor = grub_ofconsole_setcolor,
|
.setcolor = grub_terminfo_setcolor,
|
||||||
.getcolor = grub_ofconsole_getcolor,
|
.getcolor = grub_terminfo_getcolor,
|
||||||
.setcursor = grub_ofconsole_setcursor,
|
.setcursor = grub_ofconsole_setcursor,
|
||||||
.refresh = grub_ofconsole_refresh,
|
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||||
.flags = GRUB_TERM_CODE_TYPE_ASCII
|
.data = &grub_ofconsole_terminfo_output
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void grub_terminfo_fini (void);
|
||||||
|
void grub_terminfo_init (void);
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_console_init (void)
|
grub_console_init_early (void)
|
||||||
{
|
{
|
||||||
grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
|
grub_term_register_input ("ofconsole", &grub_ofconsole_term_input);
|
||||||
grub_term_register_output ("ofconsole", &grub_ofconsole_term_output);
|
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
|
void
|
||||||
grub_console_fini (void)
|
grub_console_fini (void)
|
||||||
{
|
{
|
||||||
grub_term_unregister_input (&grub_ofconsole_term_input);
|
grub_term_unregister_input (&grub_ofconsole_term_input);
|
||||||
grub_term_unregister_output (&grub_ofconsole_term_output);
|
grub_term_unregister_output (&grub_ofconsole_term_output);
|
||||||
|
grub_terminfo_output_unregister (&grub_ofconsole_term_output);
|
||||||
|
|
||||||
|
grub_terminfo_fini ();
|
||||||
}
|
}
|
||||||
|
|
189
term/serial.c
189
term/serial.c
|
@ -27,19 +27,8 @@
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/i18n.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;
|
static unsigned int registered = 0;
|
||||||
|
|
||||||
/* An input buffer. */
|
|
||||||
static int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
|
|
||||||
static int npending = 0;
|
|
||||||
|
|
||||||
static struct grub_term_output grub_serial_term_output;
|
|
||||||
|
|
||||||
/* Argument options. */
|
/* Argument options. */
|
||||||
static const struct grub_arg_option options[] =
|
static const struct grub_arg_option options[] =
|
||||||
{
|
{
|
||||||
|
@ -152,35 +141,6 @@ serial_get_divisor (unsigned int speed)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The serial version of checkkey. */
|
|
||||||
static int
|
|
||||||
grub_serial_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
if (npending)
|
|
||||||
return input_buf[0];
|
|
||||||
|
|
||||||
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
|
|
||||||
|
|
||||||
if (npending)
|
|
||||||
return input_buf[0];
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The serial version of getkey. */
|
|
||||||
static int
|
|
||||||
grub_serial_getkey (struct grub_term_input *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
while (! npending)
|
|
||||||
grub_terminfo_readkey (input_buf, &npending, serial_hw_fetch);
|
|
||||||
|
|
||||||
ret = input_buf[0];
|
|
||||||
npending--;
|
|
||||||
grub_memmove (input_buf, input_buf + 1, npending);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize a serial device. PORT is the port number for a serial device.
|
/* 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,
|
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
|
19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
|
||||||
|
@ -219,150 +179,56 @@ serial_hw_init (void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Drain the input buffer. */
|
/* Drain the input buffer. */
|
||||||
while (grub_serial_checkkey (0) != -1)
|
while (serial_hw_fetch () != -1);
|
||||||
(void) grub_serial_getkey (0);
|
|
||||||
|
|
||||||
/* FIXME: should check if the serial terminal was found. */
|
/* FIXME: should check if the serial terminal was found. */
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The serial version of putchar. */
|
|
||||||
static void
|
|
||||||
grub_serial_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
const struct grub_unicode_glyph *c)
|
|
||||||
{
|
|
||||||
/* Keep track of the cursor. */
|
|
||||||
if (keep_track)
|
|
||||||
{
|
|
||||||
switch (c->base)
|
|
||||||
{
|
|
||||||
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 ((c->base & 0xC0) == 0x80)
|
|
||||||
break;
|
|
||||||
if (xpos + c->estimated_width >= TEXT_WIDTH + 1)
|
|
||||||
{
|
|
||||||
xpos = 0;
|
|
||||||
if (ypos < TEXT_HEIGHT - 1)
|
|
||||||
ypos++;
|
|
||||||
serial_hw_put ('\r');
|
|
||||||
serial_hw_put ('\n');
|
|
||||||
}
|
|
||||||
xpos += c->estimated_width;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serial_hw_put (c->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint16_t
|
static grub_uint16_t
|
||||||
grub_serial_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
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;
|
return (TEXT_WIDTH << 8) | TEXT_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_uint16_t
|
struct grub_terminfo_input_state grub_serial_terminfo_input =
|
||||||
grub_serial_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
{
|
||||||
{
|
.readkey = serial_hw_fetch
|
||||||
return ((xpos << 8) | ypos);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
struct grub_terminfo_output_state grub_serial_terminfo_output =
|
||||||
grub_serial_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
{
|
||||||
grub_uint8_t x, grub_uint8_t y)
|
.put = serial_hw_put,
|
||||||
{
|
.normal_color = 0x7,
|
||||||
if (x > TEXT_WIDTH || y > TEXT_HEIGHT)
|
.highlight_color = 0x70
|
||||||
{
|
};
|
||||||
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 (struct grub_term_output *term __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
keep_track = 0;
|
|
||||||
grub_terminfo_cls (&grub_serial_term_output);
|
|
||||||
keep_track = 1;
|
|
||||||
|
|
||||||
xpos = ypos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_serial_setcolorstate (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
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 (struct grub_term_output *term __attribute__ ((unused)),
|
|
||||||
const int on)
|
|
||||||
{
|
|
||||||
if (on)
|
|
||||||
grub_terminfo_cursor_on (&grub_serial_term_output);
|
|
||||||
else
|
|
||||||
grub_terminfo_cursor_off (&grub_serial_term_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grub_term_input grub_serial_term_input =
|
static struct grub_term_input grub_serial_term_input =
|
||||||
{
|
{
|
||||||
.name = "serial",
|
.name = "serial",
|
||||||
.checkkey = grub_serial_checkkey,
|
.init = grub_terminfo_input_init,
|
||||||
.getkey = grub_serial_getkey,
|
.checkkey = grub_terminfo_checkkey,
|
||||||
|
.getkey = grub_terminfo_getkey,
|
||||||
|
.data = &grub_serial_terminfo_input
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct grub_term_output grub_serial_term_output =
|
static struct grub_term_output grub_serial_term_output =
|
||||||
{
|
{
|
||||||
.name = "serial",
|
.name = "serial",
|
||||||
.putchar = grub_serial_putchar,
|
.putchar = grub_terminfo_putchar,
|
||||||
.getwh = grub_serial_getwh,
|
.getwh = grub_serial_getwh,
|
||||||
.getxy = grub_serial_getxy,
|
.getxy = grub_terminfo_getxy,
|
||||||
.gotoxy = grub_serial_gotoxy,
|
.gotoxy = grub_terminfo_gotoxy,
|
||||||
.cls = grub_serial_cls,
|
.cls = grub_terminfo_cls,
|
||||||
.setcolorstate = grub_serial_setcolorstate,
|
.setcolorstate = grub_terminfo_setcolorstate,
|
||||||
.setcursor = grub_serial_setcursor,
|
.setcolor = grub_terminfo_setcolor,
|
||||||
|
.getcolor = grub_terminfo_getcolor,
|
||||||
|
.setcursor = grub_terminfo_setcursor,
|
||||||
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
.flags = GRUB_TERM_CODE_TYPE_ASCII,
|
||||||
|
.data = &grub_serial_terminfo_output
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -466,6 +332,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
|
||||||
{
|
{
|
||||||
grub_term_register_input ("serial", &grub_serial_term_input);
|
grub_term_register_input ("serial", &grub_serial_term_input);
|
||||||
grub_term_register_output ("serial", &grub_serial_term_output);
|
grub_term_register_output ("serial", &grub_serial_term_output);
|
||||||
|
grub_terminfo_output_register (&grub_serial_term_output, "vt100");
|
||||||
registered = 1;
|
registered = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,6 +349,7 @@ grub_cmd_serial (grub_extcmd_t cmd,
|
||||||
/* If unable to restore settings, unregister terminal. */
|
/* If unable to restore settings, unregister terminal. */
|
||||||
grub_term_unregister_input (&grub_serial_term_input);
|
grub_term_unregister_input (&grub_serial_term_input);
|
||||||
grub_term_unregister_output (&grub_serial_term_output);
|
grub_term_unregister_output (&grub_serial_term_output);
|
||||||
|
grub_terminfo_output_unregister (&grub_serial_term_output);
|
||||||
registered = 0;
|
registered = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,5 +386,6 @@ GRUB_MOD_FINI(serial)
|
||||||
{
|
{
|
||||||
grub_term_unregister_input (&grub_serial_term_input);
|
grub_term_unregister_input (&grub_serial_term_input);
|
||||||
grub_term_unregister_output (&grub_serial_term_output);
|
grub_term_unregister_output (&grub_serial_term_output);
|
||||||
|
grub_terminfo_output_unregister (&grub_serial_term_output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
412
term/terminfo.c
412
term/terminfo.c
|
@ -34,25 +34,15 @@
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
|
|
||||||
struct terminfo
|
static struct grub_term_output *terminfo_outputs;
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
char *gotoxy;
|
|
||||||
char *cls;
|
|
||||||
char *reverse_video_on;
|
|
||||||
char *reverse_video_off;
|
|
||||||
char *cursor_on;
|
|
||||||
char *cursor_off;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct terminfo term;
|
|
||||||
|
|
||||||
/* Get current terminfo name. */
|
/* Get current terminfo name. */
|
||||||
char *
|
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. */
|
/* Free *PTR and set *PTR to NULL, to prevent double-free. */
|
||||||
|
@ -63,10 +53,29 @@ grub_terminfo_free (char **ptr)
|
||||||
*ptr = 0;
|
*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. */
|
/* Set current terminfo type. */
|
||||||
grub_err_t
|
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
|
/* TODO
|
||||||
* Lookup user specified terminfo type. If found, set term variables
|
* Lookup user specified terminfo type. If found, set term variables
|
||||||
* as appropriate. Otherwise return an error.
|
* as appropriate. Otherwise return an error.
|
||||||
|
@ -84,93 +93,290 @@ grub_terminfo_set_current (const char *str)
|
||||||
* d. Your idea here.
|
* d. Your idea here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Free previously allocated memory. */
|
grub_terminfo_all_free (term);
|
||||||
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);
|
|
||||||
|
|
||||||
if (grub_strcmp ("vt100", str) == 0)
|
if (grub_strcmp ("vt100", str) == 0)
|
||||||
{
|
{
|
||||||
term.name = grub_strdup ("vt100");
|
data->name = grub_strdup ("vt100");
|
||||||
term.gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH");
|
||||||
term.cls = grub_strdup ("\e[H\e[J");
|
data->cls = grub_strdup ("\e[H\e[J");
|
||||||
term.reverse_video_on = grub_strdup ("\e[7m");
|
data->reverse_video_on = grub_strdup ("\e[7m");
|
||||||
term.reverse_video_off = grub_strdup ("\e[m");
|
data->reverse_video_off = grub_strdup ("\e[m");
|
||||||
term.cursor_on = grub_strdup ("\e[?25h");
|
data->cursor_on = grub_strdup ("\e[?25h");
|
||||||
term.cursor_off = grub_strdup ("\e[?25l");
|
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_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper for grub_putchar to write strings. */
|
grub_err_t
|
||||||
static void
|
grub_terminfo_output_register (struct grub_term_output *term,
|
||||||
putstr (const char *str, grub_term_output_t oterm)
|
const char *type)
|
||||||
{
|
{
|
||||||
while (*str)
|
grub_err_t err;
|
||||||
{
|
struct grub_terminfo_output_state *data;
|
||||||
struct grub_unicode_glyph c =
|
|
||||||
{
|
err = grub_terminfo_set_current (term, type);
|
||||||
.base = *str++,
|
|
||||||
.variant = 0,
|
if (err)
|
||||||
.attributes = 0,
|
return err;
|
||||||
.ncomb = 0,
|
|
||||||
.combining = 0
|
data = (struct grub_terminfo_output_state *) term->data;
|
||||||
};
|
data->next = terminfo_outputs;
|
||||||
oterm->putchar (oterm, &c);
|
terminfo_outputs = term;
|
||||||
}
|
|
||||||
|
data->normal_color = 0x07;
|
||||||
|
data->highlight_color = 0x70;
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move the cursor to the given position starting with "0". */
|
grub_err_t
|
||||||
void
|
grub_terminfo_output_unregister (struct grub_term_output *term)
|
||||||
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
|
|
||||||
{
|
{
|
||||||
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. */
|
/* Clear the screen. */
|
||||||
void
|
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
|
void
|
||||||
grub_terminfo_reverse_video_on (grub_term_output_t oterm)
|
grub_terminfo_setcolor (struct grub_term_output *term,
|
||||||
|
grub_uint8_t normal_color,
|
||||||
|
grub_uint8_t highlight_color)
|
||||||
{
|
{
|
||||||
putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
|
struct grub_terminfo_output_state *data
|
||||||
|
= (struct grub_terminfo_output_state *) term->data;
|
||||||
|
|
||||||
|
/* Discard bright bit. */
|
||||||
|
data->normal_color = normal_color & 0x77;
|
||||||
|
data->highlight_color = highlight_color & 0x77;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set reverse video mode off. */
|
|
||||||
void
|
void
|
||||||
grub_terminfo_reverse_video_off (grub_term_output_t oterm)
|
grub_terminfo_getcolor (struct grub_term_output *term,
|
||||||
|
grub_uint8_t *normal_color,
|
||||||
|
grub_uint8_t *highlight_color)
|
||||||
{
|
{
|
||||||
putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
|
struct grub_terminfo_output_state *data
|
||||||
|
= (struct grub_terminfo_output_state *) term->data;
|
||||||
|
|
||||||
|
*normal_color = data->normal_color;
|
||||||
|
*highlight_color = data->highlight_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show cursor. */
|
|
||||||
void
|
void
|
||||||
grub_terminfo_cursor_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.cursor_on), oterm);
|
struct grub_terminfo_output_state *data
|
||||||
|
= (struct grub_terminfo_output_state *) term->data;
|
||||||
|
|
||||||
|
if (data->setcolor)
|
||||||
|
{
|
||||||
|
int fg;
|
||||||
|
int bg;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case GRUB_TERM_COLOR_STANDARD:
|
||||||
|
case GRUB_TERM_COLOR_NORMAL:
|
||||||
|
fg = data->normal_color & 0x0f;
|
||||||
|
bg = data->normal_color >> 4;
|
||||||
|
break;
|
||||||
|
case GRUB_TERM_COLOR_HIGHLIGHT:
|
||||||
|
fg = data->highlight_color & 0x0f;
|
||||||
|
bg = data->highlight_color >> 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
putstr (term, grub_terminfo_tparm (data->setcolor, fg, bg));
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide cursor. */
|
|
||||||
void
|
void
|
||||||
grub_terminfo_cursor_off (grub_term_output_t oterm)
|
grub_terminfo_setcursor (struct grub_term_output *term, const int on)
|
||||||
{
|
{
|
||||||
putstr (grub_terminfo_tparm (term.cursor_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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The terminfo version of putchar. */
|
||||||
|
void
|
||||||
|
grub_terminfo_putchar (struct grub_term_output *term,
|
||||||
|
const struct grub_unicode_glyph *c)
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ANSI_C0 0x9b
|
#define ANSI_C0 0x9b
|
||||||
|
|
||||||
void
|
static void
|
||||||
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
|
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
@ -276,21 +482,80 @@ grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
|
||||||
#undef CONTINUE_READ
|
#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. */
|
/* GRUB Command. */
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char **args)
|
int argc, char **args)
|
||||||
{
|
{
|
||||||
|
struct grub_term_output *cur;
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
{
|
{
|
||||||
grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
|
grub_printf ("Current terminfo types: \n");
|
||||||
return GRUB_ERR_NONE;
|
for (cur = terminfo_outputs; cur;
|
||||||
}
|
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
|
||||||
else if (argc != 1)
|
grub_printf ("%s: %s\n", cur->name,
|
||||||
|
grub_terminfo_get_current(cur));
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few parameters");
|
||||||
|
if (argc != 2)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
|
||||||
else
|
|
||||||
return grub_terminfo_set_current (args[0]);
|
for (cur = terminfo_outputs; cur;
|
||||||
|
cur = ((struct grub_terminfo_output_state *) cur->data)->next)
|
||||||
|
if (grub_strcmp (args[0], cur->name) == 0)
|
||||||
|
return grub_terminfo_set_current (cur, args[1]);
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"no terminal %s found or it's not handled by terminfo",
|
||||||
|
args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_command_t cmd;
|
static grub_command_t cmd;
|
||||||
|
@ -298,8 +563,7 @@ static grub_command_t cmd;
|
||||||
GRUB_MOD_INIT(terminfo)
|
GRUB_MOD_INIT(terminfo)
|
||||||
{
|
{
|
||||||
cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
|
cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
|
||||||
N_("[TERM]"), N_("Set terminfo type."));
|
N_("[TERM TYPE]"), N_("Set terminfo type of TERM to TYPE."));
|
||||||
grub_terminfo_set_current ("vt100");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(terminfo)
|
GRUB_MOD_FINI(terminfo)
|
||||||
|
|
|
@ -751,6 +751,9 @@ grub_terminfo_tparm (const char *string, ...)
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
|
if (!string)
|
||||||
|
return "";
|
||||||
|
|
||||||
va_start (ap, string);
|
va_start (ap, string);
|
||||||
result = tparam_internal (string, ap);
|
result = tparam_internal (string, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
Loading…
Reference in a new issue