From e21e66137b454fb3afd50a113de68599dd28de09 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 11 Dec 2008 14:59:36 -0800 Subject: [PATCH] Add new "UI" directive instead of abusing the DEFAULT directive Add a new "UI" directive to specify a user interface module, instead of abusing the DEFAULT directive. This allows the DEFAULT directive to be used for setting the default, even when the menu system is enabled. Signed-off-by: H. Peter Anvin --- NEWS | 4 ++++ com32/menu/menu.h | 3 ++- com32/menu/readconfig.c | 42 ++++++++++++++++++++++++++++++++++++++++++ core/keywords | 1 + core/keywords.inc | 3 ++- core/parseconfig.inc | 9 ++++++--- core/ui.inc | 8 +++++--- doc/menu.txt | 37 +++++++++++++++++++++++++++++-------- doc/syslinux.txt | 5 +++++ 9 files changed, 96 insertions(+), 16 deletions(-) diff --git a/NEWS b/NEWS index fbee594..07149d1 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ Changes in 3.73: * mboot.c32: add "-solaris" option to pass DHCP information to the Solaris kernel; required for automatic Solaris boot without using Solaris' pxeboot program. + * New UI directive, which allows a more natural way to specify + a menu system (or not.) With the UI directive specifying + the menu system, the DEFAULT directive can be used to select + the default entry inside the menus. Changes in 3.72: * Include the pxechain.com module from Jeffery Hutzelman at diff --git a/com32/menu/menu.h b/com32/menu/menu.h index 1fa1a24..e2ffc1b 100644 --- a/com32/menu/menu.h +++ b/com32/menu/menu.h @@ -49,7 +49,7 @@ enum menu_action { }; struct menu_entry { - int entry; /* Entry number inside menu */ + struct menu *menu; /* Parent menu */ const char *displayname; const char *label; const char *passwd; @@ -57,6 +57,7 @@ struct menu_entry { const char *cmdline; struct menu *submenu; struct menu_entry *next; /* Linked list of all labels across menus */ + int entry; /* Entry number inside menu */ enum menu_action action; unsigned char hotkey; }; diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c index 0d3093b..01dadff 100644 --- a/com32/menu/readconfig.c +++ b/com32/menu/readconfig.c @@ -33,6 +33,10 @@ int shiftkey = 0; /* Only display menu if shift key pressed */ int hiddenmenu = 0; long long totaltimeout = 0; +/* Keep track of global default */ +static int has_ui = 0; /* DEFAULT only counts if UI is found */ +static const char *globaldefault = NULL; + /* Linked list of all entires, hidden or not; used by unlabel() */ static struct menu_entry *all_entries; static struct menu_entry **all_entries_end = &all_entries; @@ -245,6 +249,7 @@ static struct menu_entry *new_entry(struct menu *m) } me = calloc(1, sizeof(struct menu_entry)); + me->menu = m; me->entry = m->nentries; m->menu_entries[m->nentries++] = me; *all_entries_end = me; @@ -390,6 +395,27 @@ static struct menu *end_submenu(void) return current_menu->parent ? current_menu->parent : current_menu; } +static struct menu_entry *find_label(const char *str) +{ + const char *p; + struct menu_entry *me; + int pos; + + p = str; + while ( *p && !my_isspace(*p) ) + p++; + + /* p now points to the first byte beyond the kernel name */ + pos = p-str; + + for (me = all_entries; me; me = me->next) { + if (!strncmp(str, me->label, pos) && !me->label[pos]) + return me; + } + + return NULL; +} + static const char *unlabel(const char *str) { /* Convert a CLI-style command line to an executable command line */ @@ -912,6 +938,11 @@ static void parse_config_file(FILE *f) ld.ipappend = atoi(skipspace(p+8)); else ipappend = atoi(skipspace(p+8)); + } else if ( looking_at(p, "default") ) { + refstr_put(globaldefault); + globaldefault = refstrdup(skipspace(p+7)); + } else if ( looking_at(p, "ui") ) { + has_ui = 1; } } } @@ -958,6 +989,7 @@ void parse_configs(char **argv) { const char *filename; struct menu *m; + struct menu_entry *me; empty_string = refstrdup(""); @@ -984,6 +1016,16 @@ void parse_configs(char **argv) /* Common postprocessing */ resolve_gotos(); + /* Handle global default */ + if (has_ui && globaldefault) { + me = find_label(globaldefault); + if (me && me->menu != hide_menu) { + me->menu->defentry = me->entry; + start_menu = me->menu; + } + } + + /* Final per-menu initialization, with all labels known */ for (m = menu_list; m; m = m->next) { m->curentry = m->defentry; /* All menus start at their defaults */ diff --git a/core/keywords b/core/keywords index 7cd9ace..aeafb96 100644 --- a/core/keywords +++ b/core/keywords @@ -5,6 +5,7 @@ append initrd config default +ui display font implicit diff --git a/core/keywords.inc b/core/keywords.inc index f563b9d..f2940e8 100644 --- a/core/keywords.inc +++ b/core/keywords.inc @@ -50,7 +50,8 @@ keywd_table: keyword include, pc_opencmd, pc_include keyword append, pc_append keyword initrd, pc_filename, InitRD - keyword default, pc_default + keyword default, pc_default, 1 + keyword ui, pc_default, 2 keyword display, pc_opencmd, get_msg_file keyword font, pc_opencmd, loadfont keyword implicit, pc_setint16, AllowImplicit diff --git a/core/parseconfig.inc b/core/parseconfig.inc index 55d6fbb..2fb26fd 100644 --- a/core/parseconfig.inc +++ b/core/parseconfig.inc @@ -18,12 +18,14 @@ section .text ; -; "default" command +; "default" or "ui" command, with level (1 = default, 2 = ui) ; -pc_default: mov di,default_cmd +pc_default: cmp ax,[DefaultLevel] + jb .skip + mov di,default_cmd call getline mov byte [di-1],0 ; null-terminate - ret +.skip: ret ; ; "ontimeout" command @@ -467,6 +469,7 @@ NoComplete dw 0 ; No label completion on TAB key AllowImplicit dw 1 ; Allow implicit kernels AllowOptions dw 1 ; User-specified options allowed IncludeLevel dw 1 ; Nesting level +DefaultLevel dw 0 ; The current level of default SerialPort dw 0 ; Serial port base (or 0 for no serial port) VKernel db 0 ; Have we seen any "label" statements? diff --git a/core/ui.inc b/core/ui.inc index 4f5b1fd..7f88cda 100644 --- a/core/ui.inc +++ b/core/ui.inc @@ -48,10 +48,12 @@ no_config_file: ; Check whether or not we are supposed to display the boot prompt. ; check_for_key: - cmp word [ForcePrompt],0 ; Force prompt? - jnz enter_command test byte [KbdFlags],5Bh ; Shift Alt Caps Scroll - jz auto_boot ; If neither, default boot + jnz enter_command + cmp word [ForcePrompt],0 ; Force prompt? + jz auto_boot + cmp word [DefaultLevel],1 ; Active UI statement? + ja auto_boot enter_command: cmp word [NoEscape],0 ; If NOESCAPE, no prompt, diff --git a/doc/menu.txt b/doc/menu.txt index a03c72a..fd5a44d 100644 --- a/doc/menu.txt +++ b/doc/menu.txt @@ -28,28 +28,31 @@ configuration file for SYSLINUX, EXTLINUX and ISOLINUX, and the same directory as pxelinux.0 for PXELINUX), and put the following options in your configuration file: -DEFAULT menu.c32 -PROMPT 0 +UI menu.c32 -There are a few menu additions to the command line, all starting with -the keywords MENU or TEXT; like the rest of the Syslinux config file -language, it is case insensitive: +There are a few menu additions to the configuration file, all starting +with the keywords MENU or TEXT; like the rest of the Syslinux config +file language, it is case insensitive: + MENU TITLE title Give the menu a title. The title is presented at the top of the menu. + MENU HIDDEN Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. + MENU SEPARATOR Insert an empty line in the menu. + MENU LABEL label (Only valid after a LABEL statement.) @@ -85,6 +88,7 @@ MENU INDENT count (Only valid after a LABEL statement.) Will add "count" spaces in front of the displayed menu entry. + MENU DISABLE (Only valid after a LABEL statement.) @@ -142,8 +146,9 @@ MENU HIDE MENU DEFAULT (Only valid after a LABEL statement.) - Indicates that this entry should be the default. If no - default is specified, use the first one. + + Indicates that this entry should be the default for this + particular submenu. See also the DEFAULT directive below. TEXT HELP @@ -239,7 +244,23 @@ MENU START (Only valid inside MENU BEGIN ... MENU END) Indicates that the menu system should start at the menu being - defined instead of at the top-level menu. + defined instead of at the top-level menu. See also the + DEFAULT directive below. + + +DEFAULT label + + Set the global default. If "label" points into a submenu, + that menu becomes the start menu; in other words, this + directive has the same effect as both MENU DEFAULT and MENU + START. + + For backwards compatibility with earlier versions of Syslinux, + this directive is ignored unless the configuration file also + contains a UI directive. + + Note: the CLI accepts options after the label, or even a + non-label. The menu system does not support that. INCLUDE filename [tagname] diff --git a/doc/syslinux.txt b/doc/syslinux.txt index 285be8b..2d64e4b 100644 --- a/doc/syslinux.txt +++ b/doc/syslinux.txt @@ -145,6 +145,11 @@ DEFAULT kernel options... true, as it caused problems when using a shell as a substitute for "init." You may want to include this option manually. +UI module options... + Selects a specific user interface module (typically menu.c32 + or vesamenu.c32). The command-line interface treats this as a + directive that overrides the DEFAULT and PROMPT directives. + APPEND options... Add one or more options to the kernel command line. These are added both for automatic and manual boots. The options are -- 2.7.4