syslinux-3.08-2 sources from FC4
[bootcd.git] / syslinux / menu / MANUAL
1           Overview of writing code using the menu system
2           ----------------------------------------------
3
4 This file contains implementation and developer documentation.
5 For simple cases, you should start by using simple.c as a template.
6 complex.c illustrates most of the features available in the menu system.
7
8 Menu Features currently supported are:
9 * menu items, 
10 * submenus, 
11 * disabled items,
12 * checkboxes,
13 * invisible items (useful for dynamic menus), and
14 * Radio menus,
15 * Context sensitive help
16 * Authenticated users 
17
18 The keys used are:
19
20 * Arrow Keys, PgUp, PgDn, Home, End Keys
21 * Space to switch state of a checkbox
22 * Enter to choose the item
23 * Escape to exit from it
24 * Shortcut keys
25
26 1. Overview
27 -----------
28
29 The code usually consists of many stages. 
30
31  * Configuring the menusytem
32  * Installing global handlers [optional]
33  * Populating the menusystem 
34  * Executing the menusystem
35  * Processing the result
36
37 1.1 Configuring the menusystem
38 ------------------------------
39 This includes setting the window the menu system should use, 
40 the choice of colors, the title of the menu etc. In most functions
41 calls, a value of -1 indicates that the default value be used.
42 For details about what the arguments are look at function 
43 declarations in menu.h
44
45 <code>
46   // Choose the default title and setup default values for all attributes....
47   init_menusystem(NULL);
48   set_window_size(1,1,23,78); // Leave one row/col border all around
49   
50   // Choose the default values for all attributes and char's
51   // -1 means choose defaults (Actually the next 4 lines are not needed)
52   set_normal_attr (-1,-1,-1,-1); 
53   set_status_info (-1,-1); 
54   set_title_info  (-1,-1); 
55   set_misc_info(-1,-1,-1,-1);
56 </code>
57   
58 1.2 Populating the menusystem
59 -----------------------------
60 This involves adding a menu to the system, and the options which
61 should appear in the menu. An example is given below.
62
63 <code>
64   MAINMENU = add_menu(" Menu Title ",-1);
65   CHECKED = 1;
66   add_item("option1","Status 1",OPT_RUN,"kernel1 arg1=val1",0);
67   add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
68   add_sep();
69   add_item("checkbox,"Checkbox Info",OPT_CHECKBOX,NULL,CHECKED);
70   add_item("Exit ","Status String",OPT_EXITMENU,NULL,0);
71   //   "any string" not used by the menu system, useful for storing kernel names
72   //   NUM = index of submenu if OPT_SUBMENU, 
73   //         0/1 default checked state if OPT_CHECKBOX
74   //         unused otherwise.
75 </code>
76
77 The call to add_menu has two arguments, the first being the title of 
78 the menu and the second an upper bound on the number of items in the menu.
79 Putting a -1, will use the default (see MENUSIZE in menu.h). If you try
80 to add more items than specified, the extra items will not appear in 
81 the menu. The accuracy of this number affects the memory required
82 to run the system. Currently the code compiles to a .COM file which 
83 has a 64K limit on memory used. 
84
85 The call to add_item has five arguments.
86 The first argument is the text which appears in the menu itself.
87 The second argument is the text displayed in the status line.
88 The third argument indicates the type of this menuitem. It is one of
89 the following
90
91  * OPT_RUN : executable content
92  * OPT_EXITMENU : exits menu to parent 
93  * OPT_SUBMENU : if selected, displays a submenu
94  * OPT_CHECKBOX : associates a boolean with this item which can be toggled
95  * OPT_RADIOMENU: associates this with a radio menu. 
96       After execution, the data field of this item will point 
97       to the option selected.
98  * OPT_SEP : A menu seperator (visually divide menu into parts)
99  * OPT_RADIOITEM: this item is one of the options in a RADIOMENU
100  * OPT_INACTIVE : A disabled item (user cannot select this)
101  * OPT_INVISIBLE: This item will not be displayed.
102   
103 The fourth argument is the value of the data field. This pointer is just
104 stored. In case of a radiomenu this points to the menuitem chosen (Dont 
105 forget to typecase this pointer to (t_menuitem *) when reading this info).
106
107 The fifth argument is a number whose meaning depends on the type of the 
108 item. For a CHECKBOX it should be 0/1 setting the initial state of the
109 checkbox. For a SUBMENU it should be the index of the menu which should
110 be displayed if this option is chosen. For a RADIOMENU it should be the
111 index of the menu which contains all the options (All items in that menu
112 should not of type RADIOITEM are ignored). For all other types, this
113 argument has no meaning at all.
114
115 A call to add_sep is a convenient shorthand for calling add_item
116 with the type set to OPT_SEP.
117
118 1.3 Executing the menusystem
119 ----------------------------
120 This is the simplest of all. Just call showmenus, with the index
121 of the main menu as its argument. It returns a pointer to the menu
122 item which was selected by the user.
123
124 <code>
125    choice = showmenus(MAIN); // Initial menu is the one with index MAIN
126 </code>
127
128 1.4 Processing the result
129 -------------------------
130 This pointer will either be NULL (user hit Escape) or always point 
131 to a menuitem which can be "executed", i.e. it will be of type OPT_RUN.
132 Usually at this point, all we need to do is to ask syslinux to run 
133 the command associated with this menuitem. The following code executes
134 the command stored in choice->data (there is no other use for the data 
135 field, except for radiomenu's)
136
137 <code>
138   if (choice)
139   {
140         if (choice->action == OPT_RUN)
141         {
142             if (syslinux) runcommand(choice->data);
143             else csprint(choice->data,0x07);
144             return 1;
145         }
146         csprint("Error in programming!",0x07);
147   }
148 </code>
149
150 2. Advanced features
151 --------------------
152 Everycall to add_item actually returns a pointer to the menuitem
153 created. This can be useful when using any of the advanced features.
154
155 2.1 extra_data
156 --------------
157 For example, every menuitem has an "extra_data" field (a pointer)
158 which the user can use to point any data he/she pleases. The menusystem
159 itself does not use this field in anyway.
160
161 2.2 helpid
162 ----------
163 Every item also has a field called "helpid". It is meant to hold some
164 kind of identifier which can be referenced and used to generate
165 a context sensitive help system. This can be set after a call to 
166 add_item as follows
167 <code>
168   add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
169   set_item_options('A',4516);
170 </code>
171
172 The first is the shortcut key for this entry. You can put -1 to ensure
173 that the shortcut key is not reset. The second is some unsigned integer.
174 If this value is 0xFFFF, then the helpid is not changed.
175
176 2.3 Installing global handlers 
177 ------------------------------
178 It is possible to register handlers for the menu system. These are
179 user functions which are called by the menusystem in certain 
180 situations. Usually the handlers get a pointer to the menusystem
181 datastructure as well as a pointer to the current item selected.
182 Some handlers may get additional information. Some handlers are
183 required to return values while others are not required to do so.
184
185 Currently the menusystem support three types of global handlers
186 * timeout handler
187 * screen handler
188 * keys handler
189
190 2.3.1 timeout handler
191 ---------------------
192 This is installed using a call to "reg_ontimeout(fn,numsteps,stepsize)" 
193 function. fn is a pointer to a function which takes no arguments and
194 returns one of CODE_WAIT, CODE_ENTER, CODE_ESCAPE. This function is
195 called when numsteps*stepsize Centiseconds have gone by without any
196 user input. If the function returns CODE_WAIT then the menusystem
197 waits for user input (for another numsteps*stepsize Centiseconds). If
198 CODE_ENTER or CODE_ESCAPE is returned, then the system pretends that
199 the user hit ENTER or ESCAPE on the keyboard and acts accordingly.
200
201 2.3.2 Screen handler
202 --------------------
203 This is installed using a call to "reg_handler(HDLR_SCREEN,fn)". fn is
204 a pointer to a function which takes a pointer to the menusystem 
205 datastructure and the current item selected and returns nothing.
206 This is called everytime a menu is drawn (i.e. everytime user changes 
207 the current selection). This is meant for displaying any additional
208 information which reflects the current state of the system.
209
210 2.3.3 Keys handler
211 ------------------
212 This is installed using a call to "reg_handler(HDLR_KEYS,fn)". fn is
213 a pointer to a function which takes a pointer to the menusystem
214 datastructure, the current item and the scan code of a key and returns
215 nothing. This function is called when the user presses a key which 
216 the menusystem does not know to dealwith. In any case, when this call 
217 returns the screen should not have changed in any way. Usually,
218 one can change the active page and display any output needed and 
219 reset the active page when you return from this call.
220
221 complex.c implements a key_handler, which implements a simple
222 context sensitive help system, by displaying the contents of a 
223 file whose name is based on the helpid of the active item.
224
225 Also, complex.c's handler allows certain users to make changes
226 to edit the commands associated with a menu item.
227
228 2.4 Installing item level handlers
229 ----------------------------------
230 In addition to global handlers, one can also install handlers for each 
231 individual item. A handler for an individual item is a function which
232 takes a pointer to the menusystem datastructure and a pointer to the 
233 current item and return a structure of type t_handler_return. Currently
234 it has two bit fields "valid" and "refresh".
235
236 This handler is called when the user hits "enter" on a RUN item, or
237 changes the status of a CHECKBOX, or called *after* a radio menu choice
238 has been set. In all other cases, installing a handler has no effect.
239
240 The handler can change any of the internal datastructures it pleases.
241 For e.g. in a radiomenu handler, one can change the text displayed
242 on the menuitem depending on which choice was selected (see complex.c
243 for an example). The return values are ignored for RADIOMENU's.
244
245 In case of RUN items: the return values are used as follows. If the 
246 return value of "valid" was false, then this user choice is ignored.
247 This is useful if the handler has useful side effects. For e.g. 
248 complex.c has a Login item, whose handler always return INVALID. It 
249 sets a global variable to the name of the user logged in, and enables
250 some menu items, and makes some invisible items visible. 
251
252 * If the handler does not change the visibility status of any items, 
253   the handler should set "refresh" to 0. 
254 * If the handler changes the visibility status of items in the current 
255   menu set "refresh" to 1. 
256 * If you are changing the visibility status of items in menu's currently 
257   not displayed, then you can set "refresh" to 0. 
258 * Changing the visibility status of items in another menu
259   which is currently displayed, is not supported. If you do it, 
260   the screen contents may not reflect the change until you get to the 
261   menu which was changed. When you do get to that menu, you may notice
262   pieces of the old menu still on the screen.
263
264 In case of CHECKBOXES: the return value of "valid" is ignored. Because, 
265 the handler can change the value of checkbox if the user selected value
266 is not appropriate. only the value of "refresh" is honored. In this case
267 all the caveats in the previous paragraph apply.
268
269 menu.h defines two instances of t_handler_return 
270 ACTION_VALID and ACTION_INVALID for common use. These set the valid flag 
271 to 1 and 0 respectively and the refresh flag to 0.
272
273 3. Things to look out for
274 -------------------------
275 When you define the menu system, always declare it in the opposite 
276 order, i.e. all lower level menu's should be defined before the higher
277 level menus. This is because in order to define the MAINMENU, you need 
278 to know the index assigned to all its submenus.
279
280 4. Additional Modules
281 ---------------------
282 You can make use of the following additional modules, in writing your
283 handlers.
284
285 * Passwords
286 * Help
287
288 4.1 Passwords
289 -------------
290 This module was written by Th. Gebhardt. This is basically a modification
291 of the DES crypt function obtained by removing the dependence of the
292 original crypt function on C libraries. The following functions are 
293 defined
294
295   init_passwords(PWDFILE) 
296       // Read in the password database from the file
297   authenticate_user(user,pwd) 
298       // Checks if user,pwd is valid
299   isallowed(user,perm) 
300       // Checks if the user has a specified permission
301   close_passwords() 
302       // Unloads password database from memory
303
304   See the sample password file for more details about the file format
305   and the implementation of permissions.
306
307 See complex.c for a example of how to use this. 
308
309 4.2 Help
310 --------
311 This can be used to set up a context sensitive help system. The following
312 functions are defined
313
314    init_help(HELPBASEDIR)
315        // Initialises the help system. All help files will be loaded
316        // from the directory specified.
317    runhelpsystem(context)
318        // Displays the contents of HELPBASEDIR/hlp<context>.txt
319
320 In order to have a functioning help system, you just need to create
321 the hlp<NNNNN>.txt files and initialize the help system by specifying
322 the base directory.
323
324 The first line of this file assumed to be the title of the help screen.
325 You can use ^N and ^O to change attributes absolutely and relatively, 
326 i.e. [^O]46 (i.e. Ctrl-O followed by chars 4 and 6) will set the 
327 attribute to 46, while [^N]08 will XOR the current attribute with 
328 specified number, thus in this case the first [^N]08 will turn on 
329 highlighting and the second one will turn it off.
330