Implemented a simple boot menu to play with (this can be taken over by
other boot menu implementations for a start). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12181 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,6 +22,8 @@ extern int __libc_argc;
|
|||||||
extern char **__libc_argv;
|
extern char **__libc_argv;
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
|
|
||||||
|
extern bool gShowMenu;
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
get_device(const char *path, Node **_device)
|
get_device(const char *path, Node **_device)
|
||||||
@@ -179,11 +181,14 @@ platform_add_block_devices(struct stage2_args *args, NodeList *list)
|
|||||||
addDevices = false;
|
addDevices = false;
|
||||||
else if (!strcmp(option, "--no-scsi"))
|
else if (!strcmp(option, "--no-scsi"))
|
||||||
scsi = false;
|
scsi = false;
|
||||||
|
else if (!strcmp(option, "--menu"))
|
||||||
|
gShowMenu = true;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "usage: %s [OPTIONS] [image ...]\n"
|
fprintf(stderr, "usage: %s [OPTIONS] [image ...]\n"
|
||||||
" --no-devices\tDon't add real devices from /dev/disk\n"
|
" --no-devices\tDon't add real devices from /dev/disk\n"
|
||||||
" --no-scsi\tDon't add SCSI devices (might be problematic with some\n"
|
" --no-scsi\tDon't add SCSI devices (might be problematic with some\n"
|
||||||
"\t\tUSB mass storage drivers)\n", __progname);
|
"\t\tUSB mass storage drivers)\n"
|
||||||
|
" --menu\tShow boot menu\n", __progname);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,129 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
const char *kNormalColor = "\33[0m";
|
||||||
|
const char *kDisabledColor = "\33[31m"; // red
|
||||||
|
const char *kTitleColor = "\33[34m"; // blue
|
||||||
|
|
||||||
|
|
||||||
extern RootFileSystem *gRoot;
|
extern RootFileSystem *gRoot;
|
||||||
|
bool gShowMenu = false;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_item_at(int32 line, MenuItem *item, bool clearHelp = true)
|
||||||
|
{
|
||||||
|
if (!item->IsEnabled())
|
||||||
|
printf("%s ", kDisabledColor);
|
||||||
|
else
|
||||||
|
printf("%2ld. ", line);
|
||||||
|
|
||||||
|
if (item->Type() == MENU_ITEM_MARKABLE) {
|
||||||
|
printf(" [");
|
||||||
|
printf("%c", item->IsMarked() ? 'x' : ' ');
|
||||||
|
printf("] ");
|
||||||
|
} else
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
printf(item->Label());
|
||||||
|
|
||||||
|
if (item->Submenu() && item->Submenu()->Type() == CHOICE_MENU) {
|
||||||
|
// show the current choice (if any)
|
||||||
|
Menu *subMenu = item->Submenu();
|
||||||
|
MenuItem *subItem = NULL;
|
||||||
|
|
||||||
|
for (int32 i = subMenu->CountItems(); i-- > 0; ) {
|
||||||
|
subItem = subMenu->ItemAt(i);
|
||||||
|
if (subItem != NULL && subItem->IsMarked())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" (Current: ");
|
||||||
|
printf(subItem != NULL ? subItem->Label() : "None");
|
||||||
|
putchar(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item->IsEnabled())
|
||||||
|
printf(kNormalColor);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw_menu(Menu *menu)
|
||||||
|
{
|
||||||
|
printf("\n %s--- ", kTitleColor);
|
||||||
|
if (menu->Title())
|
||||||
|
printf("%s", menu->Title());
|
||||||
|
else
|
||||||
|
printf("Welcome To The Haiku Bootloader");
|
||||||
|
printf(" ---%s\n\n", kNormalColor);
|
||||||
|
|
||||||
|
MenuItemIterator iterator = menu->ItemIterator();
|
||||||
|
MenuItem *item;
|
||||||
|
int32 i = 0, selected = -1;
|
||||||
|
|
||||||
|
while ((item = iterator.Next()) != NULL) {
|
||||||
|
if (item->Type() == MENU_ITEM_SEPARATOR) {
|
||||||
|
putchar('\n');
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->IsSelected())
|
||||||
|
selected = i;
|
||||||
|
|
||||||
|
print_item_at(i++, item, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n[%ld]? ", selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
dump_devices_hook(Menu *menu, MenuItem *item)
|
||||||
|
{
|
||||||
|
puts("List of known root directories:");
|
||||||
|
|
||||||
|
void *cookie;
|
||||||
|
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
||||||
|
Directory *directory;
|
||||||
|
while (gRoot->GetNextNode(cookie, (Node **)&directory) == B_OK) {
|
||||||
|
char name[256];
|
||||||
|
if (directory->GetName(name, sizeof(name)) == B_OK)
|
||||||
|
printf("%s:: %s (%p)%s\n", kTitleColor, name, directory, kNormalColor);
|
||||||
|
|
||||||
|
void *subCookie;
|
||||||
|
if (directory->Open(&subCookie, O_RDONLY) == B_OK) {
|
||||||
|
while (directory->GetNextEntry(subCookie, name, sizeof(name)) == B_OK) {
|
||||||
|
printf("\t%s\n", name);
|
||||||
|
}
|
||||||
|
directory->Close(subCookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gRoot->Close(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
platform_add_menus(Menu *menu)
|
platform_add_menus(Menu *menu)
|
||||||
{
|
{
|
||||||
|
MenuItem *item;
|
||||||
|
|
||||||
|
switch (menu->Type()) {
|
||||||
|
case MAIN_MENU:
|
||||||
|
menu->AddItem(item = new MenuItem("Dump all recognized volumes"));
|
||||||
|
item->SetTarget(dump_devices_hook);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -32,25 +149,47 @@ platform_update_menu_item(Menu *menu, MenuItem *item)
|
|||||||
void
|
void
|
||||||
platform_run_menu(Menu *menu)
|
platform_run_menu(Menu *menu)
|
||||||
{
|
{
|
||||||
puts("List of known root directories:");
|
// Get selected entry, or select the last one, if there is none
|
||||||
|
int32 selected;
|
||||||
|
MenuItem *item = menu->FindSelected(&selected);
|
||||||
|
if (item == NULL) {
|
||||||
|
selected = menu->CountItems() - 1;
|
||||||
|
item = menu->ItemAt(selected);
|
||||||
|
if (item != NULL)
|
||||||
|
item->Select(true);
|
||||||
|
}
|
||||||
|
|
||||||
void *cookie;
|
while (true) {
|
||||||
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
draw_menu(menu);
|
||||||
Directory *directory;
|
|
||||||
while (gRoot->GetNextNode(cookie, (Node **)&directory) == B_OK) {
|
|
||||||
char name[256];
|
|
||||||
if (directory->GetName(name, sizeof(name)) == B_OK)
|
|
||||||
printf(":: %s (%p)\n", name, directory);
|
|
||||||
|
|
||||||
void *subCookie;
|
char buffer[32];
|
||||||
if (directory->Open(&subCookie, O_RDONLY) == B_OK) {
|
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
|
||||||
while (directory->GetNextEntry(subCookie, name, sizeof(name)) == B_OK) {
|
return;
|
||||||
printf("\t%s\n", name);
|
|
||||||
}
|
if (buffer[0] != '\n')
|
||||||
directory->Close(subCookie);
|
selected = atoi(buffer);
|
||||||
}
|
|
||||||
}
|
item = menu->ItemAt(selected);
|
||||||
gRoot->Close(cookie);
|
|
||||||
|
// leave the menu
|
||||||
|
if (item->Submenu() != NULL) {
|
||||||
|
menu->Hide();
|
||||||
|
|
||||||
|
platform_run_menu(item->Submenu());
|
||||||
|
if (item->Target() != NULL)
|
||||||
|
(*item->Target())(menu, item);
|
||||||
|
|
||||||
|
// restore current menu
|
||||||
|
menu->FindSelected(&selected);
|
||||||
|
menu->Show();
|
||||||
|
} else if (item->Type() == MENU_ITEM_MARKABLE) {
|
||||||
|
// toggle state
|
||||||
|
item->SetMarked(!item->IsMarked());
|
||||||
|
|
||||||
|
if (item->Target() != NULL)
|
||||||
|
(*item->Target())(menu, item);
|
||||||
|
} else if (item->Target() == NULL || (*item->Target())(menu, item))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2003-2005, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
** Distributed under the terms of the Haiku License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <boot/platform.h>
|
#include <boot/platform.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern bool gShowMenu;
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
platform_boot_options(void)
|
platform_boot_options(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return gShowMenu ? BOOT_OPTION_MENU: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user