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