source: bootcd/isolinux/syslinux-6.03/com32/cmenu/MANUAL

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 13.6 KB
Line 
1          Overview of writing code using the menu system
2          ----------------------------------------------
3
4This file contains implementation and developer documentation.
5For simple cases, you should start by using simple.c as a template.
6complex.c illustrates most of the features available in the menu system.
7
8Menu 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
18The 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
261. Overview
27-----------
28
29The 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
371.1 Configuring the menusystem
38------------------------------
39This includes setting the window the menu system should use,
40the choice of colors, the title of the menu etc. In most functions
41calls, a value of -1 indicates that the default value be used.
42For details about what the arguments are look at function
43declarations 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
581.2 Populating the menusystem
59-----------------------------
60This involves adding a menu to the system, and the options which
61should 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_item("othermenu","Status 3",OPT_SUBMENU,"menuname",0);
69  add_sep();
70  add_item("checkbox,"Checkbox Info",OPT_CHECKBOX,NULL,CHECKED);
71  add_item("Exit ","Status String",OPT_EXITMENU,NULL,0);
72</code>
73
74The call to add_menu has two arguments, the first being the title of
75the menu and the second an upper bound on the number of items in the menu.
76Putting a -1, will use the default (see MENUSIZE in menu.h). If you try
77to add more items than specified, the extra items will not appear in
78the menu. The accuracy of this number affects the memory required
79to run the system.
80
81If you do not want to keep track of the return values, you can also use
82the following variant of add_menu
83
84<code>
85add_named_menu("main"," Menu Title ",-1)
86</code>
87
88This creates a new menu as before and gives it a name "main". When using named
89menus, you get an alternate way for adding submenu's. See below for details.
90
91The call to add_item has five arguments.
92The first argument is the text which appears in the menu itself.
93The second argument is the text displayed in the status line.
94The third argument indicates the type of this menuitem. It is one of
95the following
96
97 * OPT_RUN : executable content
98 * OPT_EXITMENU : exits menu to parent
99 * OPT_SUBMENU : if selected, displays a submenu
100 * OPT_CHECKBOX : associates a boolean with this item which can be toggled
101 * OPT_RADIOMENU: associates this with a radio menu.
102      After execution, the data field of this item will point
103      to the option selected.
104 * OPT_SEP : A menu seperator (visually divide menu into parts)
105 * OPT_RADIOITEM: this item is one of the options in a RADIOMENU
106 * OPT_INACTIVE : A disabled item (user cannot select this)
107 * OPT_INVISIBLE: This item will not be displayed.
108
109The fourth argument is the value of the data field always a string.
110Usually this string is just copied and nothing is done with it. Two
111cases, where it is used.
112
113In case of a radiomenu the input string is ignored and the "data" field
114points to the menuitem chosen (Dont forget to typecast this pointer to
115(t_menuitem *) when reading this info).
116
117In case of a submenu, this string if non-trivial is interpreted as the
118name of the submenu which should be linked there. This interpretation
119happens when the menu is first run and not when the menu system is being
120created. This allows the user to create the menusystem in an arbitrary
121order.
122
123
124The fifth argument is a number whose meaning depends on the type of the
125item. For a CHECKBOX it should be 0/1 setting the initial state of the
126checkbox. For a SUBMENU it should be the index of the menu which should
127be displayed if this option is chosen. Incase the data field is non-trivial,
128this number is ignored and computed later. For a RADIOMENU it should be the
129index of the menu which contains all the options (All items in that menu
130not of type RADIOITEM are ignored). For all other types, this
131argument has no meaning at all.
132
133A call to add_sep is a convenient shorthand for calling add_item
134with the type set to OPT_SEP.
135
1361.3 Executing the menusystem
137----------------------------
138This is the simplest of all. Just call showmenus, with the index
139of the main menu as its argument. It returns a pointer to the menu
140item which was selected by the user.
141
142<code>
143   choice = showmenus(MAIN); // Initial menu is the one with index MAIN
144   // or choice = showmenus(find_menu_num("main")); // Initial menu is the one named "main"
145</code>
146
1471.4 Processing the result
148-------------------------
149This pointer will either be NULL (user hit Escape) or always point
150to a menuitem which can be "executed", i.e. it will be of type OPT_RUN.
151Usually at this point, all we need to do is to ask syslinux to run
152the command associated with this menuitem. The following code executes
153the command stored in choice->data (there is no other use for the data
154field, except for radiomenu's)
155
156<code>
157  if (choice)
158  {
159        if (choice->action == OPT_RUN)
160        {
161            if (syslinux) runcommand(choice->data);
162            else csprint(choice->data,0x07);
163            return 1;
164        }
165        csprint("Error in programming!",0x07);
166  }
167</code>
168
1692. Advanced features
170--------------------
171Everycall to add_item actually returns a pointer to the menuitem
172created. This can be useful when using any of the advanced features.
173
1742.1 extra_data
175--------------
176For example, every menuitem has an "extra_data" field (a pointer)
177which the user can use to point any data he/she pleases. The menusystem
178itself does not use this field in anyway.
179
1802.2 helpid
181----------
182Every item also has a field called "helpid". It is meant to hold some
183kind of identifier which can be referenced and used to generate
184a context sensitive help system. This can be set after a call to
185add_item as follows
186<code>
187  add_item("selfloop","Status 2",OPT_SUBMENU,NULL,MAINMENU);
188  set_item_options('A',4516);
189</code>
190
191The first is the shortcut key for this entry. You can put -1 to ensure
192that the shortcut key is not reset. The second is some unsigned integer.
193If this value is 0xFFFF, then the helpid is not changed.
194
1952.3 Installing global handlers
196------------------------------
197It is possible to register handlers for the menu system. These are
198user functions which are called by the menusystem in certain
199situations. Usually the handlers get a pointer to the menusystem
200datastructure as well as a pointer to the current item selected.
201Some handlers may get additional information. Some handlers are
202required to return values while others are not required to do so.
203
204Currently the menusystem support three types of global handlers
205* timeout handler
206* screen handler
207* keys handler
208
2092.3.1 timeout handler
210---------------------
211This is installed using a call to "reg_ontimeout(fn,numsteps,stepsize)"
212function. fn is a pointer to a function which takes no arguments and
213returns one of CODE_WAIT, CODE_ENTER, CODE_ESCAPE. This function is
214called when numsteps*stepsize Centiseconds have gone by without any
215user input. If the function returns CODE_WAIT then the menusystem
216waits for user input (for another numsteps*stepsize Centiseconds). If
217CODE_ENTER or CODE_ESCAPE is returned, then the system pretends that
218the user hit ENTER or ESCAPE on the keyboard and acts accordingly.
219
2202.3.2 Screen handler
221--------------------
222This is installed using a call to "reg_handler(HDLR_SCREEN,fn)". fn is
223a pointer to a function which takes a pointer to the menusystem
224datastructure and the current item selected and returns nothing.
225This is called everytime a menu is drawn (i.e. everytime user changes
226the current selection). This is meant for displaying any additional
227information which reflects the current state of the system.
228
2292.3.3 Keys handler
230------------------
231This is installed using a call to "reg_handler(HDLR_KEYS,fn)". fn is
232a pointer to a function which takes a pointer to the menusystem
233datastructure, the current item and the scan code of a key and returns
234nothing. This function is called when the user presses a key which
235the menusystem does not know to dealwith. In any case, when this call
236returns the screen should not have changed in any way. Usually,
237one can change the active page and display any output needed and
238reset the active page when you return from this call.
239
240complex.c implements a key_handler, which implements a simple
241context sensitive help system, by displaying the contents of a
242file whose name is based on the helpid of the active item.
243
244Also, complex.c's handler allows certain users to make changes
245to edit the commands associated with a menu item.
246
2472.4 Installing item level handlers
248----------------------------------
249In addition to global handlers, one can also install handlers for each
250individual item. A handler for an individual item is a function which
251takes a pointer to the menusystem datastructure and a pointer to the
252current item and return a structure of type t_handler_return. Currently
253it has two bit fields "valid" and "refresh".
254
255This handler is called when the user hits "enter" on a RUN item, or
256changes the status of a CHECKBOX, or called *after* a radio menu choice
257has been set. In all other cases, installing a handler has no effect.
258
259The handler can change any of the internal datastructures it pleases.
260For e.g. in a radiomenu handler, one can change the text displayed
261on the menuitem depending on which choice was selected (see complex.c
262for an example). The return values are ignored for RADIOMENU's.
263
264In case of RUN items: the return values are used as follows. If the
265return value of "valid" was false, then this user choice is ignored.
266This is useful if the handler has useful side effects. For e.g.
267complex.c has a Login item, whose handler always return INVALID. It
268sets a global variable to the name of the user logged in, and enables
269some menu items, and makes some invisible items visible.
270
271* If the handler does not change the visibility status of any items,
272  the handler should set "refresh" to 0.
273* If the handler changes the visibility status of items in the current
274  menu set "refresh" to 1.
275* If you are changing the visibility status of items in menu's currently
276  not displayed, then you can set "refresh" to 0.
277* Changing the visibility status of items in another menu
278  which is currently displayed, is not supported. If you do it,
279  the screen contents may not reflect the change until you get to the
280  menu which was changed. When you do get to that menu, you may notice
281  pieces of the old menu still on the screen.
282
283In case of CHECKBOXES: the return value of "valid" is ignored. Because,
284the handler can change the value of checkbox if the user selected value
285is not appropriate. only the value of "refresh" is honored. In this case
286all the caveats in the previous paragraph apply.
287
288menu.h defines two instances of t_handler_return
289ACTION_VALID and ACTION_INVALID for common use. These set the valid flag
290to 1 and 0 respectively and the refresh flag to 0.
291
2923. Things to look out for
293-------------------------
294When you define the menu system, always declare it in the opposite
295order, i.e. all lower level menu's should be defined before the higher
296level menus. This is because in order to define the MAINMENU, you need
297to know the index assigned to all its submenus.
298
2994. Additional Modules
300---------------------
301You can make use of the following additional modules, in writing your
302handlers.
303
304* Passwords
305* Help
306
3074.1 Passwords
308-------------
309This module was written by Th. Gebhardt. This is basically a modification
310of the DES crypt function obtained by removing the dependence of the
311original crypt function on C libraries. The following functions are
312defined
313
314  init_passwords(PWDFILE)
315      // Read in the password database from the file
316  authenticate_user(user,pwd)
317      // Checks if user,pwd is valid
318  isallowed(user,perm)
319      // Checks if the user has a specified permission
320  close_passwords()
321      // Unloads password database from memory
322
323  See the sample password file for more details about the file format
324  and the implementation of permissions.
325
326See complex.c for a example of how to use this.
327
3284.2 Help
329--------
330This can be used to set up a context sensitive help system. The following
331functions are defined
332
333   init_help(HELPBASEDIR)
334       // Initialises the help system. All help files will be loaded
335       // from the directory specified.
336   runhelpsystem(context)
337       // Displays the contents of HELPBASEDIR/hlp<context>.txt
338
339In order to have a functioning help system, you just need to create
340the hlp<NNNNN>.txt files and initialize the help system by specifying
341the base directory.
342
343The first line of this file assumed to be the title of the help screen.
344You can use ^N and ^O to change attributes absolutely and relatively,
345i.e. [^O]46 (i.e. Ctrl-O followed by chars 4 and 6) will set the
346attribute to 46, while [^N]08 will XOR the current attribute with
347specified number, thus in this case the first [^N]08 will turn on
348highlighting and the second one will turn it off.
Note: See TracBrowser for help on using the repository browser.