virtual_console.rs 61 KB

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