mirror of
https://github.com/ZeroOSProject/ZeroOS.git
synced 2026-09-13 02:24:42 +08:00
vi and busybox
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
use crate::efi::{EfiGraphicsOutputProtocol, EfiGraphicsPixelFormat};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Rgb {
|
||||
pub red: u8,
|
||||
pub green: u8,
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
pub struct Framebuffer {
|
||||
base: *mut u8,
|
||||
width: usize,
|
||||
height: usize,
|
||||
stride: usize,
|
||||
pixel_format: EfiGraphicsPixelFormat,
|
||||
}
|
||||
|
||||
impl Framebuffer {
|
||||
pub unsafe fn from_gop(gop: *mut EfiGraphicsOutputProtocol) -> Option<Self> {
|
||||
let mode = unsafe { (*gop).mode };
|
||||
if mode.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let info = unsafe { (*mode).info };
|
||||
if info.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let pixel_format = unsafe { (*info).pixel_format };
|
||||
if pixel_format != EfiGraphicsPixelFormat::RedGreenBlueReserved8BitPerColor
|
||||
&& pixel_format != EfiGraphicsPixelFormat::BlueGreenRedReserved8BitPerColor
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Self {
|
||||
base: unsafe { (*mode).frame_buffer_base as *mut u8 },
|
||||
width: unsafe { (*info).horizontal_resolution as usize },
|
||||
height: unsafe { (*info).vertical_resolution as usize },
|
||||
stride: unsafe { (*info).pixels_per_scan_line as usize },
|
||||
pixel_format,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
pub fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
|
||||
pub fn clear(&mut self, color: Rgb) {
|
||||
self.fill_rect(0, 0, self.width, self.height, color);
|
||||
}
|
||||
|
||||
pub fn fill_rect(&mut self, x: usize, y: usize, width: usize, height: usize, color: Rgb) {
|
||||
let end_x = x.saturating_add(width).min(self.width);
|
||||
let end_y = y.saturating_add(height).min(self.height);
|
||||
|
||||
for py in y..end_y {
|
||||
for px in x..end_x {
|
||||
self.put_pixel(px, py, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_region_up(&mut self, top: usize, bottom: usize, pixels: usize, fill: Rgb) {
|
||||
if pixels == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let top = top.min(self.height);
|
||||
let bottom = bottom.min(self.height);
|
||||
if top >= bottom {
|
||||
return;
|
||||
}
|
||||
|
||||
if pixels >= bottom - top {
|
||||
self.fill_rect(0, top, self.width, bottom - top, fill);
|
||||
return;
|
||||
}
|
||||
|
||||
for y in top..bottom {
|
||||
for x in 0..self.width {
|
||||
if y + pixels < bottom {
|
||||
self.copy_pixel(x, y + pixels, x, y);
|
||||
} else {
|
||||
self.put_pixel(x, y, fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_pixel(&mut self, x: usize, y: usize, color: Rgb) {
|
||||
if x >= self.width || y >= self.height {
|
||||
return;
|
||||
}
|
||||
|
||||
let offset = (y * self.stride + x) * 4;
|
||||
unsafe {
|
||||
let pixel = self.base.add(offset);
|
||||
match self.pixel_format {
|
||||
EfiGraphicsPixelFormat::RedGreenBlueReserved8BitPerColor => {
|
||||
pixel.write_volatile(color.red);
|
||||
pixel.add(1).write_volatile(color.green);
|
||||
pixel.add(2).write_volatile(color.blue);
|
||||
pixel.add(3).write_volatile(0);
|
||||
}
|
||||
EfiGraphicsPixelFormat::BlueGreenRedReserved8BitPerColor => {
|
||||
pixel.write_volatile(color.blue);
|
||||
pixel.add(1).write_volatile(color.green);
|
||||
pixel.add(2).write_volatile(color.red);
|
||||
pixel.add(3).write_volatile(0);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_pixel(&mut self, source_x: usize, source_y: usize, target_x: usize, target_y: usize) {
|
||||
let source_offset = (source_y * self.stride + source_x) * 4;
|
||||
let target_offset = (target_y * self.stride + target_x) * 4;
|
||||
|
||||
unsafe {
|
||||
let source = self.base.add(source_offset);
|
||||
let target = self.base.add(target_offset);
|
||||
target.write_volatile(source.read_volatile());
|
||||
target.add(1).write_volatile(source.add(1).read_volatile());
|
||||
target.add(2).write_volatile(source.add(2).read_volatile());
|
||||
target.add(3).write_volatile(source.add(3).read_volatile());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user