#include <grub/symbol.h>
/* 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. */
void grub_console_fini (void);
+++ /dev/null
-/*
- * 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 */
+++ /dev/null
-/*
- * 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 */
#include <grub/types.h>
#include <grub/term.h>
-char *EXPORT_FUNC(grub_terminfo_get_current) (void);
-grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (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);
+char *EXPORT_FUNC(grub_terminfo_get_current) (struct grub_term_output *term);
+grub_err_t EXPORT_FUNC(grub_terminfo_set_current) (struct grub_term_output *term,
+ const char *);
#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 */
#include <grub/env.h>
#include <grub/misc.h>
#include <grub/time.h>
-#include <grub/machine/console.h>
+#include <grub/ieee1275/console.h>
#include <grub/machine/kernel.h>
#include <grub/cpu/kernel.h>
#include <grub/ieee1275/ofdisk.h>
grub_ieee1275_init ();
- grub_console_init ();
+ grub_console_init_early ();
#ifdef __i386__
grub_get_extended_memory ();
#endif
grub_claim_heap ();
+ grub_console_init_lately ();
grub_ofdisk_init ();
/* Process commandline. */
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/terminfo.h>
-#include <grub/machine/console.h>
+#include <grub/ieee1275/console.h>
#include <grub/ieee1275/ieee1275.h>
static grub_ieee1275_ihandle_t stdout_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[GRUB_TERMINFO_READKEY_MAX_LEN];
-static int grub_buflen;
-
struct color
{
int red;
{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)
-{
- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI))
- 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)
+put (const int c)
{
- char chr;
+ char chr = c;
- 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);
}
-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
readkey (void)
{
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
grub_ofconsole_dimensions (void)
{
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 ("\f\e[2J");
- grub_ofconsole_gotoxy (term, 0, 0);
-}
-
static void
grub_ofconsole_setcursor (struct grub_term_output *term __attribute__ ((unused)),
int on)
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
-grub_ofconsole_init_input (struct grub_term_input *term __attribute__ ((unused)))
+grub_ofconsole_init_input (struct grub_term_input *term)
{
grub_ssize_t actual;
|| 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_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 (term, GRUB_TERM_COLOR_NORMAL);
+ /* Set the right fg and bg colors. */
+ grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
}
grub_ofconsole_dimensions ();
}
\f
+
+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,
- .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,
- .putchar = grub_ofconsole_putchar,
- .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,
+ .setcolor = grub_terminfo_setcolor,
+ .getcolor = grub_terminfo_getcolor,
.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
-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 ();
}
#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 int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN];
-static int npending = 0;
-
-static struct grub_term_output grub_serial_term_output;
-
/* Argument options. */
static const struct grub_arg_option options[] =
{
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.
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
#endif
/* Drain the input buffer. */
- while (grub_serial_checkkey (0) != -1)
- (void) grub_serial_getkey (0);
+ 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 (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
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 (struct grub_term_output *term __attribute__ ((unused)))
-{
- return ((xpos << 8) | ypos);
-}
-
-static void
-grub_serial_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
- 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 (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;
-}
+struct grub_terminfo_input_state grub_serial_terminfo_input =
+ {
+ .readkey = serial_hw_fetch
+ };
-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);
-}
+struct grub_terminfo_output_state grub_serial_terminfo_output =
+ {
+ .put = serial_hw_put,
+ .normal_color = 0x7,
+ .highlight_color = 0x70
+ };
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,
+ .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,
+ .getxy = grub_terminfo_getxy,
+ .gotoxy = grub_terminfo_gotoxy,
+ .cls = grub_terminfo_cls,
+ .setcolorstate = grub_terminfo_setcolorstate,
+ .setcolor = grub_terminfo_setcolor,
+ .getcolor = grub_terminfo_getcolor,
+ .setcursor = grub_terminfo_setcursor,
.flags = GRUB_TERM_CODE_TYPE_ASCII,
+ .data = &grub_serial_terminfo_output
};
\f
{
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;
}
}
/* 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;
}
}
{
grub_term_unregister_input (&grub_serial_term_input);
grub_term_unregister_output (&grub_serial_term_output);
+ grub_terminfo_output_unregister (&grub_serial_term_output);
}
}
#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. */
*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.
* 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 ("\f\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");
}
+grub_err_t
+grub_terminfo_output_register (struct grub_term_output *term,
+ const char *type)
+{
+ 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;
+
+ data->normal_color = 0x07;
+ data->highlight_color = 0x70;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_terminfo_output_unregister (struct grub_term_output *term)
+{
+ 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 (const char *str, grub_term_output_t oterm)
+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))
{
- struct grub_unicode_glyph c =
- {
- .base = *str++,
- .variant = 0,
- .attributes = 0,
- .ncomb = 0,
- .combining = 0
- };
- oterm->putchar (oterm, &c);
+ 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;
}
-/* Move the cursor to the given position starting with "0". */
+/* Clear the screen. */
void
-grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
+grub_terminfo_cls (struct grub_term_output *term)
{
- putstr (grub_terminfo_tparm (term.gotoxy, y, x), 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;
}
-/* Clear the screen. */
void
-grub_terminfo_cls (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.cls), 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 on. */
void
-grub_terminfo_reverse_video_on (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_on), oterm);
+ struct grub_terminfo_output_state *data
+ = (struct grub_terminfo_output_state *) term->data;
+
+ *normal_color = data->normal_color;
+ *highlight_color = data->highlight_color;
}
-/* Set reverse video mode off. */
void
-grub_terminfo_reverse_video_off (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_off), 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;
+ }
}
-/* Show cursor. */
void
-grub_terminfo_cursor_on (grub_term_output_t oterm)
+grub_terminfo_setcursor (struct grub_term_output *term, const int on)
{
- putstr (grub_terminfo_tparm (term.cursor_on), 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));
}
-/* Hide cursor. */
+/* The terminfo version of putchar. */
void
-grub_terminfo_cursor_off (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_off), 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);
}
#define ANSI_C0 0x9b
-void
+static void
grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
{
int c;
#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
grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
+ struct grub_term_output *cur;
+
if (argc == 0)
- {
- grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current());
- return GRUB_ERR_NONE;
- }
- else if (argc != 1)
+ {
+ grub_printf ("Current terminfo types: \n");
+ for (cur = terminfo_outputs; cur;
+ cur = ((struct grub_terminfo_output_state *) cur->data)->next)
+ 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");
- 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;
GRUB_MOD_INIT(terminfo)
{
cmd = grub_register_command ("terminfo", grub_cmd_terminfo,
- N_("[TERM]"), N_("Set terminfo type."));
- grub_terminfo_set_current ("vt100");
+ N_("[TERM TYPE]"), N_("Set terminfo type of TERM to TYPE."));
}
GRUB_MOD_FINI(terminfo)
va_list ap;
char *result;
+ if (!string)
+ return "";
+
va_start (ap, string);
result = tparam_internal (string, ap);
va_end (ap);