mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
完成与Linux兼容的Ntty (#517)
* 已经完成的功能: - 写:printf能够正常在tty输出 - 读:与键盘驱动接上 - 信号: 能够正常通过ctrl向前台进程发送信号 * 支持目前的shell,改动printk使其与新版tty兼容。 * 删除原有tty文件夹,并更改新tty文件名 * 添加clear清屏程序 * 实现tty部分ioctl,更改部分问题
This commit is contained in:
BIN
kernel/src/libs/font/bin/VGA_8X16.bytes
Normal file
BIN
kernel/src/libs/font/bin/VGA_8X16.bytes
Normal file
Binary file not shown.
BIN
kernel/src/libs/font/bin/VGA_8X8.bytes
Normal file
BIN
kernel/src/libs/font/bin/VGA_8X8.bytes
Normal file
Binary file not shown.
2
kernel/src/libs/font/font_type/mod.rs
Normal file
2
kernel/src/libs/font/font_type/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod vga8x16;
|
||||
pub mod vga8x8;
|
10
kernel/src/libs/font/font_type/vga8x16.rs
Normal file
10
kernel/src/libs/font/font_type/vga8x16.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::libs::font::FontDesc;
|
||||
|
||||
pub const FONT_VGA_8X16: FontDesc = FontDesc {
|
||||
index: 1,
|
||||
name: "VGA8x16",
|
||||
width: 8,
|
||||
height: 16,
|
||||
char_count: 256,
|
||||
data: include_bytes!("../bin/VGA_8X16.bytes"),
|
||||
};
|
11
kernel/src/libs/font/font_type/vga8x8.rs
Normal file
11
kernel/src/libs/font/font_type/vga8x8.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::libs::font::FontDesc;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const FONT_VGA_8X8: FontDesc = FontDesc {
|
||||
index: 0,
|
||||
name: "VGA8x8",
|
||||
width: 8,
|
||||
height: 8,
|
||||
char_count: 256,
|
||||
data: include_bytes!("../bin/VGA_8X8.bytes"),
|
||||
};
|
49
kernel/src/libs/font/mod.rs
Normal file
49
kernel/src/libs/font/mod.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use self::font_type::vga8x16::FONT_VGA_8X16;
|
||||
|
||||
pub mod font_type;
|
||||
|
||||
pub struct FontDesc {
|
||||
pub index: usize,
|
||||
pub name: &'static str,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub char_count: u32,
|
||||
pub data: &'static [u8],
|
||||
}
|
||||
|
||||
impl FontDesc {
|
||||
pub fn get_default_font(_xres: u32, _yres: u32, _font_w: u32, _font_h: u32) -> &'static Self {
|
||||
// todo: 目前先直接返回一个字体
|
||||
&FONT_VGA_8X16
|
||||
}
|
||||
|
||||
pub const DOUBLE_WIDTH_RANGE: &'static [(u32, u32)] = &[
|
||||
(0x1100, 0x115F),
|
||||
(0x2329, 0x232A),
|
||||
(0x2E80, 0x303E),
|
||||
(0x3040, 0xA4CF),
|
||||
(0xAC00, 0xD7A3),
|
||||
(0xF900, 0xFAFF),
|
||||
(0xFE10, 0xFE19),
|
||||
(0xFE30, 0xFE6F),
|
||||
(0xFF00, 0xFF60),
|
||||
(0xFFE0, 0xFFE6),
|
||||
(0x20000, 0x2FFFD),
|
||||
(0x30000, 0x3FFFD),
|
||||
];
|
||||
pub fn is_double_width(ch: u32) -> bool {
|
||||
if ch < Self::DOUBLE_WIDTH_RANGE.first().unwrap().0
|
||||
|| ch > Self::DOUBLE_WIDTH_RANGE.last().unwrap().1
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (first, last) in Self::DOUBLE_WIDTH_RANGE {
|
||||
if ch > *first && ch < *last {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
@ -1,6 +1,11 @@
|
||||
use core::sync::atomic::Ordering;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::driver::tty::tty_device::TtyDevice;
|
||||
use crate::driver::tty::{
|
||||
tty_port::{TtyPort, TTY_PORTS},
|
||||
virtual_terminal::virtual_console::CURRENT_VCNUM,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const NUM_SCAN_CODES: u8 = 0x80;
|
||||
@ -28,25 +33,21 @@ pub enum KeyFlag {
|
||||
pub struct TypeOneFSM {
|
||||
status: ScanCodeStatus,
|
||||
current_state: TypeOneFSMState,
|
||||
tty: Arc<TtyDevice>,
|
||||
}
|
||||
|
||||
impl TypeOneFSM {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(tty: Arc<TtyDevice>) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
status: ScanCodeStatus::new(),
|
||||
current_state: TypeOneFSMState::Start,
|
||||
tty,
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 解析扫描码
|
||||
#[allow(dead_code)]
|
||||
pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
|
||||
self.current_state = self
|
||||
.current_state
|
||||
.parse(scancode, &mut self.status, &self.tty);
|
||||
self.current_state = self.current_state.parse(scancode, &mut self.status);
|
||||
self.current_state
|
||||
}
|
||||
}
|
||||
@ -69,42 +70,30 @@ pub enum TypeOneFSMState {
|
||||
|
||||
impl TypeOneFSMState {
|
||||
/// @brief 状态机总控程序
|
||||
fn parse(
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
||||
// kdebug!("the code is {:#x}\n", scancode);
|
||||
match self {
|
||||
TypeOneFSMState::Start => {
|
||||
return self.handle_start(scancode, scancode_status, tty);
|
||||
return self.handle_start(scancode, scancode_status);
|
||||
}
|
||||
TypeOneFSMState::PauseBreak(n) => {
|
||||
return self.handle_pause_break(*n, scancode_status, tty);
|
||||
return self.handle_pause_break(*n, scancode_status);
|
||||
}
|
||||
TypeOneFSMState::Func0 => {
|
||||
return self.handle_func0(scancode, scancode_status, tty);
|
||||
return self.handle_func0(scancode, scancode_status);
|
||||
}
|
||||
TypeOneFSMState::Type3 => {
|
||||
return self.handle_type3(scancode, scancode_status, tty);
|
||||
}
|
||||
TypeOneFSMState::PrtscPress(n) => {
|
||||
return self.handle_prtsc_press(*n, scancode_status, tty)
|
||||
return self.handle_type3(scancode, scancode_status);
|
||||
}
|
||||
TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status),
|
||||
TypeOneFSMState::PrtscRelease(n) => {
|
||||
return self.handle_prtsc_release(*n, scancode_status, tty)
|
||||
return self.handle_prtsc_release(*n, scancode_status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 处理起始状态
|
||||
fn handle_start(
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
||||
//kdebug!("in handle_start the code is {:#x}\n",scancode);
|
||||
match scancode {
|
||||
0xe1 => {
|
||||
@ -115,7 +104,7 @@ impl TypeOneFSMState {
|
||||
}
|
||||
_ => {
|
||||
//kdebug!("in _d the code is {:#x}\n",scancode);
|
||||
return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status, tty);
|
||||
return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,17 +114,16 @@ impl TypeOneFSMState {
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
|
||||
let i = match self {
|
||||
TypeOneFSMState::PauseBreak(i) => *i,
|
||||
_ => {
|
||||
return self.handle_type3(scancode, scancode_status, tty);
|
||||
return self.handle_type3(scancode, scancode_status);
|
||||
}
|
||||
};
|
||||
if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
|
||||
return self.handle_type3(scancode, scancode_status, tty);
|
||||
return self.handle_type3(scancode, scancode_status);
|
||||
} else {
|
||||
if i == 5 {
|
||||
// 所有Pause Break扫描码都被清除
|
||||
@ -146,12 +134,7 @@ impl TypeOneFSMState {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_func0(
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
||||
//0xE0
|
||||
match scancode {
|
||||
0x2a => {
|
||||
@ -214,7 +197,7 @@ impl TypeOneFSMState {
|
||||
}
|
||||
0x53 => {
|
||||
scancode_status.del = true;
|
||||
Self::emit(tty, 127);
|
||||
Self::emit(127);
|
||||
}
|
||||
0xd3 => {
|
||||
scancode_status.del = false;
|
||||
@ -233,32 +216,32 @@ impl TypeOneFSMState {
|
||||
}
|
||||
0x48 => {
|
||||
scancode_status.arrow_u = true;
|
||||
Self::emit(tty, 224);
|
||||
Self::emit(tty, 72);
|
||||
Self::emit(224);
|
||||
Self::emit(72);
|
||||
}
|
||||
0xc8 => {
|
||||
scancode_status.arrow_u = false;
|
||||
}
|
||||
0x4b => {
|
||||
scancode_status.arrow_l = true;
|
||||
Self::emit(tty, 224);
|
||||
Self::emit(tty, 75);
|
||||
Self::emit(224);
|
||||
Self::emit(75);
|
||||
}
|
||||
0xcb => {
|
||||
scancode_status.arrow_l = false;
|
||||
}
|
||||
0x50 => {
|
||||
scancode_status.arrow_d = true;
|
||||
Self::emit(tty, 224);
|
||||
Self::emit(tty, 80);
|
||||
Self::emit(224);
|
||||
Self::emit(80);
|
||||
}
|
||||
0xd0 => {
|
||||
scancode_status.arrow_d = false;
|
||||
}
|
||||
0x4d => {
|
||||
scancode_status.arrow_r = true;
|
||||
Self::emit(tty, 224);
|
||||
Self::emit(tty, 77);
|
||||
Self::emit(224);
|
||||
Self::emit(77);
|
||||
}
|
||||
0xcd => {
|
||||
scancode_status.arrow_r = false;
|
||||
@ -269,14 +252,14 @@ impl TypeOneFSMState {
|
||||
scancode_status.kp_forward_slash = true;
|
||||
|
||||
let ch = '/' as u8;
|
||||
Self::emit(tty, ch);
|
||||
Self::emit(ch);
|
||||
}
|
||||
0xb5 => {
|
||||
scancode_status.kp_forward_slash = false;
|
||||
}
|
||||
0x1c => {
|
||||
scancode_status.kp_enter = true;
|
||||
Self::emit(tty, '\n' as u8);
|
||||
Self::emit('\n' as u8);
|
||||
}
|
||||
0x9c => {
|
||||
scancode_status.kp_enter = false;
|
||||
@ -288,12 +271,7 @@ impl TypeOneFSMState {
|
||||
return TypeOneFSMState::Start;
|
||||
}
|
||||
|
||||
fn handle_type3(
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
|
||||
// 判断按键是被按下还是抬起
|
||||
let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
|
||||
false //up
|
||||
@ -358,18 +336,36 @@ impl TypeOneFSMState {
|
||||
}
|
||||
}
|
||||
|
||||
let ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
|
||||
let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
|
||||
if key != KeyFlag::NoneFlag {
|
||||
// kdebug!("EMIT: ch is '{}', keyflag is {:?}\n", ch as char, key);
|
||||
Self::emit(tty, ch);
|
||||
if scancode_status.ctrl_l || scancode_status.ctrl_r {
|
||||
ch = Self::to_ctrl(ch);
|
||||
}
|
||||
Self::emit(ch);
|
||||
}
|
||||
return TypeOneFSMState::Start;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_ctrl(ch: u8) -> u8 {
|
||||
return match ch as char {
|
||||
'a'..='z' => ch - 0x40,
|
||||
'A'..='Z' => ch - 0x40,
|
||||
'@'..='_' => ch - 0x40,
|
||||
_ => ch,
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn emit(tty: &Arc<TtyDevice>, ch: u8) {
|
||||
fn emit(ch: u8) {
|
||||
// 发送到tty
|
||||
tty.input(&[ch]).ok();
|
||||
let _ = Self::current_port().receive_buf(&[ch], &[], 1);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn current_port() -> Arc<dyn TtyPort> {
|
||||
TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
|
||||
}
|
||||
|
||||
/// @brief 处理Prtsc按下事件
|
||||
@ -377,7 +373,6 @@ impl TypeOneFSMState {
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
|
||||
let i = match self {
|
||||
@ -389,7 +384,7 @@ impl TypeOneFSMState {
|
||||
return TypeOneFSMState::Start;
|
||||
}
|
||||
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
||||
return self.handle_type3(scancode, scancode_status, tty);
|
||||
return self.handle_type3(scancode, scancode_status);
|
||||
} else {
|
||||
if i == 3 {
|
||||
// 成功解析出PrtscPress
|
||||
@ -405,7 +400,6 @@ impl TypeOneFSMState {
|
||||
&self,
|
||||
scancode: u8,
|
||||
scancode_status: &mut ScanCodeStatus,
|
||||
tty: &Arc<TtyDevice>,
|
||||
) -> TypeOneFSMState {
|
||||
static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
|
||||
let i = match self {
|
||||
@ -417,7 +411,7 @@ impl TypeOneFSMState {
|
||||
return TypeOneFSMState::Start;
|
||||
}
|
||||
if scancode != PRTSC_SCAN_CODE[i as usize] {
|
||||
return self.handle_type3(scancode, scancode_status, tty);
|
||||
return self.handle_type3(scancode, scancode_status);
|
||||
} else {
|
||||
if i == 3 {
|
||||
// 成功解析出PrtscRelease
|
||||
|
@ -8,9 +8,7 @@ use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
driver::{
|
||||
tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
|
||||
},
|
||||
driver::{serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager},
|
||||
libs::{lib_ui::textui::textui_is_enable_put_to_window, rwlock::RwLock, spinlock::SpinLock},
|
||||
mm::VirtAddr,
|
||||
};
|
||||
|
@ -1,6 +1,11 @@
|
||||
use crate::{
|
||||
driver::{
|
||||
tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
|
||||
serial::serial8250::send_to_default_serial8250_port,
|
||||
tty::{
|
||||
tty_driver::TtyOperation, tty_port::TTY_PORTS,
|
||||
virtual_terminal::virtual_console::CURRENT_VCNUM,
|
||||
},
|
||||
video::video_refresh_manager,
|
||||
},
|
||||
kdebug, kinfo,
|
||||
libs::{
|
||||
@ -984,6 +989,29 @@ where
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_textui_putchar(character: u8, fr_color: u32, bk_color: u32) -> i32 {
|
||||
let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
|
||||
if current_vcnum != -1 {
|
||||
// tty已经初始化了之后才输出到屏幕
|
||||
let fr = (fr_color & 0x00ff0000) >> 16;
|
||||
let fg = (fr_color & 0x0000ff00) >> 8;
|
||||
let fb = fr_color & 0x000000ff;
|
||||
let br = (bk_color & 0x00ff0000) >> 16;
|
||||
let bg = (bk_color & 0x0000ff00) >> 8;
|
||||
let bb = bk_color & 0x000000ff;
|
||||
let buf = format!(
|
||||
"\x1B[38;2;{fr};{fg};{fb};48;2;{br};{bg};{bb}m{}\x1B[0m",
|
||||
character as char
|
||||
);
|
||||
let port = TTY_PORTS[current_vcnum as usize].clone();
|
||||
let tty = port.port_data().tty();
|
||||
if tty.is_some() {
|
||||
let tty = tty.unwrap();
|
||||
return tty
|
||||
.write(tty.core(), buf.as_bytes(), buf.len())
|
||||
.map(|_| 0)
|
||||
.unwrap_or_else(|e| e.to_posix_errno());
|
||||
}
|
||||
}
|
||||
return textui_putchar(
|
||||
character as char,
|
||||
FontColor::from(fr_color),
|
||||
|
@ -6,7 +6,7 @@ use core::{
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::driver::{
|
||||
tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
|
||||
serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
|
||||
};
|
||||
|
||||
use super::textui::{
|
||||
|
@ -25,3 +25,5 @@ pub mod volatile;
|
||||
pub mod futex;
|
||||
pub mod rand;
|
||||
pub mod wait_queue;
|
||||
|
||||
pub mod font;
|
||||
|
@ -1,10 +1,20 @@
|
||||
use core::fmt::{self, Write};
|
||||
use core::{
|
||||
fmt::{self, Write},
|
||||
sync::atomic::Ordering,
|
||||
};
|
||||
|
||||
use alloc::string::ToString;
|
||||
|
||||
use super::lib_ui::textui::{textui_putstr, FontColor};
|
||||
|
||||
use crate::{
|
||||
driver::{
|
||||
serial::serial8250::send_to_default_serial8250_port,
|
||||
tty::{
|
||||
tty_driver::TtyOperation, tty_port::TTY_PORTS,
|
||||
virtual_terminal::virtual_console::CURRENT_VCNUM,
|
||||
},
|
||||
},
|
||||
filesystem::procfs::{
|
||||
kmsg::KMSG,
|
||||
log::{LogLevel, LogMessage},
|
||||
@ -57,7 +67,7 @@ macro_rules! kinfo {
|
||||
macro_rules! kwarn {
|
||||
($($arg:tt)*) => {
|
||||
$crate::libs::printk::Logger.log(4,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
$crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::lib_ui::textui::FontColor::YELLOW, $crate::libs::lib_ui::textui::FontColor::BLACK, "[ WARN ] ");
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[1;33m[ WARN ] \x1B[0m"));
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
}
|
||||
}
|
||||
@ -66,7 +76,7 @@ macro_rules! kwarn {
|
||||
macro_rules! kerror {
|
||||
($($arg:tt)*) => {
|
||||
$crate::libs::printk::Logger.log(3,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
$crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::lib_ui::textui::FontColor::RED, $crate::libs::lib_ui::textui::FontColor::BLACK, "[ ERROR ] ");
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ ERROR ] \x1B[0m"));
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
}
|
||||
}
|
||||
@ -75,7 +85,7 @@ macro_rules! kerror {
|
||||
macro_rules! kBUG {
|
||||
($($arg:tt)*) => {
|
||||
$crate::libs::printk::Logger.log(1,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
$crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::lib_ui::textui::FontColor::RED, $crate::libs::lib_ui::textui::FontColor::BLACK, "[ BUG ] ");
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ BUG ] \x1B[0m"));
|
||||
$crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
|
||||
}
|
||||
}
|
||||
@ -91,11 +101,21 @@ impl PrintkWriter {
|
||||
/// 并输出白底黑字
|
||||
/// @param str: 要写入的字符
|
||||
pub fn __write_string(&mut self, s: &str) {
|
||||
textui_putstr(s, FontColor::WHITE, FontColor::BLACK).ok();
|
||||
}
|
||||
|
||||
pub fn __write_string_color(&self, fr_color: FontColor, bk_color: FontColor, s: &str) {
|
||||
textui_putstr(s, fr_color, bk_color).ok();
|
||||
let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
|
||||
if current_vcnum != -1 {
|
||||
// tty已经初始化了之后才输出到屏幕
|
||||
let port = TTY_PORTS[current_vcnum as usize].clone();
|
||||
let tty = port.port_data().tty();
|
||||
if tty.is_some() {
|
||||
let tty = tty.unwrap();
|
||||
let _ = tty.write(tty.core(), s.as_bytes(), s.len());
|
||||
send_to_default_serial8250_port(s.as_bytes());
|
||||
} else {
|
||||
let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
|
||||
}
|
||||
} else {
|
||||
let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user