1-- 2-- Copyright (c) 2015 Pedro Souza <pedrosouza@freebsd.org> 3-- All rights reserved. 4-- 5-- Redistribution and use in source and binary forms, with or without 6-- modification, are permitted provided that the following conditions 7-- are met: 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. 13-- 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 24-- SUCH DAMAGE. 25-- 26-- $FreeBSD$ 27-- 28 29local drawer = {}; 30 31local color = require("color"); 32local core = require("core"); 33local screen = require("screen"); 34 35drawer.brand_position = {x = 2, y = 1}; 36drawer.fbsd_logo = { 37 " ______ ____ _____ _____ ", 38 " | ____| | _ \\ / ____| __ \\ ", 39 " | |___ _ __ ___ ___ | |_) | (___ | | | |", 40 " | ___| '__/ _ \\/ _ \\| _ < \\___ \\| | | |", 41 " | | | | | __/ __/| |_) |____) | |__| |", 42 " | | | | | | || | | |", 43 " |_| |_| \\___|\\___||____/|_____/|_____/ " 44}; 45 46drawer.logo_position = {x = 46, y = 1}; 47drawer.beastie_color = { 48 " \027[31m, ,", 49 " /( )`", 50 " \\ \\___ / |", 51 " /- \027[37m_\027[31m `-/ '", 52 " (\027[37m/\\/ \\\027[31m \\ /\\", 53 " \027[37m/ / |\027[31m ` \\", 54 " \027[34mO O \027[37m) \027[31m/ |", 55 " \027[37m`-^--'\027[31m`< '", 56 " (_.) _ ) /", 57 " `.___/` /", 58 " `-----' /", 59 " \027[33m<----.\027[31m __ / __ \\", 60 " \027[33m<----|====\027[31mO)))\027[33m==\027[31m) \\) /\027[33m====|", 61 " \027[33m<----'\027[31m `--' `.__,' \\", 62 " | |", 63 " \\ / /\\", 64 " \027[36m______\027[31m( (_ / \\______/", 65 " \027[36m,' ,-----' |", 66 " `--{__________)\027[37m" 67}; 68 69drawer.beastie = { 70 " , ,", 71 " /( )`", 72 " \\ \\___ / |", 73 " /- _ `-/ '", 74 " (/\\/ \\ \\ /\\", 75 " / / | ` \\", 76 " O O ) / |", 77 " `-^--'`< '", 78 " (_.) _ ) /", 79 " `.___/` /", 80 " `-----' /", 81 " <----. __ / __ \\", 82 " <----|====O)))==) \\) /====|", 83 " <----' `--' `.__,' \\", 84 " | |", 85 " \\ / /\\", 86 " ______( (_ / \\______/", 87 " ,' ,-----' |", 88 " `--{__________)" 89}; 90 91drawer.fbsd_logo_shift = {x = 5, y = 4}; 92drawer.fbsd_logo_v = { 93 " ______", 94 " | ____| __ ___ ___ ", 95 " | |__ | '__/ _ \\/ _ \\", 96 " | __|| | | __/ __/", 97 " | | | | | | |", 98 " |_| |_| \\___|\\___|", 99 " ____ _____ _____", 100 " | _ \\ / ____| __ \\", 101 " | |_) | (___ | | | |", 102 " | _ < \\___ \\| | | |", 103 " | |_) |____) | |__| |", 104 " | | | |", 105 " |____/|_____/|_____/" 106}; 107 108drawer.orb_shift = {x = 2, y = 4}; 109drawer.orb_color = { 110 " \027[31m``` \027[31;1m`\027[31m", 111 " s` `.....---...\027[31;1m....--.``` -/\027[31m", 112 " +o .--` \027[31;1m/y:` +.\027[31m", 113 " yo`:. \027[31;1m:o `+-\027[31m", 114 " y/ \027[31;1m-/` -o/\027[31m", 115 " .- \027[31;1m::/sy+:.\027[31m", 116 " / \027[31;1m`-- /\027[31m", 117 " `: \027[31;1m:`\027[31m", 118 " `: \027[31;1m:`\027[31m", 119 " / \027[31;1m/\027[31m", 120 " .- \027[31;1m-.\027[31m", 121 " -- \027[31;1m-.\027[31m", 122 " `:` \027[31;1m`:`", 123 " \027[31;1m.-- `--.", 124 " .---.....----.\027[37m" 125}; 126 127drawer.orb = { 128 " ``` `", 129 " s` `.....---.......--.``` -/", 130 " +o .--` /y:` +.", 131 " yo`:. :o `+-", 132 " y/ -/` -o/", 133 " .- ::/sy+:.", 134 " / `-- /", 135 " `: :`", 136 " `: :`", 137 " / /", 138 " .- -.", 139 " -- -.", 140 " `:` `:`", 141 " .-- `--.", 142 " .---.....----." 143}; 144 145drawer.none = {""}; 146 147drawer.none_shift = {x = 17, y = 0}; 148 149drawer.menu_position = {x = 6, y = 11}; 150 151drawer.box_pos_dim = {x = 3, y = 10, w = 41, h = 11}; 152 153function drawer.drawscreen(menu_opts) 154 -- drawlogo() must go first. 155 -- it determines the positions of other elements 156 drawer.drawlogo(); 157 drawer.drawbrand(); 158 drawer.drawbox(); 159 return drawer.drawmenu(menu_opts); 160end 161 162function drawer.drawmenu(m) 163 x = drawer.menu_position.x; 164 y = drawer.menu_position.y; 165 166 -- print the menu and build the alias table 167 local alias_table = {}; 168 local entry_num = 0; 169 for line_num, e in ipairs(m) do 170 -- Allow menu items to be conditionally visible by specifying 171 -- a visible function. 172 if (e.visible ~= nil) and (not e.visible()) then 173 goto continue; 174 end 175 if (e.entry_type ~= core.MENU_SEPARATOR) then 176 entry_num = entry_num + 1; 177 screen.setcursor(x, y + line_num); 178 local name = ""; 179 180 if (e.entry_type == core.MENU_CAROUSEL_ENTRY) then 181 local carid = e.carousel_id; 182 local caridx = menu.getCarouselIndex(carid); 183 local choices = e.items(); 184 185 if (#choices < caridx) then 186 caridx = 1; 187 end 188 name = e.name(caridx, choices[caridx], choices); 189 else 190 name = e.name(); 191 end 192 print(entry_num .. ". "..name); 193 194 -- fill the alias table 195 alias_table[tostring(entry_num)] = e; 196 if (e.alias ~= nil) then 197 for n, a in ipairs(e.alias) do 198 alias_table[a] = e; 199 end 200 end 201 else 202 screen.setcursor(x, y + line_num); 203 print(e.name()); 204 end 205 ::continue:: 206 end 207 return alias_table; 208end 209 210 211function drawer.drawbox() 212 x = drawer.box_pos_dim.x; 213 y = drawer.box_pos_dim.y; 214 w = drawer.box_pos_dim.w; 215 h = drawer.box_pos_dim.h; 216 217 local hl = string.char(0xCD); 218 local vl = string.char(0xBA); 219 220 local tl = string.char(0xC9); 221 local bl = string.char(0xC8); 222 local tr = string.char(0xBB); 223 local br = string.char(0xBC); 224 225 screen.setcursor(x, y); print(tl); 226 screen.setcursor(x, y+h); print(bl); 227 screen.setcursor(x+w, y); print(tr); 228 screen.setcursor(x+w, y+h); print(br); 229 230 for i = 1, w-1 do 231 screen.setcursor(x+i, y); 232 print(hl); 233 screen.setcursor(x+i, y+h); 234 print(hl); 235 end 236 237 for i = 1, h-1 do 238 screen.setcursor(x, y+i); 239 print(vl); 240 screen.setcursor(x+w, y+i); 241 print(vl); 242 end 243 244 screen.setcursor(x+(w/2)-9, y); 245 print("Welcome to FreeBSD"); 246end 247 248function drawer.draw(x, y, logo) 249 for i = 1, #logo do 250 screen.setcursor(x, y + i); 251 print(logo[i]); 252 end 253end 254 255function drawer.drawbrand() 256 local x = tonumber(loader.getenv("loader_brand_x")) or 257 drawer.brand_position.x; 258 local y = tonumber(loader.getenv("loader_brand_y")) or 259 drawer.brand_position.y; 260 261 local logo = load("return " .. tostring(loader.getenv("loader_brand")))() or 262 drawer.fbsd_logo; 263 drawer.draw(x, y, logo); 264end 265 266function drawer.drawlogo() 267 local x = tonumber(loader.getenv("loader_logo_x")) or 268 drawer.logo_position.x; 269 local y = tonumber(loader.getenv("loader_logo_y")) or 270 drawer.logo_position.y; 271 272 local logo = loader.getenv("loader_logo"); 273 local s = {x = 0, y = 0}; 274 local colored = color.isEnabled(); 275 276 if (logo == "beastie") then 277 if (colored) then 278 logo = drawer.beastie_color; 279 end 280 elseif (logo == "beastiebw") then 281 logo = drawer.beastie; 282 elseif (logo == "fbsdbw") then 283 logo = drawer.fbsd_logo_v; 284 s = drawer.fbsd_logo_shift; 285 elseif (logo == "orb") then 286 if (colored) then 287 logo = drawer.orb_color; 288 end 289 s = drawer.orb_shift; 290 elseif (logo == "orbbw") then 291 logo = drawer.orb; 292 s = drawer.orb_shift; 293 elseif (logo == "tribute") then 294 logo = drawer.fbsd_logo; 295 elseif (logo == "tributebw") then 296 logo = drawer.fbsd_logo; 297 elseif (logo == "none") then 298 --centre brand and text if no logo 299 drawer.brand_position.x = drawer.brand_position.x + drawer.none_shift.x; 300 drawer.brand_position.y = drawer.brand_position.y + drawer.none_shift.y; 301 drawer.menu_position.x = drawer.menu_position.x + drawer.none_shift.x; 302 drawer.menu_position.y = drawer.menu_position.y + drawer.none_shift.y; 303 drawer.box_pos_dim.x = drawer.box_pos_dim.x + drawer.none_shift.x; 304 drawer.box_pos_dim.y = drawer.box_pos_dim.y + drawer.none_shift.y; 305 --prevent redraws from moving menu further 306 drawer.none_shift.x = 0; 307 drawer.none_shift.y = 0; 308 logo = drawer.none; 309 end 310 if (not logo) then 311 if (colored) then 312 logo = drawer.orb_color; 313 else 314 logo = drawer.orb; 315 end 316 end 317 drawer.draw(x + s.x, y + s.y, logo); 318end 319 320return drawer; 321