Skip to content

Commit

Permalink
Continue to work on terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
AlixANNERAUD committed Dec 21, 2024
1 parent ef93570 commit 4f39dbf
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 135 deletions.
1 change: 1 addition & 0 deletions Modules/Executables/Terminal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Time = { path = "../../Time" }
Drivers = { path = "../../Drivers" }
Time = { path = "../../Time" }
LittleFS = { path = "../../LittleFS" }
Command_line_shell = { path = "../Shell/Command_line" }

[[test]]
name = "Integration_test"
Expand Down
5 changes: 5 additions & 0 deletions Modules/Executables/Terminal/Tests/Integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use Terminal::Terminal_executable_type;
#[ignore]
#[test]
fn main() {
use Command_line_shell::Shell_executable_type;
use Drivers::Native::Window_screen;
use Graphics::{Get_minimal_buffer_size, Input_type_type, Point_type};

Expand Down Expand Up @@ -53,6 +54,10 @@ fn main() {

let Task = Task_instance.Get_current_task_identifier().unwrap();

Virtual_file_system::Get_instance()
.Mount_static_device(Task, &"/Shell", Create_device!(Shell_executable_type))
.unwrap();

Virtual_file_system::Get_instance()
.Mount_static_device(Task, &"/Terminal", Create_device!(Terminal_executable_type))
.unwrap();
Expand Down
30 changes: 15 additions & 15 deletions Modules/Executables/Terminal/src/Device.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
use Executable::Read_data_type;
use File_system::Device_trait;

use crate::Main::Main;
use crate::Terminal::Terminal_type;

pub struct Terminal_executable_type;

impl Device_trait for Terminal_executable_type {
impl Device_trait for Terminal_type {
fn Read(&self, Buffer: &mut [u8]) -> File_system::Result_type<File_system::Size_type> {
let Read_data: &mut Read_data_type = Buffer
.try_into()
.map_err(|_| File_system::Error_type::Invalid_parameter)?;

*Read_data = Read_data_type::New(Main, 1024 * 32);
let Size = self
.Read_input(Buffer)
.map_err(|_| File_system::Error_type::Internal_error)?;

Ok(size_of::<Read_data_type>().into())
Ok(Size.into())
}

fn Write(&self, _: &[u8]) -> File_system::Result_type<File_system::Size_type> {
Err(File_system::Error_type::Unsupported_operation)
fn Write(&self, Buffer: &[u8]) -> File_system::Result_type<File_system::Size_type> {
let String = String::from_utf8_lossy(Buffer);

self.Print(&String)
.map_err(|_| File_system::Error_type::Internal_error)?;

Ok(Buffer.len().into())
}

fn Get_size(&self) -> File_system::Result_type<File_system::Size_type> {
Err(File_system::Error_type::Unsupported_operation)
Ok(0_usize.into())
}

fn Set_position(
Expand All @@ -32,6 +32,6 @@ impl Device_trait for Terminal_executable_type {
}

fn Flush(&self) -> File_system::Result_type<()> {
Err(File_system::Error_type::Unsupported_operation)
Ok(())
}
}
48 changes: 47 additions & 1 deletion Modules/Executables/Terminal/src/Error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use core::num::NonZeroUsize;
use core::result::Result;
use core::str::Utf8Error;
use core::{fmt::Display, num::NonZeroU8};
use std::num::NonZeroUsize;
use std::sync::PoisonError;

pub type Result_type<T> = Result<T, Error_type>;

Expand All @@ -9,6 +11,11 @@ pub type Result_type<T> = Result<T, Error_type>;
pub enum Error_type {
Graphics(Graphics::Error_type),
Failed_to_create_object,
UTF_8(Utf8Error),
Poisoned_lock,
Failed_to_mount_device(File_system::Error_type),
Failed_to_get_task_identifier(Task::Error_type),
Failed_to_execute(Executable::Error_type),
}

impl Error_type {
Expand All @@ -17,6 +24,36 @@ impl Error_type {
}
}

impl From<Executable::Error_type> for Error_type {
fn from(Error: Executable::Error_type) -> Self {
Self::Failed_to_execute(Error)
}
}

impl From<Task::Error_type> for Error_type {
fn from(Error: Task::Error_type) -> Self {
Self::Failed_to_get_task_identifier(Error)
}
}

impl From<File_system::Error_type> for Error_type {
fn from(Error: File_system::Error_type) -> Self {
Self::Failed_to_mount_device(Error)
}
}

impl<T> From<PoisonError<T>> for Error_type {
fn from(_: PoisonError<T>) -> Self {
Self::Poisoned_lock
}
}

impl From<Utf8Error> for Error_type {
fn from(Error: Utf8Error) -> Self {
Self::UTF_8(Error)
}
}

impl From<Graphics::Error_type> for Error_type {
fn from(Error: Graphics::Error_type) -> Self {
Self::Graphics(Error)
Expand All @@ -28,6 +65,15 @@ impl Display for Error_type {
match self {
Self::Graphics(Error) => write!(Formatter, "Graphics: {}", Error),
Self::Failed_to_create_object => write!(Formatter, "Failed to create object"),
Self::UTF_8(Error) => write!(Formatter, "UTF-8: {}", Error),
Self::Poisoned_lock => write!(Formatter, "Poisoned lock"),
Self::Failed_to_mount_device(Error) => {
write!(Formatter, "Failed to mount device: {}", Error)
}
Self::Failed_to_get_task_identifier(Error) => {
write!(Formatter, "Failed to get task identifier: {}", Error)
}
Self::Failed_to_execute(Error) => write!(Formatter, "Failed to execute: {}", Error),
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions Modules/Executables/Terminal/src/Executable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use Executable::Read_data_type;
use File_system::Device_trait;

use crate::Main::Main;

pub struct Terminal_executable_type;

impl Device_trait for Terminal_executable_type {
fn Read(&self, Buffer: &mut [u8]) -> File_system::Result_type<File_system::Size_type> {
let Read_data: &mut Read_data_type = Buffer
.try_into()
.map_err(|_| File_system::Error_type::Invalid_parameter)?;

*Read_data = Read_data_type::New(Main, 1024 * 32);

Ok(size_of::<Read_data_type>().into())
}

fn Write(&self, _: &[u8]) -> File_system::Result_type<File_system::Size_type> {
Err(File_system::Error_type::Unsupported_operation)
}

fn Get_size(&self) -> File_system::Result_type<File_system::Size_type> {
Err(File_system::Error_type::Unsupported_operation)
}

fn Set_position(
&self,
_: &File_system::Position_type,
) -> File_system::Result_type<File_system::Size_type> {
Err(File_system::Error_type::Unsupported_operation)
}

fn Flush(&self) -> File_system::Result_type<()> {
Err(File_system::Error_type::Unsupported_operation)
}
}
173 changes: 56 additions & 117 deletions Modules/Executables/Terminal/src/Main.rs
Original file line number Diff line number Diff line change
@@ -1,134 +1,73 @@
use core::num::NonZeroUsize;
use std::ffi::CStr;
use std::{sync::Arc, time::Duration};

use Executable::Standard_type;
use Graphics::{
Event_code_type, Key_type, Window_type,
LVGL::{self, lv_indev_active},
};

use crate::Error::Result_type;

pub struct Terminal_type {
Window: Window_type,
Running: bool,
Buffer: String,
Display: *mut LVGL::lv_obj_t,
Input: *mut LVGL::lv_obj_t,
use File_system::{Device_type, Flags_type, Mode_type, Unique_file_identifier_type};
use Task::Task_identifier_type;

use crate::{Error::Result_type, Terminal::Terminal_type};

fn Mount_and_open(
Task: Task_identifier_type,
Terminal: Arc<Terminal_type>,
) -> Result_type<(
Unique_file_identifier_type,
Unique_file_identifier_type,
Unique_file_identifier_type,
)> {
Virtual_file_system::Get_instance().Mount_device(
Task,
&"/Devices/Terminal",
Device_type::New(Terminal),
)?;

let Standard_in = Virtual_file_system::Get_instance().Open(
&"/Devices/Terminal",
Flags_type::New(Mode_type::Read_only, None, None),
Task,
)?;

let Standard_out = Virtual_file_system::Get_instance().Open(
&"/Devices/Terminal",
Mode_type::Write_only.into(),
Task,
)?;

let Standard_error =
Virtual_file_system::Get_instance().Duplicate_file_identifier(Standard_out, Task)?;

Ok((Standard_in, Standard_out, Standard_error))
}

impl Terminal_type {
pub fn New() -> Result_type<Self> {
let Window = Graphics::Get_instance().Create_window()?;
fn Inner_main(Task: Task_identifier_type) -> Result_type<()> {
let Terminal = Terminal_type::New()?;

let _Lock = Graphics::Get_instance().Lock()?;
let Terminal = Arc::new(Terminal);

unsafe {
LVGL::lv_obj_set_flex_flow(
Window.Get_object(),
LVGL::lv_flex_flow_t_LV_FLEX_FLOW_COLUMN,
);
}
let (Standard_in, Standard_out, Standard_error) = Mount_and_open(Task, Terminal.clone())?;

let Container = unsafe {
let Container = LVGL::lv_obj_create(Window.Get_object());
let Standard = Standard_type::New(
Standard_in,
Standard_out,
Standard_error,
Task::Get_instance().Get_current_task_identifier()?,
Virtual_file_system::Get_instance(),
);

LVGL::lv_obj_set_width(Container, LVGL::lv_pct(100));
LVGL::lv_obj_set_flex_grow(Container, 1);
Executable::Execute("/Shell", "".to_string(), Standard)?;

Container
};

let Buffer = String::with_capacity(80 * 24);

let Display = unsafe {
let Label = LVGL::lv_label_create(Container);

if Label.is_null() {
return Err(crate::Error::Error_type::Failed_to_create_object);
}

LVGL::lv_obj_set_width(Label, LVGL::lv_pct(100));
LVGL::lv_label_set_text_static(Label, Buffer.as_ptr() as *const i8);
LVGL::lv_obj_set_style_text_font(
Label,
&raw const LVGL::lv_font_unscii_8,
LVGL::LV_STATE_DEFAULT,
);

Label
};

let Input = unsafe {
let Input = LVGL::lv_textarea_create(Window.Get_object());

if Input.is_null() {
return Err(crate::Error::Error_type::Failed_to_create_object);
}

LVGL::lv_textarea_set_placeholder_text(Input, c"Enter your command ...".as_ptr());
LVGL::lv_obj_set_width(Input, LVGL::lv_pct(100));
LVGL::lv_textarea_set_one_line(Input, true);

Input
};

Ok(Self {
Buffer,
Window,
Running: true,
Display,
Input,
})
}

pub fn Event_handler(&mut self) {
while let Some(Event) = self.Window.Pop_event() {
match Event.Get_code() {
Event_code_type::Delete => self.Running = false,
Event_code_type::Key => {
if let Some(Key_type::Character(Character)) = Event.Get_key() {
if Character == b'\n' || Character == b'\r' {
unsafe {
let Text = LVGL::lv_textarea_get_text(self.Input);

if !self.Buffer.is_empty() {
self.Buffer.remove(self.Buffer.len() - 1);
}

if let Ok(Text) = CStr::from_ptr(Text).to_str() {
self.Buffer += Text;
self.Buffer += "\n\0";
LVGL::lv_label_set_text(
self.Display,
self.Buffer.as_ptr() as *const i8,
);
}

LVGL::lv_textarea_set_text(self.Input, c"".as_ptr());
}
}
}
}
_ => {}
}
}
while Terminal.Event_handler()? {
Task::Manager_type::Sleep(Duration::from_millis(20));
}

pub fn Main(&mut self, _: String) {
while self.Running {
self.Event_handler();
}
}
Ok(())
}

pub fn Main(Standard: Standard_type, Arguments: String) -> Result<(), NonZeroUsize> {
Terminal_type::New()
.map_err(|Error| {
Standard.Print_error(&Error.to_string());
NonZeroUsize::from(Error)
})?
.Main(Arguments);
pub fn Main(Standard: Standard_type, _: String) -> Result<(), NonZeroUsize> {
if let Err(Error) = Inner_main(Standard.Get_task()) {
Standard.Print_error(&Error.to_string());
return Err(Error.into());
}

Ok(())
}
Loading

0 comments on commit 4f39dbf

Please sign in to comment.