diff --git a/res/open-sans/LICENSE b/res/open-sans/LICENSE new file mode 100644 index 0000000..c91bd22 --- /dev/null +++ b/res/open-sans/LICENSE @@ -0,0 +1,88 @@ +Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to +provide a free and open framework in which fonts may be shared and +improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software +components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, +deleting, or substituting -- in part or in whole -- any of the +components of the Original Version, by changing formats or by porting +the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, +modify, redistribute, and sell modified and unmodified copies of the +Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in +Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the +corresponding Copyright Holder. This restriction only applies to the +primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created using +the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/res/open-sans/OpenSans-Regular.ttf b/res/open-sans/OpenSans-Regular.ttf new file mode 100644 index 0000000..db43334 Binary files /dev/null and b/res/open-sans/OpenSans-Regular.ttf differ diff --git a/src/fde.rs b/src/fde.rs index 7027279..89134e8 100644 --- a/src/fde.rs +++ b/src/fde.rs @@ -350,11 +350,7 @@ fn wait_for_events(form: &Form) -> Result { events.push(form.FormRefreshEvent); } - Result::from((uefi.BootServices.WaitForEvent)( - events.len(), - events.as_mut_ptr(), - &mut index, - ))?; + Result::from((uefi.BootServices.WaitForEvent)(events.len(), events.as_mut_ptr(), &mut index))?; if index == 0 { Ok(EventType::Keyboard) @@ -378,6 +374,9 @@ fn form_display_inner(form: &Form, user_input: &mut UserInput) -> Result<()> { &mut *DISPLAY }; + // If you want to test the security screen, uncomment this line: + // crate::security::confirm(display); + let (display_w, display_h) = (display.width(), display.height()); let scale = if display_h > 1440 { @@ -389,7 +388,7 @@ fn form_display_inner(form: &Form, user_input: &mut UserInput) -> Result<()> { }; // Style { - let margin_lr = 8 * scale; + let margin_lr = 12 * scale; let margin_tb = 4 * scale; let title_font_size = (20 * scale) as f32; @@ -417,9 +416,7 @@ fn form_display_inner(form: &Form, user_input: &mut UserInput) -> Result<()> { let option_ptr = option as *const _; if let Some(op) = option.OptionOpCode() { let value = unsafe { op.Value.to_enum(op.Kind) }; - let prompt = ui - .font - .render(&string(op.Option).unwrap_or_default(), font_size); + let prompt = ui.font.render(&string(op.Option).unwrap_or_default(), font_size); options.push(ElementOption { option_ptr, prompt, @@ -428,86 +425,83 @@ fn form_display_inner(form: &Form, user_input: &mut UserInput) -> Result<()> { } } - let add_element = - |header: IfrStatementHeader, selectable: bool, editable: bool, list: bool| { - let value = unsafe { - statement - .CurrentValue - .Value - .to_enum(statement.CurrentValue.Kind) + let add_element = |header: IfrStatementHeader, + selectable: bool, + editable: bool, + list: bool| { + let value = + unsafe { statement.CurrentValue.Value.to_enum(statement.CurrentValue.Kind) }; + let buffer_opt = if statement.CurrentValue.Buffer.is_null() { + None + } else { + let buffer = unsafe { + slice::from_raw_parts_mut( + statement.CurrentValue.Buffer, + statement.CurrentValue.BufferLen as usize, + ) }; - let buffer_opt = if statement.CurrentValue.Buffer.is_null() { - None - } else { - let buffer = unsafe { - slice::from_raw_parts_mut( - statement.CurrentValue.Buffer, - statement.CurrentValue.BufferLen as usize, - ) - }; - // Order list according to buffer - if list { - let mut offset = 0; - for i in 0..options.len() { - for j in i..options.len() { - macro_rules! check_option { - ($x:ident) => {{ - let next_offset = offset + mem::size_of_val(&$x); - if next_offset <= buffer.len() { - let mut x_copy = $x; - unsafe { - ptr::copy( - buffer.as_ptr().add(offset) as *const _, - &mut x_copy, - 1, - ); - }; - if $x == x_copy { - offset = next_offset; - true - } else { - false - } + // Order list according to buffer + if list { + let mut offset = 0; + for i in 0..options.len() { + for j in i..options.len() { + macro_rules! check_option { + ($x:ident) => {{ + let next_offset = offset + mem::size_of_val(&$x); + if next_offset <= buffer.len() { + let mut x_copy = $x; + unsafe { + ptr::copy( + buffer.as_ptr().add(offset) as *const _, + &mut x_copy, + 1, + ); + }; + if $x == x_copy { + offset = next_offset; + true } else { false } - }}; - } - let matches = match options[j].value { - IfrTypeValueEnum::U8(u8) => check_option!(u8), - IfrTypeValueEnum::U16(u16) => check_option!(u16), - IfrTypeValueEnum::U32(u32) => check_option!(u32), - IfrTypeValueEnum::U64(u64) => check_option!(u64), - _ => false, - }; - if matches { - if i != j { - options.swap(i, j); + } else { + false } - break; + }}; + } + let matches = match options[j].value { + IfrTypeValueEnum::U8(u8) => check_option!(u8), + IfrTypeValueEnum::U16(u16) => check_option!(u16), + IfrTypeValueEnum::U32(u32) => check_option!(u32), + IfrTypeValueEnum::U64(u64) => check_option!(u64), + _ => false, + }; + if matches { + if i != j { + options.swap(i, j); } + break; } } } - Some(buffer) - }; - if statement_ptr == form.HighLightedStatement || (selected == !0 && selectable) - { - selected = elements.len(); } - elements.push(Element { - statement_ptr, - prompt: string(header.Prompt).unwrap_or_default(), - help: string(header.Help).unwrap_or_default(), - value, - options, - selectable, - editable, - list, - list_i: 0, - buffer_opt, - }); + Some(buffer) }; + if statement_ptr == form.HighLightedStatement || (selected == !0 && selectable) { + selected = elements.len(); + } + elements.push(Element { + statement_ptr, + prompt: string(header.Prompt).unwrap_or_default(), + help: string(header.Help).unwrap_or_default(), + value, + options, + selectable, + editable, + list, + list_i: 0, + buffer_opt, + }); + }; if let Some(op) = statement.OpCode() { macro_rules! cast { @@ -672,7 +666,7 @@ fn form_display_inner(form: &Form, user_input: &mut UserInput) -> Result<()> { if selected == !0 { render_hotkey_help(""); } else if !editing || !editing_value { - render_hotkey_help("↑↓=Move Highlight"); + render_hotkey_help("Up/Down=Move Highlight"); } if editing { diff --git a/src/image/bmp.rs b/src/image/bmp.rs index 026ca32..8db9681 100644 --- a/src/image/bmp.rs +++ b/src/image/bmp.rs @@ -24,9 +24,7 @@ pub fn parse(file_data: &[u8]) -> core::result::Result { }; let gets = |start: usize, len: usize| -> String { - (start..start + len) - .map(|i| get(i) as char) - .collect::() + (start..start + len).map(|i| get(i) as char).collect::() }; if gets(0, 2) == "BM" { diff --git a/src/image/mod.rs b/src/image/mod.rs index 539d0c1..ba883de 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -23,10 +23,8 @@ impl ImageRoi<'_> { pub fn draw(&self, renderer: &mut R, x: i32, mut y: i32) { let stride = self.image.w; let mut offset = (self.y * stride + self.x) as usize; - let last_offset = cmp::min( - ((self.y + self.h) * stride + self.x) as usize, - self.image.data.len(), - ); + let last_offset = + cmp::min(((self.y + self.h) * stride + self.x) as usize, self.image.data.len()); while offset < last_offset { let next_offset = offset + stride as usize; renderer.image_legacy(x, y, self.w, 1, &self.image.data[offset..]); @@ -68,7 +66,7 @@ impl Image { ) -> core::result::Result { if (width * height) as usize != data.len() { return Err( - "not enough or too much data given compared to width and height".to_string(), + "not enough or too much data given compared to width and height".to_string() ); } diff --git a/src/key.rs b/src/key.rs index 46436a0..bc0c378 100644 --- a/src/key.rs +++ b/src/key.rs @@ -79,11 +79,7 @@ pub fn raw_key(wait: bool) -> Result { if wait { let mut index = 0; - Result::from((uefi.BootServices.WaitForEvent)( - 1, - &uefi.ConsoleIn.WaitForKey, - &mut index, - ))?; + Result::from((uefi.BootServices.WaitForEvent)(1, &uefi.ConsoleIn.WaitForKey, &mut index))?; } let mut key = TextInputKey { diff --git a/src/rng.rs b/src/rng.rs index 8ab039f..3f9f53a 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -8,12 +8,7 @@ pub struct Rng(pub &'static mut RngProtocol); impl Rng { pub fn read(&self, buf: &mut [u8]) -> Result<()> { - Result::from((self.0.GetRNG)( - self.0, - ptr::null(), - buf.len(), - buf.as_mut_ptr(), - ))?; + Result::from((self.0.GetRNG)(self.0, ptr::null(), buf.len(), buf.as_mut_ptr()))?; Ok(()) } } diff --git a/src/security.rs b/src/security.rs index 90622e6..6f663ef 100644 --- a/src/security.rs +++ b/src/security.rs @@ -40,7 +40,7 @@ impl Timeout for UefiTimeout { } } -fn confirm(display: &mut Display) -> Result<()> { +pub(crate) fn confirm(display: &mut Display) -> Result<()> { let (display_w, display_h) = (display.width(), display.height()); let scale: i32 = if display_h > 1440 { @@ -52,8 +52,8 @@ fn confirm(display: &mut Display) -> Result<()> { }; // Style { - let margin_lr = 16 * scale; - let margin_tb = 8 * scale; + let margin_lr = 12 * scale; + let margin_tb = 4 * scale; let form_width = cmp::min(640 * scale as u32, display_w - margin_lr as u32 * 2); let form_x = (display_w as i32 - form_width as i32) / 2; @@ -93,10 +93,7 @@ fn confirm(display: &mut Display) -> Result<()> { texts.push(ui.font.render(&code, font_size)); let mut button_i = 0; - let buttons = [ - ui.font.render("Confirm", font_size), - ui.font.render("Cancel", font_size), - ]; + let buttons = [ui.font.render("Confirm", font_size), ui.font.render("Cancel", font_size)]; let mut max_input = String::new(); while max_input.len() < code.len() { @@ -145,14 +142,7 @@ fn confirm(display: &mut Display) -> Result<()> { // Draw input box let input_text = ui.font.render(&input, font_size); - ui.draw_pretty_box( - display, - x, - y, - max_input_text.width(), - font_size as u32, - false, - ); + ui.draw_pretty_box(display, x, y, max_input_text.width(), font_size as u32, false); input_text.draw(display, x, y, ui.text_color); if input.len() < code.len() { display.rect( @@ -310,7 +300,9 @@ pub fn install() -> Result<()> { //let uefi = unsafe { std::system_table_mut() }; - let protocol = Box::new(System76SecurityProtocol { Run: run }); + let protocol = Box::new(System76SecurityProtocol { + Run: run, + }); let protocol_ptr = Box::into_raw(protocol); let mut handle = Handle(0); Result::from((uefi.BootServices.InstallProtocolInterface)( diff --git a/src/ui.rs b/src/ui.rs index 80374c3..4cfe0c1 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -8,7 +8,7 @@ use std::prelude::*; use crate::display::Display; use crate::image::{self, Image}; -static FONT_TTF: &[u8] = include_bytes!("../res/FiraSans-Regular.ttf"); +static FONT_TTF: &[u8] = include_bytes!("../res/open-sans/OpenSans-Regular.ttf"); static CHECKBOX_CHECKED_BMP: &[u8] = include_bytes!("../res/checkbox_checked.bmp"); static CHECKBOX_UNCHECKED_BMP: &[u8] = include_bytes!("../res/checkbox_unchecked.bmp"); @@ -29,11 +29,11 @@ pub struct Ui { impl Ui { pub fn new() -> Result { - let background_color = Color::rgb(0x36, 0x32, 0x2F); - let highlight_color = Color::rgb(0xFB, 0xB8, 0x6C); + let background_color = Color::rgb(0x1B, 0x1B, 0x1B); + let highlight_color = Color::rgb(0x63, 0xD0, 0xDF); let outline_color = Color::rgba(0xfe, 0xff, 0xff, 0xc4); - let text_color = Color::rgb(0xCC, 0xCC, 0xCC); - let highlight_text_color = Color::rgb(0x27, 0x27, 0x27); + let text_color = Color::rgb(0xC4, 0xC4, 0xC4); + let highlight_text_color = Color::rgb(0x00, 0x00, 0x00); let font = unsafe { if FONT.is_null() { @@ -151,126 +151,22 @@ impl Ui { // Style { let padding_lr = 4 * scale; let padding_tb = 2 * scale; - - //TODO: does not scale due to hardcoded checkbox image! - let rect_radius = 4; + let radius = 4 * scale; // } Style - let checkbox = if highlighted { - // Center - display.rect( - x - padding_lr, - y - padding_tb + rect_radius, - w + padding_lr as u32 * 2, - h + (padding_tb - rect_radius) as u32 * 2, - self.highlight_color, - ); - - // Top middle - display.rect( - x - padding_lr + rect_radius, - y - padding_tb, - w + (padding_lr - rect_radius) as u32 * 2, - rect_radius as u32, - self.highlight_color, - ); - - // Bottom middle - display.rect( - x - padding_lr + rect_radius, - y + h as i32 + padding_tb - rect_radius, - w + (padding_lr - rect_radius) as u32 * 2, - rect_radius as u32, - self.highlight_color, - ); - - self.checkbox_checked - } else { - // Top middle - display.rect( - x - padding_lr + rect_radius, - y - padding_tb, - w + (padding_lr - rect_radius) as u32 * 2, - 2, - self.outline_color, - ); - - // Bottom middle - display.rect( - x - padding_lr + rect_radius, - y + h as i32 + padding_tb - 2, - w + (padding_lr - rect_radius) as u32 * 2, - 2, - self.outline_color, - ); - - // Left middle - display.rect( - x - padding_lr, - y - padding_tb + rect_radius, - 2, - h + (padding_tb - rect_radius) as u32 * 2, - self.outline_color, - ); - - // Right middle - display.rect( - x + w as i32 + padding_lr - 2, - y - padding_tb + rect_radius, - 2, - h + (padding_tb - rect_radius) as u32 * 2, - self.outline_color, - ); - - self.checkbox_unchecked - }; - - // Top left - checkbox - .roi(0, 0, rect_radius as u32, rect_radius as u32) - .draw(display, x - padding_lr, y - padding_tb); - - // Top right - checkbox - .roi( - checkbox.width() - rect_radius as u32, - 0, - rect_radius as u32, - rect_radius as u32, - ) - .draw( - display, - x + w as i32 + padding_lr - rect_radius, - y - padding_tb, - ); - - // Bottom left - checkbox - .roi( - 0, - checkbox.height() - rect_radius as u32, - rect_radius as u32, - rect_radius as u32, - ) - .draw( - display, - x - padding_lr, - y + h as i32 + padding_tb - rect_radius, - ); - - // Bottom right - checkbox - .roi( - checkbox.width() - rect_radius as u32, - checkbox.height() - rect_radius as u32, - rect_radius as u32, - rect_radius as u32, - ) - .draw( - display, - x + w as i32 + padding_lr - rect_radius, - y + h as i32 + padding_tb - rect_radius, - ); + display.rounded_rect( + x - padding_lr, + y - padding_tb, + w + (padding_lr * 2) as u32, + h + (padding_tb * 2) as u32, + radius as u32, + highlighted, + if highlighted { + self.highlight_color + } else { + self.outline_color + }, + ); } pub fn draw_text_box( @@ -283,14 +179,7 @@ impl Ui { highlighted: bool, ) { if pretty_box { - self.draw_pretty_box( - display, - x, - y, - rendered.width(), - rendered.height(), - highlighted, - ); + self.draw_pretty_box(display, x, y, rendered.width(), rendered.height(), highlighted); } let text_color = if highlighted { self.highlight_text_color