Work in progress of the boot loader menu.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8095 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
689c94c815
commit
c54d49c275
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
@ -10,18 +10,273 @@
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <util/kernel_cpp.h>
|
||||
#include <boot/menu.h>
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/vfs.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
MenuItem::MenuItem(const char *label, Menu *subMenu)
|
||||
:
|
||||
fLabel(strdup(label)),
|
||||
fTarget(NULL),
|
||||
fIsMarked(false),
|
||||
fIsSelected(false),
|
||||
fType(MENU_ITEM_STANDARD),
|
||||
fMenu(NULL),
|
||||
fSubMenu(subMenu)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MenuItem::~MenuItem()
|
||||
{
|
||||
free(const_cast<char *>(fLabel));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetTarget(menu_item_hook target)
|
||||
{
|
||||
fTarget = target;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetMarked(bool marked)
|
||||
{
|
||||
if (fIsMarked == marked)
|
||||
return;
|
||||
|
||||
if (marked && fMenu != NULL && fMenu->Type() == CHOICE_MENU) {
|
||||
// unmark previous item
|
||||
MenuItem *markedItem = fMenu->FindMarked();
|
||||
if (markedItem != NULL)
|
||||
markedItem->SetMarked(false);
|
||||
}
|
||||
|
||||
fIsMarked = marked;
|
||||
|
||||
if (fMenu != NULL)
|
||||
fMenu->Draw(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::Select(bool selected)
|
||||
{
|
||||
if (fIsSelected == selected)
|
||||
return;
|
||||
|
||||
if (selected && fMenu != NULL) {
|
||||
// unselect previous item
|
||||
MenuItem *selectedItem = fMenu->FindSelected();
|
||||
if (selectedItem != NULL)
|
||||
selectedItem->Select(false);
|
||||
}
|
||||
|
||||
fIsSelected = selected;
|
||||
|
||||
if (fMenu != NULL)
|
||||
fMenu->Draw(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetType(menu_item_type type)
|
||||
{
|
||||
fType = type;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MenuItem::SetMenu(Menu *menu)
|
||||
{
|
||||
fMenu = menu;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Menu::Menu(menu_type type, const char *title)
|
||||
:
|
||||
fTitle(title),
|
||||
fCount(0),
|
||||
fIsHidden(true),
|
||||
fType(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
// take all remaining items with us
|
||||
|
||||
MenuItem *item;
|
||||
while ((item = fItems.RemoveHead()) != NULL) {
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::ItemAt(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= fCount)
|
||||
return NULL;
|
||||
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
if (index-- == 0)
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Menu::IndexOf(MenuItem *searchedItem)
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
int32 index = 0;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
if (item == searchedItem)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Menu::CountItems() const
|
||||
{
|
||||
return fCount;
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::FindMarked()
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
if (item->IsMarked())
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::FindSelected(int32 *_index)
|
||||
{
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
int32 index = 0;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
if (item->IsSelected()) {
|
||||
if (_index != NULL)
|
||||
*_index = index;
|
||||
return item;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Menu::AddItem(MenuItem *item)
|
||||
{
|
||||
item->fMenu = this;
|
||||
fItems.Add(item);
|
||||
fCount++;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_menu(Directory **_bootVolume)
|
||||
Menu::AddSeparatorItem()
|
||||
{
|
||||
platform_switch_to_text_mode();
|
||||
MenuItem *item = new MenuItem();
|
||||
if (item == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
int32 index = 1;
|
||||
item->SetType(MENU_ITEM_SEPARATOR);
|
||||
|
||||
AddItem(item);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
MenuItem *
|
||||
Menu::RemoveItemAt(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= fCount)
|
||||
return NULL;
|
||||
|
||||
MenuItemIterator iterator = ItemIterator();
|
||||
MenuItem *item;
|
||||
|
||||
while ((item = iterator.Next()) != NULL) {
|
||||
if (index-- == 0) {
|
||||
RemoveItem(item);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Menu::RemoveItem(MenuItem *item)
|
||||
{
|
||||
item->fMenu = NULL;
|
||||
fItems.Remove(item);
|
||||
fCount--;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Menu::Draw(MenuItem *item)
|
||||
{
|
||||
if (!IsHidden())
|
||||
platform_update_menu_item(this, item);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Menu::Run()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static Menu *
|
||||
add_boot_volume_menu(Directory *bootVolume)
|
||||
{
|
||||
Menu *menu = new Menu(CHOICE_MENU, "Select Boot Volume");
|
||||
MenuItem *item;
|
||||
void *cookie;
|
||||
|
||||
if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
|
||||
@ -32,18 +287,62 @@ user_menu(Directory **_bootVolume)
|
||||
continue;
|
||||
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
if (volume->GetName(name, sizeof(name)) == B_OK)
|
||||
printf("%ld) /%s\n", index++, name);
|
||||
|
||||
// ToDo: for now, just choose the first volume as boot volume
|
||||
if (*_bootVolume == NULL)
|
||||
*_bootVolume = volume;
|
||||
if (volume->GetName(name, sizeof(name)) == B_OK) {
|
||||
menu->AddItem(item = new MenuItem(name));
|
||||
if (volume == bootVolume) {
|
||||
item->SetMarked(true);
|
||||
item->Select(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
gRoot->Close(cookie);
|
||||
}
|
||||
puts("(it always tries to boot from the first for now...)");
|
||||
|
||||
platform_switch_to_logo();
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(item = new MenuItem("Rescan volumes"));
|
||||
menu->AddItem(item = new MenuItem("Return to main manu"));
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
static Menu *
|
||||
add_safe_mode_menu()
|
||||
{
|
||||
Menu *safeMenu = new Menu(SAFE_MODE_MENU, "Safe Mode Options");
|
||||
MenuItem *item;
|
||||
|
||||
safeMenu->AddItem(item = new MenuItem("Disable user add-ons"));
|
||||
item->SetType(MENU_ITEM_MARKABLE);
|
||||
|
||||
platform_add_menus(safeMenu);
|
||||
|
||||
safeMenu->AddSeparatorItem();
|
||||
safeMenu->AddItem(item = new MenuItem("Return to main menu"));
|
||||
|
||||
return safeMenu;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
user_menu(Directory **_bootVolume)
|
||||
{
|
||||
Menu *menu = new Menu(MAIN_MENU);
|
||||
MenuItem *item;
|
||||
|
||||
// Add boot volume
|
||||
menu->AddItem(item = new MenuItem("Select boot volume", add_boot_volume_menu(*_bootVolume)));
|
||||
|
||||
// Add safe mode
|
||||
menu->AddItem(item = new MenuItem("Select safe mode options", add_safe_mode_menu()));
|
||||
|
||||
// Add platform dependent menus
|
||||
platform_add_menus(menu);
|
||||
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(item = new MenuItem("Continue booting"));
|
||||
|
||||
platform_run_menu(menu);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user