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