diff --git a/ChangeLog b/ChangeLog index 889643932..481446c45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,144 @@ +2008-11-07 Robert Millan + + Modularize at_keyboard.mod: + + * conf/i386.rmk (pkglib_MODULES): Add `at_keyboard.mod'. + (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) + (at_keyboard_mod_LDFLAGS): New variables. + + Actual terminal split: + + * include/grub/term.h (struct grub_term): Split in ... + (struct grub_term_input): ... this, and ... + (struct grub_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/term.c (grub_term_list): Split in ... + (grub_term_list_input): ... this, and ... + (grub_term_list_output): ... this. Update all users. + (grub_cur_term): Split in ... + (grub_cur_term_input): ... this, and ... + (grub_cur_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/misc.c (grub_abort): Split use of grub_term_get_current() into + a check for input and one for output (and only attempt to get keys + from user when input works). + + * util/grub-probe.c (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + * util/grub-fstest.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/grub-editenv.c: Likewise. + + Portability adjustments: + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Remove + `term/i386/pc/at_keyboard.c'. + * kern/ieee1275/init.c [__i386__] (grub_machine_init): Remove call to + grub_keyboard_controller_init() (now handled by terminal .init). + * kern/i386/coreboot/init.c (grub_machine_init): Add call to + grub_at_keyboard_init(). + * include/grub/i386/ieee1275/console.h (grub_keyboard_controller_init) + (grub_console_checkkey, grub_console_getkey): Remove (now provided by + at_keyboard.mod via input terminal interface). + * include/grub/i386/coreboot/console.h: Convert into a stub for + `'. + + Migrate full terminals to new API: + + * term/efi/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + * term/ieee1275/ofconsole.c: Remove __i386__ hack. + (grub_ofconsole_init): Split into ... + (grub_ofconsole_init_input): ... this, and ... + (grub_ofconsole_init_output): ... this. + (grub_ofconsole_term): Split into ... + (grub_ofconsole_term_input): ... this, and ... + (grub_ofconsole_term_output): ... this. Update all users. + * term/i386/pc/serial.c (grub_serial_term): Split into ... + (grub_serial_term_input): ... this, and ... + (grub_serial_term_output): ... this. Update all users. + * term/i386/pc/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + (grub_console_term_input): Only enable it on PC/BIOS platform. + (grub_console_init): Remove grub_keyboard_controller_init() call. + + Migrate input terminals to new API: + + * term/i386/pc/at_keyboard.c: Replace `cpu' and `machine' with + `i386' and `i386/pc' to enable build on x86_64 (this driver is + i386-specific anyway). + (grub_console_checkkey): Rename to ... + (grub_at_keyboard_checkkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_orig): New variable. + (grub_console_getkey): Rename to ... + (grub_at_keyboard_getkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_init): Static-ize. Save original + controller value so that it can be restored ... + (grub_keyboard_controller_fini): ... here (new function). + (grub_at_keyboard_term): New structure. + (GRUB_MOD_INIT(at_keyboard), GRUB_MOD_FINI(at_keyboard)): New + functions. + + Migrate output terminals to new API: + + * term/i386/pc/vga.c (grub_vga_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * term/gfxterm.c (grub_video_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * include/grub/i386/pc/console.h (grub_console_checkkey) + (grub_console_getkey): Do not export (no longer needed by gfxterm, + etc). + + Migrate `terminal' command and userland tools to new API: + + * commands/terminal.c (grub_cmd_terminal): Split into ... + (grub_cmd_terminal_input): ... this, and ... + (grub_cmd_terminal_output): ... this. + (GRUB_MOD_INIT(terminal)): Split `terminal' command in two commands: + `terminal_input' and `terminal_output'. + * util/grub.d/00_header.in: Adjust `terminal' calls to new + `terminal_input' / `terminal_output' API. + * util/grub-mkconfig.in: Export ${GRUB_TERMINAL_INPUT} and + ${GRUB_TERMINAL_OUTPUT} instead of ${GRUB_TERMINAL} (and if user + provided ${GRUB_TERMINAL}, convert it). + 2008-11-04 Robert Millan * util/grub.d/10_freebsd.in: New file. Generate grub configuration diff --git a/commands/terminal.c b/commands/terminal.c index bd57b6f96..31c979d4c 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -24,21 +24,21 @@ #include static grub_err_t -grub_cmd_terminal (struct grub_arg_list *state __attribute__ ((unused)), - int argc, char **args) +grub_cmd_terminal_input (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) { - grub_term_t term = 0; + grub_term_input_t term = 0; - auto int print_terminal (grub_term_t); - auto int find_terminal (grub_term_t); + auto int print_terminal (grub_term_input_t); + auto int find_terminal (grub_term_input_t); - int print_terminal (grub_term_t t) + int print_terminal (grub_term_input_t t) { grub_printf (" %s", t->name); return 0; } - int find_terminal (grub_term_t t) + int find_terminal (grub_term_input_t t) { if (grub_strcmp (t->name, args[0]) == 0) { @@ -51,19 +51,65 @@ grub_cmd_terminal (struct grub_arg_list *state __attribute__ ((unused)), if (argc == 0) { - grub_printf ("Available terminal(s):"); - grub_term_iterate (print_terminal); + grub_printf ("Available input terminal(s):"); + grub_term_iterate_input (print_terminal); grub_putchar ('\n'); - grub_printf ("Current terminal: %s\n", grub_term_get_current ()->name); + grub_printf ("Current input terminal: %s\n", grub_term_get_current_input ()->name); } else { - grub_term_iterate (find_terminal); + grub_term_iterate_input (find_terminal); if (! term) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such terminal"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such input terminal"); - grub_term_set_current (term); + grub_term_set_current_input (term); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_terminal_output (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_term_output_t term = 0; + + auto int print_terminal (grub_term_output_t); + auto int find_terminal (grub_term_output_t); + + int print_terminal (grub_term_output_t t) + { + grub_printf (" %s", t->name); + return 0; + } + + int find_terminal (grub_term_output_t t) + { + if (grub_strcmp (t->name, args[0]) == 0) + { + term = t; + return 1; + } + + return 0; + } + + if (argc == 0) + { + grub_printf ("Available output terminal(s):"); + grub_term_iterate_output (print_terminal); + grub_putchar ('\n'); + + grub_printf ("Current output terminal: %s\n", grub_term_get_current_output ()->name); + } + else + { + grub_term_iterate_output (find_terminal); + if (! term) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such output terminal"); + + grub_term_set_current_output (term); } return GRUB_ERR_NONE; @@ -73,8 +119,10 @@ grub_cmd_terminal (struct grub_arg_list *state __attribute__ ((unused)), GRUB_MOD_INIT(terminal) { (void)mod; /* To stop warning. */ - grub_register_command ("terminal", grub_cmd_terminal, GRUB_COMMAND_FLAG_BOTH, - "terminal [TERM...]", "Select a terminal.", 0); + grub_register_command ("terminal_input", grub_cmd_terminal_input, GRUB_COMMAND_FLAG_BOTH, + "terminal_input [TERM...]", "Select an input terminal.", 0); + grub_register_command ("terminal_output", grub_cmd_terminal_output, GRUB_COMMAND_FLAG_BOTH, + "terminal_output [TERM...]", "Select an output terminal.", 0); } GRUB_MOD_FINI(terminal) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 2e27ca1da..bbd856640 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -22,7 +22,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \ kern/time.c \ kern/generic/millisleep.c \ kern/ieee1275/ieee1275.c \ - term/ieee1275/ofconsole.c term/i386/pc/at_keyboard.c \ + term/ieee1275/ofconsole.c \ disk/ieee1275/ofdisk.c \ symlist.c kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \ diff --git a/conf/i386.rmk b/conf/i386.rmk index 458415b08..577d58f66 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -1,8 +1,11 @@ # -*- makefile -*- pkglib_MODULES += cpuid.mod - -# For cpuid.mod. cpuid_mod_SOURCES = commands/i386/cpuid.c cpuid_mod_CFLAGS = $(COMMON_CFLAGS) cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += at_keyboard.mod +at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c +at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h new file mode 100644 index 000000000..305a46d8e --- /dev/null +++ b/include/grub/i386/coreboot/console.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/ieee1275/console.h b/include/grub/i386/ieee1275/console.h index ba1a9d295..854724ac1 100644 --- a/include/grub/i386/ieee1275/console.h +++ b/include/grub/i386/ieee1275/console.h @@ -21,10 +21,6 @@ #include -void EXPORT_FUNC(grub_keyboard_controller_init) (void); -int EXPORT_FUNC(grub_console_checkkey) (void); -int EXPORT_FUNC(grub_console_getkey) (void); - /* Initialize the console system. */ void grub_console_init (void); diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 03ad42ba9..2b37db515 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -40,8 +40,8 @@ /* These are global to share code between C and asm. */ extern grub_uint8_t grub_console_cur_color; void grub_console_real_putchar (int c); -int EXPORT_FUNC(grub_console_checkkey) (void); -int EXPORT_FUNC(grub_console_getkey) (void); +int grub_console_checkkey (void); +int grub_console_getkey (void); grub_uint16_t grub_console_getxy (void); void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y); void grub_console_cls (void); diff --git a/include/grub/term.h b/include/grub/term.h index 3ffee425b..13835bbbb 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -137,7 +137,29 @@ grub_term_color_state; - 1) -struct grub_term +struct grub_term_input +{ + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (void); + + /* Clean up the terminal. */ + grub_err_t (*fini) (void); + + /* Check if any input character is available. */ + int (*checkkey) (void); + + /* Get a character. */ + int (*getkey) (void); + + /* The next terminal. */ + struct grub_term_input *next; +}; +typedef struct grub_term_input *grub_term_input_t; + +struct grub_term_output { /* The terminal name. */ const char *name; @@ -155,12 +177,6 @@ struct grub_term encoded in Unicode. */ grub_ssize_t (*getcharwidth) (grub_uint32_t c); - /* Check if any input character is available. */ - int (*checkkey) (void); - - /* Get a character. */ - int (*getkey) (void); - /* Get the screen size. The return value is ((Width << 8) | Height). */ grub_uint16_t (*getwh) (void); @@ -194,16 +210,21 @@ struct grub_term grub_uint32_t flags; /* The next terminal. */ - struct grub_term *next; + struct grub_term_output *next; }; -typedef struct grub_term *grub_term_t; +typedef struct grub_term_output *grub_term_output_t; -void EXPORT_FUNC(grub_term_register) (grub_term_t term); -void EXPORT_FUNC(grub_term_unregister) (grub_term_t term); -void EXPORT_FUNC(grub_term_iterate) (int (*hook) (grub_term_t term)); +void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term); +void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term); +void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term); +void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term); +void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term)); +void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term)); -grub_err_t EXPORT_FUNC(grub_term_set_current) (grub_term_t term); -grub_term_t EXPORT_FUNC(grub_term_get_current) (void); +grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term); +grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term); +grub_term_input_t EXPORT_FUNC(grub_term_get_current_input) (void); +grub_term_output_t EXPORT_FUNC(grub_term_get_current_output) (void); void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code); diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 6890e9053..051154765 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -138,6 +138,7 @@ grub_machine_init (void) grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START; grub_tsc_init (); + grub_at_keyboard_init (); } void diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index b07fe67f9..71b7ba9c6 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -217,7 +217,6 @@ grub_machine_init (void) grub_console_init (); #ifdef __i386__ grub_get_extended_memory (); - grub_keyboard_controller_init (); #endif grub_claim_heap (); grub_ofdisk_init (); diff --git a/kern/misc.c b/kern/misc.c index 635eb7227..5b1e65e4a 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1026,10 +1026,15 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, const grub_uint8_t *src, void grub_abort (void) { - if (grub_term_get_current ()) + if (grub_term_get_current_output ()) { - grub_printf ("\nAborted. Press any key to exit."); - grub_getkey (); + grub_printf ("\nAborted."); + + if (grub_term_get_current_input ()) + { + grub_printf (" Press any key to exit."); + grub_getkey (); + } } grub_exit (); diff --git a/kern/term.c b/kern/term.c index 4c45d713d..24324c203 100644 --- a/kern/term.c +++ b/kern/term.c @@ -23,10 +23,12 @@ #include /* The list of terminals. */ -static grub_term_t grub_term_list; +static grub_term_input_t grub_term_list_input; +static grub_term_output_t grub_term_list_output; /* The current terminal. */ -static grub_term_t grub_cur_term; +static grub_term_input_t grub_cur_term_input; +static grub_term_output_t grub_cur_term_output; /* The amount of lines counted by the pager. */ static int grub_more_lines; @@ -38,18 +40,25 @@ static int grub_more; static int cursor_state = 1; void -grub_term_register (grub_term_t term) +grub_term_register_input (grub_term_input_t term) { - term->next = grub_term_list; - grub_term_list = term; + term->next = grub_term_list_input; + grub_term_list_input = term; } void -grub_term_unregister (grub_term_t term) +grub_term_register_output (grub_term_output_t term) { - grub_term_t *p, q; + term->next = grub_term_list_output; + grub_term_list_output = term; +} + +void +grub_term_unregister_input (grub_term_input_t term) +{ + grub_term_input_t *p, q; - for (p = &grub_term_list, q = *p; q; p = &(q->next), q = q->next) + for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next) if (q == term) { *p = q->next; @@ -58,36 +67,78 @@ grub_term_unregister (grub_term_t term) } void -grub_term_iterate (int (*hook) (grub_term_t term)) +grub_term_unregister_output (grub_term_output_t term) { - grub_term_t p; + grub_term_output_t *p, q; - for (p = grub_term_list; p; p = p->next) + for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next) + if (q == term) + { + *p = q->next; + break; + } +} + +void +grub_term_iterate_input (int (*hook) (grub_term_input_t term)) +{ + grub_term_input_t p; + + for (p = grub_term_list_input; p; p = p->next) + if (hook (p)) + break; +} + +void +grub_term_iterate_output (int (*hook) (grub_term_output_t term)) +{ + grub_term_output_t p; + + for (p = grub_term_list_output; p; p = p->next) if (hook (p)) break; } grub_err_t -grub_term_set_current (grub_term_t term) +grub_term_set_current_input (grub_term_input_t term) { - if (grub_cur_term && grub_cur_term->fini) - if ((grub_cur_term->fini) () != GRUB_ERR_NONE) + if (grub_cur_term_input && grub_cur_term_input->fini) + if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE) return grub_errno; if (term->init) if ((term->init) () != GRUB_ERR_NONE) return grub_errno; - grub_cur_term = term; - grub_cls (); - grub_setcursor (grub_getcursor ()); + grub_cur_term_input = term; return GRUB_ERR_NONE; } -grub_term_t -grub_term_get_current (void) +grub_err_t +grub_term_set_current_output (grub_term_output_t term) { - return grub_cur_term; + if (grub_cur_term_output && grub_cur_term_output->fini) + if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE) + return grub_errno; + + if (term->init) + if ((term->init) () != GRUB_ERR_NONE) + return grub_errno; + + grub_cur_term_output = term; + return GRUB_ERR_NONE; +} + +grub_term_input_t +grub_term_get_current_input (void) +{ + return grub_cur_term_input; +} + +grub_term_output_t +grub_term_get_current_output (void) +{ + return grub_cur_term_output; } /* Put a Unicode character. */ @@ -96,7 +147,7 @@ grub_putcode (grub_uint32_t code) { int height = grub_getwh () & 255; - if (code == '\t' && grub_cur_term->getxy) + if (code == '\t' && grub_cur_term_output->getxy) { int n; @@ -107,7 +158,7 @@ grub_putcode (grub_uint32_t code) return; } - (grub_cur_term->putchar) (code); + (grub_cur_term_output->putchar) (code); if (code == '\n') { @@ -171,70 +222,70 @@ grub_putchar (int c) grub_ssize_t grub_getcharwidth (grub_uint32_t code) { - return (grub_cur_term->getcharwidth) (code); + return (grub_cur_term_output->getcharwidth) (code); } int grub_getkey (void) { - return (grub_cur_term->getkey) (); + return (grub_cur_term_input->getkey) (); } int grub_checkkey (void) { - return (grub_cur_term->checkkey) (); + return (grub_cur_term_input->checkkey) (); } grub_uint16_t grub_getxy (void) { - return (grub_cur_term->getxy) (); + return (grub_cur_term_output->getxy) (); } grub_uint16_t grub_getwh (void) { - return (grub_cur_term->getwh) (); + return (grub_cur_term_output->getwh) (); } void grub_gotoxy (grub_uint8_t x, grub_uint8_t y) { - (grub_cur_term->gotoxy) (x, y); + (grub_cur_term_output->gotoxy) (x, y); } void grub_cls (void) { - if ((grub_cur_term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) + if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) { grub_putchar ('\n'); grub_refresh (); } else - (grub_cur_term->cls) (); + (grub_cur_term_output->cls) (); } void grub_setcolorstate (grub_term_color_state state) { - if (grub_cur_term->setcolorstate) - (grub_cur_term->setcolorstate) (state); + if (grub_cur_term_output->setcolorstate) + (grub_cur_term_output->setcolorstate) (state); } void grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) { - if (grub_cur_term->setcolor) - (grub_cur_term->setcolor) (normal_color, highlight_color); + if (grub_cur_term_output->setcolor) + (grub_cur_term_output->setcolor) (normal_color, highlight_color); } void grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { - if (grub_cur_term->getcolor) - (grub_cur_term->getcolor) (normal_color, highlight_color); + if (grub_cur_term_output->getcolor) + (grub_cur_term_output->getcolor) (normal_color, highlight_color); } int @@ -242,9 +293,9 @@ grub_setcursor (int on) { int ret = cursor_state; - if (grub_cur_term->setcursor) + if (grub_cur_term_output->setcursor) { - (grub_cur_term->setcursor) (on); + (grub_cur_term_output->setcursor) (on); cursor_state = on; } @@ -260,8 +311,8 @@ grub_getcursor (void) void grub_refresh (void) { - if (grub_cur_term->refresh) - (grub_cur_term->refresh) (); + if (grub_cur_term_output->refresh) + (grub_cur_term_output->refresh) (); } void diff --git a/term/efi/console.c b/term/efi/console.c index f3b62a58b..33d404f26 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -332,15 +332,18 @@ grub_console_setcursor (int on) efi_call_2 (o->enable_cursor, o, on); } -static struct grub_term grub_console_term = +static struct grub_term_input grub_console_term_input = { .name = "console", - .init = 0, - .fini = 0, - .putchar = grub_console_putchar, - .getcharwidth = grub_console_getcharwidth, .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, + }; + +static struct grub_term_output grub_console_term_output = + { + .name = "console", + .putchar = grub_console_putchar, + .getcharwidth = grub_console_getcharwidth, .getwh = grub_console_getwh, .getxy = grub_console_getxy, .gotoxy = grub_console_gotoxy, @@ -350,7 +353,6 @@ static struct grub_term grub_console_term = .getcolor = grub_console_getcolor, .setcursor = grub_console_setcursor, .flags = 0, - .next = 0 }; void @@ -364,12 +366,15 @@ grub_console_init (void) return; } - grub_term_register (&grub_console_term); - grub_term_set_current (&grub_console_term); + grub_term_register_input (&grub_console_term_input); + grub_term_register_output (&grub_console_term_output); + grub_term_set_current_output (&grub_console_term_output); + grub_term_set_current_input (&grub_console_term_input); } void grub_console_fini (void) { - grub_term_unregister (&grub_console_term); + grub_term_unregister_input (&grub_console_term_input); + grub_term_unregister_output (&grub_console_term_output); } diff --git a/term/gfxterm.c b/term/gfxterm.c index 8efcd91a2..c4377929c 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -1056,15 +1056,13 @@ grub_gfxterm_background_image_cmd (struct grub_arg_list *state __attribute__ ((u return grub_errno; } -static struct grub_term grub_video_term = +static struct grub_term_output grub_video_term = { .name = "gfxterm", .init = grub_gfxterm_init, .fini = grub_gfxterm_fini, .putchar = grub_gfxterm_putchar, .getcharwidth = grub_gfxterm_getcharwidth, - .checkkey = grub_console_checkkey, - .getkey = grub_console_getkey, .getwh = grub_virtual_screen_getwh, .getxy = grub_virtual_screen_getxy, .gotoxy = grub_gfxterm_gotoxy, @@ -1081,7 +1079,7 @@ static struct grub_term grub_video_term = GRUB_MOD_INIT(term_gfxterm) { my_mod = mod; - grub_term_register (&grub_video_term); + grub_term_register_output (&grub_video_term); grub_register_command ("background_image", grub_gfxterm_background_image_cmd, @@ -1094,5 +1092,5 @@ GRUB_MOD_INIT(term_gfxterm) GRUB_MOD_FINI(term_gfxterm) { grub_unregister_command ("bgimage"); - grub_term_unregister (&grub_video_term); + grub_term_unregister_output (&grub_video_term); } diff --git a/term/i386/pc/at_keyboard.c b/term/i386/pc/at_keyboard.c index c9bbd836c..c674ef312 100644 --- a/term/i386/pc/at_keyboard.c +++ b/term/i386/pc/at_keyboard.c @@ -16,9 +16,10 @@ * along with GRUB. If not, see . */ -#include -#include -#include +#include +#include +#include +#include #include #include @@ -61,6 +62,8 @@ static char keyboard_map_shift[128] = 'B', 'N', 'M', '<', '>', '?' }; +static grub_uint8_t grub_keyboard_controller_orig; + static void grub_keyboard_controller_write (grub_uint8_t c) { @@ -77,12 +80,6 @@ grub_keyboard_controller_read (void) return grub_inb (KEYBOARD_REG_DATA); } -void -grub_keyboard_controller_init (void) -{ - grub_keyboard_controller_write (grub_keyboard_controller_read () | KEYBOARD_SCANCODE_SET1); -} - /* FIXME: This should become an interrupt service routine. For now it's just used to catch events from control keys. */ static void @@ -148,8 +145,8 @@ grub_keyboard_getkey (void) } /* If there is a character pending, return it; otherwise return -1. */ -int -grub_console_checkkey (void) +static int +grub_at_keyboard_checkkey (void) { int code, key; code = grub_keyboard_getkey (); @@ -192,13 +189,47 @@ grub_console_checkkey (void) return (int) key; } -int -grub_console_getkey (void) +static int +grub_at_keyboard_getkey (void) { int key; do { - key = grub_console_checkkey (); + key = grub_at_keyboard_checkkey (); } while (key == -1); return key; } + +static grub_err_t +grub_keyboard_controller_init (void) +{ + grub_keyboard_controller_orig = grub_keyboard_controller_read (); + grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_keyboard_controller_fini (void) +{ + grub_keyboard_controller_write (grub_keyboard_controller_orig); + return GRUB_ERR_NONE; +} + +static struct grub_term_input grub_at_keyboard_term = + { + .name = "at_keyboard", + .init = grub_keyboard_controller_init, + .fini = grub_keyboard_controller_fini, + .checkkey = grub_at_keyboard_checkkey, + .getkey = grub_at_keyboard_getkey, + }; + +GRUB_MOD_INIT(at_keyboard) +{ + grub_term_register_input (&grub_at_keyboard_term); +} + +GRUB_MOD_FINI(at_keyboard) +{ + grub_term_unregister_output (&grub_at_keyboard_term); +} diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 1d199e927..6105ac7d8 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -125,15 +125,22 @@ grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color *highlight_color = grub_console_highlight_color; } -static struct grub_term grub_console_term = +/* On non-BIOS platforms, console.c is used in combination with vga_text.c + (only to handle output). */ +#ifdef GRUB_MACHINE_PCBIOS +static struct grub_term_input grub_console_term_input = { .name = "console", - .init = 0, - .fini = 0, - .putchar = grub_console_putchar, - .getcharwidth = grub_console_getcharwidth, .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, + }; +#endif + +static struct grub_term_output grub_console_term_output = + { + .name = "console", + .putchar = grub_console_putchar, + .getcharwidth = grub_console_getcharwidth, .getwh = grub_console_getwh, .getxy = grub_console_getxy, .gotoxy = grub_console_gotoxy, @@ -143,23 +150,26 @@ static struct grub_term grub_console_term = .getcolor = grub_console_getcolor, .setcursor = grub_console_setcursor, .flags = 0, - .next = 0 }; void grub_console_init (void) { - grub_term_register (&grub_console_term); - grub_term_set_current (&grub_console_term); - -#ifdef GRUB_MACHINE_LINUXBIOS - grub_keyboard_controller_init (); + grub_term_register_output (&grub_console_term_output); + grub_term_set_current_output (&grub_console_term_output); +#ifdef GRUB_MACHINE_PCBIOS + grub_term_register_input (&grub_console_term_input); + grub_term_set_current_input (&grub_console_term_input); #endif } void grub_console_fini (void) { - grub_term_set_current (&grub_console_term); - grub_term_unregister (&grub_console_term); + grub_term_set_current_output (&grub_console_term_output); +#ifdef GRUB_MACHINE_PCBIOS + grub_term_set_current_input (&grub_console_term_input); + grub_term_unregister_input (&grub_console_term_input); +#endif + grub_term_unregister_output (&grub_console_term_output); } diff --git a/term/i386/pc/serial.c b/term/i386/pc/serial.c index 2d76ec1f8..612492206 100644 --- a/term/i386/pc/serial.c +++ b/term/i386/pc/serial.c @@ -467,15 +467,18 @@ grub_serial_setcursor (const int on) grub_terminfo_cursor_off (); } -static struct grub_term grub_serial_term = +static struct grub_term_input grub_serial_term_input = { .name = "serial", - .init = 0, - .fini = 0, - .putchar = grub_serial_putchar, - .getcharwidth = grub_serial_getcharwidth, .checkkey = grub_serial_checkkey, .getkey = grub_serial_getkey, +}; + +static struct grub_term_output grub_serial_term_output = +{ + .name = "serial", + .putchar = grub_serial_putchar, + .getcharwidth = grub_serial_getcharwidth, .getwh = grub_serial_getwh, .getxy = grub_serial_getxy, .gotoxy = grub_serial_gotoxy, @@ -483,7 +486,6 @@ static struct grub_term grub_serial_term = .setcolorstate = grub_serial_setcolorstate, .setcursor = grub_serial_setcursor, .flags = 0, - .next = 0 }; @@ -575,7 +577,8 @@ grub_cmd_serial (struct grub_arg_list *state, /* Register terminal if not yet registered. */ if (registered == 0) { - grub_term_register (&grub_serial_term); + grub_term_register_input (&grub_serial_term_input); + grub_term_register_output (&grub_serial_term_output); registered = 1; } } @@ -590,7 +593,8 @@ grub_cmd_serial (struct grub_arg_list *state, if (serial_hw_init () != GRUB_ERR_NONE) { /* If unable to restore settings, unregister terminal. */ - grub_term_unregister (&grub_serial_term); + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); registered = 0; } } @@ -616,5 +620,8 @@ GRUB_MOD_FINI(serial) { grub_unregister_command ("serial"); if (registered == 1) /* Unregister terminal only if registered. */ - grub_term_unregister (&grub_serial_term); + { + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); + } } diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index ebcc54d1d..7143745cc 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -473,15 +473,13 @@ grub_vga_setcursor (int on) } } -static struct grub_term grub_vga_term = +static struct grub_term_output grub_vga_term = { .name = "vga", .init = grub_vga_mod_init, .fini = grub_vga_mod_fini, .putchar = grub_vga_putchar, .getcharwidth = grub_vga_getcharwidth, - .checkkey = grub_console_checkkey, - .getkey = grub_console_getkey, .getwh = grub_vga_getwh, .getxy = grub_vga_getxy, .gotoxy = grub_vga_gotoxy, @@ -489,7 +487,6 @@ static struct grub_term grub_vga_term = .setcolorstate = grub_vga_setcolorstate, .setcursor = grub_vga_setcursor, .flags = 0, - .next = 0 }; GRUB_MOD_INIT(vga) @@ -497,10 +494,10 @@ GRUB_MOD_INIT(vga) #ifndef GRUB_UTIL my_mod = mod; #endif - grub_term_register (&grub_vga_term); + grub_term_register_output (&grub_vga_term); } GRUB_MOD_FINI(vga) { - grub_term_unregister (&grub_vga_term); + grub_term_unregister_output (&grub_vga_term); } diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index faa104926..ec35a13ea 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -33,10 +33,8 @@ static grub_uint8_t grub_ofconsole_height; static int grub_curr_x; static int grub_curr_y; -#ifndef __i386__ static int grub_keybuf; static int grub_buflen; -#endif struct color { @@ -144,7 +142,6 @@ grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_col *highlight_color = grub_ofconsole_highlight_color; } -#ifndef __i386__ static int grub_ofconsole_readkey (int *key) { @@ -342,7 +339,20 @@ grub_ofconsole_refresh (void) } static grub_err_t -grub_ofconsole_init (void) +grub_ofconsole_init_input (void) +{ + grub_ssize_t actual; + + if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle, + sizeof stdin_ihandle, &actual) + || actual != sizeof stdin_ihandle) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin"); + + return 0; +} + +static grub_err_t +grub_ofconsole_init_output (void) { grub_ssize_t actual; int col; @@ -358,11 +368,6 @@ grub_ofconsole_init (void) || actual != sizeof stdout_ihandle) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout"); - if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle, - sizeof stdin_ihandle, &actual) - || actual != sizeof stdin_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin"); - /* Initialize colors. */ if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)) { @@ -385,20 +390,22 @@ grub_ofconsole_fini (void) -static struct grub_term grub_ofconsole_term = +static struct grub_term_input grub_ofconsole_term_input = { .name = "ofconsole", - .init = grub_ofconsole_init, + .init = grub_ofconsole_init_input, + .fini = grub_ofconsole_fini, + .checkkey = grub_ofconsole_checkkey, + .getkey = grub_ofconsole_getkey, + }; + +static struct grub_term_output grub_ofconsole_term_output = + { + .name = "ofconsole", + .init = grub_ofconsole_init_output, .fini = grub_ofconsole_fini, .putchar = grub_ofconsole_putchar, .getcharwidth = grub_ofconsole_getcharwidth, -#ifdef __i386__ - .checkkey = grub_console_checkkey, - .getkey = grub_console_getkey, -#else - .checkkey = grub_ofconsole_checkkey, - .getkey = grub_ofconsole_getkey, -#endif .getxy = grub_ofconsole_getxy, .getwh = grub_ofconsole_getwh, .gotoxy = grub_ofconsole_gotoxy, @@ -409,18 +416,20 @@ static struct grub_term grub_ofconsole_term = .setcursor = grub_ofconsole_setcursor, .refresh = grub_ofconsole_refresh, .flags = 0, - .next = 0 }; void grub_console_init (void) { - grub_term_register (&grub_ofconsole_term); - grub_term_set_current (&grub_ofconsole_term); + grub_term_register_input (&grub_ofconsole_term_input); + grub_term_register_output (&grub_ofconsole_term_output); + grub_term_set_current_output (&grub_ofconsole_term_output); + grub_term_set_current_input (&grub_ofconsole_term_input); } void grub_console_fini (void) { - grub_term_unregister (&grub_ofconsole_term); + grub_term_unregister_input (&grub_ofconsole_term_input); + grub_term_unregister_output (&grub_ofconsole_term_output); } diff --git a/util/console.c b/util/console.c index 01eb55758..30f184e91 100644 --- a/util/console.c +++ b/util/console.c @@ -371,7 +371,8 @@ void grub_console_init (void) { grub_term_register (&grub_ncurses_term); - grub_term_set_current (&grub_ncurses_term); + grub_term_set_current_input (&grub_ncurses_term); + grub_term_set_current_output (&grub_ncurses_term); } void diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f53a9bb7b..68caf4263 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -41,7 +41,13 @@ grub_refresh (void) } void * -grub_term_get_current (void) +grub_term_get_current_input (void) +{ + return 0; +} + +void * +grub_term_get_current_output (void) { return 0; } diff --git a/util/grub-fstest.c b/util/grub-fstest.c index fc259f2ee..b622f8491 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -54,7 +54,13 @@ grub_getkey (void) } grub_term_t -grub_term_get_current (void) +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_t +grub_term_get_current_output (void) { return 0; } diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index f7cf0d1f0..2d7510f83 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -130,31 +130,37 @@ if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub fi -case x${GRUB_TERMINAL} in +# XXX: should this be deprecated at some point? +if [ "x${GRUB_TERMINAL}" != "x" ] ; then + GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}" + GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}" +fi + +case x${GRUB_TERMINAL_OUTPUT} in x) # If this platform supports gfxterm, try to use it. if test -e ${grub_prefix}/gfxterm.mod ; then - GRUB_TERMINAL=gfxterm + GRUB_TERMINAL_OUTPUT=gfxterm fi ;; xconsole | xserial | xofconsole | xgfxterm) ;; - *) echo "Invalid terminal \"${GRUB_TERMINAL}\"" >&2 ; exit 1 ;; + *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;; esac # check for terminals that require fonts -case ${GRUB_TERMINAL} in +case ${GRUB_TERMINAL_OUTPUT} in gfxterm) if path=`font_path` ; then GRUB_FONT_PATH="${path}" else # fallback to the native terminal for this platform - unset GRUB_TERMINAL + unset GRUB_TERMINAL_OUTPUT fi ;; esac # does our terminal support utf-8 ? -case ${GRUB_TERMINAL} in +case ${GRUB_TERMINAL_OUTPUT} in gfxterm) ;; *) # make sure all our children behave in conformance with ascii.. @@ -167,7 +173,7 @@ esac export GRUB_DEVICE GRUB_DEVICE_UUID GRUB_DEVICE_BOOT GRUB_DEVICE_BOOT_UUID GRUB_FS GRUB_FONT_PATH GRUB_PRELOAD_MODULES # These are optional, user-defined variables. -export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE +export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL_OUTPUT GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE if test "x${grub_cfg}" != "x"; then rm -f ${grub_cfg}.new diff --git a/util/grub-probe.c b/util/grub-probe.c index 4681cf72d..402b75839 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -66,8 +66,14 @@ grub_getkey (void) return -1; } -grub_term_t -grub_term_get_current (void) +grub_term_input_t +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_output_t +grub_term_get_current_output (void) { return 0; } diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index a8e2902b1..a0b314b32 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -40,8 +40,31 @@ set default=${GRUB_DEFAULT} set timeout=${GRUB_TIMEOUT} EOF -case x${GRUB_TERMINAL} in - xgfxterm) +case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in + serial:* | *: serial) + if ! test -e ${grub_prefix}/serial.mod ; then + echo "Serial terminal not available on this platform." >&2 ; exit 1 + fi + + if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then + echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2 + GRUB_SERIAL_COMMAND=serial + fi + echo "${GRUB_SERIAL_COMMAND}" + ;; +esac + +case x${GRUB_TERMINAL_INPUT} in + x) + # Just use the native terminal + ;; + x*) + echo "terminal_input ${GRUB_TERMINAL_INPUT}" + ;; +esac + +case x${GRUB_TERMINAL_OUTPUT} in + xgfxterm) # Make the font accessible prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}` @@ -62,26 +85,14 @@ if font `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then set gfxmode=${GRUB_GFXMODE} insmod gfxterm insmod ${video_backend} - terminal gfxterm + terminal_output gfxterm fi EOF ;; - xserial) - if ! test -e ${grub_prefix}/serial.mod ; then - echo "Serial terminal not available on this platform." >&2 ; exit 1 - fi - - if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then - echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2 - GRUB_SERIAL_COMMAND=serial - fi - echo "${GRUB_SERIAL_COMMAND}" - echo "terminal serial" - ;; x) # Just use the native terminal ;; x*) - echo "terminal ${GRUB_TERMINAL}" + echo "terminal_output ${GRUB_TERMINAL_OUTPUT}" ;; esac diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 39fd825f5..ccbb46536 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -74,8 +74,14 @@ grub_getkey (void) return -1; } -grub_term_t -grub_term_get_current (void) +grub_term_input_t +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_output_t +grub_term_get_current_output (void) { return 0; }