[syslinux] Does advanced menu actually support ontimeout?

Murali Krishnan Ganapathy gmurali at cs.uchicago.edu
Mon Nov 7 06:13:41 PST 2005


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:
>>     
>>> 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.  ^_^
>>
>>     
>
> Hey, sorry for the extra message, but, I thought I should let you know
> that add_seperator() didn't work.  Perhaps I didn't include a needed
> file or something.  I couldn't find any obvious command like that in
> the .h or .c files though.  Anyway, just letting you know in case it
> matters.
>
>   
Sorry. It is "add_sep()" not "add_seperator()".

- Murali




More information about the Syslinux mailing list