[syslinux] Does advanced menu actually support ontimeout?

Nazo nazosan at gmail.com
Sun Nov 6 21:22:13 PST 2005


On 11/6/05, Murali Krishnan Ganapathy <gmurali at cs.uchicago.edu> wrote:
> Nazo wrote:
> > On 11/6/05, Murali Krishnan Ganapathy <gmurali at cs.uchicago.edu> wrote:
> >
> >> Nazo wrote:
> >>
> >>
> >>> On 11/6/05, Murali Krishnan Ganapathy <gmurali at cs.uchicago.edu> wrote:
> >>>
> >>>
> >>>
> >>>> reg_ontimeout(ontimeout,1500,0);
> >>>>
> >>>> should become
> >>>>
> >>>> reg_ontimeout(ontimeout,150,10);
> >>>>
> >>>> Basically the second argument should also be non-zero. In the second
> >>>> case, we are saying that the timeout handler should be called if no key
> >>>> is pressed for 15 seconds (150*10 centiseconds) and check for a key
> >>>> should be done every 10 centi-seconds.
> >>>>
> >>>> Also, there is a routine you can call to add a seperator. The call is
> >>>> equivalent to what you are doing, so don't have to worry about it.
> >>>>
> >>>> Hope this helps.
> >>>>
> >>>> - Murali
> >>>>
> >>>> Nazo wrote:
> >>>>
> >>>>
> >>>>
> >>>>> On 11/6/05, Nazo <nazosan at gmail.com> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>> On 11/6/05, Murali Krishnan Ganapathy <gmurali at cs.uchicago.edu> wrote:
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>> For the tab_key code to take effect you need to register the "keys
> >>>>>>> handler". Basically the menu system will call your keys handler, if the
> >>>>>>> user presses any key which it does not understand. You can do what you
> >>>>>>> want with it.
> >>>>>>>
> >>>>>>> - Murali
> >>>>>>>
> >>>>>>> Nazo wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>> I've finally gotten around to playing with the advanced menu, though
> >>>>>>>> the complex example is definitely still beyond me.  I'm trying to
> >>>>>>>> figure out a few basics from it, such as the tab key for line editing
> >>>>>>>> (don't know what I've done wrong here since it seems like I copied
> >>>>>>>> that part right) and the timeout.  It looks to me like the only
> >>>>>>>> ontimeout implemented so far is an option to not even show the menu at
> >>>>>>>> all if the user doesn't press a key within a certain time period.
> >>>>>>>> But, I want it to show the menu and simply time out after a while of
> >>>>>>>> no keypresses.  Is there any way to implement this that doesn't
> >>>>>>>> require several pages of code?  Have I just gotten mixed up and it
> >>>>>>>> already does this but I copied that code wrong too?
> >>>>>>>>
> >>>>>>>> _______________________________________________
> >>>>>>>> SYSLINUX mailing list
> >>>>>>>> Submissions to SYSLINUX at zytor.com
> >>>>>>>> Unsubscribe or set options at:
> >>>>>>>> http://www.zytor.com/mailman/listinfo/syslinux
> >>>>>>>> Please do not send private replies to mailing list traffic.
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>> Yes, well, I caught that part.  Thing is, I copied these two lines
> >>>>>>
> >>>>> >from the complex sample code:
> >>>>>
> >>>>>>  reg_handler(HDLR_KEYS,&keys_handler);
> >>>>>>  reg_ontimeout(ontimeout,1000,0);
> >>>>>>
> >>>>>> And the appropriate declarations for those to work (as far as I know
> >>>>>> anyway) and neither one is functioning.  That's why I asked in here.
> >>>>>> Both seem to fit that criteria mentioned earlier.  I'm probably
> >>>>>> missing something, but, I'm afraid I don't know what it is.  If it
> >>>>>> were as simple as just looking in the manual and automatically
> >>>>>> understanding I wouldn't be asking here, and I still hesitated as it
> >>>>>> was.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>> I guess, in case it makes it any easier, I should just paste the code
> >>>>> I currently have.  Note that it's probably not all right and I know
> >>>>> it.  I'm trying to learn as I go, but, some of this stuff is a bit
> >>>>> over my head as it is.  I started from the complex code and tried to
> >>>>> simplify as much as I could.  Here's my current attempt at "complex"
> >>>>> menu code:
> >>>>>
> >>>>> /* -----------------------------------------------------------------------------
> >>>>>  Advanced menu system for syslinux - C code.
> >>>>>
> >>>>>  For main PC
> >>>>> ----------------------------------------------------------------------------- */
> >>>>>
> >>>>>
> >>>>> #ifndef NULL
> >>>>> #define NULL ((void *) 0)
> >>>>> #endif
> >>>>>
> >>>>> #include "menu.h"
> >>>>> #include "com32io.h"
> >>>>> #include <string.h>
> >>>>>
> >>>>> #define EDITPROMPT 22
> >>>>>
> >>>>> TIMEOUTCODE ontimeout() {
> >>>>>  beep();
> >>>>>  return CODE_WAIT;
> >>>>> }
> >>>>>
> >>>>>
> >>>>> void keys_handler(t_menusystem *ms, t_menuitem *mi,unsigned int scancode) {
> >>>>>   char nc;
> >>>>>
> >>>>>   if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN)) {
> >>>>>     nc = getnumcols();
> >>>>>     // User hit TAB
> >>>>>     gotoxy(EDITPROMPT,1,ms->menupage);
> >>>>>     csprint("Command line:",0x07);
> >>>>>     editstring(mi->data,ACTIONLEN);
> >>>>>     gotoxy(EDITPROMPT,1,ms->menupage);
> >>>>>     cprint(' ',0x07,nc-1,ms->menupage);
> >>>>>   }
> >>>>> }
> >>>>>
> >>>>>
> >>>>> int main(void) {
> >>>>>  t_menuitem * curr;
> >>>>>
> >>>>>  char MAIN;
> >>>>>
> >>>>>  reg_handler(HDLR_KEYS,&keys_handler);
> >>>>>  reg_ontimeout(ontimeout,1500,0);
> >>>>>
> >>>>>
> >>>>>  // setvideomode(0)
> >>>>>
> >>>>>  init_menusystem(NULL);
> >>>>>  set_window_size(1,1,23,78); // Leave one row/col border all around
> >>>>>
> >>>>>  MAIN = add_menu(" Syslinux Boot Menu ", 10);
> >>>>>    add_item("<W>indows","Boot Windows",OPT_RUN,"chain.c32 hd0 2",0);
> >>>>>    add_item("<L>inux","Boot Gentoo Linux 2005.1",OPT_RUN,"gentoo
> >>>>> initrd=gentinit vga=0x31b root=/dev/ram0 real_root=/dev/hda7 udev
> >>>>> ramdisk=16384 video=vesafb:mtrr,ywrap,1280x1024-32 at 60",0);
> >>>>>    add_item("<G>eeXboX","Boot GeeXboX",OPT_RUN,"geexbox
> >>>>> initrd=geexinit.gz root=/dev/ram0 rw init=linuxrc boot=hda1 splash=0
> >>>>> vga=0x315 video=vesafb:ywrap,mtrr",0);
> >>>>>    add_item("<P>artition Magic 8","Boot Partition Magic 8 Rescue
> >>>>> Disk",OPT_RUN,"memdisk initrd=/disks/pqmagic.gz floppy",0);
> >>>>>    add_item("<M>emtest86+ 1.60","Boot MemTest86+",OPT_RUN,"memtestp",0);
> >>>>>    add_item("Prime<9>5 24.13","Boot Prime95 Test
> >>>>> Disk",OPT_RUN,"mprime initrd=mpinit.gz rw ramdisk_size=5325",0);
> >>>>>    add_item("DOS <B>ootdisk (Windows 98 based)","Boot
> >>>>> DOS",OPT_RUN,"memdisk initrd=/disks/dos.gz floppy",0);
> >>>>>    add_item("DOS <6>.22 Bootdisk","Boot DOS",OPT_RUN,"memdisk
> >>>>> initrd=/disks/dos622.gz floppy",0);
> >>>>>    add_item("----------------------------------","SEPERATOR",OPT_INACTIVE,"SEPERATOR",0);
> >>>>>    add_item("E<x>it","Return to Prompt",OPT_EXITMENU,"exit",0);
> >>>>>
> >>>>>
> >>>>>  curr = showmenus(MAIN);
> >>>>>  if (curr) {
> >>>>>        if (curr->action == OPT_RUN) {
> >>>>>            if (issyslinux()) runsyslinuxcmd(curr->data);
> >>>>>            else csprint(curr->data,0x07);
> >>>>>            return 1;
> >>>>>        }
> >>>>>        csprint("Error in programming!",0x07);
> >>>>>  }
> >>>>>  return 0;
> >>>>> }
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>
> >>> In other words, I had it done correctly, I just had it set to 10x the
> >>> length of time I actually wanted...  -.-  Well, the original complex
> >>> code I copied from says 1000 = 10 seconds, so I just changed it to
> >>> 1500.  Well, thanks for that info.
> >>>
> >>> Any idea what I did wrong on the tab key thing while you're at it?
> >>>
> >>>
> >>>
> >>>
> >> Sorry for replying at the top instead of the bottom. A few
> >> clarifications are in order. The code for check_keypress in the complex
> >> example is set in terms of milli seconds while the setting for the
> >> on_timeout handler is in terms of centi-seconds. my mistake for writing
> >> the check_keypress code using milli seconds instead of centiseconds (to
> >> be consistent with the timeout handler units).
> >>
> >> Second mistake: My previous explanation though correct was incomplete (I
> >> had forgotten what I had coded). The actual time we will wait is the
> >> product of the two numbers (in centiseconds). However 0 is a special
> >> value. Giving 0 means "keep the previous value". The default values are
> >> 30,000 and 10 respectively giving a default of 3000 seconds. So
> >>
> >> reg_ontimeout(ontimeout,1500,0);
> >>
> >> is a valid call and will result in a time out of 150 seconds (the second
> >> value has a default of 10 which is not changed).
> >>
> >> TAB key thing: I dont see anything wrong with the code or the way it is
> >> registered. The problem is with WHEN it is registered. This also
> >> explains why the timeout did not seem to be working as well.
> >>
> >> You MUST initialize the menusystem before doing anything, including
> >> setting up handlers. The init_menusystem allocates space for and
> >> initializes data structures. In particular it sets all the handlers to
> >> NULL. Doing any menu related calls before initializing should usually
> >> result in a SEGFAULT. So you should move the init_menusystem call to
> >> before the handlers are registered, like
> >>
> >>   init_menusystem(NULL);
> >>
> >>   reg_handler(HDLR_KEYS,&keys_handler);
> >>   reg_ontimeout(ontimeout,1500,0);
> >>
> >>
> >> Hope this fixes your problem.
> >>
> >> - Murali
> >>
> >>
> >>
> > Ok, this gets me a lot closer.  First of all, you're definitely right
> > about placement.  That was a key detail I didn't understand about.  I
> > moved those two lines down to after the init_menusystem call.  The tab
> > key now works.  ontimeout doesn't work RIGHT though.  I emphasise
> > right, because, it is partially working now.  Firstly, I think I
> > understood the amount of time correctly the first time.  1500 must be
> > 15 seconds.  I tried 150 and it was approximiately 1.5 seconds (I
> > didn't check exactly how much as my clock next to the PC has only
> > seconds resolution, but, you get the idea.)  Secondly, even though
> > it's timing out (I hear the beep ever 1.5 seconds or so) it doesn't
> > actually do anything.  I definitely have an ONTIMEOUT command in the
> > extlinux configuration, so my only guess is that the CODE_WAIT isn't
> > passed to syslinux correctly or something.  That or maybe it's the
> > wrong code?  The other codes I see mentioned don't look right though.
> >
> >
> The advanced menu does not read your config file and hence cannot honor
> the ONTIMEOUT command or any syslinux command. You will have to
> implement that using the ontimeout handler. The ontimeout handler
> provided with complex example just beeps and returns control back to the
> menu system. Instead of returning CODE_WAIT in the handler you can
> return CODE_ENTER or CODE_ESCAPE to make the menu system pretend that
> the user hit ENTER or ESCAPE. If you choose ESCAPE, then eventually the
> return value of  the "showmenus" call will be NULL. Then it is up to you
> to handle that case appropriately. Another option is to not return from
> your timeout handler and directly run your favorite kernel using
> "runsyslinuxcmd".
>
> I have always wanted to write some parser which reads the syslinux
> config file or some other config file and eliminate the need to actually
> write C code, at least for the simple cases consisting of just a bunch
> of menus, kernel images, authentication and help system (without
> checkboxes, radio buttons and the like). I never got around to doing it
> and don't see myself doing it in the near future. All it requires is
> basic C coding to parse a file and call the appropriate menu system
> calls. So if anybody is interested in doing it, I can point them in the
> right direction.
>
> - Murali
>
> P.S: Try using add_seperator() instead of  add_item("--------",....)
>
>
Ah, I mistakenly thought it returned from the menu program to
syslinux/whatever with a code saying it had timed out.  So you have to
manually implement the ontimeout command.  That's fine I guess.  Works
out about the same in the end, just you have to remember to change
both lines I suppose.  The CODE_ENTER would be fine too if you could
force it to jump the cursor to a particular item somehow, but, I don't
know how.  Anyway, this should be enough info for me to get my own
somewhat basic menu thrown together now, and hopefully I can now just
change a minimal amount to make a similar menu for my HTPC as well as
rescue discs and such.  The advanced menu is definitely a little nicer
than the simple menu.  Thanks for all your help.

BTW, it might be that you can steal some of the simple menu's parsing code.  ^_^




More information about the Syslinux mailing list