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