#include <grub/term.h>
#include <grub/handler.h>
#include <grub/command.h>
+ #include <grub/i18n.h>
static grub_err_t
-grub_cmd_handler (struct grub_command *cmd,
+grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
- char *class_name;
void *curr_item = 0;
grub_handler_class_t head;
{
cmd_handler =
grub_register_command ("handler", grub_cmd_handler,
- "handler [class [handler]]",
- "List or select a handler.");
+ N_("[class [handler]]"),
+ N_("List or select a handler."));
- cmd_terminal_input =
- grub_register_command ("terminal_input", grub_cmd_handler,
- N_("[handler]"),
- N_("List or select an input terminal."));
- cmd_terminal_output =
- grub_register_command ("terminal_output", grub_cmd_handler,
- N_("[handler]"),
- N_("List or select an output terminal."));
}
GRUB_MOD_FINI(handler)
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/extcmd.h>
+ #include <grub/i18n.h>
+ #include <grub/mm.h>
+ #include <grub/normal.h>
++#include <grub/charset.h>
static grub_err_t
grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
{
- struct grub_term_output *cur;
- int desclen = grub_strlen (cmd->summary);
- FOR_ACTIVE_TERM_OUTPUTS(cur)
++ struct grub_term_output *term;
++ const char *summary_translated = _(cmd->summary);
+ char *command_help;
- int stringwidth;
+ grub_uint32_t *unicode_command_help;
+ grub_uint32_t *unicode_last_position;
- grub_uint32_t *unicode_last_screen_position;
- const char *summary_translated = _(cmd->summary);
+
+ command_help = grub_malloc (grub_strlen (cmd->name) +
+ sizeof (" ") - 1 +
+ grub_strlen (summary_translated));
+
+ grub_sprintf(command_help, "%s %s", cmd->name, summary_translated);
+
+ grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
+ &unicode_last_position);
-
- unicode_last_screen_position = unicode_command_help;
-
- stringwidth = 0;
-
- while (unicode_last_screen_position < unicode_last_position &&
- stringwidth < ((GRUB_TERM_WIDTH / 2) - 2))
- {
- stringwidth += grub_getcharwidth (*unicode_last_screen_position);
- unicode_last_screen_position++;
- }
+
- grub_print_ucs4 (unicode_command_help, unicode_last_screen_position);
-
- if ((cnt++) % 2)
- {
- grub_putchar ('\n');
- }
- else
- {
- grub_print_spaces (GRUB_TERM_WIDTH / 2 - stringwidth);
- }
++ FOR_ACTIVE_TERM_OUTPUTS(term)
+ {
- int width = grub_term_width(cur);
- char description[width / 2];
-
- /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled
- with the description followed by spaces. */
- grub_memset (description, ' ', width / 2 - 1);
- description[width / 2 - 1] = '\0';
- grub_memcpy (description, cmd->summary,
- (desclen < width / 2 - 1
- ? desclen : width / 2 - 1));
- grub_puts_terminal (description, cur);
++ unsigned stringwidth;
++ grub_uint32_t *unicode_last_screen_position;
++
++ unicode_last_screen_position = unicode_command_help;
++
++ stringwidth = 0;
++
++ while (unicode_last_screen_position < unicode_last_position &&
++ stringwidth < ((grub_term_width (term) / 2) - 2))
++ {
++ stringwidth
++ += grub_term_getcharwidth (term,
++ *unicode_last_screen_position);
++ unicode_last_screen_position++;
++ }
++
++ grub_print_ucs4 (unicode_command_help,
++ unicode_last_screen_position, term);
++ if (!(cnt % 2))
++ grub_print_spaces (term, grub_term_width (term) / 2
++ - stringwidth);
+ }
- if ((cnt++) % 2)
++ if (cnt % 2)
+ grub_printf ("\n");
- else
- grub_printf (" ");
++ cnt++;
+
+ grub_free (command_help);
+ grub_free (unicode_command_help);
}
return 0;
}
{
grub_err_t err;
char *pass;
+ int copylen;
if (argc != 2)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
- pass = grub_strdup (args[1]);
+ pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
if (!pass)
return grub_errno;
+ copylen = grub_strlen (args[1]);
+ if (copylen >= GRUB_AUTH_MAX_PASSLEN)
+ copylen = GRUB_AUTH_MAX_PASSLEN - 1;
+ grub_memcpy (pass, args[1], copylen);
err = grub_auth_register_authentication (args[0], check_password, pass);
if (err)
--- /dev/null
- "terminal_input [--append|--remove] "
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/command.h>
+#include <grub/term.h>
+#include <grub/i18n.h>
+#include <grub/misc.h>
+
+struct grub_term_autoload *grub_term_input_autoload = NULL;
+struct grub_term_autoload *grub_term_output_autoload = NULL;
+
+static grub_err_t
+grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ int i;
+ grub_term_input_t term;
+ struct grub_term_autoload *aut;
+
+ if (argc == 0)
+ {
+ grub_puts_ (N_ ("Active input terminals:"));
+ FOR_ACTIVE_TERM_INPUTS(term)
+ grub_printf ("%s ", term->name);
+ grub_printf ("\n");
+ grub_puts_ (N_ ("Available input terminals:"));
+ FOR_DISABLED_TERM_INPUTS(term)
+ grub_printf ("%s ", term->name);
+ /* This is quadratic but we don't expect mode than 30 terminal
+ modules ever. */
+ for (aut = grub_term_input_autoload; aut; aut = aut->next)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ FOR_ACTIVE_TERM_INPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ grub_printf ("%s ", aut->name);
+ }
+ grub_printf ("\n");
+ return GRUB_ERR_NONE;
+ }
+ i = 0;
+
+ if (grub_strcmp (args[0], "--append") == 0
+ || grub_strcmp (args[0], "--remove") == 0)
+ i++;
+
+ if (i == argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
+
+ for (; i < argc; i++)
+ {
+ int again = 0;
+ while (1)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term == 0)
+ FOR_ACTIVE_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ break;
+ if (again)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ for (aut = grub_term_input_autoload; aut; aut = aut->next)
+ if (grub_strcmp (args[i], aut->name) == 0)
+ {
+ grub_dl_t mod;
+ mod = grub_dl_load (aut->modname);
+ if (mod)
+ grub_dl_ref (mod);
+ grub_errno = GRUB_ERR_NONE;
+ break;
+ }
+ if (!aut)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ again = 1;
+ }
+ }
+
+ if (grub_strcmp (args[0], "--append") == 0)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
+ GRUB_AS_LIST (term));
+ if (term->init)
+ term->init ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
+ GRUB_AS_LIST (term));
+ }
+ }
+ return GRUB_ERR_NONE;
+ }
+
+ if (grub_strcmp (args[0], "--remove") == 0)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ FOR_ACTIVE_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ if (!term->next && term == grub_term_inputs)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't remove the last terminal");
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
+ GRUB_AS_LIST (term));
+ if (term->fini)
+ term->fini ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
+ GRUB_AS_LIST (term));
+ }
+ }
+ return GRUB_ERR_NONE;
+ }
+ for (i = 0; i < argc; i++)
+ {
+ FOR_DISABLED_TERM_INPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
+ GRUB_AS_LIST (term));
+ if (term->init)
+ term->init ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
+ GRUB_AS_LIST (term));
+ }
+ }
+
+ FOR_ACTIVE_TERM_INPUTS(term)
+ {
+ for (i = 0; i < argc; i++)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (i == argc)
+ {
+ if (!term->next && term == grub_term_inputs)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't remove the last terminal");
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
+ GRUB_AS_LIST (term));
+ if (term->fini)
+ term->fini ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
+ GRUB_AS_LIST (term));
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ int i;
+ grub_term_output_t term;
+ struct grub_term_autoload *aut;
+
+ if (argc == 0)
+ {
+ grub_puts_ (N_ ("Active output terminals:"));
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ grub_printf ("%s ", term->name);
+ grub_printf ("\n");
+ grub_puts_ (N_ ("Available output terminals:"));
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ grub_printf ("%s ", term->name);
+ /* This is quadratic but we don't expect mode than 30 terminal
+ modules ever. */
+ for (aut = grub_term_output_autoload; aut; aut = aut->next)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (grub_strcmp (term->name, aut->name) == 0)
+ break;
+ if (!term)
+ grub_printf ("%s ", aut->name);
+ }
+ grub_printf ("\n");
+ return GRUB_ERR_NONE;
+ }
+ i = 0;
+
+ if (grub_strcmp (args[0], "--append") == 0
+ || grub_strcmp (args[0], "--remove") == 0)
+ i++;
+
+ if (i == argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
+
+ for (; i < argc; i++)
+ {
+ int again = 0;
+ while (1)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term == 0)
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ break;
+ if (again)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ for (aut = grub_term_output_autoload; aut; aut = aut->next)
+ if (grub_strcmp (args[i], aut->name) == 0)
+ {
+ grub_dl_t mod;
+ mod = grub_dl_load (aut->modname);
+ if (mod)
+ grub_dl_ref (mod);
+ grub_errno = GRUB_ERR_NONE;
+ break;
+ }
+ if (!aut)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
+ args[i]);
+ again = 1;
+ }
+ }
+
+ if (grub_strcmp (args[0], "--append") == 0)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
+ GRUB_AS_LIST (term));
+ if (term->init)
+ term->init ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
+ GRUB_AS_LIST (term));
+ }
+ }
+ return GRUB_ERR_NONE;
+ }
+
+ if (grub_strcmp (args[0], "--remove") == 0)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ if (!term->next && term == grub_term_outputs)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't remove the last terminal");
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
+ GRUB_AS_LIST (term));
+ if (term->fini)
+ term->fini ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
+ GRUB_AS_LIST (term));
+ }
+ }
+ return GRUB_ERR_NONE;
+ }
+
+ for (i = 0; i < argc; i++)
+ {
+ FOR_DISABLED_TERM_OUTPUTS(term)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (term)
+ {
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
+ GRUB_AS_LIST (term));
+ if (term->init)
+ term->init ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
+ GRUB_AS_LIST (term));
+ }
+ }
+
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ {
+ for (i = 0; i < argc; i++)
+ if (grub_strcmp (args[i], term->name) == 0)
+ break;
+ if (i == argc)
+ {
+ if (!term->next && term == grub_term_outputs)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't remove the last terminal");
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
+ GRUB_AS_LIST (term));
+ if (term->fini)
+ term->fini ();
+ grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
+ GRUB_AS_LIST (term));
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_command_t cmd_terminal_input, cmd_terminal_output;
+
+GRUB_MOD_INIT(terminal)
+{
+ cmd_terminal_input =
+ grub_register_command ("terminal_input", grub_cmd_terminal_input,
- "terminal_output [--append|--remove] "
++ "[--append|--remove] "
+ "[TERMINAL1] [TERMINAL2] ...",
+ "List or select an input terminal.");
+ cmd_terminal_output =
+ grub_register_command ("terminal_output", grub_cmd_terminal_output,
++ "[--append|--remove] "
+ "[TERMINAL1] [TERMINAL2] ...",
+ "List or select an output terminal.");
+}
+
+GRUB_MOD_FINI(terminal)
+{
+ grub_unregister_command (cmd_terminal_input);
+ grub_unregister_command (cmd_terminal_output);
+}
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/command.h>
+#include <grub/crypto.h>
+ #include <grub/i18n.h>
-struct tohash
-{
- grub_uint8_t prefix[16];
- grub_uint64_t serial;
-} __attribute__ ((packed));
-
/* This prefix is used by xnu and boot-132 to hash
together with volume serial. */
static grub_uint8_t hash_prefix[16]
static inline void
grub_term_unregister_output (grub_term_output_t term)
{
- grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
+ grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
+ grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
+ GRUB_AS_LIST (term));
}
-static inline grub_err_t
-grub_term_set_current_input (grub_term_input_t term)
+#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
+#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next)
+#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next)
+#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
+
+void EXPORT_FUNC(grub_putchar) (int c);
+void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
+ struct grub_term_output *term);
+int EXPORT_FUNC(grub_getkey) (void);
+int EXPORT_FUNC(grub_checkkey) (void);
+int EXPORT_FUNC(grub_getkeystatus) (void);
+void EXPORT_FUNC(grub_cls) (void);
+void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
+void EXPORT_FUNC(grub_refresh) (void);
+void grub_puts_terminal (const char *str, struct grub_term_output *term);
+grub_uint16_t *grub_term_save_pos (void);
+void grub_term_restore_pos (grub_uint16_t *pos);
+
+static inline unsigned grub_term_width (struct grub_term_output *term)
{
- return grub_handler_set_current (&grub_term_input_class,
- GRUB_AS_HANDLER (term));
+ return ((term->getwh()&0xFF00)>>8);
}
-static inline grub_err_t
-grub_term_set_current_output (grub_term_output_t term)
+static inline unsigned grub_term_height (struct grub_term_output *term)
{
- return grub_handler_set_current (&grub_term_output_class,
- GRUB_AS_HANDLER (term));
+ return (term->getwh()&0xFF);
}
-static inline grub_term_input_t
-grub_term_get_current_input (void)
+/* The width of the border. */
+static inline unsigned
+grub_term_border_width (struct grub_term_output *term)
{
- return (grub_term_input_t) grub_term_input_class.cur_handler;
+ return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
}
-static inline grub_term_output_t
-grub_term_get_current_output (void)
+/* The max column number of an entry. The last "-1" is for a
+ continuation marker. */
+static inline int
+grub_term_entry_width (struct grub_term_output *term)
{
- return (grub_term_output_t) grub_term_output_class.cur_handler;
+ return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
}
-void EXPORT_FUNC(grub_putchar) (int c);
-void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
-grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
-int EXPORT_FUNC(grub_getkey) (void);
-int EXPORT_FUNC(grub_checkkey) (void);
-int EXPORT_FUNC(grub_getkeystatus) (void);
-grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
-grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
-void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
-void EXPORT_FUNC(grub_cls) (void);
-void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
-void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color,
- grub_uint8_t highlight_color);
-void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color,
- grub_uint8_t *highlight_color);
-int EXPORT_FUNC(grub_setcursor) (int on);
-int EXPORT_FUNC(grub_getcursor) (void);
-void EXPORT_FUNC(grub_refresh) (void);
-void EXPORT_FUNC(grub_set_more) (int onoff);
+/* The height of the border. */
+
+static inline unsigned
+grub_term_border_height (struct grub_term_output *term)
+{
+ return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
+ - GRUB_TERM_MESSAGE_HEIGHT;
+}
+
+/* The number of entries shown at a time. */
+static inline int
+grub_term_num_entries (struct grub_term_output *term)
+{
+ return grub_term_border_height (term) - 2;
+}
+
+static inline int
+grub_term_cursor_x (struct grub_term_output *term)
+{
+ return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
+ - GRUB_TERM_MARGIN - 1);
+}
+
+static inline grub_uint16_t
+grub_term_getxy (struct grub_term_output *term)
+{
+ return term->getxy ();
+}
+
+static inline void
+grub_term_refresh (struct grub_term_output *term)
+{
+ if (term->refresh)
+ term->refresh ();
+}
+
+static inline void
+grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
+{
+ term->gotoxy (x, y);
+}
+
+static inline void
+grub_term_setcolorstate (struct grub_term_output *term,
+ grub_term_color_state state)
+{
+ if (term->setcolorstate)
+ term->setcolorstate (state);
+}
+
+ /* Set the normal color and the highlight color. The format of each
+ color is VGA's. */
+static inline void
+grub_term_setcolor (struct grub_term_output *term,
+ grub_uint8_t normal_color, grub_uint8_t highlight_color)
+{
+ if (term->setcolor)
+ term->setcolor (normal_color, highlight_color);
+}
+
+/* Turn on/off the cursor. */
+static inline void
+grub_term_setcursor (struct grub_term_output *term, int on)
+{
+ if (term->setcursor)
+ term->setcursor (on);
+}
+
+static inline void
+grub_term_cls (struct grub_term_output *term)
+{
+ if (term->cls)
+ (term->cls) ();
+ else
+ {
+ grub_putcode ('\n', term);
+ grub_term_refresh (term);
+ }
+}
+
+static inline grub_ssize_t
+grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
+{
+ if (term->getcharwidth)
+ return term->getcharwidth (c);
+ else
+ return 1;
+}
+
+static inline void
+grub_term_getcolor (struct grub_term_output *term,
+ grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
+{
+ if (term->getcolor)
+ term->getcolor (normal_color, highlight_color);
+ else
+ {
+ *normal_color = 0x07;
+ *highlight_color = 0x07;
+ }
+}
+
+extern void (*EXPORT_VAR (grub_newline_hook)) (void);
+
+struct grub_term_autoload
+{
+ struct grub_term_autoload *next;
+ char *name;
+ char *modname;
+};
+
+extern struct grub_term_autoload *grub_term_input_autoload;
+extern struct grub_term_autoload *grub_term_output_autoload;
-grub_print_spaces (int number_spaces)
+ static inline void
- grub_putchar (' ');
++grub_print_spaces (struct grub_term_output *term, int number_spaces)
+ {
+ while (--number_spaces >= 0)
++ grub_putcode (' ', term);
+ }
+
+
/* For convenience. */
#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff)
grub_size_t saved_lpos = lpos;
lpos = llen - len;
- cl_set_pos ();
- cl_print (lpos, ' ');
+ cl_set_pos_all ();
+ cl_print_all (lpos, ' ');
lpos = saved_lpos;
- cl_set_pos ();
+ cl_set_pos_all ();
- grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
+ grub_memmove (buf + lpos, buf + lpos + len,
+ sizeof (grub_uint32_t) * (llen - lpos + 1));
llen -= len;
- cl_print (lpos, echo_char);
- cl_set_pos ();
+ cl_print_all (lpos, 0);
+ cl_set_pos_all ();
}
-
- grub_refresh ();
}
- plen = grub_strlen (prompt_translated);
+ void init_clterm (struct cmdline_term *cl_term_cur)
+ {
+ cl_term_cur->xpos = plen;
+ cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF);
+ cl_term_cur->ystart = cl_term_cur->ypos;
+ cl_term_cur->width = grub_term_width (cl_term_cur->term);
+ cl_term_cur->height = grub_term_height (cl_term_cur->term);
+ }
+
+ void init_clterm_all (void)
+ {
+ unsigned i;
+ for (i = 0; i < nterms; i++)
+ init_clterm (&cl_terms[i]);
+ }
+
+ buf = grub_malloc (max_len * sizeof (grub_uint32_t));
+ if (!buf)
+ return 0;
+
+ plen = grub_strlen (prompt_translated) + sizeof (" ") - 1;
lpos = llen = 0;
buf[0] = '\0';
- if ((grub_getxy () >> 8) != 0)
- grub_putchar ('\n');
+ {
+ grub_term_output_t term;
- grub_printf ("%s", prompt_translated);
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if ((grub_term_getxy (term) >> 8) != 0)
+ grub_putcode ('\n', term);
+ }
+ grub_printf ("%s ", prompt_translated);
- xpos = plen;
- ystart = ypos = (grub_getxy () & 0xFF);
-
- cl_insert (cmdline);
+ {
+ struct cmdline_term *cl_term_cur;
+ struct grub_term_output *cur;
+ nterms = 0;
+ FOR_ACTIVE_TERM_OUTPUTS(cur)
+ nterms++;
+
+ cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
+ if (!cl_terms)
+ return 0;
+ cl_term_cur = cl_terms;
+ FOR_ACTIVE_TERM_OUTPUTS(cur)
+ {
+ cl_term_cur->term = cur;
+ init_clterm (cl_term_cur);
+ cl_term_cur++;
+ }
+ }
- if (history && hist_used == 0)
- grub_history_add (buf);
+ if (hist_used == 0)
+ grub_history_add (buf, llen);
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
{
return 0;
}
-static char cmdline[GRUB_MAX_CMDLINE];
static grub_err_t
-grub_normal_read_line (char **line, int cont)
+grub_normal_read_line_real (char **line, int cont, int nested)
{
grub_parser_t parser = grub_parser_get_current ();
- char prompt[sizeof("> ") + grub_strlen (parser->name)];
+ char prompt[sizeof(">") + grub_strlen (parser->name)];
- grub_sprintf (prompt, "%s>", parser->name);
+ if (cont)
- grub_sprintf (prompt, "> ");
++ grub_sprintf (prompt, ">");
+ else
- grub_sprintf (prompt, "%s> ", parser->name);
++ grub_sprintf (prompt, "%s>", parser->name);
while (1)
{
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
/* Register a command "normal" for the rescue mode. */
- grub_register_command_prio ("normal", grub_cmd_normal,
- 0, "Enter normal mode.", 0);
+ grub_register_command ("normal", grub_cmd_normal,
- 0, "Enter normal mode");
++ 0, "Enter normal mode.");
+ grub_register_command ("normal_exit", grub_cmd_normal_exit,
- 0, "Exit from normal mode");
++ 0, "Exit from normal mode.");
/* Reload terminal colors when these variables are written to. */
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
next_new_line = (grub_uint32_t *) last_position;
- while (grub_getstringwidth (current_position, next_new_line) > line_len
+ while (grub_getstringwidth (current_position, next_new_line,term)
+ > line_len
- || (*next_new_line != ' ' && next_new_line > current_position &&
- next_new_line != last_position))
+ || (next_new_line != last_position && *next_new_line != ' '
+ && next_new_line > current_position))
{
next_new_line--;
}
}
static void
-print_timeout (int timeout, int offset)
+menu_text_print_timeout (int timeout, void *dataptr)
{
const char *msg =
- _("The highlighted entry will be booted automatically in %ds.");
+ _("The highlighted entry will be executed automatically in %ds.");
+ struct menu_viewer_data *data = dataptr;
+ char *msg_translated;
+ int posx;
- grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+ grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
- char *msg_translated =
- grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
+ msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
+ if (!msg_translated)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ return;
+ }
grub_sprintf (msg_translated, msg, timeout);
- grub_print_message_indented (msg_translated, 3, 0);
+ grub_print_message_indented (msg_translated, 3, 0, data->term);
- int posx;
- posx = grub_getxy() >> 8;
- grub_print_spaces (GRUB_TERM_WIDTH - posx - 1);
+ posx = grub_term_getxy (data->term) >> 8;
+ print_spaces (grub_term_width (data->term) - posx - 1, data->term);
- grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
- grub_refresh ();
+ grub_term_gotoxy (data->term,
+ grub_term_cursor_x (data->term),
+ GRUB_TERM_FIRST_ENTRY_Y + data->offset);
+ grub_term_refresh (data->term);
}
-/* Show the menu and handle menu entry selection. Returns the menu entry
- index that should be executed or -1 if no entry should be executed (e.g.,
- Esc pressed to exit a sub-menu or switching menu viewers).
- If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
- entry to be executed is a result of an automatic default selection because
- of the timeout. */
-static int
-run_menu (grub_menu_t menu, int nested, int *auto_boot)
+static void
+menu_text_set_chosen_entry (int entry, void *dataptr)
{
- int first, offset;
- grub_uint64_t saved_time;
- int default_entry;
- int timeout;
-
- first = 0;
+ struct menu_viewer_data *data = dataptr;
+ int oldoffset = data->offset;
+ int complete_redraw = 0;
- default_entry = get_entry_number ("default");
-
- /* If DEFAULT_ENTRY is not within the menu entries, fall back to
- the first entry. */
- if (default_entry < 0 || default_entry >= menu->size)
- default_entry = 0;
-
- /* If timeout is 0, drawing is pointless (and ugly). */
- if (grub_menu_get_timeout () == 0)
+ data->offset = entry - data->first;
+ if (data->offset > grub_term_num_entries (data->term) - 1)
{
- *auto_boot = 1;
- return default_entry;
+ data->first = entry - (grub_term_num_entries (data->term) - 1);
+ data->offset = grub_term_num_entries (data->term) - 1;
+ complete_redraw = 1;
}
-
- offset = default_entry;
- if (offset > GRUB_TERM_NUM_ENTRIES - 1)
+ if (data->offset < 0)
{
- first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
- offset = GRUB_TERM_NUM_ENTRIES - 1;
+ data->offset = 0;
+ data->first = entry;
+ complete_redraw = 1;
}
-
- /* Initialize the time. */
- saved_time = grub_get_time_ms ();
-
- refresh:
- grub_setcursor (0);
- grub_menu_init_page (nested, 0);
- print_entries (menu, first, offset);
- grub_refresh ();
-
- timeout = grub_menu_get_timeout ();
-
- if (timeout > 0)
- print_timeout (timeout, offset);
-
- while (1)
+ if (complete_redraw)
+ print_entries (data->menu, data->first, data->offset, data->term);
+ else
{
- int c;
- timeout = grub_menu_get_timeout ();
-
- if (timeout > 0)
- {
- grub_uint64_t current_time;
-
- current_time = grub_get_time_ms ();
- if (current_time - saved_time >= 1000)
- {
- timeout--;
- grub_menu_set_timeout (timeout);
- saved_time = current_time;
- print_timeout (timeout, offset);
- }
- }
-
- if (timeout == 0)
- {
- grub_env_unset ("timeout");
- *auto_boot = 1;
- return default_entry;
- }
-
- if (grub_checkkey () >= 0 || timeout < 0)
- {
- c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
-
- if (timeout >= 0)
- {
- grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
- grub_print_spaces (GRUB_TERM_WIDTH - 1);
-
- grub_env_unset ("timeout");
- grub_env_unset ("fallback");
- grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
- }
-
- switch (c)
- {
- case GRUB_TERM_HOME:
- first = 0;
- offset = 0;
- print_entries (menu, first, offset);
- break;
-
- case GRUB_TERM_END:
- offset = menu->size - 1;
- if (offset > GRUB_TERM_NUM_ENTRIES - 1)
- {
- first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
- offset = GRUB_TERM_NUM_ENTRIES - 1;
- }
- print_entries (menu, first, offset);
- break;
-
- case GRUB_TERM_UP:
- case '^':
- if (offset > 0)
- {
- print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
- grub_menu_get_entry (menu, first + offset));
- offset--;
- print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
- grub_menu_get_entry (menu, first + offset));
- }
- else if (first > 0)
- {
- first--;
- print_entries (menu, first, offset);
- }
- break;
-
- case GRUB_TERM_DOWN:
- case 'v':
- if (menu->size > first + offset + 1)
- {
- if (offset < GRUB_TERM_NUM_ENTRIES - 1)
- {
- print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
- grub_menu_get_entry (menu, first + offset));
- offset++;
- print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
- grub_menu_get_entry (menu, first + offset));
- }
- else
- {
- first++;
- print_entries (menu, first, offset);
- }
- }
- break;
-
- case GRUB_TERM_PPAGE:
- if (first == 0)
- {
- offset = 0;
- }
- else
- {
- first -= GRUB_TERM_NUM_ENTRIES;
-
- if (first < 0)
- {
- offset += first;
- first = 0;
- }
- }
- print_entries (menu, first, offset);
- break;
-
- case GRUB_TERM_NPAGE:
- if (offset == 0)
- {
- offset += GRUB_TERM_NUM_ENTRIES - 1;
- if (first + offset >= menu->size)
- {
- offset = menu->size - first - 1;
- }
- }
- else
- {
- first += GRUB_TERM_NUM_ENTRIES;
-
- if (first + offset >= menu->size)
- {
- first -= GRUB_TERM_NUM_ENTRIES;
- offset += GRUB_TERM_NUM_ENTRIES;
-
- if (offset > menu->size - 1 ||
- offset > GRUB_TERM_NUM_ENTRIES - 1)
- {
- offset = menu->size - first - 1;
- }
- if (offset > GRUB_TERM_NUM_ENTRIES)
- {
- first += offset - GRUB_TERM_NUM_ENTRIES + 1;
- offset = GRUB_TERM_NUM_ENTRIES - 1;
- }
- }
- }
- print_entries (menu, first, offset);
- break;
-
- case '\n':
- case '\r':
- case 6:
- grub_setcursor (1);
- *auto_boot = 0;
- return first + offset;
-
- case '\e':
- if (nested)
- {
- grub_setcursor (1);
- return -1;
- }
- break;
-
- case 'c':
- grub_cmdline_run (1);
- goto refresh;
-
- case 'e':
- {
- grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset);
- if (e)
- grub_menu_entry_run (e);
- }
- goto refresh;
-
- default:
- break;
- }
-
- grub_refresh ();
- }
+ print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
+ grub_menu_get_entry (data->menu, data->first + oldoffset),
+ data->term);
+ print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1,
+ grub_menu_get_entry (data->menu, data->first + data->offset),
+ data->term);
}
-
- /* Never reach here. */
- return -1;
+ grub_term_refresh (data->term);
}
-/* Callback invoked immediately before a menu entry is executed. */
static void
-notify_booting (grub_menu_entry_t entry,
- void *userdata __attribute__((unused)))
+menu_text_fini (void *dataptr)
{
- grub_printf (" ");
- grub_printf_ (N_("Booting \'%s\'"), entry->title);
- grub_printf ("\n\n");
-}
+ struct menu_viewer_data *data = dataptr;
+
+ grub_term_setcursor (data->term, 1);
+ grub_term_cls (data->term);
-/* Callback invoked when a default menu entry executed because of a timeout
- has failed and an attempt will be made to execute the next fallback
- entry, ENTRY. */
-static void
-notify_fallback (grub_menu_entry_t entry,
- void *userdata __attribute__((unused)))
-{
- grub_printf ("\n ");
- grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
- grub_printf ("\n\n");
- grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
}
-/* Callback invoked when a menu entry has failed and there is no remaining
- fallback entry to attempt. */
static void
-notify_execution_failure (void *userdata __attribute__((unused)))
+menu_text_clear_timeout (void *dataptr)
{
- if (grub_errno != GRUB_ERR_NONE)
- {
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- }
- grub_printf ("\n ");
- grub_printf_ (N_("Failed to boot default entries.\n"));
- grub_wait_after_message ();
+ struct menu_viewer_data *data = dataptr;
+
+ grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
+ print_spaces (grub_term_width (data->term) - 1, data->term);
+ grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
+ GRUB_TERM_FIRST_ENTRY_Y + data->offset);
+ grub_term_refresh (data->term);
}
-/* Callbacks used by the text menu to provide user feedback when menu entries
- are executed. */
-static struct grub_menu_execute_callback execution_callback =
+grub_err_t
+grub_menu_try_text (struct grub_term_output *term,
+ int entry, grub_menu_t menu, int nested)
{
- .notify_booting = notify_booting,
- .notify_fallback = notify_fallback,
- .notify_failure = notify_execution_failure
-};
+ struct menu_viewer_data *data;
+ struct grub_menu_viewer *instance;
-static grub_err_t
-show_text_menu (grub_menu_t menu, int nested)
-{
- while (1)
- {
- int boot_entry;
- grub_menu_entry_t e;
- int auto_boot;
+ instance = grub_zalloc (sizeof (*instance));
+ if (!instance)
+ return grub_errno;
- boot_entry = run_menu (menu, nested, &auto_boot);
- if (boot_entry < 0)
- break;
+ data = grub_zalloc (sizeof (*data));
+ if (!data)
+ {
+ grub_free (instance);
+ return grub_errno;
+ }
- e = grub_menu_get_entry (menu, boot_entry);
- if (! e)
- continue; /* Menu is empty. */
+ data->term = term;
+ instance->data = data;
+ instance->set_chosen_entry = menu_text_set_chosen_entry;
+ instance->print_timeout = menu_text_print_timeout;
+ instance->clear_timeout = menu_text_clear_timeout;
+ instance->fini = menu_text_fini;
- grub_cls ();
- grub_setcursor (1);
+ data->menu = menu;
- if (auto_boot)
- {
- grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
- }
- else
- {
- grub_errno = GRUB_ERR_NONE;
- grub_menu_execute_entry (e);
- if (grub_errno != GRUB_ERR_NONE)
- {
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- grub_wait_after_message ();
- }
- }
+ data->offset = entry;
+ data->first = 0;
+ if (data->offset > grub_term_num_entries (data->term) - 1)
+ {
+ data->first = data->offset - (grub_term_num_entries (data->term) - 1);
+ data->offset = grub_term_num_entries (data->term) - 1;
}
+ grub_term_setcursor (data->term, 0);
+ grub_menu_init_page (nested, 0, data->term);
+ print_entries (menu, data->first, data->offset, data->term);
+ grub_term_refresh (data->term);
+ grub_menu_register_viewer (instance);
+
return GRUB_ERR_NONE;
}
-
-struct grub_menu_viewer grub_normal_text_menu_viewer =
-{
- .name = "text",
- .show_menu = show_text_menu
-};
#include <grub/menu.h>
#include <grub/auth.h>
-/* The list of menu viewers. */
-static grub_menu_viewer_t menu_viewer_list;
-
-void
-grub_menu_viewer_register (grub_menu_viewer_t viewer)
-{
- viewer->next = menu_viewer_list;
- menu_viewer_list = viewer;
-}
-
-static grub_menu_viewer_t get_current_menu_viewer (void)
-{
- const char *selected_name = grub_env_get ("menuviewer");
-
- /* If none selected, pick the last registered one. */
- if (selected_name == 0)
- return menu_viewer_list;
-
- grub_menu_viewer_t cur;
- for (cur = menu_viewer_list; cur; cur = cur->next)
- {
- if (grub_strcmp (cur->name, selected_name) == 0)
- return cur;
- }
-
- /* Fall back to the first entry (or null). */
- return menu_viewer_list;
-}
-
-grub_err_t
-grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
-{
- grub_menu_viewer_t cur = get_current_menu_viewer ();
- grub_err_t err1, err2;
- if (!cur)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menu viewer available");
-
- while (1)
- {
- err1 = cur->show_menu (menu, nested);
- grub_print_error ();
-
- err2 = grub_auth_check_authentication (NULL);
- if (err2)
- {
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- continue;
- }
-
- break;
- }
-
- return err1;
-}
--
GRUB_MOD_INIT(term_gfxterm)
{
+#ifdef GRUB_MACHINE_MIPS_YEELOONG
+ grub_term_register_output_active ("gfxterm", &grub_video_term);
+#else
grub_term_register_output ("gfxterm", &grub_video_term);
+#endif
cmd = grub_register_command ("background_image",
grub_gfxterm_background_image_cmd,
- 0, "Load background image for active terminal");
+ 0, "Load background image for active terminal.");
}
GRUB_MOD_FINI(term_gfxterm)