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