]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Support submenus.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 20 Sep 2010 22:47:49 +0000 (00:47 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 20 Sep 2010 22:47:49 +0000 (00:47 +0200)
* grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New
parameter submenu. All users updated.
* grub-core/normal/main.c (free_menu): Rename to ...
(grub_normal_free_menu): ... this. Made global.
* grub-core/normal/menu.c (grub_menu_execute_entry): Open new context
if requested.
* grub-core/normal/menu_entry.c (screen): New field submenu.
(make_screen): Set submenu.
(run): Open new context if requested.
* include/grub/menu.h (grub_menu_entry): New field submenu.
* include/grub/normal.h (grub_normal_free_menu): New proto.

ChangeLog
grub-core/commands/legacycfg.c
grub-core/commands/menuentry.c
grub-core/normal/main.c
grub-core/normal/menu.c
grub-core/normal/menu_entry.c
include/grub/menu.h
include/grub/normal.h

index df1e4541d1284c79de473d654d64dab8fad76230..934e3c73a11ee97631db6f14b6045a6d07fc8459 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2010-09-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Support submenus.
+
+       * grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New
+       parameter submenu. All users updated.
+       * grub-core/normal/main.c (free_menu): Rename to ...
+       (grub_normal_free_menu): ... this. Made global.
+       * grub-core/normal/menu.c (grub_menu_execute_entry): Open new context
+       if requested.
+       * grub-core/normal/menu_entry.c (screen): New field submenu.
+       (make_screen): Set submenu.
+       (run): Open new context if requested.
+       * include/grub/menu.h (grub_menu_entry): New field submenu.
+       * include/grub/normal.h (grub_normal_free_menu): New proto.
+
 2010-09-20  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Menu entries extractor.
index d69dad75b4e1b9570a4ad54b0adb2a1fe8da2272..1b0e968c5d16216918a334a6cd8968c6ef362db6 100644 (file)
@@ -118,7 +118,7 @@ legacy_file (const char *filename)
              }
            args[0] = oldname;
            grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
-                                       entrysrc);
+                                       entrysrc, 0);
            grub_free (args);
            entrysrc[0] = 0;
            grub_free (oldname);
@@ -168,7 +168,7 @@ legacy_file (const char *filename)
          return grub_errno;
        }
       args[0] = entryname;
-      grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc);
+      grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0);
       grub_free (args);
     }
 
index f10e05dc361ff380592ded7ac23244ca88b78aa9..9718d1eab29709620277fca9e9b0e4e35a6fca3c 100644 (file)
@@ -68,9 +68,9 @@ static struct
 grub_err_t
 grub_normal_add_menu_entry (int argc, const char **args, char **classes,
                            const char *users, const char *hotkey,
-                           const char *prefix, const char *sourcecode)
+                           const char *prefix, const char *sourcecode,
+                           int submenu)
 {
-  unsigned i;
   int menu_hotkey = 0;
   char **menu_args = NULL;
   char *menu_users = NULL;
@@ -93,6 +93,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
 
   if (classes)
     {
+      int i;
       for (i = 0; classes[i]; i++); /* count # of menuentry classes */
       menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) * i);
       if (! menu_classes)
@@ -116,6 +117,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
 
   if (hotkey)
     {
+      unsigned i;
       for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++)
        if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0)
          {
@@ -141,13 +143,16 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
   if (! menu_args)
     goto fail;
 
-  for (i = 0; i < argc; i++)
-    {
-      menu_args[i] = grub_strdup (args[i]);
-      if (! menu_args[i])
-       goto fail;
-    }
-  menu_args[argc] = NULL;
+  {
+    int i;
+    for (i = 0; i < argc; i++)
+      {
+       menu_args[i] = grub_strdup (args[i]);
+       if (! menu_args[i])
+         goto fail;
+      }
+    menu_args[argc] = NULL;
+  }
 
   /* Add the menu entry at the end of the list.  */
   while (*last)
@@ -166,6 +171,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
   (*last)->argc = argc;
   (*last)->args = menu_args;
   (*last)->sourcecode = menu_sourcecode;
+  (*last)->submenu = submenu;
 
   menu->size++;
   return GRUB_ERR_NONE;
@@ -173,13 +179,19 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes,
  fail:
 
   grub_free (menu_sourcecode);
-  for (i = 0; menu_classes && menu_classes[i].name; i++)
-    grub_free (menu_classes[i].name);
-  grub_free (menu_classes);
+  {
+    int i;
+    for (i = 0; menu_classes && menu_classes[i].name; i++)
+      grub_free (menu_classes[i].name);
+    grub_free (menu_classes);
+  }
 
-  for (i = 0; menu_args && menu_args[i]; i++)
-    grub_free (menu_args[i]);
-  grub_free (menu_args);
+  {
+    int i;
+    for (i = 0; menu_args && menu_args[i]; i++)
+      grub_free (menu_args[i]);
+    grub_free (menu_args);
+  }
 
   grub_free (menu_users);
   grub_free (menu_title);
@@ -259,7 +271,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
     return grub_normal_add_menu_entry (argc, (const char **) args,
                                       ctxt->state[0].args, ctxt->state[1].arg,
                                       ctxt->state[2].arg, 0,
-                                      ctxt->state[3].arg);
+                                      ctxt->state[3].arg,
+                                      ctxt->extcmd->cmd->name[0] == 's');
 
   src = args[argc - 1];
   args[argc - 1] = NULL;
@@ -274,7 +287,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
 
   r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
                                  ctxt->state[0].args, ctxt->state[1].arg,
-                                 ctxt->state[2].arg, prefix, src + 1);
+                                 ctxt->state[2].arg, prefix, src + 1,
+                                 ctxt->extcmd->cmd->name[0] == 's');
 
   src[len - 1] = ch;
   args[argc - 1] = src;
