xref: /DragonOS/kernel/src/driver/tty/virtual_terminal/virtual_console.rs (revision cf7f801e1d50ee5b04cb728e4251a57f4183bfbc)
1 use core::sync::atomic::{AtomicBool, AtomicIsize, Ordering};
2 
3 use alloc::{
4     sync::{Arc, Weak},
5     vec::Vec,
6 };
7 use bitmap::{traits::BitMapOps, StaticBitmap};
8 use log::warn;
9 
10 use crate::{
11     driver::{
12         serial::serial8250::send_to_default_serial8250_port,
13         tty::{
14             console::ConsoleSwitch,
15             tty_port::{DefaultTtyPort, TtyPort},
16             ConsoleFont, KDMode,
17         },
18     },
19     libs::{font::FontDesc, rwlock::RwLock},
20     process::Pid,
21 };
22 
23 use super::{
24     console_map::{TranslationMap, TranslationMapType},
25     Color, DrawRegion, VtMode, VtModeData, COLOR_TABLE, DEFAULT_BLUE, DEFAULT_GREEN, DEFAULT_RED,
26 };
27 
28 pub(super) const NPAR: usize = 16;
29 
30 lazy_static! {
31     /// 是否已经添加了软光标
32     pub(super) static ref SOFTCURSOR_ORIGINAL: RwLock<Option<VcCursor>> = RwLock::new(None);
33 
34 
35 }
36 
37 pub static CURRENT_VCNUM: AtomicIsize = AtomicIsize::new(-1);
38 
39 pub static CONSOLE_BLANKED: AtomicBool = AtomicBool::new(false);
40 
41 /// ## 虚拟控制台的信息
42 #[derive(Debug, Clone)]
43 pub struct VirtualConsoleData {
44     pub num: usize,
45     pub state: VirtualConsoleInfo,
46     pub saved_state: VirtualConsoleInfo,
47     /// 最大列数
48     pub cols: usize,
49     /// 最大行数
50     pub rows: usize,
51     // ///  每行的字节数
52     // pub bytes_per_row: usize,
53     /// 扫描行数
54     pub scan_lines: usize,
55     /// 字符单元高度
56     pub cell_height: u32,
57 
58     // /// 实际屏幕地址的开始
59     // pub screen_base: VirtAddr,
60     // /// 实际屏幕的结束
61     // pub scr_end: u64,
62     /// 可见窗口的开始
63     pub visible_origin: usize,
64     /// 滚动窗口的顶部
65     pub top: usize,
66     /// 滚动窗口的底部
67     pub bottom: usize,
68     /// 当前读取位置
69     pub pos: usize,
70 
71     /// 颜色集合
72     pub palette: [Color; 16],
73     /// 默认颜色
74     pub def_color: u8,
75     /// 下划线颜色
76     pub underline_color: u32,
77     /// 斜体颜色
78     pub italic_color: u32,
79     /// 半强度颜色
80     pub half_color: u32,
81 
82     pub mode: KDMode,
83     pub vt_mode: VtModeData,
84 
85     /// 是否启用颜色
86     pub color_mode: bool,
87 
88     // 字符
89     pub hi_font_mask: u16,
90     pub font: ConsoleFont,
91 
92     pub erase_char: u16,
93 
94     pub complement_mask: u16,
95     pub s_complement_mask: u16,
96 
97     pub cursor_blink_ms: u16,
98 
99     pub pid: Option<Pid>,
100     pub index: usize,
101 
102     pub vc_state: VirtualConsoleState,
103 
104     // 一些标志
105     /// 指示是否显示 ASCII 字符小于 32 的控制字符(vc_disp_ctrl)
106     pub display_ctrl: bool,
107     /// 指示是否切换高位(meta)位。Meta 键是一个特殊的按键,用于扩展字符集。
108     pub toggle_meta: bool,
109     /// 表示屏幕模式(vc_decscnm)
110     pub screen_mode: bool,
111     /// 指定光标移动的起始位置,是相对于屏幕的左上角还是相对于当前页的左上角(vc_decom)
112     pub origin_mode: bool,
113     /// 控制光标到达行末时是否自动换行(vc_decawm)
114     pub autowrap: bool,
115     /// 控制光标的可见性(vc_deccm)
116     pub cursor_visible: bool,
117     /// 光标相关
118     pub cursor_type: VcCursor,
119     /// 控制插入或替换模式(vc_decim)
120     pub insert_mode: bool,
121     /// 表示一些私有模式或状态,通常由特定终端实现定义(vc_priv)
122     pub private: Vt102_OP,
123     /// 是否需要进行自动换行
124     pub need_wrap: bool,
125     /// 控制鼠标事件的报告方式
126     pub report_mouse: u8,
127     /// 指示终端是否使用 UTF-8 编码
128     pub utf: bool,
129     /// UTF-8 编码的字符计数,表示还需要多少个字节才能够构建完成
130     pub utf_count: u8,
131     /// UTF-8 编码的字符,表示正在构建的utf字符
132     pub utf_char: u32,
133     /// 构建utf时需要的参数,表示目前接收了多少个字节的数据来构建utf字符
134     pub npar: u32,
135     pub par: [u32; NPAR],
136 
137     /// 字符转换表 用于将输入字符映射到特定的字符
138     pub translate: TranslationMap,
139 
140     pub tab_stop: StaticBitmap<256>,
141 
142     pub attr: u8,
143 
144     /// vc缓冲区
145     pub screen_buf: Vec<u16>,
146 
147     /// 对应的Console Driver funcs
148     driver_funcs: Option<Weak<dyn ConsoleSwitch>>,
149 
150     /// 对应端口
151     port: Arc<dyn TtyPort>,
152 }
153 
154 impl VirtualConsoleData {
155     #[inline(never)]
156     pub fn new(num: usize) -> Self {
157         Self {
158             state: VirtualConsoleInfo::new(0, 0),
159             saved_state: Default::default(),
160             cols: Default::default(),
161             rows: Default::default(),
162             // bytes_per_row: Default::default(),
163             scan_lines: Default::default(),
164             cell_height: Default::default(),
165             // origin: Default::default(),
166             // scr_end: Default::default(),
167             visible_origin: Default::default(),
168             top: Default::default(),
169             bottom: Default::default(),
170             palette: [Default::default(); 16],
171             def_color: Default::default(),
172             underline_color: Default::default(),
173             italic_color: Default::default(),
174             half_color: Default::default(),
175             mode: Default::default(),
176             color_mode: Default::default(),
177             hi_font_mask: Default::default(),
178             erase_char: Default::default(),
179             complement_mask: Default::default(),
180             s_complement_mask: Default::default(),
181             cursor_blink_ms: 200,
182             pos: Default::default(),
183             vt_mode: VtModeData {
184                 mode: VtMode::Auto,
185                 relsig: 0,
186                 acqsig: 0,
187             },
188             pid: None,
189             index: 0,
190             font: Default::default(),
191             vc_state: VirtualConsoleState::ESnormal,
192             display_ctrl: Default::default(),
193             toggle_meta: Default::default(),
194             screen_mode: Default::default(),
195             origin_mode: Default::default(),
196             autowrap: Default::default(),
197             cursor_visible: Default::default(),
198             insert_mode: Default::default(),
199             private: Vt102_OP::Pecma,
200             need_wrap: Default::default(),
201             report_mouse: Default::default(),
202             utf: Default::default(),
203             utf_count: Default::default(),
204             utf_char: Default::default(),
205             translate: TranslationMap::new(TranslationMapType::Lat1),
206             npar: Default::default(),
207             tab_stop: StaticBitmap::new(),
208             par: [0; 16],
209             attr: Default::default(),
210             screen_buf: Default::default(),
211             driver_funcs: None,
212             cursor_type: VcCursor::empty(),
213             num,
214             port: Arc::new(DefaultTtyPort::new()),
215         }
216     }
217 
218     #[inline]
219     pub fn port(&self) -> Arc<dyn TtyPort> {
220         self.port.clone()
221     }
222 
223     pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
224         if let Some(rows) = rows {
225             self.rows = rows;
226         }
227         if let Some(cols) = cols {
228             self.cols = cols;
229         }
230 
231         self.pos = self.cols * self.state.y + self.state.x;
232         // self.bytes_per_row = self.cols << 1;
233 
234         self.def_color = 15; // white
235         self.italic_color = 2; // green
236         self.underline_color = 3; // cyan
237         self.half_color = 0x08; // grey
238 
239         self.screen_buf.resize(self.cols * self.rows, 0);
240         self.reset(clear);
241     }
242 
243     pub fn should_update(&self) -> bool {
244         self.is_visible() && !CONSOLE_BLANKED.load(Ordering::SeqCst)
245     }
246 
247     pub fn is_visible(&self) -> bool {
248         let cur_vc = CURRENT_VCNUM.load(Ordering::SeqCst);
249         if cur_vc == -1 {
250             return false;
251         }
252 
253         cur_vc as usize == self.num
254     }
255 
256     fn driver_funcs(&self) -> Arc<dyn ConsoleSwitch> {
257         self.driver_funcs.as_ref().unwrap().upgrade().unwrap()
258     }
259 
260     pub(super) fn set_driver_funcs(&mut self, func: Weak<dyn ConsoleSwitch>) {
261         self.driver_funcs = Some(func);
262     }
263 
264     pub(super) fn reset(&mut self, do_clear: bool) {
265         self.mode = KDMode::KdText;
266         // unicode?
267         self.vt_mode.mode = VtMode::Auto;
268         self.vt_mode.acqsig = 0;
269         self.vt_mode.relsig = 0;
270         self.display_ctrl = false;
271         self.toggle_meta = false;
272         self.screen_mode = false;
273         self.origin_mode = false;
274         self.autowrap = true;
275         self.cursor_visible = true;
276         self.insert_mode = false;
277         self.need_wrap = false;
278         self.report_mouse = 0;
279         self.utf_count = 0;
280         self.translate = TranslationMap::new(TranslationMapType::Lat1);
281         self.utf = true;
282         self.pid = None;
283         self.vc_state = VirtualConsoleState::ESnormal;
284         self.reset_palette();
285         // self.cursor_type = VcCursor::CUR_UNDERLINE;
286         self.cursor_type = VcCursor::CUR_BLOCK;
287 
288         self.default_attr();
289         self.update_attr();
290 
291         self.tab_stop.set_all(false);
292 
293         for i in (0..256).step_by(8) {
294             self.tab_stop.set(i, true);
295         }
296 
297         self.state.x = 0;
298         self.state.y = 0;
299         self.pos = 0;
300 
301         if do_clear {
302             self.csi_J(2);
303         }
304     }
305 
306     fn reset_palette(&mut self) {
307         for (idx, color) in self.palette.iter_mut().enumerate() {
308             color.red = DEFAULT_RED[idx];
309             color.green = DEFAULT_GREEN[idx];
310             color.blue = DEFAULT_BLUE[idx];
311         }
312 
313         self.set_palette();
314     }
315 
316     fn set_palette(&self) {
317         if self.mode != KDMode::KdGraphics {
318             // todo: 通知driver层的Console
319             let _ = self.driver_funcs().con_set_palette(self, COLOR_TABLE);
320         }
321     }
322 
323     /// ## 翻译字符,将字符转换为终端控制符
324     /// ### 参数
325     ///
326     /// ### c: 需要转换的字符
327     ///
328     /// ### 返回值
329     /// ### (转换后的字符:i32,是否需要更多的数据才能进行转换:bool)
330     pub(super) fn translate(&mut self, c: &mut u32) -> (Option<u32>, bool) {
331         if self.vc_state != VirtualConsoleState::ESnormal {
332             // 在控制字符状态下不需要翻译
333             return (Some(*c), false);
334         }
335         if self.utf && !self.display_ctrl {
336             // utf模式并且不显示控制字符
337             let (ret, rescan) = self.translate_unicode(*c);
338             if let Some(ret) = ret {
339                 *c = ret;
340             }
341             return (ret, rescan);
342         }
343 
344         return (Some(self.translate_ascii(*c)), false);
345     }
346 
347     /// 该数组包含每个字节序列长度变化的阈值
348     /// 即如果由两个字节组成的unicode字符,则长度应该在UTF8_LENGTH_CHANGES[0] ~ UTF8_LENGTH_CHANGES[1]之间
349     const UTF8_LENGTH_CHANGES: &'static [u32] = &[
350         0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff,
351     ];
352 
353     /// ## 翻译字符,将UTF-8 编码的字符转换为 Unicode 编码
354     /// ### 参数
355     ///
356     /// ### c: 需要转换的字符
357     ///
358     /// ### 返回值
359     /// ### (转换后的字符:i32,是否需要重新传入该字符:bool)
360     ///
361     /// !!! 注意,该函数返回true时,元组的第一个数据是无效数据(未转换完成)
362     fn translate_unicode(&mut self, c: u32) -> (Option<u32>, bool) {
363         // 收到的字符不是首个
364         if (c & 0xc0) == 0x80 {
365             // 已经不需要继续的字符了,说明这个字符是非法的
366             if self.utf_count == 0 {
367                 return (Some(0xfffd), false);
368             }
369 
370             self.utf_char = (self.utf_char << 6) | (c & 0x3f);
371             self.npar += 1;
372 
373             self.utf_count -= 1;
374             if self.utf_count > 0 {
375                 // 表示需要更多字节
376                 return (None, false);
377             }
378 
379             let c = self.utf_char;
380 
381             // 先检查一遍是否合格
382             if c <= Self::UTF8_LENGTH_CHANGES[self.npar as usize - 1]
383                 || c > Self::UTF8_LENGTH_CHANGES[self.npar as usize]
384             {
385                 return (Some(0xfffd), false);
386             }
387 
388             return (Some(Self::sanitize_unicode(c)), false);
389         }
390 
391         // 接收到单个ASCII字符或者一个序列的首字符,且上次的未处理完,则上一个字符视为无效,则需要重新传入该字符处理
392         if self.utf_count > 0 {
393             self.utf_count = 0;
394             return (Some(0xfffd), true);
395         }
396 
397         // ascii
398         if c <= 0x7f {
399             return (Some(c), false);
400         }
401 
402         // 第一个字节
403         self.npar = 0;
404         if (c & 0xe0) == 0xc0 {
405             self.utf_count = 1;
406             self.utf_char = c & 0x1f;
407         } else if (c & 0xf0) == 0xe0 {
408             self.utf_count = 2;
409             self.utf_char = c & 0x0f;
410         } else if (c & 0xf8) == 0xf0 {
411             self.utf_count = 3;
412             self.utf_char = c & 0x07;
413         } else if (c & 0xfc) == 0xf8 {
414             self.utf_count = 4;
415             self.utf_char = c & 0x03;
416         } else if (c & 0xfe) == 0xfc {
417             self.utf_count = 5;
418             self.utf_char = c & 0x01;
419         } else {
420             /* 254 and 255 are invalid */
421             return (Some(0xfffd), false);
422         }
423 
424         (None, false)
425     }
426 
427     /// ## 翻译字符,将字符转换为Ascii
428     fn translate_ascii(&self, c: u32) -> u32 {
429         let mut c = c;
430         if self.toggle_meta {
431             c |= 0x80;
432         }
433 
434         return self.translate.translate(c) as u32;
435     }
436 
437     /// ## 用于替换无效的 Unicode 代码点(code points)。
438     /// Unicode 代码点的范围是从 U+0000 到 U+10FFFF,
439     /// 但是有一些特殊的代码点是无效的或者保留给特定用途的。
440     /// 这个函数的主要目的是将无效的 Unicode 代码点替换为 U+FFFD,即 Unicode 替代字符。
441     fn sanitize_unicode(c: u32) -> u32 {
442         if (0xd800..=0xdfff).contains(&c) || c == 0xfffe || c == 0xffff {
443             return 0xfffd;
444         }
445         return c;
446     }
447 
448     /// 用于表示小于 32 的字符中,哪些字符对应的位被设置为 1,
449     /// 表示这些字符会触发一些特殊的动作,比如光标移动等。
450     /// 这些字符在 disp_ctrl 模式未开启时不应该被显示为图形符号
451     const CTRL_ACTION: u32 = 0x0d00ff81;
452     /// 用于表示哪些控制字符是始终显示的,即便 disp_ctrl 模式未开启。
453     /// 这些字符对于终端来说是必要的,显示它们是为了保证终端正常工作。
454     /// 这些字符在 disp_ctrl 模式开启或关闭时都应该显示为控制字符。
455     const CTRL_ALWAYS: u32 = 0x0800f501;
456 
457     /// ## 用于判断tc(终端字符)在当前VC下是不是需要显示的控制字符
458     pub(super) fn is_control(&self, tc: u32, c: u32) -> bool {
459         // 当前vc状态机不在正常状态,即在接收特殊字符的状态,则是控制字符
460         if self.vc_state != VirtualConsoleState::ESnormal {
461             return true;
462         }
463 
464         if tc == 0 {
465             return true;
466         }
467 
468         if c < 32 {
469             if self.display_ctrl {
470                 // 查看在位图中是否有该字符
471                 return Self::CTRL_ALWAYS & (1 << c) != 0;
472             } else {
473                 return self.utf || (Self::CTRL_ACTION & (1 << c) != 0);
474             }
475         }
476 
477         if c == 127 && !self.display_ctrl {
478             return true;
479         }
480 
481         if c == 128 + 27 {
482             return true;
483         }
484 
485         false
486     }
487 
488     pub(super) fn set_cursor(&mut self) {
489         if self.mode == KDMode::KdGraphics {
490             return;
491         }
492 
493         if self.cursor_visible {
494             // TODO: 处理选择
495             self.add_softcursor();
496             if self.cursor_type.cursor_size() != VcCursor::CUR_NONE {
497                 self.driver_funcs().con_cursor(self, CursorOperation::Draw);
498             }
499         } else {
500             self.hide_cursor();
501         }
502     }
503 
504     /// ## 添加软光标
505     fn add_softcursor(&mut self) {
506         let mut i = self.screen_buf[self.pos] as u32;
507         let cursor_type = self.cursor_type;
508 
509         if !cursor_type.contains(VcCursor::CUR_SW) {
510             return;
511         }
512 
513         if SOFTCURSOR_ORIGINAL.read_irqsave().is_some() {
514             // 已经设置了软光标
515             return;
516         }
517 
518         let mut soft_cursor_guard = SOFTCURSOR_ORIGINAL.write_irqsave();
519         *soft_cursor_guard = Some(unsafe { VcCursor::from_bits_unchecked(i) });
520 
521         let soft_cursor = soft_cursor_guard.unwrap();
522 
523         i |= cursor_type.cursor_set();
524         i ^= cursor_type.cursor_change();
525         if cursor_type.contains(VcCursor::CUR_ALWAYS_BG)
526             && ((soft_cursor.bits & VcCursor::CUR_BG.bits) == (i & VcCursor::CUR_BG.bits))
527         {
528             i ^= VcCursor::CUR_BG.bits;
529         }
530         if cursor_type.contains(VcCursor::CUR_INVERT_FG_BG)
531             && ((i & VcCursor::CUR_FG.bits) == ((i & VcCursor::CUR_BG.bits) >> 4))
532         {
533             i ^= VcCursor::CUR_FG.bits;
534         }
535 
536         self.screen_buf[self.pos] = i as u16;
537 
538         let _ =
539             self.driver_funcs()
540                 .con_putc(self, i as u16, self.state.y as u32, self.state.x as u32);
541     }
542 
543     pub fn hide_cursor(&mut self) {
544         // TODO: 处理选择
545 
546         self.driver_funcs().con_cursor(self, CursorOperation::Erase);
547         self.hide_softcursor();
548     }
549 
550     fn hide_softcursor(&mut self) {
551         let softcursor = SOFTCURSOR_ORIGINAL.upgradeable_read_irqsave();
552         if softcursor.is_some() {
553             self.screen_buf[self.pos] = softcursor.unwrap().bits as u16;
554             let _ = self.driver_funcs().con_putc(
555                 self,
556                 softcursor.unwrap().bits as u16,
557                 self.state.y as u32,
558                 self.state.x as u32,
559             );
560 
561             *softcursor.upgrade() = None;
562         }
563     }
564 
565     fn gotoxay(&mut self, x: i32, y: i32) {
566         if self.origin_mode {
567             self.gotoxy(x, self.top as i32 + y);
568         } else {
569             self.gotoxy(x, y)
570         }
571     }
572 
573     // ## 将当前vc的光标移动到目标位置
574     fn gotoxy(&mut self, x: i32, y: i32) {
575         if x < 0 {
576             self.state.x = 0;
577         } else if x as usize >= self.cols {
578             self.state.x = self.cols - 1;
579         } else {
580             self.state.x = x as usize;
581         }
582 
583         let max_y;
584         let min_y;
585         if self.origin_mode {
586             min_y = self.top;
587             max_y = self.bottom - 1;
588         } else {
589             min_y = 0;
590             max_y = self.rows - 1;
591         }
592 
593         if y < min_y as i32 {
594             self.state.y = min_y;
595         } else if y >= max_y as i32 {
596             self.state.y = max_y;
597         } else {
598             self.state.y = y as usize;
599         }
600 
601         self.pos = self.state.y * self.cols + self.state.x;
602         self.need_wrap = false;
603     }
604 
605     fn scroll(&mut self, dir: ScrollDir, mut nr: usize) {
606         // todo: uniscr_srceen
607         if self.top + nr >= self.bottom {
608             // 滚动超过一页,则按一页计算
609             nr = self.bottom - self.top - 1;
610         }
611 
612         if nr < 1 {
613             return;
614         }
615 
616         if self.is_visible()
617             && self
618                 .driver_funcs()
619                 .con_scroll(self, self.top, self.bottom, dir, nr)
620         {
621             // 如果成功
622             return;
623         }
624 
625         // 调整screen_buf
626         let count = nr * self.cols;
627         if dir == ScrollDir::Up {
628             for i in self.screen_buf[0..count].iter_mut() {
629                 *i = self.erase_char;
630             }
631             self.screen_buf.rotate_left(count);
632         } else if dir == ScrollDir::Down {
633             todo!();
634         }
635     }
636 
637     /// ## 退格
638     fn backspace(&mut self) {
639         if self.state.x > 0 {
640             self.pos -= 1;
641             self.state.x -= 1;
642             self.need_wrap = false;
643 
644             // TODO: notify
645         }
646     }
647 
648     /// ## 换行
649     fn line_feed(&mut self) {
650         if self.state.y + 1 == self.bottom {
651             self.scroll(ScrollDir::Up, 1);
652         } else if self.state.y < self.rows - 1 {
653             self.state.y += 1;
654             self.pos += self.cols;
655         }
656 
657         self.need_wrap = false;
658         // TODO: Notify write
659     }
660 
661     /// ## 回车
662     fn carriage_return(&mut self) {
663         // 写入位置回退到该行最前
664         self.pos -= self.state.x;
665         self.need_wrap = false;
666         self.state.x = 0;
667     }
668 
669     /// ## Del
670     fn delete(&mut self) {
671         // ignore
672     }
673 
674     /// ## 向上滚动虚拟终端的内容,或者将光标上移一行
675     fn reverse_index(&mut self) {
676         if self.state.y == self.top {
677             self.scroll(ScrollDir::Down, 1);
678         } else if self.state.y > 0 {
679             self.state.y -= 1;
680             self.pos -= self.cols;
681         }
682         self.need_wrap = false;
683     }
684 
685     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/vt/vt.c#restore_cur
686     fn restore_cursor(&mut self) {
687         self.saved_state = self.state.clone();
688 
689         self.gotoxy(self.state.x as i32, self.state.y as i32);
690 
691         // TODO Gx_charset
692 
693         self.update_attr();
694         self.need_wrap = false;
695         todo!()
696     }
697 
698     /// ## 设置当前vt的各项属性
699     fn set_mode(&mut self, on_off: bool) {
700         for i in 0..self.npar as usize {
701             if self.private == Vt102_OP::Pdec {
702                 match self.par[i] {
703                     1 => {
704                         todo!("kbd todo");
705                     }
706                     3 => {
707                         todo!("reisze todo");
708                     }
709                     5 => {
710                         todo!("invert_screen todo");
711                     }
712                     6 => {
713                         self.origin_mode = on_off;
714                         if on_off {
715                             self.gotoxy(0, self.top as i32);
716                         } else {
717                             self.gotoxy(0, 0);
718                         }
719                     }
720                     7 => {
721                         self.autowrap = on_off;
722                     }
723                     8 => {
724                         todo!("kbd todo");
725                     }
726                     9 => {
727                         todo!("report mouse todo");
728                     }
729                     25 => {
730                         self.cursor_visible = on_off;
731                     }
732                     1000 => {
733                         todo!("report mouse todo");
734                     }
735                     _ => {}
736                 }
737             } else {
738                 match self.par[i] {
739                     3 => {
740                         self.display_ctrl = on_off;
741                     }
742                     4 => {
743                         self.insert_mode = on_off;
744                     }
745                     20 => {
746                         todo!("kbd todo");
747                     }
748                     _ => {}
749                 }
750             }
751         }
752     }
753 
754     #[inline(never)]
755     fn do_getpars(&mut self, c: char) {
756         if c == ';' && self.npar < (NPAR - 1) as u32 {
757             self.npar += 1;
758             return;
759         }
760 
761         if c.is_ascii_digit() {
762             self.par[self.npar as usize] *= 10;
763             self.par[self.npar as usize] += (c as u8 - b'0') as u32;
764             return;
765         }
766 
767         if c as u8 >= 0x20 && c as u8 <= 0x3f {
768             self.vc_state = VirtualConsoleState::EScsiignore;
769             return;
770         }
771 
772         self.vc_state = VirtualConsoleState::ESnormal;
773 
774         match c {
775             'h' => {
776                 if self.private <= Vt102_OP::Pdec {
777                     self.set_mode(true);
778                 }
779                 return;
780             }
781             'l' => {
782                 if self.private <= Vt102_OP::Pdec {
783                     self.set_mode(false);
784                 }
785                 return;
786             }
787             'c' => {
788                 if self.private == Vt102_OP::Pdec {
789                     if self.par[0] != 0 {
790                         self.cursor_type =
791                             VcCursor::make_cursor(self.par[0], self.par[1], self.par[2])
792                     } else {
793                         self.cursor_type = VcCursor::CUR_UNDERLINE;
794                     }
795                     return;
796                 }
797             }
798             'm' => {
799                 if self.private == Vt102_OP::Pdec {
800                     if self.par[0] != 0 {
801                         self.complement_mask = (self.par[0] << 8 | self.par[1]) as u16;
802                     } else {
803                         self.complement_mask = self.s_complement_mask;
804                     }
805                     return;
806                 }
807             }
808             'n' => {
809                 if self.private == Vt102_OP::Pecma {
810                     if self.par[0] == 5 {
811                         send_to_default_serial8250_port("tty status report todo".as_bytes());
812                         panic!();
813                     } else if self.par[0] == 6 {
814                         send_to_default_serial8250_port("tty cursor report todo".as_bytes());
815                         panic!();
816                     }
817                 }
818                 return;
819             }
820             _ => {}
821         }
822 
823         if self.private != Vt102_OP::Pecma {
824             self.private = Vt102_OP::Pecma;
825             return;
826         }
827 
828         match c {
829             'G' | '`' => {
830                 if self.par[0] != 0 {
831                     self.par[0] -= 1;
832                 }
833                 self.gotoxy(self.par[0] as i32, self.state.y as i32);
834                 return;
835             }
836             'A' => {
837                 if self.par[0] == 0 {
838                     self.par[0] += 1;
839                 }
840                 self.gotoxy(
841                     self.state.x as i32,
842                     (self.state.y - self.par[0] as usize) as i32,
843                 );
844                 return;
845             }
846             'B' | 'e' => {
847                 if self.par[0] == 0 {
848                     self.par[0] += 1;
849                 }
850                 self.gotoxy(
851                     self.state.x as i32,
852                     (self.state.y + self.par[0] as usize) as i32,
853                 );
854                 return;
855             }
856             'C' | 'a' => {
857                 if self.par[0] == 0 {
858                     self.par[0] += 1;
859                 }
860                 self.gotoxy(
861                     (self.state.x + self.par[0] as usize) as i32,
862                     self.state.y as i32,
863                 );
864                 return;
865             }
866             'D' => {
867                 if self.par[0] == 0 {
868                     self.par[0] += 1;
869                 }
870                 self.gotoxy(
871                     self.state.x as i32 - self.par[0] as i32,
872                     self.state.y as i32,
873                 );
874                 return;
875             }
876             'E' => {
877                 if self.par[0] == 0 {
878                     self.par[0] += 1;
879                 }
880                 self.gotoxy(0, (self.state.y + self.par[0] as usize) as i32);
881                 return;
882             }
883             'F' => {
884                 if self.par[0] == 0 {
885                     self.par[0] += 1;
886                 }
887                 self.gotoxy(0, self.state.y as i32 - self.par[0] as i32);
888                 return;
889             }
890             'd' => {
891                 if self.par[0] != 0 {
892                     self.par[0] -= 1;
893                 }
894                 self.gotoxay(self.state.x as i32, self.par[0] as i32);
895                 return;
896             }
897             'H' | 'f' => {
898                 // MOVETO
899                 if self.par[0] != 0 {
900                     self.par[0] -= 1;
901                 }
902                 if self.par[1] != 0 {
903                     self.par[1] -= 1;
904                 }
905                 self.gotoxay(self.par[1] as i32, self.par[0] as i32);
906                 return;
907             }
908             'J' => {
909                 self.csi_J(self.par[0]);
910                 return;
911             }
912             'K' => {
913                 self.csi_K(self.par[0]);
914                 return;
915             }
916             'L' => {
917                 todo!("csi_L todo");
918             }
919             'M' => {
920                 todo!("csi_M todo");
921             }
922             'P' => {
923                 todo!("csi_P todo");
924             }
925 
926             // 非ANSI标准,为ANSI拓展
927             'S' => {
928                 self.scroll(ScrollDir::Up, self.par[0] as usize);
929                 return;
930             }
931 
932             'T' => {
933                 self.scroll(ScrollDir::Down, self.par[0] as usize);
934                 return;
935             }
936 
937             'c' => {
938                 if self.par[0] == 0 {
939                     warn!("respone ID todo");
940                 }
941                 return;
942             }
943             'g' => {
944                 if self.par[0] == 0 && self.state.x < 256 {
945                     self.tab_stop.set(self.state.x, true);
946                 } else if self.par[0] == 3 {
947                     self.tab_stop.set_all(false);
948                 }
949                 return;
950             }
951             'm' => {
952                 self.csi_m();
953                 return;
954             }
955             'q' => {
956                 if self.par[0] < 4 {
957                     todo!("vt set led state todo");
958                 }
959                 return;
960             }
961             'r' => {
962                 if self.par[0] == 0 {
963                     self.par[0] += 1;
964                 }
965                 if self.par[1] == 0 {
966                     self.par[1] = self.rows as u32;
967                 }
968                 if self.par[0] < self.par[1] && self.par[1] <= self.rows as u32 {
969                     self.top = self.par[0] as usize - 1;
970                     self.bottom = self.par[1] as usize;
971                     self.gotoxay(0, 0);
972                 }
973                 return;
974             }
975             's' => {
976                 self.saved_state = self.state.clone();
977                 return;
978             }
979             'u' => {
980                 self.restore_cursor();
981                 return;
982             }
983             '@' => {
984                 todo!("csi_at todo");
985             }
986             ']' => {
987                 todo!("set termial command todo");
988             }
989             _ => {}
990         }
991     }
992 
993     /// ##  处理Control Sequence Introducer(控制序列引导符) m字符
994     #[inline(never)]
995     fn csi_m(&mut self) {
996         let mut i = 0;
997         loop {
998             if i > self.npar as usize {
999                 break;
1000             }
1001             match self.par[i] {
1002                 0 => {
1003                     // 关闭所有属性
1004                     self.default_attr();
1005                 }
1006 
1007                 1 => {
1008                     // 设置粗体
1009                     self.state.intensity = VirtualConsoleIntensity::Bold;
1010                 }
1011 
1012                 2 => {
1013                     // 设置半亮度(半明显
1014                     self.state.intensity = VirtualConsoleIntensity::HalfBright;
1015                 }
1016 
1017                 3 => {
1018                     // 斜体
1019                     self.state.italic = true;
1020                 }
1021 
1022                 4 | 21 => {
1023                     // 下划线
1024 
1025                     // 21是设置双下划线,但是不支持,就单下划线
1026                     self.state.underline = true;
1027                 }
1028 
1029                 5 => {
1030                     // 设置闪烁
1031                     self.state.blink = true;
1032                 }
1033 
1034                 7 => {
1035                     // 设置反显(前景色与背景色对调)
1036                     self.state.reverse = true;
1037                 }
1038 
1039                 10 => {
1040                     // 选择主要字体
1041                     todo!()
1042                 }
1043 
1044                 11 => {
1045                     // 选择第一个替代字体
1046                     todo!()
1047                 }
1048 
1049                 12 => {
1050                     // 选择第二个替代字体
1051                     todo!()
1052                 }
1053 
1054                 22 => {
1055                     //  关闭粗体和半亮度,恢复正常亮度
1056                     self.state.intensity = VirtualConsoleIntensity::Normal;
1057                 }
1058 
1059                 23 => {
1060                     // 关闭斜体
1061                     self.state.italic = false;
1062                 }
1063 
1064                 24 => {
1065                     // 关闭下划线
1066                     self.state.underline = false;
1067                 }
1068 
1069                 25 => {
1070                     // 关闭字符闪烁
1071                     self.state.blink = false;
1072                 }
1073 
1074                 27 => {
1075                     // 关闭反显
1076                     self.state.reverse = false;
1077                 }
1078 
1079                 38 => {
1080                     // 设置前景色
1081                     let (idx, color) = self.t416_color(i);
1082                     i = idx;
1083                     if let Some(color) = color {
1084                         let mut max = color.red.max(color.green);
1085                         max = max.max(color.blue);
1086 
1087                         let mut hue = 0;
1088                         if color.red > max / 2 {
1089                             hue |= 4;
1090                         }
1091                         if color.green > max / 2 {
1092                             hue |= 2;
1093                         }
1094                         if color.blue > max / 2 {
1095                             hue |= 1;
1096                         }
1097 
1098                         if hue == 7 && max <= 0x55 {
1099                             hue = 0;
1100                             self.state.intensity = VirtualConsoleIntensity::Bold;
1101                         } else if max > 0xaa {
1102                             self.state.intensity = VirtualConsoleIntensity::Bold;
1103                         } else {
1104                             self.state.intensity = VirtualConsoleIntensity::Normal;
1105                         }
1106 
1107                         self.state.color = (self.state.color & 0xf0) | hue;
1108                     }
1109                 }
1110 
1111                 48 => {
1112                     // 设置背景色
1113                     let (idx, color) = self.t416_color(i);
1114                     i = idx;
1115                     if let Some(color) = color {
1116                         self.state.color = (self.state.color & 0x0f)
1117                             | ((color.red as u8 & 0x80) >> 1)
1118                             | ((color.green as u8 & 0x80) >> 2)
1119                             | ((color.blue as u8 & 0x80) >> 3);
1120                     }
1121                 }
1122 
1123                 39 => {
1124                     // 恢复默认前景色
1125                     self.state.color = (self.def_color & 0x0f) | (self.state.color & 0xf0);
1126                 }
1127 
1128                 49 => {
1129                     // 恢复默认背景色
1130                     self.state.color = (self.def_color & 0xf0) | (self.state.color & 0x0f);
1131                 }
1132 
1133                 _ => {
1134                     if self.par[i] >= 90 && self.par[i] <= 107 {
1135                         if self.par[i] < 100 {
1136                             self.state.intensity = VirtualConsoleIntensity::Bold;
1137                         }
1138                         self.par[i] -= 60;
1139                     }
1140 
1141                     if self.par[i] >= 30 && self.par[i] <= 37 {
1142                         self.state.color =
1143                             COLOR_TABLE[self.par[i] as usize - 30] | self.state.color & 0xf0;
1144                     } else if self.par[i] >= 40 && self.par[i] <= 47 {
1145                         self.state.color =
1146                             (COLOR_TABLE[self.par[i] as usize - 40] << 4) | self.state.color & 0xf0;
1147                     }
1148                 }
1149             }
1150 
1151             i += 1;
1152         }
1153 
1154         self.update_attr();
1155     }
1156 
1157     /// ##  处理Control Sequence Introducer(控制序列引导符) J字符
1158     /// 该命令用于擦除终端显示区域的部分或全部内容。根据参数 vpar 的不同值,执行不同的擦除操作:
1159     /// - vpar 为 0 时,擦除从光标位置到显示区域末尾的内容;
1160     /// - vpar 为 1 时,擦除从显示区域起始位置到光标位置的内容;
1161     /// - vpar 为 2 或 3 时,分别表示擦除整个显示区域的内容,其中参数 3 还会清除回滚缓冲区的内容。
1162     #[allow(non_snake_case)]
1163     fn csi_J(&mut self, vpar: u32) {
1164         let count;
1165         let start;
1166 
1167         match vpar {
1168             0 => {
1169                 // 擦除从光标位置到显示区域末尾的内容
1170                 count = self.screen_buf.len() - self.pos;
1171                 start = self.pos;
1172             }
1173             1 => {
1174                 // 擦除从显示区域起始位置到光标位置的内容
1175                 count = self.pos;
1176                 start = 0;
1177             }
1178             2 => {
1179                 // 擦除整个显示区域的内容
1180                 count = self.screen_buf.len();
1181                 start = 0;
1182             }
1183             3 => {
1184                 // 表示擦除整个显示区域的内容,还会清除回滚缓冲区的内容
1185                 // TODO:当前未实现回滚缓冲
1186                 count = self.screen_buf.len();
1187                 start = 0;
1188             }
1189             _ => {
1190                 return;
1191             }
1192         }
1193 
1194         for i in self.screen_buf[start..(start + count)].iter_mut() {
1195             *i = self.erase_char;
1196         }
1197 
1198         if self.should_update() {
1199             self.do_update_region(start, count)
1200         }
1201 
1202         self.need_wrap = false;
1203     }
1204 
1205     /// ##  处理Control Sequence Introducer(控制序列引导符) K字符
1206     /// 该命令用于擦除终端当前行的部分或全部内容。根据参数 vpar 的不同值,执行不同的擦除操作:
1207     /// - vpar 为 0 时,擦除从光标位置到该行末尾的内容
1208     /// - vpar 为 1 时,擦除从该行起始位置到光标位置的内容
1209     /// - vpar 为 2 时,擦除整个行。
1210     #[allow(non_snake_case)]
1211     fn csi_K(&mut self, vpar: u32) {
1212         let count;
1213         let start;
1214 
1215         match vpar {
1216             0 => {
1217                 // 擦除从光标位置到该行末尾的内容
1218                 count = self.cols - self.state.x;
1219                 start = self.pos;
1220             }
1221             1 => {
1222                 // 擦除从该行起始位置到光标位置的内容
1223                 count = self.state.x + 1;
1224                 start = self.pos - self.state.x;
1225             }
1226             2 => {
1227                 // 擦除整个行
1228                 count = self.cols;
1229                 start = self.pos - self.state.x;
1230             }
1231             _ => {
1232                 return;
1233             }
1234         }
1235 
1236         let max_idx = self.screen_buf.len();
1237         for i in self.screen_buf[start..max_idx.min(start + count)].iter_mut() {
1238             *i = self.erase_char;
1239         }
1240 
1241         if self.should_update() {
1242             self.do_update_region(start, count.min(max_idx - start))
1243         }
1244 
1245         self.need_wrap = false;
1246     }
1247 
1248     fn t416_color(&mut self, mut idx: usize) -> (usize, Option<Color>) {
1249         idx += 1;
1250         if idx > self.npar as usize {
1251             return (idx, None);
1252         }
1253 
1254         if self.par[idx] == 5 && idx < self.npar as usize {
1255             // 256色
1256             idx += 1;
1257             return (idx, Some(Color::from_256(self.par[idx])));
1258         } else if self.par[idx] == 2 && idx + 3 <= self.npar as usize {
1259             // 24位
1260             let color = Color {
1261                 red: self.par[idx + 1] as u16,
1262                 green: self.par[idx + 2] as u16,
1263                 blue: self.par[idx + 3] as u16,
1264                 ..Default::default()
1265             };
1266             idx += 3;
1267             return (idx, Some(color));
1268         } else {
1269             return (idx, None);
1270         }
1271     }
1272 
1273     /// ## 处理终端控制字符
1274     #[inline(never)]
1275     pub(super) fn do_control(&mut self, ch: u32) {
1276         // 首先检查是否处于 ANSI 控制字符串状态
1277         if self.vc_state.is_ansi_control_string() && (8..=13).contains(&ch) {
1278             return;
1279         }
1280 
1281         match ch {
1282             0 => {
1283                 return;
1284             }
1285             7 => {
1286                 // BEL
1287                 if self.vc_state.is_ansi_control_string() {
1288                     self.vc_state = VirtualConsoleState::ESnormal;
1289                 }
1290                 // TODO: 发出声音?
1291                 return;
1292             }
1293             8 => {
1294                 // BS backspace
1295                 self.backspace();
1296                 return;
1297             }
1298             9 => {
1299                 // 水平制表符(Horizontal Tab)
1300                 self.pos -= self.state.x;
1301 
1302                 let ret = self.tab_stop.next_index(self.state.x + 1);
1303 
1304                 if let Some(x) = ret {
1305                     self.state.x = x;
1306                 } else {
1307                     self.state.x = self.cols - 1;
1308                 }
1309 
1310                 self.pos += self.state.x;
1311                 // TODO: notify
1312                 return;
1313             }
1314             10..=12 => {
1315                 // LD line feed
1316                 self.line_feed();
1317                 // TODO: 检查键盘模式
1318                 self.carriage_return();
1319                 return;
1320             }
1321             13 => {
1322                 // CR 回车符
1323                 self.carriage_return();
1324                 return;
1325             }
1326             14 => {
1327                 todo!("Gx_charset todo!");
1328             }
1329             15 => {
1330                 todo!("Gx_charset todo!");
1331             }
1332             24 | 26 => {
1333                 self.vc_state = VirtualConsoleState::ESnormal;
1334                 return;
1335             }
1336             27 => {
1337                 // esc
1338                 self.vc_state = VirtualConsoleState::ESesc;
1339                 return;
1340             }
1341             127 => {
1342                 // delete
1343                 self.delete();
1344                 return;
1345             }
1346             155 => {
1347                 // '['
1348                 self.vc_state = VirtualConsoleState::ESsquare;
1349                 return;
1350             }
1351             _ => {}
1352         }
1353 
1354         match self.vc_state {
1355             VirtualConsoleState::ESesc => {
1356                 self.vc_state = VirtualConsoleState::ESnormal;
1357                 match ch as u8 as char {
1358                     '[' => {
1359                         self.vc_state = VirtualConsoleState::ESsquare;
1360                     }
1361                     ']' => {
1362                         self.vc_state = VirtualConsoleState::ESnonstd;
1363                     }
1364                     '_' => {
1365                         self.vc_state = VirtualConsoleState::ESapc;
1366                     }
1367                     '^' => {
1368                         self.vc_state = VirtualConsoleState::ESpm;
1369                     }
1370                     '%' => {
1371                         self.vc_state = VirtualConsoleState::ESpercent;
1372                     }
1373                     'E' => {
1374                         self.carriage_return();
1375                         self.line_feed();
1376                     }
1377                     'M' => {
1378                         self.reverse_index();
1379                     }
1380                     'D' => {
1381                         self.line_feed();
1382                     }
1383                     'H' => {
1384                         if self.state.x < 256 {
1385                             self.tab_stop.set(self.state.x, true);
1386                         }
1387                     }
1388                     'P' => {
1389                         self.vc_state = VirtualConsoleState::ESdcs;
1390                     }
1391                     'Z' => {
1392                         todo!("Respond ID todo!");
1393                     }
1394                     '7' => self.saved_state = self.state.clone(),
1395                     '8' => self.restore_cursor(),
1396                     '(' => {
1397                         self.vc_state = VirtualConsoleState::ESsetG0;
1398                     }
1399                     ')' => {
1400                         self.vc_state = VirtualConsoleState::ESsetG1;
1401                     }
1402                     '#' => {
1403                         self.vc_state = VirtualConsoleState::EShash;
1404                     }
1405                     'c' => {
1406                         self.reset(true);
1407                     }
1408                     '>' => {
1409                         todo!("clr_kbd todo");
1410                     }
1411                     '=' => {
1412                         todo!("set_kbd todo");
1413                     }
1414                     _ => {}
1415                 }
1416             }
1417             VirtualConsoleState::ESsquare => {
1418                 for i in self.par.iter_mut() {
1419                     *i = 0;
1420                 }
1421                 self.vc_state = VirtualConsoleState::ESgetpars;
1422                 self.npar = 0;
1423                 let c = ch as u8 as char;
1424                 if c == '[' {
1425                     self.vc_state = VirtualConsoleState::ESfunckey;
1426                     return;
1427                 }
1428 
1429                 match c {
1430                     '?' => {
1431                         self.private = Vt102_OP::Pdec;
1432                         return;
1433                     }
1434                     '>' => {
1435                         self.private = Vt102_OP::Pgt;
1436                         return;
1437                     }
1438                     '=' => {
1439                         self.private = Vt102_OP::Peq;
1440                         return;
1441                     }
1442                     '<' => {
1443                         self.private = Vt102_OP::Plt;
1444                         return;
1445                     }
1446                     _ => {}
1447                 }
1448 
1449                 self.private = Vt102_OP::Pecma;
1450                 self.do_getpars(c);
1451             }
1452             VirtualConsoleState::ESgetpars => {
1453                 let c = ch as u8 as char;
1454                 self.do_getpars(c);
1455             }
1456             VirtualConsoleState::ESfunckey => {
1457                 self.vc_state = VirtualConsoleState::ESnormal;
1458                 return;
1459             }
1460             VirtualConsoleState::EShash => {
1461                 self.vc_state = VirtualConsoleState::ESnormal;
1462                 if ch as u8 as char == '8' {
1463                     self.erase_char = (self.erase_char & 0xff00) | 'E' as u16;
1464                     self.csi_J(2);
1465                     self.erase_char = (self.erase_char & 0xff00) | ' ' as u16;
1466                     self.do_update_region(0, self.screen_buf.len());
1467                 }
1468                 return;
1469             }
1470             VirtualConsoleState::ESsetG0 => {
1471                 todo!("SetGx todo");
1472             }
1473             VirtualConsoleState::ESsetG1 => {
1474                 todo!("SetGx todo");
1475             }
1476             VirtualConsoleState::ESpercent => {
1477                 self.vc_state = VirtualConsoleState::ESnormal;
1478                 let c = ch as u8 as char;
1479                 match c {
1480                     '@' => {
1481                         self.utf = false;
1482                         return;
1483                     }
1484                     'G' | '8' => {
1485                         self.utf = true;
1486                         return;
1487                     }
1488                     _ => {}
1489                 }
1490                 return;
1491             }
1492             VirtualConsoleState::EScsiignore => {
1493                 if (20..=0x3f).contains(&ch) {
1494                     return;
1495                 }
1496                 self.vc_state = VirtualConsoleState::ESnormal;
1497                 return;
1498             }
1499             VirtualConsoleState::ESnonstd => {
1500                 let c = ch as u8 as char;
1501                 if c == 'P' {
1502                     for i in self.par.iter_mut() {
1503                         *i = 0;
1504                     }
1505                     self.npar = 0;
1506                     self.vc_state = VirtualConsoleState::ESpalette;
1507                     return;
1508                 } else if c == 'R' {
1509                     self.reset_palette();
1510                     self.vc_state = VirtualConsoleState::ESnormal;
1511                 } else if c.is_ascii_digit() {
1512                     self.vc_state = VirtualConsoleState::ESosc;
1513                 } else {
1514                     self.vc_state = VirtualConsoleState::ESnormal;
1515                 }
1516             }
1517             VirtualConsoleState::ESpalette => {
1518                 let c = ch as u8 as char;
1519                 if c.is_ascii_hexdigit() {
1520                     self.npar += 1;
1521                     self.par[self.npar as usize] = c.to_digit(16).unwrap();
1522 
1523                     if self.npar == 7 {
1524                         let mut i = self.par[0] as usize;
1525                         let mut j = 0;
1526                         self.palette[i].red = self.par[j] as u16;
1527                         j += 1;
1528                         self.palette[i].green = self.par[j] as u16;
1529                         j += 1;
1530                         self.palette[i].blue = self.par[j] as u16;
1531                         j += 1;
1532                         i += 1;
1533                         self.palette[i].red = self.par[j] as u16;
1534                         j += 1;
1535                         self.palette[i].green = self.par[j] as u16;
1536                         j += 1;
1537                         self.palette[i].blue = self.par[j] as u16;
1538                         self.set_palette();
1539                         self.vc_state = VirtualConsoleState::ESnormal;
1540                     }
1541                 }
1542             }
1543             VirtualConsoleState::ESosc => {}
1544             VirtualConsoleState::ESapc => {}
1545             VirtualConsoleState::ESpm => {}
1546             VirtualConsoleState::ESdcs => {}
1547             VirtualConsoleState::ESnormal => {}
1548         }
1549     }
1550 
1551     #[inline(never)]
1552     pub(super) fn console_write_normal(
1553         &mut self,
1554         mut tc: u32,
1555         c: u32,
1556         draw: &mut DrawRegion,
1557     ) -> bool {
1558         let mut attr = self.attr;
1559         let himask = self.hi_font_mask;
1560         let charmask = if himask == 0 { 0xff } else { 0x1ff };
1561         let mut width = 1;
1562         // 表示需不需要反转
1563         let mut invert = false;
1564         if self.utf && !self.display_ctrl && FontDesc::is_double_width(c) {
1565             width = 2;
1566         }
1567 
1568         let tmp = self.unicode_to_index(tc);
1569         if tmp & (!charmask as i32) != 0 {
1570             if tmp == -1 || tmp == -2 {
1571                 return false;
1572             }
1573 
1574             // 未找到
1575             if (!self.utf || self.display_ctrl || c < 128) && c & !charmask == 0 {
1576                 tc = c;
1577             } else {
1578                 let tmp = self.unicode_to_index(0xfffd);
1579                 if tmp < 0 {
1580                     invert = true;
1581                     let tmp = self.unicode_to_index('?' as u32);
1582                     if tmp < 0 {
1583                         tc = '?' as u32;
1584                     } else {
1585                         tc = tmp as u32;
1586                     }
1587 
1588                     attr = self.invert_attr();
1589                     self.flush(draw);
1590                 }
1591             }
1592         }
1593 
1594         loop {
1595             if self.need_wrap || self.insert_mode {
1596                 self.flush(draw);
1597             }
1598             if self.need_wrap {
1599                 self.carriage_return();
1600                 self.line_feed();
1601             }
1602 
1603             if self.insert_mode {
1604                 self.insert_char(1);
1605             }
1606 
1607             // TODO: 处理unicode screen buf
1608 
1609             if himask != 0 {
1610                 tc = (if tc & 0x100 != 0 { himask as u32 } else { 0 }) | (tc & 0xff);
1611             }
1612 
1613             tc |= ((attr as u32) << 8) & (!himask as u32);
1614 
1615             // warn!(
1616             //     "ch {} pos {} x {} y {} cols {}",
1617             //     c as u8 as char,
1618             //     self.pos,
1619             //     self.state.x,
1620             //     self.state.y,
1621             //     self.cols,
1622             // );
1623             self.screen_buf[self.pos] = tc as u16;
1624 
1625             if draw.x.is_none() {
1626                 // 设置draw参数
1627                 draw.x = Some(self.state.x as u32);
1628                 draw.offset = self.pos;
1629             }
1630 
1631             if self.state.x == self.cols - 1 {
1632                 // 需要换行?
1633                 self.need_wrap = self.autowrap;
1634                 draw.size += 1;
1635             } else {
1636                 self.state.x += 1;
1637                 self.pos += 1;
1638                 draw.size += 1;
1639             }
1640 
1641             width -= 1;
1642             if width == 0 {
1643                 break;
1644             }
1645             let tmp = self.unicode_to_index(' ' as u32);
1646             tc = if tmp < 0 { ' ' as u32 } else { tmp as u32 };
1647         }
1648 
1649         if invert {
1650             self.flush(draw);
1651         }
1652 
1653         true
1654     }
1655 
1656     /// ## 当前vc插入nr个字符
1657     fn insert_char(&mut self, nr: usize) {
1658         // TODO: 管理unicode屏幕信息
1659 
1660         let pos = self.pos;
1661         // 把当前位置以后得字符向后移动nr*2位
1662         self.screen_buf[pos..].rotate_right(nr * 2);
1663 
1664         // 把空出来的位置用erase_char填充
1665         for c in &mut self.screen_buf[pos..(pos + nr * 2)] {
1666             *c = self.erase_char
1667         }
1668 
1669         self.need_wrap = false;
1670 
1671         // 更新本行后面部分
1672         self.do_update_region(self.pos, self.cols - self.state.x);
1673     }
1674 
1675     /// ## 更新虚拟控制台指定区域的显示
1676     fn do_update_region(&self, mut start: usize, mut count: usize) {
1677         let ret = self.driver_funcs().con_getxy(self, start);
1678         let (mut x, mut y) = if let Ok((_, tmp_x, tmp_y)) = ret {
1679             // start = tmp_start;
1680             (tmp_x, tmp_y)
1681         } else {
1682             (start % self.cols, start / self.cols)
1683         };
1684 
1685         loop {
1686             // 记录当前字符的属性
1687             let mut attr = self.screen_buf[start] & 0xff00;
1688             let mut startx = x;
1689             let mut size = 0;
1690 
1691             while count != 0 && x < self.cols {
1692                 // 检查属性是否变化,如果属性变了,则将前一个字符先输出
1693                 if attr != (self.screen_buf[start] & 0xff00) && size > 0 {
1694                     let _ = self.driver_funcs().con_putcs(
1695                         self,
1696                         &self.screen_buf[start..],
1697                         size,
1698                         y as u32,
1699                         startx as u32,
1700                     );
1701                     startx = x;
1702                     start += size;
1703                     size = 0;
1704                     attr = self.screen_buf[start] & 0xff00;
1705                 }
1706                 size += 1;
1707                 x += 1;
1708                 count -= 1;
1709             }
1710 
1711             if size > 0 {
1712                 let _ = self.driver_funcs().con_putcs(
1713                     self,
1714                     &self.screen_buf[start..],
1715                     size,
1716                     y as u32,
1717                     startx as u32,
1718                 );
1719             }
1720             if count == 0 {
1721                 break;
1722             }
1723 
1724             // 一行
1725             x = 0;
1726             y += 1;
1727 
1728             let ret = self.driver_funcs().con_getxy(self, start);
1729             if let Ok(ret) = ret {
1730                 start = ret.0;
1731             } else {
1732                 return;
1733             }
1734         }
1735     }
1736 
1737     const UNI_DIRECT_MAKS: u32 = 0x01ff;
1738     const UNI_DIRECT_BASE: u32 = 0xf000;
1739     /// ## unicode字符转对应的坐标,暂时这样写,还没有适配unicode
1740     /// 这里是糊代码的,后面重写
1741     fn unicode_to_index(&self, ch: u32) -> i32 {
1742         if ch > 0xfff {
1743             // 未找到
1744             return -4;
1745         } else if ch < 0x20 {
1746             // 不可打印
1747             return -1;
1748         } else if ch == 0xfeff || (0x200b..=0x200f).contains(&ch) {
1749             // 零长空格
1750             return -2;
1751         } else if (ch & !Self::UNI_DIRECT_MAKS) == Self::UNI_DIRECT_BASE {
1752             return (ch & Self::UNI_DIRECT_MAKS) as i32;
1753         }
1754 
1755         // TODO: 暂时这样写,表示不支持
1756         return -3;
1757     }
1758 
1759     fn invert_attr(&self) -> u8 {
1760         if !self.color_mode {
1761             return self.attr ^ 0x08;
1762         }
1763 
1764         if self.hi_font_mask == 0x100 {
1765             return (self.attr & 0x11) | ((self.attr & 0xe0) >> 4) | ((self.attr & 0x0e) << 4);
1766         }
1767 
1768         return (self.attr & 0x88) | ((self.attr & 0x70) >> 4) | ((self.attr & 0x07) << 4);
1769     }
1770 
1771     pub(super) fn flush(&self, draw: &mut DrawRegion) {
1772         if draw.x.is_none() {
1773             return;
1774         }
1775 
1776         let _ = self.driver_funcs().con_putcs(
1777             self,
1778             &self.screen_buf[draw.offset..draw.offset + draw.size],
1779             draw.size,
1780             self.state.y as u32,
1781             draw.x.unwrap(),
1782         );
1783 
1784         draw.x = None;
1785         draw.size = 0;
1786     }
1787 
1788     #[allow(clippy::manual_rotate)]
1789     fn build_attr(
1790         &self,
1791         color: u8,
1792         intensity: VirtualConsoleIntensity,
1793         blink: bool,
1794         underline: bool,
1795         reverse: bool,
1796         italic: bool,
1797     ) -> u8 {
1798         let ret = self
1799             .driver_funcs()
1800             .con_build_attr(self, color, intensity, blink, underline, reverse, italic);
1801 
1802         if let Ok(ret) = ret {
1803             return ret;
1804         }
1805 
1806         let mut ret = color;
1807 
1808         if !self.color_mode {
1809             return intensity as u8
1810                 | (italic as u8) << 1
1811                 | (underline as u8) << 2
1812                 | (reverse as u8) << 3
1813                 | (blink as u8) << 7;
1814         }
1815 
1816         if italic {
1817             ret = (ret & 0xf0) | self.italic_color as u8;
1818         } else if underline {
1819             ret = (ret & 0xf0) | self.underline_color as u8;
1820         } else if intensity == VirtualConsoleIntensity::HalfBright {
1821             ret = (ret & 0xf0) | self.half_color as u8;
1822         }
1823 
1824         if reverse {
1825             ret = (ret & 0x88) | (((ret >> 4) | (ret << 4)) & 0x77);
1826         }
1827 
1828         if blink {
1829             ret ^= 0x80;
1830         }
1831 
1832         if intensity == VirtualConsoleIntensity::Bold {
1833             ret ^= 0x08;
1834         }
1835 
1836         if self.hi_font_mask == 0x100 {
1837             ret <<= 1;
1838         }
1839 
1840         ret
1841     }
1842 
1843     pub(super) fn update_attr(&mut self) {
1844         self.attr = self.build_attr(
1845             self.state.color,
1846             self.state.intensity,
1847             self.state.blink,
1848             self.state.underline,
1849             self.state.reverse ^ self.screen_mode,
1850             self.state.italic,
1851         );
1852 
1853         self.erase_char = ' ' as u16
1854             | ((self.build_attr(
1855                 self.state.color,
1856                 VirtualConsoleIntensity::Normal,
1857                 self.state.blink,
1858                 false,
1859                 self.screen_mode,
1860                 false,
1861             ) as u16)
1862                 << 8);
1863     }
1864 
1865     fn default_attr(&mut self) {
1866         self.state.intensity = VirtualConsoleIntensity::Normal;
1867         self.state.italic = false;
1868         self.state.underline = false;
1869         self.state.reverse = false;
1870         self.state.blink = false;
1871         self.state.color = self.def_color;
1872     }
1873 }
1874 
1875 /// ## 虚拟控制台的状态信息
1876 #[derive(Debug, Default, Clone)]
1877 pub struct VirtualConsoleInfo {
1878     // x,y表示光标坐标
1879     pub x: usize,
1880     pub y: usize,
1881     pub color: u8,
1882 
1883     /// 表示字符的强度
1884     intensity: VirtualConsoleIntensity,
1885     /// 斜体
1886     italic: bool,
1887     /// 下划线
1888     underline: bool,
1889     /// 字符闪烁
1890     blink: bool,
1891     /// 前景与背景色反转
1892     reverse: bool,
1893 }
1894 
1895 impl VirtualConsoleInfo {
1896     pub fn new(x: usize, y: usize) -> Self {
1897         Self {
1898             x,
1899             y,
1900             color: Default::default(),
1901             intensity: Default::default(),
1902             italic: Default::default(),
1903             underline: Default::default(),
1904             blink: Default::default(),
1905             reverse: Default::default(),
1906         }
1907     }
1908 }
1909 
1910 /// 字符强度
1911 #[derive(Debug, Clone, PartialEq, Copy)]
1912 pub enum VirtualConsoleIntensity {
1913     /// 暗淡
1914     HalfBright = 0,
1915     /// 正常
1916     Normal = 1,
1917     /// 粗体
1918     Bold = 2,
1919 }
1920 
1921 impl Default for VirtualConsoleIntensity {
1922     fn default() -> Self {
1923         Self::Normal
1924     }
1925 }
1926 
1927 /// ## 虚拟控制台的状态
1928 ///
1929 /// 可以把VC的接收字符理解为一个状态机
1930 #[derive(Debug, PartialEq, Clone)]
1931 pub enum VirtualConsoleState {
1932     /// 正常状态
1933     ESnormal,
1934     /// 收到了转义字符 \e,即"Escape"字符
1935     ESesc,
1936     /// 收到了 "[" 字符,通常是 ANSI 控制序列的开始
1937     ESsquare,
1938     /// 解析参数状态
1939     ESgetpars,
1940     /// 功能键状态
1941     ESfunckey,
1942     /// 收到了 "#" 字符
1943     EShash,
1944     /// 设置 G0 字符集状态
1945     ESsetG0,
1946     /// 设置 G1 字符集状态
1947     ESsetG1,
1948     /// 收到了 "%" 字符
1949     ESpercent,
1950     /// 忽略 ANSI 控制序列状态
1951     EScsiignore,
1952     /// 非标准字符状态
1953     ESnonstd,
1954     /// 调色板状态
1955     ESpalette,
1956     /// Operating System Command (OSC) 状态
1957     ESosc,
1958     ///  Application Program Command (APC) 状态
1959     ESapc,
1960     /// Privacy Message (PM) 状态
1961     ESpm,
1962     /// Device Control String (DCS) 状态
1963     ESdcs,
1964 }
1965 
1966 impl VirtualConsoleState {
1967     pub fn is_ansi_control_string(&self) -> bool {
1968         if *self == Self::ESosc
1969             || *self == Self::ESapc
1970             || *self == Self::ESpm
1971             || *self == Self::ESdcs
1972         {
1973             return true;
1974         }
1975 
1976         false
1977     }
1978 }
1979 
1980 #[derive(Debug, Clone, PartialEq, PartialOrd)]
1981 #[allow(non_camel_case_types)]
1982 pub enum Vt102_OP {
1983     Pecma,
1984     Pdec,
1985     Peq,
1986     Pgt,
1987     Plt,
1988 }
1989 
1990 bitflags! {
1991     #[derive(Default)]
1992     pub struct VcCursor: u32 {
1993         /// 默认
1994         const CUR_DEF			=       0;
1995         /// 无光标
1996         const CUR_NONE			=       1;
1997         /// 下划线形式
1998         const CUR_UNDERLINE		=	    2;
1999         /// 光标占据底部的三分之一
2000         const CUR_LOWER_THIRD	=	    3;
2001         /// 光标占据底部的一半
2002         const CUR_LOWER_HALF	=       4;
2003         ///  光标占据底部的三分之二
2004         const CUR_TWO_THIRDS	=       5;
2005         /// 光标为块状(方块)形式
2006         const CUR_BLOCK			=       6;
2007         /// 光标属性,用于指示软件光标
2008         const CUR_SW			=	0x000010;
2009         /// 光标属性,用于指示光标是否始终在背景上显示
2010         const CUR_ALWAYS_BG		=	0x000020;
2011         /// 光标属性,用于指示前景和背景是否反转
2012         const CUR_INVERT_FG_BG	=	0x000040;
2013         /// 光标前景色属性,用于指定光标的前景色
2014         const CUR_FG			=	0x000700;
2015         /// 光标背景色属性,用于指定光标的背景色
2016         const CUR_BG			=	0x007000;
2017     }
2018 }
2019 
2020 impl VcCursor {
2021     pub fn make_cursor(size: u32, change: u32, set: u32) -> Self {
2022         unsafe { Self::from_bits_unchecked(size | (change << 8) | (set << 16)) }
2023     }
2024 
2025     pub fn cursor_size(&self) -> Self {
2026         Self::from_bits_truncate(self.bits & 0x00000f)
2027     }
2028 
2029     pub fn cursor_set(&self) -> u32 {
2030         (self.bits & 0xff0000) >> 8
2031     }
2032 
2033     pub fn cursor_change(&self) -> u32 {
2034         self.bits & 0x00ff00
2035     }
2036 }
2037 
2038 #[derive(Debug, PartialEq)]
2039 #[allow(dead_code)]
2040 pub enum CursorOperation {
2041     Draw,
2042     Erase,
2043     Move,
2044 }
2045 
2046 #[derive(Debug, PartialEq, Clone, Copy)]
2047 pub enum ScrollDir {
2048     Up,
2049     Down,
2050 }
2051