Run Nindent on com32/menu/menumain.c
authorH. Peter Anvin <hpa@zytor.com>
Fri, 29 May 2009 22:10:28 +0000 (15:10 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 29 May 2009 22:10:28 +0000 (15:10 -0700)
Automatically reformat com32/menu/menumain.c using Nindent.

Do this for all files except HDT, gPXE and externally maintained
libraries (zlib, tinyjpeg, libpng).

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
com32/menu/menumain.c

index 81780ea..b86e9b4 100644 (file)
 static struct menu *cm;
 
 const struct menu_parameter mparm[NPARAMS] = {
-  [P_WIDTH]            = { "width", 0 },
-  [P_MARGIN]           = { "margin", 10 },
-  [P_PASSWD_MARGIN]    = { "passwordmargin", 3 },
-  [P_MENU_ROWS]                = { "rows", 12 },
-  [P_TABMSG_ROW]       = { "tabmsgrow", 18 },
-  [P_CMDLINE_ROW]      = { "cmdlinerow", 18 },
-  [P_END_ROW]          = { "endrow", -1 },
-  [P_PASSWD_ROW]       = { "passwordrow", 11 },
-  [P_TIMEOUT_ROW]      = { "timeoutrow", 20 },
-  [P_HELPMSG_ROW]      = { "helpmsgrow", 22 },
-  [P_HELPMSGEND_ROW]   = { "helpmsgendrow", -1 },
-  [P_HSHIFT]           = { "hshift", 0 },
-  [P_VSHIFT]           = { "vshift", 0 },
-  [P_HIDDEN_ROW]       = { "hiddenrow", -2 },
+    [P_WIDTH] = {"width", 0},
+    [P_MARGIN] = {"margin", 10},
+    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
+    [P_MENU_ROWS] = {"rows", 12},
+    [P_TABMSG_ROW] = {"tabmsgrow", 18},
+    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
+    [P_END_ROW] = {"endrow", -1},
+    [P_PASSWD_ROW] = {"passwordrow", 11},
+    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
+    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
+    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
+    [P_HSHIFT] = {"hshift", 0},
+    [P_VSHIFT] = {"vshift", 0},
+    [P_HIDDEN_ROW] = {"hiddenrow", -2},
 };
 
 /* These macros assume "cm" is a pointer to the current menu */
@@ -68,25 +68,24 @@ const struct menu_parameter mparm[NPARAMS] = {
 #define VSHIFT         (cm->mparm[P_VSHIFT])
 #define HIDDEN_ROW     (cm->mparm[P_HIDDEN_ROW])
 
-static char *
-pad_line(const char *text, int align, int width)
+static char *pad_line(const char *text, int align, int width)
 {
-  static char buffer[MAX_CMDLINE_LEN];
-  int n, p;
+    static char buffer[MAX_CMDLINE_LEN];
+    int n, p;
 
-  if ( width >= (int) sizeof buffer )
-    return NULL;               /* Can't do it */
+    if (width >= (int)sizeof buffer)
+       return NULL;            /* Can't do it */
 
-  n = strlen(text);
-  if ( n >= width )
-    n = width;
+    n = strlen(text);
+    if (n >= width)
+       n = width;
 
-  memset(buffer, ' ', width);
-  buffer[width] = 0;
-  p = ((width-n)*align)>>1;
-  memcpy(buffer+p, text, n);
+    memset(buffer, ' ', width);
+    buffer[width] = 0;
+    p = ((width - n) * align) >> 1;
+    memcpy(buffer + p, text, n);
 
-  return buffer;
+    return buffer;
 }
 
 /* Display an entry, with possible hotkey highlight.  Assumes
@@ -96,999 +95,1026 @@ static void
 display_entry(const struct menu_entry *entry, const char *attrib,
              const char *hotattrib, int width)
 {
-  const char *p = entry->displayname;
-  char marker;
-
-  if (!p)
-    p = "";
-
-  switch (entry->action) {
-  case MA_SUBMENU:
-    marker = '>';
-    break;
-  case MA_EXIT:
-    marker = '<';
-    break;
-  default:
-    marker = 0;
-    break;
-  }
-
-  if (marker)
-    width -= 2;
-
-  while ( width ) {
-    if ( *p ) {
-      if ( *p == '^' ) {
-       p++;
-       if ( *p && ((unsigned char)*p & ~0x20) == entry->hotkey ) {
-         fputs(hotattrib, stdout);
-         putchar(*p++);
-         fputs(attrib, stdout);
-         width--;
+    const char *p = entry->displayname;
+    char marker;
+
+    if (!p)
+       p = "";
+
+    switch (entry->action) {
+    case MA_SUBMENU:
+       marker = '>';
+       break;
+    case MA_EXIT:
+       marker = '<';
+       break;
+    default:
+       marker = 0;
+       break;
+    }
+
+    if (marker)
+       width -= 2;
+
+    while (width) {
+       if (*p) {
+           if (*p == '^') {
+               p++;
+               if (*p && ((unsigned char)*p & ~0x20) == entry->hotkey) {
+                   fputs(hotattrib, stdout);
+                   putchar(*p++);
+                   fputs(attrib, stdout);
+                   width--;
+               }
+           } else {
+               putchar(*p++);
+               width--;
+           }
+       } else {
+           putchar(' ');
+           width--;
        }
-      } else {
-       putchar(*p++);
-       width--;
-      }
-    } else {
-      putchar(' ');
-      width--;
     }
-  }
 
-  if (marker) {
-    putchar(' ');
-    putchar(marker);
-  }
+    if (marker) {
+       putchar(' ');
+       putchar(marker);
+    }
 }
 
-static void
-draw_row(int y, int sel, int top, int sbtop, int sbbot)
+static void draw_row(int y, int sel, int top, int sbtop, int sbbot)
 {
-  int i = (y-4-VSHIFT)+top;
-  int dis = (i < cm->nentries) && is_disabled(cm->menu_entries[i]);
-
-  printf("\033[%d;%dH\1#1\016x\017%s ",
-        y, MARGIN+1+HSHIFT,
-        (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3");
-
-  if ( i >= cm->nentries ) {
-    fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout);
-  } else {
-    display_entry(cm->menu_entries[i],
-                 (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3",
-                 (i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4",
-                 WIDTH-2*MARGIN-4);
-  }
-
-  if ( cm->nentries <= MENU_ROWS ) {
-    printf(" \1#1\016x\017");
-  } else if ( sbtop > 0 ) {
-    if ( y >= sbtop && y <= sbbot )
-      printf(" \1#7\016a\017");
-    else
-      printf(" \1#1\016x\017");
-  } else {
-    putchar(' ');              /* Don't modify the scrollbar */
-  }
+    int i = (y - 4 - VSHIFT) + top;
+    int dis = (i < cm->nentries) && is_disabled(cm->menu_entries[i]);
+
+    printf("\033[%d;%dH\1#1\016x\017%s ",
+          y, MARGIN + 1 + HSHIFT,
+          (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3");
+
+    if (i >= cm->nentries) {
+       fputs(pad_line("", 0, WIDTH - 2 * MARGIN - 4), stdout);
+    } else {
+       display_entry(cm->menu_entries[i],
+                     (i == sel) ? "\1#5" : dis ? "\2#17" : "\1#3",
+                     (i == sel) ? "\1#6" : dis ? "\2#17" : "\1#4",
+                     WIDTH - 2 * MARGIN - 4);
+    }
+
+    if (cm->nentries <= MENU_ROWS) {
+       printf(" \1#1\016x\017");
+    } else if (sbtop > 0) {
+       if (y >= sbtop && y <= sbbot)
+           printf(" \1#7\016a\017");
+       else
+           printf(" \1#1\016x\017");
+    } else {
+       putchar(' ');           /* Don't modify the scrollbar */
+    }
 }
 
 static jmp_buf timeout_jump;
 
 int mygetkey(clock_t timeout)
 {
-  clock_t t0, t;
-  clock_t tto, to;
-  int key;
+    clock_t t0, t;
+    clock_t tto, to;
+    int key;
 
-  if ( !totaltimeout )
-    return get_key(stdin, timeout);
+    if (!totaltimeout)
+       return get_key(stdin, timeout);
 
-  for (;;) {
-    tto = min(totaltimeout, INT_MAX);
-    to = timeout ? min(tto, timeout) : tto;
+    for (;;) {
+       tto = min(totaltimeout, INT_MAX);
+       to = timeout ? min(tto, timeout) : tto;
 
-    t0 = times(NULL);
-    key = get_key(stdin, to);
-    t = times(NULL) - t0;
+       t0 = times(NULL);
+       key = get_key(stdin, to);
+       t = times(NULL) - t0;
 
-    if ( totaltimeout <= t )
-      longjmp(timeout_jump, 1);
+       if (totaltimeout <= t)
+           longjmp(timeout_jump, 1);
 
-    totaltimeout -= t;
+       totaltimeout -= t;
 
-    if ( key != KEY_NONE )
-      return key;
+       if (key != KEY_NONE)
+           return key;
 
-    if ( timeout ) {
-      if ( timeout <= t )
-       return KEY_NONE;
+       if (timeout) {
+           if (timeout <= t)
+               return KEY_NONE;
 
-      timeout -= t;
+           timeout -= t;
+       }
     }
-  }
 }
 
-static int
-ask_passwd(const char *menu_entry)
+static int ask_passwd(const char *menu_entry)
 {
-  char user_passwd[WIDTH], *p;
-  int done;
-  int key;
-  int x;
-  int rv;
-
-  printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN+1);
-  for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ )
-    putchar('q');
-
-  printf("k\033[%d;%dHx", PASSWD_ROW+1, PASSWD_MARGIN+1);
-  for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ )
-    putchar(' ');
-
-  printf("x\033[%d;%dHm", PASSWD_ROW+2, PASSWD_MARGIN+1);
-  for ( x = 2 ; x <= WIDTH-2*PASSWD_MARGIN-1 ; x++ )
-    putchar('q');
-
-  printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13",
-        PASSWD_ROW, (WIDTH-(strlen(cm->messages[MSG_PASSPROMPT])+2))/2,
-        cm->messages[MSG_PASSPROMPT], PASSWD_ROW+1, PASSWD_MARGIN+3);
-
-  drain_keyboard();
-
-  /* Actually allow user to type a password, then compare to the SHA1 */
-  done = 0;
-  p = user_passwd;
-
-  while ( !done ) {
-    key = mygetkey(0);
-
-    switch ( key ) {
-    case KEY_ENTER:
-    case KEY_CTRL('J'):
-      done = 1;
-      break;
-
-    case KEY_ESC:
-    case KEY_CTRL('C'):
-      p = user_passwd;         /* No password entered */
-      done = 1;
-      break;
-
-    case KEY_BACKSPACE:
-    case KEY_DEL:
-    case KEY_DELETE:
-      if ( p > user_passwd ) {
-       printf("\b \b");
-       p--;
-      }
-      break;
-
-    case KEY_CTRL('U'):
-      while ( p > user_passwd ) {
-       printf("\b \b");
-       p--;
-      }
-      break;
+    char user_passwd[WIDTH], *p;
+    int done;
+    int key;
+    int x;
+    int rv;
+
+    printf("\033[%d;%dH\2#11\016l", PASSWD_ROW, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+       putchar('q');
+
+    printf("k\033[%d;%dHx", PASSWD_ROW + 1, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+       putchar(' ');
+
+    printf("x\033[%d;%dHm", PASSWD_ROW + 2, PASSWD_MARGIN + 1);
+    for (x = 2; x <= WIDTH - 2 * PASSWD_MARGIN - 1; x++)
+       putchar('q');
+
+    printf("j\017\033[%d;%dH\2#12 %s \033[%d;%dH\2#13",
+          PASSWD_ROW, (WIDTH - (strlen(cm->messages[MSG_PASSPROMPT]) + 2)) / 2,
+          cm->messages[MSG_PASSPROMPT], PASSWD_ROW + 1, PASSWD_MARGIN + 3);
+
+    drain_keyboard();
+
+    /* Actually allow user to type a password, then compare to the SHA1 */
+    done = 0;
+    p = user_passwd;
+
+    while (!done) {
+       key = mygetkey(0);
+
+       switch (key) {
+       case KEY_ENTER:
+       case KEY_CTRL('J'):
+           done = 1;
+           break;
+
+       case KEY_ESC:
+       case KEY_CTRL('C'):
+           p = user_passwd;    /* No password entered */
+           done = 1;
+           break;
+
+       case KEY_BACKSPACE:
+       case KEY_DEL:
+       case KEY_DELETE:
+           if (p > user_passwd) {
+               printf("\b \b");
+               p--;
+           }
+           break;
+
+       case KEY_CTRL('U'):
+           while (p > user_passwd) {
+               printf("\b \b");
+               p--;
+           }
+           break;
 
-    default:
-      if ( key >= ' ' && key <= 0xFF &&
-          (p-user_passwd) < WIDTH-2*PASSWD_MARGIN-5 ) {
-       *p++ = key;
-       putchar('*');
-      }
-      break;
+       default:
+           if (key >= ' ' && key <= 0xFF &&
+               (p - user_passwd) < WIDTH - 2 * PASSWD_MARGIN - 5) {
+               *p++ = key;
+               putchar('*');
+           }
+           break;
+       }
     }
-  }
 
-  if ( p == user_passwd )
-    return 0;                  /* No password entered */
+    if (p == user_passwd)
+       return 0;               /* No password entered */
 
-  *p = '\0';
+    *p = '\0';
 
-  rv = (cm->menu_master_passwd &&
-       passwd_compare(cm->menu_master_passwd, user_passwd))
-    || (menu_entry && passwd_compare(menu_entry, user_passwd));
+    rv = (cm->menu_master_passwd &&
+         passwd_compare(cm->menu_master_passwd, user_passwd))
+       || (menu_entry && passwd_compare(menu_entry, user_passwd));
 
-  /* Clean up */
-  memset(user_passwd, 0, WIDTH);
-  drain_keyboard();
+    /* Clean up */
+    memset(user_passwd, 0, WIDTH);
+    drain_keyboard();
 
-  return rv;
+    return rv;
 }
 
-
-static void
-draw_menu(int sel, int top, int edit_line)
+static void draw_menu(int sel, int top, int edit_line)
 {
-  int x, y;
-  int sbtop = 0, sbbot = 0;
-  const char *tabmsg;
-  int tabmsg_len;
-
-  if ( cm->nentries > MENU_ROWS ) {
-    int sblen = max(MENU_ROWS*MENU_ROWS/cm->nentries, 1);
-    sbtop = (MENU_ROWS-sblen+1)*top/(cm->nentries-MENU_ROWS+1);
-    sbbot = sbtop+sblen-1;
-    sbtop += 4;  sbbot += 4;   /* Starting row of scrollbar */
-  }
-
-  printf("\033[%d;%dH\1#1\016l", VSHIFT+1, HSHIFT+MARGIN+1);
-  for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ )
-    putchar('q');
-
-  printf("k\033[%d;%dH\1#1x\017\1#2 %s \1#1\016x",
-        VSHIFT+2,
-        HSHIFT+MARGIN+1,
-        pad_line(cm->title, 1, WIDTH-2*MARGIN-4));
-
-  printf("\033[%d;%dH\1#1t", VSHIFT+3, HSHIFT+MARGIN+1);
-  for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ )
-    putchar('q');
-  fputs("u\017", stdout);
-
-  for ( y = 4+VSHIFT ; y < 4+VSHIFT+MENU_ROWS ; y++ )
-    draw_row(y, sel, top, sbtop, sbbot);
-
-  printf("\033[%d;%dH\1#1\016m", y, HSHIFT+MARGIN+1);
-  for ( x = 2+HSHIFT ; x <= (WIDTH-2*MARGIN-1)+HSHIFT ; x++ )
-    putchar('q');
-  fputs("j\017", stdout);
-
-  if ( edit_line && cm->allowedit && !cm->menu_master_passwd )
-    tabmsg = cm->messages[MSG_TAB];
-  else
-    tabmsg = cm->messages[MSG_NOTAB];
-
-  tabmsg_len = strlen(tabmsg);
-
-  printf("\1#8\033[%d;%dH%s",
-        TABMSG_ROW, 1+HSHIFT+((WIDTH-tabmsg_len)>>1), tabmsg);
-  printf("\1#0\033[%d;1H", END_ROW);
+    int x, y;
+    int sbtop = 0, sbbot = 0;
+    const char *tabmsg;
+    int tabmsg_len;
+
+    if (cm->nentries > MENU_ROWS) {
+       int sblen = max(MENU_ROWS * MENU_ROWS / cm->nentries, 1);
+       sbtop = (MENU_ROWS - sblen + 1) * top / (cm->nentries - MENU_ROWS + 1);
+       sbbot = sbtop + sblen - 1;
+       sbtop += 4;
+       sbbot += 4;             /* Starting row of scrollbar */
+    }
+
+    printf("\033[%d;%dH\1#1\016l", VSHIFT + 1, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+       putchar('q');
+
+    printf("k\033[%d;%dH\1#1x\017\1#2 %s \1#1\016x",
+          VSHIFT + 2,
+          HSHIFT + MARGIN + 1, pad_line(cm->title, 1, WIDTH - 2 * MARGIN - 4));
+
+    printf("\033[%d;%dH\1#1t", VSHIFT + 3, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+       putchar('q');
+    fputs("u\017", stdout);
+
+    for (y = 4 + VSHIFT; y < 4 + VSHIFT + MENU_ROWS; y++)
+       draw_row(y, sel, top, sbtop, sbbot);
+
+    printf("\033[%d;%dH\1#1\016m", y, HSHIFT + MARGIN + 1);
+    for (x = 2 + HSHIFT; x <= (WIDTH - 2 * MARGIN - 1) + HSHIFT; x++)
+       putchar('q');
+    fputs("j\017", stdout);
+
+    if (edit_line && cm->allowedit && !cm->menu_master_passwd)
+       tabmsg = cm->messages[MSG_TAB];
+    else
+       tabmsg = cm->messages[MSG_NOTAB];
+
+    tabmsg_len = strlen(tabmsg);
+
+    printf("\1#8\033[%d;%dH%s",
+          TABMSG_ROW, 1 + HSHIFT + ((WIDTH - tabmsg_len) >> 1), tabmsg);
+    printf("\1#0\033[%d;1H", END_ROW);
 }
 
-static void
-clear_screen(void)
+static void clear_screen(void)
 {
-  fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+    fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
 }
 
-static void
-display_help(const char *text)
+static void display_help(const char *text)
 {
-  int row;
-  const char *p;
-
-  if (!text) {
-    text = "";
-    printf("\1#0\033[%d;1H", HELPMSG_ROW);
-  } else {
-    printf("\2#16\033[%d;1H", HELPMSG_ROW);
-  }
-
-  for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) {
-    switch (*p) {
-    case '\r':
-    case '\f':
-    case '\v':
-    case '\033':
-      break;
-    case '\n':
-      printf("\033[K\033[%d;1H", ++row);
-      break;
-    default:
-      putchar(*p);
+    int row;
+    const char *p;
+
+    if (!text) {
+       text = "";
+       printf("\1#0\033[%d;1H", HELPMSG_ROW);
+    } else {
+       printf("\2#16\033[%d;1H", HELPMSG_ROW);
     }
-  }
 
-  fputs("\033[K", stdout);
+    for (p = text, row = HELPMSG_ROW; *p && row <= HELPMSGEND_ROW; p++) {
+       switch (*p) {
+       case '\r':
+       case '\f':
+       case '\v':
+       case '\033':
+           break;
+       case '\n':
+           printf("\033[K\033[%d;1H", ++row);
+           break;
+       default:
+           putchar(*p);
+       }
+    }
 
-  while (row <= HELPMSGEND_ROW) {
-    printf("\033[K\033[%d;1H", ++row);
-  }
+    fputs("\033[K", stdout);
+
+    while (row <= HELPMSGEND_ROW) {
+       printf("\033[K\033[%d;1H", ++row);
+    }
 }
 
 static void show_fkey(int key)
 {
-  int fkey;
-
-  while (1) {
-    switch (key) {
-    case KEY_F1:  fkey =  0;  break;
-    case KEY_F2:  fkey =  1;  break;
-    case KEY_F3:  fkey =  2;  break;
-    case KEY_F4:  fkey =  3;  break;
-    case KEY_F5:  fkey =  4;  break;
-    case KEY_F6:  fkey =  5;  break;
-    case KEY_F7:  fkey =  6;  break;
-    case KEY_F8:  fkey =  7;  break;
-    case KEY_F9:  fkey =  8;  break;
-    case KEY_F10: fkey =  9;  break;
-    case KEY_F11: fkey = 10;  break;
-    case KEY_F12: fkey = 11;  break;
-    default: fkey = -1; break;
-    }
+    int fkey;
+
+    while (1) {
+       switch (key) {
+       case KEY_F1:
+           fkey = 0;
+           break;
+       case KEY_F2:
+           fkey = 1;
+           break;
+       case KEY_F3:
+           fkey = 2;
+           break;
+       case KEY_F4:
+           fkey = 3;
+           break;
+       case KEY_F5:
+           fkey = 4;
+           break;
+       case KEY_F6:
+           fkey = 5;
+           break;
+       case KEY_F7:
+           fkey = 6;
+           break;
+       case KEY_F8:
+           fkey = 7;
+           break;
+       case KEY_F9:
+           fkey = 8;
+           break;
+       case KEY_F10:
+           fkey = 9;
+           break;
+       case KEY_F11:
+           fkey = 10;
+           break;
+       case KEY_F12:
+           fkey = 11;
+           break;
+       default:
+           fkey = -1;
+           break;
+       }
 
-    if (fkey == -1)
-      break;
+       if (fkey == -1)
+           break;
 
-    if (cm->fkeyhelp[fkey].textname)
-      key = show_message_file(cm->fkeyhelp[fkey].textname,
-                             cm->fkeyhelp[fkey].background);
-    else
-      break;
-  }
+       if (cm->fkeyhelp[fkey].textname)
+           key = show_message_file(cm->fkeyhelp[fkey].textname,
+                                   cm->fkeyhelp[fkey].background);
+       else
+           break;
+    }
 }
 
-static const char *
-edit_cmdline(const char *input, int top)
+static const char *edit_cmdline(const char *input, int top)
 {
-  static char cmdline[MAX_CMDLINE_LEN];
-  int key, len, prev_len, cursor;
-  int redraw = 1;              /* We enter with the menu already drawn */
-
-  strncpy(cmdline, input, MAX_CMDLINE_LEN);
-  cmdline[MAX_CMDLINE_LEN-1] = '\0';
-
-  len = cursor = strlen(cmdline);
-  prev_len = 0;
-
-  for (;;) {
-    if ( redraw > 1 ) {
-      /* Clear and redraw whole screen */
-      /* Enable ASCII on G0 and DEC VT on G1; do it in this order
-        to avoid confusing the Linux console */
-      clear_screen();
-      draw_menu(-1, top, 1);
-      prev_len = 0;
-    }
+    static char cmdline[MAX_CMDLINE_LEN];
+    int key, len, prev_len, cursor;
+    int redraw = 1;            /* We enter with the menu already drawn */
+
+    strncpy(cmdline, input, MAX_CMDLINE_LEN);
+    cmdline[MAX_CMDLINE_LEN - 1] = '\0';
+
+    len = cursor = strlen(cmdline);
+    prev_len = 0;
+
+    for (;;) {
+       if (redraw > 1) {
+           /* Clear and redraw whole screen */
+           /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+              to avoid confusing the Linux console */
+           clear_screen();
+           draw_menu(-1, top, 1);
+           prev_len = 0;
+       }
 
-    if ( redraw > 0 ) {
-      /* Redraw the command line */
-      printf("\033[?25l\033[%d;1H\1#9> \2#10%s",
-            CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len)));
-      printf("\2#10\033[%d;3H%s\033[?25h",
-            CMDLINE_ROW, pad_line(cmdline, 0, cursor));
-      prev_len = len;
-      redraw = 0;
-    }
+       if (redraw > 0) {
+           /* Redraw the command line */
+           printf("\033[?25l\033[%d;1H\1#9> \2#10%s",
+                  CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len)));
+           printf("\2#10\033[%d;3H%s\033[?25h",
+                  CMDLINE_ROW, pad_line(cmdline, 0, cursor));
+           prev_len = len;
+           redraw = 0;
+       }
 
-    key = mygetkey(0);
-
-    switch( key ) {
-    case KEY_CTRL('L'):
-      redraw = 2;
-      break;
-
-    case KEY_ENTER:
-    case KEY_CTRL('J'):
-      return cmdline;
-
-    case KEY_ESC:
-    case KEY_CTRL('C'):
-      return NULL;
-
-    case KEY_BACKSPACE:
-    case KEY_DEL:
-      if ( cursor ) {
-       memmove(cmdline+cursor-1, cmdline+cursor, len-cursor+1);
-       len--;
-       cursor--;
-       redraw = 1;
-      }
-      break;
-
-    case KEY_CTRL('D'):
-    case KEY_DELETE:
-      if ( cursor < len ) {
-       memmove(cmdline+cursor, cmdline+cursor+1, len-cursor);
-       len--;
-       redraw = 1;
-      }
-      break;
-
-    case KEY_CTRL('U'):
-      if ( len ) {
-       len = cursor = 0;
-       cmdline[len] = '\0';
-       redraw = 1;
-      }
-      break;
-
-    case KEY_CTRL('W'):
-      if ( cursor ) {
-       int prevcursor = cursor;
-
-       while ( cursor && my_isspace(cmdline[cursor-1]) )
-         cursor--;
-
-       while ( cursor && !my_isspace(cmdline[cursor-1]) )
-         cursor--;
-
-       memmove(cmdline+cursor, cmdline+prevcursor, len-prevcursor+1);
-       len -= (cursor-prevcursor);
-       redraw = 1;
-      }
-      break;
-
-    case KEY_LEFT:
-    case KEY_CTRL('B'):
-      if ( cursor ) {
-       cursor--;
-       redraw = 1;
-      }
-      break;
-
-    case KEY_RIGHT:
-    case KEY_CTRL('F'):
-      if ( cursor < len ) {
-       putchar(cmdline[cursor++]);
-      }
-      break;
-
-    case KEY_CTRL('K'):
-      if ( cursor < len ) {
-       cmdline[len = cursor] = '\0';
-       redraw = 1;
-      }
-      break;
-
-    case KEY_HOME:
-    case KEY_CTRL('A'):
-      if ( cursor ) {
-       cursor = 0;
-       redraw = 1;
-      }
-      break;
-
-    case KEY_END:
-    case KEY_CTRL('E'):
-      if ( cursor != len ) {
-       cursor = len;
-       redraw = 1;
-      }
-      break;
-
-    case KEY_F1:
-    case KEY_F2:
-    case KEY_F3:
-    case KEY_F4:
-    case KEY_F5:
-    case KEY_F6:
-    case KEY_F7:
-    case KEY_F8:
-    case KEY_F9:
-    case KEY_F10:
-    case KEY_F11:
-    case KEY_F12:
-      show_fkey(key);
-      redraw = 1;
-      break;
+       key = mygetkey(0);
+
+       switch (key) {
+       case KEY_CTRL('L'):
+           redraw = 2;
+           break;
+
+       case KEY_ENTER:
+       case KEY_CTRL('J'):
+           return cmdline;
+
+       case KEY_ESC:
+       case KEY_CTRL('C'):
+           return NULL;
+
+       case KEY_BACKSPACE:
+       case KEY_DEL:
+           if (cursor) {
+               memmove(cmdline + cursor - 1, cmdline + cursor,
+                       len - cursor + 1);
+               len--;
+               cursor--;
+               redraw = 1;
+           }
+           break;
+
+       case KEY_CTRL('D'):
+       case KEY_DELETE:
+           if (cursor < len) {
+               memmove(cmdline + cursor, cmdline + cursor + 1, len - cursor);
+               len--;
+               redraw = 1;
+           }
+           break;
+
+       case KEY_CTRL('U'):
+           if (len) {
+               len = cursor = 0;
+               cmdline[len] = '\0';
+               redraw = 1;
+           }
+           break;
+
+       case KEY_CTRL('W'):
+           if (cursor) {
+               int prevcursor = cursor;
+
+               while (cursor && my_isspace(cmdline[cursor - 1]))
+                   cursor--;
+
+               while (cursor && !my_isspace(cmdline[cursor - 1]))
+                   cursor--;
+
+               memmove(cmdline + cursor, cmdline + prevcursor,
+                       len - prevcursor + 1);
+               len -= (cursor - prevcursor);
+               redraw = 1;
+           }
+           break;
+
+       case KEY_LEFT:
+       case KEY_CTRL('B'):
+           if (cursor) {
+               cursor--;
+               redraw = 1;
+           }
+           break;
+
+       case KEY_RIGHT:
+       case KEY_CTRL('F'):
+           if (cursor < len) {
+               putchar(cmdline[cursor++]);
+           }
+           break;
+
+       case KEY_CTRL('K'):
+           if (cursor < len) {
+               cmdline[len = cursor] = '\0';
+               redraw = 1;
+           }
+           break;
+
+       case KEY_HOME:
+       case KEY_CTRL('A'):
+           if (cursor) {
+               cursor = 0;
+               redraw = 1;
+           }
+           break;
+
+       case KEY_END:
+       case KEY_CTRL('E'):
+           if (cursor != len) {
+               cursor = len;
+               redraw = 1;
+           }
+           break;
+
+       case KEY_F1:
+       case KEY_F2:
+       case KEY_F3:
+       case KEY_F4:
+       case KEY_F5:
+       case KEY_F6:
+       case KEY_F7:
+       case KEY_F8:
+       case KEY_F9:
+       case KEY_F10:
+       case KEY_F11:
+       case KEY_F12:
+           show_fkey(key);
+           redraw = 1;
+           break;
 
-    default:
-      if ( key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN-1 ) {
-       if ( cursor == len ) {
-         cmdline[len] = key;
-         cmdline[++len] = '\0';
-         cursor++;
-         putchar(key);
-         prev_len++;
-       } else {
-         memmove(cmdline+cursor+1, cmdline+cursor, len-cursor+1);
-         cmdline[cursor++] = key;
-         len++;
-         redraw = 1;
+       default:
+           if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
+               if (cursor == len) {
+                   cmdline[len] = key;
+                   cmdline[++len] = '\0';
+                   cursor++;
+                   putchar(key);
+                   prev_len++;
+               } else {
+                   memmove(cmdline + cursor + 1, cmdline + cursor,
+                           len - cursor + 1);
+                   cmdline[cursor++] = key;
+                   len++;
+                   redraw = 1;
+               }
+           }
+           break;
        }
-      }
-      break;
     }
-  }
 }
 