@@ -282,7 +296,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
   return r;
 }
 
-static grub_extcmd_t cmd;
+static grub_extcmd_t cmd, cmd_sub;
 
 void
 grub_menu_init (void)
@@ -291,10 +305,16 @@ grub_menu_init (void)
                              GRUB_COMMAND_FLAG_BLOCKS
                              | GRUB_COMMAND_FLAG_EXTRACTOR,
                              N_("BLOCK"), N_("Define a menuentry."), options);
+  cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry,
+                                 GRUB_COMMAND_FLAG_BLOCKS
+                                 | GRUB_COMMAND_FLAG_EXTRACTOR,
+                                 N_("BLOCK"), N_("Define a submenu."),
+                                 options);
 }
 
 void
 grub_menu_fini (void)
 {
   grub_unregister_extcmd (cmd);
+  grub_unregister_extcmd (cmd_sub);
 }
index f2e5eaf51a6834b1562f0a3a17ca15f65079364e..3bfbbeb72c2d807cd007522beef69ce1a6c88ffb 100644 (file)
@@ -123,8 +123,8 @@ grub_file_getline (grub_file_t file)
   return cmdline;
 }
 
-static void
-free_menu (grub_menu_t menu)
+void
+grub_normal_free_menu (grub_menu_t menu)
 {
   grub_menu_entry_t entry = menu->entry_list;
 
@@ -289,7 +289,7 @@ grub_normal_execute (const char *config, int nested, int batch)
        {
          grub_show_menu (menu, nested);
          if (nested)
-           free_menu (menu);
+           grub_normal_free_menu (menu);
        }
     }
 }
index 9c0a2182f1d9ebe1ebf2ca5e3276915477b37ec4..807ad51e00b80e0637623101563d341ea79dc330 100644 (file)
@@ -159,6 +159,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
 {
   grub_err_t err = GRUB_ERR_NONE;
   int errs_before;
+  grub_menu_t menu;
 
   if (entry->restricted)
     err = grub_auth_check_authentication (entry->users);
@@ -172,6 +173,15 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
 
   errs_before = grub_err_printed_errors;
 
+  if (entry->submenu)
+    {
+      grub_env_context_open ();
+      menu = grub_zalloc (sizeof (*menu));
+      if (! menu)
+       return;
+      grub_env_set_menu (menu);
+    }
+
   grub_env_set ("chosen", entry->title);
   grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
 
@@ -181,6 +191,16 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
   if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
     /* Implicit execution of boot, only if something is loaded.  */
     grub_command_execute ("boot", 0, 0);
+
+  if (entry->submenu)
+    {
+      if (menu && menu->size)
+       {
+         grub_show_menu (menu, 1);
+         grub_normal_free_menu (menu);
+       }
+      grub_env_context_close ();
+    }
 }
 
 /* Execute ENTRY from the menu MENU, falling back to entries specified
index 82506fa6f004b437f858c19b324746479b35fa66..096600e09573061c35516e157222c1456dbb001a 100644 (file)
@@ -71,6 +71,8 @@ struct screen
   /* The flag of a completion window.  */
   int completion_shown;
 
+  int submenu;
+
   struct per_term_screen *terms;
   unsigned nterms;
 };
@@ -496,6 +498,8 @@ make_screen (grub_menu_entry_t entry)
   if (! screen)
     return 0;
 
+  screen->submenu = entry->submenu;
+
   screen->num_lines = 1;
   screen->lines = grub_malloc (sizeof (struct line));
   if (! screen->lines)
@@ -1162,6 +1166,7 @@ run (struct screen *screen)
   int currline = 0;
   char *nextline;
   int errs_before;
+  grub_menu_t menu;
 
   auto grub_err_t editor_getline (char **line, int cont);
   grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
@@ -1197,6 +1202,15 @@ run (struct screen *screen)
 
   errs_before = grub_err_printed_errors;
 
+  if (screen->submenu)
+    {
+      grub_env_context_open ();
+      menu = grub_zalloc (sizeof (*menu));
+      if (! menu)
+       return;
+      grub_env_set_menu (menu);
+    }
+
   /* Execute the script, line for line.  */
   while (currline < screen->num_lines)
     {
@@ -1212,6 +1226,16 @@ run (struct screen *screen)
     /* Implicit execution of boot, only if something is loaded.  */
     grub_command_execute ("boot", 0, 0);
 
+  if (screen->submenu)
+    {
+      if (menu && menu->size)
+       {
+         grub_show_menu (menu, 1);
+         grub_normal_free_menu (menu);
+       }
+      grub_env_context_close ();
+    }
+
   if (grub_errno != GRUB_ERR_NONE)
     {
       grub_print_error ();
index 608253863da5da8ed2845542c102cb968e25e263..5ff356beb48e6609c4ef1d1fae18c74a53b7f056 100644 (file)
@@ -53,6 +53,8 @@ struct grub_menu_entry
 
   int hotkey;
 
+  int submenu;
+
   /* The next element.  */
   struct grub_menu_entry *next;
 };
index 2fc289373ec8ed27419fe59c42d0d349d85b2e04..18756779743270a86a92328c5bf625472441b324 100644 (file)
@@ -119,11 +119,14 @@ extern int grub_extractor_level;
 grub_err_t
 grub_normal_add_menu_entry (int argc, const char **args, char **classes,
                            const char *users, const char *hotkey,
-                           const char *prefix, const char *sourcecode);
+                           const char *prefix, const char *sourcecode,
+                           int submenu);
 
 grub_err_t
 grub_normal_set_password (const char *user, const char *password);
 
+void grub_normal_free_menu (grub_menu_t menu);
+
 void grub_normal_auth_init (void);
 void grub_normal_auth_fini (void);