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