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
no_init_textui_putchar_window( character: char, frcolor: FontColor, bkcolor: FontColor, is_put_to_window: bool, ) -> Result<(), SystemError>33 pub fn no_init_textui_putchar_window(
34 character: char,
35 frcolor: FontColor,
36 bkcolor: FontColor,
37 is_put_to_window: bool,
38 ) -> Result<(), SystemError> {
39 if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) > TRUE_LINE_NUM.load(Ordering::SeqCst) {
40 NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
41 }
42 //字符'\0'代表ASCII码表中的空字符,表示字符串的结尾
43 if unlikely(character == '\0') {
44 return Ok(());
45 }
46 send_to_default_serial8250_port(&[character as u8]);
47
48 // 进行换行操作
49 if unlikely(character == '\n') {
50 // 换行时还需要输出\r
51 send_to_default_serial8250_port(&[b'\r']);
52 if is_put_to_window == true {
53 NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst);
54 NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
55 }
56 return Ok(());
57 }
58 // 输出制表符
59 else if character == '\t' {
60 if is_put_to_window == true {
61 let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
62
63 //打印的空格数(注意将每行分成一个个表格,每个表格为8个字符)
64 let mut space_to_print = 8 - NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst) % 8;
65 while space_to_print > 0 {
66 char.no_init_textui_render_chromatic(
67 LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
68 LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
69 );
70 NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
71 space_to_print -= 1;
72 }
73 return Ok(());
74 }
75 }
76 // 字符 '\x08' 代表 ASCII 码中的退格字符。它在输出中的作用是将光标向左移动一个位置,并在该位置上输出后续的字符,从而实现字符的删除或替换。
77 else if character == '\x08' {
78 if is_put_to_window == true {
79 NO_ALLOC_OPERATIONS_INDEX.fetch_sub(1, Ordering::SeqCst);
80 let op_char = NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst);
81 if op_char >= 0 {
82 let char = TextuiCharChromatic::new(Some(' '), frcolor, bkcolor);
83 char.no_init_textui_render_chromatic(
84 LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
85 LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
86 );
87
88 NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
89 }
90 // 需要向上缩一行
91 if op_char < 0 {
92 // 上缩一行
93 NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
94 NO_ALLOC_OPERATIONS_LINE.fetch_sub(1, Ordering::SeqCst);
95
96 if NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst) < 0 {
97 NO_ALLOC_OPERATIONS_LINE.store(0, Ordering::SeqCst);
98 }
99 }
100 }
101 } else {
102 if is_put_to_window == true {
103 // 输出其他字符
104 let char = TextuiCharChromatic::new(Some(character), frcolor, bkcolor);
105
106 if NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)
107 == CHAR_PER_LINE.load(Ordering::SeqCst)
108 {
109 NO_ALLOC_OPERATIONS_INDEX.store(0, Ordering::SeqCst);
110 NO_ALLOC_OPERATIONS_LINE.fetch_add(1, Ordering::SeqCst);
111 }
112 char.no_init_textui_render_chromatic(
113 LineId::new(NO_ALLOC_OPERATIONS_LINE.load(Ordering::SeqCst)),
114 LineIndex::new(NO_ALLOC_OPERATIONS_INDEX.load(Ordering::SeqCst)),
115 );
116
117 NO_ALLOC_OPERATIONS_INDEX.fetch_add(1, Ordering::SeqCst);
118 }
119 }
120
121 return Ok(());
122 }
123