bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch for "more DUMB" serial support


From: Christoph Plattner
Subject: Patch for "more DUMB" serial support
Date: Sat, 12 Jan 2002 17:21:18 +0100

Hello,

here is a patch to make the dumb serial support "more dumb".
Not not only single keys pressed leads to reaction, the
user has to push <ENTER> after a command key. With this
change, the GRUB menu can also be used on cannonical terminals
(with some restrictions to the command line editing, where
I have nothing changed).

Short description:

When after booting the timeout runs, the usercan select
the highlighted (default) menu entry simple with <ENTER>.

When a user want to boot a different entry, simple use
<num><ENTER>, for example `3<ENTER>'. 

To go to command line interface, use `c<ENTER>'.

To edit menu entry 1, simple use `e1<ENTER>'.

The editing fiunctions `d', `o', `O' are also
used with argument, like `o0<ENTER>' inserts a line
after the first one.

With `u<ENTER>' the user can back to main menu (instead 
of <ESC>).

With `b<ENTER>' the user can boot the current edited boot
sequence.

The patch is quite simple. Instead of fetching only a single
character from the serial line, a small parser gets the whole
user entry, parses that, and sets `c' and eventually `entryno'
to the appropriate values. For the rest of the menu processing
this is completely transparent and therefore the code is
untouched.

Only the bey explanations below the menu have been changed for
dumb serial support.