-static inline int
-shift_is_held(void)
+static inline int shift_is_held(void)
 {
-  uint8_t shift_bits = *(uint8_t *)0x417;
+    uint8_t shift_bits = *(uint8_t *) 0x417;
 
-  return !!(shift_bits & 0x5d);        /* Caps/Scroll/Alt/Shift */
+    return !!(shift_bits & 0x5d);      /* Caps/Scroll/Alt/Shift */
 }
 
-static void
-print_timeout_message(int tol, int row, const char *msg)
+static void print_timeout_message(int tol, int row, const char *msg)
 {
-  char buf[256];
-  int nc = 0, nnc;
-  const char *tp = msg;
-  char tc;
-  char *tq = buf;
-
-  while ((size_t)(tq-buf) < (sizeof buf-16) && (tc = *tp)) {
-    tp++;
-    if (tc == '#') {
-      nnc = sprintf(tq, "\2#15%d\2#14", tol);
-      tq += nnc;
-      nc += nnc-8;             /* 8 formatting characters */
-    } else if (tc == '{') {
-      /* Deal with {singular[,dual],plural} constructs */
-      struct {
-       const char *s, *e;
-      } tx[3];
-      const char *tpp;
-      int n = 0;
-
-      memset(tx, 0, sizeof tx);
-
-      tx[0].s = tp;
-
-      while (*tp && *tp != '}') {
-       if (*tp == ',' && n < 2) {
-         tx[n].e = tp;
-         n++;
-         tx[n].s = tp+1;
-       }
+    char buf[256];
+    int nc = 0, nnc;
+    const char *tp = msg;
+    char tc;
+    char *tq = buf;
+
+    while ((size_t) (tq - buf) < (sizeof buf - 16) && (tc = *tp)) {
        tp++;
-      }
-      tx[n].e = tp;
-
-      if (*tp)
-       tp++;                   /* Skip final bracket */
-
-      if (!tx[1].s)
-       tx[1] = tx[0];
-      if (!tx[2].s)
-       tx[2] = tx[1];
-
-      /* Now [0] is singular, [1] is dual, and [2] is plural,
-        even if the user only specified some of them. */
-
-      switch (tol) {
-      case 1: n = 0; break;
-      case 2: n = 1; break;
-      default: n = 2; break;
-      }
-
-      for (tpp = tx[n].s; tpp < tx[n].e; tpp++) {
-       if ((size_t)(tq-buf) < (sizeof buf)) {
-         *tq++ = *tpp;
-         nc++;
+       if (tc == '#') {
+           nnc = sprintf(tq, "\2#15%d\2#14", tol);
+           tq += nnc;
+           nc += nnc - 8;      /* 8 formatting characters */
+       } else if (tc == '{') {
+           /* Deal with {singular[,dual],plural} constructs */
+           struct {
+               const char *s, *e;
+           } tx[3];
+           const char *tpp;
+           int n = 0;
+
+           memset(tx, 0, sizeof tx);
+
+           tx[0].s = tp;
+
+           while (*tp && *tp != '}') {
+               if (*tp == ',' && n < 2) {
+                   tx[n].e = tp;
+                   n++;
+                   tx[n].s = tp + 1;
+               }
+               tp++;
+           }
+           tx[n].e = tp;
+
+           if (*tp)
+               tp++;           /* Skip final bracket */
+
+           if (!tx[1].s)
+               tx[1] = tx[0];
+           if (!tx[2].s)
+               tx[2] = tx[1];
+
+           /* Now [0] is singular, [1] is dual, and [2] is plural,
+              even if the user only specified some of them. */
+
+           switch (tol) {
+           case 1:
+               n = 0;
+               break;
+           case 2:
+               n = 1;
+               break;
+           default:
+               n = 2;
+               break;
+           }
+
+           for (tpp = tx[n].s; tpp < tx[n].e; tpp++) {
+               if ((size_t) (tq - buf) < (sizeof buf)) {
+                   *tq++ = *tpp;
+                   nc++;
+               }
+           }
+       } else {
+           *tq++ = tc;
+           nc++;
        }
-      }
-    } else {
-      *tq++ = tc;
-      nc++;
     }
-  }
-  *tq = '\0';
+    *tq = '\0';
 
-  /* Let's hope 4 spaces on each side is enough... */
-  printf("\033[%d;%dH\2#14    %s    ", row, HSHIFT+1+((WIDTH-nc-8)>>1), buf);
+    /* Let's hope 4 spaces on each side is enough... */
+    printf("\033[%d;%dH\2#14    %s    ", row,
+          HSHIFT + 1 + ((WIDTH - nc - 8) >> 1), buf);
 }
 
 /* Set the background screen, etc. */
-static void
-prepare_screen_for_menu(void)
+static void prepare_screen_for_menu(void)
 {
-  console_color_table = cm->color_table;
-  console_color_table_size = menu_color_table_size;
-  set_background(cm->menu_background);
+    console_color_table = cm->color_table;
+    console_color_table_size = menu_color_table_size;
+    set_background(cm->menu_background);
 }
 
-static const char *
-do_hidden_menu(void)
+static const char *do_hidden_menu(void)
 {
-  int key;
-  int timeout_left, this_timeout;
+    int key;
+    int timeout_left, this_timeout;
 
-  clear_screen();
+    clear_screen();
 
-  if ( !setjmp(timeout_jump) ) {
-    timeout_left = cm->timeout;
+    if (!setjmp(timeout_jump)) {
+       timeout_left = cm->timeout;
 
-    while (!cm->timeout || timeout_left) {
-      int tol = timeout_left/CLK_TCK;
+       while (!cm->timeout || timeout_left) {
+           int tol = timeout_left / CLK_TCK;
 
-      print_timeout_message(tol, HIDDEN_ROW, cm->messages[MSG_AUTOBOOT]);
+           print_timeout_message(tol, HIDDEN_ROW, cm->messages[MSG_AUTOBOOT]);
 
-      this_timeout = min(timeout_left, CLK_TCK);
-      key = mygetkey(this_timeout);
+           this_timeout = min(timeout_left, CLK_TCK);
+           key = mygetkey(this_timeout);
 
-      if (key != KEY_NONE)
-       return NULL;            /* Key pressed */
+           if (key != KEY_NONE)
+               return NULL;    /* Key pressed */
 
-      timeout_left -= this_timeout;
+           timeout_left -= this_timeout;
+       }
     }
-  }
 
-  return cm->menu_entries[cm->defentry]->cmdline; /* Default entry */
+    return cm->menu_entries[cm->defentry]->cmdline;    /* Default entry */
 }
 
-static const char *
-run_menu(void)
+static const char *run_menu(void)
 {
-  int key;
-  int done = 0;
-  volatile int entry = cm->curentry;
-  int prev_entry = -1;
-  volatile int top = cm->curtop;
-  int prev_top = -1;
-  int clear = 1, to_clear;
-  const char *cmdline = NULL;
-  volatile clock_t key_timeout, timeout_left, this_timeout;
-  const struct menu_entry *me;
-
-  /* Note: for both key_timeout and timeout == 0 means no limit */
-  timeout_left = key_timeout = cm->timeout;
-
-  /* If we're in shiftkey mode, exit immediately unless a shift key
-     is pressed */
-  if ( shiftkey && !shift_is_held() ) {
-    return cm->menu_entries[cm->defentry]->cmdline;
-  } else {
-    shiftkey = 0;
-  }
-
-  /* Do this before hiddenmenu handling, so we show the background */
-  prepare_screen_for_menu();
-
-  /* Handle hiddenmenu */
-  if ( hiddenmenu ) {
-    cmdline = do_hidden_menu();
-    if (cmdline)
-      return cmdline;
-
-    /* Otherwise display the menu now; the timeout has already been
-       cancelled, since the user pressed a key. */
-    hiddenmenu = 0;
-    key_timeout = 0;
-  }
-
-  /* Handle both local and global timeout */
-  if ( setjmp(timeout_jump) ) {
-    entry = cm->defentry;
-
-    if ( top < 0 || top < entry-MENU_ROWS+1 )
-      top = max(0, entry-MENU_ROWS+1);
-    else if ( top > entry || top > max(0, cm->nentries-MENU_ROWS) )
-      top = min(entry, max(0, cm->nentries-MENU_ROWS));
-
-    draw_menu(cm->ontimeout ? -1 : entry, top, 1);
-    cmdline = cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline;
-    done = 1;
-  }
-
-  while ( !done ) {
-    if (entry <= 0) {
-      entry = 0;
-      while (entry < cm->nentries && is_disabled(cm->menu_entries[entry]))
-       entry++;
-    }
-    if (entry >= cm->nentries) {
-      entry = cm->nentries-1;
-      while (entry > 0 && is_disabled(cm->menu_entries[entry]))
-       entry--;
-    }
-
-    me = cm->menu_entries[entry];
-
-    if ( top < 0 || top < entry-MENU_ROWS+1 )
-      top = max(0, entry-MENU_ROWS+1);
-    else if ( top > entry || top > max(0, cm->nentries-MENU_ROWS) )
-      top = min(entry, max(0, cm->nentries-MENU_ROWS));
-
-    /* Start with a clear screen */
-    if ( clear ) {
-      /* Clear and redraw whole screen */
-      /* Enable ASCII on G0 and DEC VT on G1; do it in this order
-        to avoid confusing the Linux console */
-      if (clear >= 2)
-       prepare_screen_for_menu();
-      clear_screen();
-      clear = 0;
-      prev_entry = prev_top = -1;
-    }
-
-    if ( top != prev_top ) {
-      draw_menu(entry, top, 1);
-      display_help(me->helptext);
-    } else if ( entry != prev_entry ) {
-      draw_row(prev_entry-top+4+VSHIFT, entry, top, 0, 0);
-      draw_row(entry-top+4+VSHIFT, entry, top, 0, 0);
-      display_help(me->helptext);
+    int key;
+    int done = 0;
+    volatile int entry = cm->curentry;
+    int prev_entry = -1;
+    volatile int top = cm->curtop;
+    int prev_top = -1;
+    int clear = 1, to_clear;
+    const char *cmdline = NULL;
+    volatile clock_t key_timeout, timeout_left, this_timeout;
+    const struct menu_entry *me;
+
+    /* Note: for both key_timeout and timeout == 0 means no limit */
+    timeout_left = key_timeout = cm->timeout;
+
+    /* If we're in shiftkey mode, exit immediately unless a shift key
+       is pressed */
+    if (shiftkey && !shift_is_held()) {
+       return cm->menu_entries[cm->defentry]->cmdline;
+    } else {
+       shiftkey = 0;
     }
 
-    prev_entry = entry;  prev_top = top;
-    cm->curentry = entry;
-    cm->curtop = top;
+    /* Do this before hiddenmenu handling, so we show the background */
+    prepare_screen_for_menu();
 
-    /* Cursor movement cancels timeout */
-    if ( entry != cm->defentry )
-      key_timeout = 0;
+    /* Handle hiddenmenu */
+    if (hiddenmenu) {
+       cmdline = do_hidden_menu();
+       if (cmdline)
+           return cmdline;
 
-    if ( key_timeout ) {
-      int tol = timeout_left/CLK_TCK;
-      print_timeout_message(tol, TIMEOUT_ROW, cm->messages[MSG_AUTOBOOT]);
-      to_clear = 1;
-    } else {
-      to_clear = 0;
+       /* Otherwise display the menu now; the timeout has already been
+          cancelled, since the user pressed a key. */
+       hiddenmenu = 0;
+       key_timeout = 0;
     }
 
-    this_timeout = min(min(key_timeout, timeout_left), (clock_t)CLK_TCK);
-    key = mygetkey(this_timeout);
+    /* Handle both local and global timeout */
+    if (setjmp(timeout_jump)) {
+       entry = cm->defentry;
 
-    if ( key != KEY_NONE ) {
-      timeout_left = key_timeout;
-      if ( to_clear )
-       printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW);
-    }
+       if (top < 0 || top < entry - MENU_ROWS + 1)
+           top = max(0, entry - MENU_ROWS + 1);
+       else if (top > entry || top > max(0, cm->nentries - MENU_ROWS))
+           top = min(entry, max(0, cm->nentries - MENU_ROWS));
 
-    switch ( key ) {
-    case KEY_NONE:             /* Timeout */
-      /* This is somewhat hacky, but this at least lets the user
-        know what's going on, and still deals with "phantom inputs"
-        e.g. on serial ports.
-
-        Warning: a timeout will boot the default entry without any
-        password! */
-      if ( key_timeout ) {
-       if ( timeout_left <= this_timeout )
-         longjmp(timeout_jump, 1);
-
-       timeout_left -= this_timeout;
-      }
-      break;
-
-    case KEY_CTRL('L'):
-      clear = 1;
-      break;
-
-    case KEY_ENTER:
-    case KEY_CTRL('J'):
-      key_timeout = 0;         /* Cancels timeout */
-      if ( me->passwd ) {
-       clear = 1;
-       done = ask_passwd(me->passwd);
-      } else {
+       draw_menu(cm->ontimeout ? -1 : entry, top, 1);
+       cmdline =
+           cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline;
        done = 1;
-      }
-      cmdline = NULL;
-      if (done) {
-       switch (me->action) {
-       case MA_CMD:
-         cmdline = me->cmdline;
-         break;
-       case MA_SUBMENU:
-       case MA_GOTO:
-       case MA_EXIT:
-         done = 0;
-         clear = 2;
-         cm = me->submenu;
-         entry = cm->curentry;
-         top = cm->curtop;
-         break;
-       case MA_QUIT:
-         /* Quit menu system */
-         done = 1;
-         clear = 1;
-         draw_row(entry-top+4+VSHIFT, -1, top, 0, 0);
-         break;
-       default:
-         done = 0;
-         break;
+    }
+
+    while (!done) {
+       if (entry <= 0) {
+           entry = 0;
+           while (entry < cm->nentries && is_disabled(cm->menu_entries[entry]))
+               entry++;
        }
-      }
-      if (done && !me->passwd) {
-       /* Only save a new default if we don't have a password... */
-       if (me->save && me->label) {
-         syslinux_setadv(ADV_MENUSAVE, strlen(me->label), me->label);
-         syslinux_adv_write();
+       if (entry >= cm->nentries) {
+           entry = cm->nentries - 1;
+           while (entry > 0 && is_disabled(cm->menu_entries[entry]))
+               entry--;
        }
-      }
-      break;
-
-    case KEY_UP:
-    case KEY_CTRL('P'):
-      while (entry > 0) {
-       entry--;
-       if (entry < top)
-         top -= MENU_ROWS;
-       if (!is_disabled(cm->menu_entries[entry]))
-         break;
-      }
-      break;
-
-    case KEY_DOWN:
-    case KEY_CTRL('N'):
-      while (entry < cm->nentries-1) {
-       entry++;
-       if (entry >= top+MENU_ROWS)
-         top += MENU_ROWS;
-       if (!is_disabled(cm->menu_entries[entry]))
-         break;
-      }
-      break;
-
-    case KEY_PGUP:
-    case KEY_LEFT:
-    case KEY_CTRL('B'):
-    case '<':
-      entry -= MENU_ROWS;
-      top   -= MENU_ROWS;
-      while (entry > 0 && is_disabled(cm->menu_entries[entry])) {
-         entry--;
-         if (entry < top)
-           top -= MENU_ROWS;
-      }
-      break;
-
-    case KEY_PGDN:
-    case KEY_RIGHT:
-    case KEY_CTRL('F'):
-    case '>':
-    case ' ':
-      entry += MENU_ROWS;
-      top   += MENU_ROWS;
-      while (entry < cm->nentries-1 && is_disabled(cm->menu_entries[entry])) {
-       entry++;
-       if (entry >= top+MENU_ROWS)
-         top += MENU_ROWS;
-      }
-      break;
-
-    case '-':
-      while (entry > 0) {
-       entry--;
-       top--;
-       if (!is_disabled(cm->menu_entries[entry]))
-         break;
-      }
-      break;
-
-    case '+':
-      while (entry < cm->nentries-1) {
-       entry++;
-       top++;
-       if (!is_disabled(cm->menu_entries[entry]))
-         break;
-      }
-      break;
-
-    case KEY_CTRL('A'):
-    case KEY_HOME:
-      top = entry = 0;
-      break;
-
-    case KEY_CTRL('E'):
-    case KEY_END:
-      entry = cm->nentries - 1;
-      top = max(0, cm->nentries-MENU_ROWS);
-      break;
-
-    case KEY_F1:
-    case KEY_F2:
-    case KEY_F3:
-    case KEY_F4:
-    case KEY_F5:
-    case KEY_F6:
-    case KEY_F7:
-    case KEY_F8:
-    case KEY_F9:
-    case KEY_F10:
-    case KEY_F11:
-    case KEY_F12:
-      show_fkey(key);
-      clear = 1;
-      break;
-
-    case KEY_TAB:
-      if ( cm->allowedit && me->action == MA_CMD ) {
-       int ok = 1;
-
-       key_timeout = 0;        /* Cancels timeout */
-       draw_row(entry-top+4+VSHIFT, -1, top, 0, 0);
-
-       if ( cm->menu_master_passwd ) {
-         ok = ask_passwd(NULL);
-         clear_screen();
-         draw_menu(-1, top, 0);
-       } else {
-         /* Erase [Tab] message and help text*/
-         printf("\033[%d;1H\1#0\033[K", TABMSG_ROW);
-         display_help(NULL);
+
+       me = cm->menu_entries[entry];
+
+       if (top < 0 || top < entry - MENU_ROWS + 1)
+           top = max(0, entry - MENU_ROWS + 1);
+       else if (top > entry || top > max(0, cm->nentries - MENU_ROWS))
+           top = min(entry, max(0, cm->nentries - MENU_ROWS));
+
+       /* Start with a clear screen */
+       if (clear) {
+           /* Clear and redraw whole screen */
+           /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+              to avoid confusing the Linux console */
+           if (clear >= 2)
+               prepare_screen_for_menu();
+           clear_screen();
+           clear = 0;
+           prev_entry = prev_top = -1;
+       }
+
+       if (top != prev_top) {
+           draw_menu(entry, top, 1);
+           display_help(me->helptext);
+       } else if (entry != prev_entry) {
+           draw_row(prev_entry - top + 4 + VSHIFT, entry, top, 0, 0);
+           draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0);
+           display_help(me->helptext);
        }
 
-       if ( ok ) {
-         cmdline = edit_cmdline(me->cmdline, top);
-         done = !!cmdline;
-         clear = 1;            /* In case we hit [Esc] and done is null */
+       prev_entry = entry;
+       prev_top = top;
+       cm->curentry = entry;
+       cm->curtop = top;
+
+       /* Cursor movement cancels timeout */
+       if (entry != cm->defentry)
+           key_timeout = 0;
+
+       if (key_timeout) {
+           int tol = timeout_left / CLK_TCK;
+           print_timeout_message(tol, TIMEOUT_ROW, cm->messages[MSG_AUTOBOOT]);
+           to_clear = 1;
        } else {
-         draw_row(entry-top+4+VSHIFT, entry, top, 0, 0);
+           to_clear = 0;
        }
-      }
-      break;
-    case KEY_CTRL('C'):                /* Ctrl-C */
-    case KEY_ESC:              /* Esc */
-      if ( cm->parent ) {
-       cm = cm->parent;
-       clear = 2;
-       entry = cm->curentry;
-       top = cm->curtop;
-      } else if ( cm->allowedit ) {
-       done = 1;
-       clear = 1;
-       key_timeout = 0;
 
-       draw_row(entry-top+4+VSHIFT, -1, top, 0, 0);
+       this_timeout = min(min(key_timeout, timeout_left), (clock_t) CLK_TCK);
+       key = mygetkey(this_timeout);
 
-       if ( cm->menu_master_passwd )
-         done = ask_passwd(NULL);
-      }
-      break;
-    default:
-      if ( key > 0 && key < 0xFF ) {
-       key &= ~0x20;           /* Upper case */
-       if ( cm->menu_hotkeys[key] ) {
-         key_timeout = 0;
-         entry = cm->menu_hotkeys[key]->entry;
-         /* Should we commit at this point? */
+       if (key != KEY_NONE) {
+           timeout_left = key_timeout;
+           if (to_clear)
+               printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW);
+       }
+
+       switch (key) {
+       case KEY_NONE:          /* Timeout */
+           /* This is somewhat hacky, but this at least lets the user
+              know what's going on, and still deals with "phantom inputs"
+              e.g. on serial ports.
+
+              Warning: a timeout will boot the default entry without any
+              password! */
+           if (key_timeout) {
+               if (timeout_left <= this_timeout)
+                   longjmp(timeout_jump, 1);
+
+               timeout_left -= this_timeout;
+           }
+           break;
+
+       case KEY_CTRL('L'):
+           clear = 1;
+           break;
+
+       case KEY_ENTER:
+       case KEY_CTRL('J'):
+           key_timeout = 0;    /* Cancels timeout */
+           if (me->passwd) {
+               clear = 1;
+               done = ask_passwd(me->passwd);
+           } else {
+               done = 1;
+           }
+           cmdline = NULL;
+           if (done) {
+               switch (me->action) {
+               case MA_CMD:
+                   cmdline = me->cmdline;
+                   break;
+               case MA_SUBMENU:
+               case MA_GOTO:
+               case MA_EXIT:
+                   done = 0;
+                   clear = 2;
+                   cm = me->submenu;
+                   entry = cm->curentry;
+                   top = cm->curtop;
+                   break;
+               case MA_QUIT:
+                   /* Quit menu system */
+                   done = 1;
+                   clear = 1;
+                   draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+                   break;
+               default:
+                   done = 0;
+                   break;
+               }
+           }
+           if (done && !me->passwd) {
+               /* Only save a new default if we don't have a password... */
+               if (me->save && me->label) {
+                   syslinux_setadv(ADV_MENUSAVE, strlen(me->label), me->label);
+                   syslinux_adv_write();
+               }
+           }
+           break;
+
+       case KEY_UP:
+       case KEY_CTRL('P'):
+           while (entry > 0) {
+               entry--;
+               if (entry < top)
+                   top -= MENU_ROWS;
+               if (!is_disabled(cm->menu_entries[entry]))
+                   break;
+           }
+           break;
+
+       case KEY_DOWN:
+       case KEY_CTRL('N'):
+           while (entry < cm->nentries - 1) {
+               entry++;
+               if (entry >= top + MENU_ROWS)
+                   top += MENU_ROWS;
+               if (!is_disabled(cm->menu_entries[entry]))
+                   break;
+           }
+           break;
+
+       case KEY_PGUP:
+       case KEY_LEFT:
+       case KEY_CTRL('B'):
+       case '<':
+           entry -= MENU_ROWS;
+           top -= MENU_ROWS;
+           while (entry > 0 && is_disabled(cm->menu_entries[entry])) {
+               entry--;
+               if (entry < top)
+                   top -= MENU_ROWS;
+           }
+           break;
+
+       case KEY_PGDN:
+       case KEY_RIGHT:
+       case KEY_CTRL('F'):
+       case '>':
+       case ' ':
+           entry += MENU_ROWS;
+           top += MENU_ROWS;
+           while (entry < cm->nentries - 1
+                  && is_disabled(cm->menu_entries[entry])) {
+               entry++;
+               if (entry >= top + MENU_ROWS)
+                   top += MENU_ROWS;
+           }
+           break;
+
+       case '-':
+           while (entry > 0) {
+               entry--;
+               top--;
+               if (!is_disabled(cm->menu_entries[entry]))
+                   break;
+           }
+           break;
+
+       case '+':
+           while (entry < cm->nentries - 1) {
+               entry++;
+               top++;
+               if (!is_disabled(cm->menu_entries[entry]))
+                   break;
+           }
+           break;
+
+       case KEY_CTRL('A'):
+       case KEY_HOME:
+           top = entry = 0;
+           break;
+
+       case KEY_CTRL('E'):
+       case KEY_END:
+           entry = cm->nentries - 1;
+           top = max(0, cm->nentries - MENU_ROWS);
+           break;
+
+       case KEY_F1:
+       case KEY_F2:
+       case KEY_F3:
+       case KEY_F4:
+       case KEY_F5:
+       case KEY_F6:
+       case KEY_F7:
+       case KEY_F8:
+       case KEY_F9:
+       case KEY_F10:
+       case KEY_F11:
+       case KEY_F12:
+           show_fkey(key);
+           clear = 1;
+           break;
+
+       case KEY_TAB:
+           if (cm->allowedit && me->action == MA_CMD) {
+               int ok = 1;
+
+               key_timeout = 0;        /* Cancels timeout */
+               draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+
+               if (cm->menu_master_passwd) {
+                   ok = ask_passwd(NULL);
+                   clear_screen();
+                   draw_menu(-1, top, 0);
+               } else {
+                   /* Erase [Tab] message and help text */
+                   printf("\033[%d;1H\1#0\033[K", TABMSG_ROW);
+                   display_help(NULL);
+               }
+
+               if (ok) {
+                   cmdline = edit_cmdline(me->cmdline, top);
+                   done = !!cmdline;
+                   clear = 1;  /* In case we hit [Esc] and done is null */
+               } else {
+                   draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0);
+               }
+           }
+           break;
+       case KEY_CTRL('C'):     /* Ctrl-C */
+       case KEY_ESC:           /* Esc */
+           if (cm->parent) {
+               cm = cm->parent;
+               clear = 2;
+               entry = cm->curentry;
+               top = cm->curtop;
+           } else if (cm->allowedit) {
+               done = 1;
+               clear = 1;
+               key_timeout = 0;
+
+               draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0);
+
+               if (cm->menu_master_passwd)
+                   done = ask_passwd(NULL);
+           }
+           break;
+       default:
+           if (key > 0 && key < 0xFF) {
+               key &= ~0x20;   /* Upper case */
+               if (cm->menu_hotkeys[key]) {
+                   key_timeout = 0;
+                   entry = cm->menu_hotkeys[key]->entry;
+                   /* Should we commit at this point? */
+               }
+           }
+           break;
        }
-      }
-      break;
     }
-  }
 
-  printf("\033[?25h");         /* Show cursor */
+    printf("\033[?25h");       /* Show cursor */
 
-  /* Return the label name so localboot and ipappend work */
-  return cmdline;
+    /* Return the label name so localboot and ipappend work */
+    return cmdline;
 }
 
 int menu_main(int argc, char *argv[])
 {
-  const char *cmdline;
-  struct menu *m;
-  int rows, cols;
-  int i;
-
-  (void)argc;
-
-  if (getscreensize(1, &rows, &cols)) {
-    /* Unknown screen size? */
-    rows = 24;
-    cols = 80;
-  }
-
-  parse_configs(argv+1);
-
-  /* Some postprocessing for all menus */
-  for (m = menu_list; m; m = m->next) {
-    if (!m->mparm[P_WIDTH])
-      m->mparm[P_WIDTH] = cols;
-
-    /* If anyone has specified negative parameters, consider them
-       relative to the bottom row of the screen. */
-    for (i = 0; i < NPARAMS; i++)
-      if (m->mparm[i] < 0)
-       m->mparm[i] = max(m->mparm[i]+rows, 0);
-  }
-
-  if ( !cm->nentries ) {
-    fputs("Initial menu has no LABEL entries!\n", stdout);
-    return 1;                  /* Error! */
-  }
-
-  cm = start_menu;
-  for(;;) {
-    cmdline = run_menu();
-
-    printf("\033[?25h\033[%d;1H\033[0m", END_ROW);
-
-    if ( cmdline ) {
-      execute(cmdline, KT_NONE);
-      if ( cm->onerror )
-       execute(cm->onerror, KT_NONE);
-    } else {
-      return 0;                        /* Exit */
+    const char *cmdline;
+    struct menu *m;
+    int rows, cols;
+    int i;
+
+    (void)argc;
+
+    if (getscreensize(1, &rows, &cols)) {
+       /* Unknown screen size? */
+       rows = 24;
+       cols = 80;
+    }
+
+    parse_configs(argv + 1);
+
+    /* Some postprocessing for all menus */
+    for (m = menu_list; m; m = m->next) {
+       if (!m->mparm[P_WIDTH])
+           m->mparm[P_WIDTH] = cols;
+
+       /* If anyone has specified negative parameters, consider them
+          relative to the bottom row of the screen. */
+       for (i = 0; i < NPARAMS; i++)
+           if (m->mparm[i] < 0)
+               m->mparm[i] = max(m->mparm[i] + rows, 0);
+    }
+
+    if (!cm->nentries) {
+       fputs("Initial menu has no LABEL entries!\n", stdout);
+       return 1;               /* Error! */
+    }
+
+    cm = start_menu;
+    for (;;) {
+       cmdline = run_menu();
+
+       printf("\033[?25h\033[%d;1H\033[0m", END_ROW);
+
+       if (cmdline) {
+           execute(cmdline, KT_NONE);
+           if (cm->onerror)
+               execute(cm->onerror, KT_NONE);
+       } else {
+           return 0;           /* Exit */
+       }
     }
-  }
 }