summaryrefslogtreecommitdiff
path: root/menu
diff options
context:
space:
mode:
authorMurali Krishnan Ganapathy <gmurali@cs.uchicago.edu>2005-12-16 16:25:49 -0600
committerH. Peter Anvin <hpa@zytor.com>2005-12-16 14:29:04 -0800
commita22c4aff0e5649fa22bbb4b7fda9433d7a8c44de (patch)
tree9f1c365dfc9b7174b31fbc7c769faf9bf8a57d0c /menu
parent1afe52436215236ac88a7c523d779fb2cf4cbd2a (diff)
downloadsyslinux-a22c4aff0e5649fa22bbb4b7fda9433d7a8c44de.tar.gz
advanced menu patch
Python code to generate C code from ini-like file format and changes to libmenu to accomodate a one pass parser. Diff is against 3.20-pre3 - Murali
Diffstat (limited to 'menu')
-rw-r--r--menu/CHANGES8
-rw-r--r--menu/MANUAL41
-rw-r--r--menu/Makefile11
-rw-r--r--menu/README8
-rw-r--r--menu/libmenu/menu.c70
-rw-r--r--menu/libmenu/menu.h28
-rw-r--r--menu/simple.c23
7 files changed, 146 insertions, 43 deletions
diff --git a/menu/CHANGES b/menu/CHANGES
index 3998f1bd..da7fc90f 100644
--- a/menu/CHANGES
+++ b/menu/CHANGES
@@ -1,3 +1,11 @@
+Changes in v1.2
+---------------
+* Allowed menu's to have names. Submenu's can be referred to by names instead
+ of their index in the menu system. This allows user to refer to submenus
+ which are not yet part of the menusystem.
+* menugen.py: Python script for converting menu's specified in a given format
+ to corresponding C source code
+
Changes in v1.1
---------------
* Additional handler type: Keys handler
diff --git a/menu/MANUAL b/menu/MANUAL
index 50652fbb..df8a4db6 100644
--- a/menu/MANUAL
+++ b/menu/MANUAL
@@ -65,13 +65,10 @@ should appear in the menu. An example is given below.
CHECKED = 1;
add_item("option1","Status 1",OPT_RUN,"kernel1 arg1=val1",0);
add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
+ add_item("othermenu","Status 3",OPT_SUBMENU,"menuname",0);
add_sep();
add_item("checkbox,"Checkbox Info",OPT_CHECKBOX,NULL,CHECKED);
add_item("Exit ","Status String",OPT_EXITMENU,NULL,0);
- // "any string" not used by the menu system, useful for storing kernel names
- // NUM = index of submenu if OPT_SUBMENU,
- // 0/1 default checked state if OPT_CHECKBOX
- // unused otherwise.
</code>
The call to add_menu has two arguments, the first being the title of
@@ -79,8 +76,17 @@ the menu and the second an upper bound on the number of items in the menu.
Putting a -1, will use the default (see MENUSIZE in menu.h). If you try
to add more items than specified, the extra items will not appear in
the menu. The accuracy of this number affects the memory required
-to run the system. Currently the code compiles to a .COM file which
-has a 64K limit on memory used.
+to run the system.
+
+If you do not want to keep track of the return values, you can also use
+the following variant of add_menu
+
+<code>
+add_named_menu("main"," Menu Title ",-1)
+</code>
+
+This creates a new menu as before and gives it a name "main". When using named
+menus, you get an alternate way for adding submenu's. See below for details.
The call to add_item has five arguments.
The first argument is the text which appears in the menu itself.
@@ -100,16 +106,28 @@ the following
* OPT_INACTIVE : A disabled item (user cannot select this)
* OPT_INVISIBLE: This item will not be displayed.
-The fourth argument is the value of the data field. This pointer is just
-stored. In case of a radiomenu this points to the menuitem chosen (Dont
-forget to typecase this pointer to (t_menuitem *) when reading this info).
+The fourth argument is the value of the data field always a string.
+Usually this string is just copied and nothing is done with it. Two
+cases, where it is used.
+
+In case of a radiomenu the input string is ignored and the "data" field
+points to the menuitem chosen (Dont forget to typecast this pointer to
+(t_menuitem *) when reading this info).
+
+In case of a submenu, this string if non-trivial is interpreted as the
+name of the submenu which should be linked there. This interpretation
+happens when the menu is first run and not when the menu system is being
+created. This allows the user to create the menusystem in an arbitrary
+order.
+
The fifth argument is a number whose meaning depends on the type of the
item. For a CHECKBOX it should be 0/1 setting the initial state of the
checkbox. For a SUBMENU it should be the index of the menu which should
-be displayed if this option is chosen. For a RADIOMENU it should be the
+be displayed if this option is chosen. Incase the data field is non-trivial,
+this number is ignored and computed later. For a RADIOMENU it should be the
index of the menu which contains all the options (All items in that menu
-should not of type RADIOITEM are ignored). For all other types, this
+not of type RADIOITEM are ignored). For all other types, this
argument has no meaning at all.
A call to add_sep is a convenient shorthand for calling add_item
@@ -123,6 +141,7 @@ item which was selected by the user.
<code>
choice = showmenus(MAIN); // Initial menu is the one with index MAIN
+ // or choice = showmenus(find_menu_num("main")); // Initial menu is the one named "main"
</code>
1.4 Processing the result
diff --git a/menu/Makefile b/menu/Makefile
index ea753509..102b7afe 100644
--- a/menu/Makefile
+++ b/menu/Makefile
@@ -39,9 +39,16 @@ LIBS = libmenu/libmenu.a $(LUDIR)/libutil_com.a $(LDIR)/libcom32.a $(LIBGCC)
LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o
-MENUS = $(patsubst %.c,%.c32,$(wildcard *.c))
+CMENUS = $(patsubst %.c,%.c32,$(wildcard *.c))
+IMENUS = $(patsubst %.menu,%.c32,$(wildcard *.menu))
-.SUFFIXES: .S .c .o .elf .c32
+MENUS = $(CMENUS) $(IMENUS)
+
+.SUFFIXES: .S .c .o .elf .c32 .menu
+
+.PRECIOUS: %.c
+%.c: %.menu
+ python menugen.py $< $@
.PRECIOUS: %.o
%.o: %.S
diff --git a/menu/README b/menu/README
index 66116e9c..aa979ed5 100644
--- a/menu/README
+++ b/menu/README
@@ -8,8 +8,12 @@ original author.
To configure the menus, you need to set up a menu configuration file
to have the menu items you desire, then build the menu system using
make. You can use either simple.c or complex.c as a starting point
-for your own menu configuration file; then add the name with a .c32
-extension to the MENUS list in the Makefile.
+for your own menu configuration file; If your menu system is only going
+to have entries corresponding to things which can be executed directly,
+then you can create a file in ".menu" format instead of the C code.
+
+NOTE: ".menu" files can only describe the very basic type of menus
+See MENU_FORMAT for the syntax of .menu files
The resulting code is a 32-bit COMBOOT code, and hence can be executed
only under syslinux. You can use tools like bochs to help debug your
diff --git a/menu/libmenu/menu.c b/menu/libmenu/menu.c
index 7d7e76d2..75a8d724 100644
--- a/menu/libmenu/menu.c
+++ b/menu/libmenu/menu.c
@@ -652,6 +652,44 @@ pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt,
}
}
+// Finds the indexof the menu with given name
+uchar find_menu_num(const char *name)
+{
+ int i;
+ pt_menu m;
+
+ if (name == NULL) return (uchar)(-1);
+ for (i=0; i < ms->nummenus; i++)
+ {
+ m = ms->menus[i];
+ if ((m->name) && (strcmp(m->name,name)==0)) return i;
+ }
+ return (uchar)(-1);
+}
+
+// Run through all items and if they are submenus
+// with a non-trivial "action" and trivial submenunum
+// replace submenunum with the menu with name "action"
+void fix_submenus()
+{
+ int i,j;
+ pt_menu m;
+ pt_menuitem mi;
+
+ i = 0;
+ for (i=0; i < ms->nummenus; i++)
+ {
+ m = ms->menus[i];
+ for (j=0; j < m->numitems; j++)
+ {
+ mi = m->items[j];
+ // if submenu with non-trivial data string
+ if ( (mi->action == OPT_SUBMENU) && (mi->data) )
+ mi->itemdata.submenunum = find_menu_num (mi->data);
+ }
+ }
+}
+
/* User Callable functions */
pt_menuitem showmenus(uchar startmenu)
@@ -659,6 +697,8 @@ pt_menuitem showmenus(uchar startmenu)
pt_menuitem rv;
uchar oldpage,tpos;
+ fix_submenus(); // Fix submenu numbers incase nick names were used
+
// Setup screen for menusystem
oldpage = getdisppage();
setdisppage(ms->menupage);
@@ -673,6 +713,7 @@ pt_menuitem showmenus(uchar startmenu)
cursoroff(); // Doesn't seem to work?
+
// Go, main menu cannot be a radio menu
rv = runmenusystem(ms->minrow+MENUROW, ms->mincol+MENUCOL,
ms->menus[(unsigned int)startmenu], 0, NORMALMENU);
@@ -983,6 +1024,7 @@ uchar add_menu(const char *title, int maxmenusize)
if (m == NULL) return -1;
ms->menus[num] = m;
m->numitems = 0;
+ m->name = NULL;
m->row = 0xFF;
m->col = 0xFF;
if (maxmenusize < 1)
@@ -1004,6 +1046,32 @@ uchar add_menu(const char *title, int maxmenusize)
return ms->nummenus - 1;
}
+void set_menu_name(const char *name) // Set the "name" of this menu
+{
+ pt_menu m;
+
+ m = ms->menus[ms->nummenus-1];
+ if (m->name) // Free up previous name
+ {
+ free(m->name);
+ m -> name = NULL;
+ }
+
+ if (name)
+ {
+ m->name = (char *)malloc(strlen(name)+1);
+ strcpy(m->name,name);
+ }
+}
+
+// Create a new named menu and return its position
+uchar add_named_menu(const char * name, const char *title, int maxmenusize)
+{
+ add_menu(title,maxmenusize);
+ set_menu_name(name);
+ return ms->nummenus - 1;
+}
+
void set_menu_pos(uchar row,uchar col) // Set the position of this menu.
{
pt_menu m;
@@ -1118,6 +1186,7 @@ pt_menuitem add_item(const char *item, const char *status, t_action action,
break;
case OPT_RADIOMENU:
mi->itemdata.radiomenunum = itemdata;
+ if (mi->data) free(mi->data);
mi->data = NULL; // No selection made
break;
default: // to keep the compiler happy
@@ -1146,3 +1215,4 @@ void set_item_options(uchar shortcut,int helpid)
void close_menusystem(void)
{
}
+
diff --git a/menu/libmenu/menu.h b/menu/libmenu/menu.h
index 1e0a6195..a6fae5d2 100644
--- a/menu/libmenu/menu.h
+++ b/menu/libmenu/menu.h
@@ -155,6 +155,7 @@ typedef struct s_menuitem {
char *status;
char *data; // string containing kernel to run.. but...
// for radio menu's this is a pointer to the item selected or NULL (initially)
+ // for submenu's this string could be name of menu
void * extra_data; // Any other data user can point to
t_item_handler handler; // Pointer to function of type menufn
t_action action;
@@ -169,7 +170,8 @@ typedef t_menuitem *pt_menuitem; // Pointer to type menuitem
typedef struct s_menu {
pt_menuitem *items; // pointer to array of pointer to menuitems
- char *title;
+ char *title; // Title string for menu
+ char *name; // menu can be referred to by this string
int maxmenusize; // the size of array allocated
uchar numitems; // how many items do we actually have
uchar menuwidth;
@@ -215,25 +217,10 @@ typedef struct s_menusystem {
typedef t_menusystem *pt_menusystem; // Pointer to type menusystem
-/************************************************************************
- * IMPORTANT INFORMATION
- *
- * All functions which take a string as argument store the pointer
- * for later use. So if you have alloc'ed a space for the string
- * and are passing it to any of these functions, DO NOT deallocate it.
- *
- * If they are constant strings, you may receive warning from the compiler
- * about "converting from char const * to char *". Ignore these errors.
- *
- * This hack/trick of storing these pointers will help in reducing the size
- * of the internal structures by a lot.
- *
- ***************************************************************************
- */
-
pt_menuitem showmenus(uchar startmenu);
pt_menusystem init_menusystem(const char *title);
+
void close_menusystem(); // Deallocate memory used
void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected);
@@ -261,9 +248,16 @@ void reg_ontimeout(t_timeout_handler, unsigned int numsteps, unsigned int stepsi
// So stepsize=0 means numsteps is measured in centiseconds.
void unreg_ontimeout();
+// Find the number of the menu given the name
+// Returns -1 if not found
+uchar find_menu_num(const char *name);
+
// Create a new menu and return its position
uchar add_menu(const char *title, int maxmenusize);
+// Create a named menu and return its position
+uchar add_named_menu(const char *name, const char *title, int maxmenusize);
+
void set_menu_pos(uchar row,uchar col); // Set the position of this menu.
// Add item to the "current" menu
diff --git a/menu/simple.c b/menu/simple.c
index 24589096..8277c5ea 100644
--- a/menu/simple.c
+++ b/menu/simple.c
@@ -22,8 +22,6 @@ int main(void)
{
t_menuitem * curr;
- char TESTING,RESCUE,MAIN; /* The menus we're going to declare */
-
// Change the video mode here
// setvideomode(0)
@@ -38,32 +36,35 @@ int main(void)
//set_title_info (-1,-1);
//set_misc_info(-1,-1,-1,-1);
- // menuindex = add_menu(" Menu Title ",-1);
+ // menuindex = add_named_menu("name"," Menu Title ",-1);
// add_item("Item string","Status String",TYPE,"any string",NUM)
// TYPE = OPT_RUN | OPT_EXITMENU | OPT_SUBMENU | OPT_CHECKBOX | OPT_INACTIVE
- // "any string" not used by the menu system, useful for storing kernel names
+ // "any string" useful for storing kernel names
+ // In case of OPT_SUBMENU, "any string" can be set to "name" of menu to be linked
+ // in which case value NUM is ignored
// NUM = index of submenu if OPT_SUBMENU,
// 0/1 default checked state if OPT_CHECKBOX
// unused otherwise.
- TESTING = add_menu(" Testing ",-1);
- add_item("Self Loop","Go to testing",OPT_SUBMENU,NULL,TESTING);
+ add_named_menu("testing"," Testing ",-1);
+ add_item("Self Loop","Go to testing",OPT_SUBMENU,"testing",0);
add_item("Memory Test","Perform extensive memory testing",OPT_RUN, "memtest",0);
add_item("Exit this menu","Go one level up",OPT_EXITMENU,"exit",0);
- RESCUE = add_menu(" Rescue Options ",-1);
+ add_named_menu("rescue"," Rescue Options ",-1);
add_item("Linux Rescue","linresc",OPT_RUN,"linresc",0);
add_item("Dos Rescue","dosresc",OPT_RUN,"dosresc",0);
add_item("Windows Rescue","winresc",OPT_RUN,"winresc",0);
add_item("Exit this menu","Go one level up",OPT_EXITMENU,"exit",0);
- MAIN = add_menu(" Main Menu ",-1);
+ add_named_menu("main"," Main Menu ",-1);
add_item("Prepare","prep",OPT_RUN,"prep",0);
- add_item("Rescue options...","Troubleshoot a system",OPT_SUBMENU,NULL,RESCUE);
- add_item("Testing...","Options to test hardware",OPT_SUBMENU,NULL,TESTING);
+ add_item("Rescue options...","Troubleshoot a system",OPT_SUBMENU,"rescue",0);
+ add_item("Testing...","Options to test hardware",OPT_SUBMENU,"testing",0);
add_item("Exit to prompt", "Exit the menu system", OPT_EXITMENU, "exit", 0);
- curr = showmenus(MAIN); // Initial menu is the one with index MAIN
+ curr = showmenus(find_menu_num("main")); // Initial menu is the one called "main"
+
if (curr)
{
if (curr->action == OPT_RUN)