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