diff --git a/ChangeLog b/ChangeLog index dc95c5296..301f32d48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-09-20 Vladimir Serbinenko + + Suport manual terminal geometry specification. + + * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): + Save state in grub_ofconsole_terminfo_output. + (grub_ofconsole_term): Use grub_terminfo_getwh. + (grub_ofconsole_getwh): Removed. + * grub-core/term/serial.c (grub_serial_getwh): Removed. + (grub_serial_term): Use grub_terminfo_getwh. + * grub-core/term/terminfo.c (grub_terminfo_getwh): New function. + (options): New struct. + (OPTION_*): New enum. + (grub_cmd_terminfo): Transform into extcmd and handle new parameters. + * include/grub/terminfo.h (grub_terminfo_output_state): New fields + width and height. + (grub_terminfo_getwh): New proto. + * grub-core/lib/legacy_parse.c (grub_legacy_parse): Handle --lines. + 2010-09-20 Vladimir Serbinenko Handle legacy "terminal" command. diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index 09905bd42..ae27048a2 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -273,7 +273,7 @@ struct legacy_command legacy_commands[] = " default values are COM1, 9600, 8N1."}, /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ /* NOTE: setup unsupported. */ - /* FIXME: --no-echo, --no-edit, --lines, hercules unsupported. */ + /* FIXME: --no-echo, --no-edit, hercules unsupported. */ /* NOTE: both terminals are activated so --silent and --timeout are useless. */ {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, @@ -558,20 +558,16 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) } grub_strcpy (outptr, "; "); outptr += grub_strlen (outptr); - if (serial && dumb) + if (serial) { - grub_strcpy (outptr, "terminfo serial dumb; "); - outptr += grub_strlen (outptr); - } - - if (serial && !dumb) - { - grub_strcpy (outptr, "terminfo serial vt100; "); + grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr, + "terminfo serial -g 80x%d %s; ", + lines, dumb ? "dumb" : "vt100"); outptr += grub_strlen (outptr); } grub_strcpy (outptr, "\n"); - + return grub_strdup (outbuf); } diff --git a/grub-core/term/ieee1275/ofconsole.c b/grub-core/term/ieee1275/ofconsole.c index 226b78b71..944056ba6 100644 --- a/grub-core/term/ieee1275/ofconsole.c +++ b/grub-core/term/ieee1275/ofconsole.c @@ -29,8 +29,7 @@ static grub_ieee1275_ihandle_t stdout_ihandle; static grub_ieee1275_ihandle_t stdin_ihandle; -static grub_uint8_t grub_ofconsole_width; -static grub_uint8_t grub_ofconsole_height; +extern struct grub_terminfo_output_state grub_ofconsole_terminfo_output; struct color { @@ -91,7 +90,8 @@ grub_ofconsole_dimensions (void) if (! grub_ieee1275_get_property (options, "screen-#columns", val, lval, 0)) - grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10); + grub_ofconsole_terminfo_output->width + = (grub_uint8_t) grub_strtoul (val, 0, 10); } if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval) && lval >= 0 && lval < 1024) @@ -99,21 +99,16 @@ grub_ofconsole_dimensions (void) char val[lval]; if (! grub_ieee1275_get_property (options, "screen-#rows", val, lval, 0)) - grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10); + grub_ofconsole_terminfo_output->height + = (grub_uint8_t) grub_strtoul (val, 0, 10); } } /* Use a small console by default. */ - if (! grub_ofconsole_width) - grub_ofconsole_width = 80; - if (! grub_ofconsole_height) - grub_ofconsole_height = 24; -} - -static grub_uint16_t -grub_ofconsole_getwh (struct grub_term_output *term __attribute__ ((unused))) -{ - return (grub_ofconsole_width << 8) | grub_ofconsole_height; + if (! grub_ofconsole_terminfo_output->width) + grub_ofconsole_terminfo_output->width = 80; + if (! grub_ofconsole_terminfo_output->height) + grub_ofconsole_terminfo_output->height = 24; } static void @@ -187,7 +182,9 @@ struct grub_terminfo_input_state grub_ofconsole_terminfo_input = struct grub_terminfo_output_state grub_ofconsole_terminfo_output = { - .put = put + .put = put, + .width = 80, + .height = 24 }; static struct grub_term_input grub_ofconsole_term_input = @@ -204,7 +201,7 @@ static struct grub_term_output grub_ofconsole_term_output = .init = grub_ofconsole_init_output, .putchar = grub_terminfo_putchar, .getxy = grub_terminfo_getxy, - .getwh = grub_ofconsole_getwh, + .getwh = grub_terminfo_getwh, .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, .setcolorstate = grub_terminfo_setcolorstate, diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index e318e4b43..1ef17aa25 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -55,14 +55,6 @@ struct grub_serial_input_state struct grub_serial_port *port; }; -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 void serial_put (grub_term_output_t term, const int c) { @@ -89,7 +81,9 @@ struct grub_serial_output_state grub_serial_terminfo_output = { .tinfo = { - .put = serial_put + .put = serial_put, + .width = 80, + .height = 24 } }; @@ -107,7 +101,7 @@ static struct grub_term_output grub_serial_term_output = { .name = "serial", .putchar = grub_terminfo_putchar, - .getwh = grub_serial_getwh, + .getwh = grub_terminfo_getwh, .getxy = grub_terminfo_getxy, .gotoxy = grub_terminfo_gotoxy, .cls = grub_terminfo_cls, diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index 8dea7aea1..d01811959 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -358,6 +358,15 @@ grub_terminfo_putchar (struct grub_term_output *term, data->put (term, c->base); } +grub_uint16_t +grub_terminfo_getwh (struct grub_term_output *term) +{ + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) term->data; + + return (data->width << 8) | data->height; +} + #define ANSI_C0 0x9b static void @@ -537,85 +546,96 @@ print_terminfo (void) return GRUB_ERR_NONE; } +static const struct grub_arg_option options[] = +{ + {"ascii", 'a', 0, N_("Terminal is ASCII-only [default]."), 0, ARG_TYPE_NONE}, + {"utf8", 'u', 0, N_("Terminal is logical-ordered UTF-8."), 0, ARG_TYPE_NONE}, + {"visual-utf8", 'v', 0, N_("Terminal is visually-ordered UTF-8."), 0, + ARG_TYPE_NONE}, + {"geometry", 'g', 0, N_("Terminal has given geometry."), + N_("WIDTHxHEIGHT."), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +enum + { + OPTION_ASCII, + OPTION_UTF8, + OPTION_VISUAL_UTF8, + OPTION_GEOMETRY + }; + static grub_err_t -grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_term_output *cur; int encoding = GRUB_TERM_CODE_TYPE_ASCII; - int i; - char *name = NULL, *type = NULL; + struct grub_arg_list *state = ctxt->state; + int w = 0, h = 0; if (argc == 0) return print_terminfo (); - for (i = 0; i < argc; i++) + if (state[OPTION_ASCII].set) + encoding = GRUB_TERM_CODE_TYPE_ASCII; + + if (state[OPTION_UTF8].set) + encoding = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; + + if (state[OPTION_VISUAL_UTF8].set) + encoding = GRUB_TERM_CODE_TYPE_UTF8_VISUAL; + + if (state[OPTION_GEOMETRY].set) { - 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"); + char *ptr = state[OPTION_GEOMETRY].arg; + w = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr != 'x') + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "incorrect geometry specification"); + ptr++; + h = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; } - 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) + if (grub_strcmp (args[0], cur->name) == 0) { cur->flags = (cur->flags & ~GRUB_TERM_CODE_TYPE_MASK) | encoding; - if (!type) + + if (w && h) + { + struct grub_terminfo_output_state *data + = (struct grub_terminfo_output_state *) cur->data; + data->width = w; + data->height = h; + } + + if (argc == 1) return GRUB_ERR_NONE; - return grub_terminfo_set_current (cur, type); + 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", - name); + args[0]); } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(terminfo) { - cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - 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.") - - ); + cmd = grub_register_extcmd ("terminfo", grub_cmd_terminfo, 0, + N_("[[-a|-u|-v] [-g WxH] TERM [TYPE]]"), + N_("Set terminfo type of TERM to TYPE.\n"), + options); } GRUB_MOD_FINI(terminfo) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h index 1962c71b7..8317995d8 100644 --- a/include/grub/terminfo.h +++ b/include/grub/terminfo.h @@ -49,6 +49,8 @@ struct grub_terminfo_output_state char *cursor_off; char *setcolor; + unsigned int width, height; + unsigned int xpos, ypos; void (*put) (struct grub_term_output *term, const int c); @@ -68,6 +70,8 @@ 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); +grub_uint16_t EXPORT_FUNC (grub_terminfo_getwh) (struct grub_term_output *term); + grub_err_t EXPORT_FUNC (grub_terminfo_output_register) (struct grub_term_output *term, const char *type);