xref: /freebsd/stand/lua/drawer.lua (revision e19d9a9b6e44e15087a140a26ab3e24b07f6ba56)
1088b4f5fSWarner Losh--
272e39d71SKyle Evans-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD
372e39d71SKyle Evans--
4088b4f5fSWarner Losh-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org>
5df74a61fSKyle Evans-- Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
6088b4f5fSWarner Losh-- All rights reserved.
7088b4f5fSWarner Losh--
8088b4f5fSWarner Losh-- Redistribution and use in source and binary forms, with or without
9088b4f5fSWarner Losh-- modification, are permitted provided that the following conditions
10088b4f5fSWarner Losh-- are met:
11088b4f5fSWarner Losh-- 1. Redistributions of source code must retain the above copyright
12088b4f5fSWarner Losh--    notice, this list of conditions and the following disclaimer.
13088b4f5fSWarner Losh-- 2. Redistributions in binary form must reproduce the above copyright
14088b4f5fSWarner Losh--    notice, this list of conditions and the following disclaimer in the
15088b4f5fSWarner Losh--    documentation and/or other materials provided with the distribution.
16088b4f5fSWarner Losh--
17088b4f5fSWarner Losh-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18088b4f5fSWarner Losh-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19088b4f5fSWarner Losh-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20088b4f5fSWarner Losh-- ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21088b4f5fSWarner Losh-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22088b4f5fSWarner Losh-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23088b4f5fSWarner Losh-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24088b4f5fSWarner Losh-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25088b4f5fSWarner Losh-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26088b4f5fSWarner Losh-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27088b4f5fSWarner Losh-- SUCH DAMAGE.
28088b4f5fSWarner Losh--
29088b4f5fSWarner Losh-- $FreeBSD$
30088b4f5fSWarner Losh--
31088b4f5fSWarner Losh
32aedd6be5SKyle Evanslocal color = require("color")
33aedd6be5SKyle Evanslocal config = require("config")
34aedd6be5SKyle Evanslocal core = require("core")
35aedd6be5SKyle Evanslocal screen = require("screen")
36088b4f5fSWarner Losh
37aedd6be5SKyle Evanslocal drawer = {}
38c8518398SKyle Evans
391091c8feSKyle Evanslocal fbsd_brand
40aedd6be5SKyle Evanslocal none
4102122e53SKyle Evans
42a9edc01bSKyle Evanslocal menu_name_handlers
43a9edc01bSKyle Evanslocal branddefs
44a9edc01bSKyle Evanslocal logodefs
45a9edc01bSKyle Evanslocal brand_position
46a9edc01bSKyle Evanslocal logo_position
47a9edc01bSKyle Evanslocal menu_position
48a9edc01bSKyle Evanslocal frame_size
49a9edc01bSKyle Evanslocal default_shift
50a9edc01bSKyle Evanslocal shift
51a9edc01bSKyle Evans
52322a2dddSKyle Evanslocal function menuEntryName(drawing_menu, entry)
53a9edc01bSKyle Evans	local name_handler = menu_name_handlers[entry.entry_type]
54e15abd1fSKyle Evans
559f71d421SKyle Evans	if name_handler ~= nil then
56aedd6be5SKyle Evans		return name_handler(drawing_menu, entry)
57e15abd1fSKyle Evans	end
58a51f9f0cSKyle Evans	if type(entry.name) == "function" then
59aedd6be5SKyle Evans		return entry.name()
60e15abd1fSKyle Evans	end
61a51f9f0cSKyle Evans	return entry.name
62a51f9f0cSKyle Evansend
63e15abd1fSKyle Evans
64546f18f3SKyle Evanslocal function processFile(gfxname)
65546f18f3SKyle Evans	if gfxname == nil then
66546f18f3SKyle Evans		return false, "Missing filename"
67546f18f3SKyle Evans	end
68546f18f3SKyle Evans
69546f18f3SKyle Evans	local ret = try_include('gfx-' .. gfxname)
70546f18f3SKyle Evans	if ret == nil then
71546f18f3SKyle Evans		return false, "Failed to include gfx-" .. gfxname
72546f18f3SKyle Evans	end
73546f18f3SKyle Evans
74546f18f3SKyle Evans	-- Legacy format
75546f18f3SKyle Evans	if type(ret) ~= "table" then
76546f18f3SKyle Evans		return true
77546f18f3SKyle Evans	end
78546f18f3SKyle Evans
79546f18f3SKyle Evans	for gfxtype, def in pairs(ret) do
80546f18f3SKyle Evans		if gfxtype == "brand" then
81546f18f3SKyle Evans			drawer.addBrand(gfxname, def)
82546f18f3SKyle Evans		elseif gfxtype == "logo" then
83546f18f3SKyle Evans			drawer.addLogo(gfxname, def)
84546f18f3SKyle Evans		else
85546f18f3SKyle Evans			return false, "Unknown graphics type '" .. gfxtype ..
86546f18f3SKyle Evans			    "'"
87546f18f3SKyle Evans		end
88546f18f3SKyle Evans	end
89546f18f3SKyle Evans
90546f18f3SKyle Evans	return true
91546f18f3SKyle Evansend
92546f18f3SKyle Evans
93e21e1dbeSKyle Evanslocal function getBranddef(brand)
94e21e1dbeSKyle Evans	if brand == nil then
95e21e1dbeSKyle Evans		return nil
96e21e1dbeSKyle Evans	end
97e21e1dbeSKyle Evans	-- Look it up
98a9edc01bSKyle Evans	local branddef = branddefs[brand]
99e21e1dbeSKyle Evans
100e21e1dbeSKyle Evans	-- Try to pull it in
101e21e1dbeSKyle Evans	if branddef == nil then
102546f18f3SKyle Evans		local res, err = processFile(brand)
103546f18f3SKyle Evans		if not res then
104546f18f3SKyle Evans			-- This fallback should go away after FreeBSD 13.
105e21e1dbeSKyle Evans			try_include('brand-' .. brand)
106546f18f3SKyle Evans			-- If the fallback also failed, print whatever error
107546f18f3SKyle Evans			-- we encountered in the original processing.
108546f18f3SKyle Evans			if branddefs[brand] == nil then
109546f18f3SKyle Evans				print(err)
110546f18f3SKyle Evans				return nil
111546f18f3SKyle Evans			end
112546f18f3SKyle Evans		end
113546f18f3SKyle Evans
114a9edc01bSKyle Evans		branddef = branddefs[brand]
115e21e1dbeSKyle Evans	end
116e21e1dbeSKyle Evans
117e21e1dbeSKyle Evans	return branddef
118e21e1dbeSKyle Evansend
119e21e1dbeSKyle Evans
1201091c8feSKyle Evanslocal function getLogodef(logo)
121bbb516aeSKyle Evans	if logo == nil then
122bbb516aeSKyle Evans		return nil
123bbb516aeSKyle Evans	end
1241091c8feSKyle Evans	-- Look it up
125a9edc01bSKyle Evans	local logodef = logodefs[logo]
1261091c8feSKyle Evans
1271091c8feSKyle Evans	-- Try to pull it in
1281091c8feSKyle Evans	if logodef == nil then
129546f18f3SKyle Evans		local res, err = processFile(logo)
130546f18f3SKyle Evans		if not res then
131546f18f3SKyle Evans			-- This fallback should go away after FreeBSD 13.
1321091c8feSKyle Evans			try_include('logo-' .. logo)
133546f18f3SKyle Evans			-- If the fallback also failed, print whatever error
134546f18f3SKyle Evans			-- we encountered in the original processing.
135546f18f3SKyle Evans			if logodefs[logo] == nil then
136546f18f3SKyle Evans				print(err)
137546f18f3SKyle Evans				return nil
138546f18f3SKyle Evans			end
139546f18f3SKyle Evans		end
140546f18f3SKyle Evans
141a9edc01bSKyle Evans		logodef = logodefs[logo]
1421091c8feSKyle Evans	end
1431091c8feSKyle Evans
1441091c8feSKyle Evans	return logodef
1451091c8feSKyle Evansend
1461091c8feSKyle Evans
1476112ee09SKyle Evanslocal function draw(x, y, logo)
1486112ee09SKyle Evans	for i = 1, #logo do
1496112ee09SKyle Evans		screen.setcursor(x, y + i - 1)
1506112ee09SKyle Evans		printc(logo[i])
1516112ee09SKyle Evans	end
1526112ee09SKyle Evansend
1536112ee09SKyle Evans
15412eaa305SKyle Evanslocal function drawmenu(menudef)
155a9edc01bSKyle Evans	local x = menu_position.x
156a9edc01bSKyle Evans	local y = menu_position.y
15712eaa305SKyle Evans
158a9edc01bSKyle Evans	x = x + shift.x
159a9edc01bSKyle Evans	y = y + shift.y
16012eaa305SKyle Evans
16112eaa305SKyle Evans	-- print the menu and build the alias table
16212eaa305SKyle Evans	local alias_table = {}
16312eaa305SKyle Evans	local entry_num = 0
16412eaa305SKyle Evans	local menu_entries = menudef.entries
16512eaa305SKyle Evans	local effective_line_num = 0
16612eaa305SKyle Evans	if type(menu_entries) == "function" then
16712eaa305SKyle Evans		menu_entries = menu_entries()
16812eaa305SKyle Evans	end
16912eaa305SKyle Evans	for _, e in ipairs(menu_entries) do
17012eaa305SKyle Evans		-- Allow menu items to be conditionally visible by specifying
17112eaa305SKyle Evans		-- a visible function.
17212eaa305SKyle Evans		if e.visible ~= nil and not e.visible() then
17312eaa305SKyle Evans			goto continue
17412eaa305SKyle Evans		end
17512eaa305SKyle Evans		effective_line_num = effective_line_num + 1
17612eaa305SKyle Evans		if e.entry_type ~= core.MENU_SEPARATOR then
17712eaa305SKyle Evans			entry_num = entry_num + 1
17812eaa305SKyle Evans			screen.setcursor(x, y + effective_line_num)
17912eaa305SKyle Evans
18012eaa305SKyle Evans			printc(entry_num .. ". " .. menuEntryName(menudef, e))
18112eaa305SKyle Evans
18212eaa305SKyle Evans			-- fill the alias table
18312eaa305SKyle Evans			alias_table[tostring(entry_num)] = e
18412eaa305SKyle Evans			if e.alias ~= nil then
18512eaa305SKyle Evans				for _, a in ipairs(e.alias) do
18612eaa305SKyle Evans					alias_table[a] = e
18712eaa305SKyle Evans				end
18812eaa305SKyle Evans			end
18912eaa305SKyle Evans		else
19012eaa305SKyle Evans			screen.setcursor(x, y + effective_line_num)
19112eaa305SKyle Evans			printc(menuEntryName(menudef, e))
19212eaa305SKyle Evans		end
19312eaa305SKyle Evans		::continue::
19412eaa305SKyle Evans	end
19512eaa305SKyle Evans	return alias_table
19612eaa305SKyle Evansend
19712eaa305SKyle Evans
19890a25417SKyle Evanslocal function defaultframe()
19990a25417SKyle Evans	if core.isSerialConsole() then
20090a25417SKyle Evans		return "ascii"
20190a25417SKyle Evans	end
20290a25417SKyle Evans	return "double"
20390a25417SKyle Evansend
20490a25417SKyle Evans
2053630506bSToomas Soomelocal function drawframe()
206a9edc01bSKyle Evans	local x = menu_position.x - 3
207a9edc01bSKyle Evans	local y = menu_position.y - 1
208a9edc01bSKyle Evans	local w = frame_size.w
209a9edc01bSKyle Evans	local h = frame_size.h
21012eaa305SKyle Evans
21190a25417SKyle Evans	local framestyle = loader.getenv("loader_menu_frame") or defaultframe()
21212eaa305SKyle Evans	local framespec = drawer.frame_styles[framestyle]
21312eaa305SKyle Evans	-- If we don't have a framespec for the current frame style, just don't
21412eaa305SKyle Evans	-- draw a box.
21512eaa305SKyle Evans	if framespec == nil then
2163630506bSToomas Soome		return false
21712eaa305SKyle Evans	end
21812eaa305SKyle Evans
21912eaa305SKyle Evans	local hl = framespec.horizontal
22012eaa305SKyle Evans	local vl = framespec.vertical
22112eaa305SKyle Evans
22212eaa305SKyle Evans	local tl = framespec.top_left
22312eaa305SKyle Evans	local bl = framespec.bottom_left
22412eaa305SKyle Evans	local tr = framespec.top_right
22512eaa305SKyle Evans	local br = framespec.bottom_right
22612eaa305SKyle Evans
227a9edc01bSKyle Evans	x = x + shift.x
228a9edc01bSKyle Evans	y = y + shift.y
22912eaa305SKyle Evans
2303630506bSToomas Soome	if core.isFramebufferConsole() and loader.term_drawrect ~= nil then
2313630506bSToomas Soome		loader.term_drawrect(x, y, x + w, y + h)
2323630506bSToomas Soome		return true
2333630506bSToomas Soome	end
2343630506bSToomas Soome
23512eaa305SKyle Evans	screen.setcursor(x, y); printc(tl)
23612eaa305SKyle Evans	screen.setcursor(x, y + h); printc(bl)
23712eaa305SKyle Evans	screen.setcursor(x + w, y); printc(tr)
23812eaa305SKyle Evans	screen.setcursor(x + w, y + h); printc(br)
23912eaa305SKyle Evans
24012eaa305SKyle Evans	screen.setcursor(x + 1, y)
24112eaa305SKyle Evans	for _ = 1, w - 1 do
24212eaa305SKyle Evans		printc(hl)
24312eaa305SKyle Evans	end
24412eaa305SKyle Evans
24512eaa305SKyle Evans	screen.setcursor(x + 1, y + h)
24612eaa305SKyle Evans	for _ = 1, w - 1 do
24712eaa305SKyle Evans		printc(hl)
24812eaa305SKyle Evans	end
24912eaa305SKyle Evans
25012eaa305SKyle Evans	for i = 1, h - 1 do
25112eaa305SKyle Evans		screen.setcursor(x, y + i)
25212eaa305SKyle Evans		printc(vl)
25312eaa305SKyle Evans		screen.setcursor(x + w, y + i)
25412eaa305SKyle Evans		printc(vl)
25512eaa305SKyle Evans	end
2563630506bSToomas Soome	return true
2573630506bSToomas Soomeend
25812eaa305SKyle Evans
2593630506bSToomas Soomelocal function drawbox()
2603630506bSToomas Soome	local x = menu_position.x - 3
2613630506bSToomas Soome	local y = menu_position.y - 1
2623630506bSToomas Soome	local w = frame_size.w
26312eaa305SKyle Evans	local menu_header = loader.getenv("loader_menu_title") or
26412eaa305SKyle Evans	    "Welcome to FreeBSD"
26512eaa305SKyle Evans	local menu_header_align = loader.getenv("loader_menu_title_align")
26612eaa305SKyle Evans	local menu_header_x
26712eaa305SKyle Evans
2683630506bSToomas Soome	x = x + shift.x
2693630506bSToomas Soome	y = y + shift.y
2703630506bSToomas Soome
2713630506bSToomas Soome	if drawframe(x, y, w) == false then
2723630506bSToomas Soome		return
2733630506bSToomas Soome	end
2743630506bSToomas Soome
27512eaa305SKyle Evans	if menu_header_align ~= nil then
27612eaa305SKyle Evans		menu_header_align = menu_header_align:lower()
27712eaa305SKyle Evans		if menu_header_align == "left" then
27812eaa305SKyle Evans			-- Just inside the left border on top
27912eaa305SKyle Evans			menu_header_x = x + 1
28012eaa305SKyle Evans		elseif menu_header_align == "right" then
28112eaa305SKyle Evans			-- Just inside the right border on top
28212eaa305SKyle Evans			menu_header_x = x + w - #menu_header
28312eaa305SKyle Evans		end
28412eaa305SKyle Evans	end
28512eaa305SKyle Evans	if menu_header_x == nil then
286994e1f40SKyle Evans		menu_header_x = x + (w // 2) - (#menu_header // 2)
28712eaa305SKyle Evans	end
28862ffcaabSToomas Soome	screen.setcursor(menu_header_x - 1, y)
2894ba91fa0SToomas Soome	if menu_header ~= "" then
29062ffcaabSToomas Soome		printc(" " .. menu_header .. " ")
29112eaa305SKyle Evans	end
29212eaa305SKyle Evans
2934ba91fa0SToomas Soomeend
2944ba91fa0SToomas Soome
29512eaa305SKyle Evanslocal function drawbrand()
29612eaa305SKyle Evans	local x = tonumber(loader.getenv("loader_brand_x")) or
297a9edc01bSKyle Evans	    brand_position.x
29812eaa305SKyle Evans	local y = tonumber(loader.getenv("loader_brand_y")) or
299a9edc01bSKyle Evans	    brand_position.y
30012eaa305SKyle Evans
30112eaa305SKyle Evans	local branddef = getBranddef(loader.getenv("loader_brand"))
30212eaa305SKyle Evans
30312eaa305SKyle Evans	if branddef == nil then
30412eaa305SKyle Evans		branddef = getBranddef(drawer.default_brand)
30512eaa305SKyle Evans	end
30612eaa305SKyle Evans
30712eaa305SKyle Evans	local graphic = branddef.graphic
30812eaa305SKyle Evans
309a9edc01bSKyle Evans	x = x + shift.x
310a9edc01bSKyle Evans	y = y + shift.y
311*e19d9a9bSKyle Evans	if branddef.shift ~= nil then
312*e19d9a9bSKyle Evans		x = x +	branddef.shift.x
313*e19d9a9bSKyle Evans		y = y + branddef.shift.y
314*e19d9a9bSKyle Evans	end
315*e19d9a9bSKyle Evans
3163630506bSToomas Soome	if core.isFramebufferConsole() and
3173630506bSToomas Soome	    loader.term_putimage ~= nil and
3183630506bSToomas Soome	    branddef.image ~= nil then
31996bef205SToomas Soome		if loader.term_putimage(branddef.image, 1, 1, 0, 7, 0)
3203630506bSToomas Soome		then
3213630506bSToomas Soome			return true
3223630506bSToomas Soome		end
3233630506bSToomas Soome	end
32412eaa305SKyle Evans	draw(x, y, graphic)
32512eaa305SKyle Evansend
32612eaa305SKyle Evans
32712eaa305SKyle Evanslocal function drawlogo()
32812eaa305SKyle Evans	local x = tonumber(loader.getenv("loader_logo_x")) or
329a9edc01bSKyle Evans	    logo_position.x
33012eaa305SKyle Evans	local y = tonumber(loader.getenv("loader_logo_y")) or
331a9edc01bSKyle Evans	    logo_position.y
33212eaa305SKyle Evans
33312eaa305SKyle Evans	local logo = loader.getenv("loader_logo")
33412eaa305SKyle Evans	local colored = color.isEnabled()
33512eaa305SKyle Evans
33612eaa305SKyle Evans	local logodef = getLogodef(logo)
33712eaa305SKyle Evans
33812eaa305SKyle Evans	if logodef == nil or logodef.graphic == nil or
33912eaa305SKyle Evans	    (not colored and logodef.requires_color) then
34012eaa305SKyle Evans		-- Choose a sensible default
34112eaa305SKyle Evans		if colored then
3422c690e2aSKyle Evans			logodef = getLogodef(drawer.default_color_logodef)
34312eaa305SKyle Evans		else
3442c690e2aSKyle Evans			logodef = getLogodef(drawer.default_bw_logodef)
34512eaa305SKyle Evans		end
3466697f577SKyle Evans
3476697f577SKyle Evans		-- Something has gone terribly wrong.
3486697f577SKyle Evans		if logodef == nil then
3496697f577SKyle Evans			logodef = getLogodef(drawer.default_fallback_logodef)
3506697f577SKyle Evans		end
35112eaa305SKyle Evans	end
35212eaa305SKyle Evans
35312eaa305SKyle Evans	if logodef ~= nil and logodef.graphic == none then
354a9edc01bSKyle Evans		shift = logodef.shift
35512eaa305SKyle Evans	else
356a9edc01bSKyle Evans		shift = default_shift
35712eaa305SKyle Evans	end
35812eaa305SKyle Evans
359a9edc01bSKyle Evans	x = x + shift.x
360a9edc01bSKyle Evans	y = y + shift.y
36112eaa305SKyle Evans
36212eaa305SKyle Evans	if logodef ~= nil and logodef.shift ~= nil then
36312eaa305SKyle Evans		x = x + logodef.shift.x
36412eaa305SKyle Evans		y = y + logodef.shift.y
36512eaa305SKyle Evans	end
36612eaa305SKyle Evans
3673630506bSToomas Soome	if core.isFramebufferConsole() and
3683630506bSToomas Soome	    loader.term_putimage ~= nil and
3693630506bSToomas Soome	    logodef.image ~= nil then
3703630506bSToomas Soome		local y1 = 15
3713630506bSToomas Soome
3723630506bSToomas Soome		if logodef.image_rl ~= nil then
3733630506bSToomas Soome			y1 = logodef.image_rl
3743630506bSToomas Soome		end
3753630506bSToomas Soome		if loader.term_putimage(logodef.image, x, y, 0, y + y1, 0)
3763630506bSToomas Soome		then
3773630506bSToomas Soome			return true
3783630506bSToomas Soome		end
3793630506bSToomas Soome	end
38012eaa305SKyle Evans	draw(x, y, logodef.graphic)
38112eaa305SKyle Evansend
38212eaa305SKyle Evans
3833630506bSToomas Soomelocal function drawitem(func)
3843630506bSToomas Soome	local console = loader.getenv("console")
3853630506bSToomas Soome
3863630506bSToomas Soome	for c in string.gmatch(console, "%w+") do
3873630506bSToomas Soome		loader.setenv("console", c)
3883630506bSToomas Soome		func()
3893630506bSToomas Soome	end
3903630506bSToomas Soome	loader.setenv("console", console)
3913630506bSToomas Soomeend
3923630506bSToomas Soome
3931091c8feSKyle Evansfbsd_brand = {
394088b4f5fSWarner Losh"  ______               ____   _____ _____  ",
395088b4f5fSWarner Losh" |  ____|             |  _ \\ / ____|  __ \\ ",
396088b4f5fSWarner Losh" | |___ _ __ ___  ___ | |_) | (___ | |  | |",
397088b4f5fSWarner Losh" |  ___| '__/ _ \\/ _ \\|  _ < \\___ \\| |  | |",
398088b4f5fSWarner Losh" | |   | | |  __/  __/| |_) |____) | |__| |",
399088b4f5fSWarner Losh" | |   | | |    |    ||     |      |      |",
400088b4f5fSWarner Losh" |_|   |_|  \\___|\\___||____/|_____/|_____/ "
401aedd6be5SKyle Evans}
402aedd6be5SKyle Evansnone = {""}
403088b4f5fSWarner Losh
404a9edc01bSKyle Evansmenu_name_handlers = {
405b5746545SKyle Evans	-- Menu name handlers should take the menu being drawn and entry being
406b5746545SKyle Evans	-- drawn as parameters, and return the name of the item.
407b5746545SKyle Evans	-- This is designed so that everything, including menu separators, may
408b5746545SKyle Evans	-- have their names derived differently. The default action for entry
409a51f9f0cSKyle Evans	-- types not specified here is to use entry.name directly.
410e2df27e3SKyle Evans	[core.MENU_SEPARATOR] = function(_, entry)
411dd65496aSKyle Evans		if entry.name ~= nil then
412a51f9f0cSKyle Evans			if type(entry.name) == "function" then
413dd65496aSKyle Evans				return entry.name()
414dd65496aSKyle Evans			end
415a51f9f0cSKyle Evans			return entry.name
416a51f9f0cSKyle Evans		end
417dd65496aSKyle Evans		return ""
418dd65496aSKyle Evans	end,
419e2df27e3SKyle Evans	[core.MENU_CAROUSEL_ENTRY] = function(_, entry)
420aedd6be5SKyle Evans		local carid = entry.carousel_id
421aedd6be5SKyle Evans		local caridx = config.getCarouselIndex(carid)
4224f437f9eSKyle Evans		local choices = entry.items
4234f437f9eSKyle Evans		if type(choices) == "function" then
4244f437f9eSKyle Evans			choices = choices()
4254f437f9eSKyle Evans		end
4269f71d421SKyle Evans		if #choices < caridx then
427aedd6be5SKyle Evans			caridx = 1
428b5746545SKyle Evans		end
429aedd6be5SKyle Evans		return entry.name(caridx, choices[caridx], choices)
430b5746545SKyle Evans	end,
431aedd6be5SKyle Evans}
432b5746545SKyle Evans
433a9edc01bSKyle Evansbranddefs = {
434699578a6SKyle Evans	-- Indexed by valid values for loader_brand in loader.conf(5). Valid
435699578a6SKyle Evans	-- keys are: graphic (table depicting graphic)
43629aa5794SKyle Evans	["fbsd"] = {
4371091c8feSKyle Evans		graphic = fbsd_brand,
4383630506bSToomas Soome		image = "/boot/images/freebsd-brand-rev.png",
43929aa5794SKyle Evans	},
44029aa5794SKyle Evans	["none"] = {
44129aa5794SKyle Evans		graphic = none,
44229aa5794SKyle Evans	},
443aedd6be5SKyle Evans}
44429aa5794SKyle Evans
445a9edc01bSKyle Evanslogodefs = {
446bb26c57dSKyle Evans	-- Indexed by valid values for loader_logo in loader.conf(5). Valid keys
447752b2d40SKyle Evans	-- are: requires_color (boolean), graphic (table depicting graphic), and
448bb26c57dSKyle Evans	-- shift (table containing x and y).
449bb26c57dSKyle Evans	["tribute"] = {
4501091c8feSKyle Evans		graphic = fbsd_brand,
451bb26c57dSKyle Evans	},
452bb26c57dSKyle Evans	["tributebw"] = {
4531091c8feSKyle Evans		graphic = fbsd_brand,
454bb26c57dSKyle Evans	},
455bb26c57dSKyle Evans	["none"] = {
456752b2d40SKyle Evans		graphic = none,
457bb26c57dSKyle Evans		shift = {x = 17, y = 0},
458bb26c57dSKyle Evans	},
459aedd6be5SKyle Evans}
460bb26c57dSKyle Evans
461a9edc01bSKyle Evansbrand_position = {x = 2, y = 1}
462a9edc01bSKyle Evanslogo_position = {x = 46, y = 4}
463a9edc01bSKyle Evansmenu_position = {x = 5, y = 10}
464a9edc01bSKyle Evansframe_size = {w = 42, h = 13}
465a9edc01bSKyle Evansdefault_shift = {x = 0, y = 0}
466a9edc01bSKyle Evansshift = default_shift
467a9edc01bSKyle Evans
468a9edc01bSKyle Evans-- Module exports
469a9edc01bSKyle Evansdrawer.default_brand = 'fbsd'
4702c690e2aSKyle Evansdrawer.default_color_logodef = 'orb'
4712c690e2aSKyle Evansdrawer.default_bw_logodef = 'orbbw'
4726697f577SKyle Evans-- For when things go terribly wrong; this def should be present here in the
4736697f577SKyle Evans-- drawer module in case it's a filesystem issue.
4746697f577SKyle Evansdrawer.default_fallback_logodef = 'none'
475a9edc01bSKyle Evans
476546f18f3SKyle Evans-- These should go away after FreeBSD 13; only available for backwards
477546f18f3SKyle Evans-- compatibility with old logo- files.
478a9edc01bSKyle Evansfunction drawer.addBrand(name, def)
479a9edc01bSKyle Evans	branddefs[name] = def
480a9edc01bSKyle Evansend
481a9edc01bSKyle Evans
482a9edc01bSKyle Evansfunction drawer.addLogo(name, def)
483a9edc01bSKyle Evans	logodefs[name] = def
484a9edc01bSKyle Evansend
485a9edc01bSKyle Evans
486379e652eSKyle Evansdrawer.frame_styles = {
487379e652eSKyle Evans	-- Indexed by valid values for loader_menu_frame in loader.conf(5).
488379e652eSKyle Evans	-- All of the keys appearing below must be set for any menu frame style
489379e652eSKyle Evans	-- added to drawer.frame_styles.
490379e652eSKyle Evans	["ascii"] = {
491379e652eSKyle Evans		horizontal	= "-",
492379e652eSKyle Evans		vertical	= "|",
493379e652eSKyle Evans		top_left	= "+",
494379e652eSKyle Evans		bottom_left	= "+",
495379e652eSKyle Evans		top_right	= "+",
496379e652eSKyle Evans		bottom_right	= "+",
497379e652eSKyle Evans	},
498379e652eSKyle Evans	["single"] = {
49956758831SToomas Soome		horizontal	= "\xE2\x94\x80",
50056758831SToomas Soome		vertical	= "\xE2\x94\x82",
50156758831SToomas Soome		top_left	= "\xE2\x94\x8C",
50256758831SToomas Soome		bottom_left	= "\xE2\x94\x94",
50356758831SToomas Soome		top_right	= "\xE2\x94\x90",
50456758831SToomas Soome		bottom_right	= "\xE2\x94\x98",
505379e652eSKyle Evans	},
506379e652eSKyle Evans	["double"] = {
50756758831SToomas Soome		horizontal	= "\xE2\x95\x90",
50856758831SToomas Soome		vertical	= "\xE2\x95\x91",
50956758831SToomas Soome		top_left	= "\xE2\x95\x94",
51056758831SToomas Soome		bottom_left	= "\xE2\x95\x9A",
51156758831SToomas Soome		top_right	= "\xE2\x95\x97",
51256758831SToomas Soome		bottom_right	= "\xE2\x95\x9D",
513379e652eSKyle Evans	},
514379e652eSKyle Evans}
515379e652eSKyle Evans
51612eaa305SKyle Evansfunction drawer.drawscreen(menudef)
517088b4f5fSWarner Losh	-- drawlogo() must go first.
518088b4f5fSWarner Losh	-- it determines the positions of other elements
5193630506bSToomas Soome	drawitem(drawlogo)
5203630506bSToomas Soome	drawitem(drawbrand)
5213630506bSToomas Soome	drawitem(drawbox)
52212eaa305SKyle Evans	return drawmenu(menudef)
523088b4f5fSWarner Loshend
524088b4f5fSWarner Losh
525aedd6be5SKyle Evansreturn drawer
526