xref: /haiku/src/tests/system/boot/loader/platform_menu.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 /*
2  * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "RootFileSystem.h"
8 
9 #include <boot/platform.h>
10 #include <boot/vfs.h>
11 #include <boot/menu.h>
12 
13 #include <fcntl.h>
14 #include <stdio.h>
15 
16 
17 const char *kNormalColor = "\33[0m";
18 const char *kDisabledColor = "\33[31m";	// red
19 const char *kTitleColor = "\33[34m";	// blue
20 
21 
22 extern RootFileSystem *gRoot;
23 bool gShowMenu = false;
24 
25 
26 static void
27 print_item_at(int32 line, MenuItem *item, bool clearHelp = true)
28 {
29 	if (!item->IsEnabled())
30 		printf("%s    ", kDisabledColor);
31 	else
32 		printf("%2ld. ", line);
33 
34 	if (item->Type() == MENU_ITEM_MARKABLE) {
35 		printf(" [");
36 		printf("%c", item->IsMarked() ? 'x' : ' ');
37 		printf("] ");
38 	} else
39 		printf(" ");
40 
41 	printf(item->Label());
42 
43 	if (item->Submenu() && item->Submenu()->Type() == CHOICE_MENU) {
44 		// show the current choice (if any)
45 		Menu *subMenu = item->Submenu();
46 		MenuItem *subItem = NULL;
47 
48 		for (int32 i = subMenu->CountItems(); i-- > 0; ) {
49 			subItem = subMenu->ItemAt(i);
50 			if (subItem != NULL && subItem->IsMarked())
51 				break;
52 		}
53 
54 		printf(" (Current: ");
55 		printf(subItem != NULL ? subItem->Label() : "None");
56 		putchar(')');
57 	}
58 
59 	if (!item->IsEnabled())
60 		printf(kNormalColor);
61 	putchar('\n');
62 }
63 
64 
65 static void
66 draw_menu(Menu *menu)
67 {
68 	printf("\n %s--- ", kTitleColor);
69 	if (menu->Title())
70 		printf("%s", menu->Title());
71 	else
72 		printf("Welcome To The Haiku Bootloader");
73 	printf(" ---%s\n\n", kNormalColor);
74 
75 	MenuItemIterator iterator = menu->ItemIterator();
76 	MenuItem *item;
77 	int32 i = 0;
78 
79 	while ((item = iterator.Next()) != NULL) {
80 		if (item->Type() == MENU_ITEM_SEPARATOR) {
81 			putchar('\n');
82 			i++;
83 			continue;
84 		}
85 
86 		print_item_at(i++, item, false);
87 	}
88 
89 	int32 selected = -1;
90 	menu->FindSelected(&selected);
91 	printf("\n[%ld]? ", selected);
92 }
93 
94 
95 bool
96 dump_devices_hook(Menu *menu, MenuItem *item)
97 {
98 	puts("List of known root directories:");
99 
100 	void *cookie;
101 	if (gRoot->Open(&cookie, O_RDONLY) == B_OK) {
102 		Directory *directory;
103 		while (gRoot->GetNextNode(cookie, (Node **)&directory) == B_OK) {
104 			char name[256];
105 			if (directory->GetName(name, sizeof(name)) == B_OK)
106 				printf("%s:: %s (%p)%s\n", kTitleColor, name, directory, kNormalColor);
107 
108 			void *subCookie;
109 			if (directory->Open(&subCookie, O_RDONLY) == B_OK) {
110 				while (directory->GetNextEntry(subCookie, name, sizeof(name)) == B_OK) {
111 					printf("\t%s\n", name);
112 				}
113 				directory->Close(subCookie);
114 			}
115 		}
116 		gRoot->Close(cookie);
117 	}
118 
119 	return false;
120 }
121 
122 
123 //	#pragma mark -
124 
125 
126 void
127 platform_add_menus(Menu *menu)
128 {
129 	MenuItem *item;
130 
131 	switch (menu->Type()) {
132 		case MAIN_MENU:
133 			menu->AddItem(item = new MenuItem("Dump all recognized volumes"));
134 			item->SetTarget(dump_devices_hook);
135 			break;
136 		default:
137 			break;
138 	}
139 }
140 
141 
142 void
143 platform_update_menu_item(Menu *menu, MenuItem *item)
144 {
145 }
146 
147 
148 void
149 platform_run_menu(Menu *menu)
150 {
151 	// Get selected entry, or select the last one, if there is none
152 	int32 selected;
153 	MenuItem *item = menu->FindSelected(&selected);
154 	if (item == NULL) {
155 		selected = menu->CountItems() - 1;
156 		item = menu->ItemAt(selected);
157 		if (item != NULL)
158 			item->Select(true);
159 	}
160 
161 	while (true) {
162 		draw_menu(menu);
163 
164 		char buffer[32];
165 		if (fgets(buffer, sizeof(buffer), stdin) == NULL)
166 			return;
167 
168 		if (buffer[0] != '\n')
169 			selected = atoi(buffer);
170 
171 		item = menu->ItemAt(selected);
172 		item->Select(true);
173 
174 		// leave the menu
175 		if (item->Submenu() != NULL) {
176 			menu->Hide();
177 
178 			platform_run_menu(item->Submenu());
179 			if (item->Target() != NULL)
180 				(*item->Target())(menu, item);
181 
182 			// restore current menu
183 			menu->FindSelected(&selected);
184 			menu->Show();
185 		} else if (item->Type() == MENU_ITEM_MARKABLE) {
186 			// toggle state
187 			item->SetMarked(!item->IsMarked());
188 
189 			if (item->Target() != NULL)
190 				(*item->Target())(menu, item);
191 		} else if (item->Target() == NULL || (*item->Target())(menu, item))
192 			break;
193 	}
194 }
195 
196