# Soft Cap Linux
LABEL softcap
- MENU LABEL Soft Cap Linux 9.6.36
+ MENU LABEL Soft Cap ^Linux 9.6.36
KERNEL softcap-9.6.36.bzi
APPEND whatever
# A very dense operating system
LABEL brick
- MENU LABEL Windows CE/ME/NT
+ MENU LABEL ^Windows CE/ME/NT
KERNEL chain.c32
APPEND hd0 2
+ The ^ symbol in a MENU LABEL statement defines a hotkey.
+ The hotkey will be highlighted in the menu and will move the
+ menu cursor immediately to that entry.
+
MENU HIDE
(Only valid after a LABEL statement.)
const char *border; /* Border area */
const char *title; /* Title bar */
const char *unsel; /* Unselected menu item */
+ const char *hotkey; /* Unselected hotkey */
const char *sel; /* Selected */
+ const char *hotsel; /* Selected hotkey */
const char *more; /* [More] tag */
const char *tabmsg; /* Press [Tab] message */
const char *cmdmark; /* Command line marker */
.border = "\033[0;30;44m",
.title = "\033[1;36;44m",
.unsel = "\033[0;37;44m",
+ .hotkey = "\033[1;37;44m",
.sel = "\033[0;30;47m",
+ .hotsel = "\033[1;30;47m",
.more = "\033[0;37;44m",
.tabmsg = "\033[0;31;40m",
.cmdmark = "\033[1;36;40m",
return buffer;
}
+/* Display an entry, with possible hotkey highlight. Assumes
+ that the current attribute is the non-hotkey one, and will
+ guarantee that as an exit condition as well. */
+void display_entry(const struct menu_entry *entry, const char *attrib,
+ const char *hotattrib, int width)
+{
+ const char *p = entry->displayname;
+
+ while ( width ) {
+ if ( *p ) {
+ if ( *p == '^' ) {
+ p++;
+ if ( *p && (unsigned char)*p == entry->hotkey ) {
+ fputs(hotattrib, stdout);
+ putchar(*p++);
+ fputs(attrib, stdout);
+ width--;
+ }
+ } else {
+ putchar(*p++);
+ width--;
+ }
+ } else {
+ putchar(' ');
+ width--;
+ }
+ }
+}
+
void draw_menu(int sel, int top)
{
int x, y;
for ( y = 4 ; y < 4+MENU_ROWS ; y++ ) {
int i = (y-4)+top;
- const char *txt = (i >= nentries) ? "" : menu_entries[i].displayname;
- printf("\033[%d;%dH\272%s %s %s\272",
+ printf("\033[%d;%dH\272%s ",
y, MARGIN+1,
- (i == sel) ? menu_attrib->sel : menu_attrib->unsel,
- pad_line(txt, 0, WIDTH-2*MARGIN-4),
- menu_attrib->border);
+ (i == sel) ? menu_attrib->sel : menu_attrib->unsel);
+
+ if ( i >= nentries ) {
+ fputs(pad_line("", 0, WIDTH-2*MARGIN-4), stdout);
+ } else {
+ display_entry(&menu_entries[i],
+ (i == sel) ? menu_attrib->sel : menu_attrib->unsel,
+ (i == sel) ? menu_attrib->hotsel : menu_attrib->hotkey,
+ WIDTH-2*MARGIN-4);
+ }
+
+ printf(" %s\272", menu_attrib->border);
}
printf("\033[%d;%dH\310", y, MARGIN+1);
done = 1;
break;
default:
+ if ( key > 0 && key < 0xFF ) {
+ key &= ~0x20; /* Upper case */
+ if ( menu_hotkeys[key] ) {
+ entry = menu_hotkeys[key] - menu_entries;
+ /* Should we commit at this point? */
+ }
+ }
break;
}
}
char *ontimeout = NULL;
struct menu_entry menu_entries[MAX_ENTRIES];
+struct menu_entry *menu_hotkeys[256];
#define astrdup(x) ({ char *__x = (x); \
size_t __n = strlen(__x) + 1; \
{
char ipoptions[256], *ipp;
int i;
+ struct menu_entry *me = &menu_entries[nentries];
if ( ld->label ) {
char *a, *s;
- menu_entries[nentries].displayname =
- ld->menulabel ? ld->menulabel : ld->label;
- menu_entries[nentries].label = ld->label;
+ me->displayname = ld->menulabel ? ld->menulabel : ld->label;
+ me->label = ld->label;
+ me->hotkey = 0;
+
+ if ( ld->menulabel ) {
+ unsigned char *p = strchr(ld->menulabel, '^');
+ if ( p && p[1] ) {
+ int hotkey = p[1] & ~0x20;
+ if ( !menu_hotkeys[hotkey] ) {
+ me->hotkey = hotkey;
+ }
+ }
+ }
ipp = ipoptions;
*ipp = '\0';
if ( !a ) a = append;
if ( !a || (a[0] == '-' && !a[1]) ) a = "";
s = a[0] ? " " : "";
- asprintf(&menu_entries[nentries].cmdline, "%s%s%s%s", ld->kernel, ipoptions, s, a);
+ asprintf(&me->cmdline, "%s%s%s%s", ld->kernel, ipoptions, s, a);
ld->label = NULL;
free(ld->kernel);
free(ld->append);
if ( !ld->menuhide ) {
+ if ( me->hotkey )
+ menu_hotkeys[me->hotkey] = me;
+
if ( ld->menudefault )
defentry = nentries;
+
nentries++;
}
}