Working multi-terminal

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-12-24 21:54:37 +01:00
parent 3be7f8de12
commit 0aa6339849
6 changed files with 334 additions and 42 deletions

View file

@ -25,10 +25,9 @@
#include <grub/command.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;
@ -43,23 +42,19 @@ grub_cmd_handler (struct grub_command *cmd,
return 0;
}
class_name = (grub_strcmp (cmd->name, "handler")) ? (char *) cmd->name : 0;
head = grub_handler_class_list;
if ((argc == 0) && (class_name == 0))
if (argc == 0)
{
grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
}
else
{
char *class_name;
grub_handler_class_t class;
if (class_name == 0)
{
class_name = args[0];
argc--;
args++;
}
class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
if (! class)
@ -89,7 +84,7 @@ grub_cmd_handler (struct grub_command *cmd,
return 0;
}
static grub_command_t cmd_handler, cmd_terminal_input, cmd_terminal_output;
static grub_command_t cmd_handler;
GRUB_MOD_INIT(handler)
{
@ -97,19 +92,9 @@ GRUB_MOD_INIT(handler)
grub_register_command ("handler", grub_cmd_handler,
"handler [class [handler]]",
"List or select a handler.");
cmd_terminal_input =
grub_register_command ("terminal_input", grub_cmd_handler,
"terminal_input [handler]",
"List or select an input terminal.");
cmd_terminal_output =
grub_register_command ("terminal_output", grub_cmd_handler,
"terminal_output [handler]",
"List or select an output terminal.");
}
GRUB_MOD_FINI(handler)
{
grub_unregister_command (cmd_handler);
grub_unregister_command (cmd_terminal_input);
grub_unregister_command (cmd_terminal_output);
}

290
commands/terminal.c Normal file
View file

@ -0,0 +1,290 @@
/*
* 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>
grub_err_t
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_input_t term;
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);
grub_printf ("\n");
return GRUB_ERR_NONE;
}
i = 0;
if (grub_strcmp (args[0], "--append") == 0
|| grub_strcmp (args[0], "--removed") == 0)
i++;
if (i == argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
for (; i < argc; i++)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
}
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;
}
grub_err_t
grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_output_t term;
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);
grub_printf ("\n");
return GRUB_ERR_NONE;
}
i = 0;
if (grub_strcmp (args[0], "--append") == 0
|| grub_strcmp (args[0], "--removed") == 0)
i++;
if (i == argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
for (; i < argc; i++)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
}
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_input [--append|--remove] "
"[TERMINAL1] [TERMINAL2] ...",
"List or select an input terminal.");
cmd_terminal_output =
grub_register_command ("terminal_output", grub_cmd_terminal_output,
"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);
}

View file

@ -16,8 +16,4 @@
module=$1
grep -v "^#" | sed -n \
-e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" \
-e "/grub_reader_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/reader.\1: $module/;p;}" \
-e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_input.\1: $module/;p;}" \
-e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_output.\1: $module/;p;}" \
-e "/grub_menu_viewer_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/menu_viewer.\1: $module/;p;}"
-e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}"

View file

@ -68,8 +68,6 @@ grub_term_color_state;
#define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2)
/* Terminal is used as general output. */
#define GRUB_TERM_ACTIVE (1 << 3)
/* Set when the terminal needs to be initialized. */
#define GRUB_TERM_NEED_INIT (1 << 16)
@ -197,37 +195,65 @@ struct grub_term_output
};
typedef struct grub_term_output *grub_term_output_t;
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
static inline void
grub_term_register_input_active (const char *name __attribute__ ((unused)),
grub_term_input_t term)
{
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
}
static inline void
grub_term_register_input (const char *name __attribute__ ((unused)),
grub_term_input_t term)
{
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
static inline void
grub_term_register_output_active (const char *name __attribute__ ((unused)),
grub_term_output_t term)
{
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
}
static inline void
grub_term_register_output (const char *name __attribute__ ((unused)),
grub_term_output_t term)
{
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
}
static inline void
grub_term_unregister_input (grub_term_input_t term)
{
grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
static inline void
grub_term_unregister_output (grub_term_output_t 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));
}
#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) if (grub_term_is_active (var))
#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,
@ -335,12 +361,6 @@ grub_term_setcursor (struct grub_term_output *term, int on)
term->setcursor (on);
}
static inline int
grub_term_is_active (struct grub_term_output *term)
{
return !!(term->flags & GRUB_TERM_ACTIVE);
}
static inline grub_ssize_t
grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
{

View file

@ -23,6 +23,8 @@
#include <grub/env.h>
#include <grub/cpu/time.h>
struct grub_term_output *grub_term_outputs_disabled;
struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;

View file

@ -65,15 +65,14 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor,
.flags = GRUB_TERM_ACTIVE,
.setcursor = grub_console_setcursor
};
void
grub_console_init (void)
{
grub_term_register_output ("console", &grub_console_term_output);
grub_term_register_input ("console", &grub_console_term_input);
grub_term_register_output_active ("console", &grub_console_term_output);
grub_term_register_input_active ("console", &grub_console_term_input);
}
void