xref: /DragonOS/kernel/src/libs/lib_ui/textui_no_alloc.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
1abe3a6eaShanjiezhou use core::{
2abe3a6eaShanjiezhou     intrinsics::unlikely,
3abe3a6eaShanjiezhou     sync::atomic::{AtomicI32, Ordering},
4abe3a6eaShanjiezhou };
5abe3a6eaShanjiezhou 
691e9d4abSLoGin use system_error::SystemError;
791e9d4abSLoGin 
891e9d4abSLoGin use crate::driver::{
952da9a59SGnoCiYeH     serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
10abe3a6eaShanjiezhou };
11abe3a6eaShanjiezhou 
12abe3a6eaShanjiezhou use super::textui::{
13abe3a6eaShanjiezhou     FontColor, LineId, LineIndex, TextuiCharChromatic, TEXTUI_CHAR_HEIGHT, TEXTUI_CHAR_WIDTH,
14abe3a6eaShanjiezhou };
15abe3a6eaShanjiezhou 
16abe3a6eaShanjiezhou pub static TRUE_LINE_NUM: AtomicI32 = AtomicI32::new(0);
17abe3a6eaShanjiezhou pub static CHAR_PER_LINE: AtomicI32 = AtomicI32::new(0);
18abe3a6eaShanjiezhou /// textui 未初始化时直接向缓冲区写,不使用虚拟行
19abe3a6eaShanjiezhou pub static NO_ALLOC_OPERATIONS_LINE: AtomicI32 = AtomicI32::new(0);
20abe3a6eaShanjiezhou pub static NO_ALLOC_OPERATIONS_INDEX: AtomicI32 = AtomicI32::new(0);
21abe3a6eaShanjiezhou 
22abe3a6eaShanjiezhou /// 当系统刚启动的时候,由于内存管理未初始化,而texiui需要动态内存分配。因此只能暂时暴力往屏幕(video_frame_buffer_info)输出信息
textui_init_no_alloc(video_enabled: bool)231a72a751SLoGin pub fn textui_init_no_alloc(video_enabled: bool) {
241a72a751SLoGin     if video_enabled {
251496ba7bSLoGin         let height = video_refresh_manager().device_buffer().height();
261496ba7bSLoGin         let width = video_refresh_manager().device_buffer().width();
271496ba7bSLoGin         TRUE_LINE_NUM.store((height / TEXTUI_CHAR_HEIGHT) as i32, Ordering::SeqCst);
28abe3a6eaShanjiezhou 
291496ba7bSLoGin         CHAR_PER_LINE.store((width / TEXTUI_CHAR_WIDTH) as i32, Ordering::SeqCst);
30abe3a6eaShanjiezhou     }
311a72a751SLoGin }
32abe3a6eaShanjiezhou 
next_line()33bde4a334S曾俊 fn next_line() {
34bde4a334S曾俊     NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
35bde4a334S曾俊     NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst);
36bde4a334S曾俊     if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) >= TRUE_LINE_NUM.load(Ordering::SeqCst) {
37bde4a334S曾俊         NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
38bde4a334S曾俊     }
39bde4a334S曾俊 }
40bde4a334S曾俊 
no_init_textui_putchar_window( character: char, frcolor: FontColor, bkcolor: FontColor, is_put_to_window: bool, ) -> Result<(), SystemError>41abe3a6eaShanjiezhou pub fn no_init_textui_putchar_window(
42abe3a6eaShanjiezhou     character: char,
43abe3a6eaShanjiezhou     frcolor: FontColor,
44abe3a6eaShanjiezhou     bkcolor: FontColor,
45abe3a6eaShanjiezhou     is_put_to_window: bool,
46abe3a6eaShanjiezhou ) -> Result<(), SystemError> {
47abe3a6eaShanjiezhou     //字符'\0'代表ASCII码表中的空字符,表示字符串的结尾
48abe3a6eaShanjiezhou     if unlikely(character == '\0') {
49abe3a6eaShanjiezhou         return Ok(());
50abe3a6eaShanjiezhou     }
51a03c4f9dSLoGin     send_to_default_serial8250_port(&[character as u8]);
52abe3a6eaShanjiezhou 
53bde4a334S曾俊     if is_put_to_window {
54bde4a334S曾俊         match character {
55abe3a6eaShanjiezhou             // 进行换行操作
56bde4a334S曾俊             '\n' => {
57*bd70d2d1SLoGin                 send_to_default_serial8250_port(b"\r");
58b5b571e0SLoGin                 if is_put_to_window {
59bde4a334S曾俊                     next_line();
60abe3a6eaShanjiezhou                 }
61abe3a6eaShanjiezhou             }
62abe3a6eaShanjiezhou             // 输出制表符
63bde4a334S曾俊             '\t' => {
64abe3a6eaShanjiezhou                 let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
65abe3a6eaShanjiezhou                 //打印的空格数(注意将每行分成一个个表格,每个表格为8个字符)
66abe3a6eaShanjiezhou                 let mut space_to_print = 8 - NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst) % 8;
67abe3a6eaShanjiezhou                 while space_to_print > 0 {
68abe3a6eaShanjiezhou                     char.no_init_textui_render_chromatic(
69abe3a6eaShanjiezhou                         LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
70abe3a6eaShanjiezhou                         LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
71abe3a6eaShanjiezhou                     );
72abe3a6eaShanjiezhou                     NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
73abe3a6eaShanjiezhou                     space_to_print -= 1;
74abe3a6eaShanjiezhou                 }
75abe3a6eaShanjiezhou             }
76abe3a6eaShanjiezhou             // 字符 '\x08' 代表 ASCII 码中的退格字符。它在输出中的作用是将光标向左移动一个位置,并在该位置上输出后续的字符,从而实现字符的删除或替换。
77bde4a334S曾俊             '\x08' => {
78abe3a6eaShanjiezhou                 NO_ALLOC_OPERATIONS_INDEX.fetch_sub(1, Ordering::SeqCst);
79abe3a6eaShanjiezhou                 let op_char = NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst);
80abe3a6eaShanjiezhou                 if op_char >= 0 {
81abe3a6eaShanjiezhou                     let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
82abe3a6eaShanjiezhou                     char.no_init_textui_render_chromatic(
83abe3a6eaShanjiezhou                         LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
84abe3a6eaShanjiezhou                         LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
85abe3a6eaShanjiezhou                     );
86abe3a6eaShanjiezhou 
87abe3a6eaShanjiezhou                     NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
88abe3a6eaShanjiezhou                 }
89abe3a6eaShanjiezhou                 // 需要向上缩一行
90abe3a6eaShanjiezhou                 if op_char < 0 {
91abe3a6eaShanjiezhou                     // 上缩一行
92abe3a6eaShanjiezhou                     NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
93abe3a6eaShanjiezhou                     NO_ALLOC_OPERATIONS_LINE.fetch_sub(1, Ordering::SeqCst);
94abe3a6eaShanjiezhou 
95abe3a6eaShanjiezhou                     if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) < 0 {
96abe3a6eaShanjiezhou                         NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
97abe3a6eaShanjiezhou                     }
98abe3a6eaShanjiezhou                 }
99abe3a6eaShanjiezhou             }
100abe3a6eaShanjiezhou             // 输出其他字符
101bde4a334S曾俊             _ => {
102abe3a6eaShanjiezhou                 let char = TextuiCharChromatic::new(Some(character), frcolor, bkcolor);
103abe3a6eaShanjiezhou 
104bde4a334S曾俊                 if NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)
105bde4a334S曾俊                     == CHAR_PER_LINE.load(Ordering::SeqCst)
106abe3a6eaShanjiezhou                 {
107bde4a334S曾俊                     next_line();
108abe3a6eaShanjiezhou                 }
109bde4a334S曾俊 
110abe3a6eaShanjiezhou                 char.no_init_textui_render_chromatic(
111abe3a6eaShanjiezhou                     LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
112abe3a6eaShanjiezhou                     LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
113abe3a6eaShanjiezhou                 );
114abe3a6eaShanjiezhou 
115abe3a6eaShanjiezhou                 NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
116abe3a6eaShanjiezhou             }
117bde4a334S曾俊         }
118bde4a334S曾俊     }
119abe3a6eaShanjiezhou     return Ok(());
120abe3a6eaShanjiezhou }
121