1/* ----------------------------------------------------------------------- *
2 *
3 *   Copyright 2009 Erwan Velu - All Rights Reserved
4 *
5 *   Permission is hereby granted, free of charge, to any person
6 *   obtaining a copy of this software and associated documentation
7 *   files (the "Software"), to deal in the Software without
8 *   restriction, including without limitation the rights to use,
9 *   copy, modify, merge, publish, distribute, sublicense, and/or
10 *   sell copies of the Software, and to permit persons to whom
11 *   the Software is furnished to do so, subject to the following
12 *   conditions:
13 *
14 *   The above copyright notice and this permission notice shall
15 *   be included in all copies or substantial portions of the Software.
16 *
17 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 *   OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * -----------------------------------------------------------------------
27 */
28
29#include <unistd.h>
30#include <memory.h>
31#include <syslinux/reboot.h>
32#include "hdt-menu.h"
33
34int start_menu_mode(struct s_hardware *hardware, char *version_string)
35{
36    struct s_hdt_menu hdt_menu;
37
38    memset(&hdt_menu, 0, sizeof(hdt_menu));
39
40    /* Setup the menu system */
41    setup_menu(version_string);
42
43    /* Compute all submenus */
44    compute_submenus(&hdt_menu, hardware);
45
46    /* Compute the main menu */
47    compute_main_menu(&hdt_menu, hardware);
48
49#ifdef WITH_MENU_DISPLAY
50    t_menuitem *curr;
51    char cmd[160];
52
53    if (!quiet)
54	more_printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
55    curr = showmenus(hdt_menu.main_menu.menu);
56    /* When we exit the menu, do we have something to do? */
57    if (curr) {
58	/* When want to execute something */
59	if (curr->action == OPT_RUN) {
60	    /* Tweak, we want to switch to the cli */
61	    if (!strncmp
62		(curr->data, HDT_SWITCH_TO_CLI, sizeof(HDT_SWITCH_TO_CLI))) {
63		return HDT_RETURN_TO_CLI;
64	    }
65	    /* Tweak, we want to start the dump mode */
66	    if (!strncmp
67		(curr->data, HDT_DUMP, sizeof(HDT_DUMP))) {
68		    dump(hardware);
69	        return 0;
70	    }
71	    if (!strncmp
72		(curr->data, HDT_REBOOT, sizeof(HDT_REBOOT))) {
73		syslinux_reboot(1);
74	    }
75	    strcpy(cmd, curr->data);
76
77	    /* Use specific syslinux call if needed */
78	    if (issyslinux())
79		runsyslinuxcmd(cmd);
80	    else
81		csprint(cmd, 0x07);
82	    return 1;		// Should not happen when run from SYSLINUX
83	}
84    }
85#endif
86    return 0;
87}
88
89/* In the menu system, what to do on keyboard timeout */
90TIMEOUTCODE ontimeout(void)
91{
92    // beep();
93    return CODE_WAIT;
94}
95
96/* Keyboard handler for the menu system */
97void keys_handler(t_menusystem * ms
98		  __attribute__ ((unused)), t_menuitem * mi, int scancode)
99{
100    int nr, nc;
101
102    /* 0xFFFF is an invalid helpid */
103    if (scancode == KEY_F1 && mi->helpid != 0xFFFF) {
104	runhelpsystem(mi->helpid);
105    }
106
107    /*
108     * If user hit TAB, and item is an "executable" item
109     * and user has privileges to edit it, edit it in place.
110     */
111    if ((scancode == KEY_TAB) && (mi->action == OPT_RUN)) {
112//(isallowed(username,"editcmd") || isallowed(username,"root"))) {
113	if (getscreensize(1, &nr, &nc)) {
114	    /* Unknown screen size? */
115	    nc = 80;
116	    nr = 24;
117	}
118	/* User typed TAB and has permissions to edit command line */
119	gotoxy(EDITPROMPT, 1);
120	csprint("Command line:", 0x07);
121	editstring(mi->data, ACTIONLEN);
122	gotoxy(EDITPROMPT, 1);
123	cprint(' ', 0x07, nc - 1);
124    }
125}
126
127/* Setup the Menu system */
128void setup_menu(char *version)
129{
130    /* Creating the menu */
131    init_menusystem(version);
132    set_window_size(0, 0, 25, 80);
133
134    /* Do not use inactive attributes - they make little sense for HDT */
135    set_normal_attr(-1, -1, 0x17, 0x1F);
136
137    /* Register the menusystem handler */
138    // reg_handler(HDLR_SCREEN,&msys_handler);
139    reg_handler(HDLR_KEYS, &keys_handler);
140
141    /* Register the ontimeout handler, with a time out of 10 seconds */
142    reg_ontimeout(ontimeout, 1000, 0);
143}
144
145/* Compute Main' submenus */
146void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
147{
148
149    /* Compute this menu if a DMI table exists */
150    if (hardware->is_dmi_valid) {
151	if (hardware->dmi.ipmi.filled == true)
152	    compute_ipmi(&hdt_menu->ipmi_menu, &hardware->dmi);
153	if (hardware->dmi.base_board.filled == true)
154	    compute_motherboard(&(hdt_menu->mobo_menu), &(hardware->dmi));
155	if (hardware->dmi.chassis.filled == true)
156	    compute_chassis(&(hdt_menu->chassis_menu), &(hardware->dmi));
157	if (hardware->dmi.system.filled == true)
158	    compute_system(&(hdt_menu->system_menu), &(hardware->dmi));
159	compute_memory(hdt_menu, &(hardware->dmi), hardware);
160	if (hardware->dmi.bios.filled == true)
161	    compute_bios(&(hdt_menu->bios_menu), &(hardware->dmi));
162	if (hardware->dmi.battery.filled == true)
163	    compute_battery(&(hdt_menu->battery_menu), &(hardware->dmi));
164    }
165
166    compute_processor(&(hdt_menu->cpu_menu), hardware);
167    compute_vpd(&(hdt_menu->vpd_menu), hardware);
168    compute_disks(hdt_menu, hardware);
169
170    compute_PCI(hdt_menu, hardware);
171    compute_PXE(&(hdt_menu->pxe_menu), hardware);
172    compute_kernel(&(hdt_menu->kernel_menu), hardware);
173
174    compute_summarymenu(&(hdt_menu->summary_menu), hardware);
175    compute_syslinuxmenu(&(hdt_menu->syslinux_menu), hardware);
176    compute_VESA(hdt_menu, hardware);
177    compute_ACPI(hdt_menu, hardware);
178    compute_aboutmenu(&(hdt_menu->about_menu));
179}
180
181void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
182{
183    char menu_item[64];
184    /* Let's count the number of menus we have */
185    hdt_menu->total_menu_count = 0;
186    hdt_menu->main_menu.items_count = 0;
187
188    hdt_menu->main_menu.menu = add_menu(" Main Menu ", -1);
189    set_item_options(-1, 24);
190
191    snprintf(menu_item, sizeof(menu_item), "PC<I> Devices(%2d)\n",
192	     hardware->nb_pci_devices);
193    add_item(menu_item, "PCI Devices Menu", OPT_SUBMENU, NULL,
194	     hdt_menu->pci_menu.menu);
195    hdt_menu->main_menu.items_count++;
196    hdt_menu->total_menu_count += hdt_menu->pci_menu.items_count;
197
198    if (hdt_menu->disk_menu.items_count > 0) {
199	snprintf(menu_item, sizeof(menu_item), "<D>isks      (%2d)\n",
200		 hdt_menu->disk_menu.items_count);
201	add_item(menu_item, "Disks Menu", OPT_SUBMENU, NULL,
202		 hdt_menu->disk_menu.menu);
203	hdt_menu->main_menu.items_count++;
204	hdt_menu->total_menu_count += hdt_menu->disk_menu.items_count;
205    }
206
207    snprintf(menu_item, sizeof(menu_item), "<M>emory\n");
208    add_item(menu_item, "Memory Menu", OPT_SUBMENU, NULL,
209	     hdt_menu->memory_menu.menu);
210    hdt_menu->main_menu.items_count++;
211    hdt_menu->total_menu_count += hdt_menu->memory_menu.items_count;
212
213    add_item("<P>rocessor", "Main Processor Menu", OPT_SUBMENU, NULL,
214	     hdt_menu->cpu_menu.menu);
215    hdt_menu->main_menu.items_count++;
216
217    if (hardware->is_dmi_valid) {
218	if (hardware->dmi.base_board.filled == true) {
219	    add_item("M<o>therboard", "Motherboard Menu",
220		     OPT_SUBMENU, NULL, hdt_menu->mobo_menu.menu);
221	    hdt_menu->main_menu.items_count++;
222	}
223
224	if (hardware->dmi.bios.filled == true) {
225	    add_item("<B>ios", "Bios Menu", OPT_SUBMENU, NULL,
226		     hdt_menu->bios_menu.menu);
227	    hdt_menu->main_menu.items_count++;
228	}
229
230	if (hardware->dmi.chassis.filled == true) {
231	    add_item("<C>hassis", "Chassis Menu", OPT_SUBMENU, NULL,
232		     hdt_menu->chassis_menu.menu);
233	    hdt_menu->main_menu.items_count++;
234	}
235
236	if (hardware->dmi.system.filled == true) {
237	    add_item("<S>ystem", "System Menu", OPT_SUBMENU, NULL,
238		     hdt_menu->system_menu.menu);
239	    hdt_menu->main_menu.items_count++;
240	}
241
242	if (hardware->dmi.battery.filled == true) {
243	    add_item("Ba<t>tery", "Battery Menu", OPT_SUBMENU, NULL,
244		     hdt_menu->battery_menu.menu);
245	    hdt_menu->main_menu.items_count++;
246	}
247	if (hardware->dmi.ipmi.filled == true) {
248	    add_item("I<P>MI", "IPMI Menu", OPT_SUBMENU, NULL,
249		     hdt_menu->ipmi_menu.menu);
250	    hdt_menu->main_menu.items_count++;
251	}
252    }
253
254    if (hardware->is_vpd_valid == true) {
255	add_item("<V>PD", "VPD Information Menu", OPT_SUBMENU, NULL,
256		 hdt_menu->vpd_menu.menu);
257	hdt_menu->main_menu.items_count++;
258    }
259
260    if (hardware->is_pxe_valid == true) {
261	add_item("P<X>E", "PXE Information Menu", OPT_SUBMENU, NULL,
262		 hdt_menu->pxe_menu.menu);
263	hdt_menu->main_menu.items_count++;
264    }
265
266    if (hardware->is_vesa_valid == true) {
267	add_item("<V>ESA", "VESA Information Menu", OPT_SUBMENU, NULL,
268		 hdt_menu->vesa_menu.menu);
269	hdt_menu->main_menu.items_count++;
270    }
271
272    if (hardware->is_acpi_valid == true) {
273	add_item("<A>CPI", "ACPI Menu", OPT_SUBMENU, NULL,
274		 hdt_menu->acpi_menu.menu);
275	hdt_menu->main_menu.items_count++;
276    }
277
278    add_item("", "", OPT_SEP, "", 0);
279
280    if ((hardware->modules_pcimap_return_code != -ENOMODULESPCIMAP) ||
281	(hardware->modules_alias_return_code != -ENOMODULESALIAS)) {
282	add_item("<K>ernel Modules", "Kernel Modules Menu", OPT_SUBMENU,
283		 NULL, hdt_menu->kernel_menu.menu);
284	hdt_menu->main_menu.items_count++;
285    }
286
287    add_item("S<y>slinux", "Syslinux Information Menu", OPT_SUBMENU, NULL,
288	     hdt_menu->syslinux_menu.menu);
289    hdt_menu->main_menu.items_count++;
290    add_item("S<u>mmary", "Summary Information Menu", OPT_SUBMENU, NULL,
291	     hdt_menu->summary_menu.menu);
292    hdt_menu->main_menu.items_count++;
293
294    add_item("", "", OPT_SEP, "", 0);
295
296    add_item("S<w>itch to CLI", "Switch to Command Line", OPT_RUN,
297	     HDT_SWITCH_TO_CLI, 0);
298
299    if (hardware->is_pxe_valid == true) {
300    add_item("<D>ump to tftp", "Dump to tftp", OPT_RUN,
301	     HDT_DUMP, 0);
302    }
303
304    add_item("<A>bout", "About Menu", OPT_SUBMENU, NULL,
305	     hdt_menu->about_menu.menu);
306    add_item("<R>eboot", "Reboot", OPT_RUN, HDT_REBOOT, 0);
307    add_item("E<x>it", "Exit", OPT_EXITMENU, NULL, 0);
308    hdt_menu->main_menu.items_count++;
309
310    hdt_menu->total_menu_count += hdt_menu->main_menu.items_count;
311}
312