diff options
-rw-r--r-- | README.menu | 81 | ||||
-rw-r--r-- | com32/modules/menu.c | 18 | ||||
-rw-r--r-- | com32/modules/menu.h | 4 | ||||
-rw-r--r-- | com32/modules/readconfig.c | 38 | ||||
-rw-r--r-- | parsecmd.inc | 5 | ||||
-rw-r--r-- | parseconfig.inc | 2 |
6 files changed, 125 insertions, 23 deletions
diff --git a/README.menu b/README.menu new file mode 100644 index 00000000..8c358a64 --- /dev/null +++ b/README.menu @@ -0,0 +1,81 @@ +$Id$ + +There are two menu systems included with SYSLINUX, the advanced menu +system, and the simple menu system. + + ++++ THE ADVANCED MENU SYSTEM +++ + +The advanced menu system, written by Murali Krishnan Ganapathy, is +located in the menu/ subdirectly. It allows the user to create +hierarchial submenus, dynamic options, checkboxes, and just about +anything you want. It requires that the menu is compiled from a +simple C file, see menu/simple.c and menu/complex.c for examples. + +The advanced menu system doesn't support serial console at this time. + +See menu/README for more information. + + ++++ THE SIMPLE MENU SYSTEM +++ + +The simple menu system is a single module located at +com32/modules/menu.c32. It uses the same configuration file as the +regular SYSLINUX command line, and displays all the LABEL statements. + +To use the menu system, simply make sure menu.c32 is in the +appropriate location for your boot medium, and put the following +options in your configuration file: + +DEFAULT menu.c32 +PROMPT 0 + + +There are a few menu additions to the command line, all starting with +the keyword MENU; 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 LABEL label + + (Only valid after a LABEL statement.) + Changes the label displayed for a specific entry. This allows + you to have a label that isn't suitable for the command line, + for example: + + LABEL softcap + MENU LABEL Soft Cap Linux 9.6.36 + KERNEL softcap-9.6.36.bzi + APPEND whatever + +MENU HIDE + + (Only valid after a LABEL statement.) + Suppresses a particular LABEL entry from the menu. + + +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. + + +The menu system honours the TIMEOUT command; if TIMEOUT is specified +it will execute the ONTIMEOUT command if one exists, otherwise it will +pick the default menu option. + +Normally, the user can press [Tab] to edit the menu entry, and [Esc] +to return to the SYSLINUX command line. However, if the configuration +file specifies ALLOWOPTIONS 0, these keys will be disabled. + +The simple menu system supports serial console, using the normal +SERIAL directive. However, it can be quite slow over a slow serial +link; you probably want to set your baudrate to 38400 or higher if +possible. It requires a Linux/VT220/ANSI-compatible terminal on the +other end. + diff --git a/com32/modules/menu.c b/com32/modules/menu.c index e3dace2f..c9794c24 100644 --- a/com32/modules/menu.c +++ b/com32/modules/menu.c @@ -131,6 +131,8 @@ void draw_menu(int sel, int top) if ( allowedit ) printf("%s\033[%d;1H%s", menu_attrib->tabmsg, TABMSG_ROW, pad_line("Press [Tab] to edit options", 1, WIDTH)); + + printf("%s\033[%d;1H", menu_attrib->screen, END_ROW); } char *edit_cmdline(char *input) @@ -176,7 +178,7 @@ char *edit_cmdline(char *input) case KEY_CTRL('U'): if ( len ) { len = 0; - cmdline[len] = 0; + cmdline[len] = '\0'; redraw = 1; } break; @@ -187,6 +189,7 @@ char *edit_cmdline(char *input) len--; wasbs = wasbs || (cmdline[len-1] <= ' '); } + cmdline[len] = '\0'; redraw = 1; } break; @@ -207,11 +210,9 @@ const char *run_menu(void) int done = 0; int entry = defentry; int top = 0; + int clear = 1; char *cmdline; - /* Start with a clear screen */ - printf("%s\033[2J", menu_attrib->screen); - while ( !done ) { if ( entry < 0 ) entry = 0; @@ -223,6 +224,11 @@ const char *run_menu(void) else if ( top > entry ) top = entry; + /* Start with a clear screen */ + if ( clear ) + printf("%s\033[2J", menu_attrib->screen); + clear = 0; + draw_menu(entry, top); key = get_key(stdin); @@ -266,6 +272,8 @@ const char *run_menu(void) cmdline = edit_cmdline(menu_entries[entry].cmdline); if ( cmdline ) return cmdline; + else + clear = 1; } break; case KEY_CTRL('C'): /* Ctrl-C */ @@ -278,7 +286,7 @@ const char *run_menu(void) } /* Return the label name so localboot and ipappend work */ - return menu_entries[entry].displayname; + return menu_entries[entry].label; } diff --git a/com32/modules/menu.h b/com32/modules/menu.h index e892a124..4766a395 100644 --- a/com32/modules/menu.h +++ b/com32/modules/menu.h @@ -14,7 +14,7 @@ /* * menu.h * - * Header file for the menu project + * Header file for the simple menu system */ #ifndef MENU_H @@ -22,7 +22,9 @@ struct menu_entry { char *displayname; + char *label; char *cmdline; + int flags; }; #define MAX_CMDLINE_LEN 256 diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c index 39d3635d..eb64d6ae 100644 --- a/com32/modules/readconfig.c +++ b/com32/modules/readconfig.c @@ -111,7 +111,10 @@ struct labeldata { char *label; char *kernel; char *append; + char *menulabel; unsigned int ipappend; + unsigned int menuhide; + unsigned int menudefault; }; static void record(struct labeldata *ld, char *append) @@ -121,7 +124,9 @@ static void record(struct labeldata *ld, char *append) if ( ld->label ) { char *a, *s; - menu_entries[nentries].displayname = ld->label; + menu_entries[nentries].displayname = + ld->menulabel ? ld->menulabel : ld->label; + menu_entries[nentries].label = ld->label; ipp = ipoptions; *ipp = '\0'; @@ -136,14 +141,16 @@ static void record(struct labeldata *ld, char *append) s = a[0] ? " " : ""; asprintf(&menu_entries[nentries].cmdline, "%s%s%s%s", ld->kernel, ipoptions, s, a); - printf("displayname: %s\n", menu_entries[nentries].displayname); - printf("cmdline: %s\n", menu_entries[nentries].cmdline); - ld->label = NULL; free(ld->kernel); if ( ld->append ) free(ld->append); - nentries++; + + if ( !ld->menuhide ) { + if ( ld->menudefault ) + defentry = nentries; + nentries++; + } } } @@ -172,15 +179,19 @@ void parse_config(const char *filename) *p = '\0'; p = skipspace(line); - printf("> %s\n", p); if ( looking_at(p, "menu") ) { - p = skipspace(line+4); - + p = skipspace(p+4); + if ( looking_at(p, "title") ) { menu_title = strdup(skipspace(p+5)); + } else if ( looking_at(p, "label") ) { + if ( ld.label ) + ld.menulabel = strdup(skipspace(p+5)); } else if ( looking_at(p, "default") ) { - defentry = atoi(skipspace(p+7)); + ld.menudefault = 1; + } else if ( looking_at(p, "hide") ) { + ld.menuhide = 1; } else { /* Unknown, ignore for now */ } @@ -193,10 +204,11 @@ void parse_config(const char *filename) } else if ( looking_at(p, "label") ) { p = skipspace(p+5); record(&ld, append); - ld.label = strdup(p); - ld.kernel = strdup(p); - ld.append = NULL; - ld.ipappend = 0; + ld.label = strdup(p); + ld.kernel = strdup(p); + ld.append = NULL; + ld.menulabel = NULL; + ld.ipappend = ld.menudefault = ld.menuhide = 0; } else if ( looking_at(p, "kernel") ) { if ( ld.label ) { free(ld.kernel); diff --git a/parsecmd.inc b/parsecmd.inc index 2aa4144c..8d0de95e 100644 --- a/parsecmd.inc +++ b/parsecmd.inc @@ -35,8 +35,6 @@ getcommand: call skipspace ; Skip leading whitespace jz .eof ; End of file jc .find ; End of line: try again - cmp al,'0' ; Skip comment line - jb .skipline or al,20h ; Convert to lower case movzx ebx,al ; Hash for a one-char keyword @@ -72,9 +70,10 @@ getcommand: ; No parameter .noparm: mov si,err_noparm + mov al,10 ; Already at EOL .error: call cwritestr - jmp short .find + jmp short .skipline .found_keywd: lodsw ; Load argument into ax call [si] diff --git a/parseconfig.inc b/parseconfig.inc index 064dc7f4..6d7c93e9 100644 --- a/parseconfig.inc +++ b/parseconfig.inc @@ -272,7 +272,7 @@ pc_say: call pc_getline ; "say" command ; ; Comment line ; -pc_comment equ pc_getline ; Get a line and discard +pc_comment: ; Fall into pc_getline ; ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf |