]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[menu] Allow a post-activity timeout to be defined 1413/head
authorMichael Brown <mcb30@ipxe.org>
Wed, 19 Feb 2025 13:12:29 +0000 (13:12 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 19 Feb 2025 13:12:29 +0000 (13:12 +0000)
Allow the "--retimeout" option to be used to specify a timeout value
that will be (re)applied after each keypress activity.  This allows
script authors to ensure that a single (potentially accidental)
keypress will not pause the boot process indefinitely.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/hci/commands/dynui_cmd.c
src/hci/tui/menu_ui.c
src/include/ipxe/dynui.h

index d4446dc7cc145f05237cf40d2d5ac3717ca78acb..6cad63868be7fdc24380f943e26415b8c1ca3e3e 100644 (file)
@@ -207,8 +207,10 @@ static int item_exec ( int argc, char **argv ) {
 struct choose_options {
        /** Dynamic user interface name */
        char *dynui;
-       /** Timeout */
+       /** Initial timeout */
        unsigned long timeout;
+       /** Post-activity timeout */
+       unsigned long retimeout;
        /** Default selection */
        char *select;
        /** Keep dynamic user interface */
@@ -223,6 +225,8 @@ static struct option_descriptor choose_opts[] = {
                      struct choose_options, select, parse_string ),
        OPTION_DESC ( "timeout", 't', required_argument,
                      struct choose_options, timeout, parse_timeout ),
+       OPTION_DESC ( "retimeout", 'r', required_argument,
+                     struct choose_options, retimeout, parse_timeout ),
        OPTION_DESC ( "keep", 'k', no_argument,
                      struct choose_options, keep, parse_flag ),
 };
@@ -259,8 +263,8 @@ static int choose_exec ( int argc, char **argv ) {
                goto err_parse_dynui;
 
        /* Show as menu */
-       if ( ( rc = show_menu ( dynui, opts.timeout, opts.select,
-                               &item ) ) != 0 )
+       if ( ( rc = show_menu ( dynui, opts.timeout, opts.retimeout,
+                               opts.select, &item ) ) != 0 )
                goto err_show_menu;
 
        /* Apply default type if necessary */
index b7b52ee62180722180f3e20ec39036ea4c6295bf..c7fad4a6b4157770fcfbdded919f17cba2adbfa8 100644 (file)
@@ -53,8 +53,10 @@ struct menu_ui {
        struct dynamic_ui *dynui;
        /** Jump scroller */
        struct jump_scroller scroll;
-       /** Timeout (0=indefinite) */
+       /** Remaining timeout (0=indefinite) */
        unsigned long timeout;
+       /** Post-activity timeout (0=indefinite) */
+       unsigned long retimeout;
 };
 
 /**
@@ -180,8 +182,8 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
                        if ( ui->timeout == 0 )
                                chosen = 1;
                } else {
-                       /* Cancel any timeout */
-                       ui->timeout = 0;
+                       /* Reset timeout after activity */
+                       ui->timeout = ui->retimeout;
 
                        /* Handle scroll keys */
                        move = jump_scroll_key ( &ui->scroll, key );
@@ -241,12 +243,14 @@ static int menu_loop ( struct menu_ui *ui, struct dynamic_item **selected ) {
  * Show menu
  *
  * @v dynui            Dynamic user interface
- * @v timeout          Timeout period, in ticks (0=indefinite)
+ * @v timeout          Initial timeout period, in ticks (0=indefinite)
+ * @v retimeout                Post-activity timeout period, in ticks (0=indefinite)
  * @ret selected       Selected item
  * @ret rc             Return status code
  */
 int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
-               const char *select, struct dynamic_item **selected ) {
+               unsigned long retimeout, const char *select,
+               struct dynamic_item **selected ) {
        struct dynamic_item *item;
        struct menu_ui ui;
        char buf[ MENU_COLS + 1 /* NUL */ ];
@@ -258,6 +262,8 @@ int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
        ui.dynui = dynui;
        ui.scroll.rows = MENU_ROWS;
        ui.timeout = timeout;
+       ui.retimeout = retimeout;
+
        list_for_each_entry ( item, &dynui->items, list ) {
                if ( item->name ) {
                        if ( ! named_count )
index 67eb8b8f8d9a566c031d486ab3c383625a6f2058..f47f5cb364051446b6e5c515b013cc5d4b71494d 100644 (file)
@@ -60,7 +60,8 @@ extern struct dynamic_item * dynui_item ( struct dynamic_ui *dynui,
 extern struct dynamic_item * dynui_shortcut ( struct dynamic_ui *dynui,
                                              int key );
 extern int show_menu ( struct dynamic_ui *dynui, unsigned long timeout,
-                      const char *select, struct dynamic_item **selected );
+                      unsigned long retimeout, const char *select,
+                      struct dynamic_item **selected );
 extern int show_form ( struct dynamic_ui *dynui );
 
 #endif /* _IPXE_DYNUI_H */