The feature concerning the password I have not tested, but it
should work in the same way (pressing `p<ENTER>').

The command line editing is not changed. For editing lines
`emacs' is usable but not convinient. But at the moment, I
don't think, that we should change here anything. I like the
current version of the command line interface.

The seriel support without `--dumb' options is not affected
by the patch.

With friendly regards
Christoph P.


-- 
-------------------------------------------------------
private:        address@hidden
company:        address@hidden
Index: ChangeLog
===================================================================
RCS file: /cvs/grub/ChangeLog,v
retrieving revision 1.460
diff -u -r1.460 ChangeLog
--- ChangeLog   8 Jan 2002 03:19:23 -0000       1.460
+++ ChangeLog   12 Jan 2002 15:36:17 -0000
@@ -1,3 +1,9 @@
+2002-01-12  C. Plattner  <address@hidden>
+
+       * stage2/stage2.c (run_menu): added command line parser
+       for a changed DUMB terminal support menu usage under
+       `emacs' and more simple for `expect', etc.
+
 2002-01-08  Yoshinori K. Okuji  <address@hidden>
 
        * grub/main.c (use_preset_menu): New variable.
Index: stage2/stage2.c
===================================================================
RCS file: /cvs/grub/stage2/stage2.c,v
retrieving revision 1.35
diff -u -r1.35 stage2.c
--- stage2/stage2.c     8 Jan 2002 03:19:23 -0000       1.35
+++ stage2/stage2.c     12 Jan 2002 15:36:20 -0000
@@ -426,43 +426,63 @@
       
       if (terminal & TERMINAL_DUMB)
          print_entries_raw (num_entries, first_entry, menu_entries);
-
-      grub_printf ("\n\
+      else
+       grub_printf ("\n\
       Use the %c and %c keys to select which entry is highlighted.\n",
                   disp_up, disp_down);
-      
-      if (! auth && password)
+
+      if (terminal & TERMINAL_DUMB)
        {
-         printf ("\
-      Press enter to boot the selected OS or \'p\' to enter a\n\
-      password to unlock the next set of features.");
+         if (! auth && password)
+           {
+             printf ("\
+      Press \'<NUM>\' and enter to boot an OS or \'p\' and enter\n\
+      to enter a password to unlock the next set of features.");
+           }
+         else
+           {
+             if (config_entries)
+               printf ("\
+      Press \'<NUM>\' and enter to boot an OS, \'e<NUM>\' to edit\n\
+      the commands before booting, or \'c\' for a command-line.\n\n");
+             else
+               printf ("\
+      Press \'b\' to boot, \'e<NUM>' to edit the command in the\n\
+      boot sequence, \'c\' for command-line, \'o<NUM>\' to open a\n\
+      new line after (\'O<NUM>\' for before) the selected line, \n\
+      \'d<NUM>\' to remove a line or \'u\' to go back to main menu.\n");
+           }
        }
       else
        {
-         if (config_entries)
-           printf ("\
+         if (! auth && password)
+           {
+             printf ("\
+      Press enter to boot the selected OS or \'p\' to enter a\n\
+      password to unlock the next set of features.");
+           }
+         else
+           {
+             if (config_entries)
+               printf ("\
       Press enter to boot the selected OS, \'e\' to edit the\n\
       commands before booting, or \'c\' for a command-line.");
-         else
-           printf ("\
+             else
+               printf ("\
       Press \'b\' to boot, \'e\' to edit the selected command in the\n\
       boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
       after (\'O\' for before) the selected line, \'d\' to remove the\n\
       selected line, or escape to go back to the main menu.");
-       }
-
-      if (terminal & TERMINAL_DUMB)      
-       grub_printf ("\n\nThe selected entry is %d ", entryno);
-      else
-      {
+           }
+         
          print_entries (3, 12, first_entry, menu_entries);
          
          /* highlight initial line */
          set_line_highlight (4 + entryno, first_entry + entryno, 
                              menu_entries);
-      }
+       }
     }
-
+  
   /* XX using RT clock now, need to initialize value */
   while ((time1 = getrtsecs()) == 0xFF);
 
@@ -506,9 +526,193 @@
             since we're comming in here also on GRUB_TIMEOUT == -1 and
             hang in GETKEY */
          if (terminal & TERMINAL_DUMB)
-           grub_printf ("\r    Highlighted entry is %d: ", entryno);
+           grub_printf ("\n select: ");
 
-         c = translate_keycode (getkey ());
+         /* For DUMB terminal support, do complete line parsing,
+            setup the entry number and set an apporpriate 'c' */
+
+         if (! (terminal & TERMINAL_DUMB))
+           c = translate_keycode (getkey ());
+         else
+           {
+#define DUMB_BUFLEN 32
+             char dumb_buf [DUMB_BUFLEN + 1]; /* space for '\0' */
+             int dumb_pos;
+             int dumb_sel;
+             char * dumb_p;
+             int c1;
+             int spaces;
+             int dumb_abort;
+             int dumb_empty;
+             
+             /* editing function only very simple with ^H */
+             dumb_buf [0] = 0;
+             dumb_pos = 0;
+             
+             c = 0; /* ignore key */
+             do 
+               {
+                 c1 = translate_keycode (getkey ());
+                 switch (c1) 
+                   {
+                   case '\r':
+                   case '\n':
+                     dumb_buf [dumb_pos] = 0;
+                     grub_putchar ('\n');
+                     c1 = '\r';
+                     break;
+                   case '\b':
+                     if (dumb_pos > 0)
+                       {
+                         dumb_pos --;
+                         grub_printf ("\b \b");
+                       }
+                     break;
+                   default:
+                     /* check for printable characters */
+                     if ((c1 >= ' ') && (c1 < 127))
+                       {
+                         if ((dumb_pos + 1) < DUMB_BUFLEN)
+                           {
+                             dumb_buf [dumb_pos ++] = c1;
+                             grub_putchar (c1);
+                           }
+                         /* else ignore key stroke */
+                       }
+                   }
+               } while (c1 != '\r');
+             
+             /* parse the string */
+             dumb_sel = -1;
+             spaces = 0;
+             dumb_abort = 0;
+             dumb_empty = 1;
+
+             dumb_p = dumb_buf;
+             while ((* dumb_p) && (dumb_abort == 0))
+               {
+                 dumb_empty = 0;
+                 switch (* dumb_p)
+                   {
+                   case ' ':
+                     spaces = 1;
+                     break;
+                   case 'p':
+                     if ((c == 0) && (dumb_sel == -1) && (! auth && password))
+                       c = * dumb_p;
+                     else
+                       {
+                         grub_printf ("Error: invalid command\n");
+                         dumb_abort = 1;
+                       }
+                     break;
+                   case 'c':
+                   case 'e':
+                     if ((c == 0) && (dumb_sel == -1))
+                       c = * dumb_p;
+                     else
+                       {
+                         grub_printf ("Error: invalid command\n");
+                         dumb_abort = 1;
+                       }
+                     break;
+                   case 'b':
+                   case 'd':
+                   case 'o':
+                   case 'O':
+                   case 'u':
+                     if ((c == 0) && (! config_entries) && (dumb_sel == -1))
+                       c = (* dumb_p == 'u') ? 0x1b : * dumb_p;
+                     else
+                       {
+                         grub_printf ("Error: invalid command\n");
+                         dumb_abort = 1;
+                       }
+                     break;
+                   case '0':
+                   case '1':
+                   case '2':
+                   case '3':
+                   case '4':
+                   case '5':
+                   case '6':
+                   case '7':
+                   case '8':
+                   case '9':
+                     if (spaces && (dumb_sel != -1))
+                       {
+                         grub_printf ("Error: too many arguments\n");
+                         dumb_abort = 1;
+                       }
+                     else
+                       {
+                         if (dumb_sel == -1)
+                           dumb_sel = (* dumb_p) - '0';
+                         else
+                           dumb_sel = (dumb_sel * 10) + ((* dumb_p) - '0');
+                         spaces = 0;
+                       }
+                     break;
+                   default:
+                     grub_printf ("Error: invalid command\n");
+                     dumb_abort = 1;
+                     break;
+                   }
+                 dumb_p ++;
+               }
+             
+             if (dumb_abort)
+               c = 0;
+             else
+               {
+                 if (dumb_sel == -1)
+                   {
+                     /* for the commands e,d,o,O the selection number is
+                        mandatory */
+                     if ((c == 'e') || (c == 'd') || (c == 'o') || (c == 'O'))
+                       {
+                         grub_printf ("Error: Selection number must "
+                                      "be given\n");
+                         c = 0;
+                       }
+                     /* check if we have an empty input string, then
+                        the default selection is done, if timeout is
+                        not expired, otherwise ignore command */
+                     if ((dumb_empty) && (grub_timeout >= 0))
+                       {
+                         grub_printf ("  selected was %d\n", entryno);
+                         c = '\r';
+                       }
+                   }
+                 else
+                   {
+                     /* check if commands take a parameter */
+                     if ((c == 'c') || (c == 0x1b) || 
+                         (c == 'p') || (c == 'b'))
+                       {
+                         grub_printf ("Error: too many arguments\n");
+                         c = 0;
+                       }
+                     else
+                       {
+                         if (dumb_sel >= num_entries)
+                           {
+                             grub_printf ("Error: Selection number %d "
+                                          "invalid\n", dumb_sel);
+                             c = 0;
+                           }
+                         else
+                           {
+                             entryno = dumb_sel;
+                             /* if user has not given any command letter,
+                                we assume a simple selection, c -> '\n' */
+                             if (c == 0)
+                               c = '\n';
+                           }
+                       }
+                   }
+               }
+           }
 
          if (grub_timeout >= 0)
            {

reply via email to

[Prev in Thread] Current Thread [Next in Thread]