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 = {};
44 -- loader menu tree is rooted at menu.welcome
48 -- return to welcome menu
50 entry_type = core.MENU_RETURN,
52 return "Back to main menu" ..
53 color.highlight(" [Backspace]");
59 entry_type = core.MENU_ENTRY,
61 return "Load System " .. color.highlight("D") ..
71 entry_type = core.MENU_SEPARATOR,
78 entry_type = core.MENU_SEPARATOR,
80 return "Boot Options:";
86 entry_type = core.MENU_ENTRY,
88 return OnOff(color.highlight("A") .. "CPI :",
98 entry_type = core.MENU_ENTRY,
100 return OnOff("Safe " .. color.highlight("M") ..
110 entry_type = core.MENU_ENTRY,
112 return OnOff(color.highlight("S") .. "ingle user:",
116 core.setSingleUser();
122 entry_type = core.MENU_ENTRY,
124 return OnOff(color.highlight("V") .. "erbose :",
137 local menu_entries = menu.welcome.all_entries;
138 -- Swap the first two menu items on single user boot
139 if (core.isSingleUserBoot()) then
140 local multiuser = menu_entries[1];
141 local singleuser = menu_entries[2];
143 menu_entries[2] = multiuser;
144 menu_entries[1] = singleuser;
151 entry_type = core.MENU_ENTRY,
153 return color.highlight("B") .. "oot Multi user " ..
154 color.highlight("[Enter]");
157 core.setSingleUser(false);
165 entry_type = core.MENU_ENTRY,
167 return "Boot " .. color.highlight("S") .. "ingle user";
170 core.setSingleUser(true);
176 -- escape to interpreter
178 entry_type = core.MENU_RETURN,
180 return color.highlight("Esc") .. "ape to loader prompt";
183 loader.setenv("autoboot_delay", "NO");
185 alias = {core.KEYSTR_ESCAPE}
190 entry_type = core.MENU_ENTRY,
192 return color.highlight("R") .. "eboot";
195 loader.perform("reboot");
202 entry_type = core.MENU_SEPARATOR,
209 entry_type = core.MENU_SEPARATOR,
217 entry_type = core.MENU_CAROUSEL_ENTRY,
218 carousel_id = "kernel",
219 items = core.kernelList,
220 name = function(idx, choice, all_choices)
221 if (#all_choices == 0) then
225 local is_default = (idx == 1);
226 local kernel_name = "";
229 name_color = color.escapef(color.GREEN);
230 kernel_name = "default/";
232 name_color = color.escapef(color.BLUE);
234 kernel_name = kernel_name .. name_color .. choice ..
236 return color.highlight("K").."ernel: " .. kernel_name ..
238 " of " .. #all_choices .. ")";
240 func = function(idx, choice, all_choices)
241 config.selectkernel(choice);
248 entry_type = core.MENU_SUBMENU,
250 return "Boot " .. color.highlight("O") .. "ptions";
253 return menu.boot_options;
260 -- The first item in every carousel is always the default item.
261 function menu.getCarouselIndex(id)
262 local val = carousel_choices[id];
269 function menu.setCarouselIndex(id, idx)
270 carousel_choices[id] = idx;
275 if (menu.skip()) then
287 local alias_table = drawer.drawscreen(m);
293 local key = io.getchar();
295 -- Special key behaviors
296 if ((key == core.KEY_BACKSPACE) or (key == core.KEY_DELETE)) and
297 (m ~= menu.welcome) then
299 elseif (key == core.KEY_ENTER) then
304 key = string.char(key)
305 -- check to see if key is an alias
306 local sel_entry = nil;
307 for k, v in pairs(alias_table) do
313 -- if we have an alias do the assigned action:
314 if (sel_entry ~= nil) then
315 if (sel_entry.entry_type == core.MENU_ENTRY) then
318 elseif (sel_entry.entry_type == core.MENU_CAROUSEL_ENTRY) then
319 -- carousel (rotating) functionality
320 local carid = sel_entry.carousel_id;
321 local caridx = menu.getCarouselIndex(carid);
322 local choices = sel_entry.items();
324 if (#choices > 0) then
325 caridx = (caridx % #choices) + 1;
326 menu.setCarouselIndex(carid, caridx);
327 sel_entry.func(caridx, choices[caridx],
330 elseif (sel_entry.entry_type == core.MENU_SUBMENU) then
332 cont = menu.run(sel_entry.submenu());
333 elseif (sel_entry.entry_type == core.MENU_RETURN) then
334 -- allow entry to have a function/side effect
335 if (sel_entry.func ~= nil) then
341 -- if we got an alias key the screen is out of date:
344 alias_table = drawer.drawscreen(m);
348 if (m == menu.welcome) then
350 print("Exiting menu!");
359 if (core.isSerialBoot()) then
362 local c = string.lower(loader.getenv("console") or "");
363 if ((c:match("^efi[ ;]") or c:match("[ ;]efi[ ;]")) ~= nil) then
367 c = string.lower(loader.getenv("beastie_disable") or "");
368 print("beastie_disable", c);
372 function menu.autoboot()
373 if (menu.already_autoboot == true) then
376 menu.already_autoboot = true;
378 local ab = loader.getenv("autoboot_delay");
379 if (ab ~= nil) and (ab:lower() == "no") then
381 elseif (tonumber(ab) == -1) then
384 ab = tonumber(ab) or 10;
386 local x = loader.getenv("loader_menu_timeout_x") or 5;
387 local y = loader.getenv("loader_menu_timeout_y") or 22;
389 local endtime = loader.time() + ab;
393 time = endtime - loader.time();
394 screen.setcursor(x, y);
395 print("Autoboot in " .. time ..
396 " seconds, hit [Enter] to boot" ..
397 " or any other key to stop ");
399 if (io.ischar()) then
400 local ch = io.getchar();
401 if (ch == core.KEY_ENTER) then
404 -- erase autoboot msg
405 screen.setcursor(0, y);
419 function OnOff(str, b)
421 return str .. color.escapef(color.GREEN) .. "On" ..
422 color.escapef(color.WHITE);
424 return str .. color.escapef(color.RED) .. "off" ..
425 color.escapef(color.WHITE);