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