From 08c2358bdcba0ac8be745972335b6d08f5d213a2 Mon Sep 17 00:00:00 2001 From: stjet <49297268+stjet@users.noreply.github.com> Date: Mon, 18 Aug 2025 17:27:16 +0000 Subject: [PATCH] v1.2 random lockscreen message, remove rand dep for audio player, add version to about window, add o/O to malvim, add circles to draw, bug fixes, minor byte savings for font .alpha format --- Cargo.toml | 5 +- bmps/shippori-mincho/{プ0.bmp => プ3.bmp} | Bin bmps/shippori-mincho/ー6.bmp | Bin 0 -> 94 bytes bmps/shippori-mincho/中0.bmp | Bin 0 -> 534 bytes bmps/shippori-mincho/合0.bmp | Bin 0 -> 630 bytes build.rs | 4 +- docs/window-likes/draw.md | 7 ++- ming-wm-lib/Cargo.toml | 2 +- ming-wm-lib/src/utils.rs | 20 +++--- src/bin/audio_player.rs | 13 ++-- src/bin/draw.rs | 21 ++++++- src/bin/malvim.rs | 73 +++++++++++++++------- src/bin/minesweeper.rs | 8 +-- src/bin/wm.rs | 3 +- wm/Cargo.toml | 2 +- wm/src/essential/about.rs | 6 +- wm/src/essential/lock_screen.rs | 26 ++++++-- wm/src/framebuffer.rs | 4 +- wm/src/fs.rs | 4 +- wm/src/window_manager.rs | 7 ++- 20 files changed, 135 insertions(+), 70 deletions(-) rename bmps/shippori-mincho/{プ0.bmp => プ3.bmp} (100%) create mode 100644 bmps/shippori-mincho/ー6.bmp create mode 100644 bmps/shippori-mincho/中0.bmp create mode 100644 bmps/shippori-mincho/合0.bmp diff --git a/Cargo.toml b/Cargo.toml index 0d2e9ec..25a7d18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ming-wm" -version = "1.2.0-beta.0" +version = "1.2.0" repository = "https://github.com/stjet/ming-wm" license = "GPL-3.0-or-later" edition = "2021" @@ -20,7 +20,6 @@ ming-wm-lib = { path = "ming-wm-lib" } wm = { path = "wm", optional = true } linux = { path = "linux", optional = true } rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true } -rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true } id3 = { version = "1.10.0", optional = true } mp4ameta = { version = "0.11.0", optional = true } metaflac = { version = "0.2.5", optional = true } @@ -28,7 +27,7 @@ metaflac = { version = "0.2.5", optional = true } [features] default = [ "wm", "terminal" ] terminal = [ "linux" ] -audio_player = [ "id3", "mp4ameta", "metaflac", "rand", "rodio" ] +audio_player = [ "id3", "mp4ameta", "metaflac", "rodio" ] [profile.release] lto = true diff --git a/bmps/shippori-mincho/プ0.bmp b/bmps/shippori-mincho/プ3.bmp similarity index 100% rename from bmps/shippori-mincho/プ0.bmp rename to bmps/shippori-mincho/プ3.bmp diff --git a/bmps/shippori-mincho/ー6.bmp b/bmps/shippori-mincho/ー6.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4e2c5bddb879edeb39a15ce3d1d2f25bf5e03aac GIT binary patch literal 94 zcmZ?rjbnfSGa#h_#9Tnk2*wIP5+Vj>pb{&A+-*QSABZOd@pK@b3B*&O^dcbL3IG8# B2etqJ literal 0 HcmV?d00001 diff --git a/bmps/shippori-mincho/中0.bmp b/bmps/shippori-mincho/中0.bmp new file mode 100644 index 0000000000000000000000000000000000000000..998e1394b464c019e7112972a4612265f2dc74fd GIT binary patch literal 534 zcmZ?r6=Pxm12Z700mNKD%mc)X3<^M!f#Crom_i}`|NqZ`jDeCXfY<_A3>zD$W;qbM zVUt4^1FD%1#J0#{AT|&vAd3O{GlAF~CI)1)0x`(NH(_E>eKUY!W-u`zI}C_Bf%qa2 zry=2kKz17ve>#xe4a7%bdU2Q+1XR-m#Ak?5R|`~kABc^S@LC`{4vAj^WX}TPJR~uY k`i(%0tS$h^&qlTr>b_M#akzic = ch.into_iter().map(|row| { - row.join(",") + row.join(",").replace(",,,,", ":").replace(",,,", ";").replace(",,", ".") }).collect(); let chars: Vec = file_name[0].chars().collect(); File::create(dir.to_string() + "/" + &chars[0].to_string() + ".alpha").unwrap().write_all( @@ -61,7 +61,9 @@ fn main() { } //copy bmp folders to target let profile = env::var_os("PROFILE").unwrap().to_string_lossy().to_string(); + Command::new("rm").arg("-rf").arg(format!("./target/{}/ming_bmps", profile)).output().unwrap(); //delete at target first so cp works Command::new("cp").arg("-r").arg("./bmps").arg(format!("./target/{}/ming_bmps", profile)).output().unwrap(); //also copy the docs folder + Command::new("rm").arg("-rf").arg(format!("./target/{}/ming_docs", profile)).output().unwrap(); Command::new("cp").arg("-r").arg("./docs").arg(format!("./target/{}/ming_docs", profile)).output().unwrap(); } diff --git a/docs/window-likes/draw.md b/docs/window-likes/draw.md index 383a053..7ef330a 100644 --- a/docs/window-likes/draw.md +++ b/docs/window-likes/draw.md @@ -6,9 +6,10 @@ Arrow keys or hjkl. `i` to enter input mode. Use the enter key to finish a line ## Input Commands -- `line`: Start line with current point as start. Move and hit enter to determine line endpoint -- `rect`: Start rect with current point as a corner. Move and hit enter to determine the opposite corner -- `color/c/colour [lowercase 6 char hex string]`: Set current colour +- `line/l`: Start line with current point as start. Move and hit enter to determine line endpoint +- `rect/r`: Start rect with current point as a corner. Move and hit enter to determine the opposite corner +- `circle/c`: Start circle with current point as centre. Move and hit enter to determine radius +- `color/co/colour [lowercase 6 char hex string]`: Set current colour - `linewidth/lw [int]`: Set current line width - `undo`: Undo last draw - `clear`: Clear all drawings \ No newline at end of file diff --git a/ming-wm-lib/Cargo.toml b/ming-wm-lib/Cargo.toml index a420e9d..7a9d44d 100644 --- a/ming-wm-lib/Cargo.toml +++ b/ming-wm-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ming-wm-lib" -version = "0.2.0" +version = "0.2.1" repository = "https://github.com/stjet/ming-wm" description = "library for building windows for ming-wm in rust" readme = "README.md" diff --git a/ming-wm-lib/src/utils.rs b/ming-wm-lib/src/utils.rs index 68f4dd3..717c40c 100644 --- a/ming-wm-lib/src/utils.rs +++ b/ming-wm-lib/src/utils.rs @@ -7,6 +7,14 @@ pub fn min(one: usize, two: usize) -> usize { if one > two { two } else { one } } +pub fn random_u32(seed: u32) -> u32 { + let mut seed = seed; + seed ^= seed << 13; + seed ^= seed >> 17; + seed ^= seed >> 5; + seed +} + pub trait Substring { fn substring(&self, start: usize, end: usize) -> &str; fn remove(&self, index: usize, len: usize) -> String; @@ -88,18 +96,6 @@ pub fn calc_actual_lines<'a>(lines: impl Iterator, max_chars_ actual_lines } -pub fn calc_new_cursor_pos(cursor_pos: usize, new_length: usize) -> usize { - if cursor_pos >= new_length { - if new_length == 0 { - 0 - } else { - new_length - 1 - } - } else { - cursor_pos - } -} - pub fn concat_paths(current_path: &str, add_path: &str) -> Result { let mut new_path = PathBuf::from(current_path); //if current_path is a file, automatically uses it's parent (a directory) diff --git a/src/bin/audio_player.rs b/src/bin/audio_player.rs index ff62d36..ad38bc9 100644 --- a/src/bin/audio_player.rs +++ b/src/bin/audio_player.rs @@ -2,13 +2,13 @@ use std::vec::Vec; use std::vec; use std::io::BufReader; use std::path::PathBuf; +use std::collections::HashMap; use std::fs::{ read_to_string, File }; use std::time::{ Duration, SystemTime, UNIX_EPOCH }; use std::thread; use std::sync::{ Arc, Mutex }; use rodio::{ Decoder, OutputStream, Sink, Source }; -use rand::{ SeedableRng, prelude::SliceRandom, rngs::SmallRng }; use id3::TagLike; use mp4ameta; use metaflac; @@ -17,7 +17,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType }; use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::themes::ThemeInfo; -use ming_wm_lib::utils::{ concat_paths, get_all_files, path_autocomplete, format_seconds, Substring }; +use ming_wm_lib::utils::{ concat_paths, random_u32, get_all_files, path_autocomplete, format_seconds, Substring }; use ming_wm_lib::dirs::home; use ming_wm_lib::ipc::listen; @@ -253,8 +253,13 @@ impl AudioPlayer { } else { get_all_files(PathBuf::from(new_path)) }; - let mut rng = SmallRng::seed_from_u64(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()); - queue.shuffle(&mut rng); + let mut seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_millis(); + let mut q_weights: HashMap = HashMap::new(); + for q in &queue { + seed = random_u32(seed); + q_weights.insert(q.to_path_buf(), seed); + } + queue.sort_by(|a, b| q_weights[a].cmp(&q_weights[b])); if self.command.starts_with("p ") { let mut locked_internal = self.internal.lock().unwrap(); (*locked_internal).sink.clear(); diff --git a/src/bin/draw.rs b/src/bin/draw.rs index ea22446..4fa7e5b 100644 --- a/src/bin/draw.rs +++ b/src/bin/draw.rs @@ -11,7 +11,7 @@ use ming_wm_lib::ipc::listen; enum DrawAction { Line(Point, Option, usize, RGBColor), Rect(Point, Option, RGBColor), - // + Circle(Point, Option, RGBColor), } impl DrawAction { @@ -19,6 +19,7 @@ impl DrawAction { match self { DrawAction::Line(_, _, _, _) => "Line", DrawAction::Rect(_, _, _) => "Rect", + DrawAction::Circle(_, _, _) => "Circle", }.to_string() } } @@ -49,6 +50,10 @@ impl WindowLike for Draw { self.dimensions = dimensions; WindowMessageResponse::JustRedraw }, + WindowMessage::ChangeDimensions(dimensions) => { + self.dimensions = dimensions; + WindowMessageResponse::JustRedraw + }, WindowMessage::KeyPress(key_press) => { if key_press.is_escape() && (self.current_action.is_some() || self.mode != Mode::Move) { self.current_action = None; @@ -69,7 +74,10 @@ impl WindowLike for Draw { "rect" | "r" => { self.current_action = Some(DrawAction::Rect(self.current_location, None, self.current_color)); }, - "colour" | "color" | "c" => { + "circle" | "c" => { + self.current_action = Some(DrawAction::Circle(self.current_location, None, self.current_color)); + }, + "colour" | "color" | "co" => { //hex to u8 if let Some(hex_color) = parts.next() { if hex_color.len() == 6 && hex_color.chars().all(|c| HEX_CHARS.contains(&c)) { @@ -135,6 +143,10 @@ impl WindowLike for Draw { ]; DrawAction::Rect(tl, Some(d), *r) }, + DrawAction::Circle(p, _, c) => { + let r = ((self.current_location[1] as f64 - p[1] as f64).powi(2) + (self.current_location[0] as f64 - p[0] as f64).powi(2)).sqrt(); + DrawAction::Circle(*p, Some(r.round() as usize), *c) + }, }); self.current_action = None; WindowMessageResponse::JustRedraw @@ -184,6 +196,7 @@ impl WindowLike for Draw { instructions.push(match action { DrawAction::Line(p1, p2, lw, c) => DrawInstructions::Line(*p1, p2.unwrap(), *lw, *c), DrawAction::Rect(p, d, c) => DrawInstructions::Rect(*p, d.unwrap(), *c), + DrawAction::Circle(p, r, c) => DrawInstructions::Circle(*p, r.unwrap(), *c), }); } //draw cursor (crosshair) @@ -220,6 +233,10 @@ impl WindowLike for Draw { fn ideal_dimensions(&self, _dimensions: Dimensions) -> Dimensions { [410, 410] } + + fn resizable(&self) -> bool { + true + } } impl Draw { diff --git a/src/bin/malvim.rs b/src/bin/malvim.rs index c9ea350..93dec4f 100644 --- a/src/bin/malvim.rs +++ b/src/bin/malvim.rs @@ -9,7 +9,7 @@ use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManager use ming_wm_lib::themes::ThemeInfo; use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType }; -use ming_wm_lib::utils::{ calc_actual_lines, calc_new_cursor_pos, Substring }; +use ming_wm_lib::utils::{ calc_actual_lines, Substring }; use ming_wm_lib::dirs::home; use ming_wm_lib::utils::{ get_rest_of_split, path_autocomplete }; use ming_wm_lib::ipc::listen; @@ -103,10 +103,22 @@ impl WindowLike for Malvim { self.mode = Mode::Command; self.command = Some(String::new()); changed = false; - } else if (key_press.key == 'i' || key_press.key == 'A') && self.mode == Mode::Normal && self.state == State::None && self.files.len() > 0 { + } else if (key_press.key == 'i' || key_press.key == 'A' || key_press.key == 'o' || key_press.key == 'O') && self.mode == Mode::Normal && self.state == State::None && self.files.len() > 0 { + let current_file = &mut self.files[self.current_file_index]; if key_press.key == 'A' { - let current_file = &mut self.files[self.current_file_index]; current_file.cursor_pos = current_file.content[current_file.line_pos].chars().count(); + } else if key_press.key == 'o' || key_press.key == 'O' { + let current_line = ¤t_file.content[current_file.line_pos]; + let spaces = Malvim::calc_spaces(self.autoindent, current_line); + let n = if key_press.key == 'o' { + current_file.line_pos + 1 + } else { + current_file.line_pos + }; + current_file.content.insert(n, " ".repeat(spaces)); + current_file.line_pos = n; + current_file.cursor_pos = spaces; + new = true; } self.mode = Mode::Insert; changed = false; @@ -120,20 +132,7 @@ impl WindowLike for Malvim { let left = left.into_iter().map(|c| c.to_string()).collect::>().join(""); let right = right.into_iter().map(|c| c.to_string()).collect::>().join(""); current_file.content[current_file.line_pos] = left.to_string(); - let spaces = if self.autoindent { - //find out how many spaces the line starts with, copy that to the new line - let mut spaces = 0; - for c in left.chars() { - if c == ' ' { - spaces += 1; - } else { - break; - } - } - spaces - } else { - 0 - }; + let spaces = Malvim::calc_spaces(self.autoindent, &left); current_file.content.insert(current_file.line_pos + 1, " ".repeat(spaces) + &right); current_file.line_pos += 1; current_file.cursor_pos = spaces; @@ -178,7 +177,7 @@ impl WindowLike for Malvim { } } let new_length = current_file.content[current_file.line_pos].chars().count(); - current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); + current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length); } else if key_press.key == 'w' || key_press.key == '$' { let line = ¤t_file.content[current_file.line_pos]; let line_len = line.chars().count(); @@ -198,7 +197,7 @@ impl WindowLike for Malvim { }; current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos, offset); let new_length = current_file.content[current_file.line_pos].chars().count(); - current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); + current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length); } } self.state = State::None; @@ -209,7 +208,7 @@ impl WindowLike for Malvim { current_file.line_pos = current_file.content.len() - 1; } let new_length = current_file.content[current_file.line_pos].chars().count(); - current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); + current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length); } changed = false; self.state = State::None; @@ -265,7 +264,7 @@ impl WindowLike for Malvim { current_file.line_pos = current_file.line_pos.checked_sub(self.maybe_num.unwrap_or(1)).unwrap_or(0); } let new_length = current_file.content[current_file.line_pos].chars().count(); - current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); + current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length); changed = false; } else if key_press.key == 'l' || key_press.is_right_arrow() { if current_length > 0 { @@ -298,7 +297,7 @@ impl WindowLike for Malvim { } else if key_press.key == 'G' { current_file.line_pos = current_file.content.len() - 1; let new_length = current_file.content[current_file.line_pos].chars().count(); - current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); + current_file.cursor_pos = Malvim::calc_new_cursor_pos(current_file.cursor_pos, new_length); changed = false; } else if key_press.key == 'f' { self.state = State::Find; @@ -424,7 +423,7 @@ impl WindowLike for Malvim { } } else if key_press.is_backspace() { if command.len() > 0 { - self.command = Some(command[..command.len() - 1].to_string()); + self.command = Some(command.remove_last()); } } else { self.command = Some(command.to_string() + &key_press.key.to_string()); @@ -594,6 +593,34 @@ impl Malvim { Default::default() } + fn calc_spaces(autoindent: bool, left: &str) -> usize { + if autoindent { + let mut spaces = 0; + for c in left.chars() { + if c == ' ' { + spaces += 1; + } else { + break; + } + } + spaces + } else { + 0 + } + } + + fn calc_new_cursor_pos(cursor_pos: usize, new_length: usize) -> usize { + if cursor_pos >= new_length { + if new_length == 0 { + 0 + } else { + new_length - 1 + } + } else { + cursor_pos + } + } + fn calc_top_line_pos(&mut self) { if self.files.len() == 0 { return; diff --git a/src/bin/minesweeper.rs b/src/bin/minesweeper.rs index 7994f48..3e77cfe 100644 --- a/src/bin/minesweeper.rs +++ b/src/bin/minesweeper.rs @@ -7,7 +7,7 @@ use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLik use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse }; use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::themes::ThemeInfo; -use ming_wm_lib::utils::{ u8_to_hex, hex_to_u8, HEX_CHARS }; +use ming_wm_lib::utils::{ random_u32, u8_to_hex, hex_to_u8, HEX_CHARS }; use ming_wm_lib::ipc::listen; //16x16 with 40 mines @@ -252,11 +252,7 @@ impl Minesweeper { //https://en.wikipedia.org/wiki/Xorshift //from 0 to 15 pub fn random(&mut self) -> usize { - let mut x = self.random_seed; - x ^= x << 13; - x ^= x >> 17; - x ^= x << 5; - self.random_seed = x; + self.random_seed = random_u32(self.random_seed); self.random_seed as usize % 16 } diff --git a/src/bin/wm.rs b/src/bin/wm.rs index b6c8739..88f0a92 100644 --- a/src/bin/wm.rs +++ b/src/bin/wm.rs @@ -72,7 +72,7 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) { writer.init(framebuffer_info.clone()); - let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale, PASSWORD_HASH); + let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale, env!("CARGO_PKG_VERSION").to_string(), PASSWORD_HASH); let mut stdout = RawStdout::new(stdout()); stdout.enter_raw_mode().unwrap(); @@ -110,7 +110,6 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) { //read touchscreen presses (hopefully) thread::spawn(move || { - //spawn evtest, parse it for touch coords if touch { let mut events = Input::new("/dev/input/by-path/first-touchscreen").unwrap(); //panics in threads don't matter in this case let mut x: Option = None; diff --git a/wm/Cargo.toml b/wm/Cargo.toml index c5a1f46..4ff3e76 100644 --- a/wm/Cargo.toml +++ b/wm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wm" -version = "1.0.3" +version = "1.2.0" repository = "https://github.com/stjet/ming-wm" license = "GPL-3.0-or-later" edition = "2021" diff --git a/wm/src/essential/about.rs b/wm/src/essential/about.rs index b2bf7f1..d768384 100644 --- a/wm/src/essential/about.rs +++ b/wm/src/essential/about.rs @@ -13,6 +13,7 @@ use ming_wm_lib::components::paragraph::Paragraph; pub struct About { dimensions: Dimensions, components: Vec + Send>>, + version: String, } impl WindowLike for About { @@ -40,7 +41,7 @@ impl WindowLike for About { //properties fn title(&self) -> String { - "About".to_string() + "About".to_string() + " - v" + &self.version } fn subtype(&self) -> WindowLikeType { @@ -53,10 +54,11 @@ impl WindowLike for About { } impl About { - pub fn new() -> Self { + pub fn new(version: String) -> Self { Self { dimensions: [0, 0], components: Vec::new(), + version, } } } diff --git a/wm/src/essential/lock_screen.rs b/wm/src/essential/lock_screen.rs index 97b8b66..9469e62 100644 --- a/wm/src/essential/lock_screen.rs +++ b/wm/src/essential/lock_screen.rs @@ -1,5 +1,6 @@ use std::vec; use std::vec::Vec; +use std::time::{ SystemTime, UNIX_EPOCH }; //for psuedo-randomness use ming_wm_lib::framebuffer_types::Dimensions; use ming_wm_lib::themes::ThemeInfo; @@ -7,12 +8,11 @@ use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManager use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType }; use bitcoin_hashes::Sha512; -//const PASSWORD_HASH: [u8; 64] = [220, 88, 183, 188, 240, 27, 107, 181, 58, 191, 198, 170, 114, 38, 7, 148, 6, 179, 75, 128, 231, 171, 172, 220, 85, 38, 36, 113, 116, 146, 70, 197, 163, 179, 158, 192, 130, 53, 247, 48, 47, 209, 95, 96, 179, 211, 4, 122, 254, 127, 21, 165, 139, 199, 151, 226, 216, 176, 123, 41, 194, 221, 58, 69]; - pub struct LockScreen { dimensions: Dimensions, input_password: String, password_hash: [u8; 64], + lines: [String; 3], } impl WindowLike for LockScreen { @@ -51,9 +51,11 @@ impl WindowLike for LockScreen { fn draw(&self, _theme_info: &ThemeInfo) -> Vec { vec![ DrawInstructions::Rect([0, 0], self.dimensions, [0, 0, 0]), - DrawInstructions::Text([4, 4], vec!["nimbus-roman".to_string()], "The bulldozer outside the kitchen window was quite a big one.".to_string(), [255, 255, 255], [0, 0, 0], None, None), - DrawInstructions::Text([4, 4 + 16], vec!["nimbus-roman".to_string()], "\"Yellow,\" he thought, and stomped off back to his bedroom to get dressed.".to_string(), [255, 255, 255], [0, 0, 0], None, None), - DrawInstructions::Text([4, 4 + 16 * 2], vec!["nimbus-roman".to_string()], "He stared at it.".to_string(), [255, 255, 255], [0, 0, 0], None, None), + DrawInstructions::Text([4, 4], vec!["nimbus-roman".to_string()], self.lines[0].clone(), [255, 255, 255], [0, 0, 0], None, None), + //He is my brother. + DrawInstructions::Text([4, 4 + 16], vec!["nimbus-roman".to_string()], self.lines[1].clone(), [255, 255, 255], [0, 0, 0], None, None), + //But I must kill him and keep strong to do it. + DrawInstructions::Text([4, 4 + 16 * 2], vec!["nimbus-roman".to_string()], self.lines[2].clone(), [255, 255, 255], [0, 0, 0], None, None), DrawInstructions::Text([4, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "Password: ".to_string(), [255, 255, 255], [0, 0, 0], None, None), DrawInstructions::Text([80, 4 + 16 * 3], vec!["nimbus-roman".to_string()], "*".repeat(self.input_password.len()), [255, 255, 255], [0, 0, 0], None, None), ] @@ -71,10 +73,24 @@ impl WindowLike for LockScreen { impl LockScreen { pub fn new(password_hash: [u8; 64]) -> Self { + let possible_lines = [ + [ + "\"He took about forty pounds,\" the old man said aloud.".to_string(), + "He took my harpoon too and all the rope, he thought, and now my fish bleeds again and there will be others.".to_string(), + "He did not like to look at the fish anymore since it had been mutilated.".to_string() + ], + [ + "The bulldozer outside the kitchen window was quite a big one.".to_string(), + "\"Yellow,\" he thought, and stomped off back to his bedroom to get dressed.".to_string(), + "He stared at it.".to_string() + ], + ]; + let rand_index = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as usize % possible_lines.len(); Self { dimensions: [0, 0], input_password: String::new(), password_hash, + lines: possible_lines[rand_index].clone(), } } } diff --git a/wm/src/framebuffer.rs b/wm/src/framebuffer.rs index fe68a3f..9601447 100644 --- a/wm/src/framebuffer.rs +++ b/wm/src/framebuffer.rs @@ -148,7 +148,9 @@ impl FramebufferWriter { pub fn draw_pixel(&mut self, point: Point, color: RGBColor) { let start_pos = (point[1] * self.info.stride + point[0]) * self.info.bytes_per_pixel; - self._draw_pixel(start_pos, color); + if self.info.byte_len > start_pos { + self._draw_pixel(start_pos, color); + } } //shapes diff --git a/wm/src/fs.rs b/wm/src/fs.rs index 30a3185..9129505 100644 --- a/wm/src/fs.rs +++ b/wm/src/fs.rs @@ -12,9 +12,9 @@ fn get_font_char(dir: &str, c: char) -> Option<(char, Vec>, u8)> { let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); let lines: Vec<&str> = contents.split("\n").collect(); - for l in 1..lines.len() { + for ln in 1..lines.len() { //.unwrap_or(0) is important because zeroes are just empty - ch.push(lines[l].split(",").map(|n| n.parse().unwrap_or(0)).collect()); + ch.push(lines[ln].replace(":", ",,,,").replace(";", ",,,").replace(".", ",,").split(",").map(|n| n.parse().unwrap_or(0)).collect()); } return Some((c, ch, lines[0].parse().unwrap())); } diff --git a/wm/src/window_manager.rs b/wm/src/window_manager.rs index bfd5229..6fe0a53 100644 --- a/wm/src/window_manager.rs +++ b/wm/src/window_manager.rs @@ -51,6 +51,7 @@ impl fmt::Debug for WindowLikeInfo { } } + pub struct WindowManager { writer: RefCell, rotate: bool, @@ -65,13 +66,14 @@ pub struct WindowManager { current_workspace: u8, framebuffer: Framebuffer, clipboard: Option, + version: String, password_hash: [u8; 64], } //1 is up, 2 is down impl WindowManager { - pub fn new(writer: FramebufferWriter, framebuffer: Framebuffer, dimensions: Dimensions, rotate: bool, grayscale: bool, password_hash: [u8; 64]) -> Self { + pub fn new(writer: FramebufferWriter, framebuffer: Framebuffer, dimensions: Dimensions, rotate: bool, grayscale: bool, version: String, password_hash: [u8; 64]) -> Self { //println!("bg: {}x{}", dimensions[0], dimensions[1] - TASKBAR_HEIGHT - INDICATOR_HEIGHT); let mut wm = WindowManager { writer: RefCell::new(writer), @@ -87,6 +89,7 @@ impl WindowManager { current_workspace: 0, framebuffer, clipboard: None, + version, password_hash, }; wm.lock(); @@ -594,7 +597,7 @@ impl WindowManager { } let w: Option = match w.as_str() { "StartMenu" => Some(Box::new(StartMenu::new())), - "About" => Some(Box::new(About::new())), + "About" => Some(Box::new(About::new(self.version.clone()))), "Help" => Some(Box::new(Help::new())), _ => Some(Box::new(ProxyWindowLike::new(&w))), };