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