2 -- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
3 -- All rights reserved.
5 -- Redistribution and use in source and binary forms, with or without
6 -- modification, are permitted provided that the following conditions
8 -- 1. Redistributions of source code must retain the above copyright
9 -- notice, this list of conditions and the following disclaimer.
10 -- 2. Redistributions in binary form must reproduce the above copyright
11 -- notice, this list of conditions and the following disclaimer in the
12 -- documentation and/or other materials provided with the distribution.
14 -- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 -- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 -- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 -- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 -- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 -- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 -- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 local core = require("core");
33 local color = require("color");
34 local config = require("config");
35 local screen = require("screen");
36 local drawer = require("drawer");
42 local carousel_choices = {};
45 --rooted at menu.welcome
46 --submenu declarations:
51 -- return to welcome menu
53 entry_type = core.MENU_RETURN,
55 return "Back to main menu"..color.highlight(" [Backspace]");
61 entry_type = core.MENU_ENTRY,
63 return "Load System "..color.highlight("D").."efaults";
72 entry_type = core.MENU_SEPARATOR,
79 entry_type = core.MENU_SEPARATOR,
81 return "Boot Options:";
87 entry_type = core.MENU_ENTRY,
89 return OnOff(color.highlight("A").."CPI :", core.acpi);
98 entry_type = core.MENU_ENTRY,
100 return OnOff("Safe "..color.highlight("M").."ode :", core.sm);
109 entry_type = core.MENU_ENTRY,
111 return OnOff(color.highlight("S").."ingle user:", core.su);
114 core.setSingleUser();
120 entry_type = core.MENU_ENTRY,
122 return OnOff(color.highlight("V").."erbose :", core.verbose);
134 entry_type = core.MENU_ENTRY,
136 return color.highlight("B").."oot Multi user "..color.highlight("[Enter]");
139 core.setSingleUser(false);
147 entry_type = core.MENU_ENTRY,
149 return "Boot "..color.highlight("S").."ingle user";
152 core.setSingleUser(true);
158 -- escape to interpreter
160 entry_type = core.MENU_RETURN,
162 return color.highlight("Esc").."ape to loader prompt";
164 alias = {core.KEYSTR_ESCAPE}
169 entry_type = core.MENU_ENTRY,
171 return color.highlight("R").."eboot";
174 loader.perform("reboot");
181 entry_type = core.MENU_SEPARATOR,
188 entry_type = core.MENU_SEPARATOR,
196 entry_type = core.MENU_CAROUSEL_ENTRY,
197 carousel_id = "kernel",
198 items = core.kernelList,
199 name = function(idx, choice, all_choices)
200 if #all_choices == 0 then
204 local kernel_name = color.escapef(color.GREEN) ..
205 choice .. color.default();
207 kernel_name = "default/" .. kernel_name;
209 return color.highlight("K").."ernel: " .. kernel_name ..
211 " of " .. #all_choices .. ")";
213 func = function(choice)
214 config.reload(choice);
221 entry_type = core.MENU_SUBMENU,
223 return "Boot "..color.highlight("O").."ptions";
226 return menu.boot_options;
233 -- The first item in every carousel is always the default item.
234 function menu.getCarouselIndex(id)
235 local val = carousel_choices[id];
242 function menu.setCarouselIndex(id, idx)
243 carousel_choices[id] = idx;
248 if (menu.skip()) then
260 local alias_table = drawer.drawscreen(m);
266 local key = io.getchar();
268 -- Special key behaviors
269 if ((key == core.KEY_BACKSPACE) or (key == core.KEY_DELETE)) and
270 (m ~= menu.welcome) then
272 elseif (key == core.KEY_ENTER) then
277 key = string.char(key)
278 -- check to see if key is an alias
279 local sel_entry = nil;
280 for k, v in pairs(alias_table) do
286 -- if we have an alias do the assigned action:
287 if(sel_entry ~= nil) then
288 if (sel_entry.entry_type == core.MENU_ENTRY) then
291 elseif (sel_entry.entry_type == core.MENU_CAROUSEL_ENTRY) then
292 -- carousel (rotating) functionality
293 local carid = sel_entry.carousel_id;
294 local caridx = menu.getCarouselIndex(carid);
295 local choices = sel_entry.items();
297 caridx = (caridx % #choices) + 1;
298 menu.setCarouselIndex(carid, caridx);
299 sel_entry.func(choices[caridx]);
300 elseif (sel_entry.entry_type == core.MENU_SUBMENU) then
302 cont = menu.run(sel_entry.submenu());
303 elseif (sel_entry.entry_type == core.MENU_RETURN) then
307 -- if we got an alias key the screen is out of date:
310 alias_table = drawer.drawscreen(m);
314 if (m == menu.welcome) then
316 print("Exiting menu!");
324 if core.bootserial() then
327 local c = string.lower(loader.getenv("console") or "");
328 if (c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil then
332 c = string.lower(loader.getenv("beastie_disable") or "");
333 print("beastie_disable", c);
337 function menu.autoboot()
338 if menu.already_autoboot == true then
341 menu.already_autoboot = true;
343 local ab = loader.getenv("autoboot_delay");
344 if ab == "NO" or ab == "no" then
347 ab = tonumber(ab) or 10;
349 local x = loader.getenv("loader_menu_timeout_x") or 5;
350 local y = loader.getenv("loader_menu_timeout_y") or 22;
352 local endtime = loader.time() + ab;
356 time = endtime - loader.time();
357 screen.setcursor(x, y);
358 print("Autoboot in "..time.." seconds, hit [Enter] to boot"
359 .." or any other key to stop ");
362 local ch = io.getchar();
363 if ch == core.KEY_ENTER then
366 -- prevent autoboot when escaping to interpreter
367 loader.setenv("autoboot_delay", "NO");
368 -- erase autoboot msg
369 screen.setcursor(0, y);
383 function OnOff(str, b)
385 return str .. color.escapef(color.GREEN).."On"..color.escapef(color.WHITE);
387 return str .. color.escapef(color.RED).."off"..color.escapef(color.WHITE);