}
/* 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 */
- if (cm->ontimeout)
- return cm->ontimeout;
- return cm->menu_entries[cm->defentry]->cmdline; /* Default entry */
++ if (cm->ontimeout)
++ return cm->ontimeout;
++ else
++ 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 ( ok ) {
- cmdline = edit_cmdline(me->cmdline, top);
- done = !!cmdline;
- clear = 1; /* In case we hit [Esc] and done is null */
+ 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);
+ }
+
+ 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[])