* Copyright 2004-2012, Axel DΓΆrfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include "RootFileSystem.h"
#include <boot/platform.h>
#include <boot/vfs.h>
#include <boot/menu.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
const char *kNormalColor = "\33[0m";
const char *kDisabledColor = "\33[31m";
const char *kTitleColor = "\33[34m";
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) {
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;
while ((item = iterator.Next()) != NULL) {
if (item->Type() == MENU_ITEM_SEPARATOR) {
putchar('\n');
i++;
continue;
}
print_item_at(i++, item, false);
}
int32 selected = -1;
menu->FindSelected(&selected);
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;
}
void
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;
}
}
void
platform_update_menu_item(Menu *menu, MenuItem *item)
{
}
void
platform_run_menu(Menu *menu)
{
int32 selected;
MenuItem *item = menu->FindSelected(&selected);
if (item == NULL) {
selected = menu->CountItems() - 1;
item = menu->ItemAt(selected);
if (item != NULL)
item->Select(true);
}
while (true) {
draw_menu(menu);
char buffer[32];
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
return;
if (buffer[0] != '\n')
selected = atoi(buffer);
item = menu->ItemAt(selected);
if (item == NULL) {
printf("Invalid choice.");
continue;
}
item->Select(true);
if (item->Submenu() != NULL) {
menu->Hide();
platform_run_menu(item->Submenu());
if (item->Target() != NULL)
(*item->Target())(menu, item);
menu->FindSelected(&selected);
menu->Show();
} else if (item->Type() == MENU_ITEM_MARKABLE) {
item->SetMarked(!item->IsMarked());
if (item->Target() != NULL)
(*item->Target())(menu, item);
} else if (item->Target() == NULL || (*item->Target())(menu, item))
break;
}
}
size_t
platform_get_user_input_text(Menu* menu, MenuItem* item, char* buffer,
size_t bufferSize)
{
return 0;
